# xMatix documentation — full corpus Canonical product documentation for the xMatix platform. One section per page; URLs are canonical. ---- # Branches URL: https://xmatix.com/docs/administration/branches/ Last reviewed: 2026-10-09 A **branch** is one operating location of a company — a showroom, depot, service centre or office — and it is the place that documents, stock and people are keyed to. Each branch belongs to one company (its **Partner Account**). Orders, invoices, purchase documents, stock movements, payments and many other records name both the company and the branch they belong to. You set up branches once, after your companies exist and before people start transacting from those locations. ## Overview Branches are master data. A new organization starts with one company and **no branches**, and branches are optional: an organization that works from a single location can run without them. If you do create branches, xMatix uses them in four ways: - **Documents.** A transaction names the branch it was raised at. xMatix checks that the branch really belongs to the document's company and that it is active. - **Stock.** Stock is held per company and branch, and every storage location inside a warehouse belongs to exactly one branch. Moving stock between branches is a [branch transfer](/docs/warehouse/branch-transfers/). - **Tax.** A branch can carry its own GST registration. Documents raised at that branch then use the branch's GSTIN and state. - **People.** A resource's **Default Branch** fills the branch on the documents they create. On the mobile app, the branch's map position is the centre of the optional check-in location gate. ## When to use it Create a branch for every physical location that keeps its own stock, raises its own documents, holds its own GST registration or is where staff check in. If your organization truly operates from one location, you can hide the branch dimension everywhere instead (see [Configuration](#configuration)). ## How xMatix handles it - **Where branches live.** Branches are part of the core platform. Open **Branches** in the **Platform** app (after Accounts and Items). Branches also appear in the **Warehouse** app and among the masters of the Sales, Procurement and Partner Onboarding settings apps. All of these open the same list and records. - **One company per branch.** **Partner Account** names the company that owns the branch. When a company has at least one branch, every document for that company must name one of its branches. A company with no branches cannot have a branch on its documents. - **Branch pickers follow the company.** On documents, the Branch lookup lists only the branches of the company already chosen on the document. - **Values copied from the GST registration.** When you pick a **GST Registration**, xMatix copies its GSTIN and its state (into **Source of Supply**) onto the branch when you save. If **Partner Account** is still empty, it also fills it from the registration. - **Defaults handed to documents.** A purchase-side document raised at the branch takes its supplier from the branch's **Default Supplier Account** if the supplier was left empty. A sales or purchase document takes its place of supply from the branch's **Source of Supply** if that field was left empty. ## Prerequisites - The company that owns the branch must already exist and be active. A new organization's own company is created for it. Further companies are onboarded under **Setup → Feature Hub → Administration → Org Settings → Companies** (see [Tenants, companies and organizations](/docs/concepts/tenants-and-companies/)). - Optional records to create first, if you want to link them: the branch's **Address** (a contact address), its **GST Registration**, its **Business Hours** and its **Business Unit**. - Create and edit access to the Branch entity in your [security profile](/docs/administration/security-profiles/). ## Procedure ### Step 1 — Open the branch list Open the app launcher, choose the **Platform** app (or **Warehouse**) and select **Branches**. The list has these views: **All Branches**, **All Active Branches**, **All Sales Branches** and **All Service Branches**. Check the list before you add anything. A duplicate branch splits stock and documents between two records, and nothing reconciles them. ### Step 2 — Create the branch Select **New**. The create form opens with the identity fields at the top: 1. Enter **Name** and a **Code**. The code must be unique across all branches. 2. Choose the owning company in **Partner Account**. 3. Choose **Branch Type**: *Sales Branch* or *Service Branch*. It is required. 4. Optionally enter a **Marketing Name** and choose **Business Hours**. The form has three tabs below that: - **Contact Details** — **Address**, **Mobile**, **E-mail**, **Website** and **Sales Phone**. - **Operational Details** — the checkboxes **Allow Purchase**, **Allow Sales**, **Allow Inventory**, **Allow Service**, **Active**, **Home Delivery** and **Service Pickup Drop**. - **GST Details** — **GST Registration** and **Geo Location**. Tick **Active**: an inactive branch cannot be used on new documents. Select **Save**. The record page opens. ### Step 3 — Review and complete the record The record page has two tabs: **Details** and **Storage Locations**. **Details** shows three sections: - **Branch Details** — Name, Code, Business Hours, Business Unit, GST Registration, GSTIN, Branch Type, Default Supplier Account. - **Contact Information** — Address, Source of Supply, Mobile, Website, Geo Location. - **Operational Control** — the checkboxes. Fields the create form does not show, such as **Business Unit** and **Default Supplier Account**, are filled in here. Select **Edit** in the page header to change the record. ### Step 4 — Add storage locations On the **Storage Locations** tab, select **New** to add the zones, bins and vans inside the branch. Every stock figure names a storage location, so a branch that holds stock needs at least one. See [Storage locations and vans](/docs/warehouse/storage-locations/). ### Step 5 — Set the branch on people Open each **Resource** who works from the branch and set **Default Branch** (with **Default Partner Account**). From then on, documents that person creates get this company and branch automatically, unless the document already has a company or branch. The mobile check-in location gate also measures distance from the resource's default branch. ### Step 6 — Retire a branch To stop using a branch, open it, select **Edit**, clear **Active** and save. Existing documents keep the branch. New and edited documents that name it are rejected with "Branch is Inactive.". The branch then shows only in **All Branches**, not in **All Active Branches**. Prefer this to deleting a branch that has history. ## Fields | Field | What it means | Notes | | --- | --- | --- | | Name | The branch's name as it appears in lookups and on documents. | | | Code | A short identifier for the branch. | Required and unique. | | Partner Account | The company that owns the branch. | Decides which documents may use the branch. Filled from the GST registration if left empty. | | Branch Type | Whether this is a sales or a service location. | Required. Values: *Sales Branch*, *Service Branch*. Used by the All Sales Branches and All Service Branches views. | | Marketing Name | A customer-facing name for the location. | Optional. | | Business Hours | The branch's working week and time zone. | Used for attendance working-hours checks and time zone when a resource has no business hours of their own. | | Business Unit | The business unit the branch belongs to. | Record page only. | | Address | The branch's postal address, a contact address record. | | | Mobile | The branch mobile number. | Stored as text, so leading zeros are kept. Has a separate country code that defaults to +91. | | E-mail | The branch e-mail address. | Must be unique across branches. | | Website | The branch web address. | | | Sales Phone | The sales desk number. | If filled, it must be exactly 10 digits. | | Allow Purchase, Allow Sales, Allow Inventory, Allow Service | Record what the branch is meant to do. | Informational: xMatix does not currently block any document based on them. Companies onboarded through partner onboarding get all four ticked. | | Active | Whether the branch can be used on new documents. | Clear it to retire the branch. | | Home Delivery, Service Pickup Drop | Record whether the branch offers these services. | Informational. | | GST Registration | The GST registration the branch trades under. | Copies GSTIN and Source of Supply onto the branch on save. | | GSTIN | The branch's GST identification number. | Read-only, derived from GST Registration. | | Source of Supply | The state the branch supplies from. | Set from the GST registration's state. Copied to a document's place of supply when the document leaves it empty. | | Geo Location | The branch's position on the map (latitude and longitude). | Centre of the mobile check-in location gate. Also used as the depot when van loads are planned. | | Default Supplier Account | The supplier to use when a purchase document at this branch has none. | Must be an account with **Supplier Account** ticked. | The reference page also lists **Parent Location**, **Default Inventory Valuation Method**, **Inventory Valation Method**, **Payroll Business Hours**, **Document Name Code**, **Phone**, **Sales Email**, **Service Email** and **Service Phone**. These are not on the default layouts and are not used by any built-in process today. **Document Name Code** is the exception: an invoice's document series is built from the company's and the branch's codes. See the [Branch entity reference](/docs/reference/entities/branch/) for every field. ## Business rules - **Code** is required and unique, and **E-mail** is unique across branches. - **Branch Type** is required. - **Sales Phone**, when filled, must be exactly 10 digits. Otherwise the save fails with "Phone number provided is not in a valid format." - **Default Supplier Account** must exist and must be flagged as a supplier account. Otherwise saving fails with "Default Supplier Account is invalid." or "Default Supplier Account must be an account flagged as a supplier account." - **GST Registration.** Choosing or changing it copies the registration's GSTIN and state onto the branch, and fills an empty Partner Account. Clearing the registration leaves the copied values in place. Editing other fields never re-copies them, so a manual change to Source of Supply survives later edits. - **Branch checks on documents.** When a document is saved, xMatix checks its company and branch together: - If the company has branches and no branch is given, the save fails with "Branch is required for this Partner Account." - If the branch belongs to another company, it fails with "Invalid Branch for Partner Account." - If the branch is inactive, it fails with "Branch is Inactive." - If the company has no branches but a branch is given, it fails with "Invalid branch for partner account." These checks apply to orders, quotes, invoices, credit notes, payments, delivery orders, fulfilments, purchase orders, goods receipts, bills, requisitions, shipments, transfers, adjustments, cycle counts, service orders, leads, opportunities and claim batches, among others. - **Default company and branch from the creator.** A new document with no company and no branch gets them from the creating user's resource: 1. The resource's Default Partner Account and Default Branch, when both are set. 2. Otherwise the resource's current partner-resource assignment. 3. Otherwise whichever single default is set. xMatix never picks a branch just because a company has only one. ## Example A distributor opens a second depot. The administrator creates a branch: - **Name**: *North Depot* - **Code**: *NDP* - **Partner Account**: the distributor's own company - **Branch Type**: *Sales Branch* - **Business Hours**: *Standard 9 to 6* - **Active**: ticked On **GST Details**, they pick the depot's GST registration. After saving, **GSTIN** and **Source of Supply** show that registration's number and state. They add **Default Supplier Account** = *Sunrise Polymers* on the record page. On the **Storage Locations** tab, they create *NDP-MAIN* (a warehouse) and *NDP-VAN1* (a van). Finally, they set **Default Branch** = North Depot on the three resources who work there. The next morning, a sales executive at the depot creates an order. Company and branch are already filled in, and the order's place of supply is the depot's state. A purchase order raised at the depot without a supplier takes *Sunrise Polymers*. ## Training ### Practice exercise In a sandbox: 1. Create a branch *Training Branch* (Code *TRB*, Branch Type *Service Branch*, Active ticked) for your company. Expected: the record page opens and the branch appears in **All Service Branches**. 2. Enter **Sales Phone** *12345* and save. Expected: "Phone number provided is not in a valid format." 3. Correct it to a 10-digit number and save. 4. Clear **Active** and save. Then try to save a new order for that company with Branch = *Training Branch*. Expected: "Branch is Inactive." ### Quick reference - Branches: **Platform** app → **Branches** (also in **Warehouse**). - Required: Name, a unique Code, Branch Type. Always set Partner Account. - A company with branches needs a branch on every document; a company without branches cannot have one. - GSTIN is read-only; it comes from **GST Registration**. - **Default Supplier Account** fills empty suppliers on purchase documents raised at the branch. - Stock needs a storage location at the branch — add it on the **Storage Locations** tab. - Set **Default Branch** on each resource so their documents fill the branch automatically. - Retire a branch by clearing **Active**, not by deleting it. ## Permissions Branch is an ordinary entity: viewing, creating, editing and deleting branches is controlled by the Branch entity permissions in **Setup → Access Control → Profiles → Entity Permissions**. The security profiles that ship with xMatix grant full access to Branch. If you want only administrators to maintain branches, remove create, edit and delete from the other profiles but keep read: users need read access to see and pick branches on their documents. Changing the organization-shape setting below needs the `setup.org.settings.manage` capability. ## Configuration - **Use branches at all.** Go to **Setup → Feature Hub → Administration → Org Settings**. Under **Organisation shape**, the switch **We operate from multiple locations** is on by default. Turn it off only if your organization genuinely works from one location. Branch fields then disappear from every screen, list, report and dashboard, and documents are saved without a branch. Branches, branch postal codes, branch time slots and transfers are hidden too. The switch is independent of **We run multiple companies**. - **Branch fields and layouts.** The create form, record page and views are ordinary layouts and views. You can change them in the Design Studio (see [Customizing xMatix](/docs/customization/)). - **Default branch per user.** Set **Default Branch** and **Default Partner Account** on each resource. Partner-resource assignments cover people who work across several companies or branches. - **Mobile check-in location gate.** On the mobile app configuration's **Check-In** tab, the location gate checks that a check-in happens within a radius of the resource's default branch (250 m by default). The branch needs a **Geo Location**. Without one, the check-in is allowed and only the location is recorded. See [Mobile app configuration](/docs/mobile/admin-configuration/). - **Document numbering per branch.** A numbering setting under **Setup → Feature Hub → Platform → Document Settings** can take its series from a field on the document. That lets each branch number its documents independently. See [Email templates and document numbering](/docs/administration/templates/). - **Assignment by postal code.** Branch postal codes map postal codes to branches. Assignment rules can use them to route new records to the branch that covers a customer's postal code. ## Common problems ### "Branch is required for this Partner Account." The document's company has at least one branch, so every document for it must name one. Choose a branch, or set **Default Branch** on your resource so it is filled for you. ### "Invalid Branch for Partner Account." The branch on the document belongs to a different company. This usually happens after the company was changed on a document that already had a branch. Pick one of the selected company's branches. ### "Branch is Inactive." The branch has been retired. Choose an active branch, or ask an administrator to tick **Active** on the branch again. ### "Invalid branch for partner account." The company on the document has no branches at all, but a branch was given. Clear the branch, or ask an administrator whether the branch was linked to the wrong company. ### My check-in says the branch has no usable coordinates Your default branch has no **Geo Location**, so the location gate cannot measure distance. The check-in still goes through, with your location recorded. An administrator should set the branch's Geo Location. ### The Branch field has disappeared from every screen The organization has turned off **We operate from multiple locations** in Org Settings. Turn it back on if branches are needed. ## Common questions ### Do we have to create branches? No. A new organization has one company and no branches, and everything works without them. Create branches when you have more than one location that holds stock, raises documents or registers for GST separately. Once a company has a branch, every document for that company must name one, so create branches for all of that company's locations together. Assign default branches to resources at the same time. If you will only ever have one location, turn off **We operate from multiple locations** to hide the branch field everywhere. ### Can one branch serve two companies? No. A branch belongs to exactly one company through **Partner Account**, and documents are rejected when the branch and company do not match. If two companies share a building, create a branch for each company. Stock is also held per company and branch, so this keeps each company's stock and documents separate. ### Why does the Allow Sales checkbox not stop sales at a branch? The **Allow Purchase**, **Allow Sales**, **Allow Inventory** and **Allow Service** checkboxes describe the branch, but no built-in process reads them today. A branch with Allow Sales cleared can still be used on an order. If you need to enforce such a restriction, add a validation rule on the document that checks the branch, or retire the branch by clearing **Active**. ### Can I change a branch's GST registration later? Yes. Changing **GST Registration** re-copies the new registration's GSTIN and state onto the branch when you save. Documents saved earlier keep the values they had. If you clear the registration, the branch keeps the last copied GSTIN and Source of Supply. ## Related topics - [Branch entity reference](/docs/reference/entities/branch/) - [Tenants, companies and organizations](/docs/concepts/tenants-and-companies/) - [Storage locations and vans](/docs/warehouse/storage-locations/) - [Branch transfers](/docs/warehouse/branch-transfers/) - [Mobile app configuration](/docs/mobile/admin-configuration/) - [Security profiles and the grant matrix](/docs/administration/security-profiles/) - [Email templates and document numbering](/docs/administration/templates/) ---- # Export data URL: https://xmatix.com/docs/administration/data-management/export-data/ Last reviewed: 2026-09-06 The Data Export screen turns a query — one entity, your choice of fields, optional fields from related records, filters and sorting — into an Excel or CSV file produced by a background job. You build and preview the query in the **Start Export** wizard, submit the job, and download the result from **Export History** while the file is still stored. The screen is meant for administrators: it exports the tenant's data as it is, not as filtered by the exporting user's record permissions. ## Prerequisites - The data-export capability (`setup.data.export.manage`) on one of your security profiles. It gates the **Data Export** navigation item and every export endpoint. - Awareness that **export does not apply record-level or field-level security**. The job applies your organization's tenant boundary and the metadata visibility of entities and fields, nothing else: every record of the entity, and any field you tick, lands in the file regardless of sharing rules or field permissions. Treat the capability as a data-administration grant and the output as sensitive. - A plan for where the file goes. Files are kept for 7 days and then deleted; the history row stays. ## Procedure ### Step 1 — Open Data Export and pick the entity Go to **Setup → Platform Operations → Data Export**. The page body is the Export History table; the only action is **Start Export** in the page header, which opens a five-step wizard: **Entity → Columns → Sort & Filter → Records → Preview**. On the first step choose the entity in the searchable **Select an entity to export…** list — every non-hidden entity is offered. The entity is the query's fixed starting point: related fields can be added in the next step, but unrelated entities need separate export jobs. **Next** stays disabled until an entity is selected; **Reset** at the bottom-left clears the wizard at any step. ### Step 2 — Choose the columns @[guided-image](_img/export-builder.png) The **Fields & Relations** card lists the entity's fields and, below them, its relations — parents reached through lookups (marked ↑) and child collections (marked ↓) — each expandable to a further level so that an order export can carry its account's name or its owner's e-mail. Tick fields to include them; **Select common** ticks the Name field plus every non-system, non-lookup field; **Search fields…** filters the tree. The **Selected Fields** card on the right lists what you ticked as chips you can drag to set the output column order. Nothing ticked means *all fields will be exported*, which is rarely what a recipient needs — narrow the export here rather than in the spreadsheet afterwards. Related fields appear in the file as `Prefix.Field` columns. ### Step 3 — Filter and sort The **Sort & Filter** step has two tabs. **Filter** rows (**Add filter**) pair a field — including related fields of the relations you ticked — with an operator: Equals, Not equals, Contains, Starts with, Ends with, Greater than, Greater or equal, Less than, Less or equal, Is null, Is not null. Picklist fields offer their values in a dropdown. **Sort** rows (**Add sort**) pick a field and an optional **Descending** flag. Sorting matters more than it looks: when you cap the record count in the next step, the sort decides which rows survive. ### Step 4 — Set the record limit and file format @[guided-image](_img/export-records.png) **Records to export** is either **No limit (all matching)** — every matching record, split into files of up to 1,000,000 rows each — or **Limit to top N**, a row cap applied in the chosen sort order (default 100,000). **File format** is **Excel (.xlsx)** (default) or **CSV (.csv)**. There are no further output options: headers, date format and time zone are fixed (see the format notes below), and attachments are never included. ### Step 5 — Preview and submit **Preview** runs the real query against live data: choose a sample size of Top 10, 25 or 50 and use **Refresh preview** after changing anything. The **Export Lines** table shows the sample with the exact column headings the file will carry; the **Exporting {n} rows** counter is an exact count over the same filter, so compare it with your expectation before you commit. Id cells link to the records for spot checks. When the sample is right, select **Submit export**. The wizard closes with an *Export queued* message and the job id, and a new row appears at the top of Export History as **Queued**. ### Step 6 — Download from Export History Export History shows Job ID (short form, copyable), Status, Entity, Format, Rows, File, Expires, Submitted and Submitted By, and refreshes itself every five seconds while a job is Queued, Published or Processing. A job normally moves **Queued → Processing → Completed**; **Failed** carries the reason in a tooltip on the File cell. Once Completed, the File cell offers **Download** for a single file, or a **ZIP (n)** dropdown listing each part as *Part n · rows* for exports that were split. The **Expires** column shows when the stored file is removed — 7 days after the job — after which only the history row remains. Downloads are authenticated: the link works only for signed-in users holding the export capability, so share the file, not the link. **Expected result:** the history row reads *Completed* with a Rows count matching the preview counter, every part downloads, and a spot check of the file shows the columns, filters and order you previewed. ## Format notes | Format | What you get | | --- | --- | | Excel (.xlsx) | One worksheet per file, bold header row frozen at the top, autofilter enabled, uniform column width, header captions in the form `Label (FieldName)`. | | CSV (.csv) | A header row followed by the data, UTF-8 with byte-order mark (opens correctly in spreadsheet tools), dates as `yyyy-MM-dd HH:mm:ss`. | Both formats carry identical rows and columns for the same query. Choose CSV when the file feeds a script, another system or a later re-import; choose Excel when people will read or hand-edit it. ## Limits - Files are split at 1,000,000 rows; a job may produce at most 20 files. A query that would exceed that ceiling fails *before* any file is written, with a message asking you to narrow the filter or set a record limit. - The preview and the count run with a 30-second query timeout. A preview that times out usually means a broad filter on a very large entity — add a filter or a sort on an indexed field. - Some entities can be blocked from export by platform configuration; they simply do not appear in the entity list. - Submitting the same wizard state twice within a short interval returns the existing job rather than starting a duplicate. - If your platform's export feature or file storage is disabled, **Submit export** fails with a service-unavailable error; this is an operator configuration matter, not a permissions problem. ## Common problems - **The file contains records or fields users cannot see in the app.** Expected: exports apply tenant isolation and metadata visibility only, not record-level sharing or field-level security. Restrict who holds `setup.data.export.manage`, and narrow the columns and filters instead of relying on security to trim the file. - **The job failed immediately with a "narrow the filter" message.** The result would have exceeded 20 files (about 20 million rows). Add a filter, or set **Limit to top N**. - **The download link no longer works.** The file passed its **Expires** time and was deleted. Run the export again — the history row cannot revive a file. - **A colleague's link does not open for me.** Downloads are authenticated and require the export capability. Pass the downloaded file, not the link. - **One export produced a ZIP with several parts.** That is the 1,000,000-row split, not an error; each part has its own header row. ## Common questions ### Can I export several entities in one file? One entity drives each export, but the Columns tree lets you pull fields from related records — parents through lookups and children through collections, each expandable a further level — flattened onto each row as `Prefix.Field` columns. For genuinely separate data sets, run one export per entity. If you are exporting to re-import elsewhere, keep each entity in its own file anyway, since imports also work one entity at a time. ### Does the export respect my sharing rules and field permissions? No. The export applies the organization boundary and entity/field visibility from metadata, and nothing else — every record of the entity and every ticked field is written. This is why the capability is a setup-level grant rather than a per-user permission. If you need a user-scoped extract, filter it explicitly in **Sort & Filter** and review the preview. ### How do I get record ids for a later import? Tick **Id** in the Columns step (it is offered as a normal field). An [import](/docs/administration/data-management/import-data/) that carries an `id` column updates the matching records instead of creating duplicates, so export-edit-import is the safe way to bulk-update. ### Can I schedule a recurring export? Not from this screen; every export is a one-off background job started from the wizard. For a recurring extract, re-run the wizard when needed, or use a report subscription for a recurring, formatted delivery of a query. ## Related topics - [Import data with the import wizard](/docs/administration/data-management/import-data/) - [Data lifecycle concepts](/docs/concepts/data-lifecycle/) - [Security profiles](/docs/administration/security-profiles/) ---- # Import data with the import wizard URL: https://xmatix.com/docs/administration/data-management/import-data/ Last reviewed: 2026-09-06 The import wizard loads records into one entity at a time from an Excel, CSV or JSON file. You upload the file, map its columns to the entity's fields, optionally validate everything with a dry run, then run the import in the browser or as a background job. Every row gets its own result, and the Import History table keeps each run reviewable, downloadable and — for failed rows — retryable. ## Prerequisites - The data-import capability (`setup.data.import.manage`) on one of your security profiles. It gates the **Data Import** navigation item and the job endpoints; the row writes themselves run under your ordinary record permissions. - **Create** permission — and **Update** permission, if rows will update existing records — on the target entity. Each row is written exactly as a manual save would be: mandatory fields, validation scripts, business rules, automation, and record- and field-level security all apply per row. - A file in `.xlsx`, `.xls`, `.csv` or `.json` format. The soft file-size limit is 100 MB and one file may hold at most 50,000 rows; split anything larger. From the Map Columns step you can download a header-only template per entity, and starting from that template avoids most mapping problems. - For related data, a load order: import parents first (accounts), then children (their orders), so lookup columns in the child file have records to match. ## Procedure ### Step 1 — Open Data Import and start the wizard Go to **Setup → Platform Operations → Data Import**. The page body is the Import History table; the only action is **Start Import** in the page header, which opens the **Import Data** wizard with three steps: **Upload File & Select Entity**, **Map Columns** and **Import**. **Restart Import** at the bottom-left clears the wizard at any point. @[guided-image](_img/import-wizard.png) ### Step 2 — Upload the file and select the entity Drop the file on the upload area (or click it to browse). The file is parsed in the browser — nothing is uploaded yet — and the wizard reports how many columns it detected. Then choose the target entity in **Select Target Entity**; the searchable list contains every entity you may import into. An import loads one entity per run. ### Step 3 — Map columns The **Map Columns** table lists every upload column with a **Status**, a **Maps To** selector and a **Detail** note. The wizard proposes a mapping automatically, in this order: 1. A dot-notation column such as `Account.Name` maps to the lookup field `Account`, matched on the parent's `Name`. 2. An exact field-name match (case-insensitive). 3. A field-label match, for non-lookup fields. 4. A close spelling (one or two characters off) is marked **Suggested** — review these before running. Anything else is **Skipped**. Change any row with **Maps To**; the first option, **Skip (do not import)**, drops the column. Lookup columns may hold display values rather than ids: a value that matches no record is reported per row as a transform error and the row is not sent. Several dot columns on one lookup act as a composite key (`Account.Name` plus `Account.AccountNumber`). Picklist columns must contain the field's legal values exactly — they are validated by the normal write pipeline, not pre-checked here. Two more controls sit on this step: **Download Template** (a CSV with one header per active importable field, lookups written as `Parent.Name`) and **Batch Size** (1–100, default 25 rows per request for browser-driven runs). A batch size above 50 shows a warning because large batches can exceed the request timeout; use **Run Async** instead of pushing it higher. ### Step 4 — Check the preflight card The **Import** step opens with a **Ready to import into {entity}** card showing total rows, mapped columns and batch size, followed by preflight alerts: - More than 50,000 rows: the import is blocked — split the file. - 2,000 rows or more: **Run Async** is recommended. - Columns mapped to system-managed fields (Id apart, fields such as CreatedBy, OwnerId or RowVersion) are ignored. - Unmapped columns, and values in the first 200 rows that do not convert to the field's type, are listed as warnings. Required fields are **not** checked here; a missing mandatory value surfaces as a row error when you run. ### Step 5 — Choose how to run Three buttons run the import: | Button | What it does | When to use it | | --- | --- | --- | | **Dry Run** | Sends every row through the server-side validation pipeline and writes nothing. The uploaded file is kept, and the run is recorded in Import History with type *DryRun*. | Always, before a first load of a new file or entity. | | **Run Async** | Uploads the file to storage and queues a background job. Progress streams back to the wizard; **Stop watching** only stops the live view, the job keeps running. | Anything large (the wizard recommends it from 2,000 rows), or whenever you cannot keep the tab open. | | **Import Now** | Writes rows from the browser in batches of the configured size, with a live per-row result table. The run is also recorded in Import History as type *Sync*. | Small, interactive loads where you want to see each row's outcome immediately. | An **Import Now** run depends on the browser tab: if the tab closes mid-run, rows already written stay, and the history row can remain at *Processing* because nothing on the server finishes it. Prefer **Run Async** when in doubt. ### Step 6 — Read the results For every row the result is **Created**, **Updated**, **Error** or **Transform Error** (the row never reached the server, typically an unresolved lookup). Import Now shows an **Import Results** table with Row #, Status, Id and Error, plus **Download Errors** and **Download Success** buttons that build CSVs in the browser. Each row commits in its own transaction, so errors never roll back the good rows. A run ends as **Completed** (no errors), **Partial** (finished with error rows) or **Failed**. Row errors are the entity's own guardrails — a missing mandatory field, an illegal picklist value, a validation script, a record you may not update — so read the message rather than re-running blind. ### Step 7 — Use Import History Every run appears in **Import History** with Job ID, Status, Entity, Type (Sync, Async or DryRun), Records (live progress while running), Result (created, updated and error counts), Uploaded File, Failed Rows, Submitted and Submitted By. @[guided-image](_img/import-history.png) - **Uploaded File → Download** returns the original file. After a clean *Completed* run the file is removed and the cell says so; it is kept for Partial, Failed and DryRun runs. - **Failed Rows → Fix file** downloads a CSV of only the failed rows with their original columns plus an `_error` column; correct it and import that file. - **Retry** (Partial or Failed jobs whose file is still stored) queues a *new* job that replays only the failed rows, linked to the original. - Import jobs also appear under **Setup → Platform Operations → Monitoring → Jobs** with type *ImportJob* — but retry them from Import History; the Jobs screen's own Retry and Cancel actions apply to a different job type. **Expected result:** Import History shows the run as *Completed* or *Partial*, the created and updated counts match what you expected from the file, and every failed row has an actionable message or a fix file. ## Common problems - **Duplicates after a re-import.** A row updates an existing record only when it carries the record's `id`, or an `externalId` that matches exactly one existing record. Every other row creates a record, so re-importing a file without either key duplicates it. Deduplication rules feed the duplicate finder; they do not block imports. - **"Record with Id … not found".** The `id` column holds a value that matches no record (often an id copied from another organization or a deleted record). The row errors instead of creating a duplicate, which is the safe outcome; fix the id or clear it to create. - **Lookups fail to resolve.** The display value in the child file does not match a parent record exactly — a spelling or spacing difference, or the parent was never imported. Fix the values in the fix file and retry only those rows. - **A partially applied import.** Expected behaviour: rows commit independently. Use **Fix file** or **Retry** for the failed rows; do not re-run the whole file. - **An automation storm.** Every imported row fires the entity's business rules and automation exactly like a manual save, so a 20,000-row import can enqueue 20,000 automation runs. Review what is active on the entity — and run a **Dry Run** first — before a large load. ## Common questions ### How do I update existing records instead of creating new ones? Include an `id` column holding each record's identifier: rows with an id update that record as a partial update (unmapped fields are left alone); rows without one are matched on `externalId` if you map it and exactly one record carries that value; otherwise the row creates. The reliable way to get ids is to [export the records](/docs/administration/data-management/export-data/) first, edit the file, and import it back. ### Can I import more than one entity in one run? No — each run targets a single entity. For a related data set, run one import per entity, sequenced parent-first, so that each child file's lookup columns resolve against records that already exist. Keep the display values in the child's lookup columns identical to the parent records, or those rows fail as unresolved lookups. ### What is the difference between Dry Run and the preflight warnings? Preflight is a quick browser-side check of the mapping: row count, ignored system fields, unmapped columns and type conversion on a sample. A **Dry Run** sends every row to the server and runs the real validation pipeline — mandatory fields, validation scripts, security — without writing, so it is the only way to see the complete error list before committing. ### Can I undo an import? There is no single undo. Imported rows are ordinary records, so the good rows of a bad run must be found and deleted like any other data — deleted records land in the recycle bin for a grace window, from which they can be restored. Prevent the mess instead: dry-run the file, load a small test file, check the results, then load the rest. See [data lifecycle concepts](/docs/concepts/data-lifecycle/). ## Related topics - [Export data](/docs/administration/data-management/export-data/) - [Data lifecycle concepts](/docs/concepts/data-lifecycle/) - [Security profiles](/docs/administration/security-profiles/) ---- # xMatix administration guide URL: https://xmatix.com/docs/administration/ Last reviewed: 2026-09-06 This section is for the people who run xMatix for their organization: inviting users, deciding who may see and do what, keeping licenses and templates in order, moving data in and out, and testing changes in a sandbox before they reach production. Every page names the Setup screen it describes, lists the settings that matter, and states honestly what a control does — and does not — do. ## Where administration lives in the product All administrative work happens in **Setup**, reached from the app launcher. Its home page opens on a **Browse** tab (or directly on the section cards when your organization has no Setup Copilot license) that maps the same groups as the left sidebar: @[guided-image](_img/administration-overview.png) | Setup group | What administrators do there | Documented in | | --- | --- | --- | | **Access Control** | Users, Business Units, Profiles, Roles, Teams, Policies — identities and the two gates that decide what they can do and which records they see | [User accounts](/docs/administration/users/user-accounts/), [Invite a user](/docs/administration/users/invite-a-user/), [Offboard a user](/docs/administration/users/deactivate-a-user/), [Security profiles](/docs/administration/security-profiles/), [Roles, teams and business units](/docs/administration/roles-teams-business-units/), [Record security](/docs/administration/record-security/), [Restriction rules](/docs/administration/restriction-rules/) | | **Feature Hub → Administration** | Org Settings, Licenses, License Usage, Themes | [Licensing](/docs/administration/licensing/) | | **Feature Hub → Platform** | Document Settings, DeDuplication Rules, Localization Resources, Email Templates, Resources, Guided Journeys | [Email templates and document numbering](/docs/administration/templates/) | | **Platform Operations** | Sandboxes & DeltaPacks, Monitoring (Jobs, Audit, Message Log, Tracing), Data Import, Data Export | [Sandboxes and promoting changes](/docs/administration/sandboxes/), [Import data](/docs/administration/data-management/import-data/), [Export data](/docs/administration/data-management/export-data/) | The other groups — Design Studio, Process Studio, Data Studio and Sense AI Studio — are where the model, automation, analytics and AI agents are built; they are covered in [Customizing xMatix](/docs/customization/), [Data Studio](/docs/data-studio/) and [Sense AI](/docs/sense-ai/). The cards for Access Control, Feature Hub and Platform Operations list their sub-groups as text; open the actual screens from the left sidebar. Below the cards, the home page keeps shortcuts to the entities you worked on most recently. ## The access model in one paragraph Every action a user attempts passes two independent gates. A **security profile** must grant the operation — the app, the entity, the field, the action or the setup capability — and **record security** (the entity's policy, ownership, the role hierarchy, shares and rules) must expose the specific record. Roles, teams and business units never grant operations; licenses and seats are a third, commercial layer that must also be satisfied for licensed products and features. When a user "can't see something", work through the layers in order rather than widening one profile: [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/) is the ordered checklist, and [Worked security scenarios](/docs/administration/security-scenarios/) shows the building blocks combined into configurations you can copy. ## Capabilities you will need Setup screens are gated by capabilities on your security profiles. The built-in **SystemAdmin** profile holds all of them; a delegated administrator needs only the relevant ones: | Task | Capability | | --- | --- | | Users (create, edit, deactivate) | `setup.security.users.manage` | | Profiles, roles, teams, business units, policies and rules | `setup.security.manage` | | Licenses, license usage, per-user seats, license coverage | `setup.licensing.admin` | | Messaging templates | `setup.metadata.email.manage` | | Data import / data export | `setup.data.import.manage` / `setup.data.export.manage` | | Jobs monitoring | `setup.diagnostics.jobs.view` (actions: `setup.diagnostics.jobs.manage`) | | Sandboxes, copy profiles, DeltaPacks, inbound DeltaPacks | `setup.sandboxes.manage`, `setup.sandboxcopyprofiles.manage`, `setup.deltapacks.manage`, `setup.deltapacks.inbound.manage` | A screen you cannot see in the sidebar is almost always a missing capability, not a missing feature; some groups are additionally hidden when the feature is not enabled for your organization (sandboxes) or when the current environment is itself a sandbox. ## Reading order 1. [Invite a user](/docs/administration/users/invite-a-user/) — the account, provisioning and the first profile; [User accounts](/docs/administration/users/user-accounts/) covers every field and edit after that. 2. [Security profiles and the grant matrix](/docs/administration/security-profiles/) — the operation gate. 3. [Roles, teams and business units](/docs/administration/roles-teams-business-units/), [Record-level security and sharing](/docs/administration/record-security/) and [Restriction rules](/docs/administration/restriction-rules/) — the record gate. 4. [Licensing](/docs/administration/licensing/) — the commercial layer and per-user seats. 5. [Branches](/docs/administration/branches/) — the operating locations your companies transact from, in the **Platform** app rather than Setup. 6. [Resources](/docs/administration/resources/) — the person record behind each user: default company and branch, reporting line, pay and identity details, also in the **Platform** app. 7. [Email templates and document numbering](/docs/administration/templates/) — outbound messages and generated document numbers. 8. [Import data](/docs/administration/data-management/import-data/) and [Export data](/docs/administration/data-management/export-data/) — bulk data in and out. 9. [Sandboxes and promoting changes](/docs/administration/sandboxes/) — test in isolation, promote with DeltaPacks. ## Related topics - [Security model concepts](/docs/concepts/security-model/) - [Tenants and companies](/docs/concepts/tenants-and-companies/) - [Data lifecycle concepts](/docs/concepts/data-lifecycle/) - [Getting started with xMatix](/docs/getting-started/) — the user-facing orientation. - [Platform security & governance](/platform/security/) ---- # Licensing: products, features and seats URL: https://xmatix.com/docs/administration/licensing/ Last reviewed: 2026-09-06 Licensing determines what your organization has commercially enabled and which users occupy a seat on it. It is a separate layer from security: a user needs an entitlement *and* a [security profile](/docs/administration/security-profiles/) grant before a licensed product or feature becomes usable, and a module's own settings switch can still turn it off for everyone. This page explains the objects, the **Licenses** screen, per-user seats, and what the tenant administrator can and cannot change. ## Products, features and packages | Kind | What it covers | Example | | --- | --- | --- | | Product | A whole functional area of the platform, with the apps and entities it ships | CRM, Finance, Inventory | | Feature | An individual capability, licensed on its own or riding along with a product | Sense AI | | Package | An installed add-on bundle with its own licensing mode | A vertical solution package | Every feature carries a **licensing mode** set in the platform catalogue: **Licensed** features need a tenant license row and — when seat enforcement is on — a user seat; **Free** features are granted automatically to everyone who holds the parent product; **Disabled** features are off platform-wide and no tenant setting turns them on. The Licenses screen offers **Enable**/**Disable** only for Licensed rows — the missing action on a Free or Disabled row is expected, not a permissions problem. A feature also needs its parent product enabled, and a feature's seat count can never exceed the parent product's. ## The Licenses screen Go to **Setup → Feature Hub → Administration → Licenses** (page title **Tenant Licenses**). Viewing requires the `setup.licensing.admin` capability; without it the page shows a *Permission required* notice. The header tiles count Products, Features and Packages in the catalogue plus the active seats of each kind, and six tabs follow: **Products**, **Features**, **Packages**, **Unbound Entities (n)**, **Users without Seats (n)** and **Packages without Mode (n)**. @[guided-image](_img/licenses.png) Each row on the three license tabs shows License, Status, Seats (`active / count`, or `active / Unlimited` when no seat count is set, with a usage bar), Assigned and Revoked lifetime counters, Start, Expiry, Billing Ref and the actions. The status tag is computed in a fixed order: **Disabled platform-wide** (mode Disabled) → **Free** → **Disabled** → **Expired** → **Seats full** → **Active**. What you can do here: - **Enable** a license your organization has been allocated. If the product's apps and entities are not yet set up, the confirmation says *enabled — setup in progress* and they appear within minutes. Enabling fails with *Contact your platform operator* when the product has not been allocated to your organization, and with a missing-dependencies message when a prerequisite product is not enabled yet. - **Disable** a license. The confirmation warns that *users will lose access at their next sign-in or session refresh*; in practice entitlements are cached for up to about two minutes, so the cut-off follows within that window. - Open a license name to reach its **Assignments** page — every user seated on it, with Status (Active or Revoked), Assigned, Assigned by, Revoked and Revoked by — and **Revoke** individual seats there. What you cannot do here: seat counts, start and expiry dates and billing references are **not editable in the tenant Setup**. They are set by the platform operator when the license is allocated to your organization; if a seat count or expiry is wrong, raise it with your operator. ## Seats A seat puts one named user on a tenant license. Seats are assigned per user on **Setup → Access Control → Users → the user → License Allocations** (visible with `setup.licensing.admin`, or on your own account): three cards — Products, Features, Packages — each with an **Add a product…** (or feature/package) selector and an **Add license** button, and a revoke action per seat. Free-mode features are not offered because they are granted automatically. Toasts confirm *Seat assigned.* and *Seat revoked.* Rules that always apply: - When a license has a seat count, adding a seat beyond it fails with a seats-exhausted error until you revoke one or the operator raises the count. A license with no seat count is unlimited. - Revoking keeps the assignment in history (the Revoked counters on the Licenses screen) and frees the seat immediately. - Deactivating a user does **not** revoke their seats; include seat cleanup when you [offboard someone](/docs/administration/users/deactivate-a-user/). One honest caveat: whether a *missing* seat blocks access depends on platform-level seat enforcement, which is off by default. With enforcement off, a user with the profile grants can use a licensed feature without a seat, and a license with no seat allocations at all behaves as available to everyone with the grants. With enforcement on, the seat is required and profile assignment validates against it (below). Never conclude a user is seated just because a feature works — check the License Allocations tab. ## How licensing composes with security profiles Licensing and security are independent locks on the same door, and the effective entitlement is the intersection of three things: what the tenant license enables, what the user's profiles grant, and — with seat enforcement — the user's seats. - A user with a seat but no profile grant sees nothing: profiles are the unit of app, entity, field and capability access, and visibility is allowlist-based. - A user with generous profile grants but no seat is blocked only when seat enforcement is on. - Profiles can declare the product and feature licenses they require. With seat enforcement on, assigning such a profile to a user without the matching seats fails validation — allocate the seats first. The user's **Access Diagnostics** tab (next to License Allocations) shows this intersection server-side: the profiles, roles, teams and business units resolved for the user, the product and feature licenses and capabilities they hold, and — side by side — the licenses and capabilities their profiles *require* but they do not hold. Changes to licenses, seats and profiles take effect within the entitlement cache window (about two minutes) rather than strictly at the next sign-in. ## Module switches Operational module settings are separate from commercial licenses. There is deliberately no consolidated module-settings item in the navigation: a module that exposes settings has its own **Settings** entry inside its Feature Hub group (Sales, Service, Inventory, Procurement, Claims, Finance, Portals and so on). A module master switch turned off disables the module for everyone — including users holding licenses and seats — while enabling a switch never supplies a missing license or seat. Check the module's Settings alongside licensing when a whole team loses a module at once. ## Coverage and usage reports The three coverage tabs on the Licenses screen answer "what is not covered yet": - **Unbound Entities** — entities with no owning product or feature. Today entity-level license gating is not enforced, so an unbound entity is usable by anyone with profile access; the list is a review aid for binding entities before gating is switched on. Bind an entity from **Setup → Design Studio → Entities → the entity → Licensing** card (Edit → Owning product, Additional features). - **Users without Seats** — active users who hold no product seat at all. - **Packages without Mode** — installed packages whose licensing mode has not been set. The same three lists, with counts in the header, are available as a standalone **License Coverage** report reached from the Licenses screen. **Setup → Feature Hub → Administration → License Usage** records when licensed functionality was actually exercised: filter by user, usage type, source and date range (last 24 hours, 7 or 30 days); columns are Occurred, Usage Type, Source, User, Email, Profile, Product, Feature and Capability. Events are metered at most once per user per cache window (about two minutes), so the table shows *that* a user used an entitlement, not how many times. It is usage telemetry, not the audit trail — configuration changes are recorded separately. ## Common questions ### A user has a seat but still can't use the feature — why? Work outward through the other layers: the module's own Settings switch may be off, the tenant license row may be Disabled or Expired, the feature's parent product may be disabled, or the user's profiles may not grant the app, entity or capability involved — a seat unlocks nothing by itself. Open the user's Access Diagnostics tab and compare what the user holds with what the profiles require, then follow [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/). Allow up to two minutes after any change for caches to refresh. ### What happens when a license runs out of seats? The Licenses screen shows **Seats full**, and adding a further seat on the License Allocations tab fails until you revoke an existing seat or the platform operator raises the count. Nothing changes for users already seated. Deactivated users keep their seats until you revoke them, so seat cleanup belongs in offboarding. ### Does disabling a license delete anything? No. Disabling removes access, not data or configuration: records, customizations and seat assignments remain, and re-enabling restores access. Because the cut-off reaches users within minutes, treat a disable as a user-facing change and announce it first. ### Can I change the seat count or expiry date myself? No. The tenant Setup exposes Enable, Disable and per-user seat assignment and revocation; seat counts, terms and billing references are maintained by the platform operator who allocated the license. The Licenses screen shows the current values so you can see what to ask for. ## Related topics - [Security profiles](/docs/administration/security-profiles/) - [Invite a user](/docs/administration/users/invite-a-user/) - [Offboard or suspend a user](/docs/administration/users/deactivate-a-user/) - [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/) - [Platform security & governance](/platform/security/) ---- # Record-level security and sharing URL: https://xmatix.com/docs/administration/record-security/ Last reviewed: 2026-09-06 ## Two checks, both must pass Whether a user can work with a specific record is decided by two independent checks: their [security profile](/docs/administration/security-profiles/) must allow the operation on the entity, and record-level security must allow it on that record. A profile grant without record access filters the record out of lists and refuses it on open; record access without a profile grant is refused outright. This page explains the record half: ownership, the entity's sharing policy, and the ways access to individual records is granted. @[guided-image](_img/record-security-context.png) The sharing-policy detail (**Setup → Access Control → Policies → open a policy**) shows everything the runtime uses for one entity: the ownership model, the default access for internal and external users, whether hierarchy, manual sharing and team access are switched on, and the policy's rules. ## Ownership Every record carries an owner, defaulting to its creator. Ownership is the baseline of record access: on a user-owned entity, owners can always work with their own records within their profile's grants. Ownership is also what the role hierarchy rolls up — where the policy enables hierarchy access, users read (and, for write operations, edit) records owned by users whose roles sit below theirs. Ownership is transferred by changing the record's owner, which needs **Update** on the record. The grant matrix also lists an **Assign** operation; the runtime does not currently apply a separate Assign check when the owner changes, so do not rely on withholding Assign to lock ownership. ## The sharing policy Each entity has at most one sharing policy, managed under **Setup → Access Control → Policies**. The list shows every policy with its entity, ownership model and status; open one to see and edit its settings (**Edit Policy**) or add rules (**New Rule**). ![The Policies screen — one record-access policy per entity, each showing its ownership model and status](_img/security-policies.png) | Policy setting | What it decides | | --- | --- | | Entity | The entity this policy governs — one policy per entity. | | Ownership Model | **Organization Owned** — no record filtering at all; only the profile check applies. **User Owned** — records are filtered by owner plus the mechanisms below. **Team Owned** is offered in the form but the runtime currently evaluates it exactly like User Owned. | | Internal Default Access | What internal (staff) users get on records they do *not* own: **Private**, **Read Only** or **Read Write**. | | External Default Access | The same, set separately for external users (portal and partner logins). | | Grant Access Using Hierarchy | Whether users reach records owned by people in roles below theirs in the role tree. | | Allow Manual Share | Whether per-record shares are honoured for this entity. | | Allow Team Access | Whether the user's team memberships count when shares are resolved. | | Active | An inactive policy is ignored, which drops the entity back to the no-policy behaviour described below. | Two defaults matter. Platform entities ship with a `DefaultSharing` policy that is user-owned with **Read Only** defaults for both audiences and hierarchy, manual share and team access enabled — everyone reads everything; writing needs ownership, hierarchy or an elevated grant. Entities *you* create get no policy, and without one the runtime treats the entity as user-owned and **Private** for both audiences with hierarchy, sharing and team access **off** — only owners and **View All** / **Modify All** holders see records. If a new custom entity seems invisible to everyone but its creators, that is why: create its policy. ## How record access composes A user can *read* a record when any one of these holds: - the entity's policy is **Organization Owned**; - one of their profiles carries **View All** for the entity; - the policy's default access for their audience is **Read Only** or **Read Write**; - they own the record; - hierarchy access is on and the record's owner sits in a role below one of theirs; - an enabled **Access Grant** rule with effect **Grant Read** matches the record for their audience (see the rules section below); - manual sharing is on and the record is shared to them — directly, to a role, team or business unit they resolve to, or to all internal or all external users. *Write* (update and delete) access is narrower: it comes from **Organization Owned**, **Modify All**, a **Read Write** default, ownership, hierarchy, a share whose access includes the requested operation, or a matching **Grant Write** rule. **Modify All** is the one grant that skips record filtering entirely for update and delete. Record-level grants are additive; a sharing policy has no deny effect. The only subtractive element is an **Access Filter** rule with effect **Filter Visible Records**, whose predicate is ANDed onto the final query after every grant has been evaluated — see [restriction rules](/docs/administration/restriction-rules/). Composition with profiles works one way only: record-level grants never widen entity access (sharing a record with a user who has no **Read** on the entity achieves nothing), while **View All** and **Modify All** step around record-level scoping. Two details are easy to miss: - **Team access** resolves the user's teams (direct membership and team-member rows) only when the policy enables it; a share aimed at a team is invisible with team access off. - **Business-unit shares** match through the user's roles — a user belongs to a business unit through the roles assigned to them, not through a field on the user. ## Rules on a policy Rules are listed on the policy detail and added with **New Rule**. Each rule has a **Rule Type**, an **Effect**, **Applies To Audience** (All, Internal or External), **Applies To Operations** (Read, Update, Delete or Share — a rule participates only when its operations cover every operation the request needs), a **Priority**, an **Enabled** switch, and then its expressions and targets on the rule's own detail page. | Rule type | Effect | What it does | | --- | --- | --- | | Access Grant | Grant Read / Grant Write / Grant Share | Widens access: records matching the rule's expressions become readable, writable or shareable for the targeted audience. A grant rule with no targets never matches. | | Access Filter | Filter Visible Records | Narrows access: only records matching the expression remain visible, on top of whatever grants allowed. | Targets name who the grant is for — the current user or record owner, all internal or all external users, or a specific role, team or business unit. **Ownership Resolution** and **Principal Expansion** rule types, the **Resolve Owner** effect and the **Specific Principal** audience appear in the form but are disabled; they are not evaluated by the runtime. ## Manual shares A share is an explicit, per-record grant — the escape hatch for exceptions rather than patterns. A share names a principal (a user, role, team, business unit, or all internal or all external users), the record, and the access it grants (read, update, delete, share); it is honoured only while the entity's policy has **Allow Manual Share** on, and shares to teams additionally need **Allow Team Access**. Shares are consulted only when the user's baseline does not already reach every record, so they never reduce access. Share records are administered as security metadata (they require the security-management capability); there is no share dialog on record pages in the current web client. If you find yourself creating the same share repeatedly, encode the pattern as a policy default or an Access Grant rule instead. ## Common questions ### Why can a user see a record but not edit it? Because read and write compose differently. The read likely comes from a **Read Only** default, hierarchy or a share — none of which grants writing. Writing needs ownership, a **Read Write** default, **Modify All**, a share whose access includes update, or a **Grant Write** rule; and independently the user's profile must include **Update** on the entity. Check the profile grant first, then ask which mechanism was expected to allow the write on this particular record. ### Why can nobody else see the records of my new custom entity? Custom entities start with no sharing policy, and the runtime then treats them as private: only each record's owner and **View All** / **Modify All** holders see records, with hierarchy, sharing and team access off. Create the entity's policy under **Setup → Access Control → Policies → New Policy** and choose the defaults you want — **Read Only** for both audiences with hierarchy, manual share and team access on matches the platform's own entities. ### Does sharing a record with someone guarantee they can open it? No. A share grants record access, but the recipient still needs **Read** on the entity from one of their profiles — record grants never widen entity access. The policy must also allow the mechanism: **Allow Manual Share** on, and **Allow Team Access** on if the share targets a team. If a shared record stays invisible, check those in order — see [Why can't a user see something?](/docs/administration/user-cant-see-x/). ### How do managers see their team members' records? Through the role hierarchy, not through teams: managers hold a role above their reports' roles, and each entity's policy has **Grant Access Using Hierarchy** enabled. The roll-up follows record *ownership* downward through the role tree. Teams are a different mechanism — group access to shared records — so putting a manager in the same team as their reports only helps for records shared to that team. ### Does an Organization Owned policy mean everyone can edit everything? It means record-level filtering is skipped; the profile check still applies in full. A user with **Read** but not **Update** on an organization-owned entity sees every record and can edit none. ## Related topics - [Security profiles and the grant matrix](/docs/administration/security-profiles/) - [Roles, teams and business units](/docs/administration/roles-teams-business-units/) - [Restriction rules: scoping what users can see](/docs/administration/restriction-rules/) - [Security scenarios](/docs/administration/security-scenarios/) - [Why can't a user see something?](/docs/administration/user-cant-see-x/) ---- # Resources — the people who do the work URL: https://xmatix.com/docs/administration/resources/ Last reviewed: 2026-10-10 A **resource** is the record for one person who does work in xMatix — a sales executive, service advisor, technician, driver, manager or back-office employee — and it is what every document, visit, timesheet, payslip and expense claim points to when it names "who". The user account decides how someone signs in. The resource decides who they are in the business: which company and branch their documents belong to, who they report to, and how they are paid. You create a resource once per person, usually just after [inviting their user](/docs/administration/users/invite-a-user/). Then you link the two, and every module from CRM to payroll can find them. ## Overview You find resources under **Resources** in the **Platform** app. They also appear in the **Payroll** app, under **People** in the payroll list app, and in the **Rewards** app. All of these open the same records. The list has five views: **All Resource** (the default), **All Active Resource**, **All Managers**, **All Salespersons** and **All Service Advisors**. All Resource shows **Resource Name**, **Resource Id** (the code), **Phone**, **Resource Type**, **Default Partner Account**, **Default Branch**, **Active** and the audit dates. All Active Resource also shows **User**. The resource record page has these tabs: | Tab | What it holds | | --- | --- | | **Resource Availability** | A month calendar of the person's availability and bookings. See [Resource availability and slot holds](/docs/field-service/availability/). | | **Administration** | Two related lists, each with **New**: **Partner Resources**, the dated assignments of the person to a company and branch, and **Resource Compensations**, the person's salary and cost-to-company records. | | **KYC** | The person's KYC documents (KYC Type, Document Type, Document Number, Is Verified), with **New**. | | **Details** | The form, in panels: **Details**, **Banking & Identity Details**, **Default Account**, **Reporting Details**, **Related Party Details** and **System Information**. | The header shows **Code**, **Default Partner Account**, **Default Branch**, **Resource Type**, **Salary Structure** and **Active**, with **Edit** and **Delete**. The page also shows **Sense AI** nudges. ## When to use it Create a resource for everyone who: - signs in and raises documents — leads, orders, invoices, visits, service orders, expense claims; - is assigned work, even if they never sign in — a technician on a job card, a picker, a driver, a subcontractor; - is paid through payroll or claims expenses, advances or loans. A user with no linked, active resource can still sign in. But xMatix does not know who they are in the business: their new documents get no executive and no company or branch from them, they cannot check in on the mobile app, and rules that read resource fields skip them. ## How xMatix handles it ### Who "you" are When you save a record, xMatix looks for **your resource**. That is the active resource whose **User** is your user account. It uses that resource in three ways: - **Your name goes on new records.** A new record that has an empty person field (Executive, Resource, Service Advisor and similar) gets your resource. Some fields are never filled this way because they name someone else on purpose: the technician on a service order or service-order line, the receiver of a transfer, the resource on a timesheet line, route sequences, executive positions, and the assignee of a visit plan that belongs to a route. - **Your company and branch go on new documents.** A new document with no **Partner Account** and no **Branch** gets them from your resource. The order is: 1. Your **Default Partner Account** and **Default Branch**, when both are set. 2. Otherwise, your first current **Partner Resource** assignment (From Date and To Date around today), lowest **Assignment Sequence Number** first. That assignment's company and branch are used together and are never mixed with your defaults. 3. Otherwise, whichever default you do have. If none of these gives a company and your organization has exactly one company, that company is used (the branch stays empty). A document that already has a company or a branch is left alone. - **Your manager and team.** **Manager** and **Skip Manager** are your reporting line. Requests that go to your manager, such as an outlet transfer request, are addressed to the resource in **Manager**. On the mobile app, a manager's team roster lists the active resources whose Manager is them; a person nobody reports to sees only themselves. xMatix remembers which resource belongs to which user for up to ten minutes. Changing **User**, **Active**, **Default Partner Account** or **Default Branch**, or adding or deleting a resource, refreshes the assignment data straight away. If a user still sees the old values, they can sign out and back in. ### Active and effective dates **Active** is the switch that matters. A resource with Active off is no longer "you" for its user. It is also skipped by automatic assignment, refused on documents checked against partner-resource assignments, and refused at mobile check-in. **Effective From Date** and **Effective Till Date** limit the person's validity window for automatic assignment rules only. A resource outside the window is skipped with the reason *not effective yet* or *no longer effective*. Nothing else reads these dates. A past Effective Till Date does not switch the resource off; clear **Active** to do that. ### Where each group of fields is used - **Banking & Identity Details.** Salary payment batches read **Bank Account Number** and **IFSC Code** from the resource. **PAN Number** is the PAN that tax deducted from salary and the TDS returns use. See [Employees and salary structures](/docs/payroll/employees-and-structures/). - **PAN verification.** **PAN Verification**, **PAN Verified On** and **PAN Verification Source** are filled when the bulk PAN verification file is imported on a TDS return. The import stamps every record carrying that PAN as Verified, Invalid or Name Mismatch. See [TDS returns](/docs/finance/tax-center/tds-returns/). - **Related Party Details.** A resource with **Related Party** on — a director, key manager or their relative — is included as a person in the related-party disclosure and the statutory annual reports. - **Labour Cost Rate Per Hour.** It costs the person's working hours in profitability analysis. - **Salary Structure.** It is for reference only. Payroll uses the structure on the person's latest active **Resource Compensation** record. ## Prerequisites - Access to the Resource entity on your [security profile](/docs/administration/security-profiles/) (see [Permissions](#permissions)). - The person's user account, if they will sign in. See [Invite a user](/docs/administration/users/invite-a-user/). - The company (partner account) and the [branch](/docs/administration/branches/) they work from. - The person's manager already set up as a resource, if you want to fill the reporting line now. ## Procedure ### Step 1 — Check that the person does not already have a resource Open the **Platform** app and select **Resources**. Search the list for the person's name or code. Each person should have exactly one resource. A second resource for the same user splits their documents. xMatix also picks one of the two as "you" without a set order. ### Step 2 — Create the resource Select **New**. The create form asks for: - **Name** and **Code**. The code must be unique; use your employee or staff number. - **Resource Type** — Service Advisor, Manager, Salesperson or Labour. It is required. - **Phone**, **Business Hours** and **Active**. Switch **Active** on. A new resource starts inactive, and an inactive resource is invisible to sign-in-based features. On the **Default Information** tab, set **Default Partner Account** and **Default Branch** together, and choose the person's sign-in account in **User**. On the **Reporting Details** tab, choose **Manager**, **Skip Manager** and, if you use it, **Parent Resource**. Save. The record page opens. ### Step 3 — Complete the details Select **Edit** and fill the panels on the **Details** tab: 1. **Details** — Department, Designation, Joining Date, Employment Type and Grade. 2. **Banking & Identity Details** — Bank Account Number, IFSC Code, PAN Number, Aadhaar Number, UAN, PF Account, Salary Structure and Labour Cost Rate Per Hour. Fill these if the person is paid through payroll or reimbursed by bank transfer. 3. **Related Party Details** — only if the person is a related party (see Step 6). Save. ### Step 4 — Assign companies and branches If the person works for one company at one branch, the **Default Partner Account** and **Default Branch** from Step 2 are enough. If they work across several companies or branches, open the **Administration** tab. Under **Partner Resources**, select **New** for each assignment, with its **Partner Account**, **Branch**, **From Date**, **To Date** and **Assignment Sequence Number**. Documents use the lowest-numbered current assignment when the person has no complete default pair. Keep the From Date and To Date current: on documents such as orders, invoices, deliveries, purchase documents, transfers and cycle counts, a person whose assignments for the document's company or branch have all expired is refused (see [Common problems](#common-problems)). Assignment rules for automatic owner selection are also configured on partner resources. See [Automatic owner assignment](/docs/field-service/assignment-rules/). ### Step 5 — Add pay and KYC records On the **Administration** tab, under **Resource Compensations**, select **New** to record the person's CTC, salary structure and Effective From date. See [Employees and salary structures](/docs/payroll/employees-and-structures/). On the **KYC** tab, select **New** to add each identity, address or income proof, with its **KYC Type**, **Document Type** and **Document Number**. ### Step 6 — Mark a related party Under **Related Party Details**, switch **Related Party** on. Choose the **Related Party Type**, describe the **Relationship**, and set **Related Party From** and, if the relationship has ended, **Related Party To**. Save. ### Step 7 — Change the reporting line or company Open the resource, select **Edit**, change **Manager**, **Skip Manager**, **Default Partner Account** or **Default Branch**, and save. New documents use the new values. Documents that already exist keep the company and branch they were saved with. For a move with an end date, add a new dated **Partner Resource** instead of overwriting the default. ### Step 8 — Deactivate someone who leaves Open the resource, select **Edit**, switch **Active** off, and save. Their history stays: past documents, payslips and claims still point to them. Deactivate the user account as well. See [Offboard a user](/docs/administration/users/deactivate-a-user/). Avoid deleting a resource that has history. ## Fields The fields on the record page, in form order. | Field | What it means | Notes | | --- | --- | --- | | **Name** | The person's name as it appears in pickers and on documents. | Required. | | **Code** | The person's staff or employee number. | Required and unique. Shown as Resource Id in the list. It is a plain code; the payroll Employee record links to the resource, not to this code. | | **Resource Type** | The person's role: Service Advisor, Manager, Salesperson or Labour. | Required. Drives the All Managers and All Service Advisors views. | | **Department** | Department: IT, HR, Sales or Finance. | Picklist; extendable. | | **Designation** | Job title: Software Engineer, HR Executive, Sales Executive or Sales Executive Financial Analyst. | Picklist; extendable. | | **Phone** | Contact phone number. | | | **Joining Date** | The date the person joined. | Recorded for HR; not read by calculations. | | **Employment Type** | Permanent or Contractual. | Payroll uses the employment type on the Employee record instead. | | **Grade** | The person's grade. | Lookup. | | **Bank Account Number** | The account salary and reimbursements are paid to. | Read when a salary payment batch is generated. | | **IFSC Code** | The bank branch code for that account. | | | **PAN Number** | The person's PAN. | Used for salary TDS, TDS returns and PAN verification. | | **Aadhaar Number** | The person's Aadhaar number. | | | **UAN** | Provident fund universal account number. | | | **PF Account** | Provident fund account number. | | | **Salary Structure** | A salary structure for reference. | Not used by payroll — the Resource Compensation record decides. | | **Labour Cost Rate Per Hour** | What an hour of this person's time costs. | Used to cost hours in profitability analysis. | | **Default Partner Account** | The company this person normally works for. | Only partner accounts (companies) are offered. Must be set together with Default Branch. | | **Default Branch** | The branch this person normally works from. | Only the chosen company's branches are offered. Must be set together with Default Partner Account. | | **User** | The sign-in account of this person. | Leave empty for people who never sign in. Link each user to one resource only. | | **Active** | Whether the resource is in use. | Starts off. Only an active resource is "you" for its user. | | **Manager** | The person's direct manager, as another resource. | Used for manager approvals and the mobile team roster. | | **Skip Manager** | The manager one level above. | For skip-level approvals and escalation. | | **Parent Resource** | A parent in a resource structure, separate from the reporting line. | Optional. | | **Business Hours** | The person's own working hours. | Takes precedence over the branch's hours, for example for the attendance time zone. | | **Related Party** | Marks the person as a related party of your organization. | Switch it on before choosing a type. | | **Related Party Type** | Director, Key Management Personnel, Relative of Director / KMP, Holding Company, Subsidiary Company, Fellow Subsidiary (Sister Concern), Associate / Joint Venture, Entity Controlled by Director / KMP, Promoter or Other. | Required when Related Party is on; refused when it is off. | | **Related Party From** | When the relationship began. | | | **Related Party To** | When the relationship ended. | Cannot be before Related Party From. | | **Relationship** | A short description of the relationship. | | | **Created By**, **Created Date**, **Modified By**, **Modified Date** | Audit details. | Read-only. | The resource also carries fields that are not on the shipped form but can be added to it, or are filled by xMatix: **Effective From Date** and **Effective Till Date** (see [Active and effective dates](#active-and-effective-dates)), **PAN Verification**, **PAN Verified On** and **PAN Verification Source** (filled by the PAN verification import), **IncentiveResourceGroup** (a resource group for incentives), **Is Eligible for PT**, **ResourceType** (a free-text classification some organizations use in filters), **Resource Label** and **External** (an identifier from another system; unique). The [Resource reference](/docs/reference/entities/resource/) lists them all. ## Business rules - **Default company and branch go together.** Saving a resource with only one of the two is refused: *"Resource '…' has a default branch but no default partner account."* or *"Resource '…' has a default partner account but no default branch."* - **Code is unique.** Two resources cannot share a **Code**, and two cannot share an **External** identifier. - **Effective dates.** **Effective Till Date** must be after **Effective From Date**. A same-day or earlier date is refused with *"Effective Till Date cannot be before Effective From Date"*. - **Related party consistency.** A related party needs a type, a type needs Related Party switched on, the type must be one of the listed values, and Related Party To cannot be before Related Party From. - **Lookup filters.** **Default Partner Account** offers only partner accounts; **Default Branch** offers only that company's branches. - **Documents check the person's assignment dates.** Documents such as orders, invoices, credit notes, delivery orders, fulfilments, requisitions, purchase orders, transfers and cycle counts check the person they name. The check passes when the document's company and branch are the person's default pair. It also passes when the person has no partner-resource assignment for that company or branch, or has a current assignment that covers them. An assignment with no company and no branch covers everything. The check fails when the person's assignments for that company or branch are all outside their From Date and To Date on the document date, or when the resource is inactive. It runs when the document is created, and again when its person, company or branch changes. - **Audit.** Changes to resources are audited. ## Example A distributor opens a second depot and hires a sales executive for it. 1. The administrator invites `asha.verma@example.com` as a user. 2. In **Platform → Resources**, they select **New** and enter **Name** *Asha Verma*, **Code** *EMP-0142*, **Resource Type** *Salesperson* and **Phone**, and switch **Active** on. On **Default Information** they pick **Default Partner Account** *Riverbend Distributors*, **Default Branch** *East Depot* and **User** `asha.verma@example.com`. On **Reporting Details** they pick **Manager** *Ravi Menon*. They save. 3. On **Details** they add Department *Sales*, Designation *Sales Executive*, Joining Date, Employment Type *Permanent*, and her bank account, IFSC and PAN. 4. On **Administration → Resource Compensations**, payroll adds her CTC and salary structure from her joining date. 5. Asha signs in on the mobile app and creates an order. It is saved with Executive *Asha Verma*, company *Riverbend Distributors* and branch *East Depot* without her picking them. Ravi sees her on his team roster. ## Training ### Practice exercise In a sandbox: 1. Create a resource *Trainee One* with a unique code, Resource Type *Salesperson*, and Active on. Set **Default Partner Account** to a company that has branches, but leave **Default Branch** empty. Save. **Expected:** the save is refused with *"Resource 'Trainee One' has a default partner account but no default branch."* 2. Choose one of the company's branches and save. **Expected:** the record saves, and the header shows the company and branch. 3. Set **User** to a test user, sign in as that user and create a lead, leaving **Partner Account**, **Branch** and **Executive** empty. **Expected:** the lead is saved with the resource's company and branch, and an executive — the resource itself unless a partner-resource assignment picks someone else. 4. Switch **Active** off on the resource, sign in again as the test user and create another lead the same way. **Expected:** the company and branch are no longer taken from the resource. Unless your organization has only one company, or the lead has a postal code that routes it, the save is refused with *"A partner account is required unless the lead carries a postal code for geographic routing."* ### Quick reference - One person, one resource, one user — never two resources for the same user. - Switch **Active** on; new resources start inactive. - **Default Partner Account** and **Default Branch** are set together or not at all. - Several companies or dated moves → **Administration → Partner Resources**. - Pay comes from **Resource Compensations**, not from the Salary Structure field. - Bank details and PAN live on the resource, not on the Employee record. - To stop someone, switch **Active** off — an end date alone does not. ## Permissions Access is set on [security profiles](/docs/administration/security-profiles/): - **Entity access.** The shipped *Sales*, *Sales Executive*, *Service*, *Standard User* and *System Admin* profiles have full access to Resource. *Sales Manager* has every operation except View All. - **Record access.** Resources are owned records. Without View All, a user sees the resources they own plus what the role hierarchy and sharing give them. This is why ordinary users cannot browse everyone's resource record. - **Actions.** **New**, **Edit**, **Delete**, **Clone** and bulk delete are granted on the shipped *Sales Executive*, *Sales Manager*, *Standard User* and *System Admin* profiles. Grant an action on the profile's **Actions** tab. - **Field access.** Bank, PAN and Aadhaar fields can be restricted per profile on the profile's field permissions if not everyone who manages resources should see them. ## Configuration - **Where resources appear.** Resources are in the **Platform**, **Payroll** and **Rewards** apps. Add or remove the menu item in the app's navigation in Design Studio. - **Form, record page and views.** The create form (*Resource Create*), the record page (*View Resource*) and the five list views are layouts and views you can change in Design Studio. To expose **Effective From Date**, **Effective Till Date**, the PAN verification fields or **IncentiveResourceGroup**, add them to the layout. The record page can also host the **Clone**, **TDS Work Sheet** (a read-only month-wise salary TDS worksheet comparing the old and new regimes) and **Latest Form 16** actions, which the shipped header does not show. - **Picklists.** Resource Type, Department, Designation, Employment Type and Related Party Type can be extended in the entity's field settings. If you rename a Resource Type value, update the views and rules that filter on it. - **Validation.** The effective-date rule is an entity validation you can see under the entity's validations. - **Security assignment.** **Setup → Access Control → Security Assignment** grants security profiles and team memberships from a person's resource fields. For example, every Manager-type resource can get a manager profile. **Test condition** shows how many linked users match; **Re-evaluate all** previews and then applies the rules to everyone; the **History** tab lists every change. Rules apply by themselves when a resource is linked to or unlinked from a user, and when a field the rule reads changes. They do nothing for users with no linked resource, and they never grant an administrator profile. - **Partner resources and assignment.** Dated company and branch assignments, and the rules that pick an owner automatically, are on partner resources. See [Automatic owner assignment](/docs/field-service/assignment-rules/) and [Selling scope](/docs/field-sales/selling-scope/). - **Single-location organizations.** When you run one company or one location, xMatix hides the partner account and branch fields, and the sole company fills documents. See [Branches](/docs/administration/branches/). - **Payroll.** Compensation, salary structures and the Employee record are configured in the Payroll app. See [Employees and salary structures](/docs/payroll/employees-and-structures/). ## Common problems ### "Resource '…' has a default branch but no default partner account." The resource has a **Default Branch** but no **Default Partner Account**. Choose the company the branch belongs to, or clear the branch. ### "Resource '…' has a default partner account but no default branch." The resource has a company but no branch. Choose one of the company's branches, or clear the company and use a **Partner Resource** assignment instead. ### "Effective Till Date cannot be before Effective From Date" The till date is the same as or earlier than the from date. Set a later Effective Till Date, or clear it. ### "A related party must have a relationship type (director, relative, sister concern, …)." **Related Party** is on but **Related Party Type** is empty. Choose a type, or switch Related Party off. The reverse — a type with Related Party off — is refused with *"Related party type can only be set when the record is marked as a related party."* ### "Resource is not authorized for Partner Account '…'." or "Resource is not authorized for branch '…'." The person's partner-resource assignments for that company or branch do not cover the document date, or the resource is inactive. Open the resource and check **Active**, and the **From Date** and **To Date** of the matching assignment under **Administration → Partner Resources**. Extend the assignment, add a current one, or set that company and branch as the person's default pair. Otherwise, pick a person who works there now. ### My new documents get no company, branch or executive Your user has no active resource. Ask an administrator to open your resource, set **User** to your account and switch **Active** on. If both are already right, check that the resource has a company — a default pair or a current partner resource. Changes are picked up within ten minutes. ### "No active Resource is linked to your user account." The mobile app shows this when you check in without an active resource linked to your user. The fix is the same as above. ### The All Salespersons view is empty The shipped view filters on the Resource Type value *Sales Persons*, while the shipped picklist value is *Salesperson*. Use **All Resource** and filter **Resource Type** to *Salesperson*, or ask an administrator to correct the view's filter. ## Common questions ### Is a resource the same as a user? No. A user account is how someone signs in; a resource is the person in the business. A person who signs in needs both, linked through the resource's **User** field. A technician or driver who never signs in needs only a resource. Every document, timesheet, payslip and claim refers to the resource, so a person's history stays complete even if their user account is replaced or deactivated. Keep one resource per person and one user per resource. xMatix does not prevent a second link, but it then picks one of the two resources as "you" without a set order. ### Why did my order get a different company than my default? Your defaults are used only when both **Default Partner Account** and **Default Branch** are set. If one is missing, your first current **Partner Resource** assignment wins — its company and branch together. Also, a document that already carries a company or branch, for example from the customer or the visit, keeps it. Check the resource's **Default Account** panel and its **Administration → Partner Resources** list. ### Does the resource decide what the person is paid? Not directly. Payroll reads the person's latest active **Resource Compensation** record and its salary structure. The resource's own **Salary Structure** field is for reference. What the payroll run does read from the resource is the identity it pays and reports against: bank account, IFSC and PAN. Add a new compensation record for a raise rather than editing the resource. ### What happens to someone's records when they leave? Nothing is removed. Switch **Active** off on the resource and deactivate the user account. Their past documents, payslips, claims and timesheets still point to the resource, and reports still show them. They stop being offered for automatic assignment, and their user no longer acts as them. Run the [full and final settlement](/docs/payroll/full-and-final/) in payroll as well. ## Related topics - [Invite a user](/docs/administration/users/invite-a-user/) and [User accounts](/docs/administration/users/user-accounts/) - [Branches](/docs/administration/branches/) - [Automatic owner assignment](/docs/field-service/assignment-rules/) - [Selling scope and partner account mappings](/docs/field-sales/selling-scope/) - [Resource availability and slot holds](/docs/field-service/availability/) - [Employees and salary structures](/docs/payroll/employees-and-structures/) - [Security profiles](/docs/administration/security-profiles/) - [Resource reference](/docs/reference/entities/resource/) ---- # Restriction rules: scoping what users can see URL: https://xmatix.com/docs/administration/restriction-rules/ Last reviewed: 2026-09-06 You scope what users can see through the entity's security policy: tighten its default access so records are no longer broadly visible, then attach rules that grant back exactly the slices each group should see. This page walks the pattern for a common goal — each business unit sees only its own records — with the draft, test, enable discipline that keeps it safe. Every screen involved lives under **Setup → Access Control → Policies**. ## Prerequisites - The security-administration capability (`setup.security.manage`) on one of your profiles. - Profile **Read** on the entity for every affected user — rules never widen entity access, they only decide which records show ([security profiles](/docs/administration/security-profiles/)). - Business units in place, with users resolving into them through roles ([roles, teams and business units](/docs/administration/roles-teams-business-units/)). - A plan for the blast radius: a tightened default hides records organization-wide except from owners, hierarchy managers, grantees and **View All** holders. ## How the pieces fit Each entity has at most one **policy**. It sets the ownership model, the default access for internal and external users, and three switches — hierarchy access, manual sharing and team access. First-party entities ship with a policy named `DefaultSharing` whose defaults are **User Owned**, **Read Only** for both audiences, and all three switches on: everyone reads everything, writes need ownership, hierarchy or **Modify All**. An entity you create has no policy at all, and the runtime then behaves as User Owned and **Private** with every switch off — only owners and **View All** / **Modify All** holders see records. A policy owns **rules**. Each rule has a type and an effect, an audience, a priority, and two child collections: **expressions** (the condition that selects records) and **targets** (the principals who benefit). A record is readable when any one path grants it: the profile's **View All** mask, the policy default, ownership or hierarchy roll-up, an enabled rule whose expression matches and whose target includes the user, or a manual share. ## Procedure ### Step 1 — Open the entity's policy Go to **Setup → Access Control → Policies** and find the row whose **Entity** column names your entity — match the entity, not a similar-looking policy name; each entity has exactly one policy, so edit it rather than creating a duplicate with **New Policy**. Open the policy name. The detail page header summarises Entity, Ownership, Internal Access, External Access, Status, Hierarchy Access, Manual Share and Team Access, followed by the **Rules** table (Name, Type, Effect, Audience, Priority, Enabled, Description, Modified). Note the current values before changing anything so rollback is unambiguous. @[guided-image](_img/policy-detail.png) ### Step 2 — Tighten the default access Select **Edit Policy**. The dialog holds Entity, **Ownership Model** (Organization Owned, User Owned, Team Owned — Team Owned currently evaluates as User Owned), **Internal Default Access** and **External Default Access** (Private, Read Only, Read Write), **Grant Access Using Hierarchy**, **Allow Manual Share**, **Allow Team Access** and **Active**. Set **Internal Default Access** to **Private**; leave **Grant Access Using Hierarchy** on only when managers should inherit visibility into their reports' records, and keep the share switches on if you rely on manual or team sharing. This is the high-impact step: as soon as you save, broad baseline visibility disappears and access is reconstructed from ownership, hierarchy, shares and enabled rules. Confirm the header now shows *Private*. ### Step 3 — Create the rule, disabled Select **New Rule**. In the **New Security Rule** dialog: @[guided-image](_img/new-rule-dialog.png) - **Name** — state population and beneficiary, for example `West records → West business unit`. - **Rule Type** — **Access Grant** (the other selectable type, **Access Filter**, narrows what the default exposes; the greyed types are reserved). - **Effect** — **Grant Read**. Grant Write and Grant Share exist as effects, but rule *targets* can only carry a Read grant today, so read is what a rule can deliver. - **Applies To Audience** — **All**, **Internal** or **External**. - **Applies To Operations** — fixed by the effect (*Read (1)* for Grant Read; the dialog says *This effect has a fixed operation scope*). - **Priority** — default 100; lower numbers evaluate first. Give related rules a deliberate order. - **Description** — optional, shown in the Rules table. - **Enabled** — on by default: **untick it** while authoring so incomplete logic cannot affect live access. - **Stop Processing On Match** — leave off unless a later rule must be skipped once this one matches. **Create** adds the row to the Rules table with *Disabled* in the Enabled column. Open the rule name to reach its detail page with the **Expressions** and **Targets** tabs; **Edit Rule** reopens the dialog. ### Step 4 — Add the condition On the **Expressions** tab add an expression: **Expression Mode** *Formula*, **Return Type** *Boolean*, and the formula itself — for example `Region == "West"`. Formulas use the record's fields by name (`Region`, `OwnerId`), the current-user tokens `User.Id`, `User.Email` and `User.IsExternal`, `Env.UtcNow`, comparison operators and `AND`/`OR`/`NOT` (or `&&`/`||`/`!`). A formula cannot reference the current user's business unit, so "each unit sees its own records" is one rule per unit: the condition picks the unit's records, the target picks its people. The expression is validated when saved and stamped in the table's **Validation** column — confirm **Valid** and read **Validation Message** if not. An **Invalid** expression does *not* block saving; the rule simply never grants, which is easy to miss. ### Step 5 — Add the target On the **Targets** tab add a target: **Target Type** is one of **Current User**, **Owner**, **Team**, **Role**, **Business Unit**, **All Internal** or **All External**; the group types open a picker for the concrete team, role or unit, which the table shows as *Static Target Id*. **Grant Mask** is **Read (1)** — the only value the current release accepts. Choose **Business Unit** and pick the unit. Users resolve into a unit through their active roles, so a user with no role anchored to the unit is not a beneficiary. ### Step 6 — Test, then enable With the rule still disabled, sign in as a test user holding only the affected profile and a role in one unit; confirm the tightened baseline — only owned records (plus hierarchy roll-up, if left on) show. Then **Edit Rule**, tick **Enabled**, and re-test: a West user sees their own plus West records; a user in another unit sees none of West's; a **View All** holder still sees everything. Repeat Steps 3–5 for each remaining unit. ### Step 7 — Know the rollback switches If a rule misbehaves, disable that rule first (**Edit Rule** → **Enabled** off) and repeat the test-user checks; its grant stops while the policy and the other rules stay intact. Deactivating the whole policy (**Edit Policy** → **Active** off) is the larger emergency lever because it removes every rule from evaluation and drops the entity back to the no-policy behaviour described above — Private with every switch off — so use it only when the baseline itself is unsafe. Restoring the previous default access is the true rollback of Step 2. ## Expected result The entity policy is active with a Private internal baseline, every grant rule has a *Valid* expression and an explicit target, and test accounts see exactly their permitted slice. A user outside the target group cannot see the granted records, while ownership, hierarchy access (if enabled) and **View All** continue to behave as before. ## Common problems **The rule grants nothing.** Check in order: the rule is Enabled; the expression is *Valid*; the rule's audience matches the user (Internal/External); the target names the right unit, team or role; the users resolve into it through an *active* role; and they hold profile **Read** on the entity — without that, no rule can surface records. **Users see more than intended.** Another path is still open: **View All** on a profile, a default that was never actually set to Private, hierarchy roll-up, an existing manual or team share, or an organization-owned entity, where record filtering does not apply. **Users report a denial instead of a shorter list.** An explicit "not allowed to perform 'Read'" error means the profile layer refused the entity itself — a missing profile or entity grant, not a rule effect. Work through [Why can't a user see something?](/docs/administration/user-cant-see-x/). **Saving the rule failed with "Effect … is not valid for rule type".** Effects are tied to rule types: Access Grant takes the Grant effects, Access Filter takes Filter Visible Records. Pick the pair the dialog offers. ## Common questions ### Can a rule say "the current user's business unit" directly? No. Formulas expose only `User.Id`, `User.Email` and `User.IsExternal` as current-user tokens, so unit scoping is one rule per unit: a condition selecting that unit's records, targeted at that unit. More rows, but each rule stays independently testable, and one unit's scope can be disabled alone. ### Do restriction rules apply to administrators? Not to holders of **View All** or **Modify All** on the entity — those profile masks bypass record-level scoping by design. If scoping must apply to a group, make sure its profiles do not carry the bypass masks; keep those for genuine administrators, and expect your own admin view to differ from scoped users' views. ### Can a rule grant editing, not just viewing? Not in the current release — rule targets accept only the Read grant mask. Write on scoped records still comes from ownership, a Read Write default, hierarchy roll-up, **Modify All**, or a manual share. If a group must edit records they do not own, ownership or sharing is the mechanism today. ### Can a rule apply only to portal users? Yes. Set **Applies To Audience** to **External**, or target **All External**, and give the policy a separate **External Default Access**. Internal and external defaults are independent, so employees can keep Read Only while portal users stay Private plus whatever rules grant them. ## Related topics - [Record-level security and sharing](/docs/administration/record-security/) - [Roles, teams and business units](/docs/administration/roles-teams-business-units/) - [Security scenarios](/docs/administration/security-scenarios/) - [Why can't a user see something?](/docs/administration/user-cant-see-x/) ---- # Roles, teams and business units URL: https://xmatix.com/docs/administration/roles-teams-business-units/ Last reviewed: 2026-09-06 Roles, teams and business units are the organizational constructs behind record visibility in xMatix. None of them grants operations — what a user can *do* always comes from [security profiles](/docs/administration/security-profiles/). They decide *whose records* a user can see: roles through the management hierarchy, teams through group sharing, business units by giving both an address that shares and rules can target. All three are managed under **Setup → Access Control** (the `setup.security.manage` capability) on the **Roles**, **Teams** and **Business Units** screens. ## The three constructs at a glance | Construct | Use it for | It never | | --- | --- | --- | | Role | manager roll-up: seeing records owned by people below you; a target for rules and shares | grants create/read/update/delete by itself | | Team | shared record access for a working group; approval pools; report and dashboard visibility | grants create/read/update/delete by itself | | Business unit | the organizational tree that roles and teams anchor to; a target for shares and rules | owns records or partitions data by itself | ## Roles and the hierarchy Roles form a tree: each role can point to a **Parent Role**, and the **Roles** screen renders the tree as an indented, collapsible hierarchy (columns Name, Label, Description, Business Unit, Active, Modified). Where an entity's security policy has **Grant Access Using Hierarchy** enabled, a user can read records owned by users in roles *below* theirs — managerial roll-up. The grant flows downward only: ancestors see descendants' records, never the reverse or sideways. @[guided-image](_img/security-roles.png) **New Role** (and Edit) asks for Name, Label, Description, **Business Unit**, **Parent Role** and Active. Opening a role shows its summary (Name, Label, Status, Business Unit, Parent Role) and three tabs: **Assignments** — the users holding the role, each with a **Primary Role** flag and Active state, added with the **User** picker — plus **Reports** and **Dashboards**, which list the analytics content whose visibility has been granted to this role. A user can hold several roles, one marked primary. A role anchored to a business unit is how users acquire business-unit membership, because users are never assigned to a unit directly. Operational notes: - Roles carry no permissions; they act through hierarchy roll-up and as rule and share targets. - Inactive roles, and inactive role assignments, drop out of hierarchy resolution — and take unit membership with them. - The platform does not reject a cyclic parent chain; avoid creating one when re-parenting. - Before deleting a role, re-point its child roles, its user assignments, and any policy rule that targets it. ## Teams A team is a reusable group of users. The **Teams** screen lists Name, Label, Description, Business Unit, Active and Modified; **New Team** asks for Name, Label, Description, an optional anchoring Business Unit and Active. A team's detail page has the same **Assignments**, **Reports** and **Dashboards** tabs as a role, without the primary flag. Teams act wherever a group beats naming individuals: - **Shared record access** — where the entity's policy has **Allow Team Access** on, records shared to the team are visible to its members. - **Rule targets** — a policy rule can name a team as beneficiary ([restriction rules](/docs/administration/restriction-rules/)). - **Approval pools** — approval steps can resolve approvers from a team. - **Report and dashboard visibility** — analytics content can be granted to a team instead of user by user. - **Mobile rollout groups** — teams can gate who receives mobile preview builds, so renaming or deactivating a team can silently change who gets them. One nuance: membership for approval routing is stored separately from membership for record access. A user added on the team's Assignments tab shares the team's records but is not automatically an eligible approver for steps that route to the team; when a team serves as an approval pool, verify that the new member resolves as an approver on the step. ## Business units Business units form their own tree (**Parent Business Unit**) and map the organization: regions, divisions, departments. The **Business Units** screen lists Name, Label, Description, Active and Modified; a unit's detail page shows its Parent Unit and three tabs — **Child Units**, **Roles** and **Teams** — listing what is anchored to it. Roles and teams attach to a unit through their **Business Unit** field, and users belong to a unit *through their active roles*: there is no business-unit field on the user account. Business units matter in two places: records can be shared to a unit, granting access to every user whose roles resolve to it; and policy rules can target a unit — the standard way to say "this unit's people see this slice". What business units do *not* do: they never partition data by themselves — creating a unit changes nobody's visibility until a share, rule or role structure references it. Per-*company* data separation in a multi-company organization is a different mechanism — per-user company access on the user account — not business units ([tenants and companies](/docs/concepts/tenants-and-companies/)). ## Choosing the right construct | If the question is… | Reach for | | --- | --- | | What operations may this user perform? | a security profile | | Which records should roll up to a manager? | roles and the hierarchy | | Which working group needs the same records? | a team | | What organizational boundary should sharing or a rule target? | a business unit | | How is access evaluated for this entity? | the entity's security policy | ## Common questions ### Do roles or teams grant permissions? No. Entity, field, app and action permissions come exclusively from security profiles. Roles and teams only influence which *records* a user can see — through hierarchy roll-up, shares and rule targets — and only where the entity's policy has those mechanisms switched on. If a user cannot open an entity at all, no role or team assignment fixes it; the missing piece is a profile grant. ### How does a user end up in a business unit? Only through roles: a user's business units are the units of their active roles. To place someone in the West unit, assign them a role whose Business Unit is West — and note that deactivating that role or assignment, or clearing the role's Business Unit, silently removes the membership and any unit-targeted access. Audit role anchors before reorganizing the role tree. ### When should I use a team instead of a business unit? Use a team when a working group — often cross-functional, sometimes temporary — needs shared access to the same records: a project crew, a key-account pod, an approval pool. Use a business unit when the boundary is organizational and durable — a region or division — that roles anchor to and rules and shares target. Teams hold members directly; business units are only reached through roles. ### Where do I see who is in a role or team? Open the role or team from its list and read the **Assignments** tab. The same memberships appear per user on **Setup → Access Control → Users → the user → Role Assignments / Team Assignments**, and the user's **Access Diagnostics** tab shows the resolved roles, teams and business units together. ## Related topics - [Security profiles and the grant matrix](/docs/administration/security-profiles/) - [Record-level security and sharing](/docs/administration/record-security/) - [Restriction rules: scoping what users can see](/docs/administration/restriction-rules/) - [Security scenarios](/docs/administration/security-scenarios/) - [Invite a user](/docs/administration/users/invite-a-user/) ---- # Sandboxes and promoting changes URL: https://xmatix.com/docs/administration/sandboxes/ Last reviewed: 2026-09-06 A sandbox is an isolated copy of your xMatix tenant — its own sign-in address, its own database — where you can change configuration and test against production-like data without touching production. Changes you want to keep are bundled as a **DeltaPack** inside the sandbox and applied to production as a reviewed, deliberate step. This page covers the sandbox lifecycle (create, sign in, refresh, delete) and the DeltaPack round trip. ## Prerequisites - The sandboxes feature enabled for your organization by the platform operator, and the `setup.sandboxes.manage` capability on your profile. When the feature is off, the screens state *Sandboxes are not enabled for this tenant*; the screens are also hidden while you are signed in to a sandbox (a sandbox cannot be forked). - A sandbox quota with a free slot. The counter *Using X of Y sandboxes* appears inside the **New sandbox** dialog, and **New sandbox** is disabled when the cap is reached. Quotas also cap refreshes per day and may forbid data copy altogether. - To copy business data (not just configuration), an **approved copy profile** for each entity you want copied — managed at **Setup → Platform Operations → Sandboxes & DeltaPacks → Sandbox Copy Profiles** and grouped into **Sandbox Copy Profile Sets** (capability `setup.sandboxcopyprofiles.manage`). A profile names the entity, a filter, an order, a row cap and how sensitive fields are handled (copy, mask or blank); it must be **Approved** before any sandbox may use it. - For promotion: `setup.deltapacks.manage` in the sandbox and `setup.deltapacks.inbound.manage` on production, with the DeltaPacks feature enabled. ## Procedure ### Step 1 — Create the sandbox Go to **Setup → Platform Operations → Sandboxes & DeltaPacks → Sandboxes**. The list shows Ordinal (`s1`, `s2`…), Status, Server, Database, Plan, Created, Last refreshed and Subscription key. Select **New sandbox**. @[guided-image](_img/new-sandbox-dialog.png) Read the usage counter, give the sandbox a **Display name** that states its purpose (optional, up to 80 characters), and choose **What to copy**: | Option | What the sandbox gets | | --- | --- | | **Metadata only** | The full configuration model — entities, fields, layouts, scripts, custom components, reports, dashboards, rules — and no business data. | | **Copy everything** | Every data entity, using an approved copy profile where one exists and a default of the newest 1,000 rows by id, without dependency expansion, elsewhere. | | **Use a copy profile set** | A named set of approved profiles as the copy plan; the set is rejected if it is empty or contains an unapproved profile. | | **Pick entities individually (advanced)** | A table where you add entities, choose an approved copy profile per entity and optionally a *Top N* override that may only lower the profile's cap. | The three data options are disabled when your quota does not allow data copy. Choose the smallest scope that proves what you need to test — metadata only for configuration work — then select **Create**. Creation is a background job; the dialog closes and the sandbox detail page opens. ### Step 2 — Follow provisioning to Active The detail page (**Sandbox s{n}**) shows Status, Ordinal, Plan, Server, Database, a copyable Subscription key, Created and Last refreshed, and a **Provisioning job** card whose steps run **Queued → Resolve placement → Provision tenant → Export metadata → Export scripts & components → Export layouts & reports → Apply seed pack → Copy data → Recompute indices → Publish status**, with Job ID, Phase, Progress, Started, Finished and a log tail; it refreshes every few seconds. Expect minutes — a whole tenant is provisioned, and data copy adds time in proportion to the plan. Do not create a second sandbox because the first looks slow; that consumes another quota slot. The list row moves **Provisioning → Active**; treat anything else (*ProvisioningFailed*, *Failed*) as not usable and read the job message. ### Step 3 — Sign in and enable colleagues The sandbox has its own address: your organization's sign-in host with the ordinal appended on the sandbox domain — for example an organization at `acme.` reaches sandbox 1 at `acme-s1.sandbox.`. The address is not displayed in Setup; your platform operator can confirm it. Sign in with the same credentials as production. Every copied user account arrives **inactive and unprovisioned** except the administrator who created the sandbox, who is enabled with administrator rights. Colleagues who need access are enabled *inside the sandbox* through the normal user edit flow ([invite a user](/docs/administration/users/invite-a-user/)); activating them provisions their sandbox sign-in. Integrations copied from production still point at production endpoints — re-target them in the sandbox before running any flow that calls out. ### Step 4 — Build a DeltaPack with your changes Inside the sandbox, go to **Sandboxes & DeltaPacks → DeltaPacks** and select **New DeltaPack**: Name (required), Description, and the **Target tenant** (the parent production tenant by default, or a sibling sandbox). On the pack's detail page, **Add items** — pick by kind or from the metadata tree — for every configuration object to promote: entities and fields, views, relations, layouts, server actions, record types, validations, approval processes, business rules, security rules, archive rules, scripts, custom components, reports, dashboards, global picklists, apps, security profiles, roles and teams, messaging templates, localization resources, AI agents and models, data models, datasets, settings, module enablement and copy profiles. DeltaPacks carry metadata only — never business records. When the item list is complete, select **Build**: the pack moves from **Draft** to **Ready** and shows Built by, Built, payload size and hash; **View payload** lets you inspect exactly what will be applied. A Ready pack can be **Rebased to Draft** to change its items; an Applied, Undone or Failed pack can be **Cloned as new draft**. ### Step 5 — Review and apply on production On the production tenant, **Sandboxes & DeltaPacks → Inbound DeltaPacks** lists every non-draft pack targeting it, with Status, Items, **Drift**, Built by/Built and Applied by/Applied. Open the pack: review its items and payload, and read the *physical changes* banner, which flags schema-affecting changes per entity field as Breaking or Warning. Select **Apply to this tenant**. Status moves to **Applying** and then **Applied** (or **Failed** with an error, where **Retry apply** re-queues it). Apply writes metadata; it does not run business rules or scripts. After applying, **Check drift** compares production with the pack's after-image and reports *Clean* or *n modified / m deleted*; **Undo** (available while a before-image was captured) restores the pre-apply state after a fresh drift check and warns that it overwrites later edits. ### Step 6 — Refresh the sandbox when it drifts A sandbox ages as production moves on. Before choosing **Refresh Sandbox** (row action, or on the detail page; Active sandboxes only), build a DeltaPack for every change worth keeping, because refresh **replaces** the sandbox with current production: the sandbox's metadata is removed and mirrored again from the source with identifiers intact, data for the entities in the copy plan is deleted and copied afresh, and entities outside the plan are left untouched. The refresh reuses the plan the sandbox was created with (a metadata-only sandbox stays metadata-only). The address, ordinal and subscription key do not change, but users are copied again — every account inactive except the refreshing administrator's. Watch the job back to **Active**, re-enable the colleagues who still need access, and re-run your test baseline before continuing. ### Step 7 — Delete a sandbox you no longer need **Delete** (row action or detail page) marks the sandbox for deletion; it disappears from the list immediately and its database is cleaned up later by the platform's retention process. Deletion is not undoable from the tenant side — unbuilt DeltaPack content in that sandbox is lost. ## Expected result The sandbox reaches **Active**, the selected metadata and approved data scope are present, and only the creating administrator is initially enabled. Changes made there do not appear in production; the only promotion path is a DeltaPack that is separately built in the sandbox, reviewed as an Inbound DeltaPack on production, and applied there — with drift checking and undo afterwards. ## Common problems - **Colleagues cannot sign in to a new or refreshed sandbox.** By design: accounts are copied inactive; enable them inside the sandbox. - **New sandbox is disabled, or creation fails with a quota message.** Your plan's sandbox cap, daily refresh cap or data-copy allowance was reached. Delete an unused sandbox or ask the operator about the quota. - **A copy profile is not offered in the dialog.** Only **Approved** profiles are selectable; approve it on Sandbox Copy Profiles first. - **Sandbox-only work vanished after a refresh.** Refresh rebuilds metadata and planned data from production; nothing authored only in the sandbox survives unless it was built into a DeltaPack first. - **A pack sits in Applying.** The apply job stalled; contact your platform operator rather than re-submitting. - **Build rejects an item.** Tenant resources (uploaded files) can be added to a pack but are not a supported kind; remove the item and move the file manually. ## Common questions ### Can a sandbox affect production? No. A sandbox is a separate tenant with its own database and sign-in address; nothing you configure, break or delete in it touches production. The only path back is a DeltaPack, which does nothing until someone with `setup.deltapacks.inbound.manage` applies it on the production side — and an applied pack can be undone while its before-image exists. ### What exactly does a DeltaPack carry? Configuration — the metadata kinds listed in Step 4, chosen item by item. It does not carry business data: records you created in a sandbox stay there. Move data separately with [export](/docs/administration/data-management/export-data/) and [import](/docs/administration/data-management/import-data/) if a test data set needs to travel. ### How current is a sandbox's data? As of its creation or last refresh; sandboxes do not sync continuously. Refresh when you need production's current state, remembering that refresh replaces metadata and planned data and disables users again. ### Are sensitive values copied into the sandbox? Only as the approved copy profile allows. Each profile says, per sensitive field, whether to copy, mask (a deterministic replacement) or blank the value, and a profile must be approved before it can be used — that approval is the governance step for what leaves production. ## Related topics - [Customizing xMatix](/docs/customization/) — the changes you will typically build in a sandbox. - [Import data](/docs/administration/data-management/import-data/) - [Export data](/docs/administration/data-management/export-data/) - [Administration guide](/docs/administration/) ---- # Security profiles and the grant matrix URL: https://xmatix.com/docs/administration/security-profiles/ Last reviewed: 2026-09-06 A security profile decides what a user may *do* in xMatix: which entities they can read and write, which fields, which apps appear in their navigation, which actions they can run, and which Setup areas they can administer. A user can hold several profiles; their effective rights are the union of everything those profiles grant. Profiles are one half of the model — *which records* a user sees within a granted entity is decided by [record-level security](/docs/administration/record-security/), and both halves must allow an operation for it to succeed. ## The grant matrix Per entity, a profile carries allowed operations, managed under **Setup → Access Control → Profiles** on the **Entity Permissions** tab. @[guided-image](_img/security-profiles.png) | Operation | Lets the holder | | --- | --- | | Read | open the entity's lists and records | | Create | create new records | | Update | edit records they have access to | | Delete | delete records they have access to | | Share | share individual records with other people | | Assign | reserved for changing a record's owner — the runtime does not currently check it separately; owner changes are governed by Update | | View All | read every record of the entity, bypassing record-level scoping | | Modify All | update and delete every record, bypassing record-level scoping | Entity access is a strict allowlist: an entity with no grant on any of the user's profiles is denied, and a user with no active profile is denied everywhere. Include **Read** in every grant — write-only grants let users change what they cannot see — and hand out **View All** and **Modify All** sparingly; they step around record-level policies. ### Fields, apps, actions, reports **Field permissions** override the entity grant for a single field — make a sensitive field read-only or hide it. A field with no override follows the entity grant. **App visibility** is its own allowlist: an app (and each of its pages) appears in navigation only when a profile explicitly grants view access. Forgetting this is the most common reason a new profile "does nothing": right entity grants, empty navigation. **Actions**: standard New, Edit and Delete buttons follow the entity operations automatically; custom server actions each need an explicit grant on the **Actions** tab. **Reports and dashboards** are visible to everyone or to selected roles, teams and profiles. A report with no visibility grants is invisible to non-administrators. ## Capabilities: access to Setup areas Setup areas are gated by named capabilities (keys such as `setup.security.manage`), browsable under **Setup → Access Control → Capabilities** and granted per profile on the **Entitlements** tab. Each capability belongs to a feature: the profile must hold the owning feature first, and a capability of a feature your organization has not licensed and enabled stays dark even when granted. One guardrail is built in: the core security capabilities cannot be removed from the **SystemAdmin** profile, so there is always a recovery hatch. Elsewhere take care — revoking `setup.security.manage` from the profile your own account relies on locks you out of security administration. ## How profiles combine with licensing Licensed functionality has three layers that must line up: the organization's entitlement (enabled, in seats, not expired), the profile's license grants, and the user's own seat. The runtime intersects them, so a feature can be missing for one user — no profile grants it, or no seat — while the organization-level entitlement is fine. Where seat enforcement is on, assigning a profile that carries license grants fails until the user has matching seats; the assignment dialog then offers **Assign missing seats**, which enables the organization license if needed and allocates the seat, and the user's **Access Diagnostics** tab shows which requirements are unmet. See [Licensing](/docs/administration/licensing/). ## Assigning and managing profiles Profiles are assigned per user on the **Profile Assignments** tab (Setup → Access Control → Users). Each profile has an audience scope — internal, external, or both — and the assignment dialog only offers profiles whose scope matches the user's audience; a mismatched assignment is also ignored at runtime. Because access is a union, removing one profile only removes what no other profile still grants, and there is no deny. The built-in **SystemAdmin** and **StandardUser** profiles cannot be deleted or renamed — create a separate profile rather than bending the built-ins, and always leave at least one active SystemAdmin holder. The current Profiles screen has no Clone action, so create the new container and copy only the reviewed grants you intend. This deliberate copy is safer than editing a live profile, whose changes hit every assigned user immediately. ## Common questions ### What happens when a user has no profile? They see nothing: no apps, no entities, no records, and operations fail with an explicit "no security profiles" denial. This is the first thing to rule out when someone reports a blank workspace after signing in — check the **Profile Assignments** tab for at least one active assignment, then work through [Why can't a user see something?](/docs/administration/user-cant-see-x/) if the problem persists. ### Can one profile deny what another grants? No. All grants are additive and there is no explicit deny, so a user's rights are the union of their active profiles. To narrow access you remove or shrink grants — typically by moving the user to a smaller profile — rather than adding a restrictive one. For narrowing *which records* they see, rather than which operations, use [restriction rules](/docs/administration/restriction-rules/) instead. ### Why does a new profile seem to do nothing? Usually app visibility: the profile grants entity operations but no app, so the user's navigation stays empty. Next come a capability granted without its owning feature, a licensed feature your organization has not enabled, and missing seats where seat enforcement is on. The **Access Diagnostics** tab pinpoints which layer is short; a session refresh is worth trying after any grant change. ## Related topics - [Record-level security and sharing](/docs/administration/record-security/) - [Roles, teams and business units](/docs/administration/roles-teams-business-units/) - [Restriction rules: scoping what users can see](/docs/administration/restriction-rules/) - [Licensing](/docs/administration/licensing/) ---- # Worked security scenarios URL: https://xmatix.com/docs/administration/security-scenarios/ Last reviewed: 2026-09-06 Every access decision in xMatix passes two gates: a security profile must permit the operation on the entity, and record security must expose the specific record. Neither gate alone is enough. The scenarios below show how the common building blocks — ownership, the role hierarchy, teams, business units, policy rules and the view-all override — combine into configurations you can copy. Each names the exact screens and fields involved; the mechanics are explained in [Security profiles](/docs/administration/security-profiles/), [Roles, teams and business units](/docs/administration/roles-teams-business-units/), [Record security](/docs/administration/record-security/) and [Restriction rules](/docs/administration/restriction-rules/). Before you start, know the baseline. First-party entities ship with a policy (`DefaultSharing` under **Setup → Access Control → Policies**) whose defaults are **User Owned**, **Read Only** for internal and external users, and **Grant Access Using Hierarchy**, **Allow Manual Share** and **Allow Team Access** all on — everyone with profile Read sees every record; writing needs ownership, hierarchy or **Modify All**. Every scenario below that wants records hidden starts by setting **Internal Default Access** to **Private** on that policy. An entity you created has no policy and already behaves as Private with the three switches off. ## Scenario 1 — Representatives own their records; managers see the team's **Goal.** Each sales representative works only their own opportunities, while their manager can read everything the team owns. **Configuration.** The representatives' profile grants *Read* and *Update* on the entity. The entity's policy is User Owned with **Internal Default Access** set to Private, so a record is visible only to its owner unless something else grants access. The representatives' roles sit below the manager's role in the hierarchy (**Roles** → each rep role's **Parent Role** is the manager's role), and the policy has **Grant Access Using Hierarchy** on. The manager's profile also grants *Read* on the entity. **Result.** A representative sees and edits their own records; a colleague with the same profile cannot open them. The manager reads every record owned by users in descendant roles — but only because the manager's own profile grants *Read*. Hierarchy expands record visibility; it never adds entity permissions, and it never lets a representative see upward or sideways. ## Scenario 2 — Regional teams see only their region **Goal.** Users in each region work with their region's records and nothing else. **Configuration.** Keep the entity Private by default, as above. Create one business unit per region (**Business Units**) and set each region's roles' **Business Unit** to it. Give users a regional role plus a profile granting *Read* on the entity. Then open the records to the unit either by sharing records to the business unit, or — the maintainable way — with one policy rule per region: **New Rule** with Rule Type *Access Grant*, Effect *Grant Read*, an expression such as `Region == "West"`, and a target of type *Business Unit* pointing at the West unit ([restriction rules](/docs/administration/restriction-rules/)). **Result.** Users whose roles resolve to a business unit can open the records shared or granted to it; users in other regions cannot. Two caveats: business-unit membership reaches a user only through their active roles — there is no direct user-to-unit assignment. And belonging to a unit grants nothing by itself: it is the share or rule targeting that unit that opens the records. ## Scenario 3 — A support team collaborates on shared cases **Goal.** Everyone on a support team can work the cases escalated to the team, regardless of who owns each case. **Configuration.** Create the team (**Teams**) and add its members on the **Assignments** tab. On the case entity's policy, keep **Allow Team Access** on. Share the relevant case records to the team — manually from the record, or through a policy rule whose target type is *Team*. Members' profiles grant *Read* — and *Update* where they should edit — on the case entity. **Result.** Any member can open the shared cases without owning them. A member whose profile lacks the entity grant still cannot: record access alone never completes an operation — the two gates cut both ways. Note that a rule target grants read only; editing shared cases relies on the *Update* profile grant plus a Read Write default, ownership, hierarchy, **Modify All** or a manual share. ## Scenario 4 — Everyone may read reference data, nothing else changes **Goal.** Accounts of type *Reference* are visible to all internal users, while every other account stays Private to its owner and management chain. **Configuration.** Policy Private, hierarchy on, as in Scenario 1. Add one rule: Rule Type *Access Grant*, Effect *Grant Read*, Applies To Audience *Internal*, expression `AccountType == "Reference"`, target type *All Internal*. Create the rule disabled, confirm the expression shows **Valid**, test, then enable it. **Result.** Internal users see their own accounts plus every Reference account; portal (external) users are unaffected because the rule's audience excludes them. This is the general pattern for an exception to a Private baseline: one rule, one condition, one audience or group. ## Scenario 5 — An operations role that sees everything **Goal.** An operations or audit role can read every record of an entity, regardless of ownership and shares. **Configuration.** Grant the profile *Read* plus **View All** on the entity. Add **Modify All** only if the role must also update or delete anything it can see. **Result.** Record-level filtering is skipped entirely for that entity: the user reads all records even though the entity is User Owned and Private for everyone else. Because these overrides bypass every record-level control — ownership, hierarchy, shares, rules and defaults alike — reserve them for genuinely tenant-wide roles and keep the profiles that carry them narrowly assigned. ## Quick interpretation rules When a configuration does not behave as expected, these shortcuts point at the right layer. | Symptom | Where to look first | | --- | --- | | The user cannot do the operation on any record (an explicit "not allowed" error) | Profile grants on the entity | | Some records are visible, others are not | The entity policy and the record-access path (owner, hierarchy, shares, rules) | | A manager cannot see subordinate data | Role assignments, the Parent Role chain, and Grant Access Using Hierarchy on the policy | | Business-unit sharing is not working | Whether the user's active roles actually carry the expected Business Unit | | Team sharing is not working | Team membership and the policy's Allow Team Access switch | | A rule grants nothing | Rule Enabled, expression Validation = Valid, audience, target, and profile Read | | Everyone can see everything | A Read Only default that was never set to Private, or View All on a widely assigned profile | ## Common questions ### Do permissions from multiple profiles conflict? No. A user's effective permissions are the union of everything their active profiles grant, and there is no explicit deny that overrides a grant. A user with one profile granting *Read* and another granting *Update* effectively has both. The practical consequence for troubleshooting: before you conclude a grant is missing, inspect every active profile the user holds — and remember that removing one profile only removes what no other profile still grants. ### Can a share grant more than the profile allows? No. Shares, hierarchy roll-up, rules and policy defaults only decide which records are reachable; the operation itself must still be permitted by a profile grant on the entity. A record shared to a user who has no *Read* grant stays unreadable, and a readable record is not editable without an *Update* grant. When you want someone to act on shared records, check both gates deliberately. ### What does a Private default actually mean? With **Internal Default Access** Private on a User Owned entity, a record is visible only to its owner plus whatever explicit paths you configure: hierarchy roll-up to managers, shares to teams or business units, enabled policy rules, or a profile's **View All** override. Internal and external users have separate defaults on the same policy — for example Read Only for employees while portal users stay Private — so check both settings when internal and external audiences behave differently. ### Should I use shares or rules for group access? Manual shares are per record and suit exceptions — one escalated case, one strategic account. Rules are per condition and suit standing arrangements — a region's records, a record type, a status. Rules stay visible and reviewable on the policy detail page and can be disabled in one place; shares accumulate on records and are harder to audit. Both require the policy's corresponding switch (Allow Manual Share, Allow Team Access) or rule to be active. ## Related topics - [Security model concepts](/docs/concepts/security-model/) - [Security profiles](/docs/administration/security-profiles/) - [Roles, teams and business units](/docs/administration/roles-teams-business-units/) - [Record security](/docs/administration/record-security/) - [Restriction rules](/docs/administration/restriction-rules/) - [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/) ---- # Email templates and document numbering URL: https://xmatix.com/docs/administration/templates/ Last reviewed: 2026-09-06 Two pieces of tenant configuration shape how your documents look to the world: **messaging templates** — reusable, entity-bound messages that merge record data when a rule, approval or subscription sends them — and **document numbering** — automatic, structured names such as `SO-2609-000042` written onto new records. Both live under **Setup → Feature Hub → Platform**. ## Prerequisites - Messaging templates: the `setup.metadata.email.manage` capability. Bind a template to an entity so its fields are available as merge variables; a template without an entity (**Global**) can only use tokens the sending feature supplies. - Document numbering: access to Feature Hub, plus a decision about which entity and which field receives the generated name, and what the number should look like. - Delivery: e-mail goes out through your organization's [messaging channel configuration](/docs/engagement/messaging-channels/) (**Setup → Feature Hub → Service → Messaging Channels**). Templates for the other channels — SMS, chat, messaging apps, quick text — can be authored today, but only e-mail delivery is wired; treat the other channels as drafts until your organization's delivery setup covers them. ## Procedure ### Step 1 — Create a template Go to **Setup → Feature Hub → Platform → Email Templates**. The screen is titled **Messaging Templates** and manages every channel, not e-mail alone. The list shows Name (opens the designer), Label, Entity (or *Global*), Channel, Kind, Editor, Default and State, with row actions **Design**, **Edit**, **Clone** and **Delete**. @[guided-image](_img/email-templates.png) Select **New** and fill in: | Field | Meaning | | --- | --- | | **Label** (required) and **Name** | The wording administrators recognise, and the stable technical name that rules reference. | | **Entity** | The record type the template is about; locked after creation. Leave empty for a Global template. | | **Channel** | Email, SMS, Chat, messaging app or Quick Text. Rich-text content is available for Email only. | | **Editor Mode** | Text only, HTML only, or Text + HTML — which bodies the designer offers. | | **Kind** | General for rule and approval messages; Report Subscription and Dashboard Subscription for the templates offered in subscription dialogs. | | **Active** | Only active templates are offered to consumers. | | **Default template** | Marks this template as the fallback for its entity and kind — what a rule without an explicit template sends. | Confirm the row shows the intended Entity, Channel and Kind before authoring: those are the template's operating contract, while subject and body are content you can refine any time. ### Step 2 — Author the content in the designer Open the template with **Design** (or its name). The designer has two panels. **Formula Builder** on the left holds the template's variables: **Add variable** (available when the template is entity-bound) defines a named variable and the expression that fills it from the record — a field, or a path through a lookup such as the account's name on an order. **Template Content** on the right holds the **Subject** and the body tabs — **Plain Text**, and **Rich Text** for e-mail templates whose editor mode includes HTML. Insert variables as tokens: the variable name wrapped in a pair of curly braces on each side, as the Subject field's hint text shows (spaces inside the braces are tolerated; letters, digits, underscore and dots are allowed, so dotted paths work). At send time each token is replaced by its variable's value for the record being sent about. A token whose name matches no variable renders as **empty text**, not as an error — so check token spelling against the variable list before relying on a template. ### Step 3 — Test with a real send There is no preview button in the designer or on the list. To see what a template renders, wire it into its consumer (Step 4) against a test record — a draft business rule fired on a scratch record, or an approval on a test document — and read the result in the message log under **Setup → Platform Operations → Monitoring → Message Log**, which shows the rendered subject and delivery status. Fix blank tokens by matching the variable name or by populating the field on the test record, then re-send. ### Step 4 — Put the template to work Templates are consumed by the features that send messages: - **Business rules** — the **SendMessage** action takes a directive such as `template=OrderConfirmation;channels=email;to=field:Email` (the `to` part accepts a field name, `owner`, or an address; `subject=` and `body=` override the template's content; `channels=` may also list `inapp` for an in-app notification). See [business rules](/docs/customization/business-rules/). - **Approval processes** — the process carries a template per event: submit, approve, reject, recall and revert. See [approvals](/docs/customization/approvals/). - **Report and dashboard subscriptions** — the subscription dialog offers templates of kind Report Subscription or Dashboard Subscription. See [subscriptions](/docs/analytics/subscriptions/). Resolution at send time is: the explicit template id → the template name → the **Default template** for the entity and kind → the platform's built-in default. Consumers store a reference, so editing a template's content changes future sends without touching the rule, approval or subscription. Sends are rendered once and queued; the sender address and provider come from the messaging channel configuration, not from the template. User invitation and password e-mails are a separate platform system and are not restyled through these templates. ### Step 5 — Configure document numbering Go to **Setup → Feature Hub → Platform → Document Settings** (*Configure how document names are generated per entity: series, date format and running sequence*). The list shows Name (opens the detail page), Label, Entity, Destination Field, Default Series, Date Format, Number Length, Active, Created and Modified; row actions are **Edit** and **Delete**. @[guided-image](_img/document-settings.png) Select **New** and define the recipe: | Field | Meaning | | --- | --- | | **Label**, **Name** | Display and technical names of the setting. | | **Entity** (required) | The record type whose new records receive a generated name. | | **Destination Field** | The field that receives the generated name — commonly Name or a document-number field. | | **Series Field** | A field on the record that supplies the series prefix per record (a branch code, a document type). May be a calculated field. | | **Default Series** | The fixed prefix used when no Series Field is set or the field is blank. | | **Date Field** | The field whose date supplies the date portion; blank uses the creation date. | | **Date Format** | The pattern for the date portion, for example `yyMM` or `{DD}{MM}{YYYY}`; leave blank for no date part. | | **Number Length** | Zero-padded width of the running number. | | **Separator** | One character placed between series, date and number. | | **Active** | New settings are **inactive** until you switch this on, so you can review the recipe first. | The generated name is *series + separator + date part + separator + zero-padded number* — with Default Series `SO`, format `yyMM`, length 6 and separator `-`, the 42nd document is `SO-2609-000042`. Several active settings may target the same entity as long as they write different fields (a Name and a purchase-order number, say). ### Step 6 — Understand how sequences run - Names are generated on **record creation only** — never when a record is previewed or edited, so previews do not consume numbers and existing records are never renumbered. - Generation runs **before** business-rule *set value* actions on the same save, so a Series Field formula must not depend on a value a rule sets. - The counter belongs to the **series string, tenant-wide**: every record whose resolved series is `SO` advances the same counter, whatever entity, date or setting produced it. The date portion is a label inside the name, not a reset — a monthly date format does not restart numbering each month. - Numbers are allocated in atomic blocks, so bulk imports and concurrent users get consecutive, non-colliding numbers. - The detail page's **Document Numbers** tab lists each series with its **Last Number Used**; **Edit last number used** lets you move a counter forward (or back to a minimum of 0) when migrating from a previous system. Moving a counter backwards can produce duplicate names on entities that do not enforce uniqueness — do it only on an empty series. ## Expected result The messaging template appears under the intended entity, channel and kind, a test send renders every token from the sample record, and the consuming rule, approval or subscription keeps its reference so later wording changes flow into future messages. The document setting is Active and produces correctly prefixed, dated and padded values on newly created records of its entity; existing records keep their identifiers, and the Document Numbers tab shows the series advancing. ## Common problems - **A token renders blank in a real send.** Either the variable name does not match the token (unknown tokens render empty) or the field is empty on that record. Compare the token with the Formula Builder list first, then check the record. - **The message never arrives.** Rarely the template. Check the message log for the queued send and its status, then the [messaging channel](/docs/engagement/messaging-channels/) configuration. A template on an SMS, chat or messaging-app channel is not delivered — only e-mail delivery is wired. - **A rule sends the wrong template.** The rule has no explicit template and falls back to the entity's **Default template**; either name the template in the directive or fix which template carries Default. - **Two document families share numbers.** They resolve to the same series string. Give each family its own Default Series or Series Field value; the date part does not separate counters. - **New setting produces nothing.** It is still inactive (new settings default to inactive), or the entity already had a value in the destination field on the incoming record. ## Common questions ### Can two entities share one numbering sequence? Yes — and they will whether you intend it or not. The counter is keyed on the resolved series string for the whole tenant, so two settings whose series resolve to the same text advance one sequence. Use distinct series values when document families must be independent. ### Do existing records get renumbered when I add or change a setting? No. Names are generated only when a record is created. Records that existed before the setting keep whatever value the destination field held, and changing the format later affects only records created after the change. ### Can I reword a template without touching the automation that sends it? Yes. Rules, approvals and subscriptions reference the template by id or name, so editing its subject or body changes future sends without rebuilding the consumer. Because there is no preview, make the change and check the next send in the message log. ### Which channels actually deliver? E-mail. Templates can be authored for SMS, chat, messaging apps and quick text so the content is ready, but those channels are not connected to a delivery provider in the current release; a rule that lists them sends only the e-mail (and in-app) parts. ## Related topics - [Messaging channels](/docs/engagement/messaging-channels/) - [Business rules](/docs/customization/business-rules/) - [Approvals](/docs/customization/approvals/) - [Report and dashboard subscriptions](/docs/analytics/subscriptions/) - [Administration guide](/docs/administration/) ---- # Troubleshooting: a user can't see something URL: https://xmatix.com/docs/administration/user-cant-see-x/ Last reviewed: 2026-09-06 ## Start with Access Diagnostics @[guided-image](_img/access-troubleshooting-context.png) The user's **Access Diagnostics** tab (Setup → Access Control → Users → open the user) is the fastest way to see the effective picture the server computes for that person: audience, active profiles, roles, teams, business units, and — for product licenses, feature licenses and capabilities — two lists side by side: **Allocated to user** and **Required by profile**. The screen does not flag the difference for you; read the two lists and look for a name that appears under *Required* but not under *Allocated*. That is a licensing gap (check 1). Empty **Teams** or **Business Units** cards are normal for many users and only matter when a share or rule depends on them (check 3). When a user reports they can't see something — an app, a list, particular records, a field or a button — record the affected user, the app or entity, the operation and one specific missing record, then work through the checks below in order and stop at the first one that fails; that layer is the one to fix, and changes elsewhere won't help. Prefer additive fixes: grant the missing piece on the user's existing profile rather than handing out a broader admin profile. ## Before you start Rule out the cheap causes first. Is the account active? Has the user ever signed in — or did the invitation never land? Does the user hold at least one active security profile? Visibility in xMatix is allowlist-based, so a user with no profile sees no apps and no records, and the platform says so explicitly: > The current user has no security profiles and is not allowed to perform 'Read' on entity 'Order'. That message style confirms which layer refused the request. After any fix, re-open Access Diagnostics (the **Generated** timestamp confirms it recomputed) and have the user retry after a session refresh. ## The checks, in order ### Check 1 — Licensing If the missing thing belongs to a licensed module or feature, check the commercial layer first: the tenant license (**Setup → Feature Hub → Administration → Licenses**) must be enabled, unexpired and within its seat ceiling, and the user's **License Allocations** tab must contain the required non-revoked seat when enforcement applies. Also inspect that module's own Feature Hub settings if it exposes an operational enable switch; there is no consolidated Module Settings item in navigation. Fix the first failing layer. Details in [Licensing](/docs/administration/licensing/). ### Check 2 — Profile grants Profiles are the unit of app, entity, field and action access. An app appears only when an active profile grants view on it — no grant means hidden. An entity list needs *Read* in the union of grants across all the user's active profiles, and a field can be hidden or made read-only by a field-level permission even when the entity is readable. Also confirm the profile's audience matches the user (internal versus external). Inspect every active profile before declaring a grant missing, then fix by adding the specific grant. See [Security profiles](/docs/administration/security-profiles/). ### Check 3 — Record security If the user can open the list but some records are missing, entity permission is fine — record security is filtering. On a private, user-owned entity, non-owned records are reachable only through an explicit path: a broader policy default, hierarchy roll-up to the user's role, a share to them or to their role, team or business unit (team shares also need the policy's team-access setting), an Access Grant rule, or the profile's *View All* override. A custom entity with no sharing policy at all behaves as private with every mechanism off — create its policy first. In multi-company tenants, company scoping also applies — the user sees only the companies they have access to. Record grants never widen entity access: without profile *Read*, no share helps. Pick the intended path and configure it; worked examples: [Worked security scenarios](/docs/administration/security-scenarios/) and [Record security](/docs/administration/record-security/). ### Check 4 — Restriction rules Even when the profile and record security both allow a record, an active restriction rule on the entity can scope it away from users the rule targets. Restriction rules only subtract — they never grant — so a rule is the likely culprit when everything in checks 1–3 looks correct. Review the entity's restriction rules for one that applies to this user and excludes the records, and fix by adjusting its criteria or audience. See [Restriction rules](/docs/administration/restriction-rules/). ### Check 5 — View filters Last, and surprisingly common: the view itself. Saved view filters, personal column filters, leftover search text and date-range scopes hide records with no security involved. Have the user switch to an unfiltered view, clear filters and search, and compare the record count. If the records appear, nothing was ever wrong with access — adjust the view instead; a shared view's default filters can surprise a whole team. ## Common questions ### The user can see the record but one field is missing or read-only — why? That is field-level control, not record security. A field-level permission on one of the user's profiles can hide a field or make it read-only even though the entity itself is readable; with no field permission, the field follows the entity grant. Separately, the field may not be on the form layout in use. Check field permissions across all the user's active profiles first, then the layout. ### How quickly do fixes take effect? New requests re-evaluate promptly after you save a grant, seat or rule change, but an already-signed-in session can hold its previous picture until its token refreshes. Have the user refresh their session — or sign out and back in to force it — before you conclude the fix didn't work. Then re-open Access Diagnostics and compare the allocated and required lists again. ### Two users hold the same profile but see different records — why? Profiles equalize entity permissions only. Record visibility is computed per user from ownership, role hierarchy, team and business-unit shares, company scoping and restriction rules — all of which can differ between two people with the same profile. Compare the two users' roles, teams and company access on their Access Diagnostics tabs, then walk check 3 and check 4 for the records one of them is missing. ## Related topics - [Licensing](/docs/administration/licensing/) - [Security profiles](/docs/administration/security-profiles/) - [Record security](/docs/administration/record-security/) - [Restriction rules](/docs/administration/restriction-rules/) - [Worked security scenarios](/docs/administration/security-scenarios/) ---- # Offboard or suspend a user URL: https://xmatix.com/docs/administration/users/deactivate-a-user/ Last reviewed: 2026-08-31 Offboarding must remove the user's account from your organization. In the current product, clearing **Active** is **not** a sign-in suspension for an identity that has already been provisioned: it prevents an unprovisioned account from being sent for identity provisioning and affects some active-user selectors, but authenticated tenant resolution does not filter an existing account on this field. Use the Users-list **Delete** action for access removal, after preserving the person's work and reclaiming their license seats. Deleting here is tenant-scoped and soft-deletes the xMatix user row. It does not erase business records the person owned or created, and it does not remove a shared sign-in identity that may also be used with another organization. ## Prerequisites - The user-administration capability (`setup.security.users.manage`) on one of your own security profiles. - A reviewed inventory of what the person is responsible for: live records they own, approvals that route to them, teams where they act as an approver, company access, and assigned license seats. - A replacement owner or approver for every item that must continue after the person leaves. ## Procedure ### Step 1 — Verify the exact account Open **Setup → Access Control → Users** and search by the person's verified corporate email. Confirm the display name, email, audience and **Sign-in** status before changing anything. Never edit or delete **System Process**, **System Agent** or **System Anonymous**: these are built-in service identities, not people, and the UI intentionally hides their Edit and Delete actions. ### Step 2 — Re-route live work and approvals Open work does not move automatically when its owner is removed. Reassign records that still need action, especially leads, opportunities, orders, cases, visits, service work and approval requests. Check the user's delegated approver, role position and approval teams as well: replace a named approver and remove the person from any team that supplies an approval pool. Keep historical records with their original creator or owner when that attribution is required; only move work that still needs an active operator. ### Step 3 — Reclaim license seats Open the user's **License Allocations** tab and revoke every active product, feature or package seat that should return to the tenant pool. A seat remains counted while its allocation has no revocation timestamp, even if the account's **Active** field is cleared or the user is later removed. Confirm each row changes to revoked and verify the available-seat count before assigning the seat to a replacement. See [Licensing](/docs/administration/licensing/). ### Step 4 — Clean up access assignments Review **Profile Assignments**, **Role Assignments**, **Team Assignments** and multi-company access. Remove assignments your policy requires you to retire, and record any retained assignment history before deleting the account. The account deletion itself stops tenant identity resolution, but it does not use the **Active** field as a security gate and should not be substituted with a checkbox change. ### Step 5 — Remove the tenant account Return to **Setup → Access Control → Users**, find the verified row, and select **Delete** in its **Actions** column. Read the confirmation carefully and confirm only after the reassignment and seat checks are complete. This operation soft-deletes the user account in this organization and invalidates its cached identity and access snapshots; the external sign-in identity is not deleted. @[guided-image](_img/offboard-user-confirmation.png) ### Step 6 — Verify the outcome Refresh the Users list and confirm the account no longer appears. Verify that the replacement owners can open the transferred work, approval queues no longer point to the leaver, and reclaimed seats are available. If you have an authorized test process, confirm that a new request for this organization can no longer resolve the removed account; a still-valid identity-provider session by itself is not proof of tenant access. ## Expected result The user no longer appears in the organization's Users list or resolves as a live tenant account. Required license seats are revoked, active work and approvals have responsible replacements, and historical business records retain their audit attribution. ## Common problems **The user can still sign in after Active was cleared.** That is the implemented behavior for an already provisioned identity; **Active** is not the tenant sign-in gate. Complete the offboarding checklist and use the Users-list **Delete** action. **Seats are still counted against the license.** Account-state changes do not revoke seat rows. Revoke the allocations explicitly in Step 3; if a seat ceiling blocks the replacement, reclaim the leaver's seat first. **A System account appears in the list.** **System Process**, **System Agent** and **System Anonymous** are platform identities. They cannot sign in as people, and the UI deliberately prevents editing or deleting them. ## Common questions ### Can I temporarily suspend a provisioned user with Active? No. Clearing **Active** alone does not stop an already provisioned account from resolving during sign-in. You can strip profiles, roles, teams, company access and seats to reduce what the user can do, but that is not a reliable sign-in suspension and may still allow an empty workspace. If the requirement is to remove access to this organization, use the deletion procedure above. Recreating access later is a fresh onboarding task, including a new review of assignments and licenses. ### What happens to the records the user owns? Nothing changes automatically. Historical references remain, but live records can be stranded with an owner who no longer resolves as a current user. Reassign actionable work before removal so queues, hierarchy-based visibility and follow-up responsibilities stay usable. ### What does Active do for a new account? An unprovisioned account is sent to identity provisioning only while **Active** is enabled. This lets an administrator prepare an inactive account without sending its welcome message, then enable it at go-live. After the identity has been provisioned, do not treat the same field as an access-revocation control. ## Related topics - [User accounts](/docs/administration/users/user-accounts/) - [Invite a user](/docs/administration/users/invite-a-user/) - [Licensing](/docs/administration/licensing/) - [Security profiles and the grant matrix](/docs/administration/security-profiles/) - [Record-level security and sharing](/docs/administration/record-security/) - [Why can't a user see something?](/docs/administration/user-cant-see-x/) ---- # Invite a user URL: https://xmatix.com/docs/administration/users/invite-a-user/ Last reviewed: 2026-10-09 You invite someone to xMatix by creating their user account. The platform then provisions their sign-in identity in the background and e-mails them their way in — your remaining job is assigning access, because a brand-new account with no security profile can sign in but sees nothing. The whole flow takes a few minutes. ## Prerequisites - The user-administration capability (`setup.security.users.manage`) on one of your own security profiles. The built-in **SystemAdmin** profile includes it. Assigning profiles, roles and teams afterwards uses `setup.security.manage`; seats use `setup.licensing.admin`. - The person's work e-mail address, and a decision on their **Audience** — *Internal* for employees, *External* for portal and partner users. The audience cannot be worked around later: profiles are scoped to Internal, External or Both, and a mismatched profile cannot be assigned. - The [security profile](/docs/administration/security-profiles/) you plan to assign. If your organization enforces license seats, the user may also need seats for anything the profile requires — see [Licensing](/docs/administration/licensing/). ## Procedure ### Step 1 — Check the address is not already in use Open **Setup → Access Control → Users** and search for the person's e-mail address. The list shows Display Name, Name, Email, Phone, Active and **Sign-in** — *Ready* (identity provisioned, can sign in), *Pending* (provisioning still running, within the first minutes after creation), *Not provisioned* (no identity — cannot sign in) or *System* (the platform's own service identity, which never signs in and must never be edited). xMatix does not force e-mail addresses to be unique, so nothing stops a second account for the same person — but a duplicate strands the original account's assignments and makes the address ambiguous. If an account already exists, reuse it instead of creating another. ### Step 2 — Create the account Select **New** in the page header. The **New User** dialog asks for: @[guided-image](_img/invite-user-dialog.png) - **Username** — the sign-in name. It must either equal the **Email** exactly or be a plain name without `@` (letters, digits and `. - _ ! # ^ ~`, up to 64 characters); a username that is a *different* e-mail address is rejected in the dialog because the identity provider cannot provision it. Leaving it blank uses the e-mail. - **First Name**, **Last Name**, **Email**, **Phone** — the e-mail is where the invitation goes. **Display Name** is composed from first and last name when left blank. - **Audience** (required) — *Internal* or *External*. - **Active** — on by default. Only active accounts are provisioned and e-mailed. - **Locale & Time Zone** — optional language, locale and time zone. - **Approvals** — an optional **Delegated Approver**, a user who may act on this user's approval requests. Select **Create**. The list shows the new row with Sign-in *Pending*. ### Step 3 — Let provisioning run Saving an active account queues identity provisioning in the background (it does not appear in the tenant's Jobs list). Within a minute or two Sign-in turns *Ready* and the person receives one of two e-mails: a **set-password** e-mail when their sign-in identity is newly created — the link is valid for 72 hours and lands on your organization's set-password page — or an **added to your workspace** e-mail pointing at the sign-in page when they already had an identity from another organization. Accounts created inactive are not provisioned until you activate them. What the person does next is covered in [Signing in to xMatix](/docs/getting-started/sign-in/). ### Step 4 — Assign at least one security profile Open the user (click the row) and add a profile on the **Profile Assignments** tab. This step is not optional: access in xMatix is allowlist-based, so a user with no active profile sees no apps and no records at all. The profile's audience scope must match the user's audience — a profile scoped to Internal cannot be assigned to an External user (Both fits anyone), and the dialog rejects the mismatch. Effective access is the union of all active profiles, so start with the smallest profile that covers the job. ### Step 5 — Add roles, teams, seats and company access as needed On the same detail page, the **Role Assignments** tab places the user in the role hierarchy (one role can be marked **Primary Role**) and the **Team Assignments** tab adds them to teams — see [Roles, teams and business units](/docs/administration/roles-teams-business-units/). **License Allocations** assigns product, feature and package seats where the profile requires them. In a multi-company organization, also grant access to the companies the user works with, or the *access all companies* flag; without either, company-scoped records are invisible ([tenants and companies](/docs/concepts/tenants-and-companies/)). ### Step 6 — Verify Confirm Sign-in shows *Ready*, then ask the person to sign in and confirm they reach the apps you expect. The user's **Access Diagnostics** tab computes the effective picture server-side — profiles, roles, teams, business units, licenses and capabilities — and lists, side by side, what the assigned profiles require that the user does not yet hold. **Expected result:** the user can sign in and reaches a populated workspace whose apps and records match the assigned profiles, roles, teams and seats. ## Common problems **Sign-in stays "Not provisioned".** Provisioning did not complete — usually a Username that is a different e-mail address, or a missing e-mail. Fix the fields and save the account again while it is active; any save of an active, unprovisioned account re-queues provisioning. **The welcome e-mail never arrived, but Sign-in is Ready.** Saving again does nothing — the e-mail fires once, when the identity is first created. The reliable self-service path is **Forgot password** on the sign-in page: the identity exists, so a reset gets the person in. If accounts provision but welcome e-mails consistently never go out, the platform's identity e-mail configuration is incomplete — raise it with your platform operator. Never create a second account for the same person to retry an invite. **The set-password link expired.** The link is valid for 72 hours. The person should use **Forgot password** with their work e-mail. **Profile assignment is rejected.** The usual causes are an audience mismatch between the profile and the user, or — where seat enforcement is on — missing seats for license grants the profile carries. Allocate the seats first, or assign a profile without license grants. **The person signs in to an empty workspace.** No active profile assignment — see Step 4 and [Why can't a user see something?](/docs/administration/user-cant-see-x/). ## Common questions ### Can the user do anything before a profile is assigned? They can complete sign-in, but they land in an empty workspace: apps, entities and records are allowlist-based, so nothing is visible until a profile grants it. Treat account creation and profile assignment as one task. ### What if the person already uses xMatix in another organization? Their sign-in identity is reused: provisioning links it to your organization and sends the added-to-your-workspace e-mail — they keep their existing password or passkey. Their access with you is entirely what you assign; nothing carries over from the other organization. ### Can I prepare accounts ahead of a go-live? Yes. Create the accounts with **Active** off: inactive accounts are not provisioned and no e-mail goes out. Finish profile, role, team and seat assignments in advance, then activate the accounts on go-live day — provisioning runs and the welcome e-mails are sent then, and users land in a working workspace on day one. ### Can I resend the invitation? Not as such. If the account is not yet provisioned, saving it again re-queues provisioning and the e-mail. Once provisioned, the platform never re-sends the set-password e-mail; **Forgot password** on the sign-in page is the supported route, and it works because the identity already exists. ## Related topics - [User accounts](/docs/administration/users/user-accounts/) — every field, editing, delegated approvers and preferences - [Offboard or suspend a user](/docs/administration/users/deactivate-a-user/) - [Security profiles and the grant matrix](/docs/administration/security-profiles/) - [Roles, teams and business units](/docs/administration/roles-teams-business-units/) - [Licensing](/docs/administration/licensing/) - [Why can't a user see something?](/docs/administration/user-cant-see-x/) - [Signing in to xMatix](/docs/getting-started/sign-in/) ---- # User accounts URL: https://xmatix.com/docs/administration/users/user-accounts/ Last reviewed: 2026-10-09 A user account is the record that represents one person (or one built-in system identity) in your xMatix organization: it holds their sign-in name, contact details, audience, language and time zone, and it is the anchor for every profile, role, team, license seat and company grant that decides what they can do. Every record in xMatix also points back to user accounts — the **Owner**, **Created By** and **Modified By** of any record are user accounts. Accounts are created when you [invite a user](/docs/administration/users/invite-a-user/) and removed when you [offboard them](/docs/administration/users/deactivate-a-user/). This page covers everything in between: finding and reading an account, editing it, what each field does, and how the account's settings affect the person's day-to-day experience. ## Overview You manage accounts under **Setup → Access Control → Users**. The page lists every account in your organization in an **All Users** table, with a recently-opened strip in the page header and **New** as the header action. Selecting a name opens the account's detail page, where the header shows its key facts and the tabs below hold its access assignments. An account has three layers: - **Identity** — **Username**, **Email**, **Phone**, the names, and the **Audience** (*Internal* or *External*). These decide how the person signs in and which security profiles can be assigned to them. - **Preferences** — **Language**, **Locale** and **Time Zone**. These change how xMatix displays text, numbers and dates for this person. - **Access** — profiles, roles, teams, license seats and company access. These are separate records attached to the account, edited on the detail page tabs and on the Company Access tab in Org Settings. ## How xMatix handles it - **Sign-in is provisioned separately.** Saving an account writes it immediately, but the person's sign-in identity is created in the background. The **Sign-in** column tracks this: *Pending* for the first five minutes after creation, *Ready* once the identity exists, *Not provisioned* if it does not exist after that, and *System* for built-in identities. Only accounts with **Active** switched on, and with a username or e-mail, are provisioned. - **Any save retries provisioning.** Saving an active account whose sign-in is not yet ready sends it for provisioning again. This is the supported way to retry after fixing a field. - **Defaults fill gaps.** A new account is active and *Internal* unless you say otherwise. A blank **Display Name** is composed from **First Name** and **Last Name**. The account's **Name** is taken from the username, falling back to the e-mail and then the display name. - **Addresses are tidied.** Leading and trailing spaces are removed from the username and e-mail when you save. - **Three accounts are not people.** **System Process**, **System Agent** and **System Anonymous** run scheduled jobs and automation, autonomous agent runs, and anonymous storefront traffic. They never sign in, show *System* in the Sign-in column, and have no Edit or Delete action. Their detail page shows a *Built-in system identity* notice. Leave them alone — removing one breaks the work it runs. ## Prerequisites - To open **Users**, create, edit or delete accounts: the user-administration capability (`setup.security.users.manage`) together with the security-administration capability (`setup.security.manage`), which shows the **Access Control** menu group. - To see the **License Allocations** and **Access Diagnostics** tabs on someone else's account: the licensing capability (`setup.licensing.admin`). - To edit your own preferences: no capability — every signed-in user can. ## Procedure ### Step 1 — Find an account Open **Setup → Access Control → Users**. The **All Users** table shows **Display Name**, **Name**, **Email**, **Phone**, **Active** and **Sign-in** by default, sorted by name. Use the search box in the table header to match on name, display name, e-mail or phone; use the column filters to narrow by **Active** or **Sign-in** — filtering **Sign-in** is the quickest way to find accounts that cannot log in. **Refresh** reloads the list. ### Step 2 — Open the account Select the person's display name. The detail page header shows **Name**, **Display Name**, **Email**, **Audience**, **Status** (*Active* or *Inactive*) and **Sign-in**. If the sign-in identity does not exist, a warning reads *This user has no sign-in identity yet* — see [Common problems](#common-problems). The tabs below the header are: - **Role Assignments**, **Profile Assignments** and **Team Assignments** — the person's place in the role hierarchy, the security profiles that grant their access, and their teams. See [Security profiles](/docs/administration/security-profiles/) and [Roles, teams and business units](/docs/administration/roles-teams-business-units/). - **License Allocations** — product, feature and package seats, each with an add control and a **Revoke seat** action. See [Licensing](/docs/administration/licensing/). - **Access Diagnostics** — a computed summary of everything the person effectively has: counts and lists of **Profiles**, **Roles**, **Teams**, **Business Units**, **Product Licenses** and **Capabilities**, with **Product Licenses**, **Feature Licenses** and **Capabilities** each split into *Allocated to user* and *Required by profile*. An **Outlet Transfer** card previews which channel partners, HQs and beats the person can transfer outlets between on the field app, and explains why when the answer is none. ### Step 3 — Edit the account On the detail page select **Edit** in the page header, or select the edit icon in the **Actions** column of the Users list. The **Edit User** dialog has the same fields as **New User** (see [Fields](#fields)). Change what you need and select **Save**. A confirmation reads *User updated*, and the detail page reloads. **Username** and **Email** are checked against the sign-in rule before the dialog will save — fix the username if the dialog flags it. ### Step 4 — Name a delegated approver In the **Edit User** dialog, expand **Approvals** and pick a **Delegated Approver** — anyone except the person themselves. From then on, every approval step that resolves to this person also goes to the delegate: it appears in the delegate's approval inbox and notifications, and the delegate may decide it. The original approver keeps the request too; either of them can act. Clear the field to stop delegating. See [Common questions](#common-questions) for limits. ### Step 5 — Set language, locale and time zone In the **Edit User** dialog, expand **Locale & Time Zone** and fill **Language**, **Locale** and **Time Zone**. These are typed as text here, so use the standard codes: a language such as `en` or `hi`, a locale such as `en-IN`, and a time zone name such as `Asia/Kolkata`. Left blank, the person sees your organization's defaults from **Setup → Feature Hub → Administration → Org Settings**. People can also set these themselves — see the next step — where they are picked from lists, which avoids typing errors. ### Step 6 — Let people edit their own profile Any signed-in user can open their profile from the avatar menu (**Settings**, or select the avatar). On the **Account** card they select **Edit**, change **Display Name**, **First Name**, **Last Name**, **Phone**, **Language**, **Locale** or **Time Zone**, and select **Save**. **Language** offers *English (en)* and *Hindi (hi)*; **Locale** and **Time Zone** are lists. Users cannot change their own username, e-mail, audience, active state, delegated approver or access. A field left empty on the profile page keeps its previous value — users cannot blank a field this way. To clear one, an administrator edits the account. ### Step 7 — Grant company access (multi-company organizations) Company access is not on the user dialog. Open **Setup → Feature Hub → Administration → Org Settings → Company Access**, choose the person in **Select a user**, then either switch on **Access all companies**, or select **Grant company access** and pick a **Company** and an **Access kind** — *Transact (see + post)* or *View (see only)*. The tab appears only when multi-company mode is on and you hold the company-administration capability. While **Access all companies** is on, the per-company rows are ignored. How this is enforced is explained in [Tenants and companies](/docs/concepts/tenants-and-companies/). ### Step 8 — Delete an account Deleting is part of offboarding — follow [Offboard or suspend a user](/docs/administration/users/deactivate-a-user/) first. Then select the delete icon in the **Actions** column of the Users list and confirm *Delete user?*. The account disappears from the list; the business records the person owned or created keep their attribution. ## Fields These are the fields in the **New User** and **Edit User** dialogs, in form order. | Field | What it means | Notes | |---|---|---| | Username | The name the person signs in with. | Must equal **Email** exactly, or be a plain name without `@` — letters, digits and `. - _ ! # ^ ~`, up to 64 characters. A username that is a *different* e-mail address is rejected. Fills itself from **Email** (or **Phone**) until you type in it. Leave it blank to sign in with the e-mail. | | First Name | Given name. | Used to compose **Display Name**. | | Last Name | Family name. | Used to compose **Display Name**. | | Email | Work e-mail address. Where the invitation goes, and a sign-in identifier. | Not required to be unique — search before you create. Spaces are trimmed on save. | | Phone | Contact phone number. | If the username is a phone number and **Phone** is empty, it is copied from the username. | | Display Name | The name shown across xMatix — lists, owner fields, mentions. | Follows **First Name** + **Last Name** until you type in it. Composed from them on save when blank. | | Audience | *Internal* (employees) or *External* (portal and partner users). | Required. Default *Internal*. A security profile scoped to the other audience cannot be assigned. | | Active | Whether the account is live for provisioning. | On by default. Only active accounts are provisioned and receive the welcome e-mail. Create accounts inactive to prepare them before go-live. Clearing it on an already provisioned account does not stop sign-in — see [Offboard or suspend a user](/docs/administration/users/deactivate-a-user/). | | Language | Interface language, as a language code. | Under **Locale & Time Zone**. Blank uses the organization default. | | Locale | Regional format for numbers, dates and currency, such as `en-IN`. | Under **Locale & Time Zone**. When it refines the chosen language (same base language), it also drives number grouping — `en-IN` shows lakhs and crores. | | Time Zone | The zone dates and times are shown in, such as `Asia/Kolkata`. | Under **Locale & Time Zone**. Overrides the organization time zone for this person. A name xMatix does not recognise is ignored and the organization zone applies. | | Delegated Approver | A user who receives, and may decide, this person's approval requests. | Under **Approvals**. Optional. The person themselves is not offered. | Read-only facts shown elsewhere: **Name** (set from the username on creation), **Status** and **Sign-in** on the detail page header. ## Business rules - **Username rule.** On create, and on any edit that changes **Username** or **Email**, the pair must be provisionable: the username equals the e-mail, or is a plain name of up to 64 allowed characters. The dialog stops you before saving, and the server enforces the same rule. - **Defaults on create.** **Active** on, **Audience** *Internal*, **Display Name** from first and last name, **Name** from username, then e-mail, then display name. An explicit **Active** off is kept. - **Provisioning trigger.** Any save of an account that is active, has a username or e-mail, and has no sign-in identity yet sends it for provisioning. Inactive accounts are never provisioned. Once the identity exists, further saves do not send another welcome e-mail. - **No uniqueness check.** Two accounts may share an e-mail or username. Search first; a duplicate splits the person's access across two accounts. - **System identities.** **System Process**, **System Agent** and **System Anonymous** cannot be edited or deleted from the Users screen. - **Delegation is one step.** A delegate is added alongside the approver, not instead of them; a delegate's own delegate is not included. Delegation applies whether or not the original approver is active. - **Self-service limits.** On the profile page a user may change only display name, first and last name, phone, language, locale and time zone. - **Deletion.** Deleting removes the account from your organization's lists and stops it resolving as a user. It does not delete records the person owned or created, and it does not delete a sign-in identity they also use with another organization. ## Example A distribution company hires a sales coordinator who works from Kochi and approves the field team's expense claims. 1. The administrator opens **Setup → Access Control → Users**, searches `sales.coordinator@example.com` and finds nothing. 2. They select **New** and type the address in **Email** — **Username** fills with the same address. They type *Sales* and *Coordinator* in the name fields; **Display Name** becomes *Sales Coordinator*. **Audience** stays *Internal*, **Active** stays on. Under **Locale & Time Zone** they enter `en`, `en-IN` and `Asia/Kolkata`. They select **Create**. 3. The row appears with Sign-in *Pending*; a minute later it shows *Ready* and the coordinator receives the set-password e-mail. 4. On the detail page the administrator adds the coordinator's profile on **Profile Assignments** and their role on **Role Assignments**. 5. Two months later the coordinator goes on leave. The administrator opens the account, selects **Edit**, expands **Approvals**, picks the regional sales manager as **Delegated Approver** and selects **Save**. Expense claims routed to the coordinator now reach the manager's inbox too; either can approve. 6. When the coordinator returns, the administrator clears **Delegated Approver** and saves. ## Training ### Practice exercise In a sandbox: 1. Create an account for a fictitious person with **Active** switched off. Confirm the list shows Sign-in *Not provisioned* after five minutes, or *Pending* before then, and that no e-mail is sent. 2. Try to set **Username** to a different e-mail address than **Email**. Expected: the dialog refuses with the username rule message. 3. Set the person's **Time Zone** to `Asia/Dubai` and **Locale** to `en-IN`, and save. 4. Name yourself as their **Delegated Approver**. 5. Open their **Access Diagnostics** tab. Expected: zero profiles, and nothing under *Allocated to user*. 6. Delete the account. Expected: it disappears from **All Users**. ### Quick reference - Users live at **Setup → Access Control → Users**. - Username = e-mail, or a plain name without `@` (≤ 64 characters). - Only **Active** accounts are provisioned; any save of an active, unprovisioned account retries. - Sign-in: *Pending* → *Ready*; *Not provisioned* after five minutes means fix and save again. - No profile assignment means an empty workspace. - User time zone and locale override the organization's for that person. - A delegated approver shares the requests; they do not replace the approver. - Company access is on **Org Settings → Company Access**, not on the user. - Never edit or delete **System Process**, **System Agent** or **System Anonymous**. ## Permissions | What | Needs | |---|---| | See **Users** in the menu | `setup.security.manage` and `setup.security.users.manage` | | Read, create, edit or delete accounts | `setup.security.users.manage` | | Assign profiles, roles and teams | `setup.security.manage` | | See **License Allocations** and **Access Diagnostics** for another user | `setup.licensing.admin` (you always see them on your own account) | | Preview **Outlet Transfer** scope | `setup.featurehub.settings.manage` — without it the card says so and the rest of the tab still loads | | Grant company access or **Access all companies** | `setup.companies.manage`, plus access to **Org Settings** | | Edit your own profile | Any signed-in user | A user without the user-administration capability does not see **Users** in Setup, and calls to read or change accounts are refused. The built-in **SystemAdmin** profile holds all of these. ## Configuration - **Organization defaults** — **Setup → Feature Hub → Administration → Org Settings → General** holds the default locale, currency, time zone and date format that every account without its own value uses. Changing them affects everyone who has not set a personal value. - **Per-user preferences** — **Language**, **Locale** and **Time Zone** on the account, set by an administrator or by the user on their profile page. - **Audience** — decides which security profiles fit the account. Profiles are scoped to Internal, External or Both on [Security profiles](/docs/administration/security-profiles/). - **Delegated approvers** — set per account under **Approvals**. Approval steps themselves are configured on the approval process; delegation applies to every process. - **Company access** — per user on **Org Settings → Company Access**, when multi-company mode is on. See [Tenants and companies](/docs/concepts/tenants-and-companies/). - **License seats** — per user on **License Allocations**; seat enforcement and pools are described in [Licensing](/docs/administration/licensing/). - **Deferred invitations** — create accounts with **Active** off to prepare them without provisioning or e-mail, then switch **Active** on at go-live. ## Common problems ### "This user has no sign-in identity yet" The account exists but provisioning has not completed. For the first few minutes after creation that is normal. If it persists, check that **Username** matches **Email** or is a plain name without `@`, and that the account is **Active**, then save the account again to retry. ### The dialog says the username must match Email The username is a different e-mail address from **Email**, contains a character outside letters, digits and `. - _ ! # ^ ~`, or is longer than 64 characters. Make it identical to the e-mail, or a plain name that follows the rule. ### Dates and times show in the wrong time zone for one person Their account's **Time Zone** is set to another zone, or to text xMatix does not recognise, in which case the organization zone applies. Have them pick the zone from the list on their profile page, or correct it under **Locale & Time Zone**. ### Numbers show millions instead of lakhs The person's **Locale** is blank or names a region that formats that way. Set **Locale** to `en-IN` (with **Language** `en`) or `hi-IN` (with **Language** `hi`). ### The delegate cannot see an approval request **Delegated Approver** is set on the wrong account — it goes on the account of the person who is *away*, naming the person who covers. It also covers only one step: if the delegate has their own delegate, that second person is not included. ### There is no Edit or Delete on an account It is one of the built-in system identities (Sign-in shows *System*). That is deliberate. ### I cannot find the Company Access tab It appears only when multi-company mode is on and you hold the company-administration capability, and it sits in **Org Settings**, which also needs the Feature Hub and Org Settings capabilities to reach from the menu. ## Common questions ### Can two accounts share the same e-mail address? xMatix does not prevent it, but you should not create them. The person's profiles, roles, teams and seats would be split between two accounts, and the e-mail would no longer identify one account. Always search the **All Users** list by e-mail before selecting **New**, and reuse an existing account — including one that is inactive — rather than creating another. ### Does a delegated approver replace the original approver? No. The delegate is added to every approval step that resolves to the original approver, so both see the request and either can decide it. Delegation does not depend on the original approver being away or inactive — it applies as soon as it is set — so clear **Delegated Approver** when cover is no longer needed. Only one step is followed: a delegate's own delegate does not receive the request. ### Why do two people see different times on the same record? Each person sees dates in their own **Time Zone** when one is set, otherwise in the organization's time zone. Two people looking at the same record can therefore see different clock times for the same moment. The stored value is the same; only its display differs. ### Can a user change their own e-mail or username? No. The profile page lets people change their display name, first and last name, phone, language, locale and time zone only. Changes to sign-in details, audience, active state, delegated approver and access are made by an administrator with the user-administration capability, so that a sign-in identifier always passes the username rule and is re-checked. ### What is the Name column, and how is it different from Display Name? **Name** is the account's record name, set when the account is created — from the username, or the e-mail, or the display name if both are blank. **Display Name** is the friendly name shown across xMatix in lists, owner fields and mentions, and it follows first and last name unless you set it yourself. ## Related topics - [Invite a user](/docs/administration/users/invite-a-user/) - [Offboard or suspend a user](/docs/administration/users/deactivate-a-user/) - [Security profiles and the grant matrix](/docs/administration/security-profiles/) - [Roles, teams and business units](/docs/administration/roles-teams-business-units/) - [Licensing](/docs/administration/licensing/) - [Tenants and companies](/docs/concepts/tenants-and-companies/) - [Why can't a user see something?](/docs/administration/user-cant-see-x/) - [User Account entity reference](/docs/reference/entities/user-account/) ---- # Create a dashboard in the dashboard designer URL: https://xmatix.com/docs/analytics/dashboards/create-a-dashboard/ Last reviewed: 2026-09-06 Building a dashboard is composition: choose the source appropriate to each widget, decide how to visualize it, and arrange the canvas. Native KPI and chart widgets read an entity, a report or a materialized dataset; the palette also includes report tables, embedded reports, maps, navigation buttons and text. The first step happens before the designer opens — confirming each source exists, returns the intended data and is accessible to the people who will view the dashboard. ## Prerequisites - Permission to create dashboards (the **New Dashboard** action in the Dashboards page header). - The intended sources, tested independently: entity data, a materialized Data Studio dataset, or a [report](/docs/analytics/reports/create-a-report/), depending on the widget. - A plan for the audience: dashboard visibility and each source's own access rules must all admit the viewer. Report-backed widgets require the report to be shared; entity- and dataset-backed widgets require access to those records or datasets. ## Procedure ### Step 1 — Create the dashboard Open **Dashboards** and choose **New Dashboard** in the page header. The **New Dashboard** menu also offers **From Entity** and **From Dataset**, which pre-build a starter layout over one source; the plain action starts from an empty canvas. @[guided-image](_img/dashboards-list.png) | Field | What it does | | --- | --- | | Name | Stable internal identifier. | | Label | The title readers see in the Dashboards menu and on the canvas. | | Description | Shown in the menu; say who the dashboard is for. | | Folder / Sub-folder | Where it sits in the Dashboards menu tree — pick an existing folder or type a new one; the sub-folder unlocks once a folder is chosen. | | Visibility | **Only me** (default), **All users**, or **Selected users** — the last asks for at least one role, profile or team and refuses to save with none. | | Icon | Menu icon; presentation only. | | Animation | How charts enter: Full, Subtle, Fade in together, Grow from the axis, Fast (for heavy filtering), Slow (for a wall board) or None. A reader whose system asks for reduced motion always gets None. | | Sort Order | Position within its folder. | | Active | Off hides the dashboard from readers without deleting it. | Leave visibility on **Only me** while building. **Create** saves the definition and opens it; a new dashboard starts with an empty canvas and stays private until you deliberately change visibility (**Edit** on the dashboard reopens this dialog). ### Step 2 — Enter design mode Open the dashboard and choose **Design**. The viewer switches into the designer: the same canvas, now editable, with the widget palette, page rail, filter editor and a settings drawer per tile. A **Desktop / Phone** switch lets you lay the same tiles out separately for narrow screens. ### Step 3 — Add a tile and bind its data Add a widget from the palette: **KPI**, **Chart**, **Table (report)**, **Report (embedded viewer)**, **Map**, **Buttons (navigation)** or **Text**. For a KPI choose **Entity** or **Report** as the source; a chart additionally accepts **Dataset**. Report and dataset selectors list only definitions you can access; an entity-backed widget still runs under entity and record security. A live-data toggle renders every tile with real, permission-scoped data while you design; off, each tile shows a one-line summary so heavy dashboards stay responsive. ### Step 4 — Bind fields Assign fields and measures to the widget's supported slots in its settings drawer: category and value series for charts, the measure and aggregation for a KPI (with optional colour bands and weights), columns for a table, or the selected report for an embedded viewer. Calculated fields and hierarchies (drill paths such as region → branch) are defined in the designer and then offered as fields. Repeat for each widget, resizing and arranging as you go. A source type does not make every field valid for every widget, so use the drawer's offered fields rather than typing assumptions. ### Step 5 — Add filter elements Use the **Dashboard filters** editor in the designer toolbar to configure the filter bar. Filters are dashboard controls, not draggable tiles on the canvas. A branch and period filter can let one dashboard replace a family of near-duplicates; verify that each target widget recognizes the chosen field and value type — the editor shows which tiles a filter reaches. Clicking a chart's bar or slice also filters the same-entity tiles to that group instead of opening the entity list. ### Step 6 — Optional pages, alerts and style The page rail lets a dashboard hold several pages; a page can also be marked as a *tooltip page*, which is never opened directly but drawn beside a point when a reader hovers a chart that names it. **Alerts** attach threshold conditions to tiles, **Saved views** capture page-plus-filter states readers can return to, and **Dashboard style** sets the canvas theme. ### Step 7 — Save and review Save from the designer, then leave design mode and read the dashboard as a viewer will. When the design is dirty, the close action becomes **Discard & close** and leaves immediately; there is no extra confirmation dialog. Save before using it unless you intentionally want to discard the current edits. ### Step 8 — Share it — twice over Share the dashboard with its audience (**Edit → Visibility**), then verify the access path for every widget source. Share each backing report with the same audience; grant appropriate dataset access for dataset-backed widgets; and confirm the viewer's entity, field and record permissions for entity-backed widgets. The dashboard cannot widen any of those source permissions. The mechanics are in [Sharing & access](/docs/analytics/sharing-and-access/). **Expected result:** the dashboard opens outside design mode with every tile populated, shared viewers can discover it in their Dashboards menu, and those viewers also have access to each backing report. ## Reading and working with the finished dashboard The viewer toolbar offers **Design** (for people allowed to edit), **Clone** (copy under a new name and design your own), **Comments**, **Change history**, **Views** (saved page and filter states, including **Save current view…**), **Find a tile**, and **Export** as PDF or PNG image — the export matches the filters on screen. Each tile can be focused full-width. Where dashboard subscriptions are enabled for the deployment, a **Subscribe** action schedules delivery of the rendered dashboard. ## Common problems - **The expected source is absent.** Check the widget's supported source types first, then verify that the report or dataset exists and is visible to you. For Entity, confirm the entity is available under your permissions. - **Widgets are empty for other people but fine for you.** Test the source type: share a backing report, grant the dataset access, or correct the viewer's entity and record grants. Sharing only the dashboard is never a source-access bypass. - **The viewer says the definition is invalid.** The stored layout was damaged or edited outside the designer. The viewer reports that the definition is invalid rather than silently showing a blank canvas. Repair or rebuild it in the designer; never edit the stored definition by hand. - **The dashboard is missing from someone's menu.** Check Visibility (Only me is the default), the Active switch, and that the viewer has at least one of the selected roles, profiles or teams. ## Common questions ### Can two people design the same dashboard at the same time? Avoid it. A designer save writes the whole layout, so when two people design concurrently, the last save wins and the other person's changes are overwritten — there is no merge. Coordinate edits, or clone-and-replace instead of editing live. **Change history** shows who saved what, so an overwrite can at least be traced. ### Do viewers need access to the reports behind the tiles? Only report-backed widgets do. The dashboard's own visibility controls whether it is listed and opens, but each widget still uses its source's authorization: report visibility for reports, dataset access for materialized datasets, and entity/field/record security for entities. ### Is the dashboard live, or a snapshot? Live for the reader: each tile queries under that viewer's access when the dashboard opens or a filter changes, so two people can see different numbers from the same tile. Exports and scheduled deliveries are point-in-time renderings of what was on screen. ## Related topics - [Dashboards in xMatix](/docs/analytics/dashboards/) - [Create a report](/docs/analytics/reports/create-a-report/) - [Sharing & access](/docs/analytics/sharing-and-access/) - [Subscriptions](/docs/analytics/subscriptions/) ---- # Dashboards in xMatix URL: https://xmatix.com/docs/analytics/dashboards/ Last reviewed: 2026-09-06 A dashboard is a canvas of widgets — KPIs, charts, tables, embedded reports, maps, navigation buttons and text — arranged in a visual designer and opened from **Dashboards**. Its definition holds layout and source configuration, never a copy of the numbers: every time a dashboard opens, each widget's data is evaluated on the server for the person looking at it. Native widgets read an **entity**, a **report** or a Data Studio **dataset**; the dashboard's own visibility decides who can open it, and each source's own access rules decide what they see inside it. Building one is covered in [Create a dashboard](/docs/analytics/dashboards/create-a-dashboard/); this page explains how the library, the viewer and the access model work. ## The dashboard library @[guided-image](_img/dashboards-concept.png) **Dashboards** in an app's navigation opens the library. The left-hand menu carries the scopes — **Favourites**, **My Dashboards**, **All Dashboards** — and below them the folder tree; a bar under the page header lists the dashboards you opened most recently. The page header offers three ways to start: **New Dashboard** (an empty canvas after a properties dialog), **From Entity** (a starter layout generated over one entity) and **From Dataset** (a starter layout over a compiled Data Studio dataset). The table shows a **star** (favourite) and a **bell** (subscribe) toggle, then **Name**, **Type**, **Description**, **Folder**, **Status** (Active or Inactive), **My usage** (how often you have opened it and when last), **Created**, **Created By**, **Modified**, **Modified By** and the actions column. Clicking a name opens the viewer. **Type** reads *Dashboard* for a native dashboard; rows marked *Data Studio* are an older dashboard kind that still opens but no longer has a designer. The row actions are **Design** (native dashboards only — opens the designer), **Edit** (the properties dialog: name, label, description, folder, visibility, icon, animation, sort order, active) and **Delete** (permanent, after a confirmation). Two limits of the library are worth knowing. It lists only dashboards you are allowed to see — a dashboard nobody shared with you is not there, and neither is an inactive one. And **My Dashboards** does not currently apply an owner filter: it shows the same rows as **All Dashboards**, so use the **Created By** column to find your own. ## Folders A folder is a name stored on the dashboard, not a managed hierarchy. The library reads it as *who it is for*, then *what it is about*: a path such as `Sales Manager/CRM` files the dashboard under the **Sales Manager** persona with a **CRM** sub-folder, while a plain name such as `Sales` is a flat folder listed after the personas. One dashboard can sit in several folders at once — the properties dialog lets you pick more than one path — without being copied. Folder placement aids discovery only; it grants no access. ## The viewer @[guided-image](_img/dashboard-viewer.png) Opening a dashboard adds a workspace tab beside **All Dashboards** and renders the canvas. Three regions matter: - **Pages.** A dashboard with more than one page shows a page switcher in its header (here *Charts* and *Cards, tables & more*); each page is its own canvas over the same filters. - **The filter bar.** Filters the designer configured appear as chips — a branch or region picker, a value range, a date preset such as *Last 90 days* with a custom-range option, and **what-if parameters** shown as a slider whose value feeds target and reference lines. Each chip shows how many of the page's tiles it reaches (*10 of 35*). Clicking a bar or slice in a chart cross-filters the other tiles built on the same entity instead of navigating away. - **The toolbar.** From left to right: **Views** (save the current page and filter state as a named personal view, and switch between your views), **Clone** (copy the dashboard under a new name so you can design your own), **Find a tile**, the favourite **star**, **Comments**, **Delete**, **Design** (opens the designer), the subscribe **bell**, **Full screen**, **Refresh data** and **Export** (PDF, or a PNG image, matching the filters on screen). Tiles that offer it carry their own **Group by** and **Measure** switches, and every tile has a focus button that enlarges it. ## Where widget data comes from Data-bearing widgets declare a source type. A **KPI** reads an entity or a report; a **chart** reads an entity, a report or a dataset; a **table** and an **embedded report** read a report; a **map** reads an entity with location data. Report and dataset pickers list only definitions the designer can access, and entity-backed widgets run through the same entity, field and record security as the rest of the application. Because each widget carries its own source, one dashboard can mix an entity-backed sales chart, a dataset-backed inventory chart and an embedded receivables report without pretending they share one security path. ## How a dashboard loads When a dashboard opens, the server evaluates every widget's query under the viewing user's access and returns one batch. That batch is cached per user for a short interval — 60 seconds by default — and the viewer refetches on the same rhythm, so **Refresh data** is only offered again once the cached minute has passed. Two consequences follow: - **Data is near-live, not a snapshot.** A number can be up to a minute old; there is no result history inside the dashboard itself (the **Change history** panel tracks edits to the definition, not the data). - **Access is evaluated per viewer and per source.** Sharing the dashboard lets someone open it; whether a tile shows data depends on that person's access to the tile's report, dataset or entity records. A viewer who lacks report access sees an empty tile, not an error. ## Sharing and delivery A new dashboard is visible only to its creator. **Edit** → **Visibility** offers **Only me**, **All users** or **Selected users**, the last naming roles, profiles and teams — the same [visibility rule](/docs/analytics/sharing-and-access/) reports follow, including the absence of an administrator bypass and the rule that an inactive dashboard is hidden from everyone. Administrators see the complete inventory in **Setup → Data Studio → Analytics → Dashboards**. The **bell** on a row or in the viewer opens the [Subscribe](/docs/analytics/subscriptions/) dialog: a dashboard is emailed as a **PDF** on your schedule, rendered by the background worker *as you* — with your filters' defaults and your access — so the attachment matches what you see on screen. A deployment can switch dashboard subscriptions off, in which case the bell simply does not appear. Designers can also add **alerts** to KPI tiles: a threshold checked on its own schedule, delivered in-app or by email the first time it is crossed and again when it recovers. ## Common questions ### Why does a colleague see empty tiles on a dashboard I shared? Because widget data loads under the viewer's own access, sharing the dashboard is only half the job. Identify the empty tile's source and grant that: share its report, or check the viewer's access to the entity records or dataset it reads. The reasoning and the fix are in [Sharing & access](/docs/analytics/sharing-and-access/); if the tile is empty for you as well, open the source report directly — the problem is upstream. ### Does a dashboard store data or snapshots? No. It stores layout, widget definitions, filters and pages. Results are evaluated at open time and cached per user for about a minute, so "near-live" is the right expectation. A subscription PDF is a point-in-time rendering generated for that send; a personal **View** saves a page and filter state, not the numbers. ### Can one dashboard show data from several entities? Yes — that is the normal case. Each widget has its own source, so orders, inventory, receivables and visits can sit side by side as entity-, report- or dataset-backed tiles. Cross-filtering by clicking a chart applies to tiles on the same entity; filter-bar chips show how many tiles they reach so you can tell which widgets a filter will and will not affect. ### What is the difference between a filter, a view and a page? A **filter** is a control the designer placed in the bar; readers change its value. A **view** is a reader's saved combination of page and filter values, private to them and listed under **Views**. A **page** is a second canvas inside the same dashboard, sharing the filter bar. Designers define filters and pages; readers create views. ## Related topics - [Create a dashboard](/docs/analytics/dashboards/create-a-dashboard/) - [Reports in xMatix](/docs/analytics/reports/) - [Sharing & access](/docs/analytics/sharing-and-access/) - [Subscriptions](/docs/analytics/subscriptions/) - [Build a dataset](/docs/data-studio/datasets/) ---- # Document reports — print formats for records URL: https://xmatix.com/docs/analytics/document-reports/ Last reviewed: 2026-09-06 A document report is the third report format: not an interactive grid or a pivot but a designed, paginated document — an invoice layout, a purchase-order form, a delivery note, a payslip, a statement. Its data comes from the same wizard as every other report; its appearance is drawn in the full [report designer](/docs/analytics/reports/report-designer/), band by band, so the output is print-grade and deliberate. What makes document reports distinctive is *where they run*: mostly not from the report library, but from the records they describe. @[guided-image](_img/document-reports-context.png) In the **Reports** library a document report is an ordinary row whose **Type** reads *Document Report* (a grid report reads *Report*). The page header offers three starts — **New** for a grid report, **New Document Report** for a print format, **New Pivot Report** for a pivot — and the library's folders, favourites and subscriptions apply to all three alike. ## Two halves: data and layout Every document report has a data definition and a layout. - **Data** is built in the wizard, which titles this pass **Document Report Data** and walks eight steps: Data Source (the primary entity and its related entities), Relationships, Fields, Columns, Display Grouping, Display Summary, Filters and Details. **Next** stays disabled until the current step has what it needs — a primary entity first of all. - **Layout** is built in the banded report designer: page bands, headers and footers, detail rows, groups and totals, images and labels. The split shows up in the Setup analytics screen as two separate row actions — **Edit Report** for the data, **Design Report** for the layout — and in practice as two different skills: the data half is query thinking, the layout half is page design. ## Where document reports surface - **On records, as Print and Preview actions.** This is the main stage. An administrator adds an action of type **Preview** or **Print** to an entity under Design Studio → Entities → the entity → Logic → Actions, and the action form asks for the document report to render. When a user runs the action, the current record's identifier is passed to the report as its `Id` parameter, so the layout renders just that record. **Preview** opens the rendered PDF in a viewer inside the page; **Print** renders it and hands it straight to the browser's print dialog. - **From lists, for selected records.** The same actions run from a list over the selected rows, passing every selected identifier. The records are rendered into one PDF with each record starting on a fresh page — which is what a *Bulk Invoice Print* format is for. An action can be marked as requiring a selection, in which case running it with nothing selected prompts for one instead of rendering everything. - **In the report library.** A document report you can see is listed under **Reports** like any other and opens in a paginated viewer with page navigation, zoom, **Print** and **Export**. Run this way — without a record context — it renders whatever its own query and filters return; a report whose query returns nothing shows an empty document rather than an error. - **In subscription emails.** A [subscription](/docs/analytics/subscriptions/) to a document report exports the designed layout on schedule, so the attachment matches the printed form. ## Access follows the report rules A document report is a report: the [visibility rule](/docs/analytics/sharing-and-access/) decides who sees it in the library, and it starts private to its creator. Wire it to a record action and share it with the users who run that action — an unshared print format is the classic reason a Print button works for the administrator who built it and fails for everyone else. The record action itself is also permissioned like any custom action: the user's profile must grant it. ## Common questions ### How do I put a Print button on invoices? Two pieces. First, build the document report: **Reports → New Document Report**, define the data over the invoice entity (joining the customer and the invoice lines), then lay out the form in the designer — the full walk-through is in [the report designer guide](/docs/analytics/reports/report-designer/). Second, have an administrator add a **Print** action on the invoice entity that references that report, and share the report with the users who will print. From then on the button renders the current invoice and opens the print dialog; the same action on the invoice list prints the selected invoices as one PDF. ### Can one document report serve several entities? A document report is built over one primary entity — its query starts there, and record actions pass identifiers of that entity's records. Related data comes in through relationships (an invoice layout routinely prints customer fields and line items), but for genuinely different documents — an invoice form and a purchase-order form — build one document report each. ### What's the difference between a document report and exporting a grid to PDF? A grid export is the table, as rendered: columns, rows, whatever you filtered. A document report is a designed page: headers and footers where you put them, one record per document if that is the design, logo, addresses, totals in the right corner. Use exports to move data; use document reports when the page itself is the deliverable. ### Why does the report open empty from the library but print fine from a record? Because the library run has no record context. The report's own filters decide what it returns, and a layout designed around a single record often has a filter that matches nothing until an `Id` is supplied. That is expected; test print formats from the record action, not from the library. ## Related topics - [Report designer](/docs/analytics/reports/report-designer/) - [Reports in xMatix](/docs/analytics/reports/) - [Sharing & access](/docs/analytics/sharing-and-access/) - [Subscriptions](/docs/analytics/subscriptions/) ---- # xMatix Analytics & Reporting URL: https://xmatix.com/docs/analytics/ Last reviewed: 2026-09-06 Analytics & Reporting is where operational and curated data becomes something you read. A **report** is a saved query with presentation — which entity it reads, what it joins, which columns, groups, summaries and filters — run live every time it opens. A **dashboard** assembles KPI, chart, table, report, map, button and text widgets into one canvas, each widget reading an entity, a report or a Data Studio dataset under the viewer's own access. **Subscriptions** email a report on a schedule in the format you choose, or a dashboard as a PDF rendered under your own access. **Document reports** turn records into designed print formats such as invoices and purchase orders. All of it runs inside the same access model as the rest of xMatix: what you can see is what you have been granted. ## Choose the right surface | You want to… | Use | Where it lives | | --- | --- | --- | | List, sort, group and export live records | A **grid report** | **Reports** → **New** | | Cross-tabulate one dimension against another | A **pivot report** | **Reports** → **New Pivot Report** | | Print a record as a designed page | A **document report** wired to a record action | **Reports** → **New Document Report**, then the entity's Print/Preview action | | Watch several numbers on one screen | A **dashboard** | **Dashboards** → **New Dashboard**, **From Entity** or **From Dataset** | | Receive a report or dashboard by email without opening the app | A **subscription** | The bell on a library row or in the viewer | | Compute a governed, pre-aggregated table once and reuse it | A **dataset** | [Data Studio](/docs/data-studio/) → Dataset Builder | Every object is a governed definition, not a permission bypass and not a durable copy of somebody else's view: source security still applies when the query runs, and a new report or dashboard is visible only to its creator until it is shared. ## What's in this section | Page | What it covers | | --- | --- | | [Reports](/docs/analytics/reports/) | The report library, the grid, pivot and document formats, folders and favourites, row actions, and what happens when a report runs | | [Create a report](/docs/analytics/reports/create-a-report/) | The report wizard end-to-end — data source, relationships, fields, columns, grouping, summaries, bucketing, filters, details | | [Report designer](/docs/analytics/reports/report-designer/) | The banded layout designer for document reports — bands, controls, properties, preview, save | | [Dashboards](/docs/analytics/dashboards/) | The dashboard library, widget sources, how a dashboard loads, filters, sharing and delivery | | [Create a dashboard](/docs/analytics/dashboards/create-a-dashboard/) | The dashboard designer — widgets, governed sources, filter bar, pages, alerts, saving and sharing | | [Subscriptions](/docs/analytics/subscriptions/) | Scheduling a report or dashboard for email delivery — formats, schedules, recipients, what is and is not checked at send time | | [Sharing & access](/docs/analytics/sharing-and-access/) | Who can see a report or dashboard — the visibility rule and its pitfalls | | [Document reports](/docs/analytics/document-reports/) | Print formats for records, and the Print and Preview actions that surface them | | [Troubleshooting](/docs/analytics/troubleshooting/) | Missing or empty reports, blank dashboards, subscription emails that never arrive or arrive at the wrong hour | ## Where Data Studio begins Reports remain the primary surface for live operational questions: they run against current records the moment they open. [Data Studio](/docs/data-studio/) is where curated **datasets** and **data models** are defined, compiled into the analytics warehouse and rebuilt on a schedule, and where **archive rules** move cold history out of the working system. Dashboards consume those materialized datasets through **From Dataset** and dataset-backed chart widgets. If you are deciding which to use: start with a report or an entity-backed dashboard for a current operational question; move to Data Studio when one governed definition should be computed once and serve many consumers, or when the workload belongs in the warehouse rather than in the transactional path. ## Permissions and administration - **Reading** a report or dashboard needs only that it is active and shared with you (creator, all users, or one of your roles, teams or security profiles). There is no administrator bypass in the end-user menus. - **Creating** reports and dashboards happens in the **Reports** and **Dashboards** pages of any app that carries them; the page-header actions appear for users allowed to create. - **Administering** the whole inventory — every report and dashboard regardless of sharing, plus measures, calculated fields and hierarchies for dashboards — is **Setup → Data Studio → Analytics**, gated by the analytics administration capability (`setup.metadata.analytics.manage`). That screen is also where a report is deactivated or reactivated. ## Who this section is for Everyday users who open, filter and subscribe to reports need only the [Reports](/docs/analytics/reports/) and [Subscriptions](/docs/analytics/subscriptions/) pages. Analysts and administrators who build content should read the two creation guides and — before publishing anything — [Sharing & access](/docs/analytics/sharing-and-access/), because everything you create starts visible only to you. ## Related topics - [Data Studio documentation](/docs/data-studio/) - [Getting around xMatix](/docs/getting-started/navigation/) - [Analytics & Reporting product overview](/products/analytics/) - [Book a demo](/demo/) ---- # Create a report with the report wizard URL: https://xmatix.com/docs/analytics/reports/create-a-report/ Last reviewed: 2026-09-06 The report wizard builds grid and pivot reports step by step: choose the entity the report reads, join the related entities it needs, pick fields and arrange them as columns, add grouping, summaries, buckets and filters, then name and save it. The result opens immediately in the viewer and behaves like any other report — shareable, cloneable, subscribable. Document reports start in the same wizard (titled **Document Report Data**) and continue into the [report designer](/docs/analytics/reports/report-designer/). ## Prerequisites - The **Reports** page of an app you can open; the **New** actions sit in its page header. - A clear idea of the primary entity — every row of a report starts as a row of one entity, with related data joined onto it. - For a pivot report, know what you want on rows, on columns and aggregated in the cells before you start; it makes the layout step quick. ## The step rail A grid report walks nine steps: **Data Source**, **Relationships**, **Fields**, **Columns**, **Display Grouping**, **Display Summary**, **Bucketing**, **Filters**, **Details**. A pivot report replaces Columns, Display Grouping and Display Summary with one **Pivot Layout** step and skips Bucketing. A document report skips Bucketing. **Next** stays disabled until the current step has what it needs; **Reports** in the header leaves the wizard without saving. ## Procedure ### Step 1 — Start a new report Open **Reports** and choose **New** for a grid report or **New Pivot Report** for a pivot. The wizard opens as **New Report** (or **New Pivot Report**) on the Data Source step. ### Step 2 — Choose the data source Pick the **Primary Entity** — orders, invoices, visits, any entity in your data model including custom ones. This decides what one row of the report *is*: a report on orders produces one row per order, before any grouping. Once it is chosen, **Related Entities** lists the entity's lookups (link icon) and child collections (branch icon); tick the ones whose fields you need, and expand one to walk further along the relation. **Search related entities** narrows a long list. @[guided-image](_img/report-wizard-source.png) ### Step 3 — Set the relationships Each ticked relation gets a **Record matching** rule: **Keep all base records** (a left join — rows without a match keep their place with blank related fields) or **Only matched records** (an inner join — rows without a match are dropped). **Additional match rules** let you add field-to-field conditions on top of the relation's own key. Reach for *Only matched records* deliberately: it is the most common reason a finished report has fewer rows than expected. ### Step 4 — Choose fields Select the fields to include from the primary entity and everything you joined. Fields are listed per entity with their captions; a lookup field brings its display name along, so a report on orders can show the account's name rather than its identifier. ### Step 5 — Arrange the columns The **Columns** step turns selected fields into the grid: set each column's **caption**, **Width (px)** and default sort (ascending or descending), drag to reorder, and group related columns under a **band** — a header row that spans several columns, given its own band label. You can also add a **calculated column**: an expression over the other columns. The expression is validated as you type against the columns actually present in the report, and an invalid one is refused with the position of the problem, so fix it in place before continuing. ### Step 6 — Group and summarize **Display Grouping** nominates columns to group rows by — by customer, by status, by a date at **Year**, **Quarter**, **Month**, **Day** or **Day of Week** granularity. **Display Summary** adds the arithmetic: **Sum**, **Average**, **Count**, **Min** or **Max** per column, shown per group and for the report total, with optional custom labels and a choice of where group summaries appear (in the group row, in a group footer, or both). A report with grouping and summaries reads as answers rather than raw rows. ### Step 7 — Add buckets (grid reports) **Bucketing** splits a measure across generated columns so a flat query becomes a comparison you can scan. Each bucket definition has a **Label**, an **Active** switch, a **Bucket type** — **Numeric ranges** you define (half-open: from ≤ value < to), **Picklist values** (one column per value) or **Date** (calendar periods, or a comparative period such as this month against last) — the field to **Bucket on**, an **Aggregate** (type and field) and an optional **Caption prefix**; values outside your ranges land in an **Overflow** column labelled *Other* unless you rename it. The wizard warns when a filter already restricts the field you are bucketing on. ### Step 8 — Filter Add the report's built-in conditions — the ones that define what the report *means*, such as `Status = Open` or a date window. Mark a condition as **Promoted** to expose it in the viewer as a filter bar, so readers can change the period or branch without opening the filter builder. Viewers can always add their own filters on top; theirs narrow the result without changing yours. ### Step 9 — Name it and save The **Details** step takes the **Name** (a unique internal name such as `MonthlyRevenueReport`), the **Label** readers see, a **Description** and the **Folder** — pick an existing folder or type a new one, as `Persona/Sub-folder` or a plain name (see [Reports](/docs/analytics/reports/) for how folders are read). For a grid report, **Grid Layout** offers *Use centered content width* for narrow reports. Visibility is not set here: the step reminds you that reports are created as private and shared afterwards. Save, and the report opens in its viewer with live data. ### Step 10 — Share it A new report is visible only to you. When it is ready for others, open its row's **Edit** action in the library and set **Visibility** to **All users** or **Selected users** with roles, profiles and teams — see [Sharing & access](/docs/analytics/sharing-and-access/) for the mechanics and the pitfalls. **Expected result:** the saved report opens with live rows, its totals and filters answer the intended question, and only the selected audience can discover and run it. ## Pivot reports Choosing **New Pivot Report** swaps the column steps for **Pivot Layout**: drag the selected fields into the **row**, **column** and **data** areas and choose each data field's aggregation. Adding or removing fields in the Fields step is reflected in the layout immediately without losing the placements you already made. The saved report opens in the pivot viewer as a matrix and exports to Excel and PDF. ## Common problems - **Fewer rows than expected.** Almost always a relation set to *Only matched records* dropping rows that have no match, or a built-in filter tighter than intended. Switch the rule to *Keep all base records*, or loosen the filter, and compare the **Total Records** count. - **A calculated column will not save.** The expression validator rejected it and reports the offending position. Check field names against the columns you actually selected — an expression can only reference columns present in the report. - **The report runs but colleagues cannot find it.** It is still private. Nothing is wrong with the report — share it ([Sharing & access](/docs/analytics/sharing-and-access/)). - **Next is disabled.** The current step is missing something required — most often a primary entity on Data Source or a label on Details. ## Common questions ### Can I change a report after saving it? Yes — **Edit** in the report viewer's actions menu, or **Design** on the library row, reopens the wizard pre-filled with the current definition, and saving applies the changes in place. Sharing and subscriptions survive the edit; anyone who runs the report next sees the new definition. Note that **Save** in the viewer toolbar also writes column and filter changes into the shared definition — see [Reports](/docs/analytics/reports/). ### When should I pick a pivot report over a grid? Pick a pivot when the question is inherently two-dimensional — sales by product *by month*, counts by status *by team* — and you want the second dimension spread across columns with aggregated cells. Pick a grid when you need to see and work with the individual rows: sorting, scanning, exporting a list. A grid with bucketing covers the middle ground, generating comparison columns while keeping the row-level view. ### Is the data a snapshot from when I built the report? No. A report stores only its definition; the query runs afresh every time anyone opens it, so the result always reflects the data at that moment. If you need a fixed point-in-time copy, export the result from the viewer, or set up a [subscription](/docs/analytics/subscriptions/) — each delivery is generated at send time. ## Related topics - [Reports in xMatix](/docs/analytics/reports/) - [Report designer](/docs/analytics/reports/report-designer/) - [Sharing & access](/docs/analytics/sharing-and-access/) - [Subscriptions](/docs/analytics/subscriptions/) ---- # Reports in xMatix URL: https://xmatix.com/docs/analytics/reports/ Last reviewed: 2026-09-06 A report in xMatix is a saved query with presentation: which entity it reads, which related entities it joins, which columns it shows, how rows are grouped, summarized and filtered. Nothing is copied or staged — every time a report opens, its query runs live against your organization's data, so what you see is current as of that moment. Reports are built in the [report wizard](/docs/analytics/reports/create-a-report/), shared through an explicit [visibility list](/docs/analytics/sharing-and-access/), and can be [emailed on a schedule](/docs/analytics/subscriptions/). ## The report library @[guided-image](_img/reports-concept.png) **Reports** in an app's navigation opens the library. The left-hand menu scopes the list — **Favourites**, **My Reports**, **Subscribed**, **All Reports** — and below the scopes sit the folders, one entry per folder in use, nested where folder names contain a sub-folder. The page header carries the three creation actions, one per format: **New** (a grid report), **New Document Report** and **New Pivot Report**. Each opens the wizard for that format; **New Document Report** continues into the layout designer once the data is defined. The table shows **Name**, **Type** (*Report*, *Document Report* or *Pivot Report*, filterable), **Description**, **Folder** (filterable), **Created**, **Created By**, **Modified**, **Modified By** and an actions column. Clicking a name opens the report in the viewer for its format. Two per-row toggles sit before the name: the **star** adds the report to your Favourites and the **bell** opens the [Subscribe](/docs/analytics/subscriptions/) dialog (filled when a subscription already exists). The row actions are: | Action | What it does | | --- | --- | | **Design** | Reopens the definition for editing — the wizard for grid and pivot reports, the layout designer for document reports. | | **Create dashboard** | Grid reports only: starts a new dashboard with this report as its first data source. | | **Edit** | Opens the properties dialog: **Name**, **Description**, **Folder** and **Visibility** (Only me / All users / Selected users with roles, profiles and teams). This is where a report is shared. | | **Delete** | Removes the report permanently after a confirmation. | Two things the library does not do. It shows only reports you are allowed to see — a report someone else created and never shared is not listed at all, and neither is a deactivated report. And **My Reports** does not currently apply an owner filter: it lists the same reports as **All Reports**, so use the **Created By** column, not the scope, to find your own. ## The three report formats | Format | What it is | Typical use | | --- | --- | --- | | **Grid** (*Report*) | An interactive table — sortable, groupable, filterable, with summaries and optional bucketing columns | Operational lists: open orders, overdue invoices, stock by branch | | **Pivot** | A matrix that cross-tabulates rows against columns with aggregated measures | Sales by product by month, counts by status by team | | **Document** | A designed, paginated layout built in the full [report designer](/docs/analytics/reports/report-designer/) | Invoice and purchase-order print formats, statements — see [Document reports](/docs/analytics/document-reports/) | The format is chosen when the report is created — each **New** action starts one format's wizard — and cannot be switched afterwards. Each format opens in its own viewer. ## Viewing a grid report @[guided-image](_img/report-viewer-grid.png) Opening a grid report runs its query and loads rows into the table in pages as you scroll, so large reports open quickly. The header shows **Total Records** and any report-level summaries the author defined (a *SUM Quantity*, for example); grouped reports show a heading row per group with its own subtotals, and the toolbar's expand and collapse buttons open or close every group at once. The toolbar also offers search, refresh, **Filters** (your own conditions on top of the report's built-in ones), **Columns** (show, hide and reorder) and **Save**. **Save is a shared change, not a personal view.** It writes the current column arrangement, grouping, sort and filter state back into the report definition (the toast reads *Report saved*), so everyone who opens the report next sees what you saved. Use it to tidy a report you own; for a private variation, **Clone** the report and adjust the copy instead. Unsaved arrangements are remembered only in your browser for the session. The toolbar's menu carries the report-level actions: **Export to Excel** and **Export to PDF** (the current result, with your filters applied), **Edit** (reopens the wizard), **Clone**, **Add to favourites**, **Subscribe** and **Delete**. Reports whose author promoted filters show them as a filter bar above the grid, so a viewer can change the period or branch without opening the filter builder. ## Viewing pivot and document reports A pivot report opens as a matrix: the fields the author placed on rows and columns form the axes, and the measures aggregate in the cells; it exports to Excel and PDF like a grid. A document report opens as paginated pages rendered from its designed layout, with page navigation, zoom, print and export — but most document reports are reached from a record's **Print** or **Preview** action rather than from the library, because run without a record they render whatever their own filters return; see [Document reports](/docs/analytics/document-reports/). ## Folders, favourites and subscriptions Folders are names stored on the report, not a managed hierarchy: a report's **Folder** is set in the wizard's Details step or the row's **Edit** dialog, and a name that does not exist yet creates the folder. The library reads a path as *who it is for*, then *what it is about* — `Sales Manager/CRM` files the report under the **Sales Manager** persona with a **CRM** sub-folder, a plain `Sales` is a flat folder — and one report can be filed under several paths at once without being copied. Marking a report as a favourite pins it into your **Favourites** scope — the flag is personal, not shared. Subscribing puts the report in your **Subscribed** scope and emails it to you on a schedule — as PDF, Excel, CSV or embedded in the message body for a grid report; the mechanics, formats and limits are on [Subscriptions](/docs/analytics/subscriptions/). ## What runs when a report opens The report's query runs against live records. Two access checks apply: the report itself must be visible to you (active, and shared with you or created by you), and the entities it reads are read as the platform's query layer exposes them. The report's built-in filters and joins define the result set; your own viewer filters narrow it further for you alone. Because the query is defined by the author, the audience you share a report with sees the rows that query returns — a point that matters when [sharing](/docs/analytics/sharing-and-access/) a report over sensitive data. ## Common questions ### Who can see a report I create? Only you, until you share it. A new report — and a clone of an existing one — starts visible to its creator alone; other users, including administrators browsing the Reports menu, will not see it listed. Sharing is a deliberate act from the row's **Edit** dialog: everyone, or selected roles, profiles and teams. The full model is in [Sharing & access](/docs/analytics/sharing-and-access/). ### Can I start from an existing report instead of a blank one? Yes — **Clone** in the report viewer's actions menu copies the definition. The copy belongs to you and starts private, so you can rename it, adjust columns and filters through the wizard, and share it when it is ready, all without touching the original. ### What is the difference between deactivating and deleting a report? Deactivating — the **Active** switch in **Setup → Data Studio → Analytics → Reports → Edit Report** — hides the report from every user's library, including its creator's, while keeping the definition and sharing intact so it can be reactivated later. Existing subscriptions are not paused by deactivation: they keep sending until the subscriber unsubscribes or the report is deleted. Deleting removes the report permanently and ends its deliveries. Before deleting, check whether any dashboard uses the report as a widget source: those widgets lose their data when the report goes. ### Does Save in the viewer change the report for everyone? Yes. **Save** in the viewer toolbar writes your column, grouping, sort and filter arrangement into the report definition itself, so it is the same as editing the report in the wizard. There is no per-user saved view for reports today; if you want a variation without touching the shared report, **Clone** it and save your arrangement on the copy. ### Why does my report show fewer rows for a colleague than for me? Usually because the colleague has unsaved viewer filters applied, or because they are looking at a different report of the same name — the library allows duplicate names in different folders. The report's own rows are defined by its query, not by who opens it; if the counts differ with no filters set, compare the two reports' definitions. ## Related topics - [Create a report](/docs/analytics/reports/create-a-report/) - [Report designer](/docs/analytics/reports/report-designer/) - [Sharing & access](/docs/analytics/sharing-and-access/) - [Subscriptions](/docs/analytics/subscriptions/) - [Troubleshooting analytics](/docs/analytics/troubleshooting/) ---- # Design a document report in the report designer URL: https://xmatix.com/docs/analytics/reports/report-designer/ Last reviewed: 2026-09-06 Grid and pivot reports are built entirely in the wizard; a **document report** has a second half. Its data — entity, relationships, fields, filters — still comes from the wizard, but its appearance is drawn in the full report designer: a page-layout surface where you place fields, labels and images into bands and see exactly what will print. Use it for anything where the layout *is* the product: invoices, purchase orders, statements, certificates. What document reports are and where they surface on records is covered in [Document reports](/docs/analytics/document-reports/); this page is the build procedure. ## Prerequisites - The **Reports** page of an app you can open; **New Document Report** sits in its page header. - A worked-out data plan: the primary entity, the related entities the layout needs (a customer's address, the lines of an order), and the fields to print. - Ideally, a sample of the target output — an existing printed invoice, say — to design against. ## Procedure @[guided-image](_img/document-report-designer.png) ### Step 1 — Create the report and define its data Open **Reports** and choose **New Document Report**. The wizard opens as **Document Report Data** and walks Data Source, Relationships, Fields, Columns, Display Grouping, Display Summary, Filters and Details — the same steps as a grid report minus Bucketing (see [Create a report](/docs/analytics/reports/create-a-report/) for each step). Select the primary entity, add only the required relationships, choose every field the document must print, and apply filters that keep the working sample representative. The layout can bind only to fields supplied here, so verify identifiers, line fields, addresses and totals before finishing. Saving the Details step opens the designer with the report title in the page header and the configured data source in the field list. ### Step 2 — Get oriented in the designer The designer is a full-page editing surface. On the left, a **toolbox** of controls — labels, text, check boxes, pictures, lines and shapes, tables, barcodes, charts, gauges, sparklines, page info, page breaks and sub-reports. In the middle, the canvas is organized into **bands** — horizontal sections with distinct jobs: the detail band repeats once per data row; header and footer bands print once per page or once per report; group bands open and close around each group of rows; the top and bottom margin bands frame the page. On the right, **Properties** edits whatever is selected — the report itself (data source, filter string, measure units, language, page settings, printing), a band or a control — and the side rail switches to the expression editor, the field list and the report explorer. The toolbar above the canvas holds cut/copy/paste, undo/redo, zoom and the **DESIGN / PREVIEW** switch. ### Step 3 — Lay out the detail band Drag data fields into the detail band and arrange them — this band is the heart of the document, the part that repeats for every row. Add static labels for captions, and set formatting (fonts, alignment, number and date formats) on each control. ### Step 4 — Add headers, footers and groups Build the framing: a report header for the title and logo, page headers for column captions that repeat on every page, footers for page numbers and totals. If the data is grouped, group bands let you print a heading when each group starts and summary values when it ends. ### Step 5 — Preview with real data Switch to **PREVIEW** to render against live data. Inspect a short record, a multi-page record and values near formatting boundaries; verify repeated headers, page breaks, totals, dates, currencies, clipped text and blank related values. Return to Design for each correction and preview again. This renderer is shared with the viewer and print path, so treat a clean preview—not an attractive design canvas—as the acceptance criterion. ### Step 6 — Save Choose **Save** in the page header; the toast confirms * saved*. The layout is stored with the report and the designer reopens on it next time. **Edit Data** beside it returns to the **Document Report Data** wizard when the data half needs a change. ### Step 7 — Run it Return to the report library, open the saved report and verify it renders in the paginated viewer — page navigation, zoom presets from 50% to 200% plus Page Width and Whole Page, continuous-pages toggle, print, and export as PDF, Excel, Word, CSV, HTML, RTF, Text or Image. Export one test copy and compare it with the approved sample. If the document will be record-driven, wire it to the intended entity action and test **Print** or **Preview** from a disposable invoice or order; do not assume a library run proves the record-action binding. ## Expected result The report reopens with its saved bands and controls, preview renders representative records with correct pagination and formatting, and the library viewer produces the same output. Any configured record action opens the intended report with the current record context and no missing-field or blank-binding errors. ## Common problems - **The designer has no fields to place.** The data half is empty or too thin — go back through the wizard (**Edit**) and select the fields the layout needs. The designer never invents data; it lays out what the wizard defined. - **A control prints blank.** It is bound to a field that is no longer part of the data definition — usually removed in a later wizard edit. Re-add the field in the wizard or rebind the control. - **"This report is not a document report."** The id being opened belongs to a grid or pivot report. Only document-format reports have a designed layout; the other formats are configured wholly in the wizard. ## Common questions ### What edits go in the wizard and what goes in the designer? The wizard owns the data: entity, relationships, fields, filters, name and folder. The designer owns the appearance: bands, placement, fonts, page setup. In the Setup analytics screen the two are separate row actions — **Edit Report** for the data and properties, **Design Report** for the layout — and changing one never silently rewrites the other. ### Can a document report print a specific record? Yes — that is its main job. A **Print** or **Preview** action on an entity passes the current record's identifier to the document report, which renders just that record: one invoice, one purchase order. Run from the library without a record context, the report renders whatever its own query and filters return. Details in [Document reports](/docs/analytics/document-reports/). ### Can a document report be delivered by email on a schedule? Yes. [Subscriptions](/docs/analytics/subscriptions/) work for document reports like any other — the scheduled export renders the designed layout as **PDF** or **Excel**, or **Embedded** in the email body (CSV is offered for grid reports only), so the attachment is the same document the print path produces. ## Related topics - [Document reports](/docs/analytics/document-reports/) - [Create a report](/docs/analytics/reports/create-a-report/) - [Reports in xMatix](/docs/analytics/reports/) - [Subscriptions](/docs/analytics/subscriptions/) ---- # Who can see a report or dashboard URL: https://xmatix.com/docs/analytics/sharing-and-access/ Last reviewed: 2026-09-01 Reports and dashboards use a deliberate-sharing model: nothing is visible to anyone until someone makes it so. That keeps half-built content out of everyone's menus, but it also produces the single most common analytics complaint — "the report is missing" — which is almost never a lost report and almost always an unshared one. This page states the rule exactly, shows how to share, and names the pitfalls. Favorites, My Reports, Subscribed, All Reports and folders describe different relationships to a definition; none alone grants source-data access. Deliberate sharing controls whether the report or dashboard is discoverable, while entity, field and record permissions still determine what each viewer can execute and see. Creator and folder metadata help administrators trace why an asset appears in a catalogue. When someone reports missing content, confirm the exact definition, active status and grant list before examining data. When content opens but differs between users, compare parameters and underlying security rather than adding a broader report grant. Test with a representative recipient, and remember that subscription delivery also requires both definition visibility and valid recipient access at execution time. ## The visibility rule A user sees a report in their Reports menu — and can open it — when it is **active** and at least one of these holds: - they **created** it; - it is shared with **all users**; - it is assigned to one of their **roles, teams or security profiles**. Dashboards follow the identical rule with their own sharing lists. Two properties of the rule are worth stating plainly, because both defy intuition: - **There is no administrator bypass.** The Reports and Dashboards menus show an administrator only what the rule grants them, like anyone else. Administrators see the complete inventory in Setup instead (below). - **Inactive means invisible to everyone.** Deactivating a report or dashboard hides it from every user's menus — including its creator's — while preserving the definition, sharing and subscriptions for reactivation. ## New content starts private A newly created report or dashboard is visible only to its creator. So is a **clone** — copying a shared report does not copy its sharing. This is by design: you build and test privately, then publish deliberately. The corollary is that publishing is a step you must remember, and forgetting it explains most "my team can't see it" reports. ## How to share Sharing lives in the item's edit dialog — administrators reach it in **Setup → Model → Analytics**, on the **Reports** and **Dashboards** tabs, via the row's **Edit** action and its **Visibility** section. The choices map directly onto the rule: | Choice | Effect | | --- | --- | | **Only me** | No grants — creator-only, the default for new content | | **All users** | Everyone with access to the system sees it | | **Selected users** | Assignments to selected roles, teams or security profiles | Despite the current **Selected users** label, the editor exposes group principals rather than individual user accounts: **Roles**, **Profiles** and **Teams**. Share with "the sales role" and new salespeople inherit the report on day one, with no per-person maintenance. ## Dashboards need sharing twice A dashboard's tiles load their data through the dashboard's backing reports, under the viewing user's own access. Sharing the dashboard therefore only controls whether it opens; each tile still requires the viewer to see its report. **Dashboard visible + reports invisible = a frame of empty tiles.** When you share a dashboard, share its backing reports with the same audience in the same sitting. ## The unshared-content pitfall Because visibility depends on explicit grants, content with no grants is invisible to everyone except its creator — and if the creator is gone (a departed employee) or was never a person at all (content brought in by an import), it is invisible to *everyone*, administrators included, in the end-user menus. It still exists: the Setup analytics screen lists all reports and dashboards regardless of sharing, which makes it the place to diagnose and fix. Open Setup, find the item, and grant visibility. ## Sharing shares the results A report's rows are defined by its query and filters. When you share it, the audience you grant sees those results — the visibility list is, in effect, the data audience for that query. Before sharing a report over a sensitive entity with "All users", read its output the way the widest reader will, and prefer role- or team-scoped sharing when the content is narrower than the whole company. The platform's broader access machinery is described in [the security model](/docs/concepts/security-model/) and [security profiles](/docs/administration/security-profiles/). ## Common questions ### Why can't our administrator see a report in the Reports menu? Because the menu applies the same visibility rule to administrators as to everyone else — there is no bypass. The report is not gone: it is listed in **Setup → Model → Analytics**, where the administrator can open its Edit dialog and grant visibility (to themselves included). ### Does sharing a report let people change it? No — sharing grants viewing. Recipients can open the report, filter it, export it and subscribe to it, but changing its definition is a management action governed by permissions, not by the visibility list. ### A user says a shared dashboard is "empty" — what do I check first? The backing reports. Empty tiles on a dashboard that opens fine almost always mean the viewer can see the dashboard but not the reports behind its tiles. Share each backing report with the same audience as the dashboard. The general method for "user can't see X" complaints is in [Diagnosing what a user can't see](/docs/administration/user-cant-see-x/). ## Related topics - [Reports in xMatix](/docs/analytics/reports/) - [Dashboards in xMatix](/docs/analytics/dashboards/) - [Troubleshooting analytics](/docs/analytics/troubleshooting/) - [The xMatix security model](/docs/concepts/security-model/) - [Diagnosing what a user can't see](/docs/administration/user-cant-see-x/) ---- # Subscribe to reports and dashboards by email URL: https://xmatix.com/docs/analytics/subscriptions/ Last reviewed: 2026-09-06 A subscription emails you a report or dashboard on a schedule. At each occurrence a background worker generates a fresh export — the report in your chosen format, the dashboard as a PDF — and sends it to your account's email address plus any additional recipients. Subscriptions are personal: each belongs to the user who created it, with their own schedule and settings, and the same report can carry a different subscription for every subscriber. A subscription stores the schedule and email settings only; it never stores a copy of the content. ## Prerequisites - Access to the report or dashboard — the **bell** appears on library rows and in the viewer only for content you can open. - An email address on your user account; that address always receives the subscription. - For dashboards, that dashboard subscriptions are switched on for your deployment (they are on by default; when off, dashboards show no bell). ## Procedure @[guided-image](_img/subscribe-dialog.png) ### Step 1 — Open the content and choose Subscribe Choose the **bell** on the report or dashboard's row in the library, or in the viewer's toolbar (for reports it is also **Subscribe** in the actions menu). The **Subscribe** dialog opens. If it opens pre-filled with a **Save** button and an **Unsubscribe** button, you already have a subscription on this item and are editing it; a fresh dialog ends with **Subscribe**. Confirm the row you clicked is the intended content — the library allows two reports with the same name in different folders. ### Step 2 — Pick the format **Format** offers what the content supports. A grid report: **PDF**, **Excel**, **CSV** or **Embedded**. A document report: PDF, Excel or Embedded. A pivot report: Excel, PDF or Embedded. A dashboard: **PDF** only. *Embedded* puts the report's rows into the body of the email as a table instead of attaching a file — convenient for short lists read on a phone; PDF or Excel for anything long or for recipients who will work with the rows. ### Step 3 — Adjust the email (optional) Three optional settings shape the message. **Email template** (reports only) picks one of your organization's report-subscription templates for the subject and body; leave it on *Use default subscription email* for the standard message. **Subject override** replaces the default subject, which is otherwise *Scheduled Report:* or *Scheduled Dashboard:* followed by the name. **Additional recipients** is a comma-separated list of email addresses that receive the same export as you. Treat additional recipients as a sharing decision: they receive the export whether or not they could open the content inside xMatix. ### Step 4 — Set the schedule **Frequency** and its dependent fields build the schedule: | Frequency | Fields | Example | | --- | --- | --- | | **Minute** | **Interval** — every 1, 2, 5, 10, 15 or 30 minutes | every 15 minutes | | **Hourly** | **Interval** — every 1, 2, 3, 4, 6, 8 or 12 hours — and **Minute past the hour** (:00 to :55 in five-minute steps) | every 2 hours at :30 | | **Daily** | **Time** | 08:00 | | **Weekly** | **Day of week** (one or more days) and **Time** | Monday and Thursday, 07:00 | | **Monthly** | **Day of month** and **Time** | the 1st, 06:00 | **Times are UTC.** The schedule is stored as a cron expression evaluated in UTC, with no per-organization time zone: pick the UTC time that corresponds to the local hour you want the email to land, and revisit it when your region changes its clocks. ### Step 5 — Confirm and wait for the first delivery Choose **Subscribe**. The toast reads *Subscribed*, the bell fills, and the item appears in the library's **Subscribed** scope. Nothing is sent immediately: the first email arrives at the next occurrence after you subscribed (a monthly subscription created on the 5th for day 1 sends next month), and missed historical slots are never replayed. After the first delivery, check the subject, attachment type and content once before relying on the schedule. ### Step 6 — Change or stop it Choose the bell again to reopen the dialog with your stored values; change what you need and choose **Save**. **Unsubscribe** removes the schedule and the item leaves your **Subscribed** scope; emails already generated are not recalled. ## What happens at send time Every minute a scheduler checks each subscription's cron expression against the time of its **last successful send**. When an occurrence has passed, the worker exports the content and emails it, then stamps the send time. Knowing what that pipeline does and does not check avoids surprises: - **Reports are exported by the platform, not as you.** The report's own query and filters define the rows; every recipient gets the same file, and no per-recipient access filtering is applied. Share the subscription's recipient list with the same care as the report's [visibility](/docs/analytics/sharing-and-access/). - **Dashboards are rendered as the subscriber.** The PDF is produced under your own access with the dashboard's default filter values, so it matches what you see on screen — recipients you add receive *your* view. - **Deactivating or unsharing a report does not stop its subscriptions.** The send checks only that the subscription is active and due and that the report still exists. A report hidden by the **Active** switch, or whose visibility was withdrawn, keeps being delivered until the subscriber unsubscribes or the report is deleted; deleting the report ends deliveries (the worker skips a subscription whose report is gone). - **A failed send is retried.** Because the last-sent stamp moves only on success, a delivery that fails — an export error, an unreachable mail service — is attempted again on later scheduler passes (after a short suppression window that stops a failing job flooding the queue) rather than dropped. - **A schedule the platform cannot parse never fires, silently.** Saving from the dialog always writes a valid expression; the situation only arises for schedules edited outside the dialog, and re-saving from the dialog repairs it. - **Only the next occurrence is honoured.** If several occurrences pass while the worker is down, one delivery is sent when it resumes, not one per missed slot. ## Expected result The content appears in **Subscribed** with the reviewed format, recipient list and UTC schedule. At the next occurrence, you and the additional recipients receive one email with the attachment (or the embedded table), and reopening the dialog shows the same stored settings. ## Common problems - **Nothing ever arrives.** Work through the checklist in [Troubleshooting analytics](/docs/analytics/troubleshooting/): confirm the item is still in your Subscribed scope, reopen the dialog and re-save, check that your user account's email address is correct, and look for the sender in spam or filtering. - **The email lands at the wrong hour.** The schedule time is UTC, not your local time. Reopen the dialog and shift the time by your UTC offset. - **A recipient says they were not included.** Additional recipients are a comma-separated list — check for typos and separators. Every listed address gets the same email; your own address is always included automatically. - **The dashboard email says the dashboard could not be rendered.** Dashboard PDFs are drawn by a browser engine on the worker; if that host is not configured for rendering, the send fails and is retried. Report an unchanging failure to your administrator. ## Common questions ### Does each recipient get the data filtered for them? No. One export is generated per delivery and every recipient gets the same file. For a report it reflects the report definition; for a dashboard it reflects the subscriber's own view. Neither is re-filtered per recipient — which is exactly why the recipient list deserves the same care as [sharing](/docs/analytics/sharing-and-access/) does. ### Can I subscribe someone else instead of myself? You can add them as an additional recipient on your subscription — they receive every delivery you do. But the subscription remains yours: your schedule, your format, stopped when you unsubscribe. For a colleague who wants their own cadence, have them open the content and subscribe themselves. ### What happens if the report changes after I subscribe? Deliveries always render the current definition — the subscription stores the schedule and email settings, not a copy of the report. If the report's columns or filters change, the next attachment reflects the change; if someone saves a new column arrangement from the viewer, that is what arrives too. If the report is deleted, deliveries stop. ## Related topics - [Reports in xMatix](/docs/analytics/reports/) - [Dashboards in xMatix](/docs/analytics/dashboards/) - [Sharing & access](/docs/analytics/sharing-and-access/) - [Troubleshooting analytics](/docs/analytics/troubleshooting/) ---- # Troubleshooting analytics URL: https://xmatix.com/docs/analytics/troubleshooting/ Last reviewed: 2026-09-06 Most analytics surprises have short explanations, because the moving parts are few and inspectable: a report is a stored query, visibility is an explicit grant list, a dashboard is a set of tiles each evaluated for the viewer, and a subscription is a stored schedule. This page works through the frequent complaints in the order that finds the cause fastest — in every case, check access and definition before suspecting the data. Before you start, capture the essentials: the report or dashboard name *and folder* (duplicate names are allowed), who is affected, what they expected versus what they saw, when, and whether an interactive run and a scheduled delivery differ. ## A report is missing from the Reports menu The library shows only what the [visibility rule](/docs/analytics/sharing-and-access/) grants: creator, an all-users share, or a role, team or profile assignment — with no administrator bypass, and with inactive reports hidden from everyone including their creator. @[guided-image](_img/analytics-troubleshooting-context.png) 1. Confirm the report exists. An administrator opens **Setup → Data Studio → Analytics → Reports**, which lists every report in the organization regardless of sharing; search by name and check the **Folder** column, since the same name can exist in several folders. 2. If it is there but inactive, reactivate it: **Edit Report** → **Active**. Deactivation hides a report from every menu while keeping its definition, sharing and subscriptions. 3. If it is active, it has not been shared with the affected user. In the same dialog set **Visibility** to **All users** or **Selected users** with the right roles, profiles or teams. Remember that new and cloned reports start private, and content whose creator has left (or that arrived through an import) may be shared with nobody at all. ## A report opens but shows no rows The query ran and returned nothing — the question is which condition emptied it. 1. Clear your own viewer filters first (**Filters** in the toolbar); a leftover condition is the quickest win. 2. Check the report's built-in filters (**Edit** in the actions menu opens the wizard's Filters step): a date window that has slid past its data, or a status condition that no longer matches, empties a report honestly. 3. Check the relationships. **Only matched records** keeps only rows with a match in the joined entity, so a single such relation to a sparsely filled lookup can drop nearly everything. Switching it to **Keep all base records** shows what was being excluded. If specific columns are blank while rows are present, those columns come from a joined entity whose relation found no match for those rows — *Keep all base records* working as designed. ## A report's columns or filters changed and nobody edited it Someone pressed **Save** in the report viewer. Save writes the current column arrangement, grouping, sort and filter state into the shared report definition — it is not a personal view — so a colleague tidying the grid for themselves changes the report for everyone. Reopen the wizard (**Edit**) to restore the intended columns, and point people at **Clone** for private variations. See [Reports](/docs/analytics/reports/). ## A dashboard is blank, or its tiles are empty Three distinct symptoms with three distinct causes: - **Tiles render but show no data.** Tile data loads under the viewer's own access, so the viewer can open the dashboard but not the source behind a tile. For a report-backed tile, share the report with the dashboard's audience; for an entity- or dataset-backed tile, check the viewer's record access or the dataset's active state. If tiles are empty even for the report owner, open the backing report directly: if it is empty too, the problem is the report (previous section), not the dashboard. Also check the filter bar — a *Last 90 days* preset over data that stopped last quarter is empty by definition. - **Numbers look stale.** Tile results are cached per viewer for about a minute and **Refresh data** is disabled until that minute has passed; a change made seconds ago appears on the next refresh, not instantly. - **The whole dashboard opens with the alert *This dashboard's definition is invalid*.** The stored layout has been damaged — usually by an edit made outside the designer. The viewer refuses to guess rather than render something wrong. Rebuild in the designer and save; do not hand-edit stored layouts. ## A subscription email never arrives Deliveries stop for mundane reasons more often than for broken ones. In order: 1. **Confirm you are still subscribed.** The library's **Subscribed** scope lists your active subscriptions and the bell on the row is filled; choosing it shows the stored settings. Unsubscribing removes the schedule entirely. 2. **Check the timing assumption.** The first email comes at the *next* occurrence after subscribing — a monthly subscription created on the 5th for day 1 sends next month, not today. Times run in UTC (next section). 3. **Check the mailbox and the address.** The subscription always sends to your user account's email address — verify it is correct, and look in spam or filtering for the sender your organization uses. 4. **Check the content still exists.** A deleted report or dashboard ends its deliveries; the worker skips a subscription whose content is gone. Deactivating or unsharing a report does *not* stop deliveries — if you are receiving a report you can no longer open, that is why; unsubscribe. 5. **Re-save the schedule.** Reopening the dialog and choosing **Save** rewrites a clean expression; a schedule the platform cannot parse never fires and raises no error. 6. **Ask an administrator to check the worker.** Report exports and emails are retried on later scheduler passes when they fail, so a persistent outage of the mail service or, for dashboards, of the PDF renderer shows up as a run of retries in the worker's logs rather than as a bounced email. If additional recipients receive the email and you do not (or vice versa), the recipient list is the issue — it is a comma-separated list, and every address in it gets the same attachment. ## The subscription email arrives at the wrong hour Schedule times are evaluated in UTC. A schedule saved for 8:00 sends at 08:00 UTC, which lands mid-afternoon in some time zones and before dawn in others. Reopen the subscription and set the UTC time that corresponds to the local hour you want; revisit it when your region changes its clocks, since UTC does not. ## A record's Print or Preview action fails The action's error text says which piece is missing: - **"No document report is configured for this action."** The action exists but references no document report — an administrator must point it at one in the entity's Actions setup. - **"Please select at least one record."** The action requires a selection and ran from a list with nothing selected. Select the rows first. - **"This report is not a document report."** The action references a grid or pivot report. Print and Preview render designed layouts only — rebuild the target as a [document report](/docs/analytics/document-reports/). - The action works for its builder and fails for others: the document report has not been [shared](/docs/analytics/sharing-and-access/) with the users running the action. ## Related topics - [Sharing & access](/docs/analytics/sharing-and-access/) - [Subscriptions](/docs/analytics/subscriptions/) - [Reports in xMatix](/docs/analytics/reports/) - [Document reports](/docs/analytics/document-reports/) - [Diagnosing what a user can't see](/docs/administration/user-cant-see-x/) ---- # Catalogue and customer-specific pricing URL: https://xmatix.com/docs/commerce/catalogue-and-pricing/ Last reviewed: 2026-09-06 A B2B catalogue answers two questions: what does this buyer see, and what does this buyer pay. In xMatix the first is a merchandising layer — store catalogues presented through the Product Catalogue surface — and the second is the Sales pricing machinery: price lists and discount groups scoped down to the individual account. This page covers both halves and how they meet. ## The item master and the store catalogue Items are the commercial records: units of measure, SKUs, lot types, package flags and classifications live on the item, and every document line ultimately references one. Merchandising sits in a separate layer so the same item can be presented differently per audience. A **Store** (Commerce app → **Stores**) carries a name, currency and an optional partner account or partner account group; its **Related** tab holds the browse tree and the links that decide who resolves to it. - **Store categories** nest under a parent, may belong to a **Product Catalogue** (a filter-configuration record that decides which facets and price bands the browse surface offers), and carry **Show in Catalog**, which decides whether buyers see the category at all. - **Store category items** are the catalogue entries: each wraps an item with its selling content — a marketing name and description, highlights and usage notes, images, a display price and MRP, and an optional component hierarchy for composite products, with an assembly image whose regions map to components. - **Partner Store** links tie a dealer account (and optionally a branch) to the store it buys from; a store can also name a partner account or partner account group directly. Resolution is most-specific-first: the store naming the partner, then a partner-store link (branch-specific before branch-less), then the account group. Keeping merchandising separate from the item master means the catalogue can be reworked — renamed, reorganized, re-imaged — without touching the records that drive pricing, stock and accounting. The public storefront adds one more layer on top: a **published** snapshot of the store's range, described in [Direct-to-consumer selling](/docs/commerce/direct-to-consumer/). ## Browsing: the Product Catalogue surface The **Product Catalogue** action — in the record header of orders, purchase orders and service orders, and on the order-line and purchase-order-line toolbars — opens the store's catalogue against the open document. The store is resolved from the document's partner account through the links above. The surface presents entries as a card grid with search, sorting, collection tabs (**Focused**, **Frequently Ordered**, **New Items**, **Schemes**, **All**), a barcode path and a filter rail whose facets come from the data and the store's Product Catalogue configuration, and enriches each card from the item's own records: - **Units** — quantities are entered per unit of measure from the item's unit ladder (case, box, piece), not as a bare number. - **Prices** — card prices come from price list rules, the same rules that price order lines. - **Offers** — trade scheme hints appear on qualifying items, as prompts rather than applied discounts. - **Stock** — availability and reorder levels are shown from live stock. - **History** — the buyer's frequently ordered items and likely reorders, from their past orders. Each enrichment is independent, so a missing facet degrades that facet rather than blocking the catalogue; only the item read itself gates the screen. A rep's selling scope is applied on top, so the catalogue is never a way around entitlements. Two empty states differ: a store that curates nothing shows "No products in this catalogue" (or "No products match the current search and filters"), while a document whose partner account resolves to **no store at all** falls back to the whole item master with a visible warning — "Showing all products, not this account's range" — so a plausible full range is never mistaken for the account's. Fix the second by linking a store to the partner account. **Add to document** writes the chosen lines to the open document immediately, and each line then runs the normal line handlers for price, discount and derived values. What happens next is covered in [Dealer ordering](/docs/commerce/ordering/). ## Per-account price lists A price list is scoped, and the scoping is what makes pricing customer-specific. A list can be pinned to any combination of: | Scope | Meaning | | --- | --- | | Customer account | One named buyer | | Customer account group | Buyers in a *Price*-type account group — a customer tier | | Selling company (partner account) | The company doing the selling | | Partner account group | A group of selling companies | | Branch | The selling branch | One list can be marked default, and every list carries a sequence number. Two resolvers read these scopes, and they differ: - **On documents** (orders, invoices, the Product Catalogue cart), the resolver first keeps active lists whose selling company, branch, partner group and — on sales documents — customer *group* match the document, then sorts by descending sequence before the scoped fields and the default flag. Treat sequence as the primary precedence control; do not assume a narrower list automatically beats a broader one with a higher sequence. The document resolver does not select a list from the direct customer-account scope. - **In storefront carts**, the cart pricer ranks lists strictly by entitlement: a list naming this customer first, then one for a customer group they belong to, then a general list with neither, and it never prices from a list scoped to someone else. Sequence is not used; ties go to the newest effective date. A price already snapshotted on the cart line from the published catalogue wins over all of this. Within the selected list, an eligible rule must match the item, effective date and any SKU, lot-type or service-type scope. Service-type-specific rules are considered first, followed by the newest effective date and then the remaining dimensions, so a newer generic rule can beat an older specific one — test overlapping rules explicitly. The Reprice action and the handling of manually entered prices are documented in [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/). So "dealer-specific pricing" is modelled, not typed: put the dealer (or its tier group) on a price list, and every order for that dealer prices from it automatically. ## Discount groups: contract terms per account Contract discounts resolve separately from prices. A discount group has a **Discount Type** of *Sale Price* or *Purchase Price*, carries dated discount rules — each targeting an item or an item group with a discount percent — and is scoped by customer account group, selling company, partner account group and branch. A sales document's discount group defaults from the customer's account groups of type *Discount*, narrowed by selling company and branch; the matching rule fills each line's contract discount, and an item no rule covers simply gets none. A group can also be marked claimable with a claimable percentage, which feeds [trade claims](/docs/sales/claims/). Trade schemes stack their own scheme discounts and free lines on top of contract discounts — the two are independent, which is what lets a negotiated margin and a promotional offer coexist on one line. ## Common questions ### Can two dealers pay different prices for the same item? Yes. Put dealers into distinct *Price*-type customer account groups and scope price lists to those groups, or separate them through the selling-company and branch scopes. Set sequence deliberately when more than one active list can match a document. The same account-group pattern applies independently to contract discounts through *Discount*-type groups. ### Where should a negotiated price live? As a dated price-list rule on the list selected for that customer's group, selling company and branch — not as an informal hand-typed unit price. A manually owned rate can be preserved by the line's manual-rate behaviour, while an explicit Reprice uses the matching rule again. Test the exact document context and overlapping effective dates before relying on the result. ### Why does a catalogue card show an offer the order didn't get? Card offers are hints: they signal that a scheme covers the item. Whether it actually applies is decided by the scheme engine when the document is saved — conditions, slabs, account scoping and budgets all weigh in then. See [Schemes and credit](/docs/commerce/schemes-and-credit/). ### How does the Frequently Ordered tab choose its items, and can that be changed? It ranks the items on the buyer's own orders by **document date**: by default the last 180 days, ranked by how many order lines carry each item, top 25. It reads orders, not invoices, and counts orders of every status. On the mobile app an administrator can change the rule per layout, on the Take Order widget (or as **Take Order: Frequently Ordered …** on Visit Tasks and Outlet Tasks): | Setting | Options | Default | | --- | --- | --- | | Look back | A number of days, or of calendar months counted back to the 1st of the month | 180 days | | Rank by | How often it's ordered (order lines), or total quantity | Order lines | | Items shown | 1–200 | 25 | | SOQ from order history | On quotes a suggested order quantity on each card: total quantity in the window ÷ the calendar months it was ordered in, rounded up | Off | With SOQ off, cards show no SOQ figure. The web catalogue always uses the default rule. ### Why does the storefront show one price when the dealer's price list says another? The published catalogue shows one displayed price per listing, snapshotted at publish time. The dealer's own terms are applied when the cart is priced — the cart pricer prefers a list named for the signed-in customer or their group — and the checkout freeze uses that priced total. Republish the store when displayed prices should change. ## Related topics - [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/) - [Dealer ordering](/docs/commerce/ordering/) - [Schemes and credit](/docs/commerce/schemes-and-credit/) - [Portal storefronts](/docs/commerce/storefronts/) - [Commerce screens and records](/docs/commerce/screens/) ---- # Direct-to-consumer selling URL: https://xmatix.com/docs/commerce/direct-to-consumer/ Last reviewed: 2026-09-06 Everything else under Commerce describes selling to businesses — dealers, distributors and key accounts who sign in and order against agreed terms. Direct-to-consumer is the other half: selling to end customers who arrive anonymously, browse a public catalogue, pay by card or UPI, and expect an order confirmation before they close the tab. It runs on the same platform. A consumer order is an ordinary sales order, priced by the same engines and fulfilled by the same pipeline. What direct-to-consumer adds is the machinery a public storefront needs and a B2B portal does not: a catalogue that anonymous traffic can hit hard, a basket that survives sign-in, a checkout that can take money from someone with no account, and coupons that behave sensibly when thousands of people race for the same code. ## Channels: one selling surface at a time A **Commerce Channel** is one place you sell from. Channels live behind the Commerce app's **Settings** tiles; the record names the store the range comes from, the currency, what happens when stock runs short, and which merchant account takes the money. @[guided-image](_img/commerce-channel-form.png) | Field | Meaning | | --- | --- | | Channel Type | **portal** — your own storefront served by [xMatix Portals](/docs/portals/); **headless** — someone else's front end calling the storefront API; **microsite** — a partner's own storefront on its own address | | Store | The store whose range this channel sells; nothing is sellable without one | | Branch, Partner Account | The fulfilling branch and, for a microsite, the selling partner | | Currency Iso Code | Fixed per channel | | Oversell Policy | **deny** reserves stock when payment starts so a paid order can always be fulfilled; **allow** treats stock as advisory; **backorder** accepts and flags the line | | Safety Stock Buffer | Quantity held back from the sellable figure | | Auto Approve Prepaid | A prepaid order lands **Approved** rather than Draft | | Payment Gateway Account | The merchant account for this channel; empty means the tenant default (see [Payments](/docs/commerce/payments/)) | | Allowed Origins | Headless only — browser origins permitted to call the storefront API; the consumer's API key is issued once through the channel's rotate-key operation and only its hash is stored | | Route By Pincode | Route orders to the partner covering the shipping pincode (see [Partner microsites](/docs/commerce/partner-microsites/)) | | Is Active | An inactive channel answers nothing | Everything downstream is scoped to a channel, which is what lets one tenant run a brand site, a headless app and fifty partner storefronts from the same catalogue without them interfering. Choose **deny** only where stock is actually maintained: an item with no stock record is never gated, but a tracked item at zero becomes unsellable. ## The catalogue is published, not queried A storefront never reads the item master directly. Publishing builds an immutable, versioned **catalog publication** of a store's range — the listings, the browse tree, the displayed prices and stock buckets — and flips it live in one step; the previous version is superseded and the last two remain resolvable for cache and rollback. A failed build leaves the previous version serving. This matters for two reasons that only show up in production. Anonymous traffic is unpredictable and often bot-driven; serving it from a frozen projection means a crawl cannot slow the system your staff are using. And a half-finished merchandising change cannot leak: shoppers see the last complete publication until the next one is complete. The publication snapshots the displayed price-from, MRP and stock bucket (*in stock*, *low* under ten units, *out*, or *unknown* for untracked items) along with the content. Those browse values do **not** refresh until the next publication; checkout reprices the cart against current commercial rules before it freezes the deal. Product URLs are assigned once per store and never reused, so a link you published, a customer bookmarked or a search engine indexed keeps resolving across republishes. Publishing is an administrator operation on the store, not a button on a record — see [Commerce screens and records](/docs/commerce/screens/). ## Carts that survive the shopper A shopper can fill a basket before you know who they are. The cart belongs to the channel and to an anonymous token; when they sign in, it merges into whatever active basket they already had on that channel — matching lines add their quantities, new lines are carried across — rather than replacing it. Cart maths is order maths: the same routine that computes a sales order line computes a cart line, and the same scheme engine applies promotions, so the total a shopper sees is the total the order carries. Idle carts are marked **Abandoned** after four hours by default (a remarketing signal; the cart is still recoverable) and **Expired** after 72 hours; both windows are module settings. ## Checkout freezes the deal before the money moves The moment a shopper starts paying, the platform reprices the basket, hashes the result and locks it on the **checkout session**. Stock is reserved on channels that refuse to oversell, a scarce coupon code is held, and a chosen delivery window is booked. Every one of those checks can fail — `PRICE_CHANGED`, `OUT_OF_STOCK`, `COUPON_EXHAUSTED`, `DELIVERY_SLOT_UNAVAILABLE` — and every one of them fails **before** the customer is charged. Then the money moves, and the provider's signed webhook places the order from the frozen snapshot. Placement never reprices; it cannot fail on commercial grounds. The session lives 45 minutes by default, which is also how long its stock and coupon holds last. Customers with credit terms can **pay on account** (the order lands Draft for the tenant's approval), and a channel can opt in to **cash on delivery**, which places the order immediately without a payment record — the driver's cash is receipted later. The mechanics, the recovery sweep and the payment event trail are on [Payments and gateways](/docs/commerce/payments/). ## Coupons that behave under load A **Coupon Campaign** carries its benefit (a percentage with an optional cap, a fixed amount, or a delegation to a trade scheme), its window, its minimum basket value, an optional channel and account-group scope, a first-order-only switch, per-customer and total redemption caps, a stacking policy and a budget. Its **Codes** tab holds the redeemable codes, globally unique per tenant. Two behaviours are worth calling out. Codes marked as requiring reservation are **held** for the duration of a checkout, so two shoppers cannot both spend the last one; public codes are counted at redemption instead. And a campaign that crosses its budget cap does not start refusing people mid-checkout: the order completes, the redemption is flagged as exceeding budget and the campaign is marked overspent for review. A shopper is never refused for arithmetic they cannot see. Where an offer is really a trade scheme, the campaign delegates to the scheme engine instead of restating the offer in a second place. ## Where the order goes Nowhere special. A converted cart becomes a sales order and joins the pipeline described under [xMatix Sales](/docs/sales/) — allocation, fulfilment, delivery, invoice, collection. Consumer orders appear in the same lists, reports and mobile app as every other order, and record security, customization and analytics apply unchanged. That is the point: the consumer channel is a way in, not a parallel business. ## What is available today Direct-to-consumer is an early-availability capability. Available now: channels, catalogue publishing, carts and checkout, card and UPI payment through your own merchant account, pay on account and cash on delivery, coupons, the customer account area, [consumer self-signup that provisions a linked customer](/docs/commerce/consumer-accounts/), [partner microsites with pincode routing, delivery windows and commission settlement](/docs/commerce/partner-microsites/), and signed outbound events for headless consumers. Not yet: action buttons on the commerce back-office screens. Publishing a catalogue or a microsite and rotating a headless key run from administrator endpoints; settlement and payment recovery are scheduled jobs; and the configuration lists (channels, gateway accounts, coupon campaigns, microsites) show no **New** button today — records are created through the Setup Copilot or the Data API, or by opening the list's create form directly (for example `/CommerceChannel?create=1`), and are editable once they exist. ## Common questions ### Do consumer orders and dealer orders end up in the same place? Yes. Both become the same order document with the same lifecycle. The channel tells you where an order came from; it does not put it in a different system. ### Can we use our own front end? Yes — that is what a headless channel is for. The storefront API serves the published catalogue and the cart and checkout operations, and signed webhooks (order placed, order status changed, payment captured, payment failed, cart abandoned, catalog published) tell your system when things move. Deliveries retry with backoff for about a day and a subscription that keeps failing is disabled rather than retried forever. ### Where are payment credentials kept? In your own secret store. The tenant stores a reference, never the secret, and a gateway account is bound to an environment so a test key cannot be used on a live deployment. ### Can partners sell our range on their own storefronts? Yes. A partner microsite is a channel over the store that partner already resolves to, with its own address and delivery areas. Orders stamp the partner as the selling organization, and the daily settlement job accrues commission at the microsite's settlement percentage when it runs; an accrued line is never recomputed afterwards. ## Related topics - [Payments and gateways](/docs/commerce/payments/) - [Partner microsites and order routing](/docs/commerce/partner-microsites/) - [Consumer self-signup and accounts](/docs/commerce/consumer-accounts/) - [Portal storefronts](/docs/commerce/storefronts/) - [Commerce screens and records](/docs/commerce/screens/) ---- # xMatix Commerce FAQ URL: https://xmatix.com/docs/commerce/faq/ Last reviewed: 2026-09-01 The questions below are the ones evaluators of B2B commerce platforms actually ask. Each answer states what xMatix does — the mechanisms are documented in depth across [this section](/docs/commerce/) and the [Sales documentation](/docs/sales/). ## Common questions ### Is Commerce a separate product with its own order pipeline? No — and that is a feature. Commerce is the B2B layer of the platform: merchandised store catalogues, cart-style capture, the dealer purchase-order handoff and portal storefronts, all producing standard sales orders. There is no integration seam between "the shop" and "the ERP" because they are the same system — one order table, one pricing engine, one receivables ledger. ### How do dealers actually place orders? Four verified channels, all landing in the same pipeline: cart-style entry from the merchandised Product Catalogue on a document; the dealer handoff, where a dealer's purchase order becomes the supplier's sales order with outstanding quantities tracked line by line; direct entry in the Sales app; and field-sales capture during visits, including van sales. [Dealer ordering](/docs/commerce/ordering/) walks through each. ### Is there an online storefront with a checkout? There is an online storefront; there is not a portal checkout. [Portal storefronts](/docs/commerce/storefronts/) deliver merchandised catalogue browsing, self-service signup and signed-in account surfaces on your own hostname, with data exposure controlled view by view. Order capture happens through the platform channels above. If a public self-checkout is central to your evaluation, that is the honest current boundary. ### Can each dealer have its own prices and discounts? Yes, modelled rather than typed: price lists scope to a customer account, a price-tier account group, a selling company or a branch, and the most specific active list wins; discount groups fill contract discounts the same way. A negotiated rate lives as a dated rule, so it survives repricing and is auditable. See [Catalogue and pricing](/docs/commerce/catalogue-and-pricing/). ### Are trade schemes applied automatically, or computed after the fact? Automatically, at save: the scheme engine evaluates approved schemes when a document is saved, writes scheme discounts and free lines onto it, and enforces scheme and per-account budgets live against a consumption ledger. Recommendations show how far an order is from the next slab while it is being built. Details in [Schemes and credit](/docs/commerce/schemes-and-credit/) and the [trade schemes reference](/docs/sales/trade-schemes/). ### What stops an over-extended dealer from ordering more? A credit limit per customer per selling company, checked against live open receivables when an order is created and again when an invoice is created. A breach blocks the document with the open amount, document amount and limit in the message. Because the check runs on the document, it holds across every capture channel. See [credit limits](/docs/sales/credit-limits/). ### How are new dealers brought on? A dealer onboarding record type carries the application — the applicant's identity and business details, dealer code, category and lead status — through staged approvals (channel, regional sales and legal sign-off fields, with a recorded rejection reason when declined). Once trading, the dealer is a customer account like any other, carrying its account groups, price list scope, credit limit and store association. ### What happens after the order is placed? The standard order-to-cash pipeline: stock allocation, picking and fulfilment, delivery, invoicing and payment — documented start to finish under [the sales order lifecycle](/docs/sales/orders/) and [invoicing and payments](/docs/sales/invoicing-and-payments/). Commerce adds nothing proprietary downstream, which means reporting, finance and inventory see dealer business with no translation layer. ## Related topics - [xMatix Commerce overview](/docs/commerce/) - [Commerce product overview](/products/commerce/) - [xMatix Sales documentation](/docs/sales/) - [Request a demo](/demo/) ---- # xMatix Commerce URL: https://xmatix.com/docs/commerce/ Last reviewed: 2026-09-06 xMatix Commerce is how a business sells on xMatix — to other businesses (dealers, distributors, stockists and key accounts) and, through the direct-to-consumer channels, to end customers. It covers the merchandised catalogue a buyer browses, cart-style order capture, the price lists and discounts each account trades on, the trade schemes that reward volume, the credit limits that keep exposure in check, and the pipeline that turns an order into stock movement, an invoice and cash. ## Where Commerce actually lives Commerce is deliberately not a separate engine with its own orders. A dealer order **is** a sales order: it is priced by the same price lists, discounted by the same discount groups, promoted by the same scheme engine, gated by the same credit limits, and processed by the same allocation, fulfilment, delivery and invoicing chain documented under [xMatix Sales](/docs/sales/). What Commerce adds is the B2B layer on top of that machinery: | Layer | What it is | Built on | | --- | --- | --- | | Merchandised catalogue | Store catalogues that present items with marketing content, images and offers | The item master + store catalogue entries | | Cart-style capture | The Product Catalogue surface: browse, set quantities per unit, save lines onto the document | Standard order and purchase-order documents | | Dealer ordering | A dealer's requirement, raised as a purchase order, handed off into the supplier's sales order | The Sales and Procurement pipelines | | Commercial terms | Per-account price lists, discount groups, trade schemes, credit limits | The Sales pricing and scheme engines | | Storefronts | External-facing catalogue and account surfaces on their own hostname | [xMatix Portals](/docs/portals/) | Because each layer is the standard platform, everything else in this documentation applies unchanged — record security, customization, reporting and the mobile app all work on commerce data exactly as they do anywhere else. ## The Commerce app The **Commerce** app (open it from the App Launcher; it appears when your administrator has granted it) gathers the module's screens in one navigation bar. @[guided-image](_img/commerce-overview.png) | Entry | What it holds | | --- | --- | | Stores | The stores a channel sells from — name, currency, optional partner scope — with their categories and catalogue publications | | Carts | Shoppers' baskets, signed-in or anonymous, with status, totals and applied coupon (read-only: written by the pricing services) | | Checkout Sessions | Each attempt to turn a cart into an order and where it stopped (read-only) | | Orders | The ordinary sales orders that converted carts and dealer orders become | | Payment Transactions | One row per payment attempt with its gateway event trail (read-only) | | Coupon Campaigns | Offers, their codes, caps and budget | | Partner Microsites | A partner's storefront on its own address and the service areas it delivers to | | Reports, Dashboards | Commerce reporting | | Settings | Tiles for **Commerce Channels**, **Payment Gateway Accounts**, **Webhook Subscriptions**, **Partner Settlements** and **Partner Targets** | Which screens are editable and which are written only by the services that own them is covered in [Screens and records](/docs/commerce/screens/). Dealer ordering itself happens on the sales order — see [Dealer ordering](/docs/commerce/ordering/). ## Section map | Page | What it covers | | --- | --- | | [Catalogue and pricing](/docs/commerce/catalogue-and-pricing/) | Store catalogues and merchandising, and how price lists and discount groups give each account its own terms | | [Dealer ordering](/docs/commerce/ordering/) | Cart-style capture, the purchase-order handoff, and the standard pipeline the order then runs | | [Schemes and credit](/docs/commerce/schemes-and-credit/) | Trade scheme evaluation on B2B documents and the credit gates on ordering | | [Portal storefronts](/docs/commerce/storefronts/) | Delivering catalogue and account experiences to external buyers with Portals | | [Direct to consumer](/docs/commerce/direct-to-consumer/) | Selling to end customers — published catalogues, guest carts, checkout and payment, coupons, partner microsites | | [Screens and records](/docs/commerce/screens/) | Every screen in the Commerce app — what each one holds, and which are read-only by design | | [Commerce FAQ](/docs/commerce/faq/) | The questions B2B commerce evaluators ask, answered from how the platform works | ## Common questions ### Do commerce orders live somewhere separate from sales orders? No. There is one order pipeline. An order captured from a catalogue cart, handed off from a dealer's purchase order, typed in by a back-office user or taken on a field visit is the same document with the same lifecycle — the [sales order lifecycle](/docs/sales/orders/) describes it once for all of them. ### Does Commerce only cover B2B? No. The pages below describe the B2B layer, which is the older and larger half. [Direct to consumer](/docs/commerce/direct-to-consumer/) covers selling to end customers: published catalogues served to anonymous shoppers, guest carts, card and UPI checkout, coupons and partner microsites. Both produce the same order document and run the same pipeline. ### Do I need Portals to use Commerce? No. Dealer ordering, catalogues, pricing, schemes and credit control all run inside the platform's own web and mobile apps. Portals come in when you want buyers to browse or sign in on an external site of your own — that part is covered in [Portal storefronts](/docs/commerce/storefronts/). ### Where do invoicing and payment fit? Downstream, unchanged: once a dealer order is allocated and fulfilled, it is invoiced and collected exactly like any sales order — see [invoicing and payments](/docs/sales/invoicing-and-payments/). Receivables from those invoices are what the [credit limit](/docs/sales/credit-limits/) gate measures. ## Related topics - [xMatix Sales documentation](/docs/sales/) - [Commerce product overview](/products/commerce/) - [Portals product overview](/products/portals/) - [Request a demo](/demo/) ---- # Dealer ordering URL: https://xmatix.com/docs/commerce/ordering/ Last reviewed: 2026-09-06 Dealer orders reach xMatix two main ways: built up cart-style from the Product Catalogue, or handed off from the dealer's own purchase order. Both produce an ordinary sales order, so everything downstream — pricing, schemes, credit, allocation, fulfilment, invoicing — is the standard pipeline. This page covers the two capture paths and the handoff mechanics. ## Cart-style capture with the Product Catalogue @[guided-image](_img/dealer-cart-concept.png) A dealer order is an ordinary sales order in the Sales app, and everything on its page is the standard order machinery: **Partner Account**, **Branch** and **Account** in the header, the status ladder from Draft through Approval, Fulfilment, Invoicing and Delivery, the **Lines** grid, and an **Amount Summary** with **Scheme Recommendations** beside it. What Commerce adds is the **Product Catalogue** action — in the header actions and again on the Order Line toolbar next to **Quick Add** and **Import**. From an open order (or purchase order, on the buying side), **Product Catalogue** opens the store's merchandised catalogue described in [Catalogue and pricing](/docs/commerce/catalogue-and-pricing/): tabs for **Focused**, **Frequently Ordered**, **New Items**, **Schemes** and **All**, a barcode scanner, search by name or code and a sort control. The user browses, filters and sets quantities per unit of measure where the item defines a unit ladder. In this host-document surface, **Add to document** writes the selected line to the open document immediately; it is not the persisted public-storefront `Cart` record. Each created or updated line then runs the document line handlers that resolve price, discounts and other derived values. The catalogue's offer text remains a prompt; the document engines are the authority. Public storefront carts and checkout sessions are a separate direct-to-consumer flow described in [Direct-to-consumer selling](/docs/commerce/direct-to-consumer/). ## The dealer handoff: requirement to supplying order When the dealer's requirement is itself an xMatix document — a purchase order naming the supplier and the supplier's branch — the dealer-order handoff creates the supplying sales order from it, so nobody re-keys the requirement: | On the purchase order | Becomes, on the sales order | | --- | --- | | Supplier branch | The order's branch, and its partner account the selling company | | The party raising the requirement | The order's customer account | | Lines with outstanding quantity | Order lines (item, SKU, quantity), each referencing its requirement line | Three behaviours make the handoff safe to repeat: - **Only outstanding quantity moves.** Each requirement line tracks how much has already been ordered against it; the handoff takes what remains, so running it twice cannot double-supply. - **Quantities roll up.** The created order lines count back against their requirement lines, so the outstanding figure falls as supply is arranged — visible from the purchase order at any time. - **It can be selective.** The selective variant takes chosen lines and chosen quantities, capped at what is outstanding — for supplying part of a requirement now and the rest later. The handoff refuses to run without a supplier branch on the purchase order, and refuses when no line has outstanding quantity — both with explicit messages. On the sales-order side, the same **Create Dealer Order** action does the reverse convenience: an order linked to a dealer's purchase order pulls that document's outstanding lines in. **Reprice** and **Apply Scheme** on the order re-run pricing and scheme evaluation after lines arrive by either path. ## The standard pipeline takes over However captured, the order is now a sales order: | Stage | Documented at | | --- | --- | | Pricing, contract discounts, taxes fill in | [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/) | | Trade schemes evaluate on save | [Schemes and credit](/docs/commerce/schemes-and-credit/) | | Credit limit gates creation | [Credit limits](/docs/sales/credit-limits/) | | Stock is allocated | [Allocating stock to orders](/docs/sales/orders/allocation/) | | Picking and fulfilment | [Picking and fulfilment](/docs/sales/orders/picking-and-fulfilment/) | | Delivery and invoicing | [The sales order lifecycle](/docs/sales/orders/) | | Payment and receivables | [Invoicing and payments](/docs/sales/invoicing-and-payments/) | ## Other capture channels The same order document is also created by hand in the Sales app, captured on field visits (including van sales, where the vehicle sells from its own stock), and invoiced in bulk from the order-processing screen — see [creating a sales order](/docs/sales/orders/create-order/), [van sales](/docs/field-sales/van-sales/) and [bulk order processing](/docs/sales/orders/bulk-processing/). ## Common questions ### The dealer sent a second requirement for the same items — what happens? A second purchase order is a new requirement and hands off independently. Re-running the handoff on the *same* purchase order, though, only ever takes what is still outstanding — quantity already turned into an order has rolled up against the requirement lines, so the repeat covers the remainder and a fully ordered document has nothing left to hand off. ### Can the supplier accept only part of what the dealer asked for? Yes — the selective handoff takes named lines and quantities, capped at each line's outstanding figure. The rest stays outstanding on the purchase order for a later run. ### Does an order from the catalogue cart skip pricing, schemes or credit? No. Product Catalogue adds lines to the same document used by manual entry. The line and document handlers apply pricing, discounts, scheme evaluation and the available credit checks through the normal lifecycle; using the catalogue does not create an alternate pricing pipeline. ## Related topics - [The sales order lifecycle](/docs/sales/orders/) - [The purchase order lifecycle](/docs/procurement/purchase-orders/) - [Catalogue and pricing](/docs/commerce/catalogue-and-pricing/) - [Schemes and credit](/docs/commerce/schemes-and-credit/) ---- # Trade schemes and credit control URL: https://xmatix.com/docs/commerce/schemes-and-credit/ Last reviewed: 2026-09-06 Two controls sit between a dealer's cart and the invoice: trade schemes, which decide what the dealer earns on the order, and credit limits, which decide whether the order may exist at all. Both are enforced by the platform, not by policy documents — this page covers how each behaves on B2B documents and on storefront carts, and links the full references. ## Schemes on dealer orders Because a dealer order is a standard sales order, the [trade scheme engine](/docs/sales/trade-schemes/) treats it like any other: saving the document evaluates every approved **Auto Apply** scheme in validity, and qualifying slabs write their benefits onto it — scheme discounts on the lines, free-item lines added and marked as scheme-generated. **Apply On Selection** schemes wait for an explicit apply, and the qualified-slabs and recommendation actions show what the document earns now and how far it is from the next slab — useful prompts during dealer order capture, and the source of the offer hints on catalogue cards. Three parts of the scheme model matter especially in a dealer network: - **Account scoping.** A scheme can target accounts and account groups of type *Scheme*, and an account group of type **Exclude Scheme** keeps chosen dealers out — so a promotion can run for one tier of the network and not another. Only active group memberships count. - **Both sides of the chain.** Scheme types cover sale orders and invoices *and* purchase orders and bills (plus repair orders), and the *Per Period* variants qualify on an account's accumulated performance rather than a single document. A distributor running xMatix gets scheme treatment on what they buy, not only on what they sell. - **Budgets.** Unless a scheme is set to ignore budget, a benefit that applied on the sale order is carried onto the **sale invoice** only when both a global scheme budget and a matching partner budget (by account or account group) are configured with room; a scheme with a global-only, partner-only or no budget has its benefit dropped at invoicing. Consumption is recorded as documents apply and reversed when they are reset or deleted. Claimable schemes feed [trade claims](/docs/sales/claims/) for settlement. The slab, condition and benefit model — and the reset behaviour — are documented in full on the [trade schemes](/docs/sales/trade-schemes/) page. ## Schemes on storefront carts A [storefront cart](/docs/commerce/direct-to-consumer/) runs the same engine in auto-apply mode, so a shopper sees the scheme discount and free goods the order will carry, and a coupon of benefit type *scheme* delegates to it rather than restating the offer. Two differences from a document: a cart records no budget consumption, because most carts are abandoned — consumption is booked when the order is placed — and an engine failure while pricing a cart degrades to an undiscounted total rather than blocking the shopper. Coupon value is kept in its own field on the cart and order, so promotion spend and negotiated discount stay distinguishable. ## Credit control on ordering The [credit limit](/docs/sales/credit-limits/) gate is the platform's answer to over-extended dealers. A limit is configured per customer per selling company, and the check runs twice: - **On order header insert**, the check gates on the customer's **existing** open exposure — the new order's lines and amount are not yet known, so it is a guard against customers who are already over limit rather than a projected-exposure test. A customer with no limit and no outstanding balance is not gated. - **On invoice insert**, the check includes the invoice amount against open receivables. If the receivables subledger cannot be read, invoicing is allowed to proceed rather than blocked; the order-time check has no such fallback and surfaces the failure. Both checks are skipped entirely when the Sales setting **Credit limit override requires approval** is on — the tenant's approval process then owns the decision instead. A breach refuses the save with a message naming the account, the open amount, the document amount and the limit. Settled receivables reduce the open exposure used by subsequent checks. On a storefront, **pay on account** is offered only to signed-in customers and shows the available credit from the same subledger; the order lands Draft for the tenant's approval. ## Common questions ### When exactly does a scheme land on a dealer order? When the document is saved — evaluation is part of the save, so benefits appear as soon as the order is created or edited into qualification, and are refreshed as it changes. Nothing waits for a nightly job, and there is no separate "apply promotions" step unless the scheme is deliberately *Apply On Selection*. ### Can I run a promotion for some dealers and not others? Yes, by scoping: target the scheme at accounts or *Scheme*-type account groups, and put dealers who must not receive it in an *Exclude Scheme* group. Selling company and branch scoping narrow it further. Budgets then cap what any account or the whole scheme can consume. ### Why did a scheme discount show on the order but disappear on the invoice? Almost always the budget gate: the invoice carries the benefit only when both a global scheme budget and a partner budget are configured with room (or the scheme ignores budget). Check the scheme's budget rows for the partner or its account group. ### Why was a small order blocked when the order itself is well within the limit? Because the order-time check gates on the customer's existing open position: a dealer already over the limit is refused any new order until exposure comes down. The block message shows the open amount responsible — the levers are collecting payments, settling stale open items, or raising the limit. See [credit limits](/docs/sales/credit-limits/). ## Related topics - [Trade schemes](/docs/sales/trade-schemes/) - [Credit limits](/docs/sales/credit-limits/) - [Trade claims](/docs/sales/claims/) - [Dealer ordering](/docs/commerce/ordering/) - [Direct-to-consumer selling](/docs/commerce/direct-to-consumer/) ---- # Commerce screens and records URL: https://xmatix.com/docs/commerce/screens/ Last reviewed: 2026-09-06 This is the reference for what each screen in the **Commerce** app holds, what you can do on it, and — the question that comes up most — why some of them have no New button. The app's navigation lists parent records only: **Stores**, **Carts**, **Checkout Sessions**, **Orders**, **Payment Transactions**, **Coupon Campaigns**, **Partner Microsites**, **Reports**, **Dashboards** and **Settings**. ## Read-only by design Fifteen of the module's records are written **only by the services that own them**: a cart line exists because a pricing pass created it, a payment event because a gateway said something, a catalog entry because someone published. Those entities are flagged non-creatable and non-editable in the platform metadata, so every screen for them is readable, filterable, exportable and reportable but never editable — the New button is absent rather than present-and-failing, and the Data API refuses to create them. Nine records are administrator-authored: commerce channels, payment gateway accounts, webhook subscriptions, coupon campaigns and their codes, partner microsites and their service areas, and partner targets with their tiers. One honest gap on the authored side: today the lists for channels, gateway accounts, coupon campaigns and microsites carry no **New** button either, because no list actions are seeded for them. Records are created through the Setup Copilot or the Data API, or by opening the list's create form directly (`/?create=1`), and are editable once they exist. ## Storefront | Screen | What it holds | Editable | | --- | --- | --- | | Stores | A retail outlet or sales location — the range a channel sells from. Name, label, description, currency, an optional partner account or partner account group, and an external id. | Yes | Everything else about a store is on its record. The **Related** tab lists its **Store Categories** (the browse tree — categories nest, and *Show in Catalog* decides whether buyers see one), its **Partner Store** links (which dealers resolve to this store), its **Catalog Publications**, **Catalog Slugs** and **Commerce Channels**. Categories are authored here; publications and slugs are produced by publishing. A **Catalog Publication** is one immutable, versioned build of the store's range with status *Building*, *Live*, *Superseded* or *Failed*. Exactly one is Live per store; the last two superseded versions stay resolvable; a Failed build keeps its error message and leaves the previous version live. Its **Entries** are precisely what shoppers can see — when a product is on the item master but missing from the storefront, absent there means unpublished, and the fix is to publish again rather than to edit the item. A **Catalog Slug** is the permanent public URL of a listing or category, assigned once per store and never reused. ## Selling | Screen | What it holds | Editable | | --- | --- | --- | | Carts | A shopper's basket for one channel, signed in or anonymous — status, totals, applied coupon, addresses, and when it was last priced. Its Lines tab is the contents. | No | | Checkout Sessions | One attempt to turn a cart into an order and the record of where it stopped. Its Related tab carries the payment attempts and the stock and coupon holds taken for it. | No | | Orders | The ordinary sales order a converted cart becomes — the same document a dealer, a field rep or the back office produces. | Yes | Cart **Status**: *Active* is live; *Abandoned* is idle past the window (four hours by default) and still recoverable; *Ordered* converted; *Merged* was folded into another basket at sign-in; *Expired* (72 hours by default) is terminal. Checkout **Status** answers "the money left but there is no order": *Open* (addresses captured, nothing frozen), *Awaiting Payment* (snapshot locked, holds taken), *Paid* (captured; placement has not run yet — a timing state the recovery job resolves, not a lost order), *Placed*, *Failed* or *Expired*. Every **Failure Code** — `CART_EMPTY`, `PRICE_CHANGED`, `OUT_OF_STOCK`, `COUPON_EXHAUSTED`, `PAYMENT_FAILED`, `ADDRESS_INVALID`, `DELIVERY_SLOT_UNAVAILABLE` — is a **pre-payment** outcome, because the commercial snapshot is frozen before the gateway is asked for money. ## Payments | Screen | What it holds | Editable | | --- | --- | --- | | Payment Transactions | One payment *attempt* — a retry produces a second row, distinguished by attempt number and idempotency key. Gateway, method, amount, status, refunded amount and the gateway's own ids. | No | The **Events** tab is the append-only trail written from the gateway's signed callbacks and the recovery job — initiated, intent created, redirected, webhook received, signature verified or rejected, authorized, captured, failed, reconciled, refund requested, refunded — and the transaction's status (*Created*, *Authorized*, *Captured*, *Failed*, *Refunded*, *Partially Refunded*) is a projection of it. **Failure Category** buckets a failure into *declined*, *gateway error*, *timeout*, *signature invalid*, *user abandoned* or *unknown*. A transaction sitting at *Created* with no further events is an abandoned redirect, which the reconciliation pass resolves. Payment transactions, their events and gateway accounts are audited. ## Promotions | Screen | What it holds | Editable | | --- | --- | --- | | Coupon Campaigns | The offer — status (*Draft*, *Active*, *Paused*, *Ended*), benefit type (*percent* with a cap, *amount*, or *scheme* delegating to a trade scheme), window, minimum cart value, channel and account-group scope, first-order-only, per-customer and total caps, stacking policy (*exclusive* or *stackable*) and budget. Its Codes tab holds the redeemable codes. | Yes | Watch **Budget Spent** and **Is Overspent** while a campaign runs. Crossing the cap does not begin refusing shoppers: the order completes and the redemption is flagged, so nobody is rejected for arithmetic they cannot see. Redemptions and reservations beneath a campaign are service-written. ## Partners | Screen | What it holds | Editable | | --- | --- | --- | | Partner Microsites | A partner's storefront on its own slug, over the store that partner resolves to — status *Draft*, *Live* or *Suspended*, display name, theme, settlement percent and channel. Its Service Areas tab declares the pincodes it delivers to, with priorities. | Yes | | Partner Settlements (Settings) | What is owed to a partner for a month — gross, commission, net and order count — moving from *Accrued* to *Statemented* to *Settled*. | No — accrued by a daily job | | Partner Targets (Settings) | What a partner account is expected to buy in a period, with its tier ladder; achievement is computed live from invoiced or ordered documents. | Yes | A settlement's **Lines** tab is the per-order detail, and each line carries the commission percentage the job applied when it accrued that order; lines are never recomputed. ## Settings The **Settings** item opens a page of tiles rather than a menu. Behind it sit the administrator-authored records — **Commerce Channels** (one per selling surface), **Payment Gateway Accounts** (secret-store *references*, never secrets) and **Webhook Subscriptions** for headless consumers — plus the two periodic partner back-office lists, **Partner Settlements** and **Partner Targets**. They live here rather than in the top navigation because they are worked in bursts across all partners at once. A webhook subscription's **Deliveries** tab shows each attempt with its status code; deliveries retry with backoff for about a day and a subscription that keeps failing is disabled rather than retried forever. ## Why line-level records are not in the navigation Cart lines, catalog entries and categories, payment events, coupon codes and redemptions, reservations, webhook deliveries, service areas, settlement lines and target tiers have no menu entry. They are reached on their parent's detail page, the way order lines are reached from an order. Opened unscoped, a line table shows rows with no parent context — and for the service-written ones, rows you could not act on anyway. ## Who can see the app App and entity access are strict allow-lists with no administrator bypass. As shipped, the System Admin profile sees the Commerce app and its Settings with full access; the Sales Manager profile sees both with read access, plus write access on the merchandising records (campaigns, codes, microsites, service areas, targets and tiers) but not on channels, gateway accounts or webhooks. Widen it under [security profiles](/docs/administration/security-profiles/) by granting the app and then read on the entities it navigates to — the app without the entity rows is a visible tile over an empty menu. ## Common questions ### Why can I see these records but not edit them? Because a service owns them. Carts, checkout sessions, payments, catalog projections, reservations, deliveries and settlements are produced by the pricing, checkout, publishing, dispatch and accrual paths. Editing one by hand would produce a record no engine agreed to, so the platform makes the screens readable and leaves the writing to the code that owns the rules. ### Where do I find a cart's lines, or a payment's events? On the record's own page. Every commerce detail page puts the primary child collection first, then a Related tab with the other connected records, then the fields. ### A product is in the item master but not on the storefront. Where do I look? At the store's Live catalog publication, on its Entries tab. If the product is not there, it was not published — prices refresh on their own, but content changes need a publish. ### Where are the Publish, Refund and Run Settlement buttons? There are none on any record today. Publishing a catalogue or a microsite and rotating a headless key are administrator endpoints; settlement accrual, payment recovery, cart expiry and webhook dispatch are scheduled jobs; and refunds are issued at the payment provider and recorded here from its webhook. See [Payments and gateways](/docs/commerce/payments/). ## Related topics - [xMatix Commerce](/docs/commerce/) - [Direct-to-consumer selling](/docs/commerce/direct-to-consumer/) - [Payments and gateways](/docs/commerce/payments/) - [Partner microsites and order routing](/docs/commerce/partner-microsites/) - [Catalogue and pricing](/docs/commerce/catalogue-and-pricing/) ---- # Portal storefronts URL: https://xmatix.com/docs/commerce/storefronts/ Last reviewed: 2026-09-06 When the commerce experience must reach people outside your organization — dealers browsing your range, customers checking their orders, consumers buying — it is delivered with [xMatix Portals](/docs/portals/): external-facing sites you author in your tenant and publish on their own hostname. Portals are an early-availability capability; this page describes what a portal storefront does today, which surfaces can transact, and how multiple portals stay separate. There is no screenshot because the surfaces described here are portal-side pages, which exist only on a published portal in your own tenant; the administrator screens are covered in the [Portals section](/docs/portals/build-a-portal/). ## What a portal storefront is A portal is a site of pages served to external visitors — never through the internal app shell. Administrators create and manage sites under **Setup → Feature Hub → Portals**, where the registry lists each portal's name, slug, address, published state, status, anonymous access, page count and version. A site's record has three tabs — **General**, **Pages** and **Data Views** — and a header showing its address (a Draft tag until published) with a **Publish / Unpublish** action. On **General**: the label, description and slug (the hostname label — lowercase letters, digits and hyphens), **Active**, **Anonymous visitors** (off means only signed-in external users can view the portal), **Self-service signup**, **Create customer on signup**, and an Advanced section holding the theme, navigation and settings documents as JSON. Pages are designed free-form or embed a platform surface — an entity list, an entity detail, or an app page — each with a **Public** or **Authenticated** audience. Authoring is draft-first: visitors only ever see the published snapshot of a page, an unpublished page is invisible, and an inactive or unpublished site is not served at all. Custom hostnames are attached under **Domains** ([publishing and domains](/docs/portals/publishing-and-domains/)). ## Catalogue surfaces: published data views A portal reads tenant data only through **published data views** — entity views a tenant has explicitly published to that site on its **Data Views** tab. Each names the entity (fixed once published), the view whose columns and base filter bound what is reachable, an audience, and a **page size cap** (up to 250 rows). There is no general data access from a portal. Who a view serves decides whose identity runs the query: - **Public** views execute as the portal's own anonymous service identity — so every visitor, signed in or not, sees the identical catalogue, and record and field security are enforced through the standard engine rather than a parallel path. - **Authenticated** views require a signed-in external user and execute as that caller, so ownership and contact-link security scope the rows — the mechanism behind "my orders" style surfaces. A visitor's request can only narrow a view's filter, never widen it. Publishing a view grants the portal's anonymous identity read access to that entity; deactivating or removing the last published view of the entity revokes it. Exposure is therefore an explicit, reviewable list per site — see [pages and data views](/docs/portals/pages-and-data-views/). ## Signing up and signing in With **Self-service signup** on, a visitor leaves an email, name and phone and receives a set-password invitation, creating an external user account that is a member of that portal. With **Create customer on signup** (on by default) the signup also provisions a **consumer Account** and a linked **Contact** named for the person, so commerce screens resolve their account immediately — without it the new login is a dead end that cannot see an account. The response is identical whether or not the email already had an account, so signup cannot be used to probe who your customers are; and a signup never adopts an existing customer's records — connecting a known customer to a login is done by invitation from inside the platform. Signup is rate-limited per caller. Details are in [consumer self-signup and accounts](/docs/commerce/consumer-accounts/) and [visitors and signup](/docs/portals/visitors-and-signup/). ## Each portal is its own boundary A tenant can run several portals — a dealer portal, a consumer storefront, a service-partner site — and they are separated by more than navigation: - **Membership.** Inviting a user to a portal, or their self-signup on one, records them as a member of that portal, and sign-in pins the session to it. To a portal they do not belong to, an external user is simply an anonymous visitor. - **Audience.** External logins reach only the portal and storefront surfaces; the internal data, metadata and admin APIs refuse them outright, regardless of what security profiles the account carries. - **Order books.** Each order is stamped with the channel it was placed on, and a portal's order history shows only its own channel's orders. - **Money stays whole.** Invoices, ledger and credit exposure are account-level on purpose: what a customer owes is one number however many portals they shop through, so a credit limit cannot be evaded by switching storefronts. ## Two kinds of surface on one portal A portal serves two different kinds of surface, and the distinction decides what a visitor can do: - **Portal pages and published views** are the read layer: merchandised browsing, record lists, "my orders" style surfaces. They are read-only for external audiences — a page-embedded entity surface never writes. - **The commerce storefront** is the transacting layer. A [commerce channel](/docs/commerce/direct-to-consumer/) of type *portal* linked to the site gives visitors the published catalogue with a real cart, checkout and payments; each order lands in the same pipeline as every other order. The link between a site and its channel is made on the channel record, and the store's record lists the channels selling from it. Dealers who order through back-office channels — the Product Catalogue cart inside the apps, the purchase-order handoff, field-sales capture — keep doing so; those channels are described in [Dealer ordering](/docs/commerce/ordering/). The storefront adds a self-service lane beside them; it does not replace them. ## Common questions ### Can the portal show each dealer their own prices? Public catalogue views cannot — by design they run as the shared anonymous identity, so every visitor sees the same rows and columns, and the published catalogue shows one displayed price per listing. Account-specific commercial terms resolve at checkout: the cart pricer prefers a price list named for the signed-in customer, then one for their customer account group, then a general list, and never prices from a list the shopper is not entitled to. An authenticated view can scope *records* to the signed-in user, which is how account-specific surfaces are built. ### Can a dealer place an order from the storefront? Yes, where the site carries a storefront channel: the cart and checkout are real, and a placed order joins the same order book as every other channel — including pay on account for customers within their credit terms. Portal *pages* and published views remain read-only; it is the storefront surface that transacts. ### Is portal data a copy that can go stale? Published data views read live platform data at request time through the same security engine as internal users — there is no export or sync step; only the view's filter and columns limit what is exposed. The *storefront catalogue* is different: it is a published projection whose displayed prices and stock refresh only when the store is republished, while checkout always reprices against current rules. ## Related topics - [xMatix Portals documentation](/docs/portals/) - [Build a portal](/docs/portals/build-a-portal/) - [Catalogue and pricing](/docs/commerce/catalogue-and-pricing/) - [Direct-to-consumer selling](/docs/commerce/direct-to-consumer/) - [Dealer ordering](/docs/commerce/ordering/) - [Consumer self-signup and accounts](/docs/commerce/consumer-accounts/) - [Partner microsites and order routing](/docs/commerce/partner-microsites/) ---- # Apps, entities, records and views URL: https://xmatix.com/docs/concepts/apps-entities-records/ Last reviewed: 2026-09-06 ## One model, many screens xMatix is metadata-driven. Every business object — an order, an account, an item, a journal — is an **entity** whose definition lives in the tenant's metadata: its fields, relations, record types, views, layouts, validations and actions. The list you scroll, the form you fill in and the mobile screen a technician taps are all rendered from that definition. Two organizations running the same entity can see quite different screens because their metadata differs, not because their software does. Metadata supplies the common model; it does not mean every behavior is generated. Standard entities are also compiled types with first-party handlers that implement feature-specific validation and side effects (an order posting stock, an invoice creating ledger entries). Custom entities use the platform's dynamic storage and get the shared list, form, view, relation and access framework, but not those compiled handlers. ## Entities are definitions; records are the rows An entity defines a *type* of record: which fields it has, how it relates to other entities and what users may do with it. A record is one instance of that type. The Order entity says what every order carries — customer, dates, status, amounts — and each order your team creates is one Order record. Relations are what make navigation work: an order references its account, an invoice references the order it bills, so related records are always one click apart. Document-style entities pair a header with lines — an order and its order lines are two entities joined by a relation — so one business transaction is stored as one header record plus its line records. ## Where the definition lives: Design Studio → Entities @[guided-image](_img/metadata-concept.png) Administrators manage definitions in **Setup → Design Studio → Entities**. The registry lists every entity with its label and a **System** or **Custom** badge; opening one shows an **Overview** (label, collection label, icon and color, and the behavior switches: Create, Edit, Delete, Merge, Search, Audited, Notes, Activities, duplicate detection, recently-viewed tracking, list/form/query support) and three groups of sub-pages: - **Schema** — Fields, Record Types, Field Mappings, Lookup Filters, Relations and Field Dependencies. - **Logic** — Validations, Actions, Approval Processes, Document Settings and the Execution Plan. - **Experience** — Views, Layouts and Email Templates. **New** on the registry starts a custom entity definition; it never creates an ordinary business record. Records are created inside the business apps. > The registry's Fields / Relations / Views / Record Types count columns are recalculated when an entity definition is saved. Entities that arrived through a platform seed and have never been re-saved can show **0** there even though they have many fields — open the entity and read the Schema pages rather than trusting the registry counts. ## Fields A field is one attribute of a record. Each field has a **Type** (Text, Number, Currency, Date, PickList, Lookup, Calculated and so on), an underlying **Data Type**, and behavior switches: **Required**, **Hidden**, **Filterable**, plus whether the field allows sorting and grouping in lists. Lookups reference a record of another entity and are created through a relation, not directly. Fields on a standard entity carry the same **System** / **Custom** badge as entities, so you can always tell which attributes your organization added. Adding a field to an entity changes every existing and future record of that entity at once — there is no per-record schema. ## Record types A **record type** is a named variant of one entity: a Service Order and a Sales Order can be two record types of Order, each with its own label, default flag and active flag. Layouts, views and validations can be scoped to a record type, and an app's navigation entry can point at one record type, so users who only handle one variant see only its list, form and rules. Unscoped metadata keeps applying to every record type, so adding a record type is additive. ## Views A **view** is a saved way of looking at a list. Two kinds exist and they answer different needs: - **Shared (administrator) views** are metadata on the entity: a label, a filter condition, a sort order, its columns, optional summary cards, and a **View Type** (a plain list, a grouped list on a group field, or a tree on a parent field). One view per entity is the **Default**; **Hidden** and inactive views stay out of the picker. Because they are metadata, they are the same for everybody who can see the entity and are the right place for team-wide definitions such as *My Open Orders* or *Overdue Invoices*. - **Personal views** are saved by a user from the list itself. They layer runtime state — search text, sort, column visibility and column order — on top of the shared view they were saved from, and are stored in that user's own preferences. Only their owner sees them, they never change what colleagues see, and each user can keep up to 20 per entity. Filter conditions set in the filter drawer are not captured by a personal view in the current release. ## Layouts A **layout** defines how a single record is arranged on screen: which fields appear, in which sections and order, and which related lists and widgets accompany them. Each layout has a **Type** — Create, View, Preview (the side-panel preview of a record) or Action (the form an action pops up) — and a **Platform**: Web, Mobile, or Both, where one layout record carries a web arrangement and a mobile arrangement side by side. A layout can be scoped to a record type and one layout per type is the default. Layouts are authored in the layout designer; see [Design a form layout](/docs/customization/layouts/design-a-form-layout/). ## Apps group entities into workspaces An **app** is a workspace for one area of the business. Its definition holds: - **Entities** — which entities appear in the app's navigation, with an optional display label, group title, order, a default entity that opens first, and optionally a record type so the entry lists only that variant. - **Navigation items** — built-in feature routes (Reports, Dashboards, Analytics, Recycle Bin), custom **App Pages** designed for that app, and grouped entries backed by a list app. - **Web** and **Mobile** switches, an icon and color, an active flag, a hidden flag and a display order. - An optional product license, so the app is only offered to tenants licensed for that module. The **App Launcher** in the top bar lists the apps that support the client you are on (web or mobile), lets you search by app name *or* by the name of an entity inside an app, and lets you pin favorites. Which apps a user sees is also governed by their security profile: an app must be granted to the profile before it appears, and the entities inside it still require entity permissions. Administrators manage apps under **Setup → Design Studio → Apps**. ## Standard and custom entities xMatix ships standard entities across its modules — accounts, orders, invoices and payments; items, stock and transfers; purchase orders and goods receipts; journals; leads, opportunities and cases; visits, service orders and assets. Your organization is not limited to these: - **Extend a standard entity** by adding custom fields, relations, record types, views, layouts, validations and actions. Custom fields on a standard entity are provisioned by a background schema step after you save them; give it a moment before you expect the field in lists and forms. - **Define a custom entity** for data the standard set does not cover. It is stored in the platform's shared dynamic storage, participates in apps, lists, views, layouts, relations, security profiles and record security exactly like a standard entity, and is ready to hold records as soon as it is saved. It does not inherit the compiled handlers or specialized widgets of a standard entity — add validations, business rules or automation scripts explicitly for any behavior you need. Confirm required *behavior* — not only fields — before replacing a standard process with a custom entity. The step-by-step guide is [Create a custom entity](/docs/customization/data-model/create-an-entity/). ## One definition drives web and mobile Web and mobile read the same entity, field, view and access metadata, so a new field, a governed picklist or a custom entity is recognized by both. Their renderers are not identical: a layout can target Web, Mobile or Both, some widgets exist on one surface only, and a compiled feature can add behavior on one client. Validate the target layout and workflow on each client your users rely on before announcing a change. ## Common questions ### What is the difference between an entity and a record? An entity is the definition; a record is the data. The Order entity says what an order *is* — its fields, relations and behavior — while each actual order in your organization is one Order record. Users spend their day with records; administrators spend theirs with entities. When someone says "we added a field to Orders", that is a change to the entity, and every existing and future order record gains that field. ### Can we add our own entities and fields? Yes. Administrators can add fields to standard entities and define new custom entities in **Design Studio → Entities** without any code. Custom entities get the shared list, view, layout, relation and access infrastructure. They do not automatically inherit the feature-specific handlers of a standard entity, so add and test any required automation explicitly. ### Why does a list look different for me than for a colleague? Three layers can differ. You may be on a different shared view (check the view picker), you may have a personal view or column arrangement applied on top of it, or your security profile may grant you fewer fields or a narrower set of records. Shared views and field permissions are administrator settings; personal views and column order are yours to change from the list toolbar — see [Personalizing lists and views](/docs/getting-started/personalizing/). ### Why do web and mobile show the same field? Because they share the same entity, field and access model. The presentation and supported layout behavior can still differ, and some features use client-specific widgets. Treat shared metadata as the common contract, then test the configured list, form and action on both clients that will use it. ## Related topics - [Navigating xMatix: apps, lists and records](/docs/getting-started/navigation/) - [Personalizing lists and views](/docs/getting-started/personalizing/) - [Create a custom entity](/docs/customization/data-model/create-an-entity/) - [Design a form layout](/docs/customization/layouts/design-a-form-layout/) - [The security model](/docs/concepts/security-model/) - [Tenants, companies and organizations](/docs/concepts/tenants-and-companies/) - [Concepts](/docs/concepts/) ---- # The customization ladder: which tool for which job URL: https://xmatix.com/docs/concepts/customization-ladder/ Last reviewed: 2026-09-06 When you need xMatix to behave differently, there is almost always more than one tool that could do it — and they form a ladder, from plain configuration at the bottom to custom code at the top. The rule that keeps a system maintainable is simple: **pick the lowest rung that genuinely solves the problem.** Lower rungs are declarative — visible in Setup, testable before they go live, and safe across product updates. Higher rungs buy expressive power at the cost of code that someone must read, test and maintain. Climb only when the requirement truly cannot be expressed a rung below, and never ship a weaker approximation just to stay declarative. ## Where the rungs live in Setup The bottom rung is **Setup → Design Studio → Entities**: open an entity and its **Schema** (fields, record types, relations, lookup filters, field dependencies), **Logic** (validations, actions, approval processes, document settings) and **Experience** (views, layouts, email templates) pages. Every higher rung is a register under **Setup → Process Studio**: **Business Rules**, **Scripts**, **UI Components**, **Workflows**, **Approvals**, and — for system boundaries rather than behavior — **Integrations** and **Sync Profiles**. Each register is gated by its own setup capability (for example `setup.automation.businessrules.manage`, `setup.automation.scripts.manage`, `setup.automation.workflows.manage`, `setup.automation.customcomponents.manage`, `setup.metadata.approval.manage`); the data model needs `setup.metadata.model.manage`. Before adding anything, search the relevant register: overlapping rules, scripts and workflows on the same entity are the commonest cause of surprising saves. ## The ladder at a glance | Rung | Tool | Reach for it when | | --- | --- | --- | | 1 | Field, validation and record-type configuration | The change is about a field: required, unique, a default, a picklist value, a format, a layout, a variant of the record | | 2 | Business rules | "When this record is saved (or changes state), enforce, derive or hand off something" | | 3 | Approval processes | A person must sign off before something proceeds | | 4 | Workflows | Multi-step processes over time: "then wait, then notify someone, then do a second thing later" | | 5 | Automation scripts | Server-side logic beyond declarative reach: cross-record calculations, calls to other systems, custom buttons | | 6 | Custom components | The standard user-interface widgets cannot express the experience | ## The rungs in detail ### Field, validation and record-type configuration The bottom rung is not really customization at all — it is the entity model itself. Required and unique fields, defaults, picklists, field formats, lookup filters, field dependencies, record types and page layouts cover a surprising share of requirements. A **validation** on the entity is a plain, always-on check with a message; it is the right home for a rule with no condition ("Quantity must be positive"). If the ask can be stated as a property of a field or as an unconditional check, it belongs here. See [Entity behavior](/docs/customization/entity-behavior/) and [Design a form layout](/docs/customization/layouts/design-a-form-layout/). ### Business rules A business rule is declarative logic evaluated inside the save pipeline: a **condition** on the incoming record and an ordered list of **actions**. Its triggers decide *when* it is evaluated — on every save, only on insert or update, only when named fields change, on delete, when a status field makes a specific transition (Draft → Submitted), after an approval decision, on an hourly schedule, or **after the save commits**. The actions split into two families, and the split matters for choosing a rung: - **Save-time actions** shape the record before it is written: Block Save and Show Message (error, warning or info), Set Value, Copy From Field, Format Value, Lookup Value, Set Required, Set Read-Only, Lock Record (with editable exceptions) and Enforce Unique. - **Bridge actions** run only after a successful commit and hand off to another subsystem instead of changing the record: Request Approval, Invoke Automation Script (a server-action-bound script), Raise Event, Assignment (route to a queue or resource), Create Activity, Create Record (of any entity), Send Message (templated e-mail or in-app), Enqueue Job and Raise Nudge. Because of the bridges, a rule reaches further than "this record only": it can start an approval, open a task, create a related record or kick off a script without any code of its own. What a rule cannot do is call an external system directly, compare arbitrary old and new values (a status transition has its own trigger; anything else needs a script), or wait — every action of a rule runs within the save or immediately after it. Rules have a **Test Runner** in Setup, so you can prove a condition against a real record before activating it. See [Business rules](/docs/customization/business-rules/). ### Approval processes When the requirement is "a manager must allow this", model it as an approval process — even when it looks like the escape hatch of a blocking rule. An approval process is defined per entity with an entry condition, an order (the first matching active process claims the record), who may submit, and one or more steps that resolve a real approver from a record field, a role or a team. It notifies the approver, can lock the record while the decision is pending, enforces maker-checker if you ask it to, stamps the outcome onto the record and leaves an audit trail of who decided what and when. Records enter it from a **Submit for approval** action, from a business rule's Request Approval bridge, or from a workflow step. An editable "approved" checkbox is not an approval: it records no approver, no timestamp and no reason. See [Approval processes](/docs/customization/approvals/). ### Workflows A workflow orchestrates across time and across records in a visual designer: it starts from a record event (create, update or delete of a named entity, either synchronously *before* the save — the only phase that can cancel it — or asynchronously *after* it), then runs steps such as branch, wait, send a message, submit for approval, update or create records, call a script or enqueue a job. Triggers register only from the **published** version; every edit is a draft until you publish again. If the ask contains "and then, later…", it is a workflow rather than a business rule. See [Build a workflow](/docs/customization/workflows/). ### Automation scripts Scripts are C# code compiled when you save them and run by the platform in a sandbox with a single `Ctx` object as their whole contract: records with old values, data access to any entity, metadata, outbound HTTP, messaging and e-mail, jobs and queues, approvals, secrets and logging. A script is bound to an entity either on a **lifecycle** slot — load defaults (inserts), pre-validate, validate, before save, after save, before delete, after delete — with the change kinds it listens to and an optional condition, or to a **server action** behind a button. Bindings can run inline or asynchronously on the worker; inline runs have a 10-second budget, asynchronous runs 60 seconds. Reach for a script for cross-record calculations, external calls, complex old-versus-new comparisons and the logic behind custom buttons. See [Your first automation script](/docs/customization/automation-scripts/quickstart/). ### Custom components Custom components (**Process Studio → UI Components**) are your own user-interface widgets, versioned like scripts and bound to one entity or to all entities, and optionally offered inside App Pages. They are placed in layouts and pages by the designer and read and write through the same data APIs as the rest of the product, so security and validation still apply. This rung is for presentation; if the logic could live server-side, keep it there. This is the one rung that runs in the browser rather than on the server, so a component can never enforce anything — pair it with a rule or validation when data integrity depends on it. ## Choosing quickly A few signal phrases map directly to rungs: "this field must…" is configuration; "when the record is saved…" is a business rule; "someone must approve…" is an approval process; "then wait / then notify / then later…" is a workflow; "look across records / call another system…" is a script; "show it differently…" is a layout or a component. When two rungs both work, the lower one wins. Two further questions settle most borderline cases. *Does it need to block the save?* Only validations, save-time rule actions, before-save workflows and validate/before-save scripts can; anything that runs after the commit cannot. *Must it survive an edit by any administrator?* Rules, approvals and workflows are readable in Setup by anyone with the capability; a script is readable only by someone who reads code. ## Try it somewhere safe Every rung can be authored in a [sandbox](/docs/administration/sandboxes/) copied from production and moved across with a package, so a new rule, workflow or script never meets live records untested. All rungs also run inside one fixed save pipeline — defaults, validation, rules, module logic, then workflows and scripts — and when two customizations seem to fight, that order is almost always the explanation; see [What runs when you save a record](/docs/concepts/execution-order/). ## Common questions ### Why prefer a business rule over an automation script? Because a rule is declarative: any administrator can open it in Setup, read exactly what it does, test it against a record, and adjust it without a developer. A script is code — more expressive, but opaque to non-developers and a maintenance obligation from the day it ships. Both run in the save pipeline, so for single-record save logic the rule delivers the same outcome at lower cost. Reserve scripts for what rules genuinely cannot express: cross-record calculations, external calls, complex comparisons of old and new values. ### Can a business rule call another system? Not directly — a rule never makes an outbound call itself, which is what makes it safe to run inside every save. It can *hand off*: its after-commit bridge actions can invoke a server-action script (which may call out through `Ctx.Http`), send a templated message, enqueue a background job or raise an event. When a save must reach another system, use one of those bridges or an integration flow when you need connector-grade retry and monitoring. See the [integrations overview](/platform/integrations/) for how external connections are modeled. ### Isn't an "override" checkbox simpler than an approval process? Simpler to build, worse in every way that matters. A checkbox that lifts a block records nothing: no approver identity, no timestamp, no reason, and anyone with edit rights can tick it. An approval process resolves the right approver, notifies them, locks the record while pending, and writes an audit trail. If you do choose a checkbox as a deliberate lightweight alternative, restrict who can edit it with field-level security — and treat that as the exception, not the default. ### When is a workflow the wrong tool? When everything it does happens inside one save with no waiting and no branching over time — that is a rule. And when it must block the save on a condition — a rule or validation does that without the publish-and-version overhead, and an asynchronous workflow cannot block at all. ## Related topics - [What runs when you save a record](/docs/concepts/execution-order/) - [Apps, entities and records](/docs/concepts/apps-entities-records/) - [Customization](/docs/customization/) - [Business rules](/docs/customization/business-rules/) - [Approval processes](/docs/customization/approvals/) - [Build a workflow](/docs/customization/workflows/) - [Your first automation script](/docs/customization/automation-scripts/quickstart/) - [Automation on the xMatix platform](/platform/automation/) ---- # Delete, recycle bin, archive and restore URL: https://xmatix.com/docs/concepts/data-lifecycle/ Last reviewed: 2026-09-06 ## Soft delete and the Recycle Bin Deleting a supported record in xMatix is normally a soft delete. The platform stamps the row with who deleted it, when, an optional reason and a **Purge After** deadline, and excludes it from ordinary entity queries — it disappears from lists, lookups and reports even though it is still stored. Until the deadline passes it can be brought back from the **Recycle Bin**. @[guided-image](_img/data-lifecycle-context.png) Open the Recycle Bin from the App Launcher (it is listed with the apps, and administrators can add it to any app's navigation as the **Recycle Bin** item). The screen first lists every entity that currently has deleted rows, with a count; selecting one shows only that entity's soft-deleted rows with **Name**, **Deleted**, **Reason** and **Purge After**. **Restore** acts on one row; ticking rows and choosing **Restore selected** restores exactly those rows. Opening a row shows its stored field values, so you can check what you are about to bring back. The retention window is 30 days by default (`Purge After` = deletion time + the configured retention days), so read the deadline from the row rather than assuming it. Rows deleted as part of removing a whole organization are excluded from the bin. ## Delete and cascade are separate questions The delete operation can affect related rows when a relation or feature handler is configured to cascade. That behavior belongs to the entity model and the specific delete path; it is not reconstructed by the Recycle Bin. Before deleting a parent record, inspect its relations and feature documentation rather than assuming either that every child follows it or that none do. Ordinary application queries filter soft-deleted rows. Integrations or privileged maintenance paths can have different contracts, so verify the consumer rather than promising that every possible query hides deleted data in the same way. ## Restore is row-scoped Restoring a row clears its deletion timestamp, actor, reason and purge deadline, then saves that row back into the active population. Bulk restore performs the same operation for the IDs selected within one entity. Restore does **not** walk a remembered parent-child deletion graph. If an order and its lines were deleted, restoring the order does not automatically restore its lines; locate and restore every required row explicitly, then validate the aggregate before returning it to users. References may also have changed while the row was deleted, so check lookups, uniqueness constraints and downstream balances after restoration. Access to the Recycle Bin is not tied to an entity's **Delete** grant. In the current release the recycle-bin service checks only that the caller is signed in — it does not apply entity permissions or record security to the rows it lists or restores — so the practical control is whether the Recycle Bin app is visible to a user's profile. Keep that visibility to administrators. ## What happens after Purge After A platform retention worker runs on a schedule (hourly by default, where it is enabled for the deployment), finds soft-deleted rows whose **Purge After** has elapsed, writes their stored data to an archive and removes them from the live database. They then disappear from the Recycle Bin, so self-service restore is no longer available. A platform operator can request recovery of individually identified archived rows. That process re-inserts them **as soft-deleted rows** — with their original deletion metadata and a fresh Purge After of now plus the retention window — so they reappear in the Recycle Bin for an administrator to review and restore; the restore is idempotent and skips rows that already exist. Archive recovery is row-scoped: requesting one parent does not reconstruct its related rows. ## Before a bulk delete 1. **Resolve the exact population.** Save or export the filtered IDs you intend to delete and have the business owner approve them. 2. **Map delete behavior.** Inspect relations and feature handlers for cascades, blocks and cleanup actions. 3. **Export what recovery needs.** The archive can preserve rows, but an approved business export makes identity and reconciliation easier. 4. **Record the deadline.** Check the resulting **Purge After** values immediately after the operation; do not calculate the deadline from memory. 5. **Plan a row-by-row recovery set.** Include child and linking entities that would be needed to reconstruct a usable aggregate. 6. **Validate references after restore.** Recheck lookups, document lines, totals, security scope and any external system that consumed the deletion. ## Common questions ### Is deleted data destroyed immediately? Not for records handled by the platform's soft-delete path. The row is hidden from ordinary entity queries and remains in the Recycle Bin until its purge deadline. A feature-specific hard delete or external-system deletion can behave differently, so verify the exact action before relying on recovery. ### Does restoring a parent bring its children back? No automatic cascade restore is implemented by the Recycle Bin. Restore the parent and each required child or linking row explicitly, then validate the complete business record. ### What happens when the retention window expires? The retention worker archives the row and removes it from the live database; it no longer appears in the Recycle Bin. Recovery then needs a platform operator to replay the selected archived rows back into the bin with a new grace window, after which an administrator restores them. ### Can I change the retention window? The window is a platform setting (30 days by default), not something an administrator sets per organization or per entity. Ask your platform contact if you need a different window. ## Related topics - [xMatix administration guide](/docs/administration/) - [How the xMatix security model works](/docs/concepts/security-model/) - [Apps, entities and records](/docs/concepts/apps-entities-records/) ---- # What runs when you save a record URL: https://xmatix.com/docs/concepts/execution-order/ Last reviewed: 2026-09-06 ## Read the entity Execution Plan @[guided-image](_img/execution-order-context.png) The **Execution Plan** (Setup → **Design Studio → Entities →** the entity **→ Logic → Execution Plan**) is the implementation-backed answer to “what runs when this record is saved?” The example shows the Order entity with the **Insert** ladder selected. The header confirms whether the plan is complete, identifies compiled or custom storage, counts steps and phases, and warns about unsequenced or unordered work. Each numbered phase then places platform handlers, business rules, workflows and scripts on the sequence slots they occupy, and every step carries badges for its sequence origin, inline execution and whether a failure blocks or continues. Always choose the operation you are diagnosing—**Insert**, **Update**, **Delete** or **All**—before reading the ladder. Expand the affected phase, inspect every step in its slot, and treat warning badges as part of the contract. **Recent runs** answers what happened on actual saves; the plan answers what is configured to happen. xMatix does not run each customization surface as one isolated global stage. It uses shared lifecycle phases, and the configured steps from several surfaces can appear together inside a phase. The Execution Plan is therefore more reliable than a memorized rule such as “all business rules run before all scripts.” ## The lifecycle phases | Phase | Purpose | Can it prevent the operation? | | --- | --- | --- | | **Load Defaults** | Insert-only audit stamps, defaults, numbering and other initial values | No; it prepares a new row before validation | | **PreValidate** | Insert/update normalization that must happen before metadata validation | No; failures are treated as non-blocking by this phase | | **Validate** | Metadata validation, blocking business rules, validation scripts and workflow steps mapped to validation | Yes | | **Before Save** | In-transaction work immediately before an insert or update is written | Yes | | **Before Delete** | Delete-specific in-transaction checks and effects | Yes | | **After Save** | Work after the row is written while the enclosing transaction may still be open | Yes; a propagated failure can still roll back the save | | **After Delete** | Delete-specific post-write work while the transaction may still be open | Yes for the same transactional reason | | **PostCommit** | Saved triggers, post-save rule actions and deferred workflow/integration work after commit | No; the record is already committed | | **OnFailure** | Compensation and failure observers when the save itself failed | It reacts to the failure rather than deciding the original save | Not every operation uses every phase. **Load Defaults** is insert-only; delete uses its delete-specific phases; PostCommit runs only after a successful commit; OnFailure appears only on failure. Select **All** when comparing ladders, not when trying to answer the order for one concrete save. ## Sequence slots are shared within a phase Within one phase, steps are ordered on a shared numeric sequence line. An explicitly sequenced script, workflow or other supported step can therefore be placed relative to a step from another surface in that same phase. A sequence does not move work into a different phase: a Validate step cannot be sequenced into PostCommit. Three details matter: - **Unsequenced** means the artifact uses its surface's default slot. Make the sequence explicit when another step must reliably run before or after it. - **Shared slot** means multiple steps have the same effective sequence. Some, such as business rules sharing a slot, deliberately run as one engine call so `StopOnFalse` and SetValue priority can be resolved together. Other slots may be marked **unordered**, meaning their relative order is not defined. - **Sequence not enforced** means the plan can display the requested position but the current runtime path does not honor it. Treat that badge as a release blocker for any dependency on the shown order. Business-rule **Sequence** positions a rule's slot on this cross-surface line where runtime support is active. Rules within the same slot are evaluated together; their **Order** supplies the intra-slot order and **Priority** resolves competing SetValue actions on the same field. Those fields are not interchangeable. ## Platform logic, workflows, approvals and scripts First-party module behavior is represented as platform or C# handler steps in the same phases. This is where sales, inventory, finance and other feature validation or derivation appears; it is not a single opaque “module logic after rules” stage. Workflows and automation scripts are mapped to the phase configured for their binding. A validation-phase step can block; a PostCommit continuation cannot undo the committed row. Asynchronous steps can finish later, so never make the next synchronous save step depend on their completion. Approval is not an automatic universal phase that every eligible save enters. A record reaches approval only through a configured entry point—for example a Request Approval rule action, an explicit record action, a workflow or feature-specific handler. Inspect that entry artifact and the entity's Approval Processes alongside the Execution Plan. ## Diagnose a blocked save or changed value 1. Open **Design Studio → Entities**, select the exact entity, expand **Logic**, and open **Execution Plan**. 2. Select Insert, Update or Delete to match the failed operation. 3. Confirm **Plan complete**. If a source is unavailable, fix that visibility problem before assuming the ladder is exhaustive. 4. Expand the phase named by the error or trace. If none is named, start at Validate for a rejected save and work forward for an unexpected value. 5. Read slots from lowest to highest sequence. Inspect every artifact in a shared slot and every warning badge. 6. For a value change, identify each writer and find the last **successfully executed in-transaction** writer. PostCommit work can create later effects, but it cannot rewrite the already committed transaction without starting a separate operation. 7. Open **Recent runs** and match the entity, operation and timestamp. Compare observed steps with the plan before changing configuration. 8. Test the smallest safe change with both a passing and failing record, then restore the intended sequence documentation. ## Common questions ### A business rule and a script both set the same field—which wins? There is no safe category-wide answer. Compare their lifecycle phase, effective sequence and slot behavior in the entity's Execution Plan. A later in-transaction writer normally supplies the stored value, unless an earlier step blocks the save or the steps share an engine slot whose own priority rules decide the conflict. ### Can I put a script before a business rule? Yes only when both map to the same lifecycle phase and their runtime paths enforce the configured sequence. Set explicit sequences, then verify the plan shows the intended slots without a **sequence not enforced** or **unordered** warning. A sequence cannot cross phase boundaries. ### Can After Save fail the save? Yes. The row may have been written to the database context, but the enclosing transaction can still be open. A propagated After Save or After Delete failure can roll the transaction back. Only **PostCommit** is definitively too late to block the committed operation. ### Does every qualifying record enter approval automatically? No. Approval requires a configured entry action or feature path. The process definition describes what happens after entry; it does not by itself submit every record that happens to match its entity. ## Related topics - [The customization ladder](/docs/concepts/customization-ladder/) - [Apps, entities and records](/docs/concepts/apps-entities-records/) - [Automation on the xMatix platform](/platform/automation/) ---- # xMatix platform concepts URL: https://xmatix.com/docs/concepts/ Last reviewed: 2026-09-01 ## Read the platform model map @[guided-image](_img/concepts-overview.png) Setup makes the platform's mental model visible. Design Studio defines entities, apps, packages and global picklists; Process Studio defines behavior over those records; Data Studio governs movement and analytical shapes; Sense AI Studio configures intelligence; Access Control governs people and permissions; and Platform Operations covers the tenant's operating controls. The selected Entities page demonstrates how a concept becomes concrete metadata that every runtime surface consumes. Use this map to decide where a question belongs before changing configuration. A missing field begins in Design Studio, an unexpected save action in Process Studio, a visibility issue in Access Control, and an AI behavior question in Sense AI Studio. The screenshot uses visible synthetic demo2 data so readers can follow realistic rows, values and controls together; production exports and screenshots must still remain inside authorized channels. The concepts section explains the mental models behind xMatix — the small set of ideas that every screen, module and setup option is built on. Each page answers one question in plain language: how your organization's private space is structured, how work is organized into apps and records, who can see and do what, which customization tool fits which job, what runs when a record is saved, what happens to deleted data, how the mobile app works without a network, and how the Sense AI assistant is kept inside the same rules as everything else. None of these pages is a how-to; they are the background that makes the how-tos make sense. ## What this section covers The pages build on one another, so reading them in order works well the first time through: - [Tenants and companies](/docs/concepts/tenants-and-companies/) — how your organization's private tenant relates to the companies, branches and business units you run inside it. - [Apps, entities and records](/docs/concepts/apps-entities-records/) — the data model: entities describe the shape of your data, records hold it, and apps group it into workspaces. - [Security model](/docs/concepts/security-model/) — the layers that decide what a user may do and which records they may reach: profiles, capabilities, licensing and record-level security. - [Customization ladder](/docs/concepts/customization-ladder/) — which tool to reach for when you change how xMatix behaves, from plain configuration up to custom code, and why the lowest rung that works is the right choice. - [Execution order](/docs/concepts/execution-order/) — what runs, and in what sequence, when a record is saved: defaults, validation, business rules, module logic, workflows, approvals and scripts. - [Data lifecycle](/docs/concepts/data-lifecycle/) — what delete really does: the recycle bin, restore, retention windows and archiving. - [Offline mobile](/docs/concepts/offline-mobile/) — how the mobile app keeps your data on the device, queues edits made offline, and syncs them when connectivity returns. - [Sense AI governance](/docs/concepts/sense-governance/) — how the AI assistant is scoped to each user's permissions, what it is allowed to write, and how administrators control its availability. ## Who these pages are for Administrators get the most from this section: almost every configuration decision — a new field, a security profile, a business rule, an approval process — sits on top of one of these models, and choices are easier to make when you know what the platform is doing underneath. The first two pages and the offline mobile page are also written for everyday users who want to understand why the product is shaped the way it is. Implementation partners and reviewers evaluating xMatix will find the section useful as a compact description of the platform's architecture in user-facing terms. ## How concepts relate to the rest of the documentation The [getting started guide](/docs/getting-started/) teaches the screens: signing in, navigating apps, lists and records. The [administration guide](/docs/administration/) holds the procedures: the exact clicks to create a security profile or share a record. This section holds the reasoning that connects them. When a procedure tells you *what* to do, the matching concept page tells you *why* it works and what else it affects — so a good pattern is to skim the concept page once, then work from the procedures day to day and come back here when something behaves in a way you did not expect. ## Related topics - [What is xMatix?](/what-is-xmatix/) - [Getting started with xMatix](/docs/getting-started/) - [xMatix administration guide](/docs/administration/) ---- # How offline-first mobile works URL: https://xmatix.com/docs/concepts/offline-mobile/ Last reviewed: 2026-09-01 The xMatix mobile app is built offline-first: the data your work needs is kept on the device, screens read from that local copy, and edits made without a network wait in an outbox until connectivity returns. There is no separate "offline mode" to switch into — connectivity is just a state the app tracks. When the network drops mid-visit, you keep browsing and editing the same screens; when it returns, queued changes sync in the background. The design goal is that a field day with patchy coverage looks, from the user's side, like a normal day. Before field work, open the assigned record while connected and confirm the required lookups and reference data are available. After editing, use the app's sync status and pending-changes view to distinguish a locally saved item from a server-confirmed one; never assume that tapping Save proves upload. ## What lives on your device The app keeps a local copy of the data your role works with: reference data such as customers, products, price lists and picklists, plus a recent window of transactions — recent documents, records assigned to you, and anything with pending local edits. Form layouts and settings are cached too, so records open and forms render without a network. Which record types are available offline, and how much history is kept, follows your organization's sync configuration, so an administrator can widen or narrow the offline footprint per entity rather than syncing everything to every phone. ## Edits queue in an outbox Every save on mobile goes through a durable outbox on the device. Online, a queued change is sent immediately and you barely notice the queue exists; offline, it simply waits. Queued changes are kept until they sync — they survive closing the app, restarting the phone, and even your session expiring, in which case sending pauses until you sign in again rather than anything being dropped. Each queued change also carries its own identity, which the server uses to recognize a resend: if the app retries after an interrupted connection, the change is applied once, not twice. ## Sync status is visible You should never have to guess whether your work has reached the server. The app shows connection state and last-synced time, and a pending changes screen lists every queued edit with its status: waiting to send, sent, or needs attention. If the server rejects a change — a validation rule failed, for instance — the item is marked failed with the reason attached; you can open it, fix the field the server complained about, and resubmit, or discard it deliberately. Failed items stay on the device until you act on them, so a rejection is something you resolve, not something that silently vanishes. ## Conflicts are resolved, not silently lost If a record you edited offline was also changed on the server in the meantime, the app does not blindly overwrite either side. The sync detects that the record moved underneath your edit and parks your change as a conflict, and you choose how to proceed — keep your version or discard it in favor of the server's. The mechanism matters more than the label: your queued edit is preserved through the conflict, so whichever way you decide, the decision is yours and made with both versions on the table rather than by whichever device happened to sync last. ## Long stretches offline The model holds over days, not just minutes. Cached data remains readable and editable however long you are disconnected, and the outbox keeps accumulating. Two things are worth knowing about extended gaps: an expired sign-in pauses syncing but never discards local work, and after a very long gap the app refreshes its local data in full on reconnection — the reliable way to catch deletions and permission changes that happened while it was away. ## Common questions ### What happens if I close the app before my changes sync? Nothing is lost. Queued changes live in the outbox on the device, not in the app's running memory, so they survive the app being closed, the phone restarting, or the battery dying. The next time the app runs with connectivity, the queue resumes sending from where it left off. Each change's identity ensures a resend after an interruption is applied exactly once, so you can close the app mid-sync without creating duplicates. ### What if someone edited the same record while I was offline? The app detects it at sync time: your change is parked as a conflict instead of being applied over theirs. You will see it flagged on the pending changes screen with both facts visible — your edit, and that the server version moved — and you decide whether to keep your version or discard it. Neither your edit nor theirs is silently overwritten; the queued change is preserved until you make the call. ### My session expired while I was offline — is my queued work gone? No. Authentication and your local data are deliberately independent: an expired session pauses sending, nothing more. You can keep reading cached records and keep queueing edits while signed out of the server's view; when you next sign in, the outbox resumes and everything queued goes up in order. Signing out explicitly asks before touching local data, so even a deliberate logout does not quietly take your pending work with it. ### Why can't my colleague see the record I just created? Because it has not synced yet. A record created offline exists on your device the moment you save it, but it reaches your colleagues only after your outbox sends it and their apps pull the update. Check the pending changes screen: if the item is still waiting or has failed validation, that is the reason. Once it shows as sent, it is on the server and visible to everyone with access. ## Related topics - [xMatix mobile](/products/mobile/) - [Navigating xMatix: apps, lists and records](/docs/getting-started/navigation/) - [Apps, entities and records](/docs/concepts/apps-entities-records/) ---- # How the xMatix security model works URL: https://xmatix.com/docs/concepts/security-model/ Last reviewed: 2026-09-06 xMatix decides what a user can do with layered checks, and each layer answers a different question. **Licensing** answers *what exists for this organization and this user at all*. **Security profiles** answer *what operations the user may perform on each entity, field, app and action*. **Capabilities** answer *which Setup areas the user may administer*. **Record-level security** answers *which specific records the user may reach*. **Company scoping**, where it is switched on, answers *which company's books the user may see and post into*. An operation succeeds only when every applicable layer agrees — and because every grant is additive, the model stays predictable: to restrict something you narrow a grant, never add a deny. @[guided-image](_img/security-model-context.png) The one screen that shows all of these layers together for a person is the user's **Access Diagnostics** tab (**Setup → Access Control → Users**, open the user). It lists the audience, the resolved profiles and roles, teams and business units, and — for product licenses, feature licenses and capabilities — what is *allocated to the user* beside what the profiles *require*. When someone asks "why can't I see this?", start there; [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/) walks the checks in order. ## Permission and access are two different questions Most confusion about security disappears once you separate two decisions. **Permission** means a user is authorized to perform an operation in principle — "may update orders", "may read the credit-limit field". **Access** means the user may operate on one specific record — "may see *this* order, because they own it or it was shared with them". Both must be true: a user with update permission on orders still cannot edit an order they have no access to, and a user who can see a record cannot edit it without update permission. "I can see it but can't change it" and "I have the permission but can't find the record" point at the two different layers. ## Security profiles: what a user may do A security profile (**Setup → Access Control → Profiles**) is a reusable, named bundle of grants with an **Audience Scope** — *Internal*, *External* or *Both* — and an active flag. A user can hold several profiles; only active profiles whose scope matches the user's audience count, and the effective permission set is the **union** of everything they grant. The bundle has several parts: - **Entity permissions** — per entity, any combination of Read, Create, Update, Delete, Share and Assign, plus the elevated **View All** and **Modify All**, which step around record-level scoping for that entity. - **Field permissions** — per field, whether it may be read, set on create, or changed on update; this is how sensitive fields stay hidden or read-only. - **App and App Page permissions** — which apps and custom pages appear in the launcher and navigation. - **Action permissions** — which server actions (custom buttons) the user may invoke. - **Entitlements and capabilities** — the product and feature licenses the profile requires, and the Setup capabilities it grants (next two sections). - **Reports and dashboards** — visibility of shared analytics. A user with no matching profile, or whose profiles grant nothing on an entity, is denied outright — there is no implicit baseline. The step-by-step guide is in [security profiles](/docs/administration/security-profiles/). ## Capabilities: rights over Setup areas Data permissions do not cover everything an administrator does — opening Design Studio, managing licenses, tuning Sense AI, running data imports. These are governed by **capability keys** of the form `setup..` (for example `setup.security.manage`, `setup.metadata.model.manage`, `setup.diagnostics.jobs.view`). Each Setup screen is gated by one key, and a key is granted to a profile like any other permission. Two rules matter: a capability takes effect only when the user *also* holds the feature license the capability belongs to, and a user with no profile or no feature license has an empty capability set — which is why a freshly invited administrator sees no Setup menu until both are in place. Keeping capabilities separate from data permissions means granting someone a Setup right never widens their data access, and vice versa. ## Licensing: what exists at all Licensing sits above the other layers. Products (Sales, Service, Finance, Sense AI…) and the features inside them are licensed to the organization with seat counts and expiry, and users are allocated seats. A user's effective products are the intersection of three sets — what their profiles require, what the organization has licensed, and what has been allocated to them — with the same intersection for features. Features marked *free* are granted automatically to every user whose profile holds the owning product, so purely administrative capability bundles need no seat. A feature the organization has not licensed, or a user without a seat where seats are enforced, is simply not offered: no profile can grant what licensing has not made available. See [licensing](/docs/administration/licensing/). ## Record-level security: which records a user reaches For each entity, a **security policy** (**Setup → Access Control → Policies**) decides how record access is computed. It carries an **ownership model**, a **default access** level for internal and for external users (Private, Read Only or Read Write), and three switches — **Grant Access Using Hierarchy**, **Allow Manual Share** and **Allow Team Access**. First-party entities ship with a policy that is User Owned, Private by default and has all three switches on; an entity with no policy is treated the same way. Given a policy, the server resolves access for a query in this order: 1. If nobody is signed in, the query returns nothing — access fails closed. 2. If the entity is **Organization Owned**, every record is visible to anyone with Read permission. (Team Owned is not yet enforced and evaluates as User Owned.) 3. If one of the user's profiles grants **View All** on the entity, reads see every record; **Modify All** does the same for updates and deletes. 4. If the policy's default access for the user's audience is Read Only (for reads) or Read Write (for writes), every record is visible without further checks. 5. Otherwise the user reaches records they **own**; records owned by users in roles beneath theirs (**hierarchy**, when the switch is on); records **shared** with them directly, with a **team** they belong to, or with the **business unit** their role sits in (when sharing and team access are on). 6. **Rules** attached to the policy then run: an *access grant* rule widens the set for records matching its expression and its target principals (owner, team, role, business unit, all internal or external users…); an *access filter* rule narrows what is visible. Each rule names the operations it applies to, an audience, a priority and an enabled flag. Ownership, hierarchy, teams, business units and shares are all additive — a record is reachable if any one path grants it. The how-to for shares and policies is [record-level security](/docs/administration/record-security/); scoping visibility with rules is in [restriction rules](/docs/administration/restriction-rules/). ## Roles, teams and business units **Roles** form the reporting hierarchy that record visibility rolls up through: a manager's role lets them reach records owned by users in roles beneath it, on entities whose policy allows hierarchy access. Roles grant no permissions of their own. **Teams** are working groups a record can be shared with, and **business units** group roles organizationally and can also be the target of a share. All three are assigned per user under **Setup → Access Control → Users**; see [roles, teams and business units](/docs/administration/roles-teams-business-units/). ## Company scoping: a separate boundary inside the tenant Organizations that transact through several companies can restrict users to particular companies, with *view* access for reporting and *transact* access for posting. This is a distinct layer from record-level security: it is switched on per organization and enforced by deployment configuration, and a profile flag (**Access to all companies**, seeded on the built-in System Admin profile) or a per-user flag bypasses it for consolidation and administration. [Tenants and companies](/docs/concepts/tenants-and-companies/) explains when it applies. ## Common questions ### A user has the right profile but cannot see a record — why? The profile granted permission; what is missing is access. Check the entity's policy first: if the entity is User Owned with Private default access, the user needs a path to that record — ownership, a role above the owner (with hierarchy access on), membership of a team the record is shared with, a business-unit or direct share, or a grant rule. Also confirm the mechanism you expect is switched on in the policy: a team share does nothing on an entity whose policy has team access off. Access Diagnostics shows the user's resolved roles, teams and business units so you can see which paths could apply. ### Do roles grant permissions? No — and the separation is deliberate. Roles define whose records roll up to whom; profiles define what may be done. A manager who can *see* a subordinate's order still needs Update on Order from a profile before editing it. ### Can I deny a specific user something their profile grants? Not with a deny rule — the model has no explicit deny, and every grant is additive. To restrict, narrow what is granted: split a broad profile into narrower ones and assign the narrower set, remove the field permission rather than masking the field in a layout, or tighten the entity's policy so fewer access paths apply. Additive-only resolution is what keeps the outcome traceable: any access a user has can be followed back to a specific grant. ### Why does an external (portal) user see nothing even with a profile? Two likely causes. The profile's audience scope is *Internal*, so it is ignored for an external user — external users need a profile scoped *External* or *Both*. Or the entity policy's **external default access** is Private and no share or rule reaches the portal user's records; external access is decided by the external default and rules, separately from the internal one. ### How quickly does a security change take effect? Profile, role, team, license and capability resolution is cached per user for a short interval, so a change may take a few minutes to reach an already signed-in user; a fresh sign-in picks it up immediately. ## Related topics - [Managing security profiles](/docs/administration/security-profiles/) - [Record-level security](/docs/administration/record-security/) - [Restriction rules](/docs/administration/restriction-rules/) - [Roles, teams and business units](/docs/administration/roles-teams-business-units/) - [Licensing](/docs/administration/licensing/) - [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/) - [Tenants and companies](/docs/concepts/tenants-and-companies/) - [Platform security and governance](/platform/security/) ---- # How Sense AI is governed URL: https://xmatix.com/docs/concepts/sense-governance/ Last reviewed: 2026-09-06 Sense AI does not operate outside the platform. Every answer it gives, every record it touches and every nudge it raises passes through the same security, business rules and audit as a person doing the same thing — under an identity you can name, with tools you granted, inside budgets you set. Governance therefore rests on five things you control from **Setup → Sense AI Studio**: the **identity** an agent executes as, the **tools** it is allowed to call, whether an action needs **approval**, where **nudges** come from and how loudly they speak, and the **switches** that decide whether Sense exists for your users at all. @[guided-image](_img/sense-governance-context.png) An agent's detail page (**Sense AI Studio → Agents**, open an agent) is where most of this is visible in one place: which model it uses, the **Execution Account** it runs as, its **Interaction Mode**, whether it supports chat, queued runs, scheduling and **Approvals**, and its limits — maximum tool calls per run, maximum autonomous steps, timeout and concurrency. The *Instructions & Routing* tab holds the instructions a tenant may add, the **Capability Grants** that bound its tools, and the knowledge collections it may search. Managing agents requires the `setup.aistudio.agents.manage` capability; models require `setup.aistudio.models.manage`. ## Know which identity is executing Interactive chat runs as the **signed-in user**: entity, field and record access apply exactly as they do in the workspace, so two users asking the same question can legitimately get different answers. When the router hands a turn to a different agent, the identity is re-resolved for that agent — never inherited from the default one. An agent can instead be pinned to an **Execution Account**, chosen from the tenant's user accounts. That account's security profiles — not the viewer's — decide what the run can read and write, which is how a scheduled or event-triggered workflow can act without a person present, and how a pipeline can be bounded to a deliberately scoped operator. Background runs whose agent has no execution account fall back to a platform system identity (shown as *System Process Fallback* on the agent page); an operations-side option can point that fallback at a dedicated least-privilege *System Agent* user per tenant instead. Before publishing an agent that runs unattended, read its execution account as you would read a user's Access Diagnostics, and prefer a scoped account over a broad one. ## Tools are granted, never assumed An agent can only call tools it has been granted. Built-in tools are grouped into platform **capabilities**; your own script tools and MCP servers can be bundled into tenant-defined capabilities under **Configuration → Capabilities**. An agent with no grants inherits the full capability set the platform profile allows; an agent with **Capability Grants** gets only the intersection of those grants with that platform ceiling — granting a name never widens beyond what the platform and your feature licenses permit. Write-capable tools (updating records, publishing nudges, acting in the user interface) are gated separately from read tools, and the agent's *Max Tool Calls* and *Max Autonomous Steps* bound how much any single run can do. ## Approval is a deliberate setting, not a default When a tool that requires approval is about to run during a chat, the conversation pauses and the user sees **Approve this action?** with the proposed change; nothing happens until they allow it. Which tools require approval is set by the execution policy behind the agent, and the platform default is *not* to require it — so autonomous workflows and nudge publication run without a person in the loop unless you decide otherwise. The agent's **Approvals** flag says whether the agent participates in approval flows at all. Review both for every agent that can write: require approval where the business risk demands it, and remember that a scheduled run has nobody to approve, so its safety comes from its execution account and grants. ## Nudge sources have different trust models Nudges — the suggestions on record panels, list views and the Sense home feed — come from four **kinds** of source, all listed under **Configuration → Nudges**: **built-in** signal providers that run deterministic checks (dormant customers, overdue receivables, stale drafts, scheme gaps…), **rule** sources authored as the *Raise Nudge* action of a business rule, **agent** sources published by a tenant-authored agent through its nudge tools, and **external** ingests from other systems through the ingest endpoint. Each row shows its kind, category and the entities it watches, and can be disabled, given a longer dismissal cooldown, capped in how many nudges it surfaces per view, or have its thresholds overridden; no override means the code default. Treat kind as part of the evidence. A built-in provider's threshold is fixed and inspectable; an agent source depends on that agent's instructions, model and grants; an external source depends on who is allowed to post to the ingest endpoint (it requires the agents-manage capability). Whatever the source, a nudge never executes anything itself: its actions run through the ordinary APIs with the user's own token, so permissions, business rules, approvals and audit apply as if the user had done it by hand, and **Why?** shows the evidence behind it. ## Activity is recorded Sense's footprint is observable. Every agent run is stored with its conversation, the tools it called and the identity it ran under; the execution account is stamped on the run, so an autonomous change is attributable. Record changes that originate from a confirmed suggestion are ordinary audited edits. Nudge interactions — dismiss, snooze, applied, feedback — are recorded per nudge and feed ranking, so a source that users keep dismissing is demoted and can be tuned or switched off. **Configuration → AI Credits** shows allowances and consumption for the period: credits are metered per model, and when a tenant or per-user allowance is exhausted the assistant stops taking turns until the next period or a larger allocation. ## Administrators control availability Whether Sense exists for your users is layered, and each layer is yours: - **Licensing** holds the Sense AI product on security profiles — every profile holds it by default, so every user sees the Sense surfaces; remove it from a profile and those users see none, whatever else is switched on. - **Module settings** (**Configuration → Sense AI Settings**) provide the master switch for the module, an independent **Enable Sense AI nudges** switch that stops nudge computation and display while leaving the chat assistant available, **Show AI model in assistant chat** (off by default, so model and provider names stay hidden from users), and **Remember users across conversations**, which controls long-term per-user memory — users can review and forget their own memories regardless. - **Per-source and per-agent controls** — the nudge registry's enabled, cooldown, cap and threshold settings, and each agent's active flag, audience teams, execution account and grants. - **External Assistants** (**Configuration → External Assistants**) decides whether people may connect other AI assistants to xMatix at all and whether those connections may write; each person signs in with their own account and sees only what they already can, and connections can be revoked there. Off means off: a disabled nudge source stops computing, not merely displaying, and a deactivated agent cannot be routed to. ## Common questions ### Can Sense change data without a person involved? Yes, when an agent with write-capable grants runs a scheduled or event-triggered workflow and its tools do not require approval — which is the platform default. Use an execution account with only the access the job needs, grant only the capabilities it needs, keep *Max Autonomous Steps* small, and require approval on interactive agents whose writes matter. Then audit the runs. ### Can Sense reveal something a user isn't allowed to see? Interactive chat uses the asking user's permissions, so no — with one caveat. An agent pinned to an execution account answers with *that account's* access, so a broadly privileged execution account on a chat agent would show users more than their own profile allows. Fix that on the agent, not in the prompt: instructions are not an access-control layer. ### How do I roll Sense out to some users and not others? Through licensing: Sense AI is granted to every security profile by default, so remove the product from the profiles that should not have it and those users have no Sense surfaces. Agents can additionally be limited to **audience teams**, so a specialist agent is only routable for members of the teams you name. Usage is governed per user by the free daily tier and any credits an administrator assigns. There is no per-user nudge permission beyond the profile grant and the module switch. ### Where do I see what a run actually did? Open the conversation's run details in the chat, or the agent's runs in Sense AI Studio; each shows the routed agent, the tools called and the identity used. Nudges carry a **Why?** action that shows the evidence a source used, and agent-published nudges link back to the producing agent's conversation. ## Related topics - [How xMatix approaches AI trust](/ai/trust/) - [The Sense AI assistant](/ai/assistant/) - [How the xMatix security model works](/docs/concepts/security-model/) - [Managing security profiles](/docs/administration/security-profiles/) - [Licensing](/docs/administration/licensing/) ---- # Tenants, companies and organizations URL: https://xmatix.com/docs/concepts/tenants-and-companies/ Last reviewed: 2026-09-06 A **tenant** is your organization's own, isolated xMatix environment — its users, data, configuration and customizations live inside it and nowhere else. Within a tenant, the **companies** your organization transacts through can be modeled as first-class things, and user access can be scoped to them. The two boundaries behave very differently: tenant isolation is enforced by the platform on every read and write and needs no configuration, while the company boundary is an operating model your administrator switches on deliberately. @[guided-image](_img/tenant-company-context.png) Both live under **Setup → Feature Hub → Administration → Org Settings**. The **General** tab holds the organization-wide defaults every user inherits unless their own profile overrides them — default locale, currency, time zone and date format, exposed to formulas and scripts as `Org.Locale`, `Org.Currency` and so on — plus the **Multi-company (partner mode)** switch. **Custom Settings** is where you author your own named settings for formulas and scripts. **Companies** and **Company Access** appear when multi-company mode is on. Editing Org Settings needs the `setup.org.settings.manage` capability; the company tabs need `setup.companies.manage`. ## A tenant is your organization's environment Everything your organization does in xMatix happens inside its tenant: every user account, every record, every entity customization and every setting belongs to it. Tenants are strictly isolated from one another — your data is never visible to another organization, and theirs is never visible to you. This isolation is enforced on every query and every save, is not something an administrator configures, and cannot be widened by any setting described on this page. Sandboxes are separate copies of your tenant for testing; see [sandboxes](/docs/administration/sandboxes/). ## Companies within a tenant Many organizations transact through more than one legal entity — group companies, partner firms, distributors keeping their own books. xMatix models these as **companies** inside your tenant, and the model separates three ideas: - **A partner account is just an account.** Any account can be flagged as a partner account, and partners may exist that never transact. - **Onboarding makes a partner a company.** A partner becomes a company when it is onboarded on the **Companies** tab, which creates its company profile; from then on transactional records — orders, invoices, journals, bank transactions and so on — may be keyed to it. A company can also have finance enabled from a chart-of-accounts template so its books stand on their own. - **Company access is a permission layer on top.** Once companies exist, users can be restricted to particular companies (next section). Master data is more flexible than transactions. Some masters are shared tenant-wide — items and customer accounts are common to all companies — while others, such as price lists, tax groups and branches, carry a company and can therefore be company-specific or left shared. Transactions and financial balances are always kept per company, which is what makes independent, per-company statements possible. ## Scoping users to companies Company access is recorded per user, per company, on the **Company Access** tab, with one of two kinds: - **View** — the user may see the company's records, for consolidated reporting, but not post into it. - **Transact** — the user may see and post into the company; it implies View. A common pattern is Transact in the user's home company and View across the rest. Two switches bypass company scoping entirely: **Access to all companies** on the user, and the equivalent flag on a security profile (the built-in System Admin profile carries it), so administrators and group finance see everything without being granted company by company. Access changes take effect within about a minute for signed-in users. Two things are worth knowing about how this is enforced. First, restricting a user is a filter added to their queries and a guard on their saves; it applies only to records that carry a company, and it never widens what ordinary [record-level security](/docs/concepts/security-model/) already allows — a user still needs the entity permission and record access. Second, the company filter and save guard are activated by the organization's multi-company switch **together with** platform-level enforcement that the xMatix operations team turns on per environment after validating it. Until both are on, Company Access rows record intent but do not restrict anyone — so treat the switch as the start of a rollout, not proof of enforcement, and test a representative restricted user before relying on it. ## Single-company organizations If your organization is one company, leave multi-company mode off. Company scoping then does nothing, no Companies or Company Access tabs appear, and ordinary tenant security applies unchanged. Organizations that grow into several entities later can switch the mode on, onboard companies and grant access without any change to existing users, who keep seeing everything until Company Access rows restrict them. ## Common questions ### Is our data separate from other organizations' data? Yes. Every tenant is isolated: all of your records, users and configuration are scoped to your tenant, and the platform enforces that scoping on every access. No user of another tenant can see your data, and no report, search or integration crosses tenant boundaries. Company scoping operates *within* your tenant and is deliberately softer — cross-company visibility inside one organization is often legitimate for consolidation and administration. ### Do we need multi-company mode? Only if your organization transacts through more than one legal entity and needs per-company books or per-user company access. Enable it for a documented requirement: decide which masters are shared and which are company-specific, onboard each company, grant Company Access, and then have a restricted user confirm both what they can see and what they cannot post before treating it as a control. ### What is shared across companies and what is separate? Users, security profiles, entity customizations, automation and Org Settings belong to the tenant, not to any one company. Items and customer accounts are shared. Price lists, tax groups, branches and similar masters carry a company and can be shared or company-specific. Transactions and balances are always per company. ### Can one user work in more than one company? Yes. A user can hold access to several companies with a different kind in each — Transact in one, View in others — and users who need everything can be given access to all companies outright. ### Does multi-company mode give each company its own chart of accounts? It can. Each onboarded company can have finance enabled from a chart-of-accounts template, which seeds that company's ledger accounts and turns on posting for it; companies that share a chart use the same template. Document numbering is configured separately under **Setup → Feature Hub → Platform → Document Settings** and is not keyed per company. ## Related topics - [Apps, entities, records and views](/docs/concepts/apps-entities-records/) - [The xMatix security model](/docs/concepts/security-model/) - [Managing security profiles](/docs/administration/security-profiles/) - [Sandboxes](/docs/administration/sandboxes/) - [Platform security](/platform/security/) ---- # Accounts: the customer, supplier and company master URL: https://xmatix.com/docs/crm/accounts/ Last reviewed: 2026-10-10 An **account** is xMatix's single master record for every organization or person you deal with — a customer you sell to, a supplier you buy from, a retail outlet, and the companies in your own network that own transactions. Every module reads the same record: the lead you convert and the opportunity you work in CRM, the order Sales fulfils, the bill Procurement receives, the invoice Finance collects and the outlet a field rep visits all point at one account. There is no separate "CRM customer" or "vendor master" to keep in sync. ## Overview You find accounts under **Accounts** in the **CRM**, **Sales** and **Support** apps; the same list appears in the **Finance Setup**, **Partner Onboarding Settings** and **Platform** apps. It is the same record whichever app you open it from. An account carries three kinds of information: - **Identity** — **Name**, **Code**, **Account Label** (a trading name), **Account Type**, contact details, and a billing and a shipping address. - **Roles** — three independent switches: **Customer Account**, **Supplier Account** and **Partner Account**. One account can hold any combination. - **Statutory details** — PAN, GSTIN and GST registration type, TDS settings, MSME registration and related-party details, used by tax documents and statutory reports. The record page has a header showing **Account Number**, **Account Type**, **Partner Account**, **Customer Account**, **Active** and **Annual Revenue**, a **Sense AI insights** panel, and these tabs: | Tab | What it shows | | --- | --- | | **Company Settings** | Lists used when the account is a partner company | | **Sales**, **Procurement**, **Service**, **Financials** | The documents raised for or by this account in each area | | **Contact & Address Info** | The account's contacts and addresses, with **New** to add one | | **Partner Mappings** | Which partner companies and branches may deal with this account | | **Details** | Every field of the account, in collapsible panels, plus its attached files | | **Duplicates** | Other accounts that may be the same party, with merge | | **Change History** | Who changed which field, and when | Your organization can redesign these layouts, so your screen may differ. ## When to use it Create an account the first time you deal with a party that will appear on documents: a new customer, a new supplier, a new retail outlet or a new company in your network. Use the existing account every time after that — if the relationship changes (a customer starts supplying you), switch on the extra role on the same record instead of creating a second one. Unqualified interest belongs on a [lead](/docs/crm/leads/); an account is created for you when a lead is converted. ## How xMatix handles it ### Roles are switches, not record types | Switch | What it means | What it changes | | --- | --- | --- | | **Customer Account** | You sell to this party | Only customer accounts can be picked as the customer on sales and CRM documents. A primary contact is created automatically only for customer accounts | | **Supplier Account** | You buy from this party | Only supplier accounts can be picked as the supplier on procurement documents | | **Partner Account** | A company in your network that owns transactions — the company named as the **Partner Account** on orders, invoices and other documents | Partner accounts carry branches, fiscal years and company settings. When your organization runs several companies, a partner account must also be set up as a company before documents can be recorded for it | **Account Type** (shipped value **Customer - Direct**, the default) is a description only. It does not switch roles on or off. ### Active is the switch that matters **Active** decides whether the account can be used on new documents. An inactive account is refused on documents that reference it — for example *"Partner account is Inactive."* on a document whose partner account has been switched off. Switching an account off does not change documents already recorded. **Status** (Draft, Created, Pending Approval, Approved, Rejected) is an informational field. No approval process sits behind it and it does not stop an account being used; change it with **Set Status** if your organization tracks it. ### What happens when you save - **Code** and **Phone** must each be unique across all accounts. A second account with the same value is refused with *"Code '…' already exists"* or *"Phone '…' already exists"*. - Format checks run on **GSTIN** (15 characters), **PAN** (10 characters: five letters, four digits, one letter), **Phone** (10 to 15 digits, optionally starting with +, no spaces), **Email** and the **Udyam Registration Number** (`UDYAM-XX-00-0000000`). An empty field always passes. - **Phone Country Code** defaults to +91. - On a new **customer** account with **Create Account Contact** switched on, xMatix creates the account's primary contact from the account's **Name** and **Email** and links it as **Account Contact**. On later saves, while **Create Account Contact** stays on, the primary contact's name and email are kept in step with the account. The phone number is not copied to the contact. - Switching **GL Posting Enabled** on for an **existing partner account** creates a standard set of general-ledger accounts for that company, each named after the standard account and the company. Ticking it while creating the account does not create them — save the account first, then switch it on. - **MSME** and **related-party** details are checked for consistency (see [Business rules](#business-rules)). ### Where an account's details flow When you pick the account on an order, invoice, bill, purchase order, delivery order or service order, the document takes its billing and shipping address from the account's default [contact address](/docs/crm/contact-addresses/), or from the account's own address fields when there is none. Quotes and opportunities work the other way round: the account's own address fields come first and the default contact address fills only what they leave blank. Either way, xMatix fills only what is still empty on the document, so anything you typed is kept. The account's **Place of Supply** and **GST Registration Type** are fallbacks for working out how a document is taxed; a GSTIN or registration type on the billing contact address takes precedence. Pricing comes from price lists and discount groups, which can target the account directly or through an [account group](/docs/crm/configuration/#account-groups); credit limits are separate records — see [Credit limits](/docs/sales/credit-limits/). When a new lead arrives with a phone number that exactly matches an account's **Phone**, the lead links itself to that account and fills its own empty name, email and address fields from it. ## Prerequisites - Access to **Accounts** in one of the apps above, with create or edit rights (see [Permissions](#permissions)). - For a supplier or customer you invoice under GST: the party's PAN, GSTIN and GST registration type. - For a partner account in an organization that runs several companies: an administrator to set it up as a company (see [Configuration](#configuration)). ## Procedure ### Step 1 — Find an account Open **Accounts** in the CRM, Sales or Support app. The shipped list views are **All Active Accounts**, **All Customer Account**, **All Partner Account** and **All Supplier Account**; switch views from the list header, and use search, filters and column sorting to narrow the list. Always search by name, code and phone before creating an account — an existing record is the one to use. ### Step 2 — Create an account @[guided-image](_img/account-master.png) 1. In **Accounts**, select **New**. The **New Account** form opens. 2. Fill the header: **Name** (the registered or legal name), **Code** (your short code for the party), **Account Type** and, if you know it, **Annual Revenue**. **Geo Location** stores the account's map position. 3. On **Classification**, set **Account Source**, **Account Rating**, **GSTIN**, **PAN**, **TAN** and **TDS Applicable** as they apply. 4. On **Categorisation**, switch on the roles — **Partner Account**, **Supplier Account**, **Customer Account** — and **Active**. Switch on **Create Account Contact** if xMatix should create the primary contact for a customer. 5. On **Contact Details**, enter **Salutation**, **First Name**, **Last Name**, **Phone** (required on this form) and **Email**. 6. On **Billing Address** and **Shipping Address**, enter the address, city, state, region, postal code and country. 7. Select **Save**. The account opens on its record page. Some screens offer a short **Quick Create** form instead, with **Name** (required), **Account Type**, **Phone**, **Email** and **Website**. Add the remaining details from the record page afterwards. ### Step 3 — Change an account Open the account and select **Edit** in the header. The **Details** tab holds every field in panels — **Information**, **Classification**, **Categorisation**, **Related Party Information**, **MSME Related Details**, **Billing Address**, **Shipping Address** and **System Information**. Change what you need and save. Every change is recorded on **Change History**. ### Step 4 — Add contacts and addresses On **Contact & Address Info**, select **New** on the contacts list to add a person, or on the addresses list to add another billing or delivery address. Documents raised for the account offer these contacts and addresses. Default addresses, per-address GST details and the address fields are covered in [Contact addresses](/docs/crm/contact-addresses/). ### Step 5 — Record statutory details On **Details**, complete the panels that apply to the party: - **Information** — **GST Registration Type**, **GSTIN**, **PAN**, **TAN**, **Deductee Type**, **TDS Applicable** and **Default TDS Section**. - **Classification** — **Place of Supply**. - **Categorisation** — **Is RCM** for a supplier whose bills are taxed under reverse charge. - **Related Party Information** — switch on **Related Party**, then choose **Related Party Type**, describe the **Relationship** and set **Related Party From** and **Related Party To**. - **MSME Related Details** — **MSME Enterprise Category**, **MSME Enterprise Type**, **MSME Payment Due Days**, **MSME Registration Date**, **MSME Registration Status** and **MSME Verified On**. ### Step 6 — Find and merge duplicates 1. Open the account you want to keep and go to the **Duplicates** tab. It lists accounts that may be the same party and says why each one matched. 2. Expand a candidate to compare the two records side by side. 3. To merge, either tick one or more candidates and select **Merge selected** (this record's own values are kept), or open **Compare & merge** to pick, field by field, which value the surviving record keeps. **Reverse direction** in that dialog makes the other record the survivor instead. 4. Confirm with **Merge**. Merging moves the duplicate's activities, attached files, collaborators, followers and side conversations onto the surviving account and records the link. It does **not** move orders, invoices, contacts or addresses, and it does not close the duplicate — the merged-away account stays in lists and stays active. Switch **Active** off on it yourself if it should no longer be used. A merge cannot be undone. ### Step 7 — Deactivate an account Edit the account, switch **Active** off on the **Categorisation** panel and save. The account stays on every document already recorded and disappears from the pickers that only offer active accounts. Prefer this to deleting an account that has been used. ### Step 8 — Clone or delete an account **Clone** creates a new account copied from this one; give the copy its own **Code** and **Phone** before saving, because both must be unique. **Delete** (in the header, or on a list row) removes the account after you confirm. ### Step 9 — Transfer a partner's business to another partner Use this when one partner company in your network hands its business to another — a dealer takeover, for example. 1. Open the **outgoing** partner's account and select **Transfer Partner** in the header. 2. The dialog shows **From** (this account) and **To**. Pick the incoming partner in **To**; **Swap** reverses the two if you started from the wrong account. 3. Choose what moves. **Outlets**, **Resources**, **Stock** and **Open orders** are on by default; **Deactivate outgoing** is off. To move part of a scope rather than all of it, open the card and pick the records. 4. Pick the effective date and run the transfer. 5. Read the result. Each part reports what it could not move — for example orders already past Draft, or territory seats held by staff who are not transferring. Deal with those by hand; the transfer is safe to run again afterwards. Stock is not moved directly: you get draft transfers, valued at the outgoing partner's average cost, to price and post through the normal transfer process. Invoices and other financial documents are never transferred. **Deactivate outgoing** declines, and reports the amount, while receivables are still open against the outgoing partner — the rest of the transfer still goes through. ### Step 10 — Use accounts on mobile In the field app, outlets are accounts. The visit-plan agenda can suggest nearby places: **Add to Route** puts an existing account on the route, **Onboard** opens an **Onboard New Account** form pre-filled from the suggestion, and **+ Add outlet** opens a blank **Add Outlet** form. The **Dead Outlets** and **Platinum Outlets** cards list the flagged outlets on today's beat. See [Discover and onboard nearby outlets](/docs/field-sales/prospecting/). ## Fields | Field | What it means | Notes | | --- | --- | --- | | **Name** | The registered or legal name | Shown on documents. Required on the Quick Create form. Not checked for uniqueness | | **Code** | Your short code for the party | Must be unique. Preferred over **Account Number** wherever a code is looked up | | **Account Type** | Commercial classification | Shipped value: Customer - Direct (default). Description only — it does not set roles | | **Annual Revenue** | Estimated yearly turnover | For segmentation; defaults to 0. Not used by credit or pricing | | **Geo Location** | The account's map position | Used for nearby-outlet search and route planning | | **Account Source** | How the party was acquired | Web, Phone Inquiry, Partner Referral, Purchase List, Other. Reporting only | | **Account Rating** | Interest or priority grade | Hot, Warm, Cold. Reporting only | | **GSTIN** | The party's GST identification number | 15-character format check. A GSTIN on the billing contact address takes precedence on documents | | **PAN** | Permanent Account Number | 10-character format check. Used by TDS processing | | **TAN** | Tax deduction account number | | | **TDS Applicable** | Whether tax is withheld for this party | Off means the party is exempt from withholding | | **Partner Account** | A company in your network that owns transactions | See [Roles](#roles-are-switches-not-record-types) | | **Supplier Account** | You buy from this party | Required to pick it as a supplier | | **Customer Account** | You sell to this party | Required to pick it as a customer | | **Active** | Whether the account can be used on new documents | Inactive accounts are refused on documents | | **GL Posting Enabled** | Switches on general-ledger posting for a partner company | Switching it on for a saved partner account creates its standard ledger accounts | | **Create Account Contact** | Create and maintain the primary contact from the account | Customer accounts only | | **Salutation** | Title for a person account | Dr., Mr., Ms., Prof. | | **First Name**, **Last Name** | The person's name when the account is an individual | | | **Phone** | Main phone number | Must be unique. 10 to 15 digits, optional leading +. Matched against incoming leads | | **Phone Country Code** | International dialling prefix | Defaults to +91 | | **Email** | Main email address | Format check. Copied to the primary contact | | **Account Label** | Trading name, if different from **Name** | Preferred over **Name** where a display name is shown | | **Account Description** | Free-text description | | | **GST Registration Type** | The party's GST registration status | Consumer, Deemed Exports, GST Registered- Composition, GST Registered- Regular, GST Unregistered, Non GST Supply, Out Of Scope, Overseas, Special Economic Zone (SEZ). Drives how documents are taxed | | **Place of Supply** | The party's GST state | Fallback when a document and its billing address have none | | **Partner Owner Account** | The partner company that owns this outlet | Hidden when your organization runs a single company. Changed by **Transfer Partner** | | **Deductee Type** | Withholding classification | Individual, HUF, Company, Firm / LLP, AOP / BOI, Local Authority, Government, Trust | | **Default TDS Section** | Withholding section proposed on new bill and invoice lines | The line can override it | | **Account Site**, **Account Location** | Free-text site and location notes | **Account Location** holds no coordinates — use **Geo Location** | | **Dead Outlet**, **Platinum Outlet** | Outlet flags shown on the field rep's cards | Can be set by hand | | **Platinum Outlet Order Count** | The order count behind the platinum flag | Read-only | | **Is RCM** | Reverse charge applies to this supplier | Copied to new bills that do not set it themselves | | **Related Party**, **Related Party Type**, **Relationship**, **Related Party From**, **Related Party To** | Related-party status for statutory disclosure | Types: Associate / Joint Venture, Director, Entity Controlled by Director / KMP, Fellow Subsidiary (Sister Concern), Holding Company, Key Management Personnel, Other, Promoter, Relative of Director / KMP, Subsidiary Company | | **MSME Enterprise Category** | Manufacturing, Service or Trading | | | **MSME Enterprise Type** | Micro, Small or Medium | | | **MSME Payment Due Days** | Agreed payment days for this MSME supplier | 1 to 45 | | **MSME Registration Date**, **MSME Verified On** | Registration and verification dates | Neither may be in the future | | **MSME Registration Status** | Registered, Not Registered, Declaration Awaited, Deregistered | | | **Billing Address**, **Billing Street**, **Billing City**, **Billing State**, **Billing Region**, **Billing Postal Code**, **Billing Country** | The default billing address | Copied to documents that have no billing address of their own | | **Shipping Address**, **Shipping Street**, **Shipping City**, **Shipping State**, **Shipping Region**, **Shipping Postal Code**, **Shipping Country** | The default delivery address | Copied to documents that have no shipping address of their own | | **Status** | Informational lifecycle value | Draft, Created, Pending Approval, Approved, Rejected. No process reads it | | **Account Number** | Older account code | Used only when **Code** is empty | For every field, including the ones not on the shipped forms, see the [Account reference](/docs/reference/entities/account/). ## Business rules - **Code** and **Phone** are unique across accounts; **Name** is not. - GSTIN, PAN, Phone, Email and Udyam Registration Number must match their formats when filled. - **Related Party Type** can only be set when **Related Party** is on; a related party needs a type; **Related Party To** cannot be before **Related Party From**. - MSME values must come from their lists; **MSME Payment Due Days** cannot exceed 45; **MSME Registration Date** and **MSME Verified On** cannot be in the future, and **MSME Verified On** cannot be before **MSME Registration Date**. - A primary contact is created only for a customer account saved with **Create Account Contact** on, and only when it has none yet. - **GL Posting Enabled** creates standard ledger accounts only when switched on for an already-saved partner account. - A lead converted to a new account creates an active customer account (or, for a partner lead, an inactive partner account) named after the lead's account name, with the lead's address and a contact. - A shipped validation, *"Last Name is mandatory for Customer Accounts."*, is available but switched off; your administrator can turn it on. - Merge moves activities, files, collaborators, followers and side conversations only, and leaves the duplicate open. ## Example A distributor, Riverbend Traders, starts buying from you. 1. You search **Accounts** for "Riverbend" and its phone number — nothing comes back. 2. You select **New** and enter **Name** *Riverbend Traders Private Limited*, **Code** *RBT01*, **Account Type** *Customer - Direct*. On **Categorisation** you switch on **Customer Account**, **Active** and **Create Account Contact**. On **Contact Details** you enter **Phone** *9876500012* and **Email** *accounts@riverbend.example*, and you fill both addresses. 3. You save. The account opens, and its primary contact *Riverbend Traders Private Limited* has been created with the same email. 4. On **Details** you set **GST Registration Type** to *GST Registered- Regular*, enter the GSTIN and PAN, and save. 5. Six months later Riverbend also starts supplying packaging to you. You edit the same account and switch on **Supplier Account** — purchase orders can now name it as the supplier, and its sales history stays on the same record. ## Training ### Practice exercise In a sandbox: 1. Create a customer account *Practice Outlet 01* with **Code** *PR01*, a ten-digit phone number, **Customer Account**, **Active** and **Create Account Contact** switched on. 2. Create a second account with the same phone number. **Expected:** the save is refused with *"Phone '…' already exists"*. 3. Change the phone on the second account and save it. Open the first account's **Duplicates** tab and merge the second into it with **Compare & merge**. 4. **Expected:** the first account keeps the values you chose; the second account still exists and is still active. Switch **Active** off on it. 5. Edit *Practice Outlet 01* and enter PAN *ABCDE1234* (nine characters). **Expected:** *"PAN 'ABCDE1234' is not a valid 10-character PAN."* ### Quick reference - One party, one account — add a role instead of a second record. - **Customer Account**, **Supplier Account** and **Partner Account** decide where the account can be picked; **Account Type** does not. - **Active** controls use on documents; **Status** is informational. - **Code** and **Phone** must be unique. - **Create Account Contact** works for customer accounts only. - Switch **GL Posting Enabled** on after the partner account is saved. - Merge moves activities and files, not documents, and leaves the duplicate active. - Deactivate rather than delete an account that has been used. - **Transfer Partner** runs from the outgoing partner's account. ## Permissions Account access follows the user's security profiles and record-level sharing. - **Record rights.** The shipped **Sales**, **Sales Manager**, **Service**, **Procurement**, **Standard User** and **System Admin** profiles give full rights on accounts. **Sales Executive** can read, create, edit, delete, share and assign accounts but has no view-all or modify-all rights, so it relies on ownership and sharing for other users' accounts. - **Actions.** Custom actions need an explicit grant. In the shipped profiles, **Find Duplicates** and **Merge** are granted to Sales Manager, Standard User and System Admin; **Transfer Partner** and **Set Status** to Standard User and System Admin. - **Sharing.** Accounts are owned by users. By default other users in the organization can read accounts they do not own, managers gain access through the role hierarchy, and owners can share records manually or with teams. A user without a right does not see the corresponding button, or sees the operation refused. See [Security profiles](/docs/administration/security-profiles/) and [Record-level security and sharing](/docs/administration/record-security/). ## Configuration | What | Where | What it affects | | --- | --- | --- | | Forms and record page | The account layouts, in the layout designer | Which fields, tabs and related lists users see; the create form, the Quick Create form and the record page are separate layouts | | List views | The account views | The shipped views are **All Active Accounts**, **All Customer Account**, **All Partner Account** and **All Supplier Account** | | Picklists | The account fields' picklist values | **Account Type**, **Account Source**, **Account Rating**, **Industry**, **Salutation**, **Status** and the statutory lists. Several **Account Type** and **Industry** values ship inactive and can be switched on | | Validations | The account's validation rules | The shipped *Last Name is mandatory for Customer Accounts* rule is off by default | | Duplicate matching | **Setup → Feature Hub → Platform → DeDuplication Rules** | Rules for **Account** replace the built-in matching used by the **Duplicates** tab. Rules only flag duplicates — they never block a save. The tab shows at most 25 candidates | | Companies | **Setup → Feature Hub → Administration → Org Settings → Companies** | **Onboard company** sets up a partner account as a company (name, label, locale, currency, document name prefix); **Enable finance** seeds the company's chart of accounts and enables GL posting; **Set default bank** and **Withholding tax timing** are per-company settings | | Organization shape | **Org Settings → General → Organisation shape** | With **We run multiple companies** off, the company axis — including **Partner Owner Account** and **Partner Mappings** — is hidden | | Company access | **Org Settings → General → Restrict users to their own companies**, and the **Company Access** tab | Limits which companies a user can transact for | | Automatic company onboarding | **Org Settings → Custom Settings**, setting **companies** / **autoOnboardPartnerAccounts** | When on, saving an active partner account in a multi-company organization sets it up as a company. It never creates the first company and does not sweep existing partner accounts | | Account groups | **Account Groups** | Named sets of accounts targeted by price lists, discount groups, schemes, tax groups and incentives — see [CRM configuration](/docs/crm/configuration/#account-groups) | | Bulk load | The import wizard | Rows with an **External** id and no internal id update the one existing account with that id — see [Import data](/docs/administration/data-management/import-data/) | The Setup areas need the matching capabilities: organization settings need **setup.org.settings.manage**, companies need **setup.companies.manage**, and imports need **setup.data.import.manage**. ## Common problems ### "Phone '…' already exists" or "Code '…' already exists" Another account already has that phone number or code. Search for it — it is probably the same party, so use that account. If it really is a different party, give this one its own code or phone. ### "PAN '…' is not a valid 10-character PAN." (or GSTIN, Phone, Email, Udyam) The value does not match the expected format. PAN is five letters, four digits and a letter; GSTIN is 15 characters; Phone is 10 to 15 digits with no spaces; the Udyam number is `UDYAM-XX-00-0000000`. Correct the value, or clear the field. ### "MSME Payment Due Days must be between 1 and 45 (MSMED s.15)." The agreed payment period for an MSME supplier cannot exceed 45 days. Enter 45 or fewer. ### "A related party must have a relationship type (director, relative, sister concern, …)." **Related Party** is on but **Related Party Type** is empty. Choose a type, or switch **Related Party** off. The reverse — a type with **Related Party** off — is refused with *"Related party type can only be set when the record is marked as a related party."* ### I can't pick the account on an order or a purchase order The account is missing the role or is inactive. Check **Customer Account** (for sales documents) or **Supplier Account** (for procurement documents) and **Active** on **Categorisation**. ### "Transactions can only be recorded for a partner that has been onboarded as a company." Your organization runs several companies and this partner account has not been set up as one. An administrator onboards it under **Org Settings → Companies → Onboard company**. ### I switched on GL Posting Enabled but no ledger accounts appeared The standard ledger accounts are created only when the switch is turned on for a partner account that was already saved. If you ticked it on the create form, switch it off, save, switch it on and save again — and check that **Partner Account** is on. ### The account I merged away is still in the list That is expected: merge keeps the duplicate. Switch its **Active** off. ### Transfer Partner says "The incoming partner has no branch — activation should have created one." The receiving partner has no branch to receive into. Create a branch for it, then run the transfer again. Other refusals name their cause: *"The outgoing account must differ from the incoming partner's account."* (both sides are the same account) and *"The incoming account is not a partner account."* (only partner accounts can take part). ## Common questions ### Can an account be a person rather than a company? Yes. An account has **Salutation**, **First Name** and **Last Name** alongside the company fields, so individual customers are ordinary accounts. Contacts stay separate records: even a one-person customer account usually has a primary contact, because documents and activities refer to contacts for who to talk to. Switch on **Create Account Contact** when you create the account and xMatix makes that contact for you from the account's name and email. ### Where do new accounts come from? Four paths: created with **New** in the account list, created by [lead conversion](/docs/crm/leads/) when the lead is not linked to an existing account, onboarded from the field app as a new outlet, or loaded in bulk with the [import wizard](/docs/administration/data-management/import-data/). However it was created, it is the same master record from then on and every module reads it. ### Does merging move the duplicate's orders and invoices? No. Merge moves activities, attached files, collaborators, followers and side conversations onto the surviving account and records the link between the two. Orders, invoices, contacts and addresses stay on the account they were recorded against, and the merged-away account stays active. Merge before the duplicate has been used on documents where you can, and switch the duplicate's **Active** off afterwards. ### What is the difference between Account Type and the role switches? **Account Type** is a description for reporting — it does not change what the account can do. The **Customer Account**, **Supplier Account** and **Partner Account** switches decide where the account can be picked: only customer accounts on sales documents, only supplier accounts on procurement documents, and only partner accounts as the owning company of a document. ### Who can see which accounts? Account visibility follows the platform security model — the user's security profiles, record ownership and sharing — not anything CRM-specific. In the shipped setup everyone can read accounts and owners edit their own. See [record-level security and sharing](/docs/administration/record-security/). ## Related topics - [Contact addresses](/docs/crm/contact-addresses/) - [Leads](/docs/crm/leads/) - [Working opportunities through the pipeline](/docs/crm/opportunities/) - [CRM configuration: account groups](/docs/crm/configuration/#account-groups) - [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/) - [Credit limits](/docs/sales/credit-limits/) - [Tenants, companies and organizations](/docs/concepts/tenants-and-companies/) - [Selling scope and partner account mappings](/docs/field-sales/selling-scope/) - [Discover and onboard nearby outlets](/docs/field-sales/prospecting/) - [Chart of accounts](/docs/finance/chart-of-accounts/) - [GSTR-1](/docs/finance/tax-center/gstr-1/) - [Account reference](/docs/reference/entities/account/) ---- # Activities: calls, tasks and notes on records URL: https://xmatix.com/docs/crm/activities/ Last reviewed: 2026-09-06 Every record in xMatix that has activities enabled carries a **timeline** — the running history of engagement with it. One activity model covers all of it: tasks, calls, meetings and events, emails, notes and documents, each logged against the record it concerns and, where relevant, the account and contact involved. Learn it once on a lead and it works the same on an opportunity, an account, a case or an order. ## The call register at a glance @[guided-image](_img/call-register-concept.png) The **Call Register** (CRM app → **Call Register**) is the organisation-wide view of phone calls, while a record's timeline is its own engagement history. Read each call across the row: ring time and direction give the chronology, From and Contact identify the participant, Related record names the case, order, visit or deal the call was about, Agent says who handled it, and duration and outcome capture the result. The cards above the list — total calls, average talk time, missed calls — summarise the current view. When a call belongs to a case, order, lead or opportunity, link it to that record so the completed call writes into the same timeline as tasks, notes and emails. That keeps both views without duplication: supervisors analyse the register, and a record owner reads the complete customer history in context. ## Activity types | Type | What it carries | | --- | --- | | Task | Due date, status, priority — work to be done against the record | | Call | Direction (inbound/outbound), disposition (connected, no answer, …), duration | | Meeting / Event | Start and end, all-day flag, location, availability shown to others | | Email | The message logged against the record | | Note | Free-form text with a visibility setting | | Document | A file attached to the timeline | Activities can carry reminders, and notes have **visibility**: internal notes (the default) stay inside your organization, public ones are visible to external audiences such as portal users — so a customer-facing note is an explicit choice, never an accident. ## Activities do work, not just record it Timelines aren't passive. A lead, for example, keeps counters current from its activities — whether it has been called or emailed, and how many tasks and events it carries — and your organization's business rules can read those to advance the lead automatically ([working leads](/docs/crm/leads/)). Activity reporting works across records too, because every activity is one row in the same model regardless of what it hangs on. ## The call register Alongside call *activities*, CRM keeps a **Call** register: one record per actual phone call, with numbers, direction, ring/answer/end times, duration and wait time, outcome and notes. A call links to the record it was about — and from a call you can **link to record** (attach it to an existing case, order or deal) or **create record** (spin up a case, lead, opportunity, order, service order or task from the call, pre-filled with the caller and notes). A completed call writes a call activity onto the linked record's timeline, so the record's history stays in one place. ## Common questions ### Who can see a note I write? Internal notes: your colleagues, subject to normal record access. Public notes: also external viewers of the record, such as portal users. Visibility is set on the note itself; when in doubt, leave it internal — that is the default. ### Do activities change the record they are on? They append to its timeline always, and on some records they also drive fields — lead contact and task counters are recomputed from activities so edits and deletions keep them accurate. Whether a status changes as a result depends on the business rules your organization has configured. ## Related topics - [Leads](/docs/crm/leads/) - [xMatix CRM overview](/docs/crm/) - [Documentation home](/docs/) — a dedicated engagement section is planned; this page stays the CRM-side summary ---- # Scheduling appointments URL: https://xmatix.com/docs/crm/appointments/ Last reviewed: 2026-09-02 The **appointment** engine is xMatix's general booking system: one appointment record for demos, test drives, service visits, deliveries and consultations, booked against branch capacity that the platform releases from templates, with people, vehicles and facilities claimed per booking. **Appointment scheduling is in preview.** Its setting governs automatic slot-materialization and maintenance sweeps; it is not, by itself, a universal server-side block on every manual appointment surface. Confirm both the tenant setting and the enabled UI/action paths in your environment. The demo booking flow described under [product demos](/docs/crm/product-configurator/) is the generally available path today. ## Prerequisites - The appointment scheduling switch enabled when you rely on automatic slot generation, plus confirmation that the intended manual booking surface is enabled for your organization (see the [configuration reference](/docs/crm/configuration/)). - At least one active appointment type, and per branch a slot template so bookable slots exist. - Optionally, bookable resources registered where appointment types require them. ## Procedure ### Step 1 — Define appointment types (admin) An **appointment type** is the policy for one flavor of booking — Product Demo, Test Drive, Service Visit, Delivery, Consultation. It sets the default duration and setup/teardown buffers, the booking policy (minimum lead time, how far ahead booking is allowed, cancellation cutoff, maximum reschedules, overbooking allowance), which location modes are allowed (branch, onsite, virtual), reminder offsets, whether customer confirmation is required, and the resources a booking of this type must claim (for example one salesperson and one demo vehicle). New appointment flavors are configuration, not code. Save it inactive first, reread every time and capacity boundary in the branch's timezone, then activate it. Verify the type appears in the booking selector only where its location mode and effective configuration allow it. ### Step 2 — Create slot templates per branch (admin) A **slot template** is a recurring capacity pattern: a daily window in the branch's local time, cut into slots of a set duration, with a capacity per weekday (a weekday set to 0 is closed; a weekday without its own number uses the template's default capacity). Capacity can be fixed numbers, derived from available bookable resources, or the lower of the two. The platform materializes templates into concrete, bookable **slots** over a rolling horizon automatically, skipping the branch's non-working days and holidays. Templates can be scoped to one appointment type and to specific items or item groups. After saving, inspect one ordinary weekday, one closed day and one holiday inside the rolling horizon. Confirm the generated start/end times, capacity and type/item scope match the template rather than trusting the recurrence summary alone. ### Step 3 — Register bookable resources (admin) A **bookable resource** is one schedulable unit — a person, an asset such as a demo vehicle, or a facility such as a service bay (exactly one of the three). Each has a home branch, working hours (falling back to the person's or the branch's hours), an effective window, and a concurrent capacity — how many overlapping appointments it can serve (advisors may take several; a vehicle or bay takes one). Choose exactly one resource kind, validate its effective dates and local working hours, and use capacity 1 for indivisible assets unless parallel use is genuinely possible. Verify it contributes capacity to a future slot and disappears outside its effective or working window. ### Step 4 — Book the appointment Book from the record the appointment is about — a lead, opportunity, service order or delivery — choosing the appointment type and an available slot. Confirm the partner account, branch, customer context, location mode and required resource before saving. The booking is enforced server-side: a slot's capacity is claimed atomically, so a full slot refuses the booking rather than overbooking silently, and the type's resource requirements claim free resources at the same time. While a booking is being completed, the chosen slot can be held briefly; unfinished holds expire on their own. After saving, reopen the appointment from its source record and verify the displayed local time, slot usage and resource assignment. ### Step 5 — Run the day An appointment moves through a controlled lifecycle: **Requested → Scheduled → Confirmed → CheckedIn → InProgress → Completed**, with **Cancelled**, **NoShow** and **Rescheduled** as terminal states. At each hand-off, confirm the current status and customer identity before taking the next action; record operational notes where the transition depends on a real-world event. Illegal jumps are refused, terminal appointments are immutable, and cancelling inside the type's cutoff window is blocked. Rescheduling creates a linked replacement and consumes the reschedule allowance. After completion, cancellation or rescheduling, verify the old slot and resources were released and the audit trail shows who made the transition. ## Expected result The booking reserves one valid slot and every required resource without exceeding capacity. Its times display correctly in the branch timezone, its linked customer or work record opens from the appointment, and each tested lifecycle transition updates status, reminders and released capacity exactly once. ## Common problems **No slots are offered** — the scheduling switch is off, the branch has no active template covering that date (check the template's effective window and that the weekday's capacity isn't 0), or the date is a holiday or non-working day. **The slot is full** — capacity including any overbooking allowance is consumed; pick another slot or have an administrator raise capacity. **A slot shows as overcommitted** — a capacity recompute found more bookings than the slot now allows (for example approved leave removed a resource); a dispatcher needs to move bookings. **A status change is refused** — the transition isn't legal from the current state, or the appointment is already terminal. ## Common questions ### What can an appointment be about? Any record — appointments attach to the record they concern (lead, opportunity, case, service order, delivery order, account) and additionally carry the customer, contact, item and asset involved, so both the deal and the customer see the booking. ### How do onsite appointments meet field plans? An onsite appointment can be marked field-serviceable and folded into a field rep's day as an anchored visit — see [visit plans](/docs/field-sales/visit-plans/). ### How does this relate to demo bookings on opportunities? The **Product Demo** booking flow on sales opportunities ([product demos](/docs/crm/product-configurator/)) is the generally available booking path and creates a product demo record. The appointment engine on this page is its successor-in-preview: one booking model for all appointment flavors, with server-enforced capacity and resource claims. A demo can link to the appointment that hosts it. ## Related topics - [Product configurator and demos](/docs/crm/product-configurator/) - [CRM configuration reference](/docs/crm/configuration/) - [Visit plans](/docs/field-sales/visit-plans/) ---- # CRM configuration reference URL: https://xmatix.com/docs/crm/configuration/ Last reviewed: 2026-08-15 CRM configuration lives in the CRM app's **Settings** entry. This page is the administrator reference for the CRM-owned pieces: the appointment scheduling masters and their organization-level switches, and account groups. Support-side settings that share the same screen — queues, SLA policies, the knowledge base — are documented in the [Support section](/docs/support/); security, users and licensing are in the [administration guide](/docs/administration/). ## Appointment scheduling (preview) Appointment scheduling ships **disabled by default** — see [Appointments](/docs/crm/appointments/) for the user-facing behavior. Its configuration is four masters plus the organization switches. ### Appointment types One row per bookable flavor (Product Demo, Test Drive, Service Visit, Delivery, Pickup/Dropoff, Consultation, Site Visit): | Field | Meaning | | --- | --- | | Category, label, icon, color | Identity and presentation | | Default duration, buffer before/after | Booking length plus setup/teardown padding claimed on resources around it | | Resource requirements | The resources a booking must claim — role, kind (person/asset/facility), count, mandatory | | Min lead time / max advance days | How soon and how far ahead booking is allowed | | Cancellation cutoff hours | Hours before start after which cancel/reschedule is refused (0 = none) | | Max reschedules | Reschedule limit per booking chain (0 = unlimited off) | | Overbook percent | Extra bookings allowed past slot capacity, to absorb no-shows | | Requires customer confirmation | Whether the confirmation loop is expected | | Auto no-show minutes | Minutes past scheduled end after which an unstarted booking is marked no-show (0 = off) | | Applicable entities | Which record types the appointment may be about (empty = any) | | Location modes allowed | Branch, onsite, virtual (empty = all) | | Reminder offsets | Minutes-before-start reminder points | ### Slot templates One per branch pattern; templates materialize into dated slots automatically: | Field | Meaning | | --- | --- | | Branch (required), appointment type | Where the capacity is; optionally scope it to one type | | Start/end time (branch-local), slot duration, interval | The daily window and how it cuts into slots — no duration means the whole window is one slot; no interval means back-to-back | | Capacity mode | Fixed numbers, derived from available bookable resources, or the minimum of both | | Maximum capacity + per-weekday overrides | Per-slot capacity; a weekday override wins, 0 closes that day | | Effective from/to, active | The template's validity window | | Release horizon override | Days ahead this template releases slots (empty = the organization setting) | | Applicable item / item group | Scope the capacity to particular products | ### Slots Slots are the materialized, dated capacity rows the templates produce — one per template, date and start time, carrying capacity, booked and reserved counts, and a status (released, blocked, closed, recalled). Treat them as a **ledger, not a master**: the booked and reserved counters are maintained by the booking engine, and capacity recomputes flag a slot **overcommitted** instead of silently shrinking below its bookings. Block or close a slot to take it off sale; don't hand-edit its counters. ### Bookable resources | Field | Meaning | | --- | --- | | Kind | Person, asset or facility — exactly one of the three links is set | | Person / asset / facility link | The underlying record (a staff resource, a demo vehicle, a service bay) | | Branch | Home branch — the availability and matching scope | | Business hours | Working-hours override; people fall back to their own hours, then the branch's | | Concurrent capacity | Overlapping appointments the unit can serve (vehicles and bays: 1) | | Effective from/to, active | Availability window | ### Organization switches Appointment scheduling has organization-level settings alongside the masters: the **master switch** for the scheduling sweeps (off by default — with it off, slots are not released automatically, though appointments can still be created manually), the **release horizon** in days that slot materialization runs ahead, the **hold time-to-live** in minutes before an unfinished booking hold is released, and the **auto no-show fallback** in minutes for types that don't set their own. Working days and holidays are respected automatically: slot release skips days outside the branch's business hours mask and days covered by holiday rows, so maintain **Business Hours** and **Holiday** under Settings for every branch that takes bookings. ## Account groups Account groups (see [Accounts](/docs/crm/accounts/)) are configured with a type, a description, and one of two membership mechanisms: | Mechanism | How it works | | --- | --- | | Static members | Explicit member rows, one per account, individually activatable | | Rules | Rows of field / operation / value (e.g. *billing region equals West*), combined by a success criterion — all rules, any rule, or a custom logic expression over the rule sequence numbers | Rule-based membership is rebuilt when someone runs **Process Members** on the group, not continuously: after changing the rules, or when accounts have changed enough to matter, run it again. Each run replaces the members the previous run created and leaves members added by hand in place. Groups are referenced by price lists, discount groups, trade schemes, tax groups and visit routes, so changing a group's rules changes what those rules apply to — review the group's usages before editing. ## Actions vary by record type Which lifecycle actions a CRM record offers — for example which of the lead conversion variants appears — is governed by the record type and the action configuration on the entity. See [entity behavior](/docs/customization/entity-behavior/) for how actions are configured and scoped. ## Related topics - [Appointments](/docs/crm/appointments/) - [Accounts](/docs/crm/accounts/) - [Entity behavior: views, validations, actions](/docs/customization/entity-behavior/) - [xMatix administration guide](/docs/administration/) ---- # Contact addresses: an account's billing and shipping addresses URL: https://xmatix.com/docs/crm/contact-addresses/ Last reviewed: 2026-10-10 A **contact address** is one entry in an account's address book — a billing address, a delivery address, or one that serves as both — that sales, service and purchasing documents pick up as their billing and shipping address. Every contact address belongs to one [account](/docs/crm/accounts/); you add them after the account exists, and from then on the default one fills in automatically on new orders, invoices, delivery orders, service orders, bills and purchase orders, and fills gaps on quotes and opportunities. ## Overview An account carries its own billing and shipping address fields, which is enough for a customer with one location. A contact address is what you add when that is not enough: a customer with a head office and several delivery sites, a supplier who bills from one place and ships from another, or a business registered for GST in more than one state. Each contact address holds: - **What it is** — a **Name** you recognise it by, its **Address Type** (Billing, Shipping or Both) and whether it **Is Default**. - **Who it belongs to** — the **Account** (required), and optionally a **Contact** (the person at that address) and a **Branch**. - **Where it is** — **Street**, **City**, **State**, **Region**, **Postal Code** and **Country**. - **How it is taxed** — for businesses in India, the **GSTIN**, **GST Registration Type** and **Place Of Supply** that apply at that address. ## When to use it - A customer wants goods delivered somewhere other than where the invoice goes. - A customer or supplier has several sites and you want to choose the right one on each document instead of retyping it. - A party trades from several Indian states and holds a separate GSTIN for each — record each state's GSTIN on its own address so documents and GST returns carry the right one. - A branch needs a postal address: a branch's **Address** is a contact address (see [Branches](/docs/administration/branches/)). If the account has only one address, its own **Billing Address** and **Shipping Address** fields are enough; documents fall back to them when the account has no default contact address. ## How xMatix handles it **Default addresses fill documents.** When you raise a document for an account, xMatix looks for the account's contact address marked **Is Default**: a Billing or Both address for the billing side, a Shipping or Both address for the shipping side. How it uses that address depends on the document: | Document | When it is filled | What wins | | --- | --- | --- | | Sales order, invoice, purchase order | When the document is first saved | The default contact address first; the account's own address fields only when there is no default contact address | | Bill, delivery order, service order | When the document is saved, including later saves while the address is still empty | The same: default contact address first, then the account's own fields | | Quote, opportunity | When the account is chosen and on save | The account's own address fields first; the default contact address fills only the parts the account leaves blank | In every case xMatix only fills what is still empty. If you pick a different address in the document's billing or shipping address lookup, or type any part of the address yourself, your entry is kept. On a lead, choosing an existing account fills the lead's **City**, **State** and **Postal Code** from the account, using its default billing contact address for any of those the account leaves blank. **The address text is copied.** The document copies the street, city, state, region, postal code and country onto its own fields and builds the one-line address from them. Changing a contact address later does not change documents that were already raised from it. **Per-address GST (India).** On sales documents — quotes, opportunities, sales orders, invoices, service orders and delivery orders — the billing contact address comes first when xMatix works out the tax context on save: - **Place of supply** comes from the billing address, else from the account. - **GSTIN** comes from the billing address, else from the account (opportunities take the place of supply but not the GSTIN). - **GST Registration Type** on the billing address, when set, decides the tax supply type instead of the account's. *Out Of Scope* and *Non GST Supply* make the supply Exempt; *Overseas* and *Deemed Exports* make it an export; *Special Economic Zone (SEZ)* makes it SEZ; otherwise the supply is within or outside the state depending on whether the place of supply matches the branch's source of supply. Values already on the document are never replaced. Purchase documents (bills and purchase orders) take their tax context from the supplier account only; their contact addresses are used for the address alone. **GST returns.** A GSTIN recorded on a contact address is recognised by the GST statements: when a reconciliation row carries a GSTIN that is not on any account, xMatix names the party from the account that owns the address with that GSTIN. If your organisation runs a GSTIN verification integration, it can record a verification result against the address as well as against the account, and the [GSTR-1](/docs/finance/tax-center/gstr-1/) buyer-GSTIN warnings read both. **Your own branch address prints on invoices.** The printed invoice takes your company's street, city, state, postal code and country from the selling branch's **Address** contact address. ## Prerequisites - The account exists — a contact address cannot be saved without one. See [Accounts](/docs/crm/accounts/). - To link a person, the contact exists on that account. - You have access to contact addresses (see [Permissions](#permissions)). ## Procedure ### Step 1 — Add an address to an account 1. Open the account and go to the **Contact & Address Info** tab. 2. On the addresses list, select **New**. 3. Enter a **Name** that tells the addresses apart, such as *Head office* or *Pune warehouse*. 4. Choose the **Address Type**: **Billing**, **Shipping** or **Both**. 5. Check that **Account** shows the right account, and pick a **Contact** if the address belongs to a particular person. 6. Fill **Street**, **City**, **State**, **Region**, **Postal Code** and **Country**. 7. For a business in India, fill **GSTIN**, **GST Registration Type** and **Place Of Supply** if they differ from the account's. 8. Switch **Is Default** on if documents should use this address automatically (see Step 3). 9. Select **Save**. The address appears on the account's addresses list and in the address lookups of documents. ### Step 2 — Find an address - From an account: the **Contact & Address Info** tab lists that account's addresses. - As a list: where your navigation includes **Contact Addresses**, the list shows **Name**, **Account**, **Address Type**, **Street**, **Postal Code**, **City**, **State**, **Country** and **Is Default**. Use search, filters and column sorting to narrow it — for example, filter **Account** to see one customer's addresses, or **Is Default** to check which address each account defaults to. ### Step 3 — Set the default address Open the address, select **Edit**, switch **Is Default** on and save. xMatix does not switch other addresses off for you. If the account already has a default address of the same kind, open it and switch **Is Default** off — otherwise the documents may pick either one. A practical pattern is one default **Both** address, or one default **Billing** and one default **Shipping** address. ### Step 4 — Use an address on a document On an order, invoice, quote or other document, choose the account first; the default address fills in as described in [How xMatix handles it](#how-xmatix-handles-it). To use a different site, pick it in the document's billing or shipping address lookup before you fill the address fields by hand. Because xMatix never overwrites address fields you have already filled, clear the copied fields first if you switch to another address after the first one has filled in. ### Step 5 — Change an address Open the address, select **Edit**, change what you need and save. The change applies to documents raised from now on; documents already raised keep the address they copied. ### Step 6 — Copy or delete an address - **Clone** creates a copy of the address, which is a quick start for a second site of the same customer. Rename it and change what differs. - **Delete** removes an address from lists and lookups. Deleted records go to the recycle bin, so they can be restored — see [Data lifecycle](/docs/concepts/data-lifecycle/). Documents already raised keep the address text they copied. ### Step 7 — Work with addresses on mobile In the xMatix mobile app, the **New** form for a contact address asks for **Name** (required), **Address Type**, **Account**, **Branch** and **Is Default**, with **Street**, **City**, **State**, **Country**, **Region** and **Postal Code** in an **Address** section. The record view shows the same details plus **GSTIN** and **GST Registration Type**, with **Edit** and **Delete** in its header. When you raise an order offline, the app can work out the GST supply type only if the billing contact address has been synced to the device; otherwise it leaves the tax context for the server to set when the order syncs. ## Fields | Field | What it means | Notes | | --- | --- | --- | | Name | The label you recognise the address by | Shown in lists and lookups; required on the mobile form. Addresses created automatically are named after their street | | Address Type | Which side of a document the address serves | **Billing**, **Shipping** or **Both**. A **Both** address can fill either side | | Is Default | Use this address automatically on new documents | Off by default. Keep one default per side per account | | Account | The customer, supplier or company the address belongs to | Required | | Contact | The person at this address | Optional | | Branch | The branch the address is associated with | Optional. A branch's own postal address is set on the branch record, in its **Address** field | | Street | Street, building and locality | Up to 200 characters | | City | The city, as a picklist value | Your administrator maintains the list | | City (place) | The city as a place record from the places master | A second **City** field; copied to documents along with the text city | | State | The state, as a picklist value | | | Region | A free-text region or district | | | Postal Code | The postal or PIN code | | | Country | The country, as a picklist value | | | GST Registration Type | How the party is registered for GST at this address | **GST Registered- Regular**, **GST Registered- Composition**, **GST Unregistered**, **Consumer**, **Overseas**, **Special Economic Zone (SEZ)**, **Deemed Exports**, **Non GST Supply**, **Out Of Scope**. Overrides the account's value on sales documents | | GSTIN | The GST number registered at this address | Copied to sales documents whose own GSTIN is blank. No format check runs on this field when you save | | Place Of Supply | The GST state for supplies billed to this address | Copied to sales documents whose own place of supply is blank | | Partner Onboarding | The partner onboarding application the address was created from | Set automatically; see [Business rules](#business-rules) | ## Business rules - **Account is required.** An address without an account cannot be saved. - **Default resolution.** Documents look for the account's addresses with **Is Default** on: Billing or Both for billing, Shipping or Both for shipping. Nothing stops two addresses of the same kind from both being default; when that happens xMatix uses whichever it finds first, so keep exactly one. - **No overwrite.** Automatic filling never replaces an address lookup, address field, GSTIN or place of supply that already has a value on the document. - **When filling happens.** Sales orders, invoices and purchase orders fill their addresses on first save only. Bills, delivery orders and service orders also fill on later saves while the address is empty. Quotes and opportunities fill when the account is chosen and on save. - **Copy, not link, for the text.** Documents copy the address text. Editing or deleting a contact address does not change documents already raised. - **Partner onboarding.** When a partner onboarding application is activated, xMatix creates a **Both** address marked **Is Default** on the new partner account from the application's address, city, state, PIN code and GST number, with **Country** set to India — unless the account already has a default address or the application has no street or city. - **Customer portal.** Shoppers in a commerce storefront can add and delete their own addresses from their account area. These are the same contact address records. Adding one as the default there switches the account's other default addresses off, and an address added without a type is saved as **Both**. - **Account merge.** Merging accounts does not move contact addresses; they stay on the account they were recorded against. ## Example A furniture distributor sells to Riverbend Traders, which has its head office in Pune and a warehouse in Nashik, both in Maharashtra, and a second registration in Gujarat for its Surat showroom. 1. On the Riverbend Traders account, on **Contact & Address Info**, the sales coordinator adds *Head office – Pune*: **Address Type** Billing, **Is Default** on, Pune street and postal code, **GST Registration Type** GST Registered- Regular, **Place Of Supply** Maharashtra. 2. They add *Nashik warehouse*: **Address Type** Shipping, **Is Default** on. 3. They add *Surat showroom*: **Address Type** Both, **Is Default** off, with the Gujarat GSTIN and **Place Of Supply** Gujarat. 4. A new sales order for Riverbend Traders fills the head office as billing address and the Nashik warehouse as shipping address on save. The order's place of supply is Maharashtra, matching the Pune branch, so the supply is Within State. 5. For an order the Surat showroom pays for, the coordinator picks *Surat showroom* in both address lookups before saving. The order takes the Gujarat GSTIN and place of supply, and the supply becomes Outside State. ## Training ### Practice exercise In a sandbox, open a test customer account that has no contact addresses and its own billing address filled in. 1. Add a **Shipping** address named *Practice dock* with **Is Default** on. 2. Raise a new sales order for the account and save it without touching the address fields. Expected result: the order's billing address comes from the account's own billing fields (there is no default billing contact address), and its shipping address is *Practice dock*. Now add a default **Billing** address and raise a second order: its billing address is the new contact address, while the first order is unchanged. ### Quick reference - Add addresses from the account's **Contact & Address Info** tab with **New**. - **Address Type**: Billing, Shipping or Both — Both serves either side. - Keep one **Is Default** address per side per account; xMatix does not switch the old one off. - Documents only fill what is empty — pick a different address before typing. - Orders, invoices and purchase orders fill on first save; quotes and opportunities prefer the account's own address fields. - The billing address's GSTIN, place of supply and registration type beat the account's on sales documents. - Editing an address never changes documents already raised. - Deleted addresses go to the recycle bin. ## Permissions Access is set per security profile on the **Contact Address** entity, under **Setup → Access Control → Profiles → Entity Permissions** (see [Security profiles](/docs/administration/security-profiles/)). In the standard profiles, **Standard User**, **System Admin**, **Sales**, **Sales Executive**, **Sales Manager** and **Service** have full access — read, create, edit and delete. A user whose profile cannot read contact addresses does not see the account's addresses list and cannot pick an address on a document; a user who can read but not create or edit sees the addresses but no **New** or **Edit**. ## Configuration - **Where addresses appear.** On the web, the addresses list sits on the account's **Contact & Address Info** tab. The standard **Partner Onboarding Settings** app also lists **Contact Addresses** under **Partner Masters**, on web and mobile. Administrators can add the entity to other apps — see [Apps, entities and records](/docs/concepts/apps-entities-records/). - **City, State and Country picklists.** These are picklists your administrator maintains, so you can add the cities, states and countries you trade in. **GST Registration Type** uses the fixed values in [Fields](#fields); the tax logic depends on them, so do not rename them. - **Layouts and list views.** The address form, the record view, the mobile forms and the **Contact Address** list view can be changed in Studio like any other entity — see [Customizing xMatix](/docs/customization/). - **Branch addresses.** To set the address printed as the seller on invoices, open the branch and choose its **Address** — see [Branches](/docs/administration/branches/). - **GSTIN verification.** Verifying address GSTINs against the GST network needs an integration your organisation sets up; without one, address GSTINs show as not verified in GSTR-1. See [GSTR-1](/docs/finance/tax-center/gstr-1/). ## Common problems ### The address did not fill in on my order The account has no contact address with **Is Default** on of the right type — a Billing or Both address for billing, a Shipping or Both address for shipping — and its own address fields are empty too. Or you had already typed part of the address before saving, so xMatix kept your entry. Mark the right address as default, or pick it in the address lookup. ### The order used the wrong address The account has two default addresses of the same kind, and xMatix picked the other one. Open the account's addresses and leave only one default per side. On the order, pick the right address in the lookup and correct the address fields. ### A quote shows the account's address, not my default contact address Quotes and opportunities take the account's own address fields first and use the default contact address only for parts the account leaves blank. Pick the contact address in the quote's address lookup, or clear the account's own address fields if the contact addresses are meant to be the source. ### The tax on the invoice is for the wrong state The billing address's **Place Of Supply** or **GST Registration Type** — or the account's, when the address has none — does not match the customer's registration at that site. Correct the address, then check the invoice: values already on the invoice are not replaced, so clear its **Place Of Supply** or **GSTIN** and save to pick up the corrected value. ### I changed an address but old documents still show the old one Documents copy the address when they are raised. Edit the address on each open document if it must change. ### I cannot save a new address The **Account** is empty. Every contact address must belong to an account — pick the account, or open the account and add the address from its **Contact & Address Info** tab. ## Common questions ### What is the difference between the account's address fields and a contact address? The account's **Billing Address** and **Shipping Address** fields hold one address of each kind on the account record itself. Contact addresses are separate records, as many as you need, each with its own type, default flag and GST details. Sales orders, invoices, delivery orders, service orders, bills and purchase orders prefer the default contact address and fall back to the account's fields. Quotes and opportunities do the reverse: they start from the account's fields and use the default contact address to fill gaps. ### Should I use Both or separate Billing and Shipping addresses? Use **Both** when the customer is billed and receives goods at the same place — one default **Both** address fills both sides. Use separate **Billing** and **Shipping** addresses, each marked default, when the invoice and the goods go to different places. You can mix them: non-default addresses of any type stay available in the lookups for one-off documents. ### Does a contact address need its own GSTIN? Only when the party is registered at that address under a different GSTIN from the account's — typically a customer registered in several states. Leave it blank otherwise; the sales document then takes the account's GSTIN. The same goes for **Place Of Supply** and **GST Registration Type**: fill them on the address only where they differ. ### Can I delete an address that documents have used? Yes. The address leaves lists and lookups and goes to the recycle bin, and documents that used it keep the address text they copied. Consider switching **Is Default** off instead if you only want to stop new documents from using it. ## Related topics - [Accounts](/docs/crm/accounts/) - [Quotes](/docs/crm/quotes/) - [Working opportunities through the pipeline](/docs/crm/opportunities/) - [Delivery orders](/docs/warehouse/delivery-orders/) - [Branches](/docs/administration/branches/) - [GSTR-1](/docs/finance/tax-center/gstr-1/) - [Data lifecycle](/docs/concepts/data-lifecycle/) - [Contact Address reference](/docs/reference/entities/contact-address/) ---- # xMatix CRM URL: https://xmatix.com/docs/crm/ Last reviewed: 2026-09-06 xMatix CRM is the front end of the revenue funnel: it captures interest as **leads**, qualifies it into **opportunities**, prices it as **quotes**, and hands the won deal to [Sales](/docs/sales/) as an order — with **accounts** as the customer master underneath, product configuration and demo bookings on the deal, and calls, tasks and notes logged against every record along the way. This page maps the module and links every topic in this section. ## The CRM app The CRM app appears in your navigation when your administrator has granted it. Its standard entries are: @[guided-image](_img/crm-overview.png) | Entry | What it holds | | --- | --- | | Home | Landing page with summary cards | | Leads | Raw interest: captured, worked and converted | | Opportunities | Qualified deals with lines, pricing and generation actions | | Quotes | Priced offers with approve/decline and order generation | | Accounts | The customer master shared with the rest of xMatix | | Call Register | Inbound and outbound phone calls, linked to the records they were about | | Lead Allocation | Assigning leads to sellers | | Reports, Dashboards | CRM reporting | | Settings | The module's masters and scheduling configuration | Administrators can add further entries to the app — **Case** (support cases, documented in the [Support section](/docs/support/)) and **Appointment** (bookings against branch capacity, preview) are common additions — so your navigation may differ from the standard set. Because accounts, items, price lists and branches are shared platform masters, a deal priced in CRM and the order it becomes in Sales read the same data — nothing is re-keyed at the handover. ## The funnel at a glance A lead converts into an account (if the customer is new), a contact and an opportunity. The opportunity carries the deal's lines and pricing and can generate a quote, a sales order or a service order. The current quote-generation path does not enforce a one-quote or non-empty-lines guard, while the direct order and service-order paths have their own checks. A quote records approved or declined flags, but order creation currently excludes only declined quotes rather than requiring approval. Details and safeguards are on each page below. ## Section map | Page | What it covers | | --- | --- | | [Accounts](/docs/crm/accounts/) | The customer master: roles, relationships, hierarchy and account groups | | [Contact addresses](/docs/crm/contact-addresses/) | An account's billing and shipping addresses, defaults and per-address GST details | | [Leads](/docs/crm/leads/) | Capturing, qualifying and converting leads — and what conversion creates | | [Opportunities](/docs/crm/opportunities/) | Working the deal and generating quotes, orders and service orders | | [Quotes](/docs/crm/quotes/) | The quote lifecycle: pricing, approve/decline, creating the order | | [Product configurator and demos](/docs/crm/product-configurator/) | Configuring package products on deals, and booking product demos | | [Appointments](/docs/crm/appointments/) | Appointment types, slot templates, bookable resources and scheduling (preview) | | [Activities](/docs/crm/activities/) | Calls, tasks, meetings and notes — the shared engagement layer | | [CRM configuration](/docs/crm/configuration/) | Administrator reference for scheduling setup and account groups | | [Troubleshooting](/docs/crm/troubleshooting/) | The blocks CRM users actually hit, and what each one means | ## What lives elsewhere Support cases, SLA policies and the knowledge base are documented in the [Support section](/docs/support/). Order fulfilment, invoicing, pricing rules and trade schemes are in the [Sales section](/docs/sales/) — start with [creating a sales order](/docs/sales/orders/create-order/) for what happens after CRM hands the deal over. Field visits and beat plans are under [Field Sales](/docs/field-sales/). ## Related topics - [Navigating xMatix: apps, lists and records](/docs/getting-started/navigation/) - [xMatix Sales](/docs/sales/) - [CRM product overview](/products/crm/) - [Book a demo](/demo/) ---- # Working leads from capture to conversion URL: https://xmatix.com/docs/crm/leads/ Last reviewed: 2026-10-10 A **lead** is interest that has not been qualified yet: who the person or business is, how to reach them, where the enquiry came from and what they seem to want. It is the first record in the CRM funnel. You work a lead with calls, emails and bookings until it is real, then convert it into an [opportunity](/docs/crm/opportunities/) (creating or reusing the [account](/docs/crm/accounts/) and contact on the way), release it straight to a [sales order](/docs/sales/orders/) or service order, or close it as lost. You find leads in the **CRM**, **Service** and **Partner Onboarding** apps, under **Leads**. ## Overview A lead records the enquirer (first and last name, business name, phone, email), the enquiry (lead source, rating, the interested item or the asset it concerns), the routing context (**Partner Account**, **Branch** and **Executive**) and its **Status**. Every lead has one of three record types, and each has its own form and its own buttons: | Record type | Used for | Buttons on the record | | --- | --- | --- | | **Sales** | Interest in buying a product | Product Demo, Opportunity, Lead Lost, Order, Edit, Delete | | **Service** | A customer's service need on an asset they own | Appointment, Opportunity, Lead Lost, Service Order, Edit, Delete | | **Partner** | A business enquiring about becoming a dealer, distributor or service centre | Convert Lead, Lead Lost, Edit, Delete | The record page shows a stage bar for **Status** under the header, a **Details** tab, a **Related** tab (sales and service leads), an **Activities** panel and **Sense AI insights**. Sales and service lead pages also show a **Duplicates** panel, and sales lead pages show a **Lead Score** panel when your organization scores leads. ## When to use it Use a lead for any enquiry you have not yet qualified: a walk-in, a phone call, a web form, a referral or a social-media message. Once the customer has said what they want and you need to price it, convert the lead into an opportunity. When there is nothing to negotiate — the customer simply wants to buy the item or book the service — release the lead straight to an order or service order instead. Many leads are created for you rather than typed in: a campaign's **Leads**, **Contract Schedule** and **Maintenance Schedule** buttons raise leads for campaign members and for assets falling due for contract or maintenance work, and the **Lead** button on a support case turns the case into a lead. ## How xMatix handles it ### Status **Status** is the lead's stage: **New**, **Contacted**, **Nurturing**, **Lost** or **Converted**. A new lead starts as New. Shipped business rules move it for you: - When a **Call** or **Email** activity is logged against the lead, Status becomes **Contacted** (unless the lead is already Converted or Lost). - When the lead is saved with an opportunity linked — because it was converted — Status becomes **Converted**. If a freshly converted lead still shows its earlier status, refresh it; saving the lead once applies the rule. - Once a lead is **Converted** or **Lost**, its status is final: any change of status is refused with *"A Converted or Lost lead is final - its status can no longer be changed."* You can also move status yourself with the status actions **Advance Status** (one step along New → Contacted → Nurturing; it stops at Nurturing and never sets Lost or Converted), **Mark New**, **Mark Contacted**, **Mark Nurturing** and **Mark Lost**. Mark Lost refuses a Converted lead. Where these actions appear depends on your organization's layouts. ### What happens when a lead is saved - **The postal code is tidied and routed.** The **Postal Code** you enter is matched against your organization's postal code list and replaced with its standard spelling, and **City**, **State** and **Country** are filled from it. If a branch covers that postal code, the lead's **Branch** and **Partner Account** are set from the mapping — on every save, not only the first. When two mappings cover the same postal code, the older one wins. If your organization routes leads with an assignment rule instead, the assignment rule decides and the postal-code routing steps aside. - **The customer is recognised.** If you pick an **Account**, the lead takes the account's first and last name, phone, email, city, state and postal code (from the account's billing address, or its default billing address) and its most recently created contact — filling only the fields you left blank. If you pick no account but the **Phone Number** matches an existing account's phone, the lead links to that account in the same way. If you pick an **Asset** and no account, the lead links to the asset's owner. - **Names fill in.** With an account selected and **Business Name** empty, Business Name is taken from the account's name. With a contact selected, empty **First Name** and **Last Name** are taken from the contact. - **Partner Account and Branch are checked.** A partner account is required on every lead and must be active. If the partner account has branches, one of them is required and it must be active. - **The Executive is assigned.** On a new lead, the partner-resource assignments for the lead's partner account and branch pick the **Executive**. When an assignment matches, it replaces any executive you chose. See [Automatic owner assignment](/docs/field-service/assignment-rules/). - **A document number is assigned** on the first save — shipped series `L`, the date as day, month and year, and a six-digit counter, joined by hyphens (for example `L-10102026-000001`). **Document Date** defaults to today. - **A score may be set.** If your organization has published a lead scoring model, the score fields are recalculated on save. ### Converting and releasing | Button | Record type | Creates | Limits | | --- | --- | --- | --- | | **Opportunity** | Sales, Service | Opens the **Convert Lead** dialog: an account (new or existing), a contact (new or existing) and an opportunity (new or existing) | Refused once the lead has an opportunity | | **Convert Lead** | Partner | In one step: a new account if the lead has none (a partner account, inactive, for a partner enquiry), a contact if needed, and a partner opportunity | Refused once the lead has an opportunity | | **Order** | Sales | Opens the **Release Order** dialog: an account and contact (new or existing) and a sales order with one line for the interested item | No limit: each release creates another order | | **Service Order** | Service | A service order for the lead's account and asset, with one line for the interested item if there is one | Refused once the lead has a service order | What the new records carry: - **Account.** Named after the lead's **Account Name** — the Business Name, or else the first and last name. The lead's street, city, state, postal code and country fill the account's billing and shipping address. Accounts created from sales and service leads are active customer accounts. - **Contact.** Named after the lead's first and last name, with its email and phone as the contact's email and mobile. - **Opportunity.** The account and contact, the lead's partner account, branch, asset and service contract, today's date, and the matching record type (a sales lead gives a sales opportunity, a service lead a service opportunity). For a partner enquiry, the property, email, proprietor name, first and last name and business name carry over. When the lead names an **Interested Item**, the opportunity starts with one line for it, quantity 1, with the lead's SKU. - **Sales order.** The account and contact, partner account, branch, executive and today's date, linked back to the lead, with one line for the interested item and SKU, quantity 1. - **Service order.** The account, asset, partner account, branch, service contract and document date; the lead's executive becomes the service advisor and its **Remarks** become the customer's voice. Releasing an order or a service order does not change the lead's status. ## Prerequisites - Access to the **CRM**, **Service** or **Partner Onboarding** app and permission on leads (see [Permissions](#permissions)). - Your selling company (partner account) and branch — or a postal code your organization has mapped to a branch. - For a service lead, the customer's **Asset**. - For conversion and release, a partner account and branch on the lead or a postal code (not needed on partner leads). ## Procedure ### Step 1 — Find a lead ![The Leads list in the CRM app, with saved views, summary cards by status and rows showing each lead's document number, partner account, branch, account and status](_img/lead-list.png) Open **Leads** in the CRM or Service app. Pick a view: **All Leads**, **Sales Leads**, **Service Leads**, **Partner Leads**, **Open Leads** (New, Contacted or Nurturing), **Lost Leads**, **Unassigned Open Leads** (open leads with no executive) or **Service Due** (open service leads whose due date has arrived). Search, filter and sort as on any list, and open a lead to see its record page. ### Step 2 — Capture a lead 1. Switch to the view for the kind of lead you are capturing, then choose **New**. The form that opens is the form for that record type. 2. Fill the top section: **First Name**, **Last Name**, **Business Name**, **Phone Number**, **Email** and **Lead Source**. On a sales lead add the **Interested Item** and its **SKU**; on a service lead pick the **Asset** and, where relevant, the **Item Service Contract** and **Item Maintenance Schedule**; on a partner lead choose the **Partner Type**. 3. On **Details**, set the **Lead Rating**, the **Account** and **Contact** if the customer is known, the **Postal Code**, **Potential Revenue**, **Campaign**, **Lead Due Date** and **Remarks**. Leave **Executive** empty if your organization assigns executives automatically. 4. Fill **Qualification** and **Profile** with whatever the enquirer told you — industry, budget, turnover, job title, preferred language and so on. 5. On **System Details**, check **Partner Account** and **Branch**. Leave them empty only if the postal code will route the lead. 6. Save. The lead gets its document number, Status **New**, and any account, branch, partner account and executive xMatix resolved. Reopen it and check those values before you start working it. At least one of First Name, Last Name or Business Name is required, unless you pick an account or contact to take the name from. ### Step 3 — Qualify the lead Work the lead from its **Activities** panel: log calls and emails, add tasks and schedule meetings (see [Activities](/docs/crm/activities/)). Logging a call or an email moves the lead to **Contacted**. Use **Advance Status** or **Mark Nurturing** when the lead needs longer-term follow-up, and keep **Lead Rating** (Hot, Warm, Cold) current so colleagues can see which leads to chase. To book a visit, use **Product Demo** on a sales lead or **Appointment** on a service lead. Both open the **New Booking** wizard, where you pick a branch, a time slot and a date; the booking is linked to the lead and takes a seat in that slot. A full or unavailable slot is refused with a message naming the slot and date — pick another. See [Product demos](/docs/crm/product-configurator/#product-demos). Check the **Duplicates** panel: it lists other open leads with the same email, phone or contact. Merging a duplicate into the lead you keep moves its activities, attachments, collaborators, followers and side conversations across, and marks the duplicate **Lost** with Lost Reason **Duplicate**. ### Step 4 — Convert the lead to an opportunity 1. On a sales or service lead, choose **Opportunity**. The **Convert Lead** dialog opens with three tabs: **Account**, **Contact** and **Opportunity**. 2. On **Account**, choose **New Account** or **Existing Account**. The **Matching Accounts** card lists customer accounts that look like this lead and says why each matched; choose **Link** on one to use it. Only customer accounts can be picked. 3. On **Contact**, choose **New Contact** or **Existing Contact**. Existing contacts are limited to the chosen account; with a new account, Existing Contact is not available. 4. On **Opportunity**, choose **New Opportunity** and review the pre-filled values, or **Existing Opportunity** to link one the account already has. 5. Choose **Convert**. The summary shows each record as Created, Linked or Updated. The lead now links to the opportunity, and the status rule moves it to **Converted**. On a partner lead, choose **Convert Lead** instead. It runs in one step with no dialog: the account, contact and partner opportunity are created from the lead. The records you create or pick in the dialog always win over the lead's earlier links — converting with a new account points the opportunity at the new account. The lead keeps its link to the opportunity, so the deal's origin stays traceable. ### Step 5 — Or release an order or service order - **Sales order.** On a sales lead, choose **Order**. The **Release Order** dialog asks only which customer this is — **Account** and **Contact**, new or existing, as in Step 4. Choose **Release Order**. The order is created from the lead's values with one line for the interested item. Each release creates another order, so release once and continue from the order (see [Creating a sales order](/docs/sales/orders/create-order/)). - **Service order.** Choose **Service Order**. The service order is created for the lead's account and asset. A lead can raise only one service order. ### Step 6 — Close a lost lead Choose **Lead Lost**. Pick the **Lost Reason** (required) and add **Remarks**, then confirm. Status becomes **Lost** and can no longer change. **Mark Lost**, where your layout offers it, sets Lost without asking for a reason. ### Step 7 — Use leads on mobile The CRM and Service apps are available in the mobile app. There you can open lead lists, create leads (the record type comes from the list you start from), and convert a lead to an account, contact and opportunity. Leads you create offline are saved on the device and sent when you reconnect; a lead must have synced before you can convert it. ## Fields The form order below is the sales lead form. Service and partner forms use the same fields with the differences noted. | Field | What it means | Notes | | --- | --- | --- | | Document Number | The lead's number | Generated on first save from document numbering (shipped series `L`). Read-only | | First Name, Last Name | The enquirer's name | Filled from the selected account or contact when empty. Required on the partner form. At least one of these or Business Name is required on every lead | | Business Name | The enquiring business's trading name | Filled from the account name when an account is selected and the field is empty | | Phone Number | The enquirer's number | Required on sales and service forms. Matched against account phone numbers to link an existing customer. Must be a valid Indian mobile number (10 digits starting 6–9) when the country code is +91 or blank | | Email | The enquirer's email | Must contain `@` | | Lead Source | Where the lead came from | Required. Shipped values: Dealer, Campaign, Visit based, Web, Phone, Email, AMC, Scheduled Maintenance, Employee Referal, Social Media | | Interested Item | The product or service the enquirer wants | Becomes the line on the opportunity, order or service order (quantity 1). On the service form it is on Qualification | | SKU | The variant of the interested item | Limited to SKUs of the interested item | | Asset | The customer's asset the lead concerns | Service form, required. Limited to the account's assets. Sets the account when none is chosen | | Item Service Contract, Item Maintenance Schedule | The contract or maintenance schedule behind the lead | Service form. Usually set by campaign schedules | | Partner Type | The kind of partner a partner enquiry wants to become | Partner form, required: Dealer, Distributor, Service Centre | | Executive | The person handling the lead | Limited to active resources. Assigned automatically on a new lead when a partner-resource assignment matches | | Lead Rating | How promising the lead is | Hot, Warm, Cold. Descriptive only | | Account | The existing customer, if known | Limited to active customer accounts. Fills names, phone, email, address and contact | | Contact | The person at the account | Limited to the account's contacts | | Postal Code | The enquirer's postal code | Routes the lead to a branch and partner account and fills City, State and Country when it matches your postal code list | | Potential Revenue | Estimated value of the lead | For reporting; not copied to converted records | | Campaign | The campaign that produced the lead | Limited to active, current campaigns of the lead's partner account or of no partner account | | Document Date | The lead's business date | Defaults to today | | Lead Due Date | When the underlying service falls due | Set on leads raised by contract and maintenance schedules | | Remarks | Notes, in the customer's own words | Becomes the customer's voice on a service order raised from the lead | | Industry, Annual Income, Years in Business, Turnover Of Current Business, Tentative Budget | Qualification answers | Turnover bands: <25, 25-50, 50-75, >75. The partner form also asks No. of Branches and Property Available (Owned, Lease, Rented) | | Salutation, Gender, Birthdate, Age Band, Job Title, Preferred Language | The enquirer's profile | Picklists: Salutation Mr., Mrs., Ms., Mx., Dr., Prof.; Gender Male, Female, Others | | PAN, GSTIN | The business's tax identifiers | Profile tab | | Street, City, State, Country | The enquirer's address | City, State and Country are overwritten from the postal code list when the postal code matches. Copied to a new account's address on conversion | | Partner Account | Your selling company handling the lead | Required on every lead; active partner accounts only. Set from the postal code when it matches | | Branch | The branch handling the lead | Required when the partner account has branches; limited to its branches. Set from the postal code when it matches | | Case | The support case the lead came from | Service form | | Status | The lead's stage | New, Contacted, Nurturing, Lost, Converted. Defaults to New | | Lost Reason | Why the lead was lost | Asked by Lead Lost: Customer Unresponsive, Timeline Constraints, Service Unavailability, Requirement Withdrawn, Budget Constraint, Competitor Selection, Duplicate, Service Not Aligned with Requirements | | Opportunity | The opportunity created by conversion | Read on the record. Once set, the lead cannot be converted again | | Lead Fit Score, Lead Score Tier, Lead Score Status | The lead's score, its band (High, Medium, Low) and whether it is Current or Not Applicable | Written only by a published lead scoring model. Read-only | The partner form's **Profile** tab also asks Department, Income Band, No. of Employees, Website, Ownership, Firm Type and Sub Industry. ## Business rules - **Name required.** *"Enter at least one of First Name, Last Name or Business Name — or select an Account or Contact to take the name from."* - **Phone and email.** A phone number with country code +91 or blank must be 10 digits starting with 6, 7, 8 or 9; an email must contain `@`. - **Partner account and branch** are validated on every save, as described above. - **Routing.** Postal-code routing runs on every save unless an assignment rule covers Partner Account or Branch; executive assignment runs on create unless an assignment rule covers Executive. - **Status.** Contacted when a call or email is logged; Converted when the lead is saved with an opportunity linked; Converted and Lost are final. - **One conversion per lead.** Converting a lead that already has an opportunity is refused. - **One service order per lead.** A second Service Order is refused. - **Orders are not limited.** Each Order release creates another sales order. - **Partner leads** are exempt from the partner-account-and-branch check that conversion and release run. - **Merging** marks each merged-away lead Lost with Lost Reason Duplicate; leads that already have an opportunity are not changed. ## Example A visitor to a dealership asks about a scooter. The receptionist opens **Leads → Sales Leads**, chooses **New**, and enters First Name *Asha*, Last Name *Rao*, Phone Number *9876543210*, Lead Source *Visit based*, Interested Item *City Scooter 125* with SKU *Pearl White*, and Postal Code *411001*. On save the postal code routes the lead to the dealership's partner account and its city branch, an executive is assigned, and the lead becomes `L-10102026-000014` with Status New. The executive calls Asha the next day and logs the call; the lead moves to **Contacted**. They book a test ride with **Product Demo**. After the ride Asha wants a price, so the executive chooses **Opportunity**. No matching account appears, so they keep **New Account** and **New Contact**, review the opportunity and choose **Convert**. xMatix creates the account *Asha Rao*, a contact of the same name and a sales opportunity with one line for the Pearl White City Scooter 125; the lead shows **Converted**. ## Training ### Practice exercise In a sandbox, as a user with the Sales Executive profile: 1. Create a sales lead with a first name, a phone number, a lead source, an interested item, a partner account and a branch. Expected: a document number starting `L-`, Status New. 2. Log a **Call** activity on it. Expected: Status becomes Contacted. 3. Choose **Opportunity**, keep New Account and New Contact, and choose **Convert**. Expected: an account, a contact and an opportunity with one line for the interested item; Status Converted. 4. Choose **Opportunity** again. Expected: *"An opportunity has already been created for this lead."* 5. Create a second sales lead with no name, business name, account or contact. Expected: the save is refused with the name-required message. 6. Give the second lead a name and save, then choose **Lead Lost** with Lost Reason *Budget Constraint*. Expected: Status Lost. Try **Mark Contacted** or **Advance Status**. Expected: the status does not change. ### Quick reference - Pick the view for the record type before choosing **New** — the form follows the view. - A partner account is required on every lead; a mapped postal code fills it and the branch. - Picking an account, or a phone that matches one, fills the customer details. - Logging a call or email moves the lead to Contacted. - Converted and Lost are final. - **Opportunity** converts once; **Order** can release again and again; **Service Order** once. - **Lead Lost** asks for a reason; **Mark Lost** does not. - The **Unassigned Open Leads** view is the queue of leads without an executive. ## Permissions Access is set on [security profiles](/docs/administration/security-profiles/): - **Entity access.** The shipped *Sales*, *Service* and *System Admin* profiles have full access to Lead, including View All and Modify All. *Sales Executive*, *Sales Manager* and *Standard User* have Read, Create, Update, Delete, Share and Assign. - **Record sharing.** Leads are owned by a user and private by default: a user sees their own leads and those of people below them in the role hierarchy, plus everything if their profile has View All. Manual sharing and team access are off for leads. - **Actions.** Every lead button — the conversion and release buttons, Product Demo, Appointment, Lead Lost, the status actions, Find Duplicates, Merge, Clone, New, Edit and Delete — is granted on the shipped *Sales Executive*, *Sales Manager* and *Standard User* profiles. *System Admin* has every lead action except **Lead Lost**. A button needs its grant on the profile's **Actions** tab, and running it also needs update access to the lead. - **Campaign leads.** The campaign **Leads**, **Contract Schedule** and **Maintenance Schedule** buttons are granted on Sales Executive, Sales Manager, Standard User and System Admin. - **Lead scoring.** Only System Admin has access to lead scoring models in the shipped profiles. ## Configuration Administrators tailor leads in these places: - **Document numbering.** **Setup → Feature Hub → Platform → Document Settings**: *Lead Name Setting* — series `L`, separator `-`, the date as day, month and year, and a six-digit counter. See [Email templates and document numbering](/docs/administration/templates/). - **Postal-code routing.** Maintain postal codes (Code, City, State, Region, Country) and branch postal codes (Branch, Partner Account, Postal Code, Coverage Type). A postal code mapped to a branch routes every lead carrying it. Keep one mapping per postal code — with several, the oldest wins. See [Branches](/docs/administration/branches/). - **Assignment rules.** **Setup → Automation → Assignment Rules** lets you decide Partner Account, Branch or Executive for new leads with your own rules (the screen's help includes a recipe for routing new leads by postal code). A rule that sets one of those fields switches off the built-in postal-code routing or executive assignment for leads. - **Partner-resource assignment.** Without an assignment rule, the Executive comes from the **Partner Resources** on each resource: partner account, branch, assignment sequence and rule criteria. See [Automatic owner assignment](/docs/field-service/assignment-rules/). - **Status rules.** The *Set Lead Status To Contacted*, *Set Lead Status To Converted* and *Lead Terminal Status Lock* business rules set and protect Status by exact value — if you rename status values, update the rules too. *Set Business Name from Account* and *Set First / Last Name From Contact* fill names. See [Business rules](/docs/customization/business-rules/). - **Picklists.** Lead Source, Lead Rating, Lost Reason, Partner Type, Industry and the profile picklists can be extended in the entity's field settings. The Lead Lost dialog lists its Lost Reason values in its own layout, so update the dialog too when you add a reason. - **Validations.** The name-required, email and Indian mobile number rules are entity validations; add a rule per market if you take numbers from other countries. - **Lookup filters.** The shipped filters limit Account to active customer accounts, Partner Account to active partner accounts, Branch to the partner account's branches, Contact and Asset to the account, Executive to active resources, SKU to the interested item and Campaign to the partner account's active campaigns. - **Layouts, views and buttons.** The Sales, Service and Partner create forms, record pages, the buttons in each header and the list views are tenant metadata you change in Design Studio. The **Convert Lead** and **Release Order** dialogs are layouts too: they name the account, contact and opportunity forms the dialog shows. - **Lead scoring.** In the CRM settings app, open **Lead Scoring** to create a model: choose the score object and record type (one published model per record type), build the criteria, and set **High tier at** and **Medium tier at** (a new model starts at a 0–100 range with 70 and 40). **Leave out records whose** status is one of the values you list — those leads show Lead Score Status *Not Applicable*. **Review and publish** rescores every existing lead in scope in the background; **Turn off** withdraws the model and clears the scores. - **Duplicate detection.** Duplicate rules your organization defines decide what the Duplicates panel lists; without them it matches open leads on email, phone or contact. - **Record types and apps.** Leads appear in the CRM, Service and Partner Onboarding apps. - **Mobile.** Lead create and view forms for mobile are separate layouts (*All Lead Create Mobile*, *Sales Lead Create - Mobile*, *Service Lead View Mobile*). ## Common problems ### "Enter at least one of First Name, Last Name or Business Name — or select an Account or Contact to take the name from." The lead has no name at all. Type a name or business name, or pick the account or contact. ### "Enter a valid Indian mobile number — 10 digits starting with 6, 7, 8 or 9." The phone number is not a 10-digit Indian mobile number. Remove spaces and the leading 0 or +91, or set **Phone Number Country Code** if the number is from another country. ### "Invalid Partner Account." or "Partner account is Inactive." Every lead needs an active partner account. Choose one on **System Details**, or enter a postal code your organization has mapped to a branch. ### "Branch is required for this Partner Account." or "Invalid Branch for Partner Account." The partner account has branches, so the lead needs one of them. Pick a branch from the list, which shows only that partner account's branches. ### "A partner account is required unless the lead carries a postal code for geographic routing." Conversion, Order and Service Order need a partner account and branch, or a postal code. Fill them in and run the action again. The matching message for branch is *"A branch is required unless the lead carries a postal code for geographic routing."* ### "An opportunity has already been created for this lead." The lead was converted before. Open the opportunity from the lead's **Opportunity** field instead of converting again. ### "This lead already has a service order. Open the existing service order instead of generating another." A lead raises one service order. Open the existing one. ### "Resource is not authorized for branch '…'." The executive you chose is not assigned to the lead's partner account or branch. Pick another executive, or ask your administrator to add a partner resource for them. ### Status will not change The lead is Converted or Lost, and those statuses are final. Raise a new lead if the customer comes back. ### A new lead shows another customer's name Its phone number matched an existing account when it was saved. Correct the phone number or the **Account** before converting — conversion reuses the linked account. ### I released two orders from one lead **Order** has no repeat check. Cancel the order you do not need from the sales order list. ## Common questions ### What exactly does conversion create? With the **Convert Lead** dialog, exactly what you choose on each tab: a new or existing account, a new or existing contact, and a new or existing opportunity. A new opportunity carries the lead's partner account, branch, asset and service contract, and one line for the interested item. The partner **Convert Lead** button creates an account only when the lead has none, a contact only when the account has no primary contact, and always a new opportunity. Nothing is created twice: once a lead has an opportunity, it cannot be converted again. ### What happens to the lead afterwards? It stays, with Status **Converted** and a link to the opportunity in its **Opportunity** field, so the source of the deal remains traceable. Its status can no longer change. Releasing an order or a service order links the new document to the lead but leaves the lead's status as it was, so you can still convert it or close it. ### Why did the branch and partner account change when I saved? The lead's postal code is mapped to a branch, and postal-code routing runs on every save, not only the first. To keep a different branch, correct the postal code or ask your administrator to fix the postal code mapping, or to route leads with an assignment rule instead. ### Why did the Executive change from the one I picked? On a new lead, a matching partner-resource assignment chooses the executive and replaces your choice. Change the executive after the first save, or ask your administrator to adjust the partner-resource rules or use an assignment rule. ### Can I convert a lead to an existing account and opportunity? Yes. In the **Convert Lead** dialog, choose **Existing Account** (or **Link** a matching account), then **Existing Contact** and **Existing Opportunity**. The lead links to what you picked. ## Related topics - [Opportunities](/docs/crm/opportunities/) - [Accounts](/docs/crm/accounts/) - [Activities](/docs/crm/activities/) - [Product configurator and demos](/docs/crm/product-configurator/) - [Creating a sales order](/docs/sales/orders/create-order/) - [Automatic owner assignment](/docs/field-service/assignment-rules/) - [Branches](/docs/administration/branches/) - [CRM troubleshooting](/docs/crm/troubleshooting/) - [Lead — entity reference](/docs/reference/entities/lead/) ---- # Working opportunities through the pipeline URL: https://xmatix.com/docs/crm/opportunities/ Last reviewed: 2026-10-10 An **opportunity** is a qualified deal being worked in xMatix: it names the customer, the items or services under negotiation and their real prices, and it is the record you raise the quote, sales order or service order from. It sits between the [lead](/docs/crm/leads/) that produced it and the documents that follow it — a [quote](/docs/crm/quotes/), a [sales order](/docs/sales/orders/) or a service order. You find opportunities in the **CRM** app and the **Service** app, under **Opportunities**. ## Overview An opportunity has a header — the customer (**Account**) and their contact details, the selling company (**Partner Account**) and its **Branch**, the **Executive** handling the deal, addresses, and pricing and tax settings — and **Lines**, one per item or service being sold. The money figures on the header are totals of the lines, so you change amounts by changing lines. Every opportunity has one of three record types, and each has its own form: | Record type | Used for | Buttons on the record | | --- | --- | --- | | **Sales Opportunity** | Selling products to a customer | Product Demo, Quote, Order, Product Configurator, Edit, Delete | | **Service Opportunity** | A customer's service request on an asset, such as a vehicle or machine | Check In, Appointment, Quote, Service Order, Edit, Delete | | **Partner Opportunity** | Appointing a new dealer, distributor, service centre or spare-parts partner | Edit, Delete | The record page shows a stage bar for **Status** under the header, an **Amount Summary** and an **Activities** panel beside the content, and, on sales opportunities, **Sense AI insights**. ## When to use it Use an opportunity once interest is real enough to price: the customer has said what they want and you need to quote, demonstrate or book work. Unqualified interest belongs on a [lead](/docs/crm/leads/). Most opportunities are created for you — by converting a lead, by converting a case, or by running a campaign (one opportunity per campaign member) — and you can also create one directly with **New**. ## How xMatix handles it ### Status and progress **Status** is the deal's stage. The shipped values are **Prospecting**, **Appointment/Quote** and **Closed Won**; your organization may have added more. A new opportunity starts as Prospecting, and two shipped business rules move it forward for you: - When a quote has been raised from it, or it has at least one product demo or appointment, Status becomes **Appointment/Quote**. - When a sales order, service order or partner application has been raised from it, Status becomes **Closed Won**. Status is a normal field, so you can also change it yourself on the record. Separately, the read-only **Progress State** field records the milestone the deal reached (New, Quote Generated, Appointment Generated, Order Generated, Service Order Generated, Partner Onboarded, Lost); no user can edit it. ### What happens when an opportunity is saved - **Customer details fill in.** Choosing an **Account** fills the names, phone, email, contact and the billing and shipping addresses from the account. With no account chosen, xMatix takes the account from the selected **Asset**'s owner, from the originating lead, or from an account whose phone matches the **Phone Number** you entered. - **Pricing context is set.** The applicable sale price list and discount group are set on the header, and the header tax context (tax supply type, place and source of supply) is worked out from the customer's address and the branch. It is recalculated on every save. - **Lines may be added automatically.** A converted lead's interested item becomes a line (quantity 1). A campaign run adds one line per campaign item. On service opportunities, open campaign items on the asset, the pending lines of the asset's service contract, and service recommendations you accept also become lines. - **Partner Account and Branch are checked and then locked.** The branch must belong to the partner account and both must be active. Once saved, neither can be changed. - **A document number is assigned** from document numbering — shipped series `OP`, the date as day, month and year, and a six-digit counter, joined by hyphens. ### How lines are priced When you pick an item on a line, its **Unit Price** comes from the price list in force on the price date — the line's price-as-on date, else the header's **Price As On Date**, else the opportunity's **Document Date**, else today. A price you type yourself on a new line is kept. Discounts from the discount group and the line's tax are applied on save, and the header totals update. See [how prices resolve](/docs/sales/pricing-and-discounts/). ### Raising quotes and orders | Button | Creates | What is copied | Limits | | --- | --- | --- | --- | | **Quote** | A new quote linked to the opportunity | The customer, partner account, branch, executive, asset and service details, and **every** line with its price, tax group and discounts | None: each click creates another quote, and an opportunity with no lines gives a quote with no lines | | **Order** (sales) | A sales order linked to the opportunity | The customer, partner account, branch and executive, and every line that still has a **Pending Quantity**, for that quantity | Refused when there are no lines, or when every line has been released already | | **Service Order** (service) | A service order linked to the opportunity | The customer, asset, service, contract, pricing and tax details, and every line with a pending quantity | Refused when there are no lines, or when every line has been released already | A line's **Pending Quantity** is its quantity minus what has already gone onto sales orders and service orders. You can therefore run **Order** or **Service Order** again after adding lines or increasing a quantity, and only the new quantity is released. The opportunity's **Order** and **Service Order** fields show only the first one raised; every order raised from it appears with the opportunity as its source. ## Prerequisites - Access to the **CRM** or **Service** app and permission to create opportunities (see [Permissions](#permissions)). - The customer as an [account](/docs/crm/accounts/), or the details to enter for a new prospect. - Your selling company (partner account) and branch. - Items with prices on a sale price list, for the lines. - For a service opportunity, the customer's **Asset**. ## Procedure @[guided-image](_img/new-opportunity.png) ### Step 1 — Find an opportunity Open **CRM → Opportunities** (or **Service → Opportunities**). The shipped list views are **All Opportunities**, **Sales Opportunities**, **Service Opportunities**, **Partner Opportunities** and **Unassigned Open Opportunity** — the Prospecting opportunities that have no executive yet, which is the queue to assign from. The summary cards above the list count opportunities by status. Use search, filters and grouping to build a pipeline view and save it — see [personalizing lists and views](/docs/getting-started/personalizing/). ### Step 2 — Create an opportunity 1. Choose **New** and pick the record type if you are asked. 2. Fill the main fields: **First Name**, **Last Name**, **Business Name**, **Account**, **Contact**, **Phone Number**, **Email**, **Document Date**, and the **Executive** who will handle the deal. A sales opportunity also offers **Campaign** and **Remarks**. A service opportunity needs the **Asset** and offers **Service Type**; a partner opportunity needs the **Account**. 3. Check the **Billing** and **Shipping** tabs. If you picked an account, they fill from it on save; entering a **Billing Postal Code** fills the billing city, state, region and country from the postal-code master. 4. On a service opportunity, fill the **Service Details** tab (**Service Contract**, **Package Service**, **Asset Service Contract**, **Usage Reading**, **Usage Reading Hours**, **Case**, **Remarks**) and the **Logistics** tab (**Pick Up Required**, **Pick Up Address**, **Drop Off Address**, **Drop Off Required**). 5. On a partner opportunity, fill **Partner Terms** (**Partner Type** is required) and **General Information**. 6. On **System Details**, choose the **Partner Account** and **Branch** carefully — you cannot change them later — and leave **Status** as Prospecting. 7. Save. The opportunity opens with its document number and the Status stage bar at Prospecting. ### Step 3 — Add and correct lines 1. On the **Lines** tab, choose **New** (the line quick-add is labelled **Quick Add**). 2. Pick the **Item**, and the **SKU** or **Item Lot Type** if the item has them. The **Unit Price** fills from the price list; change it only if the deal has a negotiated price. 3. Enter the **Quantity** (it must be more than zero), check the **Tax Group**, and add a **Description** if needed. The item's 360° panel beside the form shows its context. 4. Save. The line gets its number (series `OPL`), its tax and discounts, and the header totals and **Amount Summary** update. To change a line, use **Edit** on its row; to remove it, **Delete**. A line whose item came from a campaign that mandates it cannot be changed or deleted. For package items, open **Product Configurator** and see [Product configurator and demos](/docs/crm/product-configurator/). ### Step 4 — Work the deal - Log calls, tasks and meetings in the **Activities** panel and always leave a dated next action — see [Activities](/docs/crm/activities/). - On a sales opportunity, **Product Demo** opens the **New Booking** dialog to book a demonstration at a branch slot; the booking appears under **Related** — see [Product configurator and demos](/docs/crm/product-configurator/). - On a service opportunity, **Appointment** opens the same booking dialog for a service appointment. - Booking a demo or appointment moves Status to **Appointment/Quote**. ### Step 5 — Check in a service customer On a service opportunity, **Check In** opens a dialog for the **Usage Reading** and **Usage Reading Hours** at arrival. Choosing **Save** creates the customer check-in inspection and opens it. If the opportunity already has a customer check-in, the button opens that one instead of creating a second. The readings cannot be lower than the asset's last recorded readings, and must sit within the usage band of a service contract on the opportunity. Use the **Health Check**, **Complaint** and **Recommendation** tabs to record findings; accepted recommendations become lines. ### Step 6 — Raise a quote Before choosing **Quote**, open **Related** and check the existing quotes, and check that the lines are complete. Choose **Quote**. A new quote is created with the customer, branch and all lines copied, and it appears in the **Related** tab's quote list. Open it to adjust prices and send it — see [Quotes](/docs/crm/quotes/). Status moves to **Appointment/Quote**. ### Step 7 — Raise the sales order or service order 1. Check the lines and their **Pending Quantity**. 2. On a sales opportunity choose **Order** and confirm **OK** in the **Perform Generate Order** dialog. On a service opportunity choose **Service Order**. 3. Wait for the result instead of clicking again. The new order carries every pending line quantity. 4. Open the order from the opportunity's **Order** or **Service Order** field (the first order) and reconcile customer, branch, partner, lines and totals. Status becomes **Closed Won**. To release more later, add lines or raise quantities and run the button again. ### Step 8 — Close a lost deal The shipped Status values have no "lost" stage, and there is no cancel action. If your organization has added a lost value to Status, set it on the record and record why in **Remarks**; otherwise follow your organization's practice. Do not delete an opportunity that has quotes or orders — they keep it as their source. ### Step 9 — Use opportunities on mobile In the xMatix mobile app, opportunities appear in the CRM and Service apps through the same forms. You can create them, convert a lead into one, add lines priced from the sale price list even while offline, book demos and appointments, check in a service customer, and run the record's actions. ## Fields Fields as they appear on the record's **Details** tab. Totals are calculated from the lines and are read-only. | Field | What it means | Notes | | --- | --- | --- | | Document Number | The opportunity's number | Assigned on save from document numbering, for example `OP-10102026-000042` | | First Name, Last Name | The person the deal is with | Filled from the lead or account; used to build **Account Name** when there is no business name | | Business Name | The firm the enquiry is for | Copied to the quote | | Account | The customer | Only active customer accounts can be picked; filled automatically from the asset, the lead or a matching phone number when empty | | Account Name | The customer's filing name | Defaults to the business name, else first and last name; copied to orders | | Contact | The contact person | Limited to the account's contacts; defaults to the account's most recent contact | | Phone Number, Email | How to reach the customer | Phone country code defaults to +91; the phone number is also used to find the account | | Document Date | The business date of the deal | Set to today by lead conversion and campaign runs; used as the price date when no price-as-on date is set | | Campaign | The campaign that produced the deal | Set by campaign runs | | Executive | The person handling the deal | Must be active and authorized for the partner account and branch | | Order, Service Order | The first sales order or service order raised | Set by the Order and Service Order buttons | | Remarks | Free notes | — | | Asset | The customer's asset (service) | Required on a service opportunity; limited to the account's assets | | Service Type | Kind of service | Accidental Repairs, PDI, Paid Repairs, Warranty Repair | | Job Type | Kind of job | No values are shipped; your organization defines them | | Service Contract, Asset Service Contract, Package Service | Contract and package the work falls under | Only asset service contracts valid today can be picked; choosing a service contract adds its pending lines | | Usage Reading, Usage Reading Hours | The asset's reading at intake | Cannot be lower than the last recorded reading; must sit within the contract's usage band | | Case | The case the opportunity came from | Set by the case's conversion action | | Pick Up Required, Drop Off Required, Pick Up Address, Drop Off Address | Logistics for the asset | — | | Partner Type | Kind of partner being appointed (partner) | Dealer, Distributor, Service Centre, Spare Parts; required on a partner opportunity | | Firm Type | Legal form of the prospective partner | Partnership, Proprietorship, LLP, Private Ltd., HUF | | Financial Capability | How the prospect will fund the business | Inventory Funding, Cash Credit Limit, Term Loan, Others | | Expected Go-Live Date, Property Available, Proposed Security Deposit | Partner terms under negotiation | Property Available: Leased, Rented, Owned | | Name of Main Proprietor, Aadhaar Number, PAN, Gender, Date of Birth | The prospective partner's details | Aadhaar is masked; Gender: Male, Female, Others | | Partner Onboarding | The partner application raised | Read-only | | Total Amount | Lines plus tax | Calculated | | Total Line Base Amount | Quantity × unit price over the lines, before discount | Calculated | | Total Tax Amount | Tax over the lines | Calculated | | Open Amount | Same as Total Amount | Calculated | | Billing and Shipping address fields | Street, city, state, region, postal code, country | Filled from the account; a billing postal code fills city, state, region and country | | Tax Supply Type, Tax Group | Tax context | Tax supply type is worked out on every save | | Partner Account | Your selling company | Only active partner accounts; locked after save | | Branch | The selling branch | Must belong to the partner account; locked after save | | Status | The deal's stage | Prospecting (default), Appointment/Quote, Closed Won, plus any your organization adds | | Record Type | Sales, Service or Partner | Read-only after creation | **Line fields.** **Item** (required; cannot be changed once the line has a quantity saved), **SKU**, **Item Lot Type**, **Alternate Item**, **Quantity** (more than zero), **Duration In Hours**, **Description** (defaults to the item name), **Unit Price**, **Discount Amount**, **Tax Amount**, **Amount**, **Tax Group**, **Price List**, and the read-only **Pending Quantity**. Service lines add the contract and campaign details, **Posting Type** and **Service Recommendation**. **Not on the shipped form.** The header **Price List**, **Discount Group**, **Discount** (a percentage) and **Price As On Date** are set automatically and are not shown on the shipped layouts. An administrator can add them; see [Configuration](#configuration). ## Business rules - **Numbering.** Opportunities are numbered from the *Opportunity Name Setting* (series `OP`) and lines from the *Opportunity Line Name Setting* (series `OPL`). - **Status rules.** *Set Opportunity Status To Appointment/Quote* fires when a quote has been raised or a demo or appointment exists. *Set Opportunity Status To Closed Won* fires when an order, service order or partner application is linked. Both overwrite the current status. - **Locked header fields.** Partner Account and Branch cannot change after save. - **Header changes that reach the lines.** Changing **Discount** applies it to every line; changing **Price As On Date** reprices every line from the price list; changing **Tax Group** recalculates header tax; changing **Service Contract** re-adds the contract's lines. - **Line validations.** Quantity must be more than zero. Inactive items are refused, an item sold only in a package cannot be added on its own, an item that needs a SKU needs one, and package components keep to their minimum and maximum quantities. - **Release tracking.** Each line tracks how much has been released to sales orders and service orders; Order and Service Order release only what is pending. - **Quotes are not tracked that way.** Quote copies every line in full each time. - **Partner application.** A partner application can only be raised from a partner opportunity at **Closed Won**, and only once. ## Example A furniture dealer's sales executive gets an enquiry from Meadow Lane Interiors for 20 office chairs and 4 meeting tables. They create a **Sales Opportunity**, pick the account, set Document Date to today, and choose their company and the city branch on **System Details**. The billing and shipping addresses fill from the account on save, and the opportunity is numbered `OP-10102026-000118` at Prospecting. On **Lines**, they add the chair (quantity 20) and the table (quantity 4); prices come from the dealer's sale price list and tax is applied. They book a showroom demo with **Product Demo**; Status moves to Appointment/Quote. They choose **Quote**, adjust the quote and send it. The customer accepts 20 chairs but only 2 tables for now, so the executive lowers the table quantity on the opportunity to 2 and chooses **Order**: a sales order for 20 chairs and 2 tables is created, and Status becomes Closed Won. A month later the customer wants the other 2 tables; the executive raises the table quantity back to 4 and chooses **Order** again, and the second order carries just those 2 tables. ## Training ### Practice exercise In a sandbox, as a user with the Sales Executive profile: 1. Create a sales opportunity for any test customer account, with a partner account and branch. 2. Add two lines with different items, quantity 3 each. 3. Choose **Quote**. Expected: a quote appears under **Related** with both lines; Status is Appointment/Quote. 4. Choose **Order** and confirm. Expected: a sales order with both lines for quantity 3; Status is Closed Won; each line's Pending Quantity is 0. 5. Choose **Order** again. Expected: *"Every line on this opportunity has already been released. There is nothing left to put on an order."* 6. Raise one line's quantity to 5 and choose **Order**. Expected: a second order for quantity 2 of that item. 7. Try to change the opportunity's Branch. Expected: the save is refused because the field is locked. ### Quick reference - Partner Account and Branch are locked after the first save — check them before saving. - Status moves itself: Appointment/Quote after a quote or demo, Closed Won after an order. - **Quote** has no limit: every click creates another quote, with or without lines. - **Order** and **Service Order** release only pending quantity and can be run again. - A typed unit price on a new line is kept; a price-as-on change reprices every line. - Quantity must be more than zero. - The **Unassigned Open Opportunity** view is the queue of deals without an executive. - Check In opens the existing customer check-in if there is one. ## Permissions Access is set on [security profiles](/docs/administration/security-profiles/): - **Entity access.** The shipped *Sales*, *Service* and *System Admin* profiles have full access to Opportunity and Opportunity Line, including View All and Modify All. *Sales Executive*, *Sales Manager* and *Standard User* have Read, Create, Update, Delete, Share and Assign, so they work on their own opportunities and the ones shared with them. - **Record sharing.** Opportunities are owned by a user and private by default: a user sees their own, those shared with them or their team, and those of people below them in the role hierarchy. Records can be shared by hand. Opportunity lines follow their opportunity and are read-only to others by default. - **Actions.** Every opportunity button — Quote, Order, Service Order, Product Demo, Appointment, Check In, Product Configurator, Clone, New, Edit, Delete — is granted on the shipped *Sales Executive*, *Sales Manager*, *Standard User* and *System Admin* profiles. A button needs its grant on the profile's **Actions** tab, and running it also needs update access to the opportunity. - **Creating opportunities from other records.** Lead conversion and case conversion are granted on the same four profiles; the campaign **Opportunities** action is granted on Sales Executive, Sales Manager and Standard User. - **Field access.** The shipped Sales Manager profile carries field-level grants on opportunity and line fields; other profiles see every field the entity grant allows. ## Configuration Administrators tailor opportunities in these places: - **Document numbering.** **Setup → Feature Hub → Platform → Document Settings**: *Opportunity Name Setting* (series `OP`) and *Opportunity Line Name Setting* (series `OPL`), each with a date part and six-digit counter. See [Email templates and document numbering](/docs/administration/templates/). - **Status values.** The Status picklist is tenant metadata: add stages such as a lost stage in the entity's field settings. The two status business rules set Appointment/Quote and Closed Won by exact value — if you rename those values, update the rules too. See [Business rules](/docs/customization/business-rules/). - **Other picklists.** Service Type, Job Type (no shipped values), Partner Type, Firm Type, Financial Capability and Property Available are picklists you can extend. - **Layouts and views.** The Sales, Service and Partner create forms and record pages, the buttons in each header, and the list views are tenant metadata you change in Design Studio. Add the header **Price List**, **Discount**, **Discount Group** or **Price As On Date** fields there if users should set them; remember that changing Discount or Price As On Date reprices every line. - **Lookup filters.** The shipped filters limit Account to active customer accounts, Partner Account to active partner accounts, Branch to the partner account's branches, Contact and Asset to the account, Executive to active resources and Asset Service Contract to contracts valid today. - **Pricing, discounts and taxes.** Sale price lists, discount groups and tax groups decide line prices and taxes — see [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/). - **Record types and apps.** Opportunities appear in the CRM, Service and Partner Onboarding apps; the Partner Onboarding app shows partner opportunities. - **Mobile.** The CRM and Service apps are available on mobile, and the mobile dashboard's quick actions include Opportunity. ## Common problems ### "Every line on this opportunity has already been released. There is nothing left to put on an order." Every line's full quantity is already on a sales order or service order. Open the existing orders from **Related** or the **Order** field. To release more, add a line or increase a quantity first. ### "No opportunity lines found to generate an order." The opportunity has no lines. Add at least one line and try again. **Service Order** shows the equivalent message, *"No opportunity lines found to generate a service order."* ### "Key fields are not editable once the related objects are added. Field Name : …" You tried to change Partner Account or Branch on a saved opportunity. They cannot change. Create a new opportunity with the right values. ### "Invalid Branch for Partner Account." or "Partner account is Inactive." The branch does not belong to the chosen partner account, or the partner account or branch is inactive. Pick a branch of that partner account, or ask an administrator to reactivate it. ### "Resource is not authorized for branch '…'." The **Executive** is not set up to work for that branch (or partner account). Pick another executive, or ask an administrator to authorize the resource. ### "Quantity should not be less than 0" A line's quantity is zero or negative. Enter a quantity greater than zero. ### "Campaign mandated items cannot be modified." The line came from a campaign that makes the item mandatory, so it cannot be changed or deleted. ### "Usage Reading cannot be less than the last recorded reading (…). Please check and try again." The reading is below the asset's last recorded reading. Check the reading on the asset and enter the current value. ### I clicked Quote twice and now have two quotes **Quote** creates a new quote on every click. Delete or decline the extra quote, and check **Related** before choosing Quote. ### The quote has no lines The opportunity had no lines when **Quote** was chosen. Add lines to the quote, or delete it, add lines to the opportunity and choose Quote again. ## Common questions ### Where is the pipeline view? Opportunities are a list like any other, so the pipeline is a view. The summary cards on **All Opportunities** count deals by status. Filter and group the list by Status, save it, and it is one click away — see [personalizing lists and views](/docs/getting-started/personalizing/). For funnel numbers across many deals, use CRM dashboards and reports. **Progress State** tells you the milestone each deal reached, independent of the stage a salesperson set. ### Should I raise the order from the opportunity or the quote? If the customer needs a formal offer, raise the quote, record their decision on it and create the order from the accepted quote — the order then links to both. If no offer is needed, choose **Order** on the opportunity. Both paths are open: raising a quote does not stop a direct order, so decide which path you follow before clicking. ### Can one opportunity have several orders? Yes. **Order** and **Service Order** release each line's pending quantity, so you can deliver a deal in instalments by releasing part, then adding or raising quantities and releasing again. The opportunity's **Order** field shows the first order; all of them are linked to the opportunity. ### Can I reprice an opportunity that has gone stale? Yes, if your layout shows **Price As On Date**: changing it reprices every line from the price list in force on that date, normally replacing prices typed on the lines. Without that field on the form, edit line prices directly, or ask an administrator to add it. ### Why did Status change on its own? Two shipped business rules move it: to Appointment/Quote when a quote, demo or appointment exists, and to Closed Won when an order, service order or partner application is linked. They overwrite the stage you set. ## Related topics - [Leads](/docs/crm/leads/) - [Quotes](/docs/crm/quotes/) - [Product configurator and demos](/docs/crm/product-configurator/) - [Appointments](/docs/crm/appointments/) - [Activities](/docs/crm/activities/) - [The sales order lifecycle](/docs/sales/orders/) - [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/) - [CRM troubleshooting](/docs/crm/troubleshooting/) - [Opportunity — entity reference](/docs/reference/entities/opportunity/) ---- # Product configurator and demos URL: https://xmatix.com/docs/crm/product-configurator/ Last reviewed: 2026-09-01 ## Read the demonstration context @[guided-image](_img/product-configurator-concept.png) The Product Demo record places a demonstration within a company, branch, sales owner and performing resource. Those fields make the activity schedulable and accountable while keeping its result connected to the customer relationship rather than in an external calendar. Before saving, confirm who owns the commercial next step and who will conduct the demonstration. Afterward, record configuration decisions, objections, outcome and follow-up against the opportunity so the demo becomes evidence for qualification and product fit. Some products aren't a single line — they are a **package** whose components the customer chooses: variants, accessories, included services. xMatix models this on the item master and lets you configure the package directly on the document you are working — an opportunity or quote in CRM, and equally an order, invoice, purchase order or requisition elsewhere. Separately, CRM books **product demos** from the opportunity so the customer can experience the product before deciding. ## How packages are defined An item flagged as a **package** carries a list of components. Each component names the component item (or specific SKU) and its selection rules: | Rule | Effect | | --- | --- | | Mandatory | The component must be included — it can't be deselected | | Pre-selected | Included by default, but removable | | Quantity, min/max | The default quantity and the editable range | | Quantity editable | Whether the user may change the quantity at all | | Feature grouping | Components group under features (e.g. *Color*, *Accessories*) for presentation | | Applicability | A component can apply only to sale, service or purchase documents | | Partner scoping | A component can be limited to specific partner accounts or account groups | Because of applicability and partner scoping, the same package can legitimately offer different components on a quote than on a purchase document, or to one dealer than another. ## Configuring a package on a document On an opportunity or quote, configuration works per line: 1. **Get Configurable Items** lists the document's lines whose item is a package — these are the lines that can be configured. 2. **Get Package Configuration** for one line returns that package's applicable components, grouped by feature, with the line's current selections and quantities, priced from the document's price list. 3. **Apply Package Configuration** writes your selection back: selected components become (or update) component lines nested under the package line; deselected components' lines are removed. The shipped quote record page has no **Product Configurator** button, so configure the package on the opportunity before choosing **Quote** — the quote copies the configured component lines with it. The configured components live as real document lines, so totals, taxes and downstream documents (the order generated from the quote) all see exactly what was chosen. Re-opening the configurator shows the current state and can be re-applied any time before the document moves on. ## Product demos On a sales opportunity, **Product Demo** opens the demo booking flow (the **New Booking** dialog): pick the branch, pick a date and time slot from the branch's available capacity, and confirm. Confirming creates a **product demo** record booked against the branch's slot capacity — a slot that is full is refused, and moving the demo to another date or slot (or cancelling it) releases the old slot and reserves the new one. Demos can also be booked **onsite** at the customer's address instead of at a branch. The demo record carries the appointment (date, time, slot), the customer and partner accounts, the item being demoed and optionally the specific demo asset used, plus confirmation and cancellation state. After the demo, capture the outcome on it — status, rating, the customer's voice and remarks — so the opportunity reflects how it went. ## Common questions ### Why does the configurator show nothing for my line? The line's item isn't marked as a package, or none of its components apply in this context — components can be scoped to sale/service/purchase documents and to partner accounts or groups, so a component list that exists on the item may still be empty *for this document and partner*. ### Where do component prices come from? From the document's price list, the same way ordinary lines price — see [pricing, discounts and taxes](/docs/sales/pricing-and-discounts/). The configurator shows prices as of the document's pricing context, so a repriced document reprices its components too. ### Is configuration only for CRM documents? No. The same configure actions exist on sales orders and invoices, and on purchase orders and requisitions — the package definition is on the item, so any document that carries the item can configure it. This page covers the CRM usage; see the [Sales](/docs/sales/) and [Procurement](/docs/procurement/) sections for those documents. ## Related topics - [Opportunities](/docs/crm/opportunities/) - [Quotes](/docs/crm/quotes/) - [Appointments](/docs/crm/appointments/) - [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/) ---- # Creating, sending and converting quotes URL: https://xmatix.com/docs/crm/quotes/ Last reviewed: 2026-10-10 A **quote** is the priced offer you send a customer: it names the customer, the items or services offered and their prices and taxes, and it is the record you create the sales order or service order from once the customer agrees. It usually follows an [opportunity](/docs/crm/opportunities/) and comes before a [sales order](/docs/sales/orders/) or a [service order](/docs/service/service-orders/). You find quotes in the **CRM** app, under **Quotes**. ## Overview A quote has a header and **Lines**. The header holds the customer (**Account**) and their contact details, the opportunity it came from, the **Executive** handling it, the billing and shipping addresses, and — on the **System Details** tab — your selling company (**Partner Account**), its **Branch** and the quote's **Status**. Each line is one item or service with its quantity, price, discount and tax. The money figures on the header are totals of the lines, so you change amounts by changing lines. Every quote has one of two record types, and each has its own form: | Record type | Used for | Buttons on the record | | --- | --- | --- | | **Sales** | Offering products to a customer | Print Quote, Order, Approve, Edit, Delete | | **Service** | Offering repair or maintenance work on a customer's asset, such as a vehicle or machine | Print Quote, Service Order, Approve, Edit, Delete | The record page shows a stage bar for **Status** under the header and, beside the content, an **Amount Summary**, an **Activities** panel and an approvals panel. Service quotes also show **Sense AI insights**. The tabs are **Lines**, **Details** and **Related** — on a sales quote, **Related** lists the orders created from it; on a service quote, the service orders. ## When to use it Use a quote when the customer needs a formal, priced offer before they commit — a written price for products, or an estimate for work on their asset. If the customer has already agreed and no offer is needed, create the order directly from the [opportunity](/docs/crm/opportunities/) instead. ## How xMatix handles it ### Where quotes come from - **From an opportunity.** The **Quote** button on an opportunity creates a quote with the customer, partner account, branch, executive, asset and service details and **every** opportunity line. Its **Document Date** is set to the day it is created. Each click creates another quote. - **Directly.** Choose **New** on the Quotes list and fill in the header, then add lines. - **By linking an opportunity later.** If you save a quote whose **Opportunity** was empty and then pick one, the opportunity's lines are added to the quote. ### What happens when a quote is saved - **Customer details fill in.** Choosing an **Account** fills the names, business name, account name, email and phone, and the billing and shipping addresses — first from the account, then from its default contact address for anything still blank. Values you typed yourself are kept. With no account chosen, xMatix takes the account from the selected **Asset**'s owner. Entering a **Billing Postal Code** fills the billing city, state, region and country from the postal-code master. - **Pricing context is set** when the quote is created: the applicable sale price list and discount group are chosen for the customer, partner account and branch. - **Tax context is worked out.** For businesses in India, the place of supply comes from the billing address (else the account), the source of supply from the branch, and the **Tax Supply Type** is recalculated on every save — Within State, Outside State, Exempt or Exports, depending on the two places and the customer's registration. - **Account, Partner Account, Branch, Opportunity and Asset lock.** Once one of them holds a value and the quote is saved, it cannot be changed. A field left empty can still be filled in later. - **A document number is assigned** from document numbering — shipped series `QT`, the date as day, month and year, and a six-digit counter, with no separator (for example `QT10102026000042`). - **The total in words is written** for printing, in the Indian numbering system. ### How lines are priced When you pick an item on a line, its **Unit Price** comes from the price list in force on the pricing date, and the discount group's discounts and the line's tax are applied on save. The header totals and the **Amount Summary** update. Changing the header **Price As On Date** reprices every line, and changing a line's item, price list or price-as-on date reprices that line. Hourly service lines take their hours from the item's standard duration. See [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/). ### Recording the customer's decision **Approve** marks the quote and every line approved and clears declined. **Decline** (not on the shipped forms) does the reverse. These are flags on the record, separate from **Status**: neither button changes Status, and nothing in the shipped configuration moves Status from **Draft** — set it yourself to Pending Approval, Approved or Declined. Both buttons do nothing on a quote that has no lines. ### Creating the order | Button | Creates | What is copied | Limits | | --- | --- | --- | --- | | **Order** (sales) | A sales order linked to the quote | The customer, partner account and branch, and every quote line with its item, quantity, prices, discounts, tax group, SKU and lot type | Works once: a second run is refused. A declined quote is skipped without a message. It does not require Approve, and a quote with no lines gives an order with no lines | | **Service Order** (service) | A service order linked to the quote as its estimate | The customer, asset, partner account, branch, executive, usage readings, service contract and service type, and every line that is not declined | Refused when the quote has no lines. A declined quote is skipped without a message. Running it again adds only the lines added since to the same service order — it never creates a second one | ## Prerequisites - Access to the **CRM** app and permission to create quotes (see [Permissions](#permissions)). - The customer as an [account](/docs/crm/accounts/), or the details to enter for a new prospect. - Your selling company (partner account) and branch. - Items with prices on a sale price list, for the lines. - For a service quote, the customer's **Asset**. ## Procedure ### Step 1 — Find a quote Open **CRM → Quotes**. The shipped list views are **All Quotes**, **Sales Quotes**, **Service Quotes** and **High-Value Quotes** (a total of 10,000 or more). The summary cards above **All Quotes** count quotes created in the last 30 days, by Status. A quote raised from an opportunity also appears on that opportunity's **Related** tab. ### Step 2 — Create a quote To create one from an opportunity, open the opportunity, check its lines and its **Related** tab for existing quotes, and choose **Quote** — then continue at Step 3. To create one directly: 1. Choose **New** and pick **Sales** or **Service** if you are asked. 2. Fill the main fields: **First Name**, **Last Name**, **Business Name**, **Account**, **Phone Number**, **Email**, **Opportunity**, **Executive** and **Remarks**. A service quote also has **Asset**. 3. On a service quote, fill the **Service Details** tab: **Service Type**, **Item Service Contract**, **Usage Reading** and **Usage Reading Hours**. 4. Check the **Billing** and **Shipping** tabs. If you picked an account, they fill from it on save. 5. On **System Details**, choose the **Partner Account** and **Branch** carefully — you cannot change them later — and leave **Status** as Draft. 6. Save. The quote opens with its document number and the Status stage bar at Draft. ### Step 3 — Add and correct lines 1. On the **Lines** tab, choose **Quick Add**. 2. Pick the **Item**, and the **SKU** or **Item Lot Type** if the item has them. The **Unit Price** fills from the price list; change it only if the offer has a negotiated price. The **Item 360** panel beside the form shows the item's context. 3. Enter the **Quantity**, check the **Tax Group**, and edit the **Description** if needed (it defaults to the item name). 4. Save. The line gets its number (series `QL`), its tax and discounts, and the header totals and **Amount Summary** update. To change a line, use **Edit** on its row; to remove it, **Delete**. A package's mandatory components cannot be removed, and deleting a package line removes its component lines. ### Step 4 — Print and send it Choose **Print Quote** to produce the printable quote and share it with the customer. Log the call, email or meeting in the **Activities** panel with a dated follow-up — see [Activities](/docs/crm/activities/). If you track sending, set **Status** to **Pending Approval** with **Edit**. ### Step 5 — Record the customer's decision When the customer accepts, choose **Approve**: the quote and all its lines are marked approved. Then use **Edit** to set **Status** to **Approved**, because Approve does not change it. If the customer turns the offer down, set **Status** to **Declined** and record why under **Details → Rejections** in **Estimate Rejection Reason** and **Rejection Remarks** — the *Quotes Lost Sale By Reason* report groups lost quotes by those remarks. ### Step 6 — Create the sales order or service order 1. Check the lines and totals — they are copied as they are. 2. On a sales quote choose **Order**; on a service quote choose **Service Order**. 3. Wait for the result instead of clicking again. 4. Open the new order from the **Related** tab and check the customer, branch, lines and totals. The order then follows the normal [sales order lifecycle](/docs/sales/orders/) or [service order](/docs/service/service-orders/) process. ### Step 7 — Use quotes on mobile In the xMatix mobile app, quotes appear in the CRM app through their mobile forms, where you can view and create them. Line prices are worked out from the sale price list on the device. Whether quotes are available offline depends on how your organization has set up the mobile app. ## Fields Fields as they appear on the record's **Details** tab. Totals are calculated from the lines and are read-only. | Field | What it means | Notes | | --- | --- | --- | | First Name, Last Name | The person the offer is for | Filled from the account; used to build **Account Name** when there is no business name | | Business Name | The firm the offer is for | Filled from the account | | Phone Number, Email | How to reach the customer | Filled from the account | | Account | The customer | Only active customer accounts can be picked; filled from the asset's owner when empty; locked once saved | | Opportunity | The deal the quote came from | Choosing one on a saved quote adds the opportunity's lines; locked once saved | | Executive | The person handling the quote | Shown in the header; activities are assigned to them | | Document Date | The quote's business date | Set to the creation day when raised from an opportunity; no default on a direct quote | | Remarks | Free notes | — | | Service Type | Kind of work (service) | Paid Repair, PDI, Warranty Repair, Accidental Repair | | Asset | The customer's asset (service) | Limited to the account's assets; locked once saved | | Service Order | The service order created from the quote | Set by the Service Order button | | Usage Reading, Usage Reading Hours | The asset's reading for the estimate | Copied to the service order | | Item Service Contract, Service Contract Item | The contract the work falls under | Choosing an item service contract adds that contract's lines | | Total Amount | Lines plus tax | Calculated | | Total Line Gross Amount, Total Tax Amount, Total Discount Amount | Line totals, tax and discounts | Calculated | | Total Labour Amount | The total of work-item lines | Calculated | | Total Amount In Words | The total written out, for printing | Written on save | | Billing and Shipping address fields | Street, city, state, region, postal code, country | Filled from the account; a billing postal code fills city, state, region and country | | Estimate Rejection Reason, Rejection Remarks | Why the customer turned the quote down | Shown under **Rejections**; the shipped reason list has only None, so your organization adds its own | | Document Number | The quote's number | Assigned on save from document numbering | | Status | Where the quote stands | Draft (default), Pending Approval, Approved, Declined; changed by hand | | Partner Account | Your selling company | Only active partner accounts; locked once saved | | Branch | The selling branch | Must belong to the partner account; locked once saved | **Line fields.** **Item**, **SKU**, **Item Lot Type**, **Quantity**, **Unit Price**, **Tax Group** and **Description** on the Quick Add form; the line record also shows **Alternate Item**, **Discount**, **Discount Amount**, **Scheme Discount**, **Tax Amount**, **Amount**, **Price List** and, on service lines, **Service Contract** and **Asset Service Contract Line**. Hourly service lines have a **Rate Basis** (Fixed Price, Standard Hours, Actual Hours, Capped Actual, Cost Plus). **Not on the shipped form.** The header **Price List**, **Discount Group**, **Discount** (a percentage), **Price As On Date**, **Tax Group** and **Tax Supply Type** are set automatically and are not shown on the shipped layouts. An administrator can add them; see [Configuration](#configuration). A create form with the pricing and tax fields added looks like this: @[guided-image](_img/new-quote.png) ## Business rules - **Numbering.** Quotes are numbered from the *Quote Document Name Setting* (series `QT`, no separator) and lines from the *Quote Line Name Setting* (series `QL`, with hyphens). - **Locked header fields.** Account, Partner Account, Branch, Opportunity and Asset cannot change once they hold a saved value. - **Partner and branch checks.** On every save the partner account and branch must exist, be active and belong together, and a partner account with branches needs one. - **Header changes that reach the lines.** Changing **Price As On Date** reprices every line. A header **Discount** is copied into each line's discount when the line is added; changing it later does not change the discount on lines already on the quote. - **Decision flags.** Approve and Decline set the approved and declined flags on the quote and every line; they never change Status. - **Status.** Starts at Draft and changes only by hand. The shipped business rule *Set Quote Status to Approved* has no actions, so it does not change anything. - **Order once.** **Order** creates one sales order per quote; a second run is refused. - **One service order.** **Service Order** creates one service order per quote; later runs add only new, not-declined lines to it. - **Declined quotes** are skipped by both **Order** and **Service Order**, without a message. - **Package lines.** Package components keep to their minimum and maximum quantities, mandatory components cannot be removed or set to zero, and some components' quantities cannot be changed. ## Example A tractor dealer's service advisor receives a request from a farmer for a 500-hour service and a replacement hydraulic pump. They open the service opportunity for the farmer's tractor and choose **Quote**. A service quote numbered `QT10102026000073` is created at Draft with the opportunity's two lines — the service package and the pump — priced from the dealer's sale price list. The advisor adds a third line for a filter kit, chooses **Print Quote** and sends it. The farmer agrees to the service and the filter kit but wants to wait on the pump, so the advisor deletes the pump line, chooses **Approve**, and sets Status to Approved. They choose **Service Order**: a service order is created for the tractor with the two remaining lines, and it appears on the quote's **Related** tab. A week later the farmer agrees to the pump; the advisor adds the line to the quote and chooses **Service Order** again, and the pump is added to the same service order. ## Training ### Practice exercise In a sandbox, as a user with the Sales Executive profile: 1. Create a sales quote directly for any test customer account, with a partner account and branch. 2. Add two lines with different items, quantity 2 each. Expected: the Amount Summary shows the lines' totals and tax. 3. Choose **Approve**. Expected: the quote is approved, but Status still shows Draft. 4. Choose **Edit** and set Status to Approved. Expected: the stage bar moves to Approved. 5. Choose **Order**. Expected: a sales order with both lines appears on the **Related** tab. 6. Choose **Order** again. Expected: *"Order has already been generated for this quote."* 7. Try to change the quote's Branch. Expected: the save is refused because the field is locked. ### Quick reference - Account, Partner Account, Branch, Opportunity and Asset lock once saved — check them first. - The opportunity's **Quote** button creates a new quote on every click. - **Approve** sets flags only; set **Status** yourself. - **Order** works once per quote; a declined quote is skipped silently. - **Service Order** never creates a second order — a re-run adds new lines to the same one. - Changing **Price As On Date** reprices every line. - Record lost quotes in **Estimate Rejection Reason** and **Rejection Remarks**. ## Permissions Access is set on [security profiles](/docs/administration/security-profiles/): - **Entity access.** The shipped *Sales*, *Service* and *System Admin* profiles have full access to Quote and Quote Line, including View All and Modify All. *Sales Executive*, *Sales Manager* and *Standard User* have Read, Create, Update, Delete, Share and Assign. - **Record sharing.** Quotes are owned by a user and private by default: a user sees their own quotes and those of people below them in the role hierarchy. Quote lines follow their quote. - **Actions.** Approve, Decline, Order, Service Order, Reprice, Clone and the package configuration actions are granted on the shipped *Sales Executive*, *Sales Manager*, *Standard User* and *System Admin* profiles. The sales **Print Quote** is granted on Sales Executive, Sales Manager and System Admin, but not Standard User. The shipped *Sales* and *Service* profiles have no action grants, so their users can edit quotes but cannot run these buttons until an administrator grants them on the profile's **Actions** tab. ## Configuration Administrators tailor quotes in these places: - **Document numbering.** **Setup → Feature Hub → Platform → Document Settings**: *Quote Document Name Setting* (series `QT`) and *Quote Line Name Setting* (series `QL`). See [Email templates and document numbering](/docs/administration/templates/). - **Status and picklists.** Status, Estimate Rejection Reason and Service Type are picklists you can extend in the entity's field settings. Add your own rejection reasons — only None is shipped. - **Status automation.** To move Status automatically — for example to Approved when an order is created — add actions to a business rule in **Setup → Process Studio → Business Rules**. See [Business rules](/docs/customization/business-rules/). - **Internal approval.** No approval process is shipped for quotes. To require sign-off, for example on large quotes, set one up in **Setup → Process Studio → Approvals**; the record page's approvals panel shows its progress. See [Approval processes](/docs/customization/approvals/). - **Layouts and views.** The Sales and Service create forms and record pages, the buttons in each header and the list views are tenant metadata you change in Design Studio. Add **Decline**, **Reprice**, **Clone**, the header **Price List**, **Discount**, **Price As On Date** or **Tax Group** there if users need them. **Clone** copies the quote with its lines, including its link to an order or service order and the marks that one was created, so a clone of a converted quote cannot create its own order. - **Print formats.** The sales record page's **Print Quote** uses the *Quote Sales Print* document report. The service record page's **Print Quote** is set to the *Pre Service Order Print* report; check that it shows what your customers should receive and change the action's report if not. See [Document reports](/docs/analytics/document-reports/). - **Lookup filters.** The shipped filters limit Account to active customer accounts, Partner Account to active partner accounts, Branch to the partner account's branches, and Asset to the account's assets. - **Pricing, discounts and taxes.** Sale price lists, discount groups and tax groups decide line prices and taxes — see [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/). - **Mobile.** Quotes reach the mobile app through the CRM app; your mobile configuration decides whether they are kept offline. ## Common problems ### "Order has already been generated for this quote." The quote already has its sales order. Open it from the **Related** tab. If the customer wants more, add the lines to that order or raise a new quote. ### "Service order has already been generated for this quote." The quote is marked as having created a service order but is no longer linked to one. Check the service orders for the customer's asset before raising new work. ### "No Quote Line found for Service Order generation." The quote has no lines. Add at least one line and try again. **Reprice** shows the equivalent message, *"No Quote Line found for Repricing."* ### I chose Order or Service Order and nothing happened The quote is declined, and declined quotes are skipped without a message. Choose **Approve** if the customer has accepted, then try again. ### "Key fields are not editable once the related objects are added. Field Name : …" You tried to change Account, Partner Account, Branch, Opportunity or Asset on a saved quote. They cannot change. Create a new quote with the right values. ### "Invalid Branch for Partner Account." or "Partner account is Inactive." The branch does not belong to the chosen partner account, or the partner account or branch is inactive (*"Branch is Inactive."*). Pick a branch of that partner account, or ask an administrator to reactivate it. *"Branch is required for this Partner Account."* means the partner account has branches and you left Branch empty. ### The Pending Quotes card always shows 0 The shipped card counts the status value "Pending", but the Status value is "Pending Approval". An administrator can correct the card's filter on the **All Quotes** view. ### "Quantity cannot be less than … for this component." or "Mandatory package component cannot be removed." The line is a component of a package item, and the package sets its allowed quantities and which components are mandatory. Keep the quantity in range, or remove the whole package line instead. ## Common questions ### Does approving a quote change its status? No. **Approve** marks the quote and every line as approved — and clears any earlier decline, so **Order** and **Service Order** work again — but the **Status** field and its stage bar stay where they were. Set Status yourself with **Edit**, or ask an administrator to add actions to a business rule that sets it for you. Approval is also separate from internal sign-off: if your organization needs a manager to approve quotes before they go out, that is an [approval process](/docs/customization/approvals/). ### Can I approve or decline individual lines? No. Approve and Decline act on the whole quote and mark every line with it. If the customer wants only part of the offer, delete or change the lines they do not want, then approve the amended quote. On a service quote, a line that is declined is not copied to the service order. ### Can I create a second order from the same quote? Not a second sales order: **Order** works once per quote. A service quote can keep adding work to its one service order — add the lines to the quote and choose **Service Order** again, and only the new lines are added. For a genuinely new offer, raise a new quote from the opportunity. ### Should I create the order from the quote or the opportunity? When the customer received a formal offer, create the order from the accepted quote so it links to the quote and carries the prices you offered. The opportunity's own **Order** button is still available and does not check for quotes, so decide which path you follow before clicking — see [Opportunities](/docs/crm/opportunities/). ## Related topics - [Opportunities](/docs/crm/opportunities/) - [Product configurator and demos](/docs/crm/product-configurator/) - [Creating a sales order](/docs/sales/orders/create-order/) - [Service orders](/docs/service/service-orders/) - [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/) - [Approval processes](/docs/customization/approvals/) - [CRM troubleshooting](/docs/crm/troubleshooting/) - [Quote entity reference](/docs/reference/entities/quote/) ---- # Troubleshooting CRM URL: https://xmatix.com/docs/crm/troubleshooting/ Last reviewed: 2026-10-10 This page collects the situations CRM users actually hit in xMatix — conversions that refuse, generation actions that won't run again, a Create Order that seems to do nothing, an empty configurator, a demo slot that won't book — with what each one means and the fix, grounded in how the engine actually decides. ## A lead won't convert *"An opportunity has already been created for this lead."* — conversion is once per lead; the lead already links to its opportunity, so open that instead of re-converting. If the deal needs restarting, work the existing opportunity — don't try to force a second conversion. *"A partner account is required unless the lead carries a postal code for geographic routing."* or *"A branch is required unless the lead carries a postal code for geographic routing."* — conversion and the Order and Service Order actions need to know who sells and from where. Either fill partner account and branch on the lead, or give it a postal code your organization has mapped, which resolves both automatically. Partner leads do not need them. See [working leads](/docs/crm/leads/). A lead releases any number of sales orders with **Order**, but only one service order: a second **Service Order** is refused with *"This lead already has a service order. Open the existing service order instead of generating another."* ## A generation action refuses to run The generation guards differ by action; do not assume one universal rule: - **Quote on an opportunity** has no duplicate or non-empty-lines guard. It can create another quote, including a header with no lines. Check existing related quotes and lines before running it. - **Order / Service Order on an opportunity** can run more than once: each releases the lines' pending quantity. They refuse with *"No opportunity lines found to generate an order."* when there are no lines, and *"Every line on this opportunity has already been released. There is nothing left to put on an order."* (or *a service order*) when every line has been released. Add a line or raise a quantity to release more. A generated quote does not block these paths. See [Opportunities](/docs/crm/opportunities/). - **Order on a quote** works once: a second run is refused with *"Order has already been generated for this quote."* It does not require Approve or lines. **Service Order on a quote** is refused with *"No Quote Line found for Service Order generation."* when there are no lines; run again, it adds only the newer lines to the same service order and never creates a second one. See [Quotes](/docs/crm/quotes/). ## Order or Service Order on a quote does nothing The quote is **declined** — declined quotes are skipped by both actions, without a message. Choose **Approve** only when the customer has actually accepted; it clears the declined state. If the quote already has its sales order, **Order** says so; open the order from the quote's **Related** tab. See [Quotes](/docs/crm/quotes/). ## Repricing is refused *"No Quote Line found for Repricing."* (and the opportunity equivalent) — repricing re-applies price list prices to lines, so a document without lines has nothing to reprice. If lines exist but a price still looks wrong after repricing, the issue is price list resolution, not the action — work through [a price looks wrong](/docs/sales/troubleshooting/). ## A header field won't change On opportunities, the partner account and branch are fixed at creation; on quotes, the account, partner account, branch, opportunity and asset are too. This is deliberate — downstream documents inherit them — so the fix for a wrong header is a new document with the right context, not an edit. ## The configurator shows nothing **Get Configurable Items** returns only lines whose item is a **package** — an ordinary item has nothing to configure. If the package line is listed but its component list comes back empty, the components exist but none apply *here*: components can be scoped to sale/service/purchase contexts and to partner accounts or account groups, so check the item's component definitions against this document's context and partner. See [product configurator](/docs/crm/product-configurator/). ## A demo won't book, or the slot is refused The demo booking flow reserves branch slot capacity when you confirm, and refuses with the specific reason: the selected time slot is inactive, the slot does not belong to the selected branch, or the item is not applicable for that slot. Pick a slot that matches the branch and item, or have an administrator review the branch's slot setup. A full slot means capacity for that date is consumed — choose another slot. ## No appointment slots are offered (preview) For the [appointment engine](/docs/crm/appointments/) (preview, off by default): slots only exist where the scheduling switch is on, an active slot template covers the branch and date (effective window, weekday capacity not 0), and the date is a working day — holidays and days outside the branch's business hours release nothing. A refused status change means the transition isn't legal from the current state or the appointment is terminal; a refused cancellation near the start time is the type's cancellation cutoff working as configured. ## A lead linked itself to the wrong account When a lead is saved without an account, a phone number that matches an existing account links it to that account and fills its blank name, contact and address details. If the match was wrong (shared or recycled numbers), correct the number or the account link on the lead **before** converting — conversion reuses the linked account. ## Related topics - [Leads](/docs/crm/leads/) - [Quotes](/docs/crm/quotes/) - [Appointments](/docs/crm/appointments/) - [Troubleshooting sales](/docs/sales/troubleshooting/) ---- # Approval processes: sign-off that gates records URL: https://xmatix.com/docs/customization/approvals/ Last reviewed: 2026-09-06 When a record needs a person's sign-off before it proceeds — a high-value order, a credit release, a price override — model it as an approval process. The process resolves a real approver for each step, notifies them, locks the record while the decision is pending, stamps the outcome onto the record, and leaves an audit trail of who decided what and when — everything an "override checkbox" cannot give you. This page builds a two-step approval end-to-end, shows every way a record enters it and every way approvers act on it (including on mobile), and explains how approval state gates what happens to the document next. ## Prerequisites - The approval-model capability (`setup.metadata.approval.manage`). Holders of this capability are also approval administrators at run time — they may act on any pending step, which matters for unblocking stuck requests. - The stored values of the entity's status field — outcome stamps are written as stored values, not display labels. - Whatever the steps will resolve approvers from: a record field holding a user (a manager or owner field), or the team or role that owns the decision. ## Procedure @[guided-image](_img/new-approval-process-dialog.png) ### Step 1 — Create the process Go to **Setup → Process Studio → Approvals** and choose **New** (the same list is reachable per entity under Design Studio → Entities → the entity → Logic → Approval Processes). Enter a reader-facing **Label** and stable internal **Name**, select the **Entity**, leave **Active** off, and set **Process Order** and **Allowed Submitters** — anyone with access to the record, the record owner only, members of a security role, or members of a team. After creating the shell, add the entry condition that decides which records qualify—for example, total amount above fifty thousand—and configure maker-checker (**require a separate approver**, which stops the submitter approving their own request), **lock record on submission**, whether the current approver may edit while the request is pending, and whether the submitter may recall. When several active processes exist for one entity, the first matching process by order claims the record, so compare neighboring orders and verify this process cannot shadow or be shadowed accidentally. ### Step 2 — Define the steps Add the steps in order. Each step names its approver: a **specific user**, a **user from a record field** (the classic "the requester's manager" — the field must hold a user), any member of a **role**, a **team**, or an approver the **submitter chooses** at submission. Per step you also decide whether one response completes it or every member must agree (unanimous), what a rejection does — end the request, or send it back to the previous step — and an optional step entry condition with a skip behavior, so a step like "finance review" engages only above a second threshold and is skipped cleanly below it. Steps can carry timeouts: after a set number of hours, auto-approve, auto-reject or escalate past the silent approver. ### Step 3 — Wire the outcomes to the record This is where approval state gates the document. On the process and its steps, configure **field updates** — partial updates applied on submission (status becomes pending approval), on a step's decision, and on the final approval, rejection, recall or revert (approved orders stamp approved; rejected ones return to draft). Add **tasks** where a decision should create follow-up work, **notifications** (with templates per event) so approvers and submitters hear about submissions and decisions, and follow-up **business rules** where a decision should run richer logic. With the lock while pending, the stamps close the loop: downstream steps — releasing, invoicing, a status transition guarded by a [business rule](/docs/customization/business-rules/) that requires the approved stamp — simply cannot happen until the sign-off exists. ### Step 4 — Activate Switch the process to active. There is no draft-version lifecycle here: active means live immediately, and edits to an active process are live immediately too — so build, review, then activate, and prefer editing during quiet hours on busy entities. ### Step 5 — Submit records into the process A record enters approval one of four ways. Interactively: the **Approval Panel** on the record form shows a submit button when the record is eligible — if the panel is missing, add the widget to the entity's [layout](/docs/customization/layouts/design-a-form-layout/). Automatically by the process itself: enable auto-submit on create or update, optionally with a condition, and matching saves submit with no further configuration. Declaratively: a business rule's request-approval action submits after a qualifying save. Or from a [workflow](/docs/customization/workflows/), whose submit step also waits for the decision so the flow can branch on the outcome. One rule spans all four: a record can have only one pending request at a time. ### Step 6 — Work the pending approvals Approvers act from two surfaces. The **Approvals** inbox page lists everything pending for the signed-in user — entity, record, step and age — with bulk approve and reject for high-volume queues. The record's Approval Panel shows the same request in context, with the full history timeline. The actions: **approve** and **reject** (with comments) for the current step's approver, their nominated delegate, a reassignee or an approval administrator; **reassign** to redirect the current step to another user; **recall** for the original submitter to withdraw a pending request; **revert** to roll back an already-approved request; and **comment** for remarks that change nothing but land in the trail. On **mobile**, the Approval Panel on the record form carries the same set — submit, approve or reject with remarks, recall, reassign, and the history — so a manager can clear approvals from the field. ### Step 7 — Verify the chain end-to-end Prove the entire chain with a disposable record over the threshold: submit as an allowed user, confirm one pending request, the expected lock and pending stamp, then act as each resolved approver and verify the timeline before advancing. Confirm final approval stamps and unlock behavior. Run negative probes as well: an under-threshold record is not eligible, an unauthorized submitter is refused, maker-checker blocks self-approval, and rejection or recall applies its configured effects. Capture the request identifiers and outcomes so support can distinguish configuration from user error later. ## Expected result Exactly one active process claims an eligible record, each step resolves to the intended approver population, and the record's lock, status stamps, notifications and history change at the configured moments. Ineligible, unauthorized and maker-checker cases fail safely, while final approval, rejection, recall and timeout paths leave an auditable terminal state. ## Common problems **Submission fails or the record is not eligible.** In order: a pending request already exists (one per record); no active process's entry condition matches — and a broken entry-condition expression fails *closed*, reporting not eligible rather than erroring; or the submitter violates the process's submitter restriction. Test the entry condition the way you test a rule condition. **The process is never selected.** A process with zero steps is never chosen, however good its entry condition. Also check process order — an earlier active process whose condition also passes claims the record first. **A step's approver cannot act or resolves to no one.** For field-based approvers, the record field must actually hold a user (an empty manager field resolves nobody); for team and role steps the actor must be an active member; maker-checker blocks the submitter even when they are a legitimate approver; and a rejection configured to "go back a step" on step one has nowhere to go — it degrades to a final rejection. **The decision succeeded but the stamp is missing.** Outcome effects are post-decision and best-effort: the field update goes through the normal save pipeline, and an active business rule can reject the stamp itself. Check the audit trail for the stamping save and the entity's rule set — the approval is intact; the follow-up write was blocked. ## Common questions ### Why not just add an "approved" checkbox instead? Because a checkbox records nothing: no resolved approver, no notification, no lock while pending, no timestamp, no reason — and anyone with edit rights can tick it. The approval process provides all of those for roughly the same setup effort. If you deliberately choose a checkbox as a lightweight exception, lock it down with field-level security and treat it as the exception, not the pattern; the reasoning is laid out in [the customization ladder](/docs/concepts/customization-ladder/). ### Can anyone edit the record while it is pending? Not when lock-on-submission is enabled — that is its purpose. Two exemptions exist by design: approval administrators can always edit, and the current approver can when the process explicitly allows approver edits during approval. Everyone else waits for the decision, which is what makes the eventual stamp trustworthy: the record the approver saw is the record that was approved. ### What if two approval processes both match a record? The first active process by process order whose entry condition passes wins, and only it — a record never runs two processes at once, and a record with a pending request cannot be submitted again anywhere. Design overlapping processes so their entry conditions partition the records (by amount band, by record type), and use process order as the tiebreaker for the overlap you cannot eliminate. ## Related topics - [Business rules](/docs/customization/business-rules/) - [Build a workflow](/docs/customization/workflows/) - [Design a form layout](/docs/customization/layouts/design-a-form-layout/) - [The customization ladder](/docs/concepts/customization-ladder/) ---- # Your first automation script URL: https://xmatix.com/docs/customization/automation-scripts/quickstart/ Last reviewed: 2026-09-06 An automation script is server-side C# the platform runs in a sandbox — the top working rung of [the customization ladder](/docs/concepts/customization-ladder/), for logic the declarative tools cannot express: calculations across many records, calls to external APIs, integration glue, and custom behavior behind buttons. A script does nothing until it is *bound* — to a phase of an entity's save lifecycle, or to a server action a button invokes — and every execution is recorded with its inputs, logs and outcome, which makes scripts unusually debuggable for code. This quickstart writes a small validation script, binds it, tests it against the real pipeline and shows the iteration loop. ## Prerequisites - The scripts capability (`setup.automation.scripts.manage`). - Confirmation that a script is the right rung — a [business rule](/docs/customization/business-rules/) that can do the job beats a script, because any administrator can read and adjust it. Scripts earn their keep on cross-record logic, external calls and button behavior. - Basic C#. Scripts are real code: version them thoughtfully, name them for what they do, and write the description field as if a stranger will read it in a year — because one will. ## Procedure @[guided-image](_img/new-automation-script-dialog.png) ### Step 1 — Understand what a script can reach Everything a script touches goes through one ambient context object, `Ctx`, whose surfaces are the sandbox's entire contract with the platform: | Surface | What it gives you | | --- | --- | | `Ctx.Records` | The record(s) in the current dispatch, with old values for comparison | | `Ctx.Data` | Read and write records of any entity — queries, counts, creates, updates, bulk operations | | `Ctx.Meta` | Read the metadata model: entities, fields, relations, views, actions | | `Ctx.Http` | Outbound HTTP to external APIs | | `Ctx.Messaging`, `Ctx.Email` | Send templated messages and email through the platform's channels | | `Ctx.Jobs`, `Ctx.Queue` | Enqueue background jobs (with idempotency keys and delays) and queue messages | | `Ctx.Approval` | Check eligibility and submit or act on approval requests | | `Ctx.Secrets` | Read stored secrets — API keys never belong in a script body | | `Ctx.Log`, `Ctx.Step`, `Ctx.Cancel` | Trace what happened, and block the save with a validation message | There are more (`Ctx.Files`, `Ctx.Cache`, `Ctx.Settings`, `Ctx.User`, `Ctx.Tenant`, `Ctx.Activities`, `Ctx.Notifications`, `Ctx.Integration`, `Ctx.Ai`). The authoritative, always-current reference is inside the product: the **Readme** tab of the script editor documents every surface, method and limit — treat this page as the map and that tab as the manual. The sandbox enforces boundaries: a time budget of **10 seconds** for synchronous runs (lifecycle bindings that run inline, and server actions) and **60 seconds** for asynchronous runs on the worker, a body-size cap of 100,000 characters, and blocked namespaces (reflection, file system, raw networking and threading) — long work belongs in asynchronous bindings or queued jobs. ### Step 2 — Create the script Go to **Setup → Process Studio → Scripts** and choose **New**. The dialog asks for four things: **Name** (required — a stable, code-friendly identifier used wherever the script is referenced by name; do not rename it casually), **Label** (required — the name administrators see in the catalogue), **Description** (state the trigger, business effect, owner and failure expectation) and the **Disabled** switch. Keep **Disabled** on while the script is incomplete, then save the shell. Verify it appears in the catalogue with no active version and no enabled binding: those two absences make the initial object inert while you author safely. Opening the script shows a statistics bar (Status, Active Version, Versions, Bindings, Updated) and the editor with its tabs: **Script**, **Versions**, **Bindings**, **Agent Tool**, **Runs** and **Readme**. ### Step 3 — Write the first version On the **Script** tab, write the body. A minimal validation script: ``` var order = (Order)Ctx.Records[0].Entity; if (order.Total <= 0) Ctx.Cancel("Total must be positive.", "Total"); ``` Field names in script code are C# properties on typed entities; `Ctx.Cancel(message, fieldName)` records a validation failure against a field and blocks the save. Saving compiles the body and reports diagnostics; a version that fails to compile is saved but never activated, so fix and save until it compiles clean. Versions accumulate on the **Versions** tab — every save is a version, and each row offers **Load version into editor**, **Activate version** (the active one is marked *Already active*) and **Delete version**. The *Active Version* in the statistics bar is the only one the runtime executes. ### Step 4 — Bind it to a trigger On the **Bindings** tab, add a binding. A binding has a **Name**, an **Entity** and a **Type** — *Lifecycle* or *Server Action*. For lifecycle behavior, pick the **Lifecycle Phase** and the **Change Kinds**. The phases run in save order: **Load Defaults** (inserts only; populates fields before validation; cannot block), **Pre-Validate** (inserts and updates; the defaulting slot that also covers edits; cannot block), **Validate** (cancel here to block the save with a message), **Before Save** (immediately before the row is written; can still block), **Before Delete** (can block the delete), **After Save** and **After Delete** (after the row is written, while the transaction may still be open — a failure here can roll the save back). Change kinds narrow the trigger to *Insert*, *Update*, *Delete* or any mix. For button behavior, choose type *Server Action* and pick the **Entity Action** instead; the script then reads `Ctx.ActionName` and `Ctx.ActionArgs`. Two fields place the binding in the phase. **Sequence** says where it runs relative to everything else in the same phase — platform handlers, domain code, business rules and other scripts; blank means last in the phase, the suggested range for your own steps is 10,000–999,999, and the entity's Execution Plan shows where a number lands. **Order** only breaks ties between bindings that share the same Sequence. The **Run Async** switch moves the run to the worker with the longer time budget — external HTTP calls belong in asynchronous After Save bindings, never blocking a save on a partner API (and note an asynchronous script cannot cancel the save; it already happened). The binding's own **Disabled** switch stops just this trigger. For our validation: phase Validate, change kinds Insert and Update, Run Async off. **The moment an enabled binding exists, the script is live for that trigger.** ### Step 5 — Test against the real pipeline Use the test panel at the top of the **Runs** tab to fire a test dispatch: choose the entity, hand-write a sample record for an insert simulation or point at an existing record by id for an update, pick the phase and change kind, and press **Run Test**. Two things to internalize about testing here. First, a test only executes your script if an enabled binding matches the tested entity, phase and change kind — no matching binding means the test reports that nothing ran, which is itself the diagnosis. Second, the test dispatches the *real* pipeline: every other enabled script on the same trigger runs too, and side effects are real — data writes commit, messages send. "Test" means "fire without saving a record", not "dry run" — test mutating scripts against disposable records. ### Step 6 — Read the run history Every failure and every test lands on the **Runs** tab with a status of *Pending*, *Running*, *Succeeded*, *Failed* or *Cancelled*. Opening a run shows the entity, phase, start and completion times, duration, mode (sync or async), the error class and message, the validation failures your `Ctx.Cancel` calls emitted, the log and step trace, and snapshots of the exact record and old values the run saw. A run that ended *Cancelled* is a script that blocked the save on purpose — for a validation script that is the success case, so read the validation failures before "fixing" anything. The run drawer's **Copy as Test Input** turns a production failure into a reproducible test in one click, and **Re-run** replays a failed run against the current version. ### Step 7 — Iterate safely on a live script Once a script is bound and live, reproduce the issue from **Runs**, make the smallest change, save it as a new version and confirm compilation before activating that version deliberately. On a busy trigger, disable the one binding while testing rather than disabling unrelated behavior, then re-enable it and observe a fresh real run. The script-level switch stops every binding; the binding switch stops one trigger. Record which switch you used and verify the catalogue and binding status agree after recovery. ## Expected result The script has a cleanly compiled active version and only the intended enabled binding. A matching disposable event produces a run with the expected logs, steps and outcome; a non-matching event produces no side effect. Validation cancellation is reported as intentional, while unexpected failures remain reproducible from captured run input. ## Common problems **The script never runs.** In order: the script is disabled; every binding is disabled; no binding matches the entity, phase and change kind of the event; or the script has no compiled active version. A binding has no condition filter — if you need the script to apply only to some records, test the condition in code and return early. **The save became slow, or runs fail at the time limit.** A synchronous binding is doing slow work — usually external HTTP. Move the work to an asynchronous After Save binding or enqueue a job; a run failing at almost exactly the time budget is a timeout, not a logic error. **The script triggers itself.** An After Save script that updates its own record dispatches a new update — which matches its own binding. Narrow the change kinds (insert only), or guard in code against re-entry. **A button's action returns success but nothing happens.** A server action with no bound script (and no built-in handler) succeeds silently by design. Check that the binding points at the right action and that the action's name matches — the dispatch is keyed on the name, so renaming the action breaks the wiring. **A job enqueued mid-save throws.** Queueing from inside the save transaction is rejected. Enqueue from an After Save asynchronous binding or a server action instead. ## Common questions ### Where is the full API documentation? Inside the product: open any script and read the **Readme** tab. It is the complete, versioned reference for every `Ctx` surface — data access, metadata, HTTP, messaging, jobs, approvals, secrets, files and the rest — with method signatures, transaction rules and sandbox limits, and it always matches the runtime you are actually on. This quickstart deliberately stays at the map level. ### When is a script wrong even though it would work? Whenever a lower rung expresses the same requirement. Single-record save logic — defaults, conditional requirements, blocking with a message, status guards — is [business-rule](/docs/customization/business-rules/) territory: same server-side enforcement, readable and adjustable by any administrator. Multi-step orchestration over time is a [workflow](/docs/customization/workflows/); human sign-off is an [approval process](/docs/customization/approvals/). A script is the right answer when the logic crosses records, calls out, or sits behind a button doing genuinely custom work. ### Can Sense AI call my script? Yes, through the **Agent Tool** tab — but as a different shape of script. Turn on **Publish as an agent tool** (off by default; nothing is exposed until you do), write the **Description shown to the model** like tool documentation, declare **Parameters (JSON)** as an array of `{ "name", "type", "description" }`, optionally set a **Required capability** the calling user must hold (the tool is hidden and refused without it; `data.script.read` additionally grants the body read-only data access), and keep the **Timeout (s)** short (default 5). A tool call has no records and no lifecycle phase, so the body gets `Input.` for its parameters and must `return` a value — `Ctx` is unavailable, and publishing refuses a body that references it. Agents invoke the tool approval-gated, so a lifecycle script and an agent tool are two separate scripts, never one. ### Can I run a script on a schedule? Not directly — there is no cron trigger for scripts. Recurring work runs through the vehicles built for it: scheduled integration flows for data movement, workflow waits for in-process timing, and the platform job scheduler for registered job types. A script can participate — expose it as a server action and have the scheduled vehicle invoke it, or enqueue jobs from event-driven bindings — but a promise of "the script runs nightly by itself" would be false, so design around events instead. ## Related topics - [The customization ladder](/docs/concepts/customization-ladder/) - [Business rules](/docs/customization/business-rules/) - [Build a workflow](/docs/customization/workflows/) - [Automation on the xMatix platform](/platform/automation/) ---- # Business rules: automating the save URL: https://xmatix.com/docs/customization/business-rules/ Last reviewed: 2026-09-06 A business rule is declarative save-time automation: when a record of one entity is saved and a condition holds, the rule's actions run — defaulting or deriving values, making fields required or read-only, locking records, blocking the save with a message, guarding status transitions, or firing post-save follow-ups like notifications. Rules are configured, not coded, and they run server-side inside the save pipeline for every write path — forms, API, imports, integrations alike. This page builds a rule end-to-end with the discipline that keeps live enforcement trustworthy: draft it inactive, activate, verify immediately in the Test Runner, and deactivate anything you cannot prove. ## Prerequisites - The business-rules capability (`setup.automation.businessrules.manage`). - The stored values of any picklist the rule will reference — conditions compare against stored values, not display labels, and a condition comparing against a value outside the field's domain can never fire. - Confirmation that a rule is the right rung: field-level asks belong on the field, human sign-off belongs in an [approval process](/docs/customization/approvals/), and cross-record writes or external calls belong in an [automation script](/docs/customization/automation-scripts/quickstart/). See [the customization ladder](/docs/concepts/customization-ladder/). ## Procedure @[guided-image](_img/new-business-rule-dialog.png) ### Step 1 — Create the rule, inactive Go to **Setup → Process Studio → Business Rules** and choose **New**. The dialog holds the rule's identity and its place in the save: | Field | What it does | | --- | --- | | **Name** (required), **Label**, **Description** | A stable name, a clear label and an intent-focused description — write the description for the administrator who finds this rule in a year. | | **Entity** (required) | The one record type whose saves the rule evaluates. | | **Active** | Off for a new rule. Keep it off until the condition and actions exist. | | **Sequence** | Where the rule runs relative to everything else in the same phase — platform handlers, domain code and automation scripts included. Blank keeps the default: immediately after the platform's validation and ahead of every domain handler. Suggested range for your own steps: 10,000–999,999. Rules sharing a Sequence are evaluated together, so Stop on False and Priority apply among them. | | **Order** | Lower numbers run first among rules that share the same Sequence. It cannot move a rule past a handler or a script — use Sequence for that. | | **Priority** | Lower numbers win when two Set Value actions target the same field. | | **Stop on False** | If this rule's condition evaluates to false, the remaining rules for the trigger are skipped. | Save the shell, then open the rule. The detail page shows a statistics bar (Entity, Status, Actions, Order, Priority) and three tabs — **Condition**, **Actions** and **Test Runner**. The trigger is chosen on the **Condition** tab under **Triggers** (one or more): *OnSave* (every insert and update), *OnInsert*, *OnUpdate*, *OnDelete* (only Block Save and Show Message have effect), *OnFieldChange* (combine with OnSave or OnUpdate and list the **Tracked Fields**; empty means any field), *OnPhaseTransition* (a status field moving between specific values, written as a **Phase Transition Directive** such as `Status;from=Draft;to=Submitted` — an empty side is a wildcard, and inserts never fire it), *OnSavedChanges* (after commit — required for the bridge actions below), *OnApprovalDecision* (after an approval step is approved, rejected, recalled or reverted; the condition can read `approvalDecision`, `approvalStepOrder` and `approvalComments`) and *OnSchedule* (evaluated hourly against a candidate filter; only meaningful with a Raise Nudge action). Compare its Sequence and Order with every active rule on the entity and verify the new row remains inactive: an unfinished active rule becomes live enforcement immediately. ### Step 2 — Write the condition On the rule's **Condition** tab, write the **Condition Expression** that must hold for the actions to run — for example `Status == "Cancelled"` or `DiscountPercent > 20 && CustomerTier != "Manager"`. An empty condition is always true. Conditions read the incoming record's fields by name, can navigate lookups (`Account.Region`, up to five hops), and can aggregate over the record's own child collections (`SUM(OrderLines, Amount) > 10000`, also `Avg`, `Min`, `Max`, `Count` and `Any`). Two boundaries to respect: the condition sees the *new* record only — "was the status previously X" is the transition trigger's job, not the condition's — and quotes matter, because an unquoted word is read as a field reference, not a text value. The full grammar is on the [expressions page](/docs/customization/expressions/). ### Step 3 — Add the actions On the **Actions** tab, add what the rule does, ordered within the rule: | Action family | What it does | Runs | | --- | --- | --- | | Block Save / Show Message | Rejects the save with your message (a literal or an expression); severity *Error* blocks, *Warning* and *Info* display without blocking | During the save | | Set Value / Copy From Field / Format Value / Lookup Value | Writes a field on the record being saved — computed (static, formula or from a child), copied from a related record, reformatted, or fetched by key; **Overwrite Existing** decides whether a filled field is replaced | During the save | | Set Required / Set Read-Only / Lock Record / Enforce Unique | Makes fields conditionally mandatory or uneditable, locks the whole record except the listed **Editable Exceptions**, or rejects a save whose **Unique Key Fields** collide with another record | During the save | | Assignment | Sets the owner or assignee of the record | During the save | | Send Message / Create Activity / Create Record / Enqueue Job / Request Approval / Invoke Automation Script / Raise Event / Raise Nudge | Follow-ups: notify by email or in-app, open a task, create a related record of any entity, queue background work (with a delay and an idempotency key), submit into an approval process, dispatch a server-action-bound automation script, publish a named event, or raise a Sense AI nudge | After the save commits | The split in the last column is structural: follow-up actions run only after a successful commit, so the rule's trigger must include *OnSavedChanges* for them to fire — on a save-phase-only rule they are skipped, and the Invoke Automation Script and Raise Event editors say so. And because after-save rules run on *every* matching commit with no change detection, scope their conditions tightly or a notification re-sends each time the record is edited. ### Step 4 — Activate, then verify immediately in the Test Runner Activate the rule, then open its **Test Runner** tab straight away — the engine evaluates the entity's *active* rules, so testing and activation travel together, and the discipline is to verify in the same sitting. Pick an existing record or paste sample JSON, run, and read the result panels: **Block Reasons**, **Entity Messages**, **Field States** (required and read-only hints) and the **Diagnostics** list. Run two probes: a record that should match (expect the block, the derived value, or the required flag) and one that should not (expect nothing). Read the diagnostics on every run — a condition that fails to parse does not error at save time, it silently disables the rule, and the diagnostics are the only place that failure is visible. Note the runner's limits: it exercises the whole active rule set for the entity, transition-triggered rules never match in it (they need real before-and-after values), and read-only and lock actions show as field-state hints rather than hard blocks. ### Step 5 — Verify transition and lock rules with a throwaway record For anything the Test Runner cannot exercise — status-transition guards, record locks, field-change gating — prove it live: create a disposable record, drive it into the guarded state, attempt the forbidden edit (expect your message), then attempt an allowed one (expect success), and delete the record. If you cannot verify a rule's behavior, deactivate it and say so — never leave unverified enforcement live. ### Step 6 — Batch future edits Every edit to an active rule is a live change. Before rework, preserve the last known condition, actions and test inputs; then deactivate where the business permits, batch the edits and run the same matching and non-matching probes. For high-impact validation, also repeat the live throwaway-record test. Finish by confirming Active, sequence, priority and **Stop on False** in the list so an otherwise-correct rule is not left in the wrong evaluation position. ## Expected result The active rule parses without diagnostics, matches only the intended records and applies ordered actions exactly once in the correct save phase. Matching and non-matching Test Runner probes behave differently as designed, and transition, lock or field-change rules also pass a disposable-record test through the real save pipeline. ## Common problems **The rule never fires.** Check in order: it is active; the diagnostics show no parse failure (a broken condition is silent); every picklist value in the condition is a stored value inside the field's actual domain; the trigger matches the event you tested (a field-change rule needs the field to actually change — saving the same value does not count); and any record-type scoping matches the test record. **A notification sends repeatedly.** After-save rules have no change detection — they fire on every commit where the condition holds. Tighten the condition to the transition moment, or move the send behind a queued job with an idempotency key so repeats collapse. **A status still escapes its terminal state.** The lock was approximated with a read-only action under a condition like `Status == "Closed"` — but the condition evaluates the *new* record, so an edit changing Closed to Draft sails through. Terminal states are the transition trigger's job: block leaving the state, and optionally pair a record lock (exempting the status field) for the other fields. **Two rules fight over one field.** Value-setting actions run in order within a rule and by rule order across rules; when two rules write the same field, the ordering decides the survivor. Consolidate the logic into one rule where possible. And remember rules are not the last word: [scripts run later in the pipeline](/docs/concepts/execution-order/) and can overwrite what a rule set. ## Common questions ### When should this be a validation instead of a rule? When the whole requirement is "check this record and show a message" — a format, a range, a mandatory combination — the lighter entity validation does the same server-side blocking with less machinery. Reach for a rule when you need what validations lack: triggers (insert-only, field-change, transitions), child-record aggregates, conditionally required or read-only fields, derived values, or post-save follow-ups. See [entity behavior](/docs/customization/entity-behavior/). ### Can a business rule call another system? Not directly — rules are deliberately self-contained: they evaluate and act on the record being saved and cannot make external calls. That boundary is what makes them safe inside every save. When a save must reach another system, hand off after the commit: an **Invoke Automation Script** action on an *OnSavedChanges* trigger dispatches a server-action-bound [automation script](/docs/customization/automation-scripts/quickstart/) by action name, or use an integration flow when you need connector-grade retry and monitoring. ### Can a rule hide a field? No — there is no hide action, on purpose. Rules control values, requiredness, editability and blocking; *visibility* is a layout concern, handled in the [form designer](/docs/customization/layouts/design-a-form-layout/). Keeping the two apart means a hidden field is still enforced correctly: a rule that requires it keeps requiring it on every write path, whether or not any form shows it. ### The unblock condition is "unless a manager allows it" — checkbox or approval? Approval. An editable override checkbox records no approver, no timestamp and no reason, and anyone with edit rights can tick it. Model the sign-off as an [approval process](/docs/customization/approvals/) whose final approval stamps a field, and add "and not yet approved" to the rule's block condition — you get a resolved approver, notifications, record locking while pending and an audit trail for one extra step. ## Related topics - [What runs when you save a record](/docs/concepts/execution-order/) - [The customization ladder](/docs/concepts/customization-ladder/) - [Expressions](/docs/customization/expressions/) - [Approval processes](/docs/customization/approvals/) ---- # Create a custom entity URL: https://xmatix.com/docs/customization/data-model/create-an-entity/ Last reviewed: 2026-08-31 A new business object in xMatix is a sequence, not a single click: the entity itself, then its fields and picklists, then a list view, a form layout, and finally a place in an app's navigation. Each step is quick, but none is optional — an entity created and abandoned after step one renders an empty list page and appears in no menu. This walkthrough builds a working entity end-to-end, using a warranty-claim tracker as the running example, and calls out the traps: names you cannot change later, types you cannot change once data exists, and the app placement everyone forgets. ## Prerequisites - The model-management capability (`setup.metadata.model.manage`) on one of your profiles; picklist edits also need `setup.metadata.picklists.manage`, and the app-placement step needs `setup.metadata.apps.manage`. - A sketch of the fields and their types. Types are effectively permanent once records exist, so this five-minute sketch is the highest-leverage part of the whole procedure. - If several kinds of this object need different forms or rules, decide the record types now — scoping is easier to build in than to retrofit. ## Procedure ### Step 1 — Create the entity Go to **Setup → Design Studio → Entities** and use **New**. In the New Metadata Entity dialog, give it a Label ("Warranty Claim"), an Internal Name (`WarrantyClaim` — ASCII letters and digits only, no underscores), a Collection Label ("Warranty Claims") and a Description, and pick a color and icon so the entity is recognizable in navigation. The behavior toggles (create, edit, delete, search, list view, audit) default sensibly — leave auditing on for anything with business consequence. On save, the entity is ready immediately: there is no publish step. Note that the platform appends a suffix to custom internal names, so the stored name differs from what you typed — anything that addresses the entity by name, including API integrations, must use the stored name shown on the entity after creation. @[guided-image](_img/new-entity-dialog.png) ### Step 2 — Add the fields Open the entity and go to **Schema → Fields**, then **New** per field: Label, Internal Name, Field Type, plus the per-type settings (length for text, precision and scale for numbers) and behavior toggles (Required, Unique, Audited, Active). System fields — id, name, owner, record type, created and modified stamps — already exist; you add only the business attributes. Three constraints to respect: pick each type as if you cannot change it, because once the entity holds data you cannot; making a field required later, after data exists, also demands a default value in the same change; and unique can only be set while the entity is empty. Skip lookup fields here — they come from relations in the next step. ### Step 3 — Define picklist values For each choice field, open the field's row menu and choose **Manage PickList Values**. Add the options — each has a stored value and a display label — then drag to order them, mark one default if creation should preselect it, and set colors or icons where the value benefits from being scannable in lists. Get the stored values right the first time: labels can change forever, but changing a stored value after records hold it orphans those records. If the option set is shared with other entities, create it under **Setup → Design Studio → Global Picklists** instead and bind the field to the global list. ### Step 4 — Link to other entities Where the new entity references another — a warranty claim belongs to an account and an item — create relations under **Schema → Relations** with **New**. Choose the Related Entity, and accept or adjust the generated Lookup Field Name and labels; saving the relation creates the lookup field on your entity automatically (this is the only way lookups are made). Leave Cascade Delete off unless the child records genuinely cannot outlive the parent, and mark the relation required only when a claim without an account is meaningless. ### Step 5 — Create a list view Under **Experience → Views**, use **New** to define the entity's default list: a name and label, an optional filter condition and sort order, then the row action **Columns** to pick and order the columns users see. Create the columns explicitly — a view with none falls back to generic columns, which reads as broken to users. Mark the view as the default. Additional filtered views ("Open Claims", "My Claims") are cheap and can come later. ### Step 6 — Design the layouts Under **Experience → Layouts**, use **New** to create a layout row (Label, Internal Name, Description, layout type), then open it with **Web Design** to lay out sections and fields in the visual designer. Create two: a **Create** layout for the new-record form and a **View** layout for the record page, and mark each the default of its type. If you skip the Create layout, the create dialog falls back to whatever layout it can find — functional, but rarely the form you want. The designer itself, record-type variants and mobile layouts are covered in [design a form layout](/docs/customization/layouts/design-a-form-layout/). ### Step 7 — Place the entity in an app A new entity appears in no app menu by itself. Go to **Setup → Design Studio → Apps**, open the app that should carry it, and use **Manage Items** to add the entity to the app's navigation at the position you want. Users reach records through apps, so until this step the entity is reachable only by administrators through Setup — the most commonly skipped step in the sequence. ### Step 8 — Verify as a user Open the app as a user would, find the entity in navigation, and create a record: the Create layout should render your sections, picklists should offer the right options in the right order, lookups should resolve, and the saved record should appear in the default view with the columns you chose. Confirm with a user holding a normal (non-administrator) profile too — entity access is granted per profile, and a missing grant shows up as the entity simply not existing for that user; see the [administration guide](/docs/administration/) for profile access. **Expected result:** an authorized user can find the entity in the intended app, create a record with the designed form, reopen it with the View layout, and retrieve it from the configured list view. ## Common problems **The entity's list page is empty and the form is bare.** The entity exists but the follow-through is missing — fields, a view with columns, and layouts are separate steps (2, 5 and 6). A bare entity is valid; it just has nothing to show. **The entity is missing from the app menu.** Either step 7 was skipped, or the viewing user's profile has no read access to the entity — navigation only shows entities the user can read. Check the app's items first, then the profile. **An API caller gets "entity not found".** Almost always the caller is using the internal name as typed rather than the suffixed stored name — check the entity's stored name and use exactly that. Caches can also lag a few minutes after creation; retry before assuming anything is wrong. If a correct name still fails much later, escalate to support rather than re-creating the entity — re-creating makes the problem worse. **A field's type or constraint change is rejected.** The entity has data. Type changes are blocked outright; required needs a default supplied in the same change; unique is refused entirely. For a type change, create a new field, migrate the values, and retire the old one. ## Common questions ### When can users start entering data? As soon as steps 1–2 are done, technically — there is no publish or deployment step, and the data API accepts records the moment the entity exists. In practice, wait until the view, layout and app placement (steps 5–7) are in place, because until then the experience is fallback columns and fallback forms. Access matters too: users see the entity only once their profiles grant it. ### Why is the stored name different from the name I typed? The platform suffixes custom internal names so they can never collide with system entities and fields — including ones added in future product updates. The label users see is unaffected. The practical rule: after creating anything custom, read the stored name off the entity or field and use that everywhere a name is required, especially in integrations and formulas. ### Should I set up record types now or later? Now, if you already know the variants — a record type is cheap to create (**Schema → Record Types**), and layouts, validations and views are easier to author scoped from the start than to split later. Later is fine too: unscoped metadata keeps applying to all types, so adding a record type is additive. What to avoid is modeling variants as separate entities when they are really one object in two shapes — merging entities later is genuinely painful. ## Related topics - [The data model](/docs/customization/data-model/) - [Entity behavior](/docs/customization/entity-behavior/) - [Design a form layout](/docs/customization/layouts/design-a-form-layout/) - [The xMatix app builder](/platform/app-builder/) ---- # The data model: entities, fields, picklists, relations and record types URL: https://xmatix.com/docs/customization/data-model/ Last reviewed: 2026-09-01 ## Read the entity model workspace @[guided-image](_img/data-model-overview.png) Design Studio's Entities register is the entry point to the operational data model. The left navigation separates entities from app placement, packages and global picklists; the header New action starts a custom entity; and the register connects each entity to its label, custom/system ownership, fields, relations, views, record types and sorting/grouping. Those columns are dependency signals: they show how far a model object reaches before anyone edits or retires it. The screenshot uses visible synthetic demo2 data so readers can follow realistic rows, values and controls together; production exports and screenshots must still remain inside authorized channels. Use search and filters to locate the exact internal object, distinguish its immutable name from its changeable label, and inspect schema dependencies before making a change. A model edit is live as soon as it is saved, so prefer additive or reversible changes, test record-type scope, and deactivate before deleting whenever existing layouts, rules or integrations may still depend on the definition. Every screen in xMatix renders data whose shape you control. An *entity* describes a business object — its fields, its option lists, its links to other entities, and its variants — and the platform generates the storage, the API, the list pages and the forms from that description. There is no schema migration to write and no publish step to wait for: a custom entity is usable the moment you create it, because its storage is provisioned in advance. This page explains the five building blocks and the rules — naming, typing, lifecycle — that decide whether a model change is safe. ## The five building blocks | Block | What it is | Where it lives | | --- | --- | --- | | Entity | A business object: label, behavior toggles (create/edit/delete, search, audit), color and icon | **Setup → Design Studio → Entities** | | Field | One attribute of the entity, with a type and constraints (required, unique, audited, active) | Entity → **Schema → Fields** | | Picklist | The option domain of a choice field — local to one field, or a global list shared by many | Field row → **Manage PickList Values**; shared lists under **Setup → Design Studio → Global Picklists** | | Relation | A link to another entity; creating it generates the lookup field for you | Entity → **Schema → Relations** | | Record type | A named variant of one entity that scopes layouts, validations, actions, views, lookup filters and field mappings | Entity → **Schema → Record Types** | The entity editor groups everything about one entity into four tab groups: **Overview**, **Schema** (Fields, Record Types, Field Mappings, Lookup Filters, Relations, Field Dependencies), **Logic** (Validations, Actions, Approval Processes) and **Experience** (Views, Layouts, Email Templates). Schema is this page's territory; the Logic and Experience surfaces are covered in [entity behavior](/docs/customization/entity-behavior/) and [form layouts](/docs/customization/layouts/design-a-form-layout/). ## System entities and custom entities The platform ships with system entities — orders, accounts, items and the rest of the application modules. System entities and system fields are read-only in your tenant: you cannot edit or delete them, and that is deliberate, because product updates must never have to merge with tenant changes. You extend them instead — add custom fields, validations, views and layouts alongside the shipped ones. Custom entities are yours entirely: created in the same editor, equal citizens of the data API, reporting and mobile. ## Names and labels Every entity and field has two names, and they age very differently. The **label** is display text — change it whenever you like, per language if needed, and nothing breaks. The **internal name** is the identity that layouts, views, filters, formulas, rules and integrations reference literally, and it is effectively permanent: treat renaming it as off the table. Custom internal names take ASCII letters and digits only — no underscores — and the platform appends a suffix to the name you type, so the stored name is not exactly what you entered; anything that addresses the field or entity by name (including API callers) must use the stored name. When someone asks for a "rename", they almost always mean the label. ## Fields and types Fields cover the usual range — text in three lengths, numbers, decimal, currency, percent, date, date-and-time, time, yes/no, choice (single and multiple), lookup, address, geolocation, binary content and calculated fields for same-record math. Two typing rules matter more than the catalog: - **Choose the type up front.** A field's type cannot change once the entity holds data — the platform rejects the change rather than risk the stored values. The escape is a new field plus a data migration, so a minute of thought at creation saves an afternoon later. - **Constraints interact with existing data.** Making a field required on an entity that already has records also demands a default value in the same change, so old rows stay saveable. Making a field unique is only allowed while the entity is empty; on a populated entity, enforce uniqueness with a validation or business rule instead. Two things that look like field types are not. A lookup is never created directly — you create a *relation* and the lookup field is generated from it. And rollups over child records (sum of line amounts, count of open tasks) are not a field type: calculated fields do same-record math only, and cross-record aggregation is a [business-rule](/docs/customization/business-rules/) job. ## Picklists: local and global A choice field's options are its picklist. Each option has a stored value and a display label — the same label/name split as fields, with the same consequence: relabel freely, but never change the stored value of an option that records already hold, or those records are orphaned on a value with no label. Options can be reordered, colored, given icons, marked default (one per list) and hidden or retired. When several fields — often on several entities — should share one option set, create a **global picklist** and bind the fields to it. One edit then updates every bound field, which is exactly the power and the risk: retiring a global value hits every entity that uses the list. Picklist options cannot vary by record type; if two record types genuinely need different options, use separate fields or drive the narrowing with a field dependency or business rule. ## Relations A relation links two entities and generates the machinery on both sides: a lookup field on the owning entity (pick an account on an order) and a child collection on the related one (the account's orders, shown as a related list). You choose the lookup's name and label, whether it is required, and whether deleting the parent cascades to the children — leave cascade off unless the children genuinely cannot exist without the parent. Related-record behavior built on top of relations — auto-filling fields from the looked-up record, restricting what the picker offers — lives in [entity behavior](/docs/customization/entity-behavior/). ## Record types Record types make one entity serve several shapes of the same object — a retail order and a service order, a corporate and an individual account — without duplicating the entity. Each record carries its record type; layouts, validations, actions, views, lookup filters and field mappings can be scoped to one type, and unscoped metadata applies to all. Exactly one type is the default, and records created without an explicit type get it. The scoping cuts both ways: metadata scoped to type A is invisible to type B, which is the first thing to check when a validation or layout "isn't applying". ## Changing and retiring model surface Model changes are live changes, so the platform biases you toward reversible ones. Deactivating a field, view, validation or picklist value takes it out of use while keeping the definition and the data; that is the right first move for anything users might still depend on. Deleting is soft — the row disappears from the model — but it performs no dependency check and never migrates data: a deleted field's values are simply stranded, and layouts, views and rules that referenced the name are left pointing at nothing. Before deleting anything, inventory what references it, remove those references, then delete children before parents. When in doubt, deactivate and revisit. ## Common questions ### Is there a publish or deploy step after changing the model? No. Custom entities and fields are usable immediately — storage is pre-provisioned, so a new entity is ready the moment it is created, and the data API, list pages and forms pick the change up straight away. What a bare entity still needs is content around it: fields, a view, a layout and a place in an app's navigation, which is why [creating an entity end-to-end](/docs/customization/data-model/create-an-entity/) is a sequence of steps rather than one. ### Can I change a field's type after users have entered data? No — the platform rejects a type change on a field whose entity already holds data, because coercing stored values is where data quietly corrupts. The working pattern is: create a new field of the right type, migrate the values across, repoint layouts and views, and retire the old field. On an empty entity, type changes are simply edits — one more reason to model deliberately before go-live. ### Should I delete a field or deactivate it? Deactivate, almost always. Deactivation is reversible, keeps the data, and immediately stops the field appearing where it is not wanted. Delete only when you have checked every dependent — layouts, view columns, validations, mappings, filters, rules and integrations reference fields by name and are not checked for you — and accepted that the field's data is not coming back. The same logic applies to picklist values: retire rather than delete anything records already hold. ### Can different record types have different picklist options? Not directly — picklist options are defined per field, not per record type. When one type should see a narrower set, either give each type its own field (scoped onto that type's layout), or keep one field and narrow the offered options with a field dependency or enforce the constraint with a business rule. See [entity behavior](/docs/customization/entity-behavior/) for field dependencies. ## Related topics - [Create a custom entity](/docs/customization/data-model/create-an-entity/) - [Entity behavior](/docs/customization/entity-behavior/) - [Design a form layout](/docs/customization/layouts/design-a-form-layout/) - [The customization ladder](/docs/concepts/customization-ladder/) ---- # Entity behavior: views, validations, actions, mappings, filters and dependencies URL: https://xmatix.com/docs/customization/entity-behavior/ Last reviewed: 2026-08-15 Beyond its fields, every xMatix entity carries six declarative behavior surfaces: saved list **views**, save-blocking **validations**, **action** buttons, create-time **field mappings**, picker-restricting **lookup filters** and dependent-picklist **field dependencies**. All six are configured on the entity itself in **Setup → Design Studio → Entities** — no code — and all six can be scoped to a record type. This page is the reference for what each one does, where it lives, and the sharp edges each carries. | Surface | What it does | Where it lives | | --- | --- | --- | | Views | Saved list definitions: columns, filter, sort, grouping, default | Entity → **Experience → Views** | | Validations | Declarative save checks with a message | Entity → **Logic → Validations** | | Actions | Buttons on the record page or list that run platform or custom behavior | Entity → **Logic → Actions** | | Field mappings | Auto-fill fields from a looked-up record at creation | Entity → **Schema → Field Mappings** | | Lookup filters | Restrict which records a lookup's picker offers | Entity → **Schema → Lookup Filters** | | Field dependencies | Narrow a picklist's options based on another field or a condition | Entity → **Schema → Field Dependencies** | ## Views A view is a saved list: the columns (picked and ordered explicitly), a filter condition baked into the definition, a sort order, and optionally grouped or tree presentation. Views can be scoped to a record type, and one view per entity (and per record type, when scoped) is the default that list pages open with. The filter and sort use the [query-filter expression language](/docs/customization/expressions/); user-applied filters at run time are combined with the view's own. Two behaviors to know. A view with no columns still renders — with generic fallback columns, which users read as breakage — so always define columns. And a filter that names a nonexistent field fails when the view *runs*, not when it is saved; open the view once after authoring it. ## Validations A validation is a declarative save check: a condition that, when true, marks the record as violating, plus a message and a severity. Only **Error** severity blocks the save — **Warning** and **Info** display without blocking, so "prevent saving" always means Error. The message can be placed at the top or bottom of the form or attached to a specific field, and the whole validation can be scoped to a record type. Validations run inside the save pipeline for every write path — forms, API, imports — not just the form that displays them; see [what runs when you save a record](/docs/concepts/execution-order/). Validation conditions are formula expressions over the record being saved, with a deliberate limit: no aggregates over child records. A condition that needs "sum of the lines" or must compare old and new values belongs in a [business rule](/docs/customization/business-rules/) instead. The classic silent failure is comparing a picklist field against a value that is not in its domain — usually the display label instead of the stored value — which produces a validation that can never fire; check stored values before writing the condition, and re-check them when auditing validations someone else wrote. ## Actions An action puts a button on one of three surfaces — the record page, the list header, or each list row — and gives it a type: the built-in behaviors (new, edit, view, delete, preview, print), a UI action, or a **server action** that runs logic on the server. Actions can show a confirmation dialog first, be scoped to a record type, be ordered among their peers, and run asynchronously as a background job when the work is slow. Server actions are the extensibility point: the button dispatches a named action to the server, where either a built-in handler or a bound [automation script](/docs/customization/automation-scripts/quickstart/) (or both — the script runs in addition to the handler) does the work. The trap is that a server action with *no* handler and no script binding is not an error: the call succeeds and nothing happens. "The button does nothing" almost always means the script binding is missing or points at a different action name — and because the binding matches on the action's name, renaming an action re-keys its trigger. ## Field mappings A field mapping copies a value from a looked-up record into the new record at creation: pick an item on an order line and the price fills in, pick an account and its region lands on the claim. Each mapping names the lookup that triggers it, the source field on the looked-up entity, and the destination field; the editor offers only type-compatible source fields. The semantics are exactly create-time and best-effort. Mappings run only when the record is created with the lookup set — changing the lookup on an existing record does **not** re-copy, and a mapping that cannot apply (source missing, types diverged) skips silently rather than failing the save. The mapped value also overwrites whatever the creator typed into the destination, so never map onto a field users are expected to fill themselves. For copy-on-change behavior, use a business rule that copies from the related record when the lookup changes. ## Lookup filters A lookup filter restricts what a lookup field's picker offers: only active accounts, only items of the record's own category, only warehouses in the user's region. The condition is a query-filter expression over the *target* entity's fields, and it can reference the host record's current in-form values, the current user, and environment values — so "accounts in the same region as this claim" is one condition, evaluated live as the user fills the form. Filters support record-type scoping on both sides: which host record type the filter applies to, and which target record type the picker is limited to. Only the first matching filter applies per lookup and host record type, so do not stack active filters on one lookup. Two limits matter. A lookup filter constrains the **picker only** — a direct API write can still set any id, so a hard constraint needs a validation or business rule behind it. And an over-tight or misspelled condition does not error; it silently yields an empty picker. Always test with a record that should match. ## Field dependencies A field dependency narrows a picklist's options while the user edits: choose "Hardware" in the category field and the subcategory field offers only hardware subcategories. Dependencies come in two shapes — **on a picklist field**, where each value of a controlling picklist maps to the allowed dependent values, and **on a condition**, where rules with conditions (over the record's fields, related records or the current user) decide the allowed set, with configurable behavior when no rule matches (all values, no values, or a default set). Enforcement is also configurable: warn on an out-of-set value, block it, or auto-clear the dependent field when the controlling value changes. Dependencies are authored from the entity's **Schema → Field Dependencies** tab or directly from the field list. Like lookup filters, dependencies shape the *editing experience*; data already stored, and writes that bypass the form, are not retroactively policed — pair a dependency with a validation when the combination must hold absolutely. ## Common questions ### When do I use a validation and when a business rule? Use a validation for a self-contained check on the record being saved — a format, a range, a required combination — where a condition plus a message is the whole requirement. Use a [business rule](/docs/customization/business-rules/) when you need anything more: triggers (only on create, only when a field changes, only on a status transition), aggregates over child records, conditionally required or read-only fields, derived values, or post-save follow-ups. Both block server-side across every write path; the rule simply has more machinery. ### Can I rely on a lookup filter or field dependency for data integrity? No — both shape what the form offers, not what the database accepts. API writes, imports and integrations can set values the picker would never have shown. When the constraint is a business requirement rather than a convenience, express it twice: the filter or dependency for a good editing experience, and a validation or business rule for enforcement. ### Why did my field mapping not update the record when I changed the lookup? Because mappings run only at record creation — that is their contract, not a malfunction. Re-copying on change is deliberately left to business rules, where you control the trigger (when the lookup field changes) and whether existing values may be overwritten. Keep the mapping for the create path and add a rule for the change path when both matter. ## Related topics - [The data model](/docs/customization/data-model/) - [Business rules](/docs/customization/business-rules/) - [Design a form layout](/docs/customization/layouts/design-a-form-layout/) - [Expressions](/docs/customization/expressions/) ---- # Expressions: formulas and query filters URL: https://xmatix.com/docs/customization/expressions/ Last reviewed: 2026-08-15 Small text expressions appear all over xMatix customization — default value formulas, validation conditions, business-rule logic, view filters, lookup filters — and they belong to two different languages with two different runtimes. **Formula expressions** are evaluated in memory against a record during load and save; **query filters** are translated into the database query that selects records for a list or a picker. The two look similar and are not interchangeable: an expression that works in a view filter can fail in a default formula and vice versa, and knowing which surface you are on is most of the skill. This page is the reference for where each language is used and what each supports. ## The two surfaces at a glance | | Formula expressions | Query filters | | --- | --- | --- | | Evaluated | In memory, against one record, during load and save | In the database, against many rows, when a list or picker runs | | Used by | Field default formulas, calculated fields, validation conditions, business-rule conditions and action expressions, approval entry conditions | Saved view filters and sort orders, lookup filter conditions, end-user list filters | | Sees | The record's fields, related records via navigation, the current user and environment | The queried entity's rows; contextual values (host record, user, environment) substituted in where the surface supports them | | Fails | At evaluation — and on some surfaces silently (see below) | At run time, when the list or picker executes — not when the expression is saved | ## Formula expressions Formulas run against a materialized record, which is what gives them their reach: they read the record's fields by name, follow lookups through dotted navigation paths (`Account.Region`, up to five hops, read-only), and — on the surfaces that allow it — aggregate over the record's own child collections. They return a value (for defaults, calculated fields and rule value expressions) or a boolean (for conditions). The syntax essentials: - Field names are identifiers: `Status`, `TotalAmount`, `Account.CreditLimit`. - **String literals must be quoted** — `"Draft"` — because a bare word is read as a field reference. An unquoted literal is the single most common broken formula. - Comparisons (`==`, `!=`, `>`, `<`, `>=`, `<=`) combine with and, or and not (`&&`, `||`, `!`). - Picklist comparisons use the option's **stored value**, never its display label — a condition comparing against a value outside the field's domain can never be true, and nothing warns you. - Date and time come from the environment context (for example, today's date for stamping and comparing), and the current user is available on surfaces that support user context. - Results are coerced to the target field's type where the formula feeds a field; a value the type cannot hold surfaces as a diagnostic, not a crash. Aggregates over child records exist in two spellings — function style, `SUM(OrderLines, UnitPrice * Quantity)` with `COUNT`, `AVG`, `MIN`, `MAX` and `ANY`, and an equivalent lambda style — with the per-element body evaluated against each child. Their availability is the sharpest difference between formula surfaces, so it is worth stating exactly: | Surface | Navigation paths | Child aggregates | | --- | --- | --- | | Business-rule conditions and value expressions | Yes | Yes — over the record's own collections, by relation name | | Validation conditions | Yes | No — a condition needing "sum of the lines" belongs in a rule | | Field default formulas | For reading, yes | No — defaults are same-record | | Calculated fields | Yes | No — calculated fields are same-record math; cross-record rollups are a business-rule job | Two further limits hold everywhere: aggregates work only on the record's *own* collections, not on collections reached through navigation (`Account.Orders` cannot be summed), and formulas never *write* through a navigation path — targets are always local fields. Anything past these limits is [automation-script](/docs/customization/automation-scripts/quickstart/) territory. The failure mode to respect: on some surfaces an unparseable formula fails **silently**. A business-rule condition that does not parse quietly disables the rule — the save proceeds as if the rule did not exist — and the only evidence is a diagnostic in the rule's Test Runner. Preview after every edit; the discipline is in the [business rules procedure](/docs/customization/business-rules/). ## Query filters Query filters select rows: a saved view's filter and sort order, a lookup filter's condition over the target entity, and the ad-hoc filters users apply to lists. Because they execute as part of the database query, they are written against the queried entity's fields and stay within what a query can express — comparisons, and/or/not combinations, and sorting. A view's filter is combined with whatever the user filters at run time; a lookup filter is combined with the user's search term. Contextual values reach a query filter by substitution, and the lookup-filter surface is the richest: its condition can reference the **host record's current in-form values** (match the picked record's region to the record being edited, live, as the user types), the **current user** (id, email, whether the user is external — useful for "my records" and partner scoping), and **environment values** such as the current time. The condition itself always runs against the *target* entity's rows. Query filters fail late: a filter naming a nonexistent field saves without complaint and breaks when the view or picker runs — and an over-tight lookup filter does not error at all, it just produces an empty picker. Always run the view and open the picker once after authoring, with a record that should match. ## Choosing the right surface Ask what the expression is *for*. Deciding something about **one record** — a default, a computed value, a check, a rule condition — is a formula. Selecting **which records appear** — in a list, a picker, a view — is a query filter. The distinction explains the differing power: formulas can navigate and aggregate because they hold one whole record in memory; query filters stay lean because they run inside queries over many rows. When an expression cannot say what you need in either language — multi-statement logic, external data, writes across records — the answer is not a cleverer expression but the next rung: an [automation script](/docs/customization/automation-scripts/quickstart/), which is full C# rather than an expression at all. ## Common questions ### Why did my expression work in a view filter but fail as a default formula? Because they are different languages on different runtimes — the query-filter grammar the view accepted is not the formula grammar the default evaluates. Rewrite for the surface rather than pasting between them, and re-test on the destination surface: the overlap (simple comparisons) is large enough to lull you, and the differences (aggregates, context tokens, coercion) bite exactly when the expression matters. ### How do I show the sum of child lines on a record? With a business rule: a value-setting action whose expression aggregates the record's own child collection — `SUM(OrderLines, Amount)` — into a regular field on save. Calculated fields will not do it (they are same-record math), and there is no rollup field type. The stored total then behaves like any field: visible on layouts, filterable in views, usable in conditions. Remember it recomputes when the *parent* saves — a rule on the child entity that touches the parent keeps it current when lines change independently. ### Why can't my condition see the record's previous value? Formula conditions evaluate the incoming record — there is no "old value of Status" token. Comparing before and after is what the business-rule *transition* trigger is for: it matches on the actual from/to movement of a field, and the condition then qualifies the new record. In scripts, both old and new values are available on the dispatched records; in plain expressions, design around the trigger instead. ## Related topics - [Business rules](/docs/customization/business-rules/) - [Entity behavior](/docs/customization/entity-behavior/) - [Your first automation script](/docs/customization/automation-scripts/quickstart/) - [The data model](/docs/customization/data-model/) ---- # Customizing xMatix URL: https://xmatix.com/docs/customization/ Last reviewed: 2026-09-01 ## Read the customization ladder in Setup @[guided-image](_img/customization-overview.png) Setup makes the ladder visible in its navigation. Design Studio shapes entities and experiences; Process Studio holds declarative Business Rules alongside scripts, components, workflows, approvals, integrations and sync profiles; Data Studio governs analytical models; and the remaining areas handle AI, access and feature operations. The active Business Rules register is intentionally shown because a save-time rule is often the lowest maintainable answer to a behavioral requirement. Use the screen hierarchy as a decision aid before selecting New. First decide whether the request changes data shape, presentation, save-time behavior, orchestration, approval or an external boundary. Then search the existing register so a new definition does not duplicate logic already active elsewhere. The screenshot uses visible synthetic demo2 data so readers can follow realistic rows, values and controls together; production exports and screenshots must still remain inside authorized channels. Everything in this section is about making xMatix behave the way your business does — new business objects, different forms, save-time enforcement, sign-off chains and server-side logic — without waiting for a release. The tools form a ladder, and the one rule that keeps a tenant maintainable is to **pick the lowest rung that genuinely solves the problem**: configuration before rules, rules before scripts, and code only when nothing declarative can express the requirement. If you read one page before any of the how-tos, make it [the customization ladder](/docs/concepts/customization-ladder/) — every page here assumes its logic. ## The pages in this section The section is ordered the way customizations are usually built: shape the data first, then the behavior around it, then the experience, then the automation on top. | Page | What it covers | | --- | --- | | [The data model](/docs/customization/data-model/) | Entities, fields, picklists, relations and record types — the no-code data model everything else builds on | | [Create a custom entity](/docs/customization/data-model/create-an-entity/) | The end-to-end procedure: entity, fields, views, layout and app placement | | [Entity behavior](/docs/customization/entity-behavior/) | Views, validations, actions, field mappings, lookup filters and field dependencies — what each does and where it lives | | [Design a form layout](/docs/customization/layouts/design-a-form-layout/) | The visual layout designer: sections, widgets, per-record-type variants, mobile layouts and defaults | | [Business rules](/docs/customization/business-rules/) | Save-time automation: conditions and actions that default, require, block, lock and notify | | [Your first automation script](/docs/customization/automation-scripts/quickstart/) | Server-side code in a sandbox — where scripts attach, what they can reach, and how to test them | | [Build a workflow](/docs/customization/workflows/) | The visual workflow designer: entity-lifecycle triggers, multi-step orchestration and publishing | | [Approval processes](/docs/customization/approvals/) | Sign-off chains: steps and approvers, submitting records, the approvals inbox, and how approval state gates documents | | [Expressions](/docs/customization/expressions/) | The two expression surfaces — formulas and query filters — where each is used and how their syntax differs | ## Where each change belongs A few signal phrases route most requests. "This field must…" is data-model configuration. "When the record is saved…" is a business rule. "Someone must approve…" is an approval process. "Then wait, then notify, then later…" is a workflow. "Look across records or call another system…" is an automation script. "Show it differently…" is a layout or a custom component. When two tools both work, the lower rung wins — it stays visible in Setup, previewable, and editable by any administrator rather than only by whoever wrote the code. Every customization here also runs inside a fixed save pipeline: defaults, then validation, then rules, then module logic, then workflows and scripts. When two customizations seem to fight, the pipeline order is almost always the explanation — see [what runs when you save a record](/docs/concepts/execution-order/). ## Common questions ### Do I need a developer to customize xMatix? Not for most of this section. The data model, entity behavior, layouts, business rules, workflows and approval processes are all configured in Setup — no code, previewable, and adjustable by any administrator with the right capabilities. Automation scripts are the exception: they are real server-side code and should be owned like code. The ladder exists precisely so that the coded rung is the last resort, not the first. ### Do customizations survive product updates? Yes — that is the point of building on the declarative surfaces. Custom entities, fields, rules, layouts and processes are tenant metadata, separate from the platform's own objects; platform updates ship new capability without rewriting your configuration. System-owned metadata is read-only in your tenant for the same reason: you extend it with custom fields and rules rather than editing it, so an update never has to merge with your changes. ### Where do I try changes before users see them? Most declarative tools carry their own safety mechanism — business rules are drafted inactive and verified in a test runner, workflows fire only when published, scripts fire only when bound — so the pattern on every page here is draft, verify, then activate. For larger changes, build in a sandbox tenant and promote when proven; see the [administration guide](/docs/administration/) for sandbox operations. ## Related topics - [The customization ladder](/docs/concepts/customization-ladder/) - [What runs when you save a record](/docs/concepts/execution-order/) - [The xMatix app builder](/platform/app-builder/) - [Automation on the xMatix platform](/platform/automation/) ---- # Design a form layout URL: https://xmatix.com/docs/customization/layouts/design-a-form-layout/ Last reviewed: 2026-09-02 A layout is the form an entity renders — which fields appear, in what sections, with what widgets and buttons. Each entity can carry several: separate layouts for creating a record and viewing it, variants per record type, and a distinct mobile body for the phone. This page walks through designing a layout in the visual designer and, just as important, through the selection rules — type, record type, platform, default — that decide which layout actually opens, because most "wrong form" reports are selection problems, not design problems. ## Prerequisites - The model-management capability (`setup.metadata.model.manage`). - The entity and its fields exist — the designer places fields, it does not create them. See [create a custom entity](/docs/customization/data-model/create-an-entity/). - If a button on the form should run behavior, the entity action exists first (entity → **Logic → Actions**). - Know the four layout types: **Create** renders the new-record form, **View** the record detail (and is the fallback when no other type matches), **Preview** the compact peek panel, **Action** a form opened by an action flow. ## Procedure ### Step 1 — Create the layout row Go to **Setup → Design Studio → Entities**, open the entity, and on the **Experience → Layouts** tab use **New**: a Label, Internal Name and Description, the layout type, and optionally a record type. Choose the record type now if the layout is a variant — it is fixed at creation and cannot be changed afterwards. Every row you create here is selectable at run time, so create the row and design it in the same sitting: an empty layout that wins selection renders a blank form. @[guided-image](_img/new-layout-dialog.png) ### Step 2 — Design the form Open the layout with **Web Design** (clicking the layout name does the same). The designer gives you a canvas of sections and a palette of widgets: field inputs bound to the entity's fields, tabs and grids for structure, related lists for child records, and purpose-built widgets such as the approval panel and audit trail. Group fields into sections a user can scan — identity first, status and ownership visible, rarely-used fields lower or in a tab. Fields bind by their internal name, so a field renamed at the label level keeps working, and required flags from the model are enforced regardless of what the layout shows. ### Step 3 — Add action buttons Buttons on the form invoke the entity's actions by name. Place the button widget where the work happens and bind it to the action — the binding is by the action's internal name, and nothing validates it at design time, so a misspelled name fails only when clicked. After saving, test the button once against a test record in a state the action accepts; server-side gating (record state, permissions) applies at click time, not render time. ### Step 4 — Create record-type variants When one entity needs different forms per record type, choose that record type when the layout row is first created. The record type is fixed after creation: **Edit Layout** disables it, and **Clone Layout** asks only for the clone's label and internal name while preserving the source layout's record-type scope. Clone an already-scoped source when you want another variant in the same scope; create a new row when you need a different scope. Selection prefers an exact record-type match and falls back to unscoped layouts, so retain an unscoped fallback for every layout type you use. Variants are per layout type: a Corporate Create variant does nothing for the View form. ### Step 5 — Design the mobile layout The phone renders its own layout body, designed with the mobile widget family. On the layout row, use **Mobile Design** to open the mobile designer; a web layout is promoted to serve both platforms on the first mobile save, and its web body is untouched — the two bodies live side by side on the same row. Each layout row declares which platforms may select it (web, mobile or both); a row marked web-only is invisible to the phone even if a mobile body exists, so the platform setting is intent, not inference. Never paste a mobile-format document into a web layout body — the web runtime will select it and render a broken form. ### Step 6 — Set the default On the **Layouts** tab, use **Edit Layout** and switch on **Default Layout**. The default wins selection among layouts of the same type and scope — but setting a new default does not clear the old one, and that is your job: exactly one default should exist per entity, layout type and record-type scope (web and mobile defaults coexist intentionally). A default that is inactive is never selected, so check both flags together. ### Step 7 — Verify on every surface it affects Open the create dialog and confirm the Create layout renders; open a record and confirm the View layout; if you built record-type variants, open one record of each type; if you designed a mobile body, open the record on the phone. Verify as a normal user as well as an administrator — field-level security can legitimately hide fields the designer shows you. **Expected result:** each platform, layout type and record type selects the intended active layout, while a normal user's field visibility still follows their security profile. ## Common problems **The create dialog shows the wrong form.** When no active Create layout exists, selection falls back to other active layouts — usually the View default. The fix is almost never re-picking; it is creating (or re-activating) the Create-typed layout. **A record type lost its form.** A previously-unscoped default was scoped to one record type, leaving other types with nothing to fall back to. Keep an unscoped layout per type in use, and scope variants on top of it. **The form renders blank.** Either an empty layout row is winning selection (often on the default flag), or a mobile-format body sits in a web layout. Check the winning row's body and platform before touching the design. **"The form changed by itself."** Audit the flags before the JSON: an inactive or unscoped default silently shifts selection to another row. The audit trail on layout records shows who changed what. **Two people edited the same layout and one change vanished.** Saves replace the whole layout body, and the last save wins — the designer does not merge. Coordinate edits, and reload any open designer tab before saving over someone else's work. ## Common questions ### What is the difference between the Create and View layouts? Create renders the new-record dialog; View renders the record page. They are requested independently, so design both — the platform falls back (a missing Create layout borrows another layout) but a purposeful create form is almost always shorter than the record page: the fields needed to start the record, not everything ever known about it. Preview covers the compact peek panel, and Action layouts are opened by specific action flows. ### Do I need a separate layout row for mobile? No — one row can carry both a web and a mobile body, and that is the recommended shape: design the web form, then use **Mobile Design** on the same row, which promotes it to serve both platforms. A separate mobile-only row also works and competes only in mobile selection. What decides visibility is the row's platform setting, not the presence of a body. ### Why does a user not see a field that is on the layout? The layout proposes; security disposes. Field-level security on the user's profile can hide or lock fields regardless of the design, and record-type scoping may be rendering that user a different layout row than the one you edited. Check which layout actually won selection for that user's record and record type, then the profile's field permissions — see the [administration guide](/docs/administration/). ## Related topics - [Create a custom entity](/docs/customization/data-model/create-an-entity/) - [Entity behavior](/docs/customization/entity-behavior/) - [The data model](/docs/customization/data-model/) - [The xMatix app builder](/platform/app-builder/) ---- # Build a workflow in the visual designer URL: https://xmatix.com/docs/customization/workflows/ Last reviewed: 2026-09-06 A workflow orchestrates a multi-step process around record events: when an order is created, email operations; when a claim changes, submit it for approval and act on the decision; enqueue background work and resume when it finishes. Where a [business rule](/docs/customization/business-rules/) lives inside one save, a workflow spans steps and time — if the requirement contains "and then, later…", it is a workflow. This page builds one in the visual designer and covers the two ideas that decide whether it actually runs: triggers only register from the *published* version, and every edit is a draft until you publish again. ## Prerequisites - The workflows capability (`setup.automation.workflows.manage`). - The entity's exact name as it appears in the model (the trigger matches on the entity name, not the display label) — check it under **Setup → Design Studio → Entities**. - If a step will submit for approval, an active [approval process](/docs/customization/approvals/) exists on the entity; if a step will send a templated message, the template exists. ## Procedure @[guided-image](_img/workflows-list.png) ### Step 1 — Create the workflow Go to **Setup → Process Studio → Workflows** and choose **New** once. This immediately creates a draft definition named *Untitled workflow* at version 1 and opens the visual designer, so do not double-click or repeat the action while navigation is in progress. Open **Workflow settings** in the designer's command bar, replace the temporary title with a name that states the trigger and outcome, add an operational description, and save. Return to the list if necessary and verify one row exists with **Draft** status and the expected version; a draft cannot receive live triggers. The list itself shows **Name** (opens the designer), **Description**, **Version**, **Status** (a *Draft* or *Published* tag that is also the publish toggle — see Step 7), **Definition Id** and an **Actions** column with *Open designer*, *View runs*, *Edit JSON* and *Delete workflow*. ### Step 2 — Add the trigger Drag the **When entity record changes** trigger from the *Triggers* group of the palette onto the canvas and configure it: **Entity name**, the **Operations** it reacts to (Create, Update, Delete — leave empty for all three), and the **Phase**. The default, **After save (async)**, runs after the save commits — asynchronous, safe, and the right choice for notifications and follow-ups. **Before save (sync — can cancel)** runs synchronously inside the save and is the only phase from which a workflow can cancel it; it never fires for deletes. The trigger exposes outputs downstream steps can use — `EventRecordId`, `EventEntityName`, `EventOperation`, `EventPhase`, `EventChangedFields` (on updates) and `EventStamp`. ### Step 3 — Add the steps Drag steps from the palette and connect them. The catalog covers: | Step | What it does | | --- | --- | | **Send Email** / **Send Message** | Direct email (To, Subject, Text body or HTML body), or a templated message over the platform's channels to the record owner, a field's address, a user or a literal recipient | | **Submit for Approval** / **Wait for Approval Decision** | Submits the record (Entity name, Entity id, Comments) into its approval process and suspends the workflow until the decision; outputs `Status` (Approved, Rejected, Recalled or Reverted), `ActorUserId` and the decision comments, which downstream steps can branch on | | **Enqueue Job** / **Wait for Job Completion** | Queues a registered background job (optionally delayed) and can suspend until it finishes | | **Cancel entity operation** | Aborts the surrounding create, update or delete with a **Reason** — before-save phase only | | **Decision (If)**, **Switch**, **Join**, **While** | Branch on a condition (True/False ports), route to the first matching case, merge branches, or repeat a body while a condition holds | | **Set Variable**, **Write Line** | Assign a workflow variable; write a line to the log for debugging | Know what is deliberately *not* here: there is no timer or scheduled trigger — "nightly at two" is a scheduled job or integration flow, not a workflow — and no HTTP call-out step, because calling external systems is the job of integrations and [automation scripts](/docs/customization/automation-scripts/quickstart/). Designing around these limits up front beats discovering them after the canvas is full. ### Step 4 — Save as a draft and keep the first version small Save the workflow. Drafts never fire, so you can save half-built work freely. Keep the first version to the trigger plus one or two steps: get one clean run before adding branches, because a fault in a ten-step workflow is ten times harder to localize than in a two-step one. ### Step 5 — Publish The designer command bar offers **Undo**, **Redo**, **Auto layout**, **Edit JSON**, **Workflow settings**, the **Publish** toggle and **Save**. Publish only after saving, peer-reviewing the trigger and proving the draft with disposable inputs. Publishing registers live triggers, so state the activation in concrete terms—such as “every Order create now emails Operations”—and watch the list change from Draft to Published. Every later edit creates a new draft while the prior published version keeps running. Before expecting a fix in production, verify the corrected version itself is Published rather than merely saved. ### Step 6 — Trigger it and inspect the run Cause the trigger event with a disposable record, then open **View runs** on the workflow's row. Every triggering produces an instance listed with **Started**, **Status**, **Sub-status**, **Version**, **Incidents**, **Finished** and **Instance Id**; a finished instance with zero incidents plus the observed side effect (the email arrived, the approval opened) is the proof. Clean up the test record. ### Step 7 — Retire or replace safely To stop new triggers, choose **Unpublish** in the designer command bar (or click the *Published* tag in the list, which toggles it and confirms with *Retracted*) and verify the list returns to Draft; running instances continue and must be monitored individually. To replace behavior without a gap, publish the corrected draft so it supersedes the old version atomically. Use Delete only when the definition should never run again: retract first, confirm there are no instances requiring investigation, and preserve any run evidence your retention policy needs. ## Expected result The list shows one intentionally named workflow at the expected version and status. When Published, one disposable trigger creates one run whose steps and side effects match the design; when Retracted, new test events create no runs while existing instances remain visible to completion. ## Common problems **Nothing fired.** Check publication first — only the published version registers triggers, and a recent "fix" may be an unpublished draft. Then check the trigger: the exact entity name (not the label), the operations list actually containing the operation you tested, and the phase you expect. A before-save trigger never fires for deletes. **An instance exists but is faulted.** A step failed — a missing template, an unresolvable recipient, a bad input. The run view shows which step; fix its configuration, save, republish, and re-test with a fresh event. **The instance finished cleanly but nothing visible happened.** The side effect went to the wrong target — a recipient that is not who you thought, a channel that is not enabled, a job type that does not exist. Verify the step's outputs against the message log and job history rather than re-editing the flow blindly. **The workflow toggled state unexpectedly.** The list page's status tag is itself a publish/retract toggle, and another administrator may have clicked it. Re-check current state before assuming your change failed. ## Common questions ### When is a workflow the wrong tool? When the whole requirement fits inside one save — validation, defaults, status guards — a [business rule](/docs/customization/business-rules/) does it with less machinery and no publishing lifecycle. When the requirement is a schedule ("every morning"), a workflow cannot express it at all: use a scheduled job or integration flow. When it needs to call an external API, that step belongs to a script or integration, orchestrated around — not inside — the workflow. ### Does retracting a workflow stop instances already running? No — retraction stops *new* triggering only; instances mid-flight (waiting on an approval decision or a job) continue to completion. That is usually what you want, since half-finished processes are worse than finished ones. If a running instance must genuinely be stopped, deal with it individually from the runs view rather than expecting retraction to sweep it away. ### Can a workflow block a save the way a rule does? Yes, in the before-save phase — a decision step feeding the cancel step aborts the save with your reason, synchronously. Use it sparingly: plain validation is clearer as a business rule, which any administrator can read on the entity itself. The workflow version earns its place when the cancellation decision genuinely needs workflow machinery, and it cannot guard deletes (the before-save phase never fires for them). ## Related topics - [Business rules](/docs/customization/business-rules/) - [Approval processes](/docs/customization/approvals/) - [Your first automation script](/docs/customization/automation-scripts/quickstart/) - [Automation on the xMatix platform](/platform/automation/) ---- # Archive rules: moving cold data to the warehouse URL: https://xmatix.com/docs/data-studio/archive-rules/ Last reviewed: 2026-09-08 An archive rule moves cold rows of one entity out of the operational database and into an archive table in the analytics warehouse, on a schedule you define. The trade is deliberate: the working system stays lean and fast, while the history remains queryable for analytics — archive tables can be used as sources in [data models](/docs/data-studio/data-models/). A run does three things in order, and stops at the first one that does not add up: 1. **Copies** every row older than the cutoff to the archive table — a real table, so it keeps the rows after they leave the live data. 2. **Checks the copy** by counting what actually landed. If that does not match the number of rows that were due, the run fails and **the live data is untouched**. 3. **Marks the rows deleted** at the source. They stay in the database, still covered by its own point-in-time backup, but they stop appearing in lists, reports over live data, API queries, data models, datasets and dashboards. Because step 3 is a soft delete, an archive run is recoverable — but recovering it is a database operation, not a button, so still treat activating a rule as a production change and estimate its impact first. **When the rule runs** offers two other modes: marking the rows deleted without copying them (for data the warehouse already holds), and deleting them permanently, which is what every rule did before 2026-09-08 and cannot be undone short of a database restore. ## Prerequisites - The archive administration capability (`setup.metadata.archive.manage`) — it also gates the **Archive Rules** entry in Setup navigation. - A provisioned, reachable analytics warehouse for your organization — runs fail cleanly when it is unreachable, copying and deleting nothing. Only the permanent-delete mode works without it. - Certainty about which entity, which date field, and which cutoff define "cold" for your data — the rule will act on exactly what you specify. ## Procedure @[guided-image](_img/new-archive-rule-dialog.png) ### Step 1 — Create the rule Open **Setup → Process Studio → Archive Rules** and choose **New Archive Rule**. Fill in **Label** and **Name** (a descriptive display label and a stable internal name), **Source Entity**, and **Date Field** — the field list fills once the entity is chosen, and the field to pick is the one that represents business age, not merely the most convenient timestamp. **When the rule runs** decides what happens to the rows, and leaving it on the default is the safe choice; **Archive table** says where the copy lands, and empty means `silver.Archive`. Then **Cutoff Formula** and, optionally, **Condition Formula**, each with an *Open … formula builder* button, plus **Schedule** and the **Active** checkbox. Leave **Active** off while defining formulas and estimating impact, then press **Create**. Before saving, verify the source/date pair against a real record so the cutoff measures what the business means by “cold.” The list shows **Label**, **Source Entity**, **Date Field**, **Target Warehouse Table**, **Active** and **Updated**; each row offers **Run**, **History**, **Edit**, **Clone Archive Rule** and **Delete**. ### Step 2 — Define what qualifies Two expressions decide which rows are archived, and both are evaluated against the entity's real data: - **Cutoff formula** (required) — an expression that resolves to a date, for example `DATEADD(year, -2, GETUTCDATE())`. Rows whose date field falls **before** the cutoff qualify. - **Condition formula** (optional) — a predicate ANDed in, for example `Status = 'Closed'`, so only rows in a safe state qualify regardless of age. Both fields offer a formula builder that can reference the selected entity's fields. Be precise here: a typo fails the run visibly, but a wrong-yet-valid condition archives the wrong rows silently. ### Step 3 — Set the target table Enter the **Target Warehouse Table**, such as `silver.orders_archive`. A bare table name without a schema lands in the `silver` schema. Neither the schema nor the table needs to exist — both are created on the first run, with the source entity's columns. ### Step 4 — Estimate the impact before activating Save the rule **inactive** and confirm the list reports it that way. Reproduce its exact predicate in a filtered list or report: selected date field before the evaluated cutoff, AND the optional condition. Record the total and inspect samples near both sides of the boundary, including linked records that must stay operational. If anything surprises you, correct the rule and repeat the estimate; an inactive rule can accumulate a large backlog, so never activate using an old count. ### Step 5 — Activate and run once manually Activate the rule, then use the row's **Run** action for a first supervised run. A run proceeds in a fixed order: check that the source entity and date field still exist (a rule whose field was renamed or removed refuses to start), resolve the cutoff, skip if an identical window was already archived, verify warehouse connectivity (an unreachable warehouse fails the run before anything is touched), bulk-copy every qualifying row into the target table, and only then delete those rows from the operational database. ### Step 6 — Verify the run Open **History** — the newest 50 attempts, each with **Started**, **Completed**, **Status** (*Pending*, *Running*, *Succeeded*, *Failed*, *Canceled* or *Skipped duplicate*), **Archived Rows**, **Duration** and **Error** — and inspect the newest attempt. Success should be close to the immediately preceding estimate; explain any difference caused by records changing in between. Spot-check that qualifying rows disappeared from operational lists and arrived in the named warehouse table with their key fields intact. A zero count is valid only when the same predicate now finds zero eligible rows. ## Expected result The first supervised run is **Success**, its archived count reconciles with a fresh estimate, qualifying rows are absent from operational queries and present in the intended warehouse table, and non-qualifying boundary records remain. History records the run, and the active UTC schedule is either intentionally populated or intentionally left manual-only. ### Step 7 — Schedule it Set the **schedule** as a five-field cron expression, evaluated in UTC — `0 2 * * 0` runs weekly at 02:00 UTC. The scheduler queues a run for every active rule whose schedule is due. The schedule is checked about once a minute, a run is queued only for occurrences after the rule's last run (the first occurrence is not back-filled), and archive runs send no notification on success or failure — History is the only record. Three things silently prevent scheduled runs: an inactive rule, an empty schedule (manual-only is a valid choice), and an invalid cron expression, which is skipped without any error — so if a rule "never runs", check those three before anything else. ## Common problems **The run failed.** Read the error on the newest history entry. The usual causes are a SQL error in the cutoff or condition formula (fix the formula and run again), a date field that was renamed or removed since the rule was written (the run refuses to start), or warehouse connectivity — in which case nothing was copied or deleted, and the run can simply be retried later. **The run says success but archived zero rows.** Usually correct behavior: nothing qualified, or an earlier run already archived the identical window — repeat runs over the same rule, cutoff, target and condition are skipped as duplicates rather than re-archived. **Other records now show empty lookups.** Records in other entities that referenced the archived rows keep dangling references — the same effect a hard delete has. If active documents still point at the rows you archived, your condition formula was too broad; tighten it so only truly closed history qualifies. ## Common questions ### Can archived records be restored? Not from within the product. Archiving is a move, not a copy — the rows exist only in the warehouse table afterwards, and recovery means copying them back into the operational database manually, which is an operator-level task. This is the sharpest difference from the [recycle bin](/docs/concepts/data-lifecycle/), where restore is self-service. Before activating a rule, apply the same discipline as before a bulk delete: estimate, and be sure. ### Is this the same archive the recycle bin uses? No, and the distinction matters. The [data lifecycle](/docs/concepts/data-lifecycle/) archive holds *deleted* records after their recycle-bin retention window, as a recovery of last resort. Archive rules act on *live* records that were never deleted — they offload cold history to the warehouse for performance and analytics. One is about undoing deletes; the other is about keeping the working set small. ### Do reports still see archived data? Reports and lists over live data do not — the rows are no longer in the operational database. The archived rows are available to the analytics side instead: an archive table in the warehouse can be a source in a [data model](/docs/data-studio/data-models/), which lets datasets combine current operational data with archived history in one analysis. ### How many rows did a rule archive in total? Sum the archived-row counts of its **successful** runs in the run history. Run entries are per-attempt and append-only — failed attempts appear too, and a skipped-duplicate entry repeats the count of the run it duplicated rather than adding to it — so totalling every row of the history overcounts. ## Related topics - [Delete, recycle bin, archive and restore](/docs/concepts/data-lifecycle/) - [Data models and materialization](/docs/data-studio/data-models/) - [Refresh scheduling and monitoring](/docs/data-studio/refresh-and-jobs/) - [Data Studio overview](/docs/data-studio/) ---- # Data models and materialization URL: https://xmatix.com/docs/data-studio/data-models/ Last reviewed: 2026-09-06 A data model is where a business definition is made once. It joins sources — operational entities, archived history, externally landed warehouse tables — into a named structure with declared output columns, and **materializes** that structure into a physical table in the analytics warehouse. [Datasets](/docs/data-studio/datasets/) then build on the model rather than on raw tables, which is the whole point: ten dashboards needing "revenue" means one model defining it, not ten private versions that drift apart. ## What a model is made of A model is authored in the **Data Model Builder** — an application page (route `/analytics/data-models`) that an administrator adds to an app's navigation as a *Feature* item; it is not in Setup. The builder lists models with **Name**, **Label**, **Root Source**, **Root Entity**, **Grain**, **Warehouse Object**, **Published** (Published or Draft), **Active** and **Updated**, with **Open Workspace**, **Edit** and **Delete** per row. **New Data Model** opens the dialog below. @[guided-image](_img/data-models-context.png) The dialog captures the model's contract before any source is joined: **Name** (the stable key), **Label**, **Description** (state the business definition), **Root Source Type** — *Entity*, *Warehouse Table* or *External Warehouse Table* — with its companion **Root Entity** or **Root Warehouse Object**, **Grain**, **Published Warehouse Object**, **Refresh Schedule** (five-field cron, UTC), and the **Published** and **Active** checkboxes (a new model is active but unpublished; there is no separate Publish button — publishing is this checkbox). Everything else is authored in the model's workspace, whose tabs are **Overview**, **Sources**, **Columns**, **Filters** and **Build History**, with **Edit**, **Build**, **Validate**, **Preview** and **Delete** in the header. A model consists of four parts: - **A root source** — an operational entity, or a warehouse table (an archive table produced by [archive rules](/docs/data-studio/archive-rules/), or external data already landed in the warehouse). - **Joined sources** — additional entities or warehouse tables, each with an alias, a join type (inner, left, right or full) and a join condition tying it to a parent alias; for an entity source the **Relation Helper** prefills the entity and join from the parent entity's relations. The join graph must have exactly one root, and every non-root source needs its parent and condition. - **Output columns** — the model's published schema: each column maps a source alias and field (or an expression) to an output column name, with a display name, an optional aggregation (Sum, Count, Average, Min, Max, Count Distinct or Expression), a **Key Column** flag and a **Visible** flag. These output columns are what datasets see and validate against. - **Filters** — predicates ANDed into the build, for scoping the model itself. The model also carries a **grain** statement ("one row per sale order"), the **warehouse object name** its build writes to, a **refresh schedule**, and two switches that mean different things: **Active** (the model participates at all) and **Published** (the model is offered to dataset authors). ## What building actually does **Build** validates the definition first (a blocking error stops the build and writes no history row), then generates SQL from the sources, columns and filters and loads the result into the model's warehouse object as a physical table — not a view, so downstream reads pay no join cost at query time. Every build is a full drop-and-recreate of that table; a bare object name without a schema lands in the `model` schema. How the data gets there depends on where the sources live: - **Warehouse sources only** — the table is built entirely inside the warehouse from the generated SQL. - **Entity sources only** — the qualifying operational data is copied into the warehouse table. - **Mixed** — entity data is first staged into the warehouse, the join then runs there against the warehouse-resident sources, and the staging copies are cleaned up afterwards. This is what lets one model combine live records with archived history in a single structure. Every build appends a **Build History** entry — started, completed, status (**Pending**, **Running**, **Succeeded**, **Failed**, **Canceled**), row count, duration and error message. Builds run on demand from the workspace's **Build** action (the toast reads *Data model build triggered*), or on the model's cron schedule; scheduled builds require the model to be active *and* published, with a valid schedule. The schedule is checked about once a minute, the first occurrence after saving is not back-filled, a malformed cron expression is skipped silently, and model builds send no notification — Build History is the only record, so a model that "never builds" is diagnosed there. Building requires a reachable warehouse; when it is not, the build is refused before anything runs. **Validate** checks the definition — the join graph, aliases, required columns, expressions — without touching the warehouse, and **Preview** shows the generated SQL and projected columns before anything runs. ## How models relate to datasets The relationship is a deliberate one-way dependency: datasets consume models, never the reverse. - **Binding.** A dataset binds to one published, active model. Binding auto-fills the dataset's source and grain, and is what the dataset's guidance and validation hang off. - **Schema guidance.** A bound dataset's editors offer the model's root object and published output columns as pick lists, and its validation rejects references to columns the model does not publish — schema mismatches surface at authoring time instead of as build failures. - **Lifecycle.** Rebuild the model and every dataset's next refresh reads the updated structure; unpublish a model and it stops being offered to new datasets. The model is the contract; datasets are its consumers. A dataset *can* bypass models and name a warehouse table directly — supported as a fallback, at the cost of all guidance and schema validation. The governed default is: model first, datasets on top. ## Common questions ### What is the difference between a data model and a dataset? A data model is a reusable *source*: the joined, governed structure where the business definition lives. A dataset is a *consumption output*: dimensions and measures over exactly one model, aggregated to an analysis grain and materialized for dashboards and embedded BI. The test: if several analyses will share it, it belongs in the model; if it is one analysis's shape — which columns to group by, which numbers to aggregate — it belongs in the dataset. ### Can a model include archived or external data? Yes — that is a core reason models exist. A source can be a warehouse table as easily as an entity: archive tables written by [archive rules](/docs/data-studio/archive-rules/), or external data already landed in the warehouse. A mixed model joins live operational records with that warehouse-resident history in one structure, so "sales including the archived years" is one model rather than a stitching exercise in every report. ### What happens if I rename the model's warehouse object after builds? The next build writes to the new name and the previously built table is simply left behind — orphaned, not migrated or dropped. Anything reading the old name (a dataset's fallback source, BI content built over it) keeps reading the stale table without errors, which is worse than breaking. Treat the warehouse object name as part of the model's contract: set it before the first build and change it only with the downstream consumers in hand. ### Why is my model not offered when creating a dataset? The dataset modal lists models that are both **published** and **active** — a draft or deactivated model does not appear, however many successful builds it has. Publishing is the explicit act of offering the model to dataset authors; check both switches on the model's overview before looking anywhere else. ## Related topics - [Build a dataset](/docs/data-studio/datasets/) - [Archive rules](/docs/data-studio/archive-rules/) - [Refresh scheduling and monitoring](/docs/data-studio/refresh-and-jobs/) - [Data Studio overview](/docs/data-studio/) ---- # Build a dataset in the Dataset Builder URL: https://xmatix.com/docs/data-studio/datasets/ Last reviewed: 2026-09-06 A dataset is an analysis-ready table: named dimensions and measures defined over a [data model](/docs/data-studio/data-models/), compiled into SQL and materialized as a physical table in the analytics warehouse, then rebuilt on a refresh schedule. Build a dataset when the question is analytical — aggregation over history, at warehouse scale, feeding many consumers such as dashboard widgets. For a plain operational listing of live records, an ordinary [report](/docs/analytics/reports/) is the better tool; the dataset earns its keep when one governed definition should serve everything downstream. ## Prerequisites - The **Dataset Builder** page in reach. It is an application page, not a Setup screen: it ships in the standard Analytics app's navigation (after Reports and Dashboards) and an administrator can add its route, `/analytics/datasets`, to any other app as a *Feature* item. - A **built, published, active data model** to bind to — the dialog offers only models that are published and active. A dataset can instead name a warehouse table directly as a *fallback source*, but a bound dataset gets root-source guidance, column pick lists and schema-aware validation, so bind when you can. - A reachable analytics warehouse. Compile refuses to run when the warehouse connection is unavailable, so an organization without a provisioned warehouse can author datasets but not materialize them. ## Procedure ### Step 1 — Create the dataset shell Open **Dataset Builder** and choose **New Dataset** in the page header. @[guided-image](_img/new-dataset-dialog.png) | Field | What it does | | --- | --- | | **Name** (required) | Internal identifier: a letter followed by letters, digits or underscores, up to 100 characters. It becomes part of the default warehouse table name and cannot be changed after creation. | | **Label** (required) | Reader-facing title shown in pickers. | | **Description** | Free text — record what the dataset answers and who owns it. | | **Published Data Model** | The governed source. Only published, active models are listed. Choosing one fills **Fallback Source Table** and **Grain** from the model if they are still empty. | | **Fallback Source Table** | A warehouse table (for example `model.FactSales`) used as the root source when no data model is bound. Either this or a data model is required, or validation fails with *dataset.source.required*. | | **Grain** | What one output row represents — "Order", "Invoice line". Write it as a testable sentence; every later dimension and measure is judged against it. | | **Refresh Type** (required) | *Full* or *Incremental*. Stored, but every refresh is currently a full rebuild — see the common questions. | | **Visibility** (required) | *Private*, *App* or *Shared*. Stored and displayed; nothing filters on it yet. | | **Refresh Schedule** | Five-field cron in UTC, for example `0 */6 * * *`. Blank means manual-only. A malformed expression is accepted and then silently never fires — see [Refresh scheduling and monitoring](/docs/data-studio/refresh-and-jobs/). | | **Warehouse Table** | Name of the materialized table (for example `Dataset_SalesDashboard`). Blank derives `Dataset_`; the table lands in the `platinum` schema unless you qualify the name. | | **Folder**, **Sort Order**, **Icon**, **Color** | Presentation in lists and pickers. | | **Active** | Inactive datasets are never refreshed on schedule and are hidden from the dashboard dataset picker. | Choose **Create**. The dataset appears in the table with its **Binding** state (*Bound* when a model was chosen, otherwise *Unmapped*) and **Last refresh** *Never run*. Clicking the name reopens this dialog for editing; the definition itself is authored in the workspace. ### Step 2 — Open the workspace From the row, choose **Open Workspace**. @[guided-image](_img/dataset-workspace.png) The workspace header carries **Edit**, **Delete**, **Compile**, **Validate** and **Preview**; the tabs are **Overview**, **Sources**, **Dimensions**, **Measures**, **Filters**, **Security** and **Refresh History**, each showing its count. A guardrail banner above the tabs tells you what kind of authoring help you have: - **Data Model guidance enabled** — the dataset is bound: the model's root object is offered as your root source and its published columns appear as pick lists. A second warning appears if your root source table does not match the model's root. - **Dataset is not bound to a Data Model** — "authoring remains mostly free text": no pick lists, no schema-aware validation; compile-time SQL errors become your first line of defence. - **Data Model schema is unavailable** — the model is bound but has not been built yet, or its schema could not be loaded. Build the model first. ### Step 3 — Define the sources On **Sources**, add the tables the dataset reads. The first source is the **root** — it has no parent alias — and exactly one root is allowed (*dataset.sources.root.multiple*). For a bound dataset, **Use Bound Root Source** fills the table name and the alias `fact` from the model. Each further source declares **Table Name**, **Alias**, **Join Type** (Inner, Left, Right, Full), the **Parent Alias** it joins to, a **Join Condition** in warehouse SQL and a **Display Order**; a non-root source without a join condition fails validation (*dataset.sources.join.required*). ### Step 4 — Define dimensions On **Dimensions**, add the columns to group by. Each dimension has a **Column Name** (or an **Expression** instead), a **Display Name**, a **Group By Order**, a **Time Dimension** flag and **Visible**. On a bound dataset, **Use Data Model Column** prefills the column from the model's published schema — use it: column names are validated against the model's *output columns*, not the operational entity's field labels (*dataset.expression.column.missing*). Dimensions become the grain of the output: every distinct combination of dimension values is one row of the compiled table. ### Step 5 — Define measures On **Measures**, add the numbers. Each measure has a **Measure Name**, an **Aggregation** — Sum, Count, Average, Min, Max, Count Distinct, or **Expression** for a fully calculated measure — an **Expression** (a column or warehouse SQL over the model's output columns), a display **Format**, **Display Order**, and the **Calculated** and **Visible** flags. A dataset with no dimensions and no measures compiles to nothing useful and validation warns you (*dataset.outputs.empty*). ### Step 6 — Add filters, and security rules if needed **Filters** are SQL predicates ANDed into the build — rows they exclude are genuinely absent from the compiled table, which makes filters the hard scoping tool. Each has a **Filter Expression**, **Display Order** and **Active** flag. **Security** rules declare per-role row scoping: a **Role Id**, a **Row Filter Expression** such as `SalesPersonId = @userId`, order and active flag (*dataset.security.role.required* if the role is missing). They appear in the Preview's **Security** tab and travel with the definition, but they are **not** injected into the compiled table's SQL — the materialized table contains every row the filters allow — and no dashboard or report applies them when reading the table today. Their intended use and the consequences are covered in [Row-level security on datasets](/docs/data-studio/row-level-security/). ### Step 7 — Validate and preview Choose **Validate**. The **Dataset Validation** dialog reports *Validation passed* or *Validation found blocking issues* with an error and warning count and each finding's code and message. Errors block compilation; warnings never do, so read them as review items. The label is required (*dataset.label.required*); a bound model must still be published and active (*dataset.data-model.unpublished* / *inactive*); a missing warehouse target is only a warning (*dataset.warehouse-target.missing*) because the name is derived. Then choose **Preview**. The **Dataset Preview** dialog has four tabs — **Columns**, **Filters**, **Security** and **SQL Preview** — showing the projected output, the active predicates, the declared security rules and the exact SQL that compile will run. Preview does not execute anything against the warehouse; reconcile the SQL with the written grain and confirm no join can duplicate rows before compiling. ### Step 8 — Compile Choose **Compile**. The dataset is validated again — any error stops the compile with the findings and **no history row is written** — then the SQL is generated and the warehouse table is dropped and recreated from it. The toast *Dataset compile triggered* confirms the request was accepted; the outcome lands in **Refresh History** as *Success* with a row count and duration, or *Failed* with the error message (an unreachable warehouse fails the run with a connectivity message). ### Step 9 — Confirm the refresh cycle Open **Refresh History** (columns **Started**, **Completed**, **Status**, **Rows**, **Duration**, **Error**; latest 50 runs) and verify the newest run is *Success* and its row count matches an independent grain-level expectation. If you set a **Refresh Schedule**, convert the UTC cron to the business timezone and confirm that the first scheduled rebuild appends a new successful entry rather than trusting the saved expression — an invalid one never fires and never complains. The scheduling rules and statuses are in [Refresh scheduling and monitoring](/docs/data-studio/refresh-and-jobs/). ## Expected result Validation has no errors, the previewed SQL matches the declared grain, and Compile creates the intended warehouse table with plausible dimensions, measures and row count. Refresh History records the manual build and, if scheduled, a later scheduled full rebuild. The dataset is offered in the dashboard designer's dataset source picker and in **Dashboards → From Dataset**. ## Common problems **Validation keeps failing on column references.** Expressions are checked against the bound data model's *output columns* — the names the model publishes, not the operational entity's field labels. Open the model's Columns tab and use its output column names verbatim; the pick lists in the dimension and measure dialogs exist precisely to prevent this mismatch. **Compile is refused and no run appears in history.** Validation failed — a compile only starts, and only writes a history entry, once validation passes. Run **Validate**, fix the errors it lists, and compile again. **Compile fails with a connectivity error.** The analytics warehouse was unreachable; nothing was built. The failed run stays in history with the message; retry later. **The dataset never refreshes on its own.** The three silent causes: the dataset is inactive, the schedule is blank (manual-only is valid), or the cron expression is invalid — an unparseable schedule is skipped without an error anywhere. Fix the expression and the next due occurrence runs. The dataset's creator receives an in-app and email notification on the first *failed* scheduled refresh, but a refresh that never starts sends nothing. **Binding shows Unmapped or Ambiguous on the list page.** The **Dataset binding status** panel is for datasets created before models existed, or whose model link was lost. **Refresh Binding Check** re-evaluates every dataset's fallback source table against published, active models; **Apply Matched Bindings** writes the model link only for rows whose status is *matched* and that have no model yet. *Ambiguous* means more than one model claims the same table — bind that dataset by hand through **Edit**. ## Common questions ### When should I build a dataset instead of a report? Build a dataset when the workload is analytical: pre-aggregated numbers over large or archived history, refreshed on a schedule, consumed by several dashboards at once. Use a plain report for operational listing and grouping of live records — it is immediate, needs no modelling, and reflects this minute's data. The dividing question: should this definition be computed once and shared, or asked fresh each time? ### What is the difference between Full and Incremental refresh? In current releases, none in behaviour — every refresh is a full rebuild: the table is dropped and recreated from the model's data each run, which is what guarantees the dataset exactly matches its definition. The refresh type is stored with the dataset and shown in the list, but it does not change how a refresh executes, so size your schedules assuming full rebuilds. ### What does Visibility do? Today it is descriptive. *Private*, *App* and *Shared* are stored and shown in the list and the Overview, but no surface filters on them: the dashboard designer's dataset picker and **From Dataset** list every active dataset. Use the setting to record intent, and use the **Active** flag when a dataset must actually disappear from pickers. ### Can a dataset skip the data model and read a table directly? Yes — the **Fallback Source Table** exists for exactly that, and the workspace banner will tell you authoring is "mostly free text" in that mode: no root-source guidance, no column pick lists, no schema-aware validation. Treat it as the escape hatch, not the pattern; the governed path is a published data model, for the reasons in [Data models and materialization](/docs/data-studio/data-models/). ## Related topics - [Data models and materialization](/docs/data-studio/data-models/) - [Row-level security on datasets](/docs/data-studio/row-level-security/) - [Refresh scheduling and monitoring](/docs/data-studio/refresh-and-jobs/) - [Troubleshooting Data Studio](/docs/data-studio/troubleshooting/) - [Dashboards in xMatix](/docs/analytics/dashboards/) ---- # xMatix Data Studio URL: https://xmatix.com/docs/data-studio/ Last reviewed: 2026-09-06 Data Studio is the modelling layer beneath xMatix analytics. Where the [Analytics section](/docs/analytics/) covers consuming numbers — reports, dashboards, pivots — Data Studio covers governing them: reusable data models built once and shared, datasets shaped for analysis and rebuilt on a schedule, row-security declarations that live with the dataset, and archival rules that move cold history out of the working system. Define revenue once here, and everything downstream means the same thing by it. ## The pipeline in one paragraph Operational records live in entities. A **data model** joins entities (and archived or externally landed warehouse tables) into a governed, reusable structure and materializes it into the analytics warehouse — a managed warehouse provisioned for your organization. A **dataset** is built *from* a data model: named dimensions and measures over that structure, compiled into SQL and materialized as its own warehouse table on a refresh schedule. Datasets are what analysis consumes — dashboard widgets can read them directly. **Archive rules** feed the warehouse from the other direction, moving cold operational rows into archive tables that data models can also read. Every materialization step is logged, schedulable and inspectable. ## Read the Dataset Builder @[guided-image](_img/data-studio-overview.png) The Dataset Builder is the working surface of Data Studio's consumption layer. The **Dataset binding status** panel reports how many datasets are bound to a published model and how many are unmapped, ambiguous or missing their source; the table below lists every dataset with its **Data Model**, **Binding**, **Refresh** type, **Visibility**, **Active** flag and last update, with **Open Workspace**, **Edit** and **Delete** on each row. **New Dataset** creates the dataset shell — the definition is then authored in the workspace. The build procedure is in [Build a dataset](/docs/data-studio/datasets/). ## What's in this section | Page | What it covers | | --- | --- | | [Build a dataset](/docs/data-studio/datasets/) | The Dataset Builder end to end — sources, dimensions, measures, filters, compile, validate, preview and refresh | | [Data models and materialization](/docs/data-studio/data-models/) | What a data model is, what building one produces, and how models relate to datasets | | [Row-level security on datasets](/docs/data-studio/row-level-security/) | Row security rules — what a rule declares, how rules are validated, and how they relate to build-time filters | | [Archive rules](/docs/data-studio/archive-rules/) | Rule-based archival — what qualifies, scheduling, and where archived data goes | | [Governed embedded BI](/docs/data-studio/embedded-bi/) | The embedded BI design — the asset allowlist and how datasets are meant to feed it (preview) | | [Refresh scheduling and monitoring](/docs/data-studio/refresh-and-jobs/) | Cron schedules, what triggers a run, run statuses and history — for datasets, models and archive rules | | [Troubleshooting Data Studio](/docs/data-studio/troubleshooting/) | Stale datasets, missing rows, failed builds — the working method for each | ## Where it lives in the product Data Studio has two entry points, deliberately split by audience: - Setup no longer carries a Data Studio section, and the org-wide analytics admin page that used to list every report and dashboard is gone with it: reports and dashboards are created, designed and deleted on the front end. **Archive Rules** lives under **Setup → Process Studio** (a rule runs on a schedule rather than defining anything analytics reads) and **Consent** under **Setup → Access Control** (it governs who may use whose data). - **Dataset Builder** (`/analytics/datasets`) and **Data Model Builder** (`/analytics/data-models`) are application pages, not Setup screens. Dataset Builder ships as a navigation item of the standard Analytics app, after Reports and Dashboards; Data Model Builder is available as a **Feature** navigation item that an administrator adds to an app (Setup → Apps → navigation items → type *Feature* → the route), so the people who model data work inside the app they already use. Access follows those two shapes. The Setup screens are capability-gated — **Analytics** requires the analytics administration capability (`setup.metadata.analytics.manage`), **Archive Rules** the archive administration capability (`setup.metadata.archive.manage`) — so modelling and archival can be held by different people. The two builder pages are reached through app navigation: who can model data is controlled by which apps carry those routes and who can open those apps. ## What Data Studio does not do yet Two settings are recorded on a dataset but do not change behaviour in current releases, and it is better to know that up front than to discover it in production: - **Refresh type.** *Full* and *Incremental* are both accepted, but every refresh is a full drop-and-rebuild of the warehouse table. Size schedules for full rebuilds. - **Visibility.** *Private*, *App* and *Shared* are stored and shown, but nothing filters on them yet — dashboard designers see every active dataset. Dataset **security rules** are likewise declarations that travel with the definition and appear in the preview; they are not applied to the compiled table, and no consuming surface applies them at read time yet either — use dataset **filters** or separate datasets when rows must genuinely be excluded. The details and the consequences are in [Row-level security on datasets](/docs/data-studio/row-level-security/). ## Common questions ### What is the difference between Data Studio and Analytics? Analytics is where numbers are consumed: dashboards, reports, pivots. Data Studio is the layer beneath — the data models, datasets, refresh schedules, security declarations and archival rules those consumers draw from. The practical consequence: when a number is *wrong everywhere*, the fix is usually one place in Data Studio, not a hunt through every report. See the [Analytics documentation](/docs/analytics/) for the consumption side. ### Do we need our own data warehouse or BI team? No. Datasets and data models materialize into a managed warehouse that is provisioned and maintained as part of the platform — there are no pipelines to build or servers to run. What your organization supplies is the modelling judgment: which entities join into which models, which dimensions and measures matter, and what "cold" means for archival. ### Who is told when a scheduled refresh breaks? The dataset's creator. The first failed scheduled refresh sends an in-app notification and an email with the error; repeated failures stay quiet, and the next success after a failure sends one more message saying the dataset is healthy again. Data model builds and archive runs record their outcome in history but do not notify anyone — see [Refresh scheduling and monitoring](/docs/data-studio/refresh-and-jobs/). ## Related topics - [Analytics documentation](/docs/analytics/) - [Delete, recycle bin, archive and restore](/docs/concepts/data-lifecycle/) - [Data Studio on the xMatix site](/products/data-studio/) - [See Data Studio in a demo](/demo/) ---- # Refresh scheduling and monitoring URL: https://xmatix.com/docs/data-studio/refresh-and-jobs/ Last reviewed: 2026-09-06 Three Data Studio objects execute on schedules: dataset refreshes, data model builds and archive runs. All three share one scheduling mechanism and one logging discipline — a cron expression on the object, a background scheduler that queues due work, and an append-only run history per object — so learning the rules once covers all of them. This page is the reference for those shared rules and the per-object specifics. ## The three scheduled jobs | Job | Scheduled by | What a run does | History | | --- | --- | --- | --- | | Dataset refresh | The dataset's **Refresh Schedule** | Validates the dataset, regenerates its SQL and rebuilds its warehouse table in full | **Refresh History** tab of the dataset workspace | | Data model build | The model's **Refresh Schedule** | Validates the model, regenerates its SQL and rematerializes its warehouse object in full | **Build History** tab of the model workspace | | Archive run | The archive rule's **Schedule** | Resolves the cutoff, copies qualifying rows to the warehouse, deletes them from the operational database | **History** action on the rule's row | Each also runs on demand — **Compile** on a dataset, **Build** on a model, **Run** on an archive rule. Manual and scheduled runs execute the same code and land in the same history; the difference is only what triggered them and, for datasets, who is notified. ## Cron rules Schedules are standard five-field cron expressions — minute, hour, day of month, month, day of week — for example `0 3 * * *` (daily at 03:00) or `0 2 * * 0` (Sundays at 02:00). Four rules matter in practice: - **Evaluation is in UTC.** There is no per-organization time zone on schedules; convert your intended local time to UTC when writing the expression. - **A blank schedule means manual-only.** Nothing runs automatically; the object still works via its manual action. This is a legitimate configuration, not a misconfiguration. - **An invalid expression is skipped silently.** The field accepts any text; a malformed expression raises no error at save time, in the history or in the logs — the object simply never runs on schedule. When something "never runs", verify the cron expression first. - **The scheduler evaluates every minute.** A due occurrence is picked up within about a minute of its time; the run itself then queues behind whatever else is executing. ## When a scheduled run fires Every minute the scheduler evaluates each eligible object and queues a run when a cron occurrence has passed since the object's **last successful run**. The eligibility gates, per object: - **Datasets** — **Active**, with a non-blank schedule. - **Data models** — **Active and Published**, with a non-blank schedule. A draft model never builds on schedule, whatever its cron says. (Published is a toggle in the model's Edit dialog — there is no separate publish action.) - **Archive rules** — **Active**, with a non-blank schedule. Three consequences of the "last successful run" baseline are worth knowing: - **Failed runs do not advance it.** A failing object is retried at each subsequent occurrence rather than dropped, so a persistent failure shows up as a run of failures in history, not as an absence. - **Nothing is replayed.** An object with no successful run yet starts from a two-minute look-back at the moment it becomes eligible, so a schedule you set for an hour ago does not fire retroactively — the first run is the next occurrence. After downtime, a long-inactive period or a run of failures, the object runs once and is current again; missed occurrences are not executed one by one (for archive rules that single run covers the whole accumulated backlog). - **Duplicates are skipped.** If a queued occurrence is processed after a later run already succeeded, it is discarded. Archive rules go further and record the skip (see below). ## Run records and statuses Every run that starts — manual or scheduled, successful or not — appends a history entry with started and completed times, status, row count, duration and an error message on failure. Statuses as the surfaces label them: | Surface | Statuses | | --- | --- | | Dataset refresh history | Queued, Running, **Success**, Failed, Canceled | | Data model build history | Pending, Running, **Succeeded**, Failed, Canceled | | Archive run history | Queued, Running, Success, Failed, Canceled, **Skipped Duplicate** | **Skipped Duplicate** is unique to archiving: a run whose window — same rule, cutoff, target, date field and condition — was already covered by a running or successful run records itself as skipped, referencing the run it duplicated, instead of re-archiving. Histories show the most recent 50 runs; they are append-only, so the trail of an incident survives its resolution. ## Who is notified | Job | On failure | On recovery | | --- | --- | --- | | Dataset refresh (scheduled) | The dataset's creator receives an in-app notification and an email with the error — once, on the first failure after a success | One in-app notification and email when the next scheduled refresh succeeds again | | Dataset compile (manual) | Nothing beyond the toast and the history row | — | | Data model build | Nothing — check Build History | — | | Archive run | Nothing — check the rule's History | — | The dataset notification is deliberately quiet: a dataset that has been broken since Tuesday does not mail its owner every hour. It also only fires for runs that *start* — a dataset that never becomes due (inactive, blank or invalid schedule) sends nothing. ## Reading the history well - **Row count** is the run's own output: rows materialized for refreshes and builds, rows moved for archive runs. Zero is a normal value when nothing qualified, not an error. - **Error message** carries the underlying reason on failure — a SQL error in an expression, a missing field, warehouse connectivity. It is the first thing to read, and usually the last. - **A validation failure leaves no run at all** for datasets and models — the SQL is only generated and executed once validation passes. History silence plus a validation error in the UI means the definition, not the execution, is what needs fixing. A scheduled run that fails validation is recorded as a notification to the dataset's creator but not retried until the next occurrence. - **Every run is a full rebuild.** The refresh type stored on a dataset (*Full* / *Incremental*) does not change execution; durations therefore track total data volume. A dataset whose rebuild time grows steadily is telling you about data growth — worth knowing before, not after, the schedule window gets tight. ## Common questions ### Why did my scheduled job never run? Answer in order of likelihood: the object is inactive; the schedule is blank; the cron expression is invalid (skipped silently, with no error surfaced anywhere); or — for data models only — the model is not published. All four produce the same symptom, an empty or unmoving history and a **Last refresh** of *Never run* in the dataset list, and all four are visible on the object's Overview in under a minute. A fifth, rarer cause: the analytics warehouse was unreachable at every occurrence — that one *does* leave failed runs in history. ### Do failed runs stop the schedule? No. The schedule measures itself against the last *successful* run, so an object that failed will be tried again at the next occurrence rather than abandoned. That is the safe default — transient warehouse connectivity heals itself — but it means a definitional error (a bad expression, a renamed field) produces repeated failures until someone fixes the definition or deactivates the object. A history full of identical failures is a fix-me signal, not a wait-it-out signal. ### What time zone do schedules use? UTC, always. An expression like `0 3 * * *` runs at 03:00 UTC regardless of where your organization or its users are. Write schedules in UTC deliberately — especially for archive rules and heavy dataset rebuilds you want inside a quiet window, since "quiet at 3 a.m." is only true in the time zone you meant. ### Can I see when the next run is due? Not on the Data Studio screens — the dataset and model Overview show the cron expression and the history shows the past, but there is no "next due" column. Work it out from the expression in UTC, or watch **Refresh History** after the first expected occurrence. ## Related topics - [Build a dataset](/docs/data-studio/datasets/) - [Data models and materialization](/docs/data-studio/data-models/) - [Archive rules](/docs/data-studio/archive-rules/) - [Troubleshooting Data Studio](/docs/data-studio/troubleshooting/) ---- # Row-level security on datasets URL: https://xmatix.com/docs/data-studio/row-level-security/ Last reviewed: 2026-09-05 A dataset can carry **row security rules**: declarations, stored with the dataset itself, of which role should see which rows. Each rule pairs a role with a row filter — a predicate over the dataset's columns — so the scoping decision is made once, where the data is defined, rather than re-implemented inside every report that consumes it. This page explains what a rule declares, how the platform checks it, and — just as important — what row security is *not*, so you choose the right tool when the requirement is a hard guarantee. The dataset definition establishes the boundary within which later Security-tab rules operate. A published data model or fallback table supplies the data, Grain defines what one row means, Visibility controls who may discover the dataset, and the warehouse table stores the full materialized result. Row-security declarations added after creation slice that result for named roles; they do not change the dataset's grain or physically remove rows. Choose the broadest legitimate audience first, then decide whether a requirement is advisory consumer-side scoping or a hard exclusion. Use a build-time filter or separate dataset for data that must never enter the materialized table, and use Security-tab role predicates only when every consuming surface is verified to enforce them. ## What a rule declares Row security rules are authored on the **Security** tab of the [dataset workspace](/docs/data-studio/datasets/). Each rule has: - **A role** — the audience the rule scopes. Every active rule must name one; validation blocks a compile otherwise. - **A row filter expression** — a SQL predicate over the dataset's columns describing the rows that role should see, for example `RegionCode = 'WEST'` on a dataset with a region dimension. - **A display order and an active flag** — rules are ordered, and inactive rules are ignored entirely. A dataset can carry several rules, one per audience. The declared meaning is scoping, not permission to open the dataset: members of the named role are meant to see the matching rows of a dataset they can already reach. ## How rules are checked Rules participate in the dataset's design-time machinery. **Validate** requires every active rule to carry both a role and a non-empty expression, and — when the dataset is bound to a published data model — checks the expression's column references against the model's published schema, so a rule cannot silently name a column that will not exist. **Preview** lists the active security rules alongside the filters and the generated SQL, making the dataset's full declared contract reviewable in one place before anything is built. ## What row security is not Two boundaries keep expectations honest: - **The materialized table is not per-user filtered.** A dataset compiles into a single warehouse table holding the full results of its definition. Row security rules are not baked into the table; they are applied when the dataset is read. **Native xMatix dashboards apply them:** a dataset tile is filtered to the rules for the viewer's roles — including roles below theirs in the role hierarchy — and a viewer who matches no rule on a secured dataset sees no rows at all (never an unfiltered result). Rules are combined with OR, so a viewer in two audiences sees both slices. Other consumers of the warehouse table (an embedded BI tool reading it directly, an export) do not apply these rules; where the requirement is absolute for those surfaces, use **dataset filters** instead — a build-time filter genuinely excludes rows from the table — or split the data into separate datasets per audience. - **It is not the application's record security.** Record-level security governs who sees which records in the live application. Datasets are separate tables in the analytics warehouse, built from the model's data as defined — a user's operational record permissions do not follow rows into a dataset. The two systems answer different questions: [record security](/docs/administration/record-security/) protects the operational system; dataset scoping decides what an analytical audience is served. The practical design rule that follows: build each dataset at the scope of its broadest legitimate audience, use filters or separate datasets for hard exclusions, and use row security rules to express per-role slicing within that audience. ## Common questions ### Is the dataset's warehouse table filtered per user? No. Compilation writes one table containing everything the dataset's definition produces — dimensions, measures and build-time filters applied, row security rules not. Per-role scoping happens at read time: native dashboards apply the rules for the viewer's roles on every query (and fail closed when none match). Surfaces that read the warehouse table directly do not, which is why the hard-guarantee tools for those are the ones that shape the table itself: dataset filters, or one dataset per audience. ### Does dataset row security replace record-level security? No — they operate on different data in different places. Record-level security (sharing, restriction rules, profiles) governs live records in the application and keeps doing so regardless of anything in Data Studio. Dataset row security scopes analytical outputs in the warehouse. A user barred from an account record by [record security](/docs/administration/record-security/) is not automatically barred from aggregate numbers a dataset computed over it — if that matters for your data, scope the dataset accordingly. ### Who can define row security rules? Anyone holding the analytics administration capability (`setup.metadata.analytics.manage`) — the same grant that covers datasets and data models, since the rules are part of the dataset's definition. There is no separate row-security permission; what there is instead is validation, which refuses to compile a dataset whose active rules are incomplete. ## Related topics - [Build a dataset](/docs/data-studio/datasets/) - [Record-level security and sharing](/docs/administration/record-security/) - [How the xMatix security model works](/docs/concepts/security-model/) - [Data Studio overview](/docs/data-studio/) ---- # Troubleshooting Data Studio URL: https://xmatix.com/docs/data-studio/troubleshooting/ Last reviewed: 2026-09-01 Data Studio problems have short diagnoses, because every materialization is logged: each dataset, data model and archive rule carries an append-only run history with statuses, row counts and error messages. The method on this page is always the same — find the object's history, read the newest entries, and let them tell you which of the usual causes you have. Guessing is never necessary; the trail is on the object. Start diagnosis from the newest run history, then follow lineage upstream and downstream: dataset refresh, model build, source entity, archive rule and target table. Compare timestamps, row counts and errors at each hand-off rather than rerunning jobs blindly. ## A dataset is stale Work down the chain from the dataset's **Refresh History** tab: 1. **No runs at all, or nothing recent.** The schedule never fires: the dataset is inactive, the schedule field is blank (manual-only), or the cron expression is invalid — invalid expressions are skipped silently, with no error anywhere. The [scheduling rules](/docs/data-studio/refresh-and-jobs/) list all the eligibility gates. 2. **The newest run is Failed.** Read its error message. Warehouse connectivity failures heal on retry — and the schedule retries failed objects automatically. SQL errors in expressions do not; fix the definition, **Validate**, and compile once manually. 3. **Runs succeed but the data is older than expected.** The schedule's cadence is the freshness — remember cron is evaluated in UTC, so a "daily 3 a.m." schedule may be firing in the middle of your business day or eight hours later than you assumed. 4. **The dataset is fresh, but a downstream surface is not.** A dashboard or embedded BI report has its own consumption step: [embedded BI models need their own refresh](/docs/data-studio/embedded-bi/) after the dataset's table updates. 5. **The dataset is fresh but the model is not.** A dataset rebuild reads the model's *materialized* table, so a stale model gives a fresh-looking dataset with old numbers. Check the model's **Build History** the same way. ## Rows are missing from a dataset Missing rows were excluded somewhere on the way in. Check the gates in the order the data passes them: 1. **The data model's filters and joins.** Model filters exclude rows at the source, and an **inner** join drops every row without a match — the classic silent absence. If orders without a customer vanish, the customer join being inner instead of left is the first suspect. 2. **The dataset's filters.** Build-time filters are ANDed into the compile; excluded rows are genuinely absent from the table. **Preview** shows the active filters and the generated SQL, which settles what the build actually asked for. 3. **Aggregation.** A dataset's rows are its dimension combinations. A "missing" record may be present but folded into an aggregate row — check whether the grain you expect matches the dimensions the dataset defines. 4. **Archival.** If an [archive rule](/docs/data-studio/archive-rules/) moved the rows out of the operational database, a model sourcing only the live entity no longer sees them. The rule's run history shows what moved and when; the fix is a model that also reads the archive table. 5. **Row security is not the cause of missing rows in the table.** Security rules do not remove rows from the materialized data — if an audience is missing rows in a consuming surface, that is the surface's scoping, not the build; see [row-level security](/docs/data-studio/row-level-security/) for what rules do and do not guarantee. ## A compile or build fails — or refuses to start - **Refused with validation errors, and no history entry.** Compilation only starts once validation passes, so a refused compile leaves no run. Run **Validate** and fix what it lists — the most common error is an expression referencing a column the bound data model does not publish. Use the model's output column names, not the operational entity's field labels; the editors' pick lists exist to make that automatic. - **Fails with a connectivity error.** The analytics warehouse was unreachable; nothing was written. The failed run stays in history with the message. Retry later — scheduled objects retry on their own. - **Fails with a SQL error.** Dimension, measure and filter expressions are warehouse SQL, executed as written. Preview the generated SQL, find the offending expression, fix it, validate, recompile. - **The workspace warns "Data Model schema is unavailable".** The dataset is bound, but the model's schema could not be loaded — authoring guidance degrades to free text, while compile-time validation still runs. Confirm the bound model still exists and publishes columns. ## Records disappeared from the application When users report records gone from lists — not from a dataset, from the *application* — and nobody deleted them, check the [archive rules](/docs/data-studio/archive-rules/) before the recycle bin. An archive run moves qualifying rows out of the operational database entirely: they stop appearing in lists, live reports and API queries, and they are not in the recycle bin, because they were never deleted. The rule's run history shows exactly when a run succeeded and how many rows it moved; if the wrong rows qualified, the rule's condition formula was too broad — tighten it, and recover the affected rows by copying them back from the warehouse table (an operator-level task; there is no in-product restore). The deleted-versus-archived distinction is laid out in [the data lifecycle](/docs/concepts/data-lifecycle/). ## Common questions ### Where do I see why a run failed? On the object's history: the **Refresh History** tab for datasets, **Build History** for data models, the **History** row action for archive rules. Every failed run carries the underlying error message, and the histories are append-only, so the evidence survives the fix. The one silence to know about: a dataset or model refused at validation leaves no run — the findings are in the **Validate** dialog instead. ### A run says Success with zero rows — is that a failure? Usually not. Zero is a legitimate output: nothing qualified for an archive rule's window, or a dataset's filters excluded everything currently in the model. It becomes a symptom only when you *expected* rows — then read it as "the definition matched nothing" and check the filters, joins and cutoffs rather than the execution. ### The numbers are wrong in every report at once — where do I start? At the model, not the reports. When every consumer of a dataset agrees on the same wrong number, the shared definition produced it: check the dataset's measures and filters, then the data model's joins and columns, then the freshness of both materializations. This is the intended failure mode of governed analytics — one place to fix instead of ten — and the histories tell you whether the definition or the data changed underneath it. ## Related topics - [Build a dataset](/docs/data-studio/datasets/) - [Data models and materialization](/docs/data-studio/data-models/) - [Refresh scheduling and monitoring](/docs/data-studio/refresh-and-jobs/) - [Archive rules](/docs/data-studio/archive-rules/) - [Delete, recycle bin, archive and restore](/docs/concepts/data-lifecycle/) ---- # Dashboards and reports in the CLI URL: https://xmatix.com/docs/developer/cli/analytics/ Last reviewed: 2026-08-15 `xmatix dashboards` and `xmatix reports` round-trip analytics definitions — including the embedded designer XML payloads that hold a dashboard's layout and a banded report's design — as one JSON file per artifact. Files carry the **complete** server row, not a trimmed summary, so server-only fields survive a pull → edit → push cycle untouched. ``` xmatix dashboards list xmatix dashboards pull # → xmatix/analytics/dashboards/.json xmatix dashboards pull xmatix dashboards push # update if the id resolves, create otherwise xmatix dashboards push --new xmatix reports list xmatix reports pull # → xmatix/analytics/reports/.json xmatix reports pull xmatix reports push ``` ## File shape Each file is the full definition row, so everything the designers persist is present: - **Dashboards** — `layoutDefinition` (the dashboard designer's XML), `settings`, `filterDefinitions`, `dashboardType` (`DataStudio` or `Sql`), `folder`, `icon`, `sortOrder`, `isActive`. - **Reports** — `queryText`, `columnDefinitions`, `filterDefinitions`, `defaultPageSize`, `reportFormat`, `compactWidth`, and `designLayoutXml` (the banded-report designer's layout) for banded reports. The XML payloads are large and designer-owned; treat them the way you treat a workflow's activity tree — reviewable as a diff, editable by hand only for mechanical changes, with the in-product designer as the real editor. ## Push semantics - `pull` first enumerates ids from the dashboards and reports listings, then fetches each artifact's complete row individually — which is why the files are full-fidelity. - `push` **updates** when the file's `id` still exists on the server and **creates** otherwise; `--new` forces a create even when the id matches (the copy-to-another-tenant case). - Before sending, the CLI strips read-only audit columns and the visibility/ACL navigation collections, so the request matches what the server accepts. **Visibility does not round-trip yet.** Who can see a dashboard or report — roles, profiles, teams, "all users" — lives in separate access-control tables and is not carried by these files. After creating an artifact on a new tenant via push, set its visibility in the product; this is planned for a future phase. ## Common questions ### My pushed dashboard is invisible to everyone — why? Because visibility is not part of the file. A freshly created dashboard or report has no access grants until someone assigns them in the product — the definition arrived intact; the audience did not. This bites hardest in tenant-to-tenant promotion: budget a manual visibility pass (or a checklist entry) after the first push of each artifact. ### Can I hand-edit queryText or the filter definitions? Yes — the textual fields (`queryText`, `columnDefinitions`, `filterDefinitions`, page size, format) are the most hand-editable part of these files and diff beautifully. The XML payloads are where caution applies: they are the designers' persistence formats, and a structurally broken edit surfaces as a designer error rather than a push error. Change them mechanically (a renamed field reference) or through the designer. ### What is the difference between the two dashboardType values? `DataStudio` dashboards are built in the interactive dashboard designer over data models; `Sql` dashboards are driven by a query. The CLI treats both identically — the type rides along in the file — but knowing which you are looking at explains which fields carry the substance (`layoutDefinition` for the former, the query for the latter). ## Related topics - [Snapshots](/docs/developer/cli/snapshot/) - [Migrations](/docs/developer/cli/migrate/) - [Workspace layout](/docs/developer/cli/workspace/) - [The data API](/docs/developer/data-api/) ---- # CLI authentication URL: https://xmatix.com/docs/developer/cli/authentication/ Last reviewed: 2026-08-15 The CLI authenticates against your organization's customer identity (CIAM) sign-in authority using the OAuth 2.0 device-code flow: `xmatix login` prints a verification URL and a short code, you complete sign-in in any browser — including on another machine — and the CLI receives tokens for the account you signed in as. Every subsequent command acquires a token silently from the cache and calls the API as that user, so the CLI's reach is always exactly the signed-in user's permissions. ``` xmatix login --tenant \ --api-base-url --authority --client-id xmatix whoami # prints the signed-in user and tenant xmatix logout # clears cached accounts for the workspace's tenant ``` The four `login` flags are needed once — they persist into the workspace config — after which a bare `xmatix login` re-runs the device-code flow with the stored settings whenever a session expires. ## The token cache Tokens are cached per tenant under `~/.xmatix/tokens/` in your home directory — not in the repository — and the cache file is encrypted with the operating system's native secure storage: the keychain on macOS, DPAPI on Windows, and the keyring/secret service on Linux. Silent acquisition refreshes tokens automatically; when a refresh is no longer possible (expiry, revocation, a password change), commands fail with a message telling you to run `xmatix login` again. `xmatix logout` removes all cached accounts for the tenant. ## Configuration `.xmatix/config.json` carries the tenant-scoped settings every command needs. It is created by `xmatix init` and populated by the first full `xmatix login`: ``` { "tenant": "", "apiBaseUrl": "", "authority": "", "clientId": "", "scopes": "", "apiVersion": "v1" } ``` | Setting | Meaning | | --- | --- | | `tenant` | Your tenant slug — it namespaces the token cache | | `apiBaseUrl` | The base URL of your organization's xMatix API | | `authority` | Your organization's sign-in authority URL | | `clientId` | The registered OAuth client id of the CLI application | | `scopes` | Space-separated OAuth scopes; when empty, defaults to `{apiBaseUrl}/.default` | | `apiVersion` | The API version segment used in routes (`v1`) | The file contains no secrets — committing it is how a whole team shares one working setup. Your administrator supplies the values; `xmatix doctor` verifies all of them plus a live token and an API round-trip. ## Non-interactive use Only the device-code flow is implemented today — there is no service-principal or client-credentials sign-in yet. For CI this means a job cannot mint a session from environment variables; the working pattern is a persistent, access-controlled runner on which `xmatix login` was completed once, after which silent acquisition keeps the cache fresh across jobs. The [CI recipes](/docs/developer/cli/ci/) page is written around this constraint, and non-interactive sign-in is planned. ## Common questions ### How do I work against two tenants? One workspace per tenant. The config file binds a workspace to a single tenant, and the token cache is namespaced by tenant slug — so two checkouts (or two repositories) each with their own `.xmatix/config.json` coexist cleanly on one machine, each signing in and caching independently. ### Does the CLI ever see or store my password? No. The device-code flow hands authentication entirely to your organization's sign-in page in the browser — the same page, policies and factors as signing in to the product. The CLI receives only the resulting tokens, and stores them encrypted by the OS credential store. ### Why does every teammate sign in as themselves rather than a shared account? Because the CLI executes with the signed-in user's permissions and the platform records who did what. A shared account erases that audit trail and usually holds broader permissions than any one person needs. Individual sign-in costs nothing — the config is shared through git; only the sign-in itself is per person. ## Related topics - [The xMatix CLI](/docs/developer/cli/) - [CLI quickstart](/docs/developer/cli/quickstart/) - [CI recipes](/docs/developer/cli/ci/) - [Troubleshooting](/docs/developer/troubleshooting/) ---- # CI recipes URL: https://xmatix.com/docs/developer/cli/ci/ Last reviewed: 2026-08-15 The CLI's verbs compose into three pipeline patterns: a **drift gate** that fails a build when the live tenant no longer matches the repository, a **promotion** job that applies a tagged repository state to a tenant, and a **release-time snapshot** that proves the repo captured everything before shipping. All three start with `xmatix doctor` so auth, config and connectivity problems fail fast with a named cause. One constraint shapes everything on this page: the CLI signs in with a device-code flow only — there is no service-principal sign-in yet (see [Authentication](/docs/developer/cli/authentication/)). Pipelines therefore run on a **persistent, access-controlled runner** where `xmatix login` was completed once; the encrypted token cache then serves silent sign-ins across jobs. On ephemeral runners the recipes below will fail at `doctor`'s token check until non-interactive sign-in ships. ## Drift gate Fails the build if any artifact changed on the live tenant since the last commit — run it on pull requests and on a schedule: ``` name: drift-gate on: [pull_request, schedule] jobs: drift: runs-on: [self-hosted, xmatix-runner] steps: - uses: actions/checkout@v4 - run: | xmatix doctor xmatix migrate plan jq -e '.counts.modified == 0 and .counts.removed == 0' \ xmatix/.snapshot/migrate-plan.json ``` `migrate plan` exports a fresh snapshot from the tenant and hash-compares it against the checkout ([how the plan works](/docs/developer/cli/migrate/)); the `jq` assertion turns its counts into a pass/fail. A failing gate means someone changed the tenant in the product without exporting — the fix is a fresh `snapshot export` committed through review, not a forced apply. ## Promote a release Applies the repository state to the tenant when a release tag is pushed: ``` name: promote on: push: tags: ['v*'] jobs: promote: runs-on: [self-hosted, xmatix-runner] steps: - uses: actions/checkout@v4 - run: xmatix doctor - run: xmatix migrate apply --dry-run - run: xmatix migrate apply ``` The `--dry-run` before the real apply is cheap insurance: it prints exactly what will be pushed, so a mis-scoped checkout or a missing folder aborts before anything is written. Remember that apply never deletes server artifacts — removals stay manual by design. ## Release-time snapshot For any CI system — three commands and a git check prove the repository captured the tenant as shipped: ``` xmatix doctor xmatix snapshot export git diff --exit-code xmatix/ ``` A non-zero exit from `git diff` means the export produced changes the repo did not have — the release is drifting from its own record. Archive the diff as a build artifact when this gate fails; it is the exact list of what was changed in-product. ## Local pre-commit hook A lightweight local guard that keeps metadata honest before it ever reaches CI — in `.git/hooks/pre-commit`: ``` #!/usr/bin/env bash set -e xmatix doctor git diff --cached --name-only | grep -q '^xmatix/' \ && xmatix metadata diff xmatix/metadata/tenant-owned.json ``` When a commit touches the artifact tree, [`metadata diff`](/docs/developer/cli/metadata/) compares the committed seed-pack against a live export, so a stale metadata file gets caught at commit time rather than at review. ## Common questions ### Which user should the pipeline sign in as? A dedicated integration account with exactly the customization capabilities the pipeline needs — the CLI acts with the signed-in user's permissions, so the account's grants are the pipeline's blast radius. Sign that account in once on the runner, and treat the runner's home directory (where the encrypted token cache lives) with the same care as any credential store. ### How does the pipeline know which tenant it targets? From the checked-out `.xmatix/config.json` — the workspace *is* the targeting. This is worth making explicit in the repo structure: one repository (or one directory with its own workspace) per tenant, so a pipeline can never apply the right files to the wrong tenant by picking up an unexpected config. ### Can the drift gate and promotion target different tenants? Yes, with one workspace each — for example, drift-gating a production tenant while promoting to a staging tenant first. Each job checks out (or `cd`s into) the workspace for its tenant; nothing else changes, because every command resolves tenant, API and identity from the workspace it runs in. ## Related topics - [Migrations](/docs/developer/cli/migrate/) - [Snapshots](/docs/developer/cli/snapshot/) - [Authentication](/docs/developer/cli/authentication/) - [Troubleshooting](/docs/developer/troubleshooting/) ---- # The xMatix CLI URL: https://xmatix.com/docs/developer/cli/ Last reviewed: 2026-09-01 `xmatix` is a single command-line tool that gives developers a git-friendly, round-trippable view of every customizable artifact in a tenant: automation scripts, business rules, workflows, dashboards, reports and metadata. Each artifact kind has `pull` and `push` verbs that write to and read from a canonical folder tree, so a tenant's configuration can live in a repository, travel through pull-request review, and be promoted by pipeline. The CLI is currently in preview: commands and file formats are stable enough to document, but expect the tool to evolve. Before a CLI change, run `xmatix doctor`, pull the current tenant state, review the diff and preserve the server version or hash used for optimistic concurrency. After a push, verify the artifact's status and active version in its product workspace and inspect run history rather than assuming upload equals activation. ## Install and first run The CLI ships as a .NET global tool and runs anywhere the .NET 10 SDK does: ``` dotnet tool install -g xmatix.cli xmatix init # scaffold the workspace in your repo root xmatix login --tenant \ --api-base-url --authority --client-id xmatix doctor # pre-flight checks xmatix snapshot export # pull everything git add xmatix/ && git commit -m "tenant snapshot" ``` `init` creates the `.xmatix/` config directory and the folder tree; `login` runs a device-code sign-in and persists the connection settings (they are only needed once — see [Authentication](/docs/developer/cli/authentication/) for where each value comes from); `doctor` verifies everything before you rely on it. The [quickstart](/docs/developer/cli/quickstart/) walks this first session end to end. ## Command map | Command | What it does | Reference | | --- | --- | --- | | `login` / `logout` / `whoami` | Device-code sign-in, cached-token cleanup, current identity | [Authentication](/docs/developer/cli/authentication/) | | `init` / `doctor` | Scaffold the workspace; run every pre-flight check | [Workspace layout](/docs/developer/cli/workspace/) | | `metadata pull` / `push` / `diff` | Round-trip tenant metadata seed-packs | [Metadata](/docs/developer/cli/metadata/) | | `scripts list` / `pull` / `push` / `run` / `logs`, `runs tail` | Round-trip automation scripts, test them, tail run history | [Scripts](/docs/developer/cli/scripts/) | | `rules list` / `pull` / `push` | Round-trip business rules, one file per rule | [Business rules](/docs/developer/cli/rules/) | | `workflows list` / `pull` / `push` | Round-trip workflow definitions | [Workflows](/docs/developer/cli/workflows/) | | `dashboards` / `reports` `list` / `pull` / `push` | Round-trip analytics definitions | [Dashboards & reports](/docs/developer/cli/analytics/) | | `snapshot export` / `import` | Pull or push every artifact kind in one command | [Snapshots](/docs/developer/cli/snapshot/) | | `migrate plan` / `apply` | Diff the repo against the live tenant; promote the reviewed state | [Migrations](/docs/developer/cli/migrate/) | | `package init` / `build` / `validate` / `install` / `list` / `logs` / `uninstall` | Author and install metadata packages (manifest + seed-packs) | — | | `watch` | Auto-push files as you save them | below | | `completions` | Emit a shell completion script | below | ## Utilities ### xmatix doctor Runs every check the other commands assume: the workspace root resolves, `config.json` is readable and complete (authority, client id, scopes), the canonical folders exist (missing ones are noted as "created on first pull"), a token can be acquired silently, and a `whoami` round-trip against the API succeeds. Exit code 0 means healthy, 1 means at least one failure — run it as the first step of every pipeline job so auth, network and config drift fail fast with a named cause. ### xmatix watch Watches the round-trip folders and re-runs the matching `push` on every save — the tight loop for local development of scripts, rules and workflows: ``` xmatix watch # all artifact kinds xmatix watch --no-rules --no-reports xmatix watch --debounce 200 ``` Each kind has a `--`/`--no-` switch (`--no-scripts`, `--no-workflows`, `--no-dashboards`, …) and `--debounce` sets the quiet period in milliseconds. Every save spawns a child `xmatix … push` process, so one failing push never tears the watcher down; child output is forwarded indented so the stream stays readable. Ctrl+C exits cleanly. ### xmatix completions Emits a static completion script for `bash`, `zsh`, `fish` or `pwsh` — for example `xmatix completions zsh` — which you redirect into your shell's completions location. The script is static, so completion never invokes the CLI at prompt time. ## Common questions ### Is the CLI required to use automation scripts, rules or workflows? No. Everything the CLI round-trips is fully authorable inside the product — the CLI's value is the *representation*: real files in a real repository, diffable in pull requests, promotable by pipeline, and editable in your own editor. Teams typically start in the product and adopt the CLI when a tenant's configuration becomes something they want to review and release like code. ### What is safe to commit? Everything the CLI writes except caches and tokens. The `xmatix/` artifact tree and `.xmatix/config.json` are designed to be committed — the config file holds connection settings, never credentials. Sign-in tokens are cached per user in your home directory, encrypted by the operating system's credential store, and never land in the repository; `init` also writes a `.gitignore` inside `.xmatix/` as a belt-and-braces guard. ### Which platforms does it run on? Anywhere the .NET 10 SDK runs — the token cache uses the platform's native secure storage on each OS (keychain on macOS, DPAPI on Windows, the keyring/secret service on Linux), so no platform needs special handling. ## Related topics - [CLI quickstart](/docs/developer/cli/quickstart/) - [Authentication](/docs/developer/cli/authentication/) - [Workspace layout](/docs/developer/cli/workspace/) - [CI recipes](/docs/developer/cli/ci/) ---- # Metadata seed-packs URL: https://xmatix.com/docs/developer/cli/metadata/ Last reviewed: 2026-08-15 `xmatix metadata` round-trips the tenant's metadata — entities, fields, views, validations, relations and field mappings — as a single seed-pack JSON file. Pull writes a pretty-printed, deterministic file designed to be reviewed in git diffs; push imports a tenant-owned seed-pack back; diff compares a local file against a fresh live export without writing anything. ``` xmatix metadata pull # default scope: TenantOwned xmatix metadata pull --scope TenantOwned --out xmatix/metadata/tenant-owned.json xmatix metadata push xmatix metadata diff # local file vs fresh server export ``` ## Scopes `metadata pull` (and `diff`) accept a `--scope`; the default output file under `xmatix/metadata/` is named for the scope (`tenant-owned.json`, `tenant-full.json`, `base-metadata.json`, …), and `--out` overrides the path. | Scope | Purpose | | --- | --- | | `TenantOwned` *(default, round-trippable)* | Rows the tenant has created or customized | | `TenantFull` | The tenant's view including base metadata visible to it | | `BaseMetadata` | The platform-shipped baseline | | `PlatformModule` | A specific platform module (requires `--package-id `) | | `PackageOwned` | A specific installed package (requires `--package-id `) | | `Namespace` | All metadata in a logical namespace (requires `--namespace `) | Only `TenantOwned` is safe to round-trip through `metadata push` — the import endpoint updates only rows the tenant owns and ignores package-owned rows, so the other scopes are effectively read-only exports for inspection and comparison. `pull` also accepts `--mode full|delta` (default `full`) and `--version ` to select the seed-pack version. ## Push ``` xmatix metadata push xmatix/metadata/tenant-owned.json ``` Push validates the JSON locally before sending, then shows what it is about to import and asks for confirmation — pass `--yes` to skip the prompt in pipelines. `--source-subscription ` supports importing a seed-pack that was exported from a *different* tenant, so its internal references resolve against the source. The server-side import is the authority on what changes: tenant-owned rows are created or updated, everything else is ignored. ## Diff `xmatix metadata diff ` exports a fresh seed-pack into memory and compares it against the local file using deterministic JSON ordering. The output is grouped by table — Entities, EntityFields, EntityViews and so on — with added, removed and modified row counts plus samples of the differing values. Its natural job is a drift gate: run it in a pipeline (or a pre-commit hook) and fail when the live tenant no longer matches the last reviewed export, so untracked in-product changes surface as a diff instead of a surprise. For a drift gate across *all* artifact kinds, use [`migrate plan`](/docs/developer/cli/migrate/). ## Common questions ### Why is only TenantOwned round-trippable? Because ownership is the write boundary. Base metadata belongs to the platform and package metadata belongs to its package — importing either from a file would let a tenant overwrite rows it does not own, so the import endpoint only applies rows the tenant owns. Pull the wider scopes when you need to *see* the full picture; push only what the tenant can legitimately change. ### Does metadata push delete rows I removed from the file? No — the import creates and updates, it does not delete. Removing an entity or field is a deliberate act with data consequences, so it stays a manual operation in the product. The `removed` section of a [`migrate plan`](/docs/developer/cli/migrate/) tells you what exists on the server but not locally, so nothing disappears silently in either direction. ### How do I put a metadata change through pull-request review? Make the change (in the product or by editing the seed-pack), run `xmatix metadata pull`, and commit — the deterministic formatting keeps the diff scoped to what actually changed. Reviewers read the JSON diff like any code change; on merge, a pipeline runs `xmatix metadata push --yes` (or a full [`migrate apply`](/docs/developer/cli/migrate/)) against the target tenant. ## Related topics - [The data model](/docs/customization/data-model/) - [Snapshots](/docs/developer/cli/snapshot/) - [Migrations](/docs/developer/cli/migrate/) - [CI recipes](/docs/developer/cli/ci/) ---- # Migrations URL: https://xmatix.com/docs/developer/cli/migrate/ Last reviewed: 2026-08-15 `xmatix migrate` is the CI-friendly two-step for promoting a repository's checked-in state onto a target tenant: `plan` produces a reviewable diff manifest of exactly what a push would create and overwrite, and `apply` performs the push. The same pair, pointed at an unchanged repository, doubles as a drift detector — a plan that is not all-unchanged means the tenant was modified outside the repo. ``` xmatix migrate plan # → xmatix/.snapshot/migrate-plan.json xmatix migrate plan --keep-server-snapshot jq '.counts' xmatix/.snapshot/migrate-plan.json xmatix migrate apply --dry-run xmatix migrate apply ``` ## How migrate plan works 1. Bootstraps a temporary workspace in the OS temp directory, pointed at the same tenant as your repo (it copies your config). 2. Runs a full `snapshot export` into that temporary tree — a fresh, complete picture of the live tenant. 3. Walks each canonical folder — `metadata`, `automation/scripts`, `automation/rules`, `automation/workflows`, `analytics/dashboards`, `analytics/reports` — and content-hashes (SHA-256) every file in both trees. 4. Classifies each file: | Status | Meaning | What apply does | | --- | --- | --- | | `added` | Present locally, missing on the server | Creates it | | `modified` | Content hash differs | Overwrites the server | | `removed` | Present on the server, missing locally | **Nothing** — never deletes | | `unchanged` | Identical | Nothing | 5. Writes the structured manifest to `xmatix/.snapshot/migrate-plan.json` — generation time, per-status counts, and every entry with its path and status — sized for both human review in a pull request and machine assertion in a pipeline. `--keep-server-snapshot` retains the live export under `xmatix/.snapshot/server/` so reviewers can open the server's actual files next to the repo's, and `--scope` passes a metadata scope through to the underlying export (default `TenantOwned`). `--out` redirects the manifest. ## migrate apply `migrate apply` is currently an alias for [`snapshot import`](/docs/developer/cli/snapshot/) — it pushes every artifact file in the canonical folders, in dependency order, and passes through `--skip` and `--dry-run`. Always run `--dry-run` first in a pipeline: it prints what would be pushed without touching the tenant, which catches a mis-scoped workspace before it matters. ## Removed files are never deleted Neither `apply` nor `snapshot import` deletes anything on the server. A file in the plan's `removed` set means the server has an artifact your repo does not — perhaps deliberately deleted from the repo, perhaps created ad hoc in the product. Deleting server artifacts is a manual, in-product decision: review the `removed` section and act on each entry knowingly. This asymmetry is deliberate — an automated pipeline should never be able to destroy configuration because of a missing file. ## Common questions ### How do I gate a pipeline on "no drift"? Assert on the plan's counts. After `xmatix migrate plan`: ``` jq -e '.counts.modified == 0 and .counts.removed == 0' \ xmatix/.snapshot/migrate-plan.json ``` fails the job when the live tenant has diverged from the repository. The [CI recipes](/docs/developer/cli/ci/) page has the full workflow. ### Does apply push only what the plan flagged? Not yet — apply currently pushes every file in the canonical folders (unchanged pushes are harmless upserts), while the plan is the *review* artifact. Consuming the plan so apply sends only added and modified files is a planned refinement; until then, use `--skip` to exclude whole kinds when that matters. ### Can I promote from one tenant to another with this? Yes — that is the primary use. The repository holds the reviewed state exported from the source tenant; a workspace configured for the *target* tenant runs `migrate plan` (showing exactly how the target differs) and then `migrate apply`. Order matters across kinds, and apply already pushes metadata before the automation and analytics that depend on it. ## Related topics - [Snapshots](/docs/developer/cli/snapshot/) - [Metadata seed-packs](/docs/developer/cli/metadata/) - [CI recipes](/docs/developer/cli/ci/) - [Workspace layout](/docs/developer/cli/workspace/) ---- # CLI quickstart: your first session URL: https://xmatix.com/docs/developer/cli/quickstart/ Last reviewed: 2026-09-02 This quickstart takes the xMatix CLI from nothing to a working loop: a repository that mirrors your tenant's customization, a verified sign-in, and a script change pushed from your own editor with its execution history tailing in a terminal. It is the foundation the [CI recipes](/docs/developer/cli/ci/) build on — everything a pipeline does later, you do here once by hand. ## Prerequisites - The .NET 10 SDK installed. - A git repository (new or existing) to hold the tenant's configuration. - Your tenant's connection values: the tenant slug, API base URL, sign-in authority URL and the CLI's registered client id. Your administrator has these; they are entered once and persisted. - A user account with the customization capabilities for what you plan to round-trip — the CLI can never do more than the signed-in user is permitted to do in the product. ## Procedure @[guided-image](_img/cli-help.png) ### Step 1 — Install the CLI ``` dotnet tool install -g xmatix.cli xmatix --version ``` The tool installs a single global command, `xmatix`. Run both `xmatix --version` and `xmatix --help`; the version proves the expected binary resolves on `PATH`, while help confirms the installed build exposes the commands used below. If another binary answers, inspect your global tool path before proceeding. To update later, use `dotnet tool update -g xmatix.cli` and repeat both checks. ### Step 2 — Scaffold the workspace From your repository root: ``` xmatix init ``` This creates `.xmatix/` (the config directory, with a `.gitignore` that keeps caches and tokens out of the repo), the first canonical artifact folder, and editor tasks for common pull and push actions. Review the generated files before committing: confirm `.xmatix/.gitignore` covers caches and tokens and that no pre-existing project files were replaced. Run `git status` from the root, then run `xmatix doctor` from a nested folder to verify workspace discovery walks upward correctly. ### Step 3 — Sign in ``` xmatix login --tenant \ --api-base-url \ --authority \ --client-id ``` The CLI prints device-code instructions—open the exact verification URL, enter the short-lived code and complete sign-in with the intended tenant user. The four non-secret connection flags persist into `.xmatix/config.json`; tokens are cached outside the repository in the OS credential store. Run `xmatix whoami` immediately and verify tenant slug and user identity before any pull or push. Inspect `git status` once more to prove no token or device code appeared in tracked files; details are in [Authentication](/docs/developer/cli/authentication/). ### Step 4 — Run the pre-flight checks ``` xmatix doctor ``` Doctor verifies the workspace root, configuration values, silent token acquisition, API reachability and every canonical artifact folder. Read every result rather than relying only on the exit code: a wrong tenant can still be reachable. Resolve red checks in order, rerun until green, then compare the reported tenant/API with `whoami`. Make this the first command in every working session and CI job so later failures are not misdiagnosed as artifact problems. ### Step 5 — Export the tenant and commit ``` xmatix snapshot export git add xmatix/ .xmatix/config.json git commit -m "Initial tenant snapshot" ``` `snapshot export` runs every artifact kind's pull in sequence—metadata, scripts, rules, workflows, dashboards and reports—into the canonical `xmatix/` tree. Review command totals and failures before staging. Run the export a second time and require a clean `git diff`; nondeterministic churn is a problem to solve, not a baseline to commit. Inspect representative files for secrets or tenant data, then commit the complete coherent snapshot with `.xmatix/config.json` only after confirming it contains connection metadata, never tokens. The [workspace layout](/docs/developer/cli/workspace/) page maps the tree. ### Step 6 — Change a script and push it Open any pulled script — say `xmatix/automation/scripts/Account/MyValidation.csx` — make an edit, and push it: ``` xmatix scripts push xmatix/automation/scripts/Account/MyValidation.csx --activate ``` The push persists a new server version and compiles it. A failed compile remains visible in version history for diagnosis, the command exits with code 3, and the prior active version keeps running; a non-zero exit therefore means “not activated,” not “nothing was stored.” Review the diff and test input before using `--activate`, because activation changes live behavior while an upload without it leaves the previous version running. After a successful compile, use the product editor's **Versions** tab to verify the new version and active marker, then pull the script again and require byte-equivalent content. Use `xmatix watch` only on a controlled branch and stop it before broad refactors to avoid unintended pushes. ### Step 7 — Watch it run ``` xmatix scripts run xmatix/automation/scripts/Account/MyValidation.csx --record xmatix runs tail --follow ``` `scripts run` fires a server-side dispatch against the supplied real record; it is not a dry run, so use a disposable record and identify every expected side effect first. In another terminal, `runs tail --follow` streams status, phase, entity, duration and errors. Match the new run to the test record and active version, verify the intended result and absence of unrelated writes, then clean up the disposable data. A successful process exit without the expected run row is not proof that the automation behaved correctly. ## Expected result `xmatix --version` and `xmatix --help` run globally, the repository contains a valid `.xmatix/` workspace without committed tokens, and `xmatix doctor` passes workspace, configuration, authentication and API checks. A pull produces reviewable artifacts and an unchanged diff reports no drift before the first push. ## Common questions ### What should the first commit contain? The `xmatix/` tree and `.xmatix/config.json` — nothing else the CLI produces. The config file carries connection settings only (no secrets), so committing it means every teammate who clones the repo needs just `xmatix login` to be productive. Tokens and caches never belong in git, and `init`'s `.gitignore` enforces that for anything that lands under `.xmatix/`. ### How do teammates onboard to an existing workspace? Clone the repo, install the tool, run `xmatix login` (the persisted config supplies everything but their credentials), then `xmatix doctor`. They sign in as themselves — the CLI acts with each user's own permissions, so there is no shared credential to manage. ### I pushed a script — why is the old behavior still running? Almost always because the push had no `--activate`: a pushed version uploads and compiles but does not become the active version until activated. Activation being explicit is deliberate — it means a half-finished edit can be uploaded for the record without going live. Push again with `--activate`, or activate the version in the product's script editor. ## Related topics - [The xMatix CLI](/docs/developer/cli/) - [Authentication](/docs/developer/cli/authentication/) - [Scripts](/docs/developer/cli/scripts/) - [Your first automation script](/docs/customization/automation-scripts/quickstart/) ---- # Business rules in the CLI URL: https://xmatix.com/docs/developer/cli/rules/ Last reviewed: 2026-08-15 `xmatix rules` round-trips [business rules](/docs/customization/business-rules/) as one self-describing JSON file per rule, organized by entity. Files carry the rule definition and its actions inline, so a rule reviews as a single unit in a pull request and pushes as a single unit to the server. ``` xmatix rules list # all rules xmatix rules list --entity Account # filter by target entity xmatix rules pull # → xmatix/automation/rules//.json xmatix rules pull --entity Account xmatix rules pull # a single rule (case-sensitive) xmatix rules push xmatix/automation/rules/Account/AutoApprove.json xmatix rules push --yes # skip the confirmation prompt ``` ## File shape Each file wraps the rule in an envelope naming its entity, so a push can resolve the target without any workspace state: ``` { "entityName": "Account", "rule": { "name": "AutoApprove", "label": "Auto approve", "description": "…", "isActive": true, "scope": 0, "triggers": 2, "conditionFormula": "…", "order": 0, "priority": 0, "stopOnFalse": false, "triggerFields": null, "actions": [ { "…": "…" } ] } } ``` The `rule` object is the server's own representation — the same fields the rule editor writes — with `actions` inline in file order. Files are named `/.json` with filesystem-unsafe characters replaced. ## Push semantics `rules push` upserts by **(entity, rule name)**: - The entity is resolved from the file's `entityName`; the push fails clearly if it does not exist on the target tenant. - If a rule with the same name already exists on that entity, it is updated in place — and **its actions are replaced wholesale** with the file's `actions` array (existing actions are removed, the file's are recreated in file order). - Otherwise the rule is created. Two consequences worth internalizing. First, the file is the source of truth for actions — there is no partial-action merge, so never hand-edit one action on the server and one in the file and expect both to survive. Second, a file whose `rule` has **no** `actions` property leaves the server's actions untouched — the wholesale replacement only happens when the file states an action list. Because replacing actions is destructive, push asks for confirmation unless you pass `--yes`. ## Common questions ### How do I safely rename a rule? Remember that push matches by name: pushing a file with a new name *creates a second rule* rather than renaming the old one. Rename in the product (or accept the create) and then delete the old rule deliberately — and re-pull afterwards so the file tree matches. The same applies to moving a rule between entities. ### The rule pushed fine but never fires — why? The usual suspects are the rule's own switches, faithfully round-tripped: `isActive` false in the file, a `conditionFormula` that never parses or never matches, or triggers that do not include the change kind you are testing. The product's rule editor and its test runner remain the best diagnosis tools — the CLI moves the definition around; the [business rules page](/docs/customization/business-rules/) explains how the definition behaves. ### Should rules be edited as JSON or in the product? Both, for different jobs. The product's editor validates conditions as you type and previews behavior; JSON editing shines for review, bulk changes and promotion — the same rule applied to a second tenant, an action tweaked across twenty rules, a pull request that shows exactly which condition changed. Whichever side edits, `pull` after in-product changes and `push` after file changes, so neither side drifts. ## Related topics - [Business rules](/docs/customization/business-rules/) - [Expressions: formulas and query filters](/docs/customization/expressions/) - [Snapshots](/docs/developer/cli/snapshot/) - [Migrations](/docs/developer/cli/migrate/) ---- # Scripts in the CLI URL: https://xmatix.com/docs/developer/cli/scripts/ Last reviewed: 2026-08-15 `xmatix scripts` round-trips [automation scripts](/docs/customization/automation-scripts/quickstart/) — the C# bodies and their version state — so scripts can be edited in a real editor, versioned in git, and tested and observed from a terminal. Pushing never bypasses the platform's safety net: every pushed version is compiled on the server before it persists, and activation remains an explicit step. ``` xmatix scripts list xmatix scripts pull --all # every script in the tenant xmatix scripts pull # a single script xmatix scripts push # upload a new version xmatix scripts push --activate # …and make it the active version xmatix scripts run --record xmatix scripts logs --script --follow xmatix runs tail --follow # cross-script run feed ``` ## File layout Scripts land under `xmatix/automation/scripts/`, organized into a folder per entity (taken from the script's first binding; scripts with no binding go under `_unbound/`). Each script is a pair: ``` xmatix/automation/scripts/Account/MyValidation.csx # the source body xmatix/automation/scripts/Account/MyValidation.meta.json ``` The `.meta.json` companion records the script id, name, label, description, current version and body hash, plus the binding metadata (lifecycle phase, change kinds, target entity, synchronous/asynchronous, order). Push reads it to attach the new version to the right script and to detect when nothing has changed; `run` reads it to default the entity and phase. Keep the pair together — a `.csx` without its sibling cannot be pushed. ## Push: compile-validated versions `scripts push` creates a new version on the server, which compiles the body before persisting. Compile failures print as diagnostics and exit non-zero — there is no separate dry-run verb because every push is already a server-validated dry run. Options: | Option | Effect | | --- | --- | | `--activate` | Make the new version the script's current (active) version — without it, the upload does not change runtime behavior | | `-m, --message ` | A comment stored against the version (a git SHA is a good habit) | | `--force` | Push even when the local meta hash no longer matches the server's current version — i.e. someone changed the script in the product since your last pull. Without `--force` the push stops so you can pull and reconcile first | ## Run: server-side test dispatches `scripts run` invokes the same test facility as the product's script editor — a real dispatch through the real pipeline, so data writes and messages are real; test mutating scripts against disposable records. | Option | Effect | | --- | --- | | `-r, --record ` | The record to bind into the script's context (optional for server-action tests) | | `-e, --entity ` | Entity name; defaults to the first lifecycle binding's entity | | `-p, --phase ` | `LoadDefaults`, `PreValidate`, `Validate`, `BeforeSave`, `BeforeDelete`, `AfterSave` or `AfterDelete`; default `BeforeSave` | | `--action ` | Test a server-action binding instead of a lifecycle phase (mutually exclusive with `--phase`) | | `--change-kind ` | `Insert`, `Update` or `Delete`; default `Update` | ## Logs and the run feed `scripts logs` lists recent run rows — status, phase, entity, duration, run id and error — and `xmatix runs tail` is the same command scoped across all scripts, the terminal twin of the product's Runs tab: | Option | Effect | | --- | --- | | `-s, --script ` | Filter to one script | | `--status ` | `Pending`, `Running`, `Succeeded`, `Failed` or `Cancelled` | | `-n, --top ` | Rows to return (1–500, default 20) | | `-f, --follow` | Poll and stream only new rows (Ctrl+C to stop) | | `--interval ` | Poll interval with `--follow` (default 3) | | `--detail ` | Print the full JSON of a single run and exit | | `--json` | Emit raw JSON instead of a table | A run that ended `Cancelled` is usually a validation script blocking a save on purpose — read the run detail before treating it as a failure. ## Common questions ### What is the recommended editing loop? `xmatix watch` in one terminal, `xmatix runs tail --follow` in another, your editor in the middle. Watch pushes every save (compile errors surface immediately), the tail shows each run as it lands, and nothing goes live unexpectedly because activation is still your explicit call — during a hot iteration, keep the binding disabled in the product and re-enable when the fix verifies. ### Why does push say the server version changed? Because someone edited the script in the product since your last pull, and your `.meta.json` hash no longer matches the server's current version. That is a real conflict, not a nuisance check: pull the script, reconcile in git (the diff shows exactly what changed in the product), then push. Use `--force` only when you have decided your local file should win. ### Where is the script API (Ctx) documented? Inside the product: the **Readme** tab of the script editor is the complete, versioned reference for every context surface, with signatures, transaction rules and sandbox limits. The [scripts quickstart](/docs/customization/automation-scripts/quickstart/) is the conceptual map — bindings, phases, testing and run history — and everything it says applies unchanged to scripts edited through the CLI. ## Related topics - [Your first automation script](/docs/customization/automation-scripts/quickstart/) - [What runs when you save a record](/docs/concepts/execution-order/) - [Snapshots](/docs/developer/cli/snapshot/) - [Workspace layout](/docs/developer/cli/workspace/) ---- # Snapshots URL: https://xmatix.com/docs/developer/cli/snapshot/ Last reviewed: 2026-08-15 `xmatix snapshot` orchestrates whole-repository operations by re-invoking the per-kind `pull` and `push` verbs in sequence — one command to mirror the live tenant onto disk, one command to push the disk state back. It is the engine under [`migrate`](/docs/developer/cli/migrate/) and the workhorse of release-time capture. ``` xmatix snapshot export # pull metadata + automation + analytics xmatix snapshot export --scope TenantFull xmatix snapshot export --skip dashboards,reports xmatix snapshot import # push every JSON/CSX in the canonical folders xmatix snapshot import --dry-run # preview only — prints what would be pushed xmatix snapshot import --skip metadata ``` ## Export `snapshot export` runs, in order: `metadata pull` (with `--scope`, default `TenantOwned`), `scripts pull`, `rules pull`, `workflows pull`, `dashboards pull`, `reports pull`. Each writes into its canonical folder under `xmatix/` (see the [workspace layout](/docs/developer/cli/workspace/)). After an export, the on-disk tree mirrors the live tenant — `git status` then shows exactly what changed in the product since the last export, which is the entire trick behind snapshot-based drift detection: export on a schedule, and a non-empty diff is a finding. ## Import and push order `snapshot import` pushes every artifact file in a conservative order, so referenced rows exist before their consumers: 1. `metadata` — entities, fields, views and the rest of the model 2. Automation: `scripts`, then `rules`, then `workflows` 3. Analytics: `dashboards`, then `reports` If an individual push fails, the snapshot **continues** with the remaining files and kinds, then exits with a non-zero aggregate code — so one bad file neither hides behind an early abort nor sneaks through a green build. `--dry-run` lists what would be pushed without sending anything. ## Skip kinds Both verbs accept a comma-separated `--skip` list drawn from: `metadata`, `scripts`, `rules`, `workflows`, `dashboards`, `reports`. Typical uses: `--skip metadata` when the model is managed by a different pipeline, or `--skip dashboards,reports` when analytics are owned in-product and only automation is under source control. ## Common questions ### How often should a team export? At every deliberate change, plus on a schedule. The deliberate exports keep the repo authoritative; the scheduled one (nightly is common) catches in-product changes nobody exported — surfacing them as a reviewable diff while the author still remembers making them. The [CI recipes](/docs/developer/cli/ci/) page shows the scheduled variant as a drift gate. ### Is import idempotent? Effectively, yes — every push is an upsert, so importing a tree that matches the server changes nothing, and importing twice is the same as importing once. That is what makes `snapshot import` safe as a pipeline step: reruns after a partial failure simply converge the tenant toward the repo state. ### Why did my import half-succeed? Because import deliberately continues past failures — check the output for the per-file failures and the non-zero exit. Common causes are ordering across *tenants* (a rule referencing an entity that only exists at the source — push metadata first, which import already does; but a `--skip metadata` import can strand automation) and scripts whose new version fails server-side compile. Fix the named files and re-run; idempotency makes the retry safe. ## Related topics - [Migrations](/docs/developer/cli/migrate/) - [Metadata seed-packs](/docs/developer/cli/metadata/) - [Workspace layout](/docs/developer/cli/workspace/) - [CI recipes](/docs/developer/cli/ci/) ---- # Workflows in the CLI URL: https://xmatix.com/docs/developer/cli/workflows/ Last reviewed: 2026-08-15 `xmatix workflows` round-trips the definitions behind the [visual workflow designer](/docs/customization/workflows/) as one JSON file per workflow. Pull writes the complete definition — the full activity tree, not a summary — so pull → edit → push is loss-less; push creates or updates by definition id and gives you explicit control over whether the result is published. ``` xmatix workflows list xmatix workflows pull # → xmatix/automation/workflows/.json xmatix workflows pull xmatix workflows push # update if known, create otherwise xmatix workflows push --publish xmatix workflows push --no-publish xmatix workflows push --new # force create even if the id matches ``` ## File shape Each file mirrors the server's full workflow detail, so nothing is lost between pull and push: ``` { "definitionId": "…", "name": "OnboardCustomer", "description": "…", "version": 7, "isPublished": true, "root": { /* the full activity tree */ }, "customProperties": { } } ``` Files are named for the workflow's `name`; a workflow with an empty name falls back to its `definitionId`. The `root` activity tree is the designer's own persistence format — the same structure you build on the canvas — which makes targeted edits (a changed condition, a renamed step) reviewable in a git diff even though the tree is verbose. ## Push semantics - If the file's `definitionId` resolves on the server, the push **updates** that definition, and the server increments the version automatically. - If there is no match — or you pass `--new` — the push **creates** a new definition. - Publish state: an explicit `--no-publish` wins over `--publish`; with neither flag, the file's `isPublished` value is preserved on update, and a newly created workflow defaults to draft. The publish flags matter because of the designer's core rule: **triggers only register from the published version**. A pushed draft changes nothing at runtime until it is published — which is exactly what you want when promoting a reviewed change that a human should activate, and exactly what surprises you when you expected the push to go live. Decide per pipeline: `--publish` for environments where merge means live, no flag where publishing stays a deliberate in-product act. ## Common questions ### Why did my pushed workflow not fire? Because it is a draft. Either the push created a new definition (drafts by default) or it updated one whose file had `isPublished: false`. Check the workflow's status in the designer — if it shows a newer draft than the published version, publish it (or push again with `--publish`). This is the single most common surprise in workflow round-tripping. ### Can I edit the activity tree by hand? Yes, with care — the tree is the designer's persistence format, and a structurally invalid edit will be rejected on push or misbehave in the designer. Hand-editing shines for mechanical changes: renaming an entity reference across many workflows, tweaking a literal, copying a step between definitions. For structural work, the visual designer is the better editor; the file is the better *diff*. ### How do I copy a workflow to another tenant? Pull it from the source workspace, then push the file from a workspace configured for the target tenant with `--new` (so it creates rather than trying to update a definition id that only exists at the source). References to entities and templates resolve by what exists in the target tenant — push the [metadata](/docs/developer/cli/metadata/) first if the workflow depends on custom entities. ## Related topics - [Build a workflow in the visual designer](/docs/customization/workflows/) - [Snapshots](/docs/developer/cli/snapshot/) - [Migrations](/docs/developer/cli/migrate/) - [Workspace layout](/docs/developer/cli/workspace/) ---- # Workspace layout URL: https://xmatix.com/docs/developer/cli/workspace/ Last reviewed: 2026-08-15 `xmatix init` scaffolds two things in your repository root: the `.xmatix/` config directory, and the canonical `xmatix/` folder tree where round-tripped artifacts live. Every `pull` writes into that tree and every `push` reads from it — the layout *is* the contract between the CLI and your repository, which is why it is fixed rather than configurable. ``` .xmatix/ config.json # tenant + API + sign-in settings (no secrets) .gitignore # keeps cache/ and tokens/ out of the repo xmatix/ metadata/ tenant-owned.json # seed-pack from `metadata pull` (per-scope names) automation/ scripts//.csx # one C# script per file… scripts//.meta.json # …with its id/version/binding companion rules//.json workflows/.json # full workflow definition incl. activity tree analytics/ dashboards/.json # full row incl. the designer XML reports/.json # full row incl. banded-report layout XML .snapshot/ migrate-plan.json # output of `migrate plan` server/ # live export kept by `migrate plan --keep-server-snapshot` ``` Sign-in tokens are deliberately *not* in this tree — they are cached per user and per tenant under `~/.xmatix/tokens/` in your home directory, encrypted by the OS credential store ([Authentication](/docs/developer/cli/authentication/) has the details). ## Discovery The CLI finds its workspace by walking up from the current directory until it meets a directory containing `.xmatix/` — so any subdirectory of the repository hosts a working invocation, and there is no flag or environment variable for "which workspace": your location decides. `xmatix doctor` prints the resolved root and validates the config and every canonical folder (folders missing before the first pull are noted, not failed). Two practical consequences. Nesting workspaces is asking for surprises — the *nearest* `.xmatix/` up the tree wins. And running the CLI outside any repository fails immediately with "no workspace found", which is the correct outcome rather than an accidental default tenant. ## File-name policy - Files are named for the artifact's logical **name**, never its id — so diffs and directory listings read like the product. - Names are sanitized: characters invalid in filenames are replaced with `_`. - Scripts are grouped into a folder per target entity (from the script's first binding); scripts with no binding land under `_unbound/`. - Workflows with an empty name fall back to their definition id as the filename. Renames follow from this: renaming an artifact in the product means the next pull writes a **new** file, and the old file lingers untracked-by-the-server. Delete the stale file in the same commit you pull the rename, or a later `snapshot import` will faithfully push the old artifact back. ## What belongs in source control Commit `.xmatix/config.json` and everything under `xmatix/` except `.snapshot/` (plan output and server exports are build artifacts — most teams gitignore `xmatix/.snapshot/`). Never commit tokens or caches; `init`'s `.gitignore` guards the `.xmatix/` side of that automatically. ## Common questions ### Can I move artifacts to different folders? No — the folder tree is the contract, and `push`, `watch`, `snapshot` and `migrate` all resolve artifact kinds from their canonical locations. What you *can* choose is where the workspace root lives (any directory, typically the repo root) and which kinds you use at all: unused folders simply stay empty. ### Why did pull create a file that duplicates an existing one? Almost always a rename or a sanitized character: the artifact's server name changed (new file, old file stale) or two artifacts sanitize to similar names. Check `git status` after every pull — added-plus-unmodified pairs with similar names are the fingerprint of a rename, and the stale file should be deleted in the same commit. ### Does one repository support multiple tenants? One workspace supports exactly one tenant, but a repository can host several workspaces in separate directories — each with its own `.xmatix/` and `xmatix/` tree. Commands act on whichever workspace encloses your current directory, and each keeps its own token cache entry, so switching tenants is `cd`, not reconfiguration. ## Related topics - [The xMatix CLI](/docs/developer/cli/) - [Authentication](/docs/developer/cli/authentication/) - [Snapshots](/docs/developer/cli/snapshot/) - [Migrations](/docs/developer/cli/migrate/) ---- # Connector authoring URL: https://xmatix.com/docs/developer/connector-authoring/ Last reviewed: 2026-08-15 Connectors are how the [integration hub](/platform/integrations/) talks to external systems, and they come in two tiers with one rule of thumb: if a partner is "JSON over HTTPS with standard auth", it is a **manifest connector** — a reviewed JSON descriptor, no code; if it needs a real driver, SDK or non-HTTP transport, it is a **compiled connector**. Both tiers implement the same contract, are dispatched identically by the integration executor, and appear in the same server-authoritative catalog that drives the connection picker and its configuration forms — so which tier a connector belongs to is invisible to the administrator using it. ## The two tiers | | Compiled connector | Manifest connector | | --- | --- | --- | | Authored as | Code, by the platform team | A reviewed JSON descriptor | | One per | Transport or SDK that needs real code | REST partner (HTTP + auth + mapping) | | Interpreted by | Itself | One shared manifest interpreter | | Examples | Generic REST (`http.rest`), Salesforce (`salesforce.rest`), message-bus queues (`azure.servicebus`), SFTP (`sftp`) | HubSpot (`hubspot.crm`), Zendesk (`zendesk.support`), Shopify (`shopify.admin`) | A connector's capabilities — read, write, bulk write, connection test, pagination — are **inferred from what it implements**, never declared separately, so the catalog cannot drift from actual behavior. Compiled connectors exist for the things templated HTTP cannot express: databases, message brokers, object stores, file protocols, and HTTP APIs outside the manifest model (form-encoded bodies, SOAP, gRPC). ## The manifest contract A manifest describes a REST partner declaratively — base URL, auth scheme, how to read, how to write, how to probe the connection, and which configuration fields to ask the administrator for: ``` { "manifestVersion": "1", "type": "example.partner", "displayName": "Example Partner", "description": "…", "docsUrl": "https://…", "baseUrl": "https://api.example.com", "auth": { "scheme": "bearer", "token": "${secret:exampleToken}" }, "read": { "method": "GET", "path": "/v1/items", "query": { }, "itemsPath": "items" }, "write": { "method": "POST", "path": "/v1/items", "headers": { }, "body": { } }, "test": { "method": "GET", "path": "/v1/ping", "okBelow": 500 }, "inputs": [ { "path": "objectType", "label": "Object type", "kind": "select", "required": true, "options": [ ] } ] } ``` | Field | Notes | | --- | --- | | `type` | The stable, lower-kebab connector type — the catalog key | | `baseUrl` | Absolute HTTPS URL; may contain `${config:…}` tokens for per-tenant hosts (for example a per-organization subdomain) | | `auth.scheme` | `none`, `bearer` (with `token`), `basic` (with `username`/`password`), or `apiKey` (with `header`/`value`); every value is templatable | | `read.itemsPath` | Dotted path selecting the record collection inside the response; when it resolves, the records are handed to the flow — otherwise the raw status/body envelope is | | `write.body` | The body template. A string leaf whose entire value is one `${input…}` or `${config…}` token is replaced by the resolved JSON value with its type preserved; omit `body` to send the step input as-is | | `test.okBelow` | Status codes below this count as a successful probe (default 500 — so auth failures still surface as failures) | | `inputs[]` | Declared configuration fields, projected into the typed connection form automatically — text, number, boolean, select and secret-reference kinds | ### Template tokens Three token families are resolved at execution time: | Token | Resolves to | | --- | --- | | `${secret:name}` | A stored partner secret — resolved by the executor, never persisted in flow configuration | | `${config:a.b}` | A value from the merged connection and step configuration; a secret reference stored *inside* a config value resolves transparently | | `${input:a.b}` | A value from the step's input record | Because a whole-string token preserves the resolved value's JSON type, manifests can write numbers as numbers and objects as objects — not everything becomes a string. ### What a manifest gets for free Each manifest registers as a first-class connector: its own entry in the catalog, a typed configuration form generated from `inputs`, secret handling, and the platform's shared resilience pipeline — retries, per-host circuit breaking and timeouts — identical to what the compiled connectors use. No product UI changes are involved; the connection picker and forms are catalog-driven. ### Current limitations The manifest engine currently reads a single page per call (no declarative pagination), writes single records (no bulk block), supports static bearer/basic/apiKey auth (no OAuth token exchange), and sends JSON bodies (no form-encoded). Partners needing any of those either use the generic `http.rest` connector, which paginates and takes caller-supplied headers, or a compiled connector. ## How new connectors get added Manifests are **curated**: they are reviewed and shipped by xMatix, carrying the same trust as compiled code — a manifest can point HTTP anywhere, so review is a security control, not a formality. If you need a REST partner that is not in the catalog, the practical paths today are, in order: configure the partner over the generic `http.rest` connector yourself; or request the partner from xMatix — a clean REST partner is typically a small manifest, which is why the catalog can grow quickly. Tenant-authored manifests — writing your own connector descriptor inside the product — are planned behind appropriate guardrails (egress allow-listing, authoring permissions) but are not available yet. ## Common questions ### When should I use http.rest instead of waiting for a manifest? When you need the partner now and its API is reachable with static headers. `http.rest` is the general-purpose escape hatch: it reads, writes, paginates and tests against any HTTP endpoint with caller-supplied configuration. A dedicated manifest earns its place by packaging the partner's specifics — auth shape, response unwrapping, a friendly config form — so administrators configure "Zendesk" rather than "HTTP". ### How are partner credentials protected? Secrets are stored in the platform's secret store and referenced from configuration as `${secret:name}` tokens; the executor resolves them at call time and raw values never persist in flow or connection configuration. The connection form's secret fields store references, not values — an administrator can rotate a secret without touching the flows that use it. ### Can a connector's catalog entry claim capabilities it doesn't have? No — capabilities are inferred from what the connector actually implements rather than declared in metadata, so a connector that cannot bulk-write never advertises bulk write. When the connection picker shows a capability, the executor can genuinely dispatch it. ## Related topics - [Integrations on the xMatix platform](/platform/integrations/) - [The data API](/docs/developer/data-api/) - [Platform extensibility](/platform/extensibility/) - [Troubleshooting](/docs/developer/troubleshooting/) ---- # The data API URL: https://xmatix.com/docs/developer/data-api/ Last reviewed: 2026-08-15 The data API is the REST surface the xMatix web and mobile clients themselves run on — there is no separate, lesser "integration API". Every entity in the tenant, standard or custom, is addressable by its logical name through one uniform set of endpoints under your organization's API base URL, with versioned routes (`/api/v1/…`) and JSON in both directions. Because it is the product's own API, two guarantees follow: requests execute as the authenticated user with the full [security model](/docs/concepts/security-model/) applied on the server, and writes run the complete save pipeline — [business rules, validations, scripts, workflows and approvals fire exactly as they do in the UI](/docs/concepts/execution-order/). ## Authentication Calls carry an OAuth 2.0 bearer token issued by your organization's sign-in authority — the same identity service that signs users into the product. The token identifies a user; the platform applies that user's [security profiles](/docs/administration/security-profiles/), record security and restriction rules to every request. For an unattended integration, use a dedicated account granted exactly what the integration needs. ``` curl -H "Authorization: Bearer $TOKEN" \ "https:///api/v1/data/Account?pageSize=50" ``` Entity names in routes are logical names as they appear in the data model (for example `Account`, not the display label) — find them in **Setup → Design Studio → Entities**, via the [CLI's metadata pull](/docs/developer/cli/metadata/), or through the [MCP endpoint's](/docs/developer/mcp-server/) describe tool. ## Reading records | Endpoint | What it returns | | --- | --- | | `GET /api/v1/data/{entity}` | A page of records, with total count and paging echo | | `GET /api/v1/data/{entity}/{id}` | One record; `?relations=` expands related records inline | | `GET /api/v1/data/{entity}/{id}/{relation}` | The records related through a named relation | List queries compose through query parameters: | Parameter | Meaning | | --- | --- | | `filter` | A filter expression over the entity's fields, evaluated in the database — the query-filter side of [Expressions](/docs/customization/expressions/) | | `search` | Free-text term, matched across the entity's searchable fields and combined with `filter` | | `orderBy` | Sort expression | | `relations` | Related records to include inline | | `ids` | Comma-separated record ids — fetch a known set in one call | | `additionalFields` | Extra fields to project beyond the default set; lookup fields included here are enriched with their display-name sibling | | `pageSize`, `pageNo` | Paging — `pageSize` defaults to 25, `pageNo` starts at 1 | The response wraps the page: the records under `data`, the total `count`, and the page size and number echoed back — everything needed to iterate a large result set deterministically. ## Writing records | Endpoint | What it does | | --- | --- | | `POST /api/v1/data/{entity}` | Creates a record from a JSON body; returns 201 with the created record and its location | | `PATCH /api/v1/data/{entity}/{id}` | Partial update — send only the fields you are changing | | `DELETE /api/v1/data/{entity}/{id}` | Deletes the record (subject to the tenant's delete and recycle-bin behavior) | | `POST /api/v1/data/{entity}/preview` | Materializes the record a create *would* produce — defaults, rules and calculations applied — without persisting anything | | `PATCH /api/v1/data/{entity}/{id}/preview` | The same, for an update | The preview endpoints are the API twin of what a form shows before you press save — useful for validating input and showing computed outcomes in your own UI without committing. Updates and deletes also respect the platform's record edit locks: while another user holds a record open for editing, the API rejects the write with a message naming the holder, exactly as the product does. ## Actions and bulk operations | Endpoint | What it does | | --- | --- | | `POST /api/v1/data/{entity}/{id}/{action}` | Invokes a named entity action on one record — the same actions buttons invoke in the UI | | `POST /api/v1/data/bulk/{entity}/{action}` | Invokes an action across many records | | `POST /api/v1/data/bulk/{entity}` | Creates many records in one call | | `PATCH /api/v1/data/bulk/{entity}` | Updates many records in one call | | `GET /api/v1/data/bulk/{entity}/{ids}` | Fetches a set of records by id | Actions are how server-side behavior is exposed by name — an action backed by an [automation script](/docs/customization/automation-scripts/quickstart/) or built-in handler does its work; an action with no handler succeeds without effect, so wire the handler before relying on the call. ## Delta sync For consumers that mirror data — the pattern behind the platform's offline mobile clients — `GET /api/v1/sync/{entity}?since=` returns records changed or soft-deleted since a cursor (deletions arrive as records carrying a deletion timestamp), along with the next cursor to store. `POST /api/v1/sync/manifest` answers, for a batch of entity/cursor pairs in one round-trip, whether each has anything new. Polling deltas is far cheaper than re-querying, and the cursor model makes catch-up after downtime automatic. ## Metadata, read-only The model itself — entities, fields, views, relations — is readable under `/api/v1/metadata/…`, which is the surface the [CLI's metadata commands](/docs/developer/cli/metadata/) ride on. For programmatic discovery ("what fields does this entity have?"), prefer the metadata routes or the MCP describe tool over guessing from record payloads. ## Common questions ### Do API writes trigger the same automation as the UI? Yes — identically. A record created through `POST /api/v1/data/{entity}` passes through the same lifecycle as a form save: defaults, validations, business rules, bound scripts, workflow triggers, approval gates. This cuts both ways: your integration gets the tenant's business logic for free, and a validation that blocks users blocks the API too — [what runs when you save a record](/docs/concepts/execution-order/) explains the order. ### How should an integration page through large tables? With `pageSize`/`pageNo` for one-off reads, and the delta-sync cursor for anything that mirrors data continuously. A nightly "fetch everything" job re-reads mostly unchanged rows; the same job on `sync/{entity}` reads only what changed, and the manifest endpoint tells it in one call which entities are even worth visiting. ### Why does a filtered query return records my filter should exclude? First check the field name — filters reference logical field names, and an unknown name will not match the way you expect. Then check the value form: picklists compare stored values rather than display labels, and lookups are ids. When a filter still misbehaves, reproduce it with a minimal query and compare against a saved view with the same condition in the product — the [query-filter reference](/docs/customization/expressions/) covers the semantics shared by both surfaces. ## Related topics - [How the xMatix security model works](/docs/concepts/security-model/) - [What runs when you save a record](/docs/concepts/execution-order/) - [The MCP endpoint](/docs/developer/mcp-server/) - [Expressions: formulas and query filters](/docs/customization/expressions/) ---- # xMatix developer documentation URL: https://xmatix.com/docs/developer/ Last reviewed: 2026-09-01 ## Start from the metadata contract An entity's Design Studio detail page is the shared contract beneath every developer surface. Its overview links the model to **Fields**, **Relations**, **Views**, **Record Types**, **Actions** and **Layouts**; together those definitions determine API shapes and supported experiences, and the same metadata can be pulled by the CLI or described through MCP. Process Studio, Data Studio and Sense AI Studio add executable, analytical and AI-facing extensions without bypassing this model. @[guided-image](_img/developer-overview.png) Start development by opening the entity definition and checking permissions before writing code. Confirm logical names rather than display labels, use supported metadata instead of hard-coded assumptions, and test as the intended user because API and MCP calls inherit that identity's grants. Most xMatix customization needs no code at all — the data model, layouts, business rules, workflows and approvals are all built in the product, and the [customization guide](/docs/customization/) covers them end to end. This section is for the work that sits beyond that: putting a tenant's configuration under source control, reading and writing records from your own systems, connecting AI tools to governed data, and extending the integration hub. Everything here rides on the same platform services and the same security model as the product itself — a developer surface never grants more than the signed-in user is permitted. ## The developer surfaces | Surface | What it does | Start here | | --- | --- | --- | | **The CLI** | A git-friendly, round-trippable view of every customizable artifact in a tenant — scripts, business rules, workflows, dashboards, reports and metadata — so configuration can be versioned, reviewed and promoted like code | [CLI overview](/docs/developer/cli/) | | **Data API** | REST endpoints over every entity in the tenant — list, read, create, update, delete, invoke actions, expand relations, page and filter — with the caller's permissions always applied | [The data API](/docs/developer/data-api/) | | **MCP endpoint** | The platform speaks the Model Context Protocol, so AI assistants and agent frameworks can list entities, query records and search knowledge under the calling user's permissions | [The MCP endpoint](/docs/developer/mcp-server/) | | **Integration connectors** | The connector engine behind the integration hub — compiled connectors for special transports, manifest connectors for REST partners | [Connector authoring](/docs/developer/connector-authoring/) | | **Script runtime** | Server-side C# in a sandbox, attached to save-lifecycle phases and action buttons — authored in the product, and round-trippable through the CLI | [Your first automation script](/docs/customization/automation-scripts/quickstart/) | ## How the pieces relate The **script runtime** is documented with the rest of customization because scripts are authored and tested inside the product; what this section adds is the [CLI's scripts commands](/docs/developer/cli/scripts/), which let you edit the same scripts in your own editor, push versions from git, and tail execution history from a terminal. The **data API** is the same API the product's own web and mobile clients run on — there is no separate "integration API" with different behavior, so a record written through the API fires exactly the automation a record saved in the UI fires ([what runs when you save a record](/docs/concepts/execution-order/)). The **MCP endpoint** exposes a read-only tool set over those same services for AI clients, and the reverse direction — bringing *your* tools to the platform's AI — is configured in [AI Studio](/docs/sense-ai/ai-studio/) and described in [Extending Sense](/docs/sense-ai/extending-sense/). **Connectors** belong to the integration hub, where scheduled flows move data between xMatix and external systems; the authoring page explains how new REST partners are added as reviewed manifest files rather than code. ## The pages in this section | Page | What it covers | | --- | --- | | [CLI overview](/docs/developer/cli/) | What the CLI is, installing it, and the full command map | | [CLI quickstart](/docs/developer/cli/quickstart/) | A first session end to end: sign in, export the tenant, push a change | | [Authentication](/docs/developer/cli/authentication/) | The device-code sign-in, the token cache, and workspace configuration | | [Metadata](/docs/developer/cli/metadata/), [Workflows](/docs/developer/cli/workflows/), [Scripts](/docs/developer/cli/scripts/), [Rules](/docs/developer/cli/rules/), [Dashboards & reports](/docs/developer/cli/analytics/) | Round-tripping each artifact kind | | [Migrations](/docs/developer/cli/migrate/), [Snapshots](/docs/developer/cli/snapshot/), [CI recipes](/docs/developer/cli/ci/), [Workspace layout](/docs/developer/cli/workspace/) | Whole-repository operations and pipelines | | [The data API](/docs/developer/data-api/) | The REST surface over entities, queries and actions | | [The MCP endpoint](/docs/developer/mcp-server/) | AI tools over governed data, in both directions | | [Connector authoring](/docs/developer/connector-authoring/) | The two connector tiers and the manifest contract | | [Troubleshooting](/docs/developer/troubleshooting/) | Developer-surface symptoms and their fixes | ## Common questions ### Do I need any of this to customize xMatix? No. Every customization tool — entities and fields, layouts, business rules, workflows, approvals, even automation scripts — has a full authoring experience inside the product, and administrators use them without touching a terminal. The developer surface earns its keep when you want configuration in git with pull-request review, changes promoted by pipeline instead of by hand, records flowing to and from your own systems, or AI tools reading tenant data under governance. ### What authentication do the developer surfaces use? OAuth 2.0 bearer tokens issued by your organization's sign-in authority — the same identity that signs users into the product. The CLI acquires tokens with a device-code flow and caches them encrypted per tenant; API and MCP calls present a bearer token and execute as that user, with [security profiles](/docs/administration/security-profiles/) and the rest of the [security model](/docs/concepts/security-model/) applied on every request. ### Can an API integration see more than a user can? No — there is no bypass tier. Every request executes as the authenticated user, and the platform applies that user's permissions, record security and restriction rules on the server for every read and write. Designing an integration therefore starts with deciding *which user* it should act as, and granting that account exactly the access the integration needs. ## Related topics - [Customizing xMatix](/docs/customization/) - [The customization ladder](/docs/concepts/customization-ladder/) - [Platform extensibility](/platform/extensibility/) - [Integrations on the xMatix platform](/platform/integrations/) ---- # The MCP endpoint URL: https://xmatix.com/docs/developer/mcp-server/ Last reviewed: 2026-09-06 The Model Context Protocol (MCP) is the standard for connecting AI assistants and agent frameworks to tools and data, and xMatix speaks it in both directions. Outbound, the platform ships an **MCP endpoint**: an MCP-capable assistant — Claude, ChatGPT, Claude Code and similar hosts — can discover your organization's entities, query and aggregate records, run reports and dashboards, search knowledge and, when allowed, create and update records, always as a signed-in user and always inside that user's permissions. Inbound, administrators can register **external MCP servers** in Sense AI Studio so the platform's own Sense agents can call *your* tools. This page covers both. ## xMatix as an MCP server ### Enabling it External assistants are off for every organization until an administrator turns them on under **Setup → Sense AI Studio → External Assistants**. The page shows the organization's **MCP endpoint** URL, statistics for assistants, writes and active connections, and a **Settings** dialog with three controls: **Allow external assistants** (the switch — turning it off cuts every existing session immediately), **Allow writes (create/update records; setup changes for administrators)** (off means every token is capped at read-only, whatever the assistant asked for) and **Approved assistants** (an optional allow-list of assistant clients). The same page lists every connection — assistant, user, access, connected and last-used times, status — with a per-row **Disconnect**. Nothing on this page grants anything a user does not already have; it only decides whether assistants may act *as* your users at all. ### How an assistant connects The endpoint is Streamable HTTP: JSON-RPC 2.0 over `POST` to the MCP URL, single requests or batches of up to 20, supporting `initialize`, `tools/list`, `tools/call` and `prompts/list`. An unauthenticated call answers `401` with protected-resource metadata, which is how a standards-compliant assistant discovers the organization's authorization server and registers itself. The user then signs in with the organization's normal sign-in, picks the organization to connect and approves the requested scopes; the assistant receives a short-lived (60-minute) token bound to that one organization, refreshed by rotation. In practice: 1. **Claude** (web or desktop): *Customize → Connectors → Add custom connector*, paste the MCP URL, sign in when prompted. 2. **ChatGPT**: *Settings → Connectors → Create*, same URL; the `search` and `fetch` tools make the connector usable in deep research. 3. **Claude Code**: `claude mcp add --transport http xmatix `; the sign-in runs in the browser. Scopes decide the ceiling: `xmatix.read` for discovery, query, reports and knowledge; `xmatix.write` for record creation and updates; `xmatix.setup` for the administration tools. The write scopes are only granted when the organization has allowed writes, and every tool that changes something is hidden while the organization is in read-only mode. The assistant always reasons with its own model: the endpoint never runs Sense or the Setup Copilot on its behalf, so a connected assistant costs the organization no AI credits. ### The tool set | Tool | What it does | | --- | --- | | `whoami` | Who the token acts as — user, organization, effective scopes | | `list_entities`, `describe_entity` | Discover the queryable entities, then load one entity's fields, types, picklists and relations by name or label | | `query_data`, `get_record`, `query_related` | Query records with filters, ordering and paging (25 rows by default, 200 at most), fetch one record by id, or walk a relation from a record | | `aggregate_data` | Group and aggregate records (counts, sums, averages) without pulling the rows | | `list_reports`, `run_report`, `list_dashboards`, `run_dashboard` | Enumerate and run the organization's saved reports and dashboards — the same evaluators the product uses | | `search_knowledge`, `read_platform_docs` | Search the organization's knowledge collections that ground Sense agents, and read the platform's own documentation | | `search`, `fetch` | The generic search-and-retrieve pair some assistants require for deep-research modes | | `create_record`, `update_record` | Write tools — need the `xmatix.write` scope and the organization's write opt-in | | `metadata_*` (`list_collections`, `describe_entity`, `list_fields`, `field_domain`, `query`, `get`, `create`, `bulk_create`, `update`, `delete`, `composite`, `clone`) | The setup tools for the data model: read and change entities, fields, views, picklists, security profiles and every other metadata collection (`xmatix.setup`) | | `layout_*` (`list`, `describe`, `get`, `get_reference`, `upsert`, `add_field`, `add_component`) | Read and edit form layouts, including adding a field or component to an existing layout | | `data_*` seeding (`query`, `get`, `query_view`, `preview`, `create`, `update`, `delete`, `composite`, `bulk_create`, `run_action`), `business_rule_preview` | Preview-first record seeding and server actions the way the Setup screens do it, plus business-rule evaluation previews | | `script_*`, `component_*`, `workflow_*`, `integration_*` | Automation scripts (draft, test, activate), custom components, Elsa workflows (create, publish, retract, instances) and the whole Integration Hub (apps, connections, bindings, flows, triggers, runs and their errors) | | `result_query`, `jobs_list`, `audit_query` | Mine an oversized setup result with a jq program, list background jobs, query the audit trail | The setup tools are the Setup Copilot's own tool layer served without its model — the same definitions, the same setup APIs, the same permission checks — offered only to users who hold the `xmatix.setup` scope in an organization that has allowed writes. Each is annotated read-only or destructive, so a well-behaved assistant runs reads freely and asks you before any change. The Setup Copilot cookbooks are also exposed as MCP **prompts**, so an assistant can pull the platform's own step-by-step recipes into its context. ### What governs a call Every `tools/call` is evaluated as the calling user, in three layers that only ever narrow: the token's **scopes**, the organization's **Sense capability grants** (a tool an agent could not be granted is not offered to an assistant either), and the user's own **security profiles, record security and restriction rules** at execution time. Locked organizations answer `423`; read-only organizations hide the write tools. Each call is audited as the calling user; setup calls also appear in the setup audit trail exactly as if the administrator had used the Setup screens. The list/describe/query triple is designed for the way language models work — discover what exists, learn its shape, then query it — so a capable client needs no organization-specific configuration beyond the endpoint URL. ## Connecting your MCP servers to xMatix The reverse direction is a Sense AI Studio concern: register an external MCP server — your pricing service, an internal API, a third-party tool — under **Setup → Sense AI Studio → MCP Servers**, and its tools become callable by [Sense agents](/docs/sense-ai/ai-studio/create-an-agent/) through the MCP tools capability. The list shows **Label**, **Endpoint**, **Auth**, **Credential** and **Status** per server, with **Set credential**, **Edit** and **Delete** actions; **New MCP server** opens the registration dialog. @[guided-image](_img/mcp-server-context.png) The dialog asks for a **Label** and a **Name (system key)**, the **Endpoint (MCP JSON-RPC URL)**, a **Description** of what the server exposes, optional **Tool names** (comma-separated — restricts routing to those tools; blank exposes all of the server's tools), the **Authentication** mode and the **Active** switch. Authentication is one of *None (public endpoint)*, *API key (custom header)* (with the **API key header name**, default `Authorization`), *Bearer token* or *OAuth 2.0 — client credentials* (with the **OAuth token endpoint**, **OAuth client id** and optional **OAuth scope**). The properties that matter to a developer building such a server: - The secret itself is never part of the registration: enter it afterwards through **Set credential**. Credentials are stored **write-only and encrypted** — they are never readable back out of the product, and the list's *Credential* column only says whether one is set. - Tools reach an agent only through the granted MCP capability (`list_mcp_tools` / `call_mcp_tool`), so registering a server changes nothing for agents that are not granted it. - MCP tool calls made from chat are **approval-gated** — the user confirms before the call runs. - Capability scoping is at the MCP-surface level, not per server: an agent granted the MCP tools can reach every active registered server, so register only servers you would trust together, and use **Active** to take one out of rotation instantly. ## Common questions ### How is the MCP endpoint different from the data API? Same platform services, same permission enforcement, different consumer. The [data API](/docs/developer/data-api/) is REST for programs you write, authenticated with your own tokens. The MCP endpoint wraps discovery, description, query, reporting, knowledge search and governed writes behind the Model Context Protocol so AI assistants can use them with nothing but a URL and a sign-in. If you are writing an integration, use the data API; if you are pointing an AI assistant or agent framework at the organization, MCP is the shape it expects. ### Can an MCP client modify data? Only when the organization allows it. Writes need three things at once: the administrator has turned on **Allow writes** under External Assistants, the assistant's token carries the `xmatix.write` scope, and the user could make the same change in the product. Otherwise `create_record` and `update_record` are not even listed. An assistant that must act at scale still belongs on software you control calling the data API, where your code decides what to submit. ### Does using MCP expose data beyond the user's permissions? No. The endpoint requires a real signed-in user, the token is bound to one organization, and every tool call is evaluated against that user's security profiles, record security and restriction rules on the server — the assistant never holds a broader credential. The practical risk to manage is the same as with any AI client: where the *client* sends what it reads. Govern which assistants your users may connect with the **Approved assistants** list and the per-connection **Disconnect**, the same way you govern any tool that handles business data. ### Why does the assistant see fewer tools than this page lists? Tool visibility is the intersection of scopes, capability grants and licensing. A read-only token hides the write tools; an organization that has not licensed or granted a Sense capability (reports, dashboards, knowledge) hides the matching tools; the setup tools appear only for the `xmatix.setup` scope, which needs the write opt-in, and only where the setup tool service is deployed. `whoami` reports the effective scopes, which is the first thing to check. ## Related topics - [The data API](/docs/developer/data-api/) - [AI Studio: governing Sense in your organization](/docs/sense-ai/ai-studio/) - [Extending Sense with your own capabilities](/docs/sense-ai/extending-sense/) - [How Sense AI is governed](/docs/concepts/sense-governance/) ---- # Troubleshooting the developer surface URL: https://xmatix.com/docs/developer/troubleshooting/ Last reviewed: 2026-09-06 Developer-surface failures cluster into a few families — identity, workspace resolution, permission, naming, and drift — and each has a distinctive fingerprint. Work top-down: `xmatix doctor` first for anything CLI-shaped (it tests workspace, config, token and API round-trip in order and names the first failure), then the specific symptom below. ## Sign-in and token problems **"No cached account; run `xmatix login`" — or doctor's token check fails.** The tenant's token cache is empty or unusable on this machine: first use, a cleared cache, or an expired session that can no longer refresh silently (password change, revoked session, long idle). Run `xmatix login`; the persisted config supplies everything except your credentials. On CI runners this is the expected failure mode after provisioning a new runner — the device-code sign-in must be completed once on that machine, because non-interactive sign-in is not available yet ([Authentication](/docs/developer/cli/authentication/)). **Login succeeds but API calls return 401.** The token and the target disagree. Check the workspace config as a set: `apiBaseUrl` and `scopes` must belong together — when `scopes` is empty the CLI derives it from `apiBaseUrl`, so an edited base URL silently changes the audience the token is requested for. After changing `apiBaseUrl` or `authority`, `xmatix logout` then `login` to mint tokens for the new values. **`whoami` shows the wrong user or tenant.** You are in a different workspace than you think — the CLI resolves everything from the nearest `.xmatix/` up the directory tree. `xmatix doctor` prints the resolved root; multi-tenant setups should keep one workspace per directory precisely so that "where am I?" has one answer. ## Workspace and version problems **"No xMatix workspace found. Run `xmatix init` in your repository root first."** No directory from the cwd upward contains `.xmatix/`. Either you are outside the repository, or the repo was cloned without the workspace (someone gitignored `.xmatix/` wholesale instead of only its `cache/` and `tokens/`). Fix the checkout or `init` + `login` fresh; the artifact tree still round-trips. **Doctor flags authority / clientId / scopes as missing.** `.xmatix/config.json` exists but was never fully populated — typically a hand-created file or a partial first login. One complete `xmatix login --tenant … --api-base-url … --authority … --client-id …` persists the full set; doctor should then pass end to end. **Commands behave differently on two machines.** Compare `xmatix --version` — a stale global tool is the usual cause, and `dotnet tool update -g xmatix.cli` the fix. Pin the version in CI images so pipelines and laptops agree on file formats and verbs. ## Push rejections Before debugging a script's behavior, read its deployment state in the product: open the script under **Setup → Process Studio → Scripts** and look at the statistics bar (**Status**, **Active Version**, **Versions**, **Bindings**) and the **Versions** tab. Every push stores a version row with its own compile status; a newer row is not proof that runtime behavior changed — only the row tagged **Active** handles work, and the lightning action on a row is how a stored version is activated by hand. @[guided-image](_img/developer-troubleshooting-context.png) **`scripts push` fails with compile diagnostics.** The server stores the attempted version, records compiler diagnostics against it and leaves the previously active version unchanged; the CLI exits with code 3. Read the line-referenced diagnostics, fix the local `.csx`, and push again. The failed version reached version history for audit, but it did not become the runtime version. **`scripts push` stops with a hash mismatch.** The script changed on the server since your last pull — someone edited it in the product. Pull, reconcile in git (the diff shows the in-product change), then push; use `--force` only once you have decided the local file should win. Treat this as a merge conflict, not an obstacle. **A push "succeeded" but behavior didn't change.** For scripts, the version uploaded without `--activate` — the previous version is still the active one; on the **Versions** tab the new row shows *Compiled* but the *Active* tag stays on the older row, and the header's **Active Version** is unchanged. For workflows, the definition updated as a *draft* — triggers only register from the published version, so publish it or push with `--publish` ([Workflows](/docs/developer/cli/workflows/)). **`metadata push` seemed to skip rows.** Only tenant-owned rows are applied on import; base and package-owned rows in the file are ignored by design. Export with the default `TenantOwned` scope for anything you intend to round-trip ([Metadata](/docs/developer/cli/metadata/)). ## Data API symptoms **401 on every call.** The bearer token is missing, expired, or minted for a different audience than the API host you are calling. Decode nothing — just re-acquire a token for the right base URL and retry; persistent 401s with a fresh token mean the client registration or authority is wrong. **403 or records mysteriously missing.** The API enforces the caller's permissions — security profiles, record security, restriction rules — identically to the UI. A record the integration "can't see" is a record its user can't see; sign in to the product as that user and look. Fix the account's access, not the query ([security model](/docs/concepts/security-model/)). **404 on an entity route.** The path takes the entity's *logical name*, not its display label — `Account`, not "Accounts". Check the name in **Setup → Design Studio → Entities**, via [`metadata pull`](/docs/developer/cli/metadata/), or with the MCP endpoint's `describe_entity` tool ([MCP](/docs/developer/mcp-server/)). **An update is rejected with 409 saying the record is being edited.** Another user holds the record's edit lock in the product; the response names the holder. This is the platform's concurrent-edit protection, applied to API writers too; retry after the lock clears rather than working around it. **An action call returns success but nothing happened.** A named entity action with no bound handler succeeds without effect by design. Verify the action has a bound [automation script](/docs/customization/automation-scripts/quickstart/) or built-in behavior, and that the name in your route matches the action's name exactly — the dispatch is keyed on the name. ## Drift symptoms **The drift gate fails but nobody changed anything.** Someone did — in the product. `migrate plan --keep-server-snapshot` retains the live export under `xmatix/.snapshot/server/`, so you can diff the actual files and identify the change. The remedy is a fresh `snapshot export` committed through review; forcing an apply over unexported changes is how in-product work gets destroyed. **Pull created duplicate-looking files.** An artifact was renamed in the product: pulls write files by logical name, so the new name arrives as a new file and the old file goes stale. Delete the stale file in the same commit — otherwise a later import pushes the old artifact back ([Workspace layout](/docs/developer/cli/workspace/)). ## Related topics - [CLI authentication](/docs/developer/cli/authentication/) - [The data API](/docs/developer/data-api/) - [Migrations](/docs/developer/cli/migrate/) - [CI recipes](/docs/developer/cli/ci/) ---- # Activities: the engagement layer on every record URL: https://xmatix.com/docs/engagement/activities/ Last reviewed: 2026-09-01 Activities are how work-about-a-record stays on the record. A follow-up task on an account, a note on an order, a meeting with a contact, the log of a phone call — each is an activity, attached to the record it concerns, and every record of every entity can carry them. Because the layer is one shared mechanism rather than per-module bolt-ons, the question "what has happened with this customer?" has one answer in one place. ## What an activity is An activity has a **subject** (required — it is also the display name), a free-text description, and three classifying fields with sensible defaults: | Field | Values | Default | | --- | --- | --- | | Type | Task, Call, Meeting, Email, Note, Visit, Document — plus system-written types | Task | | Status | Open, In Progress, Waiting, Completed, Cancelled, Deferred | Open | | Priority | Low, Normal, High, Urgent | Normal | Time fields cover the usual shapes of work: a start and end for meetings, a due date for tasks, a duration, a location. Marking an activity **Completed** stamps its completion time automatically. An activity can also carry a reminder time, and the list shows whether the reminder has been sent. Call-type activities carry call specifics — direction and a call disposition; meeting-type activities carry availability shown to others. Every activity points at its parent record as an entity-plus-record pair, and the parent's display label is copied onto the activity — so activity lists read "Invoice INV-1042", not a bare identifier. Both halves of the link are validated together, and the parent entity must be a real entity in your organization's model — which includes [custom entities](/docs/customization/data-model/create-an-entity/). Activities can additionally reference a contact and an account, so person-centric views work even when the parent is something else. ## Where you work with activities Record pages carry an **Activities** panel listing the record's activities — subject, type, status, priority, due date, reminder state — with create, edit and delete in place. Creating from the panel pre-links the new activity to the record you are on. Activities support attachments and participants, so the meeting's agenda file and its attendees live on the meeting. ## Recurrence An activity with a recurrence rule becomes a series: daily, weekly, monthly or yearly, at an interval (every 2 weeks), ending after a count of occurrences or by an end date — or never. The chaining is completion-driven: when you complete the current occurrence, the next one is created, with its due, start, end and reminder times shifted forward by the recurrence step so each keeps its relative offsets. A lapsed series doesn't pile up unfinished copies — there is always exactly one open occurrence, and the series advances only when work actually happens. Each completed occurrence chains exactly once, so re-saving an old one never spawns duplicates. ## Activities the system writes Not every activity is typed by hand. Modules write timeline entries through the same layer — most visibly, a finished phone call linked to a record writes one **Call** activity onto it with the direction, counterpart number, duration and disposition (see [Calls, dispositions and recordings](/docs/engagement/calls-and-recordings/)). System-written entries render in the same lists with proper labels; they are the reason a record's timeline is complete rather than only as complete as people's discipline. ## Common questions ### Which records can have activities? Any record of any entity — standard or custom. The layer is deliberately entity-agnostic: the parent link is validated against your organization's entity model rather than a fixed list, so an entity you created last week carries activities exactly like accounts and orders do. ### How is an activity different from the call record itself? The [call register](/docs/engagement/calls-and-recordings/) entry is the full telephony record — timings, queue, recording, transcript. The Call *activity* is the compact timeline entry written onto the business record the call was about. One call, linked to a case, produces both: the register row for call reporting, the activity for the case's story. Editing one does not rewrite the other. ### What happens to a recurring series if I cancel an occurrence instead of completing it? Nothing is scheduled next — the chain advances only on completion. That makes cancelling the natural way to end a series early: cancel the open occurrence and the series stops, no cleanup required. ## Common problems **An activity won't save.** The subject is required, and a parent link must be complete — entity and record together, or neither. A parent entity name that isn't a known entity is rejected outright. ## Related topics - [Calls, dispositions and recordings](/docs/engagement/calls-and-recordings/) - [Apps, entities and records](/docs/concepts/apps-entities-records/) - [Create an entity](/docs/customization/data-model/create-an-entity/) - [Using the softphone](/docs/engagement/softphone/) ---- # Call insights URL: https://xmatix.com/docs/engagement/call-insights/ Last reviewed: 2026-09-01 A recorded conversation is only useful if someone reads it, and nobody reads transcripts. Call insights turn a call's transcript into a structured, skimmable analysis on the call record itself — what was discussed, how it went, and what should happen next. Insights are available where your organization has telephony configured **and** transcription producing text for the call; no transcript, no analysis worth having. ## What the analysis contains The insights panel on a call record presents: - **Key discussion points** — a short prose summary of what the call was about. - **Sentiment** — a positive / neutral / negative read of the conversation, shown as a tag. - **What went well** and **Areas for improvement** — coaching notes, each with a severity level and, for improvement items, a concrete suggestion. This is the part aimed at the agent and their supervisor rather than at the record. - **Next best actions** — suggested follow-ups grounded in the conversation. - **Key points** — tag-style highlights for fast scanning. - **A suggested disposition** — advisory only; the agent's own choice is what lands on the call. The analysis never writes the call's fields. The same analysis surfaces in three places: the in-call panel while the conversation is live, the call record afterwards, and the call-details view of the [supervisor console](/docs/engagement/supervisor/). ## How it is produced and stored Analysis runs on demand and is cached. Opening a call's insights panel fetches the stored analysis if one exists, or generates one from the transcript; **Refresh** forces a regeneration — useful when the transcript arrived after the first look. The result is stored with the call's transcript record, so it survives reloads and is generated once, not on every view. The transcript is the single source of truth for the analysis. The generated text also uses what the platform already knows — the matched contact and account names, the call's direction — so summaries read like they were written by someone who knew who was on the line. One honesty mechanism worth knowing: where no AI model is configured for call analysis, the panel can still produce a simpler rule-based summary, and it says so with an explicit "generated without an AI model" note. You will never mistake the fallback for the real thing. ## What insights are not Insights are a reading of the call, not a change to it. They do not edit the call record, do not set the disposition, do not create follow-up tasks by themselves, and are not an approval or workflow step. If a suggested next action deserves to exist as work, an agent creates the task — the same human-in-the-loop stance the platform's other AI surfaces take (see [Asking Sense about your data](/docs/sense-ai/chat/) for the general principles). ## Common questions ### Why does a call have no insights? Because it has no transcript — the analysis is built from the transcript, and calls without one (transcription not enabled, the call never connected, or the text simply hasn't arrived yet) have nothing to analyze. If the transcript arrived after you first opened the panel, use **Refresh** to generate against it. ### Is the sentiment or coaching visible to the customer? No. Insights live on the call record and the supervisor console inside your organization — internal surfaces under your organization's permissions. Nothing about the analysis is sent outward. ### Can I trust the suggested disposition? Treat it as a proposal. It is derived from the same transcript as the summary and is often right, but the agent who was on the call picks the disposition that gets saved, and reporting is built on the agent's choice — precisely so a model's misread can't quietly skew your complaint or sale counts. ## Related topics - [Calls, dispositions and recordings](/docs/engagement/calls-and-recordings/) - [Using the softphone](/docs/engagement/softphone/) - [The supervisor console](/docs/engagement/supervisor/) - [Asking Sense about your data](/docs/sense-ai/chat/) ---- # Calls, dispositions and recordings URL: https://xmatix.com/docs/engagement/calls-and-recordings/ Last reviewed: 2026-09-06 In xMatix a phone call is not an event that evaporates when the line drops — it is a record. Every call handled where your organization has telephony configured lands in the call register with its parties, timings, agent, queue, outcome and links, and it stays queryable like any other record: listed, filtered, reported on. This page explains what a call record carries and where recordings and transcripts fit. ## The call register The register is the **Call Register** list (entity *Call*, in the CRM app and the Service settings app): every call is a row, with headline cards for **Total Calls**, **Avg Talk Time** and **Missed** over the current view, and the usual list tools — search, filters, column filters, saved views and export. The default columns are **Name**, **Ring start**, **Direction**, **From**, **Related record**, **Contact**, **Agent**, **Duration (s)** and **Outcome**; the call form adds the rest of the fields below. @[guided-image](_img/calls-recordings-context.png) ## The call record A call is created the moment it starts ringing (or the moment you dial) and is updated live as it progresses: | Facet | What it holds | | --- | --- | | Direction | Inbound or Outbound | | Status | **Ringing** → **In progress** → a terminal status: **Completed**, **Missed**, **Voicemail**, **Failed** or **Declined** | | Parties | The from and to numbers, plus the matched contact and account where the caller's number is on file | | Timings | **Ring start**, **Answered** and **Ended** times; **Wait (s)** (ring → answer) and **Duration (s)** (answer → end) are computed for you when the call reaches a terminal status | | Handling | The agent who answered and the queue that routed the call, stamped as readable names so lists and reports need no lookups | | Outcome | The **Outcome** field — the disposition the agent chose at wrap-up — plus their **Notes** | | Artifacts | A **Recording URL** and a **Transcript status** (*None*, *Pending*, *Ready* or *Failed*), where those exist | | Provider | Which telephony provider handled the call | Caller matching is automatic: the number is compared — by its tail digits, so formatting and country codes don't matter — against every phone field on your contacts, then account phone numbers. A match fills the call's contact and account; no match leaves them empty rather than guessing. ## Dispositions The disposition is the agent's one-word verdict on the call — the field that turns a pile of call logs into an answerable question ("how many complaints this week?"). The built-in choices are **Resolved**, **Follow Up Required**, **Call Back Later**, **Escalated**, **No Answer**, **Voicemail**, **Wrong Number**, **Complaint**, **Sale** and **Information Provided**. In the softphone's wrap-up view the six most common appear as one-tap chips (Resolved, Follow-up, Call Back Later, Escalated, Sale, Complaint) with the rest under **More…**; the choice is stored in the call's **Outcome** field, which can also be edited later on the call record. Because Outcome is an ordinary picklist, an administrator can extend it with organization-specific values. ## Linking calls to business records A call knows *who* called; it does not presume to know *what about*. The agent links the call to its subject — an existing case, order or any other record — or creates one from the call, pre-filled with the caller's details. Once a call reaches a terminal status while linked, xMatix writes exactly one timeline [activity](/docs/engagement/activities/) of type **Call** onto the linked record: subject, direction, counterpart number, duration and disposition. That is what colleagues see when they open the case or order — the call story on the record it belongs to, without opening the register. Re-linking the call moves that activity to the new record. Calls handled in a third-party dialer outside the platform's own audio path can be logged into the same register through the call-logging endpoint (`POST …/telephony/log`, called as the signed-in agent with the call's direction, numbers, timings and outcome), so the register stays the single history even in mixed setups. ## Recordings Where your organization records calls, the recording is produced by the telephony infrastructure after the call ends and attached to the call record. The call's form then shows a **recording player** — an inline audio player plus a download link, fed by the call's **Recording URL**. The player renders only when a recording actually exists; a call with no recording shows nothing rather than an empty player, so its absence is informative: recording wasn't on, or the recording hasn't arrived yet. ## Transcripts A transcribed call gets a **transcript record** of its own — channel, direction, the text, word count and timing — linked back to the call, which carries just a status flag. Keeping transcripts as separate records keeps call lists light while letting the transcript power what sits on top: [post-call insights](/docs/engagement/call-insights/) are generated from the transcript and stored alongside it. ## Common questions ### Why does a call show no recording? Three explanations, in order of likelihood: your organization doesn't record calls; recording exists but this call's file hasn't been delivered yet (it arrives after the call ends, not during); or the call never connected — there is nothing to record on a missed or declined call. The player appearing on some calls and not others is the design working, not a fault. ### Who can see call records and play recordings? Calls are ordinary records under your organization's [security model](/docs/concepts/security-model/) — entity and record permissions decide who lists them and opens them, and the recording player lives on the call form, so playing a recording requires being able to open the call. The one deliberate exception is the [supervisor console](/docs/engagement/supervisor/), where a separately-granted permission shows supervisors every live call. ### Are missed and declined calls kept? Yes. A call that rang and was never answered ends as **Missed** (or **Declined**), keeps its ring timing and caller match, and counts in per-agent and daily statistics. Missed-call rows are often the most valuable ones in the register — they are the callers you still owe a conversation. ## Related topics - [Using the softphone](/docs/engagement/softphone/) - [Call insights](/docs/engagement/call-insights/) - [Activities](/docs/engagement/activities/) - [The supervisor console](/docs/engagement/supervisor/) ---- # Telephony configuration URL: https://xmatix.com/docs/engagement/configuration/ Last reviewed: 2026-08-15 Telephony administration in xMatix splits cleanly in two: the **infrastructure** — voice trunks and phone numbers — is provisioned for your organization by xMatix, while everything **organizational** — queues, agents, routing — is yours to author. This page is the reference for the four setup screens, the permissions around them, and the deployment shapes telephony can take. It applies where your organization has telephony configured; until then the screens exist but list nothing. All four screens live under **Setup → Feature Hub → Service → Telephony** and require the **manage telephony** setup capability on your [security profile](/docs/administration/security-profiles/). ## Trunks & Numbers The overview screen shows what has been provisioned: - **Trunks** — your organization's voice connections. You can rename a trunk, add a description, enable or disable it, and mark one as the default for outbound calls. You cannot create or delete trunks, and no provider internals or credentials are shown anywhere on the screen — provider settings and secrets are platform-managed and write-protected by design. - **Phone Numbers** — the numbers allocated to your organization, each tied to a trunk. Per number you set a label ("Main support line"), an outbound caller ID, and whether it is active. Numbers, like trunks, are allocated by xMatix — an empty list means none have been provisioned yet. ## Queues Queues distribute inbound calls (and other channel work) to a pool of agents. Each queue defines: | Field | Meaning | | --- | --- | | Name, description | How the queue appears in routing and on call records | | Routing model | Direct, Round robin, Load balance, or Skill-based | | Channels | Which channel types the queue serves — voice among them | | Agent pool | A resource group; the group's **active members** are the routing candidates | | Active | Inactive queues stop taking new work | Membership is deliberately indirect: the pool is a resource group, so staffing a queue is group administration, not queue editing. Deleting a queue is confirmed with the real consequence — inbound routes pointing at it stop assigning agents. ## Agents The Agents screen has two tabs: - **AI agents** — named AI-agent identities that inbound routes can target. Each has an identity name, a display label, a description, optional metadata, and an active flag. An AI agent that is the target of a route cannot be deleted until the route is retargeted. - **Human agents** — the mapping from an xMatix user to a telephony agent identity, with an optional per-agent outbound caller ID and an active flag. Adding a human agent requires telephony to be provisioned (the entry rides your organization's trunk); one that is the target of a route cannot be removed until the route is retargeted. ## Routing Routes bind numbers to targets: each route names a phone number and a target — a queue, an AI agent, or a human agent — with an active flag. The [inbound routing](/docs/engagement/inbound-routing/) page explains the runtime semantics, including the organization-wide fallback. Operationally, the key column here is **sync status**: every route must also exist as dispatch configuration in the telephony infrastructure, and the screen shows whether that push succeeded, the error when it failed, and a re-sync action. Opening the screen re-drives pending routes automatically. ## Permissions Two separate capabilities govern telephony, granted via [security profiles](/docs/administration/security-profiles/): | Capability | Grants | | --- | --- | | Manage telephony | The four setup screens and their APIs | | Supervise telephony | The [supervisor console](/docs/engagement/supervisor/) — live calls, listen, barge | They are separable on purpose: team leads usually need supervision without configuration rights, and configuration admins do not automatically get live-call visibility. ## Deployment shapes Telephony reaches an organization in one of three shapes, chosen with your xMatix account team: 1. **Platform-managed voice** — xMatix runs the voice infrastructure and allocates your numbers from a managed pool. Nothing to host, no provider credentials to hold; this is the standard shape. 2. **Your own carrier trunk** — your organization keeps its carrier relationship and numbers, and the trunk is pointed at the platform's voice infrastructure. Agents get the same in-workspace softphone. 3. **Third-party dialer integration** — calls are handled in an external dialer whose interface embeds inside xMatix; calls are logged into the [call register](/docs/engagement/calls-and-recordings/) through the integration surface, and screen-pop opens the matched record. In this shape there is no in-app softphone. ## Common questions ### Why does adding a human agent fail with "not provisioned yet"? Agent entries attach to your organization's trunk, so they cannot exist before a trunk does. The Trunks & Numbers screen showing an empty trunk list is the confirmation: telephony has not been provisioned for the organization yet — arrange it with your xMatix account team first. ### Who do I ask for a new phone number? xMatix — numbers are allocated by the platform, not created in Setup. Once allocated, the number appears on the Phone Numbers tab for you to label, give an outbound caller ID, and route. ### Can I hide the setup screens from most administrators? Yes — the screens follow the manage-telephony capability, so only profiles granted it see them at all. Keep the supervise capability similarly narrow: its holders see every live call on the organization by design. ## Related topics - [Inbound routing](/docs/engagement/inbound-routing/) - [The supervisor console](/docs/engagement/supervisor/) - [Security profiles and the grant matrix](/docs/administration/security-profiles/) - [Troubleshooting telephony](/docs/engagement/troubleshooting/) ---- # Inbound routing URL: https://xmatix.com/docs/engagement/inbound-routing/ Last reviewed: 2026-09-06 When a call arrives on one of your organization's numbers, something has to decide who it rings. In xMatix that decision is an **inbound route**: a per-number rule, authored by your administrators, that sends the number's calls to one of three kinds of target. This page explains the model — the screens that author it are covered in [Telephony configuration](/docs/engagement/configuration/), and it applies where your organization has telephony configured. ## Numbers and routes Your organization's phone numbers are provisioned by xMatix; administrators label them and control which are active, but do not create them. Each active number can carry one active route — the called number is the whole routing key, which is why teams usually want one number per purpose (support line, sales line) rather than one number for everything. Before any routing happens, the caller is matched to a contact and account from your records, so whoever the call eventually rings sees a name, not just a number. ## Authoring a route Routes live under **Setup → Telephony → Routing**. The list shows each route's **Name**, **Number**, **Target**, **Status** (the sync status explained below) and **Updated**, with **Edit**, **Resync** and **Delete** per row; **New Route** opens the dialog. @[guided-image](_img/inbound-routing-context.png) A route has five controls: **Name**; **Number** (one of the organization's provisioned lines); **Route to** — *Queue*, *AI agent* or *Human agent*; the matching selector (a queue, a registered AI-agent identity, or a user); and **Active**. Creating or editing a route saves the row and immediately tries to push the matching dispatch rule to the telephony infrastructure. Before saving, confirm the target is active and able to take work — an inactive human-agent binding or an empty queue does not break the number, it sends its calls to the organization-wide ring described below. ## The three target types | Target | What happens to the call | | --- | --- | | **Queue** | The call becomes a work item in an omni-channel queue and is offered to one available member of the queue's agent pool, per the queue's routing model — direct, round robin, load balance, or skill-based. That agent's softphone rings, carrying the queue context. | | **Human agent** | The call rings exactly one named person's softphone — a private line or a named-account arrangement expressed as routing. | | **AI-agent identity** | The call is dispatched to a named AI-agent identity registered by your administrators, and no human is rung for it. The identity and its activation are yours to manage; retiring one that a route still targets is blocked until the route is retargeted. | Queues are the same queue machinery used across channels — a queue declares which channels it serves, and its membership is a resource group whose active members are the routing candidates. See [Telephony configuration](/docs/engagement/configuration/) for the queue fields. ## Fallback: the organization-wide ring Routing is deliberately fail-open. If a number has no active route, if a route's target can't take the call (an inactive agent, a queue with nobody available), or if route handling fails outright, the call falls back to ringing **every signed-in agent on your organization**. A misconfigured route therefore makes calls noisier, not lost — the failure mode is everyone's phone ringing, which has the useful property of being impossible to miss. ## Keeping routes in sync A route is not just a database row — it must also exist as dispatch configuration in the telephony infrastructure that actually answers the number. xMatix reconciles the two automatically on every route change, and each route displays a **Status** of *Pending*, *Synced* or *Error* (with the error text when a push fails). A failed or pending route can be re-synced explicitly with **Resync**, and simply opening the routing screen re-drives anything left pending. Deleting a route removes its dispatch rule in the same reconcile. Until a new route syncs, calls on that number keep flowing via the previous behavior or the organization-wide fallback rather than dropping. ## Common questions ### What happens when nobody in the queue is available? The call falls back to the organization-wide ring — every signed-in agent is offered it, not just the queue's members. There is no built-in hold-music waiting room in this model: a call that can't be placed with its intended pool escalates to everyone rather than parking. Staff the pool (or widen the resource group) to keep calls where you intended them. ### Can one number ring a queue during the day and an AI agent after hours? Not with routes alone — a route has no schedule; it is one number, one target. Time-of-day behavior needs either separate numbers or changing the route's target (routes can be edited and re-sync automatically). If schedule-driven routing matters to you, raise it with your account team so it's on the record as demand. ### Do declined and unanswered calls disappear? No — every inbound call is a record in the [call register](/docs/engagement/calls-and-recordings/) from the moment it rings, whatever happens next. Unanswered calls end as Missed, keep their caller match and timings, and are the natural start of a call-back list. ## Related topics - [Telephony configuration](/docs/engagement/configuration/) - [Using the softphone](/docs/engagement/softphone/) - [The supervisor console](/docs/engagement/supervisor/) - [Calls, dispositions and recordings](/docs/engagement/calls-and-recordings/) ---- # Telephony & Messaging in xMatix URL: https://xmatix.com/docs/engagement/ Last reviewed: 2026-09-01 Engagement is where xMatix meets your customers directly: phone calls handled inside the workspace, every interaction logged against the record it belongs to, and outbound messages sent over the channels your organization has configured. Because calls, notes, tasks and messages all land on the same records as your orders and invoices, the history of a relationship reads in one place — not across a phone system, a notes app and a mailbox. One availability note up front: **telephony features run only where your organization has telephony configured** — voice trunks and phone numbers provisioned for your organization. Where that is not in place, the call surfaces simply do not appear; the [activity layer](/docs/engagement/activities/) and [messaging channels](/docs/engagement/messaging-channels/) work everywhere. Interested in telephony for your organization? See the [product overview](/products/engagement/) or [request a demo](/demo/). ## The pieces **Calls in the browser.** Where telephony is configured, agents take and place calls from an embedded softphone — no separate phone software. An incoming call is matched to the caller's contact and account before anyone answers, and every call becomes a record in the call register with its timings, agent, queue, disposition, and any recording or transcript. **Intelligence on top.** Where a transcript is available, a call can be analyzed after the fact — summary, sentiment, coaching notes, suggested next actions. Supervisors get a live console with every active call, per-agent load, silent listening and barge-in. **The activity layer.** Notes, tasks, calls, meetings and reminders attach to any record of any entity — the shared timeline that both humans and the telephony module write to. This is fully available today, telephony or not. **Outbound messaging.** A single messaging pipeline sends email, in-app notifications, push notifications, SMS via your organization's messaging provider, and connector-backed channels — with a durable outbox, delivery receipts, flood protection and an administrator-visible message log. ## What's in this section | Page | What it covers | | --- | --- | | [Using the softphone](/docs/engagement/softphone/) | Taking and placing calls in the workspace: availability, dialing, the incoming-call match, in-call controls, wrap-up | | [Calls, dispositions and recordings](/docs/engagement/calls-and-recordings/) | The call register: statuses, durations, dispositions, record links, timeline activities, the recording player | | [Call insights](/docs/engagement/call-insights/) | Post-call AI analysis where transcription is available | | [Inbound routing](/docs/engagement/inbound-routing/) | Numbers and routes: sending a number's calls to a queue, a person, or an AI-agent identity | | [The supervisor console](/docs/engagement/supervisor/) | Live calls, agent stats, listen and barge-in | | [Activities](/docs/engagement/activities/) | Notes, tasks, calls and meetings on every record — statuses, reminders, recurrence | | [Messaging channels](/docs/engagement/messaging-channels/) | Channel configuration, the delivery pipeline, statuses, the message log | | [Telephony configuration](/docs/engagement/configuration/) | Administrator reference: trunks, numbers, queues, agents, routes | | [Troubleshooting telephony](/docs/engagement/troubleshooting/) | Grounded fixes for the common telephony symptoms | ## Common questions ### Do agents need to install anything to take calls? No. Where your organization has telephony configured, the softphone runs in the browser inside the xMatix workspace — call audio, controls and the caller's matched record are all in the same window. Agents need a microphone and browser permission to use it; there is no desk-phone registration and no per-agent credential to manage. ### Is telephony available to every organization? Not automatically. Voice trunks and phone numbers are provisioned per organization, and the telephony pages in this section describe behavior **where that provisioning is in place**. If the Calls surface does not appear for your organization, telephony has not been set up — talk to your administrator or your xMatix account team, or [request a demo](/demo/) to see it working. ### How do calls relate to the activities I see on records? When a call ends and is linked to a business record — a case, an order, any entity — the system writes one activity of type **Call** onto that record's timeline, carrying the direction, counterpart number, duration and disposition. The call itself remains a full record in the call register; the activity is the compact timeline entry colleagues see when they open the related record. See [Activities](/docs/engagement/activities/). ## Related topics - [Using the softphone](/docs/engagement/softphone/) - [Activities](/docs/engagement/activities/) - [Messaging channels](/docs/engagement/messaging-channels/) - [Telephony & Messaging](/products/engagement/) — product overview ---- # Messaging channels and the message log URL: https://xmatix.com/docs/engagement/messaging-channels/ Last reviewed: 2026-08-15 All outbound messages in xMatix — whatever sends them and whatever carries them — travel one pipeline: content is rendered once, a durable outbox row is written per channel and recipient, a delivery worker sends and retries, and every row's fate is visible in the message log. This page is the administrator's reference for the channels, the statuses, the protections, and the log. ## The channels | Channel | Carrier | Recipient addressing | | --- | --- | --- | | Email | Your organization's email sending service | Email address | | In-app | Delivered inside xMatix itself | User | | Push | Mobile push notifications to the xMatix app | User | | SMS | Your organization's messaging provider | Phone number | | Connector-backed | Any service reachable through a configured connector | Provider-specific target | Messages come from the platform's own senders — [business rules](/docs/customization/business-rules/), [workflows](/docs/customization/workflows/), automation scripts, and report or dashboard subscriptions — with content supplied inline or rendered from your organization's templates. Attachments (report subscriptions, typically) are supported on the email channel only, and attachment sends are still recorded in the log. ## Channel configuration Channels that need provider credentials — SMS and connector-backed ones — are configured per organization under **Setup → Feature Hub → Service → Messaging Channels**. Each configuration carries: | Field | Meaning | | --- | --- | | Label / name | How the channel appears; the name is its stable key | | Channel | Which channel kind this configures | | Provider | The provider integration that carries it | | From | Sender number or address | | Secret name | The *logical name* of the provider credential — the secret value itself is held in the platform's secure secret store and is never stored or displayed in the configuration | | Settings | Provider-specific settings, including optional per-channel rate limits and quiet hours | | Enabled | Disabled channels are skipped with a diagnostic rather than erroring | Every configuration row has a **Test send** action that queues a real message to an address you supply and shows the submission diagnostics — the two-minute proof that credentials and sender identity work before a rule depends on them. ## Delivery statuses Each outbox row moves through explicit states, all filterable in the log: | Status | Meaning | | --- | --- | | Queued | Written and waiting for the delivery worker (possibly deferred by rate limits or quiet hours) | | Sending | A delivery attempt is in flight | | Sent | Handed to the provider | | Delivered | The provider confirmed delivery — on channels that report receipts, a provider callback upgrades Sent to Delivered | | Failed | Attempts exhausted or the provider reported failure; the row keeps its last error text | | Skipped | Not attempted — for example, the recipient could not be resolved | | Held | Quarantined by the flood guard, awaiting an administrator's review | Rows stuck mid-flight (a crashed worker, a lost enqueue) are found by a recovery sweep and re-driven automatically after a grace period — delivery is at-least-once with idempotent re-drives, not fire-and-forget. ## Protections The pipeline assumes that one day a rule will misfire in a loop, and is built to make that day boring: - **Tenant-wide circuit breaker** — past an hourly send cap for the whole organization, every new message is **Held** rather than sent, and administrators are alerted with instructions to review the log, fix the source, and release. - **Per-recipient caps** — hourly and daily limits per recipient and channel hold further sends to one inbox even when the organization-wide breaker hasn't tripped. - **Rate limits and quiet hours** — per-channel settings defer a message's first attempt to the allowed window instead of dropping it. - **Opt-outs** — user preferences are enforced at submit time for the user-addressed channels (in-app and push); opted-out recipients are skipped and counted in diagnostics. Held is a quarantine, not a failure: held rows sit out of the send window (so they cannot re-trip the guard) until released. ## The message log **Setup → Platform Operations → Monitoring → Message Log** lists every outbound message across all channels — created time, channel, status, recipient, subject, attempt count, category and the last error — filterable by channel, status, recipient and date range. Two operations live here: **Resend** re-queues a failed row, and **Release** (per row, or *Release held* for everything at once) returns quarantined rows to the queue. Viewing the log is its own permission, so operations staff can watch delivery without holding wider setup rights. ## Common questions ### Why is a message Held, and what should I do? The flood guard held it — either the organization crossed its hourly send cap or that recipient hit a per-recipient limit. Before releasing, find what generated the volume (the category and source columns point at the origin) and fix it; releasing without fixing re-runs the flood with your fingerprints on it. Then filter the log to status Held and release. ### Why does a message sit at Sent and never reach Delivered? Delivered requires a provider receipt, and not every channel reports one. Absence of Delivered on such channels is normal and does not mean the message failed — failure is explicit, with status Failed and an error. Judge each channel by the statuses it can actually reach. ### Where do templates fit? A message request can name a template instead of carrying inline content; the pipeline renders it once at submit time — with the record model the sender supplied — and every channel and recipient of that submission shares the rendered result. Senders that support templates (business rules, workflows) let you pick the template where you author the rule. ## Related topics - [Business rules](/docs/customization/business-rules/) - [Workflows](/docs/customization/workflows/) - [Activities](/docs/engagement/activities/) - [Telephony & Messaging](/products/engagement/) — product overview ---- # Using the softphone URL: https://xmatix.com/docs/engagement/softphone/ Last reviewed: 2026-08-31 Where your organization has telephony configured, xMatix puts a softphone inside the workspace: calls ring in the browser, the caller is identified from your records before you answer, and the call's log writes itself. This page walks through a call from availability to disposition. ## Prerequisites - Your organization has telephony configured (trunks and numbers provisioned), and — where your administrators manage agents explicitly — you are set up as an agent. - A working microphone, with the browser allowed to use it. The first call prompts for microphone permission; a call with a denied microphone is a call nobody can hear you on. ## Procedure ### Step 1 — Open the Calls drawer and set your availability First confirm telephony is provisioned and your browser has microphone permission, then open the **Calls** drawer at the workspace edge. It shows availability, the dial box and recent calls. Choose **Available** only when you are ready to receive queue work; Busy, Away and Offline suppress offers. Calls and chat have separate presence, so verify the Calls indicator itself changes. If the live feed disconnects, the drawer pins you Offline—wait for reconnection and confirm status becomes selectable before testing a call. ### Step 2 — Place an outbound call Use an approved test destination. Type or paste the number, confirm its country code and displayed caller identity, then dial once; alternatively redial a known recent party. Watch the state progress from dialing to ringing or connected and verify audio in both directions. The system creates the outbound Call register entry immediately and attempts contact/account matching. Open that entry afterward and confirm direction, numbers, timestamps and matched party—correct an underlying phone field rather than manually linking repeated mismatches. ### Step 3 — Answer an incoming call An incoming call raises a popup above everything else in the workspace, and it identifies the caller before you answer: the matched contact's name and account where the number is recognized, an honest "Unrecognized number" where it is not, and — when this caller has called before — how long ago the last call was. Matching compares the tail digits of the number against every phone field on your contacts (then account phone numbers), so formatting and country-code differences don't break it. **Accept** connects the call and opens the full call panel; verify the timer starts and exchange a short audio confirmation before discussing anything sensitive. **Decline** dismisses the ring only on your side, so a team call may still be answered elsewhere. For the controlled test, confirm the popup's recognized or unrecognized identity is accurate, accept from one agent only, and verify other ringing clients stop when the call is claimed. ### Step 4 — Work the call The connected-call panel keeps everything in one place while you talk: - **Controls** — mute, hold, hang up; transfer and recording control where your organization has them enabled. While you navigate elsewhere, a compact pill keeps the timer and core controls visible. - **Context** — the matched contact and account are one click from their records, so you're reading the caller's history seconds into the call. - **Notes and script** — type notes as you go; a tickable guided script tracks where you are in the conversation. - **Link or create a record** — attach the call to the record it is about, or create one from the call (a case, lead, opportunity, order, service order or task by default — your administrators can change the list). Created records are pre-filled with the caller's contact, account and number. Exercise mute and hold during a test call and have the other party confirm the audio behavior; use transfer or recording only where policy and configuration allow it. Open the matched context before linking, type concise factual notes, and verify any created record's prefilled contact, account and number before saving. The compact pill should retain the correct timer and controls while you navigate away and back. ### Step 5 — Wrap up with a disposition Hang up only after confirming the conversation is complete. During the after-call-work countdown, choose the most specific disposition, finish notes and create any promised follow-up before saving; do not let the timer return you to the queue with an incomplete record. Open the Call register and linked business record to verify duration, disposition, notes and one Call activity. Finally confirm your presence returns to Available—or deliberately choose another state—before leaving the drawer. ## Expected result Telephony is provisioned, the Calls drawer shows the agent's honest availability, and a controlled test call can be placed, answered, muted, held and ended with working audio. The Call register receives one correctly timed entry linked to the intended record, with notes, disposition and any follow-up retained. ## Common problems **No softphone or Calls drawer appears.** Telephony isn't configured for your organization, or your agent setup is missing or inactive. Start with [Troubleshooting telephony](/docs/engagement/troubleshooting/). **You answer but hear nothing, or callers can't hear you.** Almost always browser microphone permission or the wrong input device — check the browser's site permissions, then your OS input device. **Calls ring colleagues but never you.** Your availability is not Available, or the number's route targets a queue whose agent pool you are not in. See [Inbound routing](/docs/engagement/inbound-routing/). ## Common questions ### Can I take calls with the tab in the background? Yes — the ring popup and call audio belong to the workspace tab, so keep it open. The popup positions itself above open panels precisely so an incoming call is never hidden behind something else. Closing the tab mid-call ends your leg of it. ### What happens if I don't pick a disposition? The call is still logged — timings, parties, agent and any record link are captured regardless. The disposition is the one part only you can add, and it is what makes call reporting worth reading; the wrap-up window exists to make choosing one a two-second act rather than an afterthought. You can also open the call record later and set the outcome there. ### Where do my calls go afterwards? Every call — answered, missed or declined — is a record in the call register, visible in the Calls drawer's recent list and as a full record with its recording, transcript and insights where those exist. See [Calls, dispositions and recordings](/docs/engagement/calls-and-recordings/). ## Related topics - [Calls, dispositions and recordings](/docs/engagement/calls-and-recordings/) - [Call insights](/docs/engagement/call-insights/) - [Inbound routing](/docs/engagement/inbound-routing/) - [Troubleshooting telephony](/docs/engagement/troubleshooting/) ---- # The supervisor console URL: https://xmatix.com/docs/engagement/supervisor/ Last reviewed: 2026-09-01 The supervisor console is the live operating picture of your organization's calls: everything ringing or in progress right now, how loaded each agent is, today's numbers, and the ability to listen to — or join — a call that needs help. It is available where your organization has telephony configured, and it is deliberately privileged: holders of the **supervise telephony** permission see every call on the organization, because a supervisor who can only see their own calls supervises nothing. Without the permission the console shows an access-required notice and opens no data feed at all. The console is a widget your administrators place on a page — typically a dedicated full-page view for team leads. ## The live picture **Headline tiles** summarize the moment: active calls, calls waiting, queue backlog, agents available, agents busy, calls handled today, and today's average talk time. **Active calls** lists every ringing and in-progress call with the matched caller name and account, the dialed number, the handling agent, the queue, status and a live-ticking duration. Completed calls drop into a **completed today** list beneath it — caller, agent, outcome, talk time, end time. Each row opens a details view with the full timings, wait and talk figures, and the call's [AI insights](/docs/engagement/call-insights/). **Agents** shows each routed agent's presence, current load against their capacity, calls in progress, handled and missed counts for the day, and average talk time — the view that answers "who has room for one more?" at a glance. Rows update from the live call feed as calls ring, connect and end; when the live feed is unavailable the console falls back to polling, and a refresh also runs whenever you return to the tab. The numbers you act on are current either way. ## Listening and barging in From an in-progress call's row, **Listen** joins you to the call audio silently — the conversation continues undisturbed while you hear both sides. From a listening session, **Barge in** escalates you to a live participant, behind an explicit confirmation that states the consequence plainly: both the agent and the customer will hear you from the moment you join. While barged you can mute and unmute yourself; **Stop** leaves the call either way, and if the monitored call ends the session ends with it. Two built-in constraints keep monitoring honest: - **You cannot monitor while on your own call** — end yours first. - **Only connected calls can be monitored** — there is nothing to hear on a ringing one. Crucially, monitoring is invisible to the call's bookkeeping. A supervisor joining is never counted as the call being answered, never stamps the answer time, and never attributes the call to the supervisor — wait-time and talk-time metrics, and the agent's own stats, stay exactly as if no one had listened. Monitoring observes the numbers; it does not participate in them. ## Common questions ### Why can't I see the console — or why is it empty? If you see "Supervisor access required", you lack the supervise telephony permission; an administrator grants it via [security profiles](/docs/administration/security-profiles/). If the console renders but shows no calls, there are simply none active — check the completed-today list and the tiles to confirm the feed is alive before suspecting a fault. ### Does listening affect the call or its metrics? No. Silent listening adds no audio and no participant the metrics recognize: answer times, durations, and per-agent attribution are computed as if you were not there. Only barging changes the conversation — and it announces itself by being audible. ### Can I monitor an agent rather than a call? Monitoring attaches to a call, not a person — pick the agent's current call from the active grid. The Agents tab is the per-person view (load, handled, missed, averages), and the details drawer plus [call insights](/docs/engagement/call-insights/) cover the review-after-the-fact case without live audio. ## Related topics - [Call insights](/docs/engagement/call-insights/) - [Inbound routing](/docs/engagement/inbound-routing/) - [Calls, dispositions and recordings](/docs/engagement/calls-and-recordings/) - [Security profiles and the grant matrix](/docs/administration/security-profiles/) ---- # Troubleshooting telephony URL: https://xmatix.com/docs/engagement/troubleshooting/ Last reviewed: 2026-09-01 ## Read the telephony provisioning context @[guided-image](_img/telephony-troubleshooting-context.png) Telephony troubleshooting begins at Setup → Service → Telephony. Trunks establish provider connectivity; Phone Numbers establish dialed identities; and the row fields expose provider, default selection and status. The empty demo2 list illustrates the base rule: without organization provisioning, softphone, call routing and recording behavior are not expected to appear, so investigating an agent or route first would skip the failing layer. Confirm an active trunk and assigned number, then move outward in call order: browser microphone permission and agent binding, presence and queue eligibility, inbound-route synchronization, call-register evidence, recording delivery, transcript and insight generation. Record the call identifier and exact timestamps when escalation is necessary, but redact numbers, contact identity, recordings and transcript text. Each layer leaves separate evidence; fix the earliest missing or failed one rather than recreating downstream configuration. Telephony problems in xMatix usually have short explanations, because each stage of a call leaves visible evidence: provisioning shows on the setup screens, routing shows a sync status, and every call — even a failed one — leaves a record in the register. This page works through the common symptoms in the order they occur in a call's life. Everything here presumes the base condition: telephony behaves only where your organization has it configured. ## No softphone — the Calls surface is missing or dead Check in this order: 1. **Is telephony provisioned at all?** An administrator should open **Setup → Feature Hub → Service → Telephony**. Empty trunk and number lists mean the organization has no telephony yet — nothing downstream can work, and the fix is provisioning, not settings. 2. **Is the trunk enabled?** A disabled trunk switches the softphone off for everyone bound to it. 3. **Is this user set up as an agent?** Where agents are managed explicitly, a missing or inactive entry on the Agents screen leaves that user without a softphone while colleagues have one. 4. **Is the microphone allowed?** A softphone that connects but carries no audio is almost always browser microphone permission or the wrong input device. ## Incoming calls don't ring me Assuming colleagues do get calls: - **Your availability.** Only an Available agent is offered queue work — check the status in the Calls drawer. If the drawer has pinned you **Offline and won't let you change it**, your live call feed is disconnected; that pinning is deliberate (ringing a dead session helps nobody). Reload the workspace and let it reconnect. - **The route doesn't point at you.** A number routed to a queue rings one member of the queue's agent pool; if you are not an active member of that resource group, it will never be you. A number routed to a specific person or an AI-agent identity rings no one else at all — by design. - **Check what the call became.** Every inbound call leaves a register row from its first ring. Find it and read the status and queue: a Missed row that names a queue tells you routing worked and staffing didn't. ## Callers show as bare numbers The ring popup says "Unrecognized number" when no contact or account carries the calling number. Matching compares the tail digits of the number against every phone field on contacts, then account phone numbers — so formatting and country-code differences are already forgiven, and the practical fix is data: put the number on the contact, and the next call matches. Two contacts sharing a number will match as one of them; matching picks a candidate rather than presenting a choice. ## No recording, or no transcript and insights - **The player only renders when a recording exists.** Its absence means recording is not enabled for your organization, the file hasn't arrived yet (recordings are delivered after the call ends), or the call never connected — nothing records on a missed call. - **Insights need a transcript.** [Call insights](/docs/engagement/call-insights/) are generated from the call's transcript; without transcription there is nothing to analyze. If the transcript arrived late, **Refresh** on the insights panel regenerates against it. ## A route shows a sync error Routes must be pushed to the telephony infrastructure, and the Routing screen shows each route's sync status with the failing error text. Use the route's re-sync action; opening the screen also re-drives anything pending automatically. Until the push lands, calls on that number follow the previous behavior or the organization-wide fallback — noisy, not lost. A sync error that persists across re-syncs is worth raising with xMatix support, quoting the error text shown on the route. ## Supervisor can't listen to a call Three gates, all deliberate: only **connected** calls can be monitored (nothing to hear on a ringing one); you cannot monitor **while on your own call**; and the token to join is minted per call, so a call that ends between click and connect fails with "the call may have ended" — pick a live one. An access-required notice instead of the console means the supervise-telephony permission is missing; see [The supervisor console](/docs/engagement/supervisor/). ## Common questions ### Everyone's phone rings for every call — is that broken? No: that is the fallback working. Calls ring the whole organization when the number has no active route, or the routed target couldn't take the call (queue with nobody available, inactive agent). The system fails open — toward noise — rather than dropping calls. Author routes for each active number and staff their pools, and the broadcast stops. ### A call connected but shows the wrong agent — how? The answering agent is stamped when the call is answered, and queue assignment names whoever the routing model selected. If a different person picked the call up on the organization-wide fallback, the stamp follows reality, not the plan — read it as evidence about staffing, not a data bug. Supervisor monitoring is the one join that never affects attribution. ### Where do I see errors for calls that failed outright? In the call register: failed calls end in the **Failed** status like any other terminal state, keeping their timings and parties. Cross-reference the [supervisor console's](/docs/engagement/supervisor/) completed-today list for the day's picture, and the Routing screen's sync column when failures cluster on one number. ## Related topics - [Using the softphone](/docs/engagement/softphone/) - [Inbound routing](/docs/engagement/inbound-routing/) - [Telephony configuration](/docs/engagement/configuration/) - [Calls, dispositions and recordings](/docs/engagement/calls-and-recordings/) ---- # Expense accounting and recharge URL: https://xmatix.com/docs/expenses/accounting/ Last reviewed: 2026-09-06 Expense Management holds no money of its own. Every event — a claim approved, an advance paid, a card bill settled — posts a balanced [journal](/docs/finance/journals/) into the same ledger as every other finance document, dated by the document's date and linked back to its source record. Posted lines are immutable; corrections are reversals. What the module adds on top is the **employee subledger**: per-employee open items that carry what the company owes each person and what each person owes back, reconciled to control accounts like any receivable or payable. ## The posting map | Event | Debit | Credit | | --- | --- | --- | | Claim posted (on final approval) | each line's expense account; input GST for ITC-eligible tax | Employee Payable, net of any advance adjustment | | Reimbursement (single or batch) | Employee Payable | Bank | | Claim settled via payroll | Employee Payable | Payroll Payable | | Advance paid | Employee Advance | Bank | | Advance settled against a claim | Employee Payable | Employee Advance | | Advance recovered in cash | Bank | Employee Advance | | Card transaction posted | the transaction's expense account | Card Payable | | Card statement paid | Card Payable | Bank | Two details in the claim posting are worth knowing. First, the **ITC split**: on a line marked ITC-eligible, the tax goes to the input-GST account and only the net amount hits the expense head — the tax is recovered, not expensed; on other lines the gross posts to the expense head. Per-component tax details (CGST, SGST, IGST, cess) are also captured for tax reporting, on a best-effort basis that never blocks the ledger posting. Second, **dimensions**: cost centers are stamped on the expense lines only — never on the control or bank lines — so cost-center reporting stays a clean P&L view, while branch rides every line it applies to. ## Where the accounting inputs live on the claim The header of an expense claim carries the accounting context: **Resource** (the employee whose subledger carries the payable), **Claim Date** (the posting date), **Currency Code**, **Branch**, **PaymentGL Account** (the bank or cash account a finance reimbursement credits) and, on the **Reimbursement** tab, **Reimbursement Mode** — *FinancePayment* (paid by a finance reimbursement, singly or in a batch) or *Payroll* (settled through a payroll run, with **Payroll Period** and **Payroll Component** to say which). Each claim line carries the **Expense GL Account** it debits, its **Cost Center**, **Tax Amount** and **Itc Eligible** flag, and the recharge fields (**Is Billable To Customer**, **Customer Account**, **Markup Percent**). The header also shows the three statuses the ledger side reads: **Approval Status**, **Posting Status** and **Payment Status**. The posting steps are entity actions on the claim, so they appear as buttons and can be driven by automation: **Evaluate Policy**, **Post Claim**, **Post Reimbursement** (asks for the bank account and payment date), **Settle Via Payroll**, **Compute Recharge** and **Link Recharge Invoice**. ## Employee balances are open items Posting a claim raises an open payable item against the claimant's employee record; paying an advance raises an open recoverable item the same way. Reimbursements, settlements and recoveries reduce those items until they close. Because balances live as open items rather than as GL detail, the GL stays summarized — the control accounts carry totals, the subledger carries the per-employee story — and the employee-payable ageing always ties to the control account, since both read the same items. This is the same open-item machinery behind the [AR and AP subledgers](/docs/finance/subledgers/). ## Automatic posting, and its one failure mode Final approval posts the claim automatically (stamping **Status** and **Posting Status** to *Posted*), and replaying a decision never double-posts because an already-posted claim is skipped. But the approval decision and the posting are deliberately decoupled: if posting fails — a missing *Employee Payable* control account is the classic cause; the error names the missing account type — the approval stands and the failure is logged rather than rolling the sign-off back. The tell is a claim whose **Approval Status** is *Approved* while **Posting Status** is not. Fix the cause and run **Post Claim** on the claim; [Troubleshooting](/docs/expenses/troubleshooting/) decodes each posting error. ## Rebilling clients: recharge Claim lines marked billable-to-customer carry the customer and an optional markup. **Compute Recharge** on the claim flags those lines as pending billing and returns the per-customer (and per-project) totals — cost, and cost with markup applied. You then raise the customer invoice through your normal sales flow for those totals, and **Link Recharge Invoice** stamps the lines as `Billed` against that invoice, closing the loop so nothing is rebilled twice or forgotten. ## Reconciliation and period close Control-account reconciliation ties the employee-payable and employee-advance open-item totals to their GL control balances, alongside the AR, AP, bank and other reconciliations. [Period close](/docs/finance/period-close/) includes advisory checks for both employee subledgers, so an untied balance is surfaced before the period is closed rather than discovered after. ## Common questions ### Which period does a claim post into? The period containing its claim date — the same rule every document and [journal](/docs/finance/journals/) follows. Reimbursements post on their payment date. A claim dated last month posts into last month, provided the period is open. ### Why isn't the employee a party on the payable, like a supplier? Because the employee is identified on the open item, not on the journal line. The control accounts are configured so their lines need no party — the subledger holds the per-employee detail while the GL stays summarized. It also means expenses and payroll share one person key: the employee record. ### The claim is approved but never appeared in the ledger — is the approval lost? No. The approval committed; the posting that follows it failed and was logged. Fix what the error names — almost always a missing control account or a claim with nothing postable — and post the claim manually. The claim's posting status tells you which side you are on. ### Can a posted claim be corrected? Not by editing — posted journal lines are immutable. Correct through the finance reversal pattern: reverse the posting journal, fix the claim, and post again. The original stays in the ledger as the audit record, exactly as with [manual journals](/docs/finance/journals/). ## Related topics - [Working with journals](/docs/finance/journals/) - [AR and AP subledgers](/docs/finance/subledgers/) - [Closing a period](/docs/finance/period-close/) - [Reimburse expense claims](/docs/expenses/reimbursement/) - [Configuring Expense Management](/docs/expenses/configuration/) ---- # Employee advances URL: https://xmatix.com/docs/expenses/advances/ Last reviewed: 2026-09-02 An advance is the mirror image of a claim: the company gives you money up front — a travel float, a project imprest — and you owe it back. The debt is cleared either by setting the advance off against the expense claims you file, or by returning the unspent cash. Every step posts a journal, so the outstanding advance is a real ledger balance, aged and reconciled like any other. ## Prerequisites - Access to the Expense Advance entity in the Expenses app. - The requester's employee record — advances, like claims, are anchored on it. - For paying and settling (finance): an Employee Advance control account configured as a current asset, and the bank account to pay from — see [Configuring Expense Management](/docs/expenses/configuration/). ## Procedure ### Step 1 — Request the advance Open **Expense Advances**, choose **New**, and confirm the employee resource before entering the requested amount and a purpose specific enough for an approver to judge. The current create layout does not expose a currency, advance date or project field, so do not use the form as evidence that those dimensions were captured. Save once and reopen the record: it should start as `Requested`, have no payment reference and show the exact requested amount without an outstanding balance yet. ### Step 2 — Get it approved Submit through the configured [approval process](/docs/customization/approvals/). Confirm the request becomes pending, the expected approver resolves, and maker-checker or amount thresholds add the required controls. The approver should review employee, purpose, amount and allocation before deciding. Finance must verify the terminal Approved state and full decision trail; an email or verbal approval is not a substitute for the record's approval status. ### Step 3 — Pay the advance (finance) On the approved record, choose **Pay Advance**, select the verified bank account and compare the confirmation amount with the approval before submitting once. Treat the Approved check as an operator control: the current pay handler does not itself reject a non-approved status. The posting debits employee-advance, credits bank and creates a recoverable open balance. Open the journal and verify date, employee, accounts and amount; the advance must read `Paid` and outstanding must equal the payment. Do not retry a direct posting: unlike approval-event replay, which skips an already-posted event, a direct repost can throw rather than return a harmless success. ### Step 4 — Settle it against a claim (finance) Wait until the related claim is both approved and posted, then choose **Settle Against Claim** and confirm employee, currency, claim open payable and advance outstanding all agree. Enter no more than the smaller balance and submit once. Open the resulting settlement and journal: both open items should fall by the same amount, and neither may go negative. Repeat with separate claims only for a remaining balance. When outstanding reaches zero verify the advance is `Settled`; when the claim also reaches zero verify it is no longer offered for reimbursement. ### Step 5 — Recover the unspent balance (finance) When all claims are accounted for, collect the unspent cash and choose **Recover Advance**. Select the bank account that actually received it and compare the entered amount with both the receipt and current outstanding; the default is the full remaining balance but partial recovery is allowed. After posting, verify bank debit and employee-advance credit, attach the receipt reference, and reconcile the new outstanding. A zero balance must close as `Recovered`; a partial balance remains open for another settlement or recovery. ## Expected result The approved advance posts once against the configured employee-advance and bank accounts, its outstanding balance equals the amount still owed, and each claim settlement or cash recovery reduces that balance with a separate auditable record. A zero balance closes in the appropriate Settled or Recovered state. ## Common problems **Settle Against Claim is refused with "Claim is not posted."** Settlement works open balance against open balance, so the claim must be approved and posted first. Post the claim (final approval does this automatically), then settle. **"Nothing to settle."** One of the two balances is already zero — the advance was consumed by earlier settlements, or the claim's payable was already cleared. Check both balances before retrying. **Pay Advance fails naming a missing control account.** The Employee Advance control account is not configured, or is not set up as a current asset. That is a one-time [configuration](/docs/expenses/configuration/) fix; the error message names exactly what is missing. **The advance shows partially settled and refuses to close.** An advance closes only when its outstanding amount reaches zero — through settlements, recoveries, or both. Settle the remaining claims or recover the remainder in cash. ## Common questions ### My claim is bigger than my advance — what happens? The settlement consumes the advance fully and leaves the rest of the claim's payable open. You are reimbursed the difference through the normal [reimbursement](/docs/expenses/reimbursement/) run. Claim minus advance is exactly what lands in your bank. ### My advance is bigger than my claim — what happens? The settlement clears the claim completely (it is marked paid — nothing is owed to you) and the advance keeps the difference as its outstanding balance. Either file further claims against it or return the unspent cash, which closes the advance. ### Where can finance see who owes what? The employee-payable ageing view can fold in the advance balances, showing per employee both what the company owes (unpaid claims) and what the employee owes (open advances) — aged into the standard buckets. Because it reads the same open items the postings maintain, it ties to the control account by construction; see [Expense accounting](/docs/expenses/accounting/). ## Related topics - [Submit and approve expense claims](/docs/expenses/claims/) - [Reimburse expense claims](/docs/expenses/reimbursement/) - [Expense accounting and recharge](/docs/expenses/accounting/) - [Configuring Expense Management](/docs/expenses/configuration/) ---- # Expense categories, grades and limits URL: https://xmatix.com/docs/expenses/categories-and-limits/ Last reviewed: 2026-08-16 Expense categories are the spend taxonomy — Travel, Hotel, Meals, Fuel — and the unit that policy rules, GL account determination and spend analysis all hang off. Grades band employees for policy purposes. This page is the field-level reference for both, and it is explicit about a distinction that trips people up: which settings are **defaults** a category declares, and which are **enforced** checks. ## Expense category fields | Field | What it does | | --- | --- | | Name, Code | Identify the category; the code is what imports and integrations key on | | Description | Free text shown to authors picking a category | | Default GL account | The expense account a line in this category posts to, unless overridden on the line | | GST eligible default | Whether lines in this category default to claiming input tax credit | | Receipt required | Declares that this category expects receipts — enforced through a receipt policy rule | | Approval required | Declares that this category expects sign-off — routing itself is the approval process | | Daily limit, Monthly limit | Declared spending guidance for the category | | Reimbursable | Whether spend in this category is normally paid back to the employee | | Billable default | Whether lines in this category default to billable-to-customer | | Active | Whether the category can be used on new claim lines | **Where enforcement actually lives.** The declared limits and the receipt/approval flags on the category master are documentation of intent; the checks that stop or trim a claim are [policy rules](/docs/expenses/policies/) — a category-scoped limit rule enforces a cap, a receipt rule enforces attachments. Configure the rule, not just the master field, or the limit will never fire. The one master field with direct teeth is **Active**: a deactivated category is a blocking violation on any new claim line, and posting refuses it independently. ## Grades A grade is a band on the employee record — the same record claims are anchored on. Grades exist for policy scoping: a policy header pinned to a grade applies only to claimants in that grade, which is how per-seniority caps (the classic hotel limit ladder) are modeled. Evaluation reads the claimant's grade automatically; nothing is chosen at claim time. ## Per-category rules at a glance A policy rule carries a rule type, an optional category scope, a threshold, and an action. The threshold's meaning follows the type: | Rule type | Scope | Threshold means | | --- | --- | --- | | Category limit | one category, or all when blank | maximum line amount, tax inclusive | | Grade hotel limit | the hotel category, inside a grade-pinned policy | maximum line amount for that grade | | Receipt mandatory above | one category or all | amount above which a receipt is required | | Late submission | all lines | days between expense date and claim date | | Blocked category | the forbidden category | not used | | Duplicate detection | all lines | not used | Actions and their outcomes — hard block, auto-disallow, higher approval, warn — are covered in [Expense policies](/docs/expenses/policies/). ## Building the taxonomy well - **Fewer, broader categories beat many narrow ones.** Policy rules, GL mapping and spend reports all multiply by category count; a dozen categories serve most organizations. - **Set the default GL account on every category.** Lines inherit it, which keeps account determination out of claimants' hands; a line can still carry its own GL account for the exceptions. - **Retire by deactivating, never deleting.** Deactivation blocks new use while history, reports and posted journals stay intact. - **Mirror the paper policy.** Every cap in your written expense policy should exist as a rule; a cap that lives only in a PDF is a cap nobody enforces. ## Common questions ### Why didn't the category's daily limit stop a claim? Because the limit fields on the category master are declared guidance, not an enforced check. Enforcement is a category-scoped limit rule inside an active policy. Create the rule with the cap as its threshold and the action you want — auto-disallow the excess or block outright — and it will fire from the next evaluation. ### Can the same category post to different GL accounts? Yes. The category's default GL account seeds the line, but the line's own expense account is what posts — so an exceptional line can be pointed elsewhere without a new category. If you find yourself overriding constantly, the taxonomy is too coarse; split the category. ### What happens to old claims when I deactivate a category? Nothing. Existing claims, violations and posted journals keep the category; only new claim lines are blocked from using it, and unposted claims still carrying it will refuse to post until the line is recategorized. ## Related topics - [Expense policies and violations](/docs/expenses/policies/) - [Configuring Expense Management](/docs/expenses/configuration/) - [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) ---- # Submit and approve expense claims URL: https://xmatix.com/docs/expenses/claims/ Last reviewed: 2026-08-31 An expense claim is the document that gets you reimbursed: one claim, one or more expense lines, receipts attached, routed for approval. When the final approver approves, the claim posts to the books automatically and the amount owed to you is recorded — you then watch it move to paid. This page walks both sides: raising and submitting a claim, and approving one. ## Prerequisites - Access to the Expenses app and the Expense Claim entity through your [security profile](/docs/administration/security-profiles/). - Your employee record — every claim is anchored on it, and it supplies your manager (for routing), grade (for policy caps) and bank details. If claims cannot find your employee record, ask your administrator. - An active approval process on expense claims (an administrator sets this up once — see [Configuring Expense Management](/docs/expenses/configuration/)). ## Procedure @[guided-image](_img/new-expense-claim.png) ### Step 1 — Create the claim In the Expenses app open **Expense Claims** and choose **New**. Confirm the employee resource, claim period and currency, then set the **claim date**—it determines the fiscal period used at posting. Select business unit, cost center, project or department when required for reporting. Save the header and reopen it before adding lines; verify the claimant is you, the date is in an open period, reimbursement mode is appropriate and no duplicate draft already covers the same period. ### Step 2 — Add a line per expense Add one line per receipt rather than combining unrelated purchases. Select category and amount, then enter expense date, merchant and invoice number exactly as shown; those fields drive duplicate detection. Record payment mode so company-card spend is not reimbursed personally. For GST, verify supplier tax details and mark **ITC eligible** only with compliant evidence; for rebilling, select the correct customer and approved markup. After saving each line, reconcile currency, tax, disallowed amount and reimbursable total to the receipt. ### Step 3 — Attach receipts Attach a legible bill or receipt to the corresponding line, not only to the claim header. Open the uploaded file and verify merchant, date, amount, tax and invoice number match the entered values and that confidential unrelated information is not included. If policy allows a missing receipt, add the required explanation; otherwise obtain evidence before submission. Confirm every threshold-sensitive line shows an attachment indicator. ### Step 4 — Choose how you are reimbursed Choose **Finance payment** when Accounts Payable will transfer the open balance, or **Payroll** when reimbursement must travel through a payslip. Confirm the employee's bank or payroll identity is current and use one mode consistently for the claim. Save and reopen the Reimbursement tab to verify the persisted choice; payroll-mode claims are intentionally refused by the finance reimbursement action later. ### Step 5 — Check the claim against policy Run **Evaluate Policy** after all lines and receipts are complete; if evaluation also runs at submission, use this earlier pass to correct issues. Review every rule result by line: warnings require acknowledgement, auto-disallowances must reconcile gross to reimbursable amount, higher-approval flags must alter the route, and hard blocks must be resolved. Rerun after changes and verify old violations clear or remain with the expected audit history. [Expense policies](/docs/expenses/policies/) explains each outcome. ### Step 6 — Submit for approval Before submission, compare line total, tax, disallowed amount, reimbursable amount and attachments one final time. Submit from the Approval Panel and verify the claim leaves `Draft`, one pending request appears, the correct approver resolves and the record locks where configured. Maker-checker must prevent self-approval. If anything is wrong, use **Recall** while pending, confirm the request closes, make the correction, rerun policy and submit a new traceable request. ### Step 7 — Approve or reject (the approver's side) Approvers open the request from the inbox, claim panel or [mobile](/docs/mobile/approvals-on-mobile/) and verify claimant, business purpose, allocation, every line, receipt, duplicate signal and policy outcome. Compare requested and reimbursable totals before acting. Approve only the reviewed amount, reject with an actionable reason, or reassign when authority is wrong. After each decision, verify the timeline records actor, timestamp and comment and that a multi-step route advances to the intended next approver rather than finalizing early. ### Step 8 — Track it to payment On final approval, wait for automatic posting and inspect the resulting journal instead of creating a manual booking. Verify expense and eligible input tax debits, employee-payable credit, allocations and total against the approved reimbursable amount. The record should show status `Posted`, approval `Approved` and payment `Unpaid` until settlement. If an advance exists, reconcile its settlement first; then follow the remaining open balance through [reimbursement](/docs/expenses/reimbursement/) until payment becomes `Paid`. ## Expected result The claim contains complete dated lines and receipts, policy evaluation records every warning or adjustment, and the configured approvers can follow a complete evidence trail. Final approval posts once to the expected expense, tax and employee-payable accounts, leaving the correct reimbursable open balance. ## Common problems **The claim will not submit.** A hard-block violation applies — a blocked or deactivated category, a missing mandatory receipt above the threshold, or a duplicate of a line you already claimed. Each violation on the claim names the rule; fix the flagged line and resubmit. If no violation shows, the approval process itself may not have picked the claim up — one pending request per record, and the claim must match an active process. **Part of the claim was not reimbursed.** An auto-disallow rule trimmed the excess over a cap — the disallowed amount and the rule are recorded on the line. The trim is deliberate policy, not an error; if the cap is wrong, that is a conversation with whoever owns the policy. **A line is flagged as a duplicate but is not one.** Duplicate detection matches merchant, invoice number and amount against this claim and your earlier claims. Two genuinely different purchases can collide when the invoice number is blank on both — fill in the real invoice numbers and re-evaluate. **Approved, but still unpaid.** Normal: approval posts the claim and records the payable; payment is a separate finance run. Check the payment status, not the approval status. ## Common questions ### Can I edit a claim after submitting it? Not while the approval is pending if the process locks records — which is the recommended setup. Recall the request, edit, and resubmit; or, if the approver rejects or returns it, it comes back editable. Once posted, the claim is in the ledger and corrections follow the finance reversal pattern rather than edits. ### Why is my claim tied to my employee record? Because everything downstream reads from it: your manager for approval routing, your grade for policy caps, your department for spend analysis, and your bank details for payment. One record keeps expenses, HR and payroll telling the same story. ### What does the approver actually see of policy? Every recorded violation — the rule, the line, the message and any excess amount — plus the claim-level flag that says violations exist. Approvers decide with the policy verdicts in front of them; approving a claim does not erase its warnings, which stay on the record for audit. ## Related topics - [Expense policies and violations](/docs/expenses/policies/) - [Employee advances](/docs/expenses/advances/) - [Reimburse expense claims](/docs/expenses/reimbursement/) - [Approval processes](/docs/customization/approvals/) - [Approvals on mobile](/docs/mobile/approvals-on-mobile/) ---- # Company cards and reconciliation URL: https://xmatix.com/docs/expenses/company-cards/ Last reviewed: 2026-09-02 ## Read the company-card master @[guided-image](_img/company-card-concept.png) The company-card master separates accountability from settlement. **Name** gives users a safe label, **Partner Account** establishes the operating company, and **Assigned Resource** identifies the employee responsible for receipts and coding. Issuing Bank and a masked card reference support statement matching. The liability GL account is the accounting hinge: posted transactions credit that account until a bank payment clears the issuer balance. Create one active master per physical card and avoid placing a full card number in the name or any narrative field. Confirm the cardholder is current, the issuing bank is correct and the liability account belongs to the right company before importing or entering transactions. When a card changes hands, deactivate or close the old assignment according to your control policy so historical transactions retain their original accountable employee. The screenshot uses visible synthetic demo2 data so readers can follow realistic rows, values and controls together; production exports and screenshots must still remain inside authorized channels. Company-card spend is not a reimbursement problem — the company owes the card issuer, not the employee. xMatix therefore keeps card spend on its own track: each card is a master mapped to its cardholder, each statement line is a transaction, posting a transaction books the expense against a card liability, and paying the statement clears that liability from the bank. No employee payable is ever raised, which is precisely the point. ## The three records - **Company card** — one per physical card: the masked card number, the issuing bank, the cardholder (an employee record), and optionally a dedicated card-liability GL account for this card. Cards can be deactivated when returned. - **Card transaction** — one per statement line: date, merchant, amount, the expense category and expense GL account it belongs to, and optionally a receipt and a link to the expense claim line it corresponds to. A new transaction starts as `Unmatched` — meaning nobody has yet posted or tied it to anything. - **Card reconciliation** — a record that ties a statement to its posted transactions, so a period's card activity can be signed off as complete. Transactions are created from the card statement — entered directly or brought in through the banking statement-import tooling — and coded with their category and expense account before posting. ## Posting card spend Running **Post** on a card transaction books it: the expense account is debited and the card's liability account is credited (the card's own account if one is set, otherwise the tenant's card-payable control account). The transaction is stamped `Posted` and carries its journal reference. A transaction needs an expense account and a positive amount before it will post, and it will not post twice. Because the credit goes to the card liability, the cardholder is never owed anything for card spend — contrast this with a claim, where posting credits the employee payable. A company-card purchase therefore belongs on the card transaction, not as a reimbursable line on a claim; the claim is for money the employee spent out of pocket. When a card purchase also appears in a claim's story (a hotel bill inside a trip claim, say), link the card transaction to the claim line — the link records the correspondence for reconciliation without paying anyone twice. ## Paying the statement When the card bill falls due, run **Pay Card Statement** on the card with the bank account and the amount you are paying. The payment debits the card liability and credits the bank. Do not rely on the card master's **Amount Due** field as a live roll-forward: the current posting/payment services do not update it. Reconcile the liability account and statement transactions directly. ## Reconciling a period Reconciliation is the discipline that makes card accounting trustworthy: every line on the issuer's statement should exist as a transaction, every transaction should be posted, and the liability account's balance should equal what the issuer says you owe. The reconciliation record ties a statement to its posted transactions; unposted or unmatched transactions are the gap list to work through. Receipts and claim-line links attached along the way are what make the sign-off defensible. ## Common questions ### Does card spend show up in the employee's expense balance? No. Card spend credits the card liability, so the employee-payable subledger never sees it. The cardholder's name is on the card master for accountability and reconciliation, not for payment. ### What happens if someone claims a card purchase as an out-of-pocket expense? The claim would reimburse them for money they never spent while the card side books the same cost against the issuer. Catch it during review: current duplicate detection compares expense-claim lines with other claim lines, not claim lines against company-card transactions. Reconcile statement rows, payment mode, merchant, invoice and amount explicitly. Card purchases belong on the card transaction. ### Can one card have its own liability account? Yes — set a card-specific liability account on the card master and its postings use it; cards without one share the tenant's card-payable control account. Per-card accounts make issuer-by-issuer reconciliation trivial at the cost of a longer chart of accounts. ## Related topics - [Expense accounting and recharge](/docs/expenses/accounting/) - [Configuring Expense Management](/docs/expenses/configuration/) - [Banking](/docs/finance/banking/) - [Bank reconciliation](/docs/finance/banking/bank-reconciliation/) ---- # Configuring Expense Management URL: https://xmatix.com/docs/expenses/configuration/ Last reviewed: 2026-08-16 Expense Management sits on top of the finance ledger, so its setup is mostly declaring where things post and who signs off. Work through this page in order: control accounts first (posting fails fast without them), then the masters, then policy, then the approval process, then security. A tenant that completes the five is fully operational — there is no hidden switch beyond them. ## 1. Control accounts Create these GL accounts in the [chart of accounts](/docs/finance/chart-of-accounts/) and set each one's control type. Expense posting refuses to run with a clear message naming any missing account, so gaps surface immediately rather than as bad postings. | Control type | Carries | Notes | | --- | --- | --- | | Employee Payable | what the company owes employees for posted claims | credited on claim posting, cleared by reimbursement | | Employee Advance | what employees owe back for paid advances | must be set up as a current-asset account | | Card Payable | the liability to company-card issuers | a card master may carry its own account instead | | Payroll Payable | claims handed to payroll for payment on the payslip | required only when payroll-mode claims are used | | Tax Credit (input GST) | recovered tax from ITC-eligible lines | required as soon as any line claims ITC | | Bank | reimbursement, advance and card payments | your existing bank GL accounts | The employee-side control accounts do not require a party on their journal lines — the employee is identified on the open item instead, which is what keeps the GL summarized while the subledger holds per-person detail. ## 2. Masters - **Expense categories** — the spend taxonomy, each with a default GL account so account determination never lands on claimants. Field-level reference: [Categories, grades and limits](/docs/expenses/categories-and-limits/). - **Grades** — bands on employee records, used to scope policies per seniority. - **Cost centers and projects** — the dimensions stamped on claims and lines; projects also drive billable recharge. - **Company cards** — one master per card, mapped to its cardholder; see [Company cards](/docs/expenses/company-cards/). - **Employee records** — every claimant needs one, carrying their manager (approval routing), grade (policy) and bank details. This is usually already true in a tenant running HR or payroll. ## 3. Policies Create at least one active expense policy with the rules that mirror your written policy — category caps, the receipt threshold, blocked categories, late-submission and duplicate checks — choosing each rule's action deliberately: warn, require higher approval, auto-disallow, or hard block. Pin per-grade policies to their grades. The full model is in [Expense policies](/docs/expenses/policies/). Wire evaluation to run at submission (a business rule on the claim, or the claim's **Evaluate Policy** action as a step in your process) so disallowances land before approval and posting. ## 4. The approval process There is no shipped default route — build one on the Expense Claim entity following [Approval processes](/docs/customization/approvals/). The pattern that fits most organizations: 1. Step 1: the claimant's **manager**, resolved from the manager field on the employee record. 2. Step 2: a **finance** role for the money check — optionally entered only above a threshold, with a skip below it. 3. Keep **maker-checker** on so nobody approves their own claim, and enable **lock on submission**. 4. If policy uses require-higher-approval, add the extra step it escalates into. The expense module listens to the process's decisions on its own: outcomes are mirrored onto the claim, and the final approval posts it — you do not configure posting into the process. Advances can carry their own simpler process on the Expense Advance entity, with field updates stamping the approval outcome. ## 5. Security Grant through [security profiles](/docs/administration/security-profiles/): employees need the Expenses app with create on claims and advances (record security scoping them to their own); managers additionally act through the approvals surfaces; finance needs the reimbursement batch, card and category/policy entities; policy and category administration is its own grant. When someone reports a missing screen or button, walk [the access checklist](/docs/administration/user-cant-see-x/) before changing configuration. ## Common questions ### What breaks first if a control account is missing? The first posting that needs it — claim posting for Employee Payable, advance payment for Employee Advance, an ITC line for Tax Credit — fails with a message naming the account type. Because claim posting runs after final approval, the approval stands and the claim shows approved-but-not-posted; create the account and post the claim manually. ### Do policy changes need anything re-activated? No. A policy applies whenever it is active and the claim date falls in its effective window; rule changes take effect from the next evaluation. Use the effective dates to stage a policy change ahead of time rather than editing on the morning it starts. ### Can different companies in one tenant have different setups? Yes — control accounts, categories, policies and cards are all per company, so each company posts to its own chart and enforces its own rules. Configure each company you run expenses in. ## Related topics - [Expense categories, grades and limits](/docs/expenses/categories-and-limits/) - [Expense policies and violations](/docs/expenses/policies/) - [Approval processes](/docs/customization/approvals/) - [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) - [Security profiles](/docs/administration/security-profiles/) ---- # xMatix Expense Management URL: https://xmatix.com/docs/expenses/ Last reviewed: 2026-09-02 xMatix Expense Management covers the whole life of employee spend: an employee raises a claim with receipts, policy rules check it, approvers sign off, and on the final approval the claim posts itself to the general ledger — finance then pays it, singly or in a batch, or hands it to payroll. Advances, company cards and client-rechargeable expenses ride the same machinery, and every balance ties back to the [finance ledger](/docs/finance/) because every step is a posted journal. ## The mental model Four ideas explain most of what you will see in the Expenses app: - **You are your employee record.** Every claim and advance is anchored on the claimant's employee record — the same record that holds their manager, department, grade and bank details. That is why approval routing, grade-based policy caps and payroll handoff need no extra setup per claim. - **Approve once — the books post themselves.** When the final approver approves a claim, the platform posts it: the expense heads are debited, recoverable tax is split out, and an employee-payable balance is raised. Nobody re-keys an approved claim into finance. - **Three status tracks, not one.** A claim carries a business **status** (`Draft` → `Submitted` → `Posted` → `Paid`/`Settled`), an **approval status** (`Pending` / `Approved` / `Rejected`) and a **payment status** (`Unpaid` / `Partial` / `Paid`). "Approved but unpaid" is a normal state, not a fault — payment is a separate finance step. - **Policy has teeth, in degrees.** Policy rules can warn, demand a higher approver, automatically trim the excess over a cap, or block submission outright. Violations stay visible on the claim so approvers see exactly what was flagged. ## Who does what | Role | What you do here | | --- | --- | | Employee | Raise claims and advance requests, attach receipts, submit for approval, track reimbursement | | Manager | Review and approve or reject claims routed to you, with the policy violations in view | | Finance | Pay reimbursements singly or in batches, pay and settle advances, post card spend, reconcile | | Administrator | Configure control accounts, categories, policies, the approval process and security | ## What is in this section - [Submit and approve expense claims](/docs/expenses/claims/) — the full claim flow, from draft through policy check, approval and posting to payment, for both the claimant and the approver. - [Employee advances](/docs/expenses/advances/) — request money up front, pay it out, settle it against claims and recover the unspent balance. - [Expense policies and violations](/docs/expenses/policies/) — what gets checked and what each outcome does, from a recorded warning to a hard block. - [Expense categories, grades and limits](/docs/expenses/categories-and-limits/) — the spend taxonomy, category defaults, and how grade-scoped caps are built. - [Company cards and reconciliation](/docs/expenses/company-cards/) — card masters, statement transactions, posting card spend and paying the statement. - [Reimburse expense claims](/docs/expenses/reimbursement/) — single payments, batch payments that settle many claims in one posting, and the payroll handoff. - [Expense accounting and recharge](/docs/expenses/accounting/) — the journals behind every expense event, employee balances as open items, and rebilling clients. - [Configuring Expense Management](/docs/expenses/configuration/) — control accounts, masters, policies, the approval process and security, in the order that works. - [Troubleshooting Expense Management](/docs/expenses/troubleshooting/) — blocked submissions, approved-but-unposted claims, posting errors decoded, and balances that do not tie. ## Common questions ### My claim was approved — why haven't I been paid? Approval books the expense and records what the company owes you; paying is a separate finance step. Watch the claim's payment status: it flips to `Paid` when finance runs your reimbursement — on its own or inside a [reimbursement batch](/docs/expenses/reimbursement/) — or when a payroll-mode claim is handed to payroll. ### Do I need the Finance app to use expenses? No. Employees and managers work entirely in the Expenses app — claims, advances, approvals. The finance team touches the ledger side (posting is automatic; reimbursement, advances and cards are finance actions), and the results surface in the [financial statements](/docs/finance/statements/) like every other posting. ### Where do the amounts actually go? Into the same double-entry ledger as every other document. A posted claim debits the expense accounts and credits an employee-payable account; reimbursement clears that payable against the bank. [Expense accounting](/docs/expenses/accounting/) maps every event to its journal. ## Related topics - [xMatix Expenses product overview](/products/expenses/) - [xMatix Finance & Accounting](/docs/finance/) — the ledger everything posts into. - [Approval processes](/docs/customization/approvals/) — the engine expense claims route through. - [Book a demo](/demo/) ---- # Expense policies and violations URL: https://xmatix.com/docs/expenses/policies/ Last reviewed: 2026-09-02 ## Read the policy header @[guided-image](_img/expense-policy-concept.png) The policy header answers three questions before any rule evaluates: what the rule set is called, which exact partner account and employee grade it scopes, and when it is effective. **Partner Account** is an exact match when present; a null partner is not a tenant-wide wildcard in the current evaluator. Grade narrows applicability to an employee band, the effective dates bound the window, and **Is Active** is the final participation switch. Design policy changes as versioned time windows rather than silently rewriting a rule that already influenced approved claims. Check for overlaps between global and grade-specific policies, verify that employee grade data is populated, and test boundary dates and each enforcement action with a representative draft claim. Deactivate a retired header only after its replacement is effective. That preserves the old policy and its violations as intelligible audit evidence while directing new claims to the current controls. An expense policy is a named set of rules that can be evaluated against a claim. Each breach is recorded as a **violation**, and the evaluator returns `isBlocked` and `requiresHigherApproval` signals while applying any disallowed excess. Those signals affect submission or routing only when a business rule, action or approval entry consumes them; the policy service is not a universal gate by itself. ## Which policies apply to a claim A policy header carries an **active** flag, **Partner Account**, an optional **grade**, and an optional **effective window**. The current evaluator requires an exact partner-account match, including null-to-null; leaving Partner Account blank does not make a policy tenant-wide for claims that carry a partner. A blank grade applies across grades within that exact partner scope, while a populated grade must match the claimant's employee record. The claim date must fall inside the effective window. ## What gets checked Each rule names a **rule type**, an optional **category scope** (blank means every category), a **threshold** where the type needs one, and the **action** to take on breach. Line amounts are checked inclusive of tax. | Check | Fires when | Typical action | | --- | --- | --- | | Category limit | a line in the scoped category exceeds the threshold amount | Auto-disallow the excess | | Grade hotel limit | a hotel line exceeds the cap set for the grade's policy | Auto-disallow or higher approval | | Receipt mandatory above | a line over the threshold has no receipt attached | Hard block or warn | | Blocked category | a line uses a category the policy forbids outright | Hard block | | Late submission | a line's expense date is more than N days before the claim date | Warn or higher approval | | Duplicate detection | same merchant, invoice number and amount appear on another line of this claim or on a prior claim by the same employee | Warn or hard block | One check runs regardless of any policy: a **deactivated category** on a claim line is always a blocking violation, and posting refuses it too. Deactivating a category is how you retire it without touching history. Duplicate detection skips lines with neither a merchant nor an invoice number — there is nothing reliable to match on — which is why claimants should fill both in. ## What each action does | Action | Effect | Hard or soft | | --- | --- | --- | | Hard block | The evaluator returns `isBlocked`; the calling submission or approval flow must honor it | Hard only when wired | | Auto-disallow | The excess is added to the line's disallowed amount; re-running evaluation can add it again | Mutating | | Require higher approval | The evaluator returns `requiresHigherApproval`; routing must consume the signal | Extra sign-off only when wired | | Warn | The violation is recorded, nothing else changes | Soft | Every evaluation also sets a claim-level flag saying violations exist, so approvers and reports can filter for flagged claims without opening each one. Disallowed amounts and warnings stay on the claim permanently — approval does not erase them. ## When evaluation runs Evaluation runs on demand through **Evaluate Policy**, and organizations can wire it into submission or approval. The current implementation is not idempotent: it appends violation rows, does not clear earlier results, and increments disallowed amounts again on a repeat run. Do not re-evaluate the same unchanged claim casually. Test the single intended invocation path, and if a claim needs reevaluation, review and correct its prior violations and disallowed amounts under a controlled procedure first. ## Common questions ### What is the practical difference between a hard block and everything else? A hard-block rule makes the evaluator return a blocked result; it stops the claim only if the submission or approval entry is wired to honor that result. Auto-disallow mutates the line, higher-approval returns a routing signal, and warn records a violation. Validate the consuming flow for every action in a test claim. ### Who decides the caps for different seniority levels? The policy author, by creating one policy per grade. The grade lives on the employee record, the policy header pins to a grade, and evaluation matches the claimant's grade to the right policy — the claimant never chooses which limits apply to them. ### Does a warning stop reimbursement? A warning records a violation. A hard block stops the claim only when the caller consumes `isBlocked`, and higher approval changes routing only when the approval flow consumes `requiresHigherApproval`; auto-disallow directly changes the disallowed amount. ### Can a rule apply to just one category? Yes — scope the rule to a category and it checks only lines in that category; leave the scope blank and it checks every line. A per-diem cap on Meals and a receipt threshold across the board coexist in the same policy. ## Related topics - [Expense categories, grades and limits](/docs/expenses/categories-and-limits/) - [Submit and approve expense claims](/docs/expenses/claims/) - [Configuring Expense Management](/docs/expenses/configuration/) - [Business rules](/docs/customization/business-rules/) ---- # Reimburse expense claims URL: https://xmatix.com/docs/expenses/reimbursement/ Last reviewed: 2026-09-02 A posted claim is a liability: the amount sits in employee payable until finance pays it. Reimbursement clears that liability one claim at a time, through a batch, or through the payroll handoff. A successful finance reimbursement moves the claim's business status from `Posted` to `Settled` and its payment status to `Paid`; keep those two fields distinct during reconciliation. ## Prerequisites - Posted claims — final approval posts a claim automatically; a claim that is not posted cannot be reimbursed. - The bank GL account the payments go out of. - Finance access to Expense Claims and Reimbursement Batches through your [security profile](/docs/administration/security-profiles/). ## Procedure @[guided-image](_img/new-reimbursement-batch.png) ### Step 1 — Find what is payable Filter Expense Claims to **Posted** and **Unpaid**, then reconcile that set with employee-payable ageing. For each candidate, confirm employee, currency, approval, posting journal, open balance, advance settlements and reimbursement mode. Separate finance-payment claims from payroll-mode claims before building a run; do not copy the gross claim amount when the open item has already been reduced. Record the selected count and total as the control figure for later verification. ### Step 2 — Pay a single claim Open the finance-mode claim, choose **Reimburse**, and verify the bank account, employee beneficiary, currency and displayed open balance; a claim-specific payment account takes precedence when present. Submit once and open the journal: employee payable is debited and bank credited for the full remaining balance after [advance settlements](/docs/expenses/advances/). Confirm the open item is closed, status is `Paid`, and a second reimbursement is refused. ### Step 3 — Pay many claims as a batch Create a **Reimbursement Batch**, enter payment date and bank account, then add one line per reviewed claim. Compare its line count and calculated total with the Step 1 control before selecting **Pay Batch**. The action settles each eligible employee payable at its actual open balance. Unposted or already-settled claims are silently skipped: their batch lines remain `Pending`, and the handler does not store a per-line skip reason. Reconcile every Pending line back to its source claim instead of treating batch completion as proof that all lines were processed. ### Step 4 — Hand payroll-mode claims to payroll For a payroll-mode claim, confirm the payroll period and employee mapping, then choose **Settle via Payroll** and link the payroll run where available. This does not pay cash: it moves the liability from employee payable to payroll payable and marks the expense-side claim `Paid`. Open the transfer journal, verify amount and accounts, and confirm the payroll run contains the reimbursement for that employee. Reconcile final cash delivery on the payslip; see [xMatix Payroll](/products/payroll/) for that side. ### Step 5 — Verify the run After each run, verify every processed claim shows payment `Paid` and business status `Settled`. Investigate every batch line still `Pending` against the source claim because no skip reason is stored. Rerun employee-payable ageing: processed items must disappear and the remaining total must equal the employee-payable control account. Reconcile batch totals to journals and payment evidence, and payroll settlements to payroll payable. ## Expected result Every processed finance-mode claim is paid for its actual open balance, payroll-mode claims move to payroll payable instead, and settled claims disappear from employee-payable ageing. Any Pending batch line is resolved from its source claim before the batch is signed off. ## Common problems **"Expense claim must be posted before it can be reimbursed."** The claim's approval finished but posting did not happen — usually a missing control account at posting time. Fix the cause and run **Post** on the claim, then reimburse. See [Troubleshooting](/docs/expenses/troubleshooting/). **"Claim is set to reimburse via payroll."** A finance reimbursement is not applicable to a payroll-mode claim by design — use **Settle via Payroll**, or change the claim's reimbursement mode first if it was set wrongly. **"Batch has no payable claims to reimburse."** Every line in the batch was skipped: the claims are unposted, already paid, or fully covered by advances. Rebuild the batch from the posted-and-unpaid filter. **A claim was paid for less than the employee expected.** The payment is the open balance — the claimed total minus policy disallowances and advance settlements. Both deductions are recorded on the claim; nothing was lost in the payment run. ## Common questions ### Can I partially pay a claim? A finance reimbursement pays the claim's full open balance in one go — partial states arise from advance settlements reducing the balance before you pay, not from partial payment runs. If you need to stagger payouts, stagger the claims. ### Can one batch mix branches and employees freely? Yes. The batch settles each claim's own payable and merges the accounting per control account and branch, so a company-wide payment run is one batch and one bank payment regardless of how the claims are spread. ### What tells the employee they have been paid? The claim itself: its payment status flips to `Paid` and the claim shows as settled. Employees track their own claims in the Expenses app — no separate notification step is required for the state to be visible. ## Related topics - [Submit and approve expense claims](/docs/expenses/claims/) - [Employee advances](/docs/expenses/advances/) - [Expense accounting and recharge](/docs/expenses/accounting/) - [Recording and applying payments](/docs/finance/payments/) ---- # Troubleshooting Expense Management URL: https://xmatix.com/docs/expenses/troubleshooting/ Last reviewed: 2026-09-02 Expense problems sort into four families: a claim that will not go forward, a claim that approved but never posted, a posting or payment action that refuses with an error, and balances that do not tie. Find your symptom below — each entry names the cause and the fix, and the posting errors are decoded verbatim. ## A claim will not submit Check in this order: 1. **A hard-block result consumed by the submission flow.** Policy evaluation records violations and returns a blocked flag, but it stops submission only where your business rule or approval entry actually consumes that result. Fix the flagged line—or the [policy](/docs/expenses/policies/)—and verify the integration rather than assuming the policy service alone gates the status change. 2. **The approval process did not pick it up.** A record can hold only one pending request, the claim must match an active process's entry condition, and a process with zero steps is never selected. The generic checks are in [Approval processes](/docs/customization/approvals/). 3. **The approver resolves to nobody.** A manager step reads the manager field on the claimant's employee record — if that field is empty, there is no one to route to. Fill in the manager. ## Approved, but never posted The approval decision and the ledger posting are decoupled on purpose: a posting failure never rolls back the sign-off, it is logged instead. A claim showing approval `Approved` with posting `NotPosted` means the automatic post failed. Find the cause in the table below (the logs carry the same message), fix it, and run **Post** on the claim — posting is idempotent, so a claim that already posted is skipped, never doubled. ## Posting errors, decoded | Message | Cause | Fix | | --- | --- | --- | | "must be anchored on a Resource" | the claim or advance has no claimant employee record set | set the claimant and retry | | "No Employee Payable control account … is configured" | the control account is missing for this company | create it in the [chart of accounts](/docs/finance/chart-of-accounts/) with the Employee Payable control type | | "No Employee Advance control account …" | same, for advances — the account must also be a current asset | create or recategorize the account as a current asset | | "An ITC-eligible line needs a TaxCredit (Input GST) control account" | a line claims input credit but no input-GST account exists | configure the Tax Credit control account | | "Expense claim has no postable expense lines" | every line is missing an expense GL account or nets to zero | give each real line its expense account and amount | | "Cannot post: expense category … is deactivated" | a line still uses a retired category | recategorize the line | | "Net reimbursable amount must be greater than zero" | an advance adjustment already covers the whole claim | settle the claim [via the advance](/docs/expenses/advances/) instead of posting for reimbursement | ## Reimbursement refused - **"Expense claim must be posted before it can be reimbursed."** Post first — see the approved-but-never-posted section above. - **"Expense claim is already fully reimbursed."** The payable is settled; nothing is owed. If the employee disputes it, read the claim's journals — an earlier batch or an advance settlement cleared it. - **"Claim is set to reimburse via payroll; finance reimbursement is not applicable."** Use **Settle via Payroll**, or correct the claim's reimbursement mode if it was set wrongly. - **"Batch has no payable claims to reimburse."** Every batch line was skipped as unposted or already settled. The current batch handler leaves skipped lines Pending and stores no per-line skip reason, so reconcile the source claims directly and rebuild from Posted, unpaid claims. ## The employee was paid the "wrong" amount Almost always the right amount: the payment is the claim's open balance — the claimed total minus policy **auto-disallowances** (recorded per line with the rule that trimmed them) and minus **advance settlements** (recorded on the claim). Both deductions are visible on the record; walk them before suspecting the payment run. ## Balances do not tie If the employee-payable ageing disagrees with the control account's GL balance, something posted to the control account outside the subledger — typically a manual journal, or a reversal made in the GL without touching the open item. Run the employee-payable and employee-advance control-account reconciliations to locate the difference, and correct on the side that is wrong (reverse the stray journal, or fix the open item's document). The [period-close](/docs/finance/period-close/) checklist runs both checks as advisories, so an untied employee subledger is flagged before the period closes. Keep manual journals off control accounts as a standing rule. ## Common questions ### Who can unstick a claim locked in a pending approval? The current step's approver (or their delegate or a reassignee) by deciding, the submitter by recalling it, or an approval administrator — who may act on any pending step. If the resolved approver has left, reassign the step or have an administrator decide. ### A duplicate flag is wrong — how do I clear the claim? Duplicate detection matches merchant, invoice number and amount against the claimant's other lines and prior claims. Blank invoice numbers on two different purchases are the usual false positive: fill in the real invoice numbers and re-evaluate. If the rule's action is warn, the claim can proceed regardless — the flag is information for the approver. ### Posting failed days ago — did anything get lost? No. The approval is intact, the claim is untouched, and no partial journal exists — the posting either completes whole or not at all. Fix the named cause and post; the claim picks up from exactly where it stopped. ## Related topics - [Expense accounting and recharge](/docs/expenses/accounting/) - [Reimburse expense claims](/docs/expenses/reimbursement/) - [Configuring Expense Management](/docs/expenses/configuration/) - [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/) ---- # xMatix frequently asked questions URL: https://xmatix.com/docs/faq/ Last reviewed: 2026-09-01 The questions evaluators and new customers actually ask, answered first and linked deeper. Each answer holds on its own; the link is there when you want the full page. ## Common questions ### What is xMatix? A business platform your organization uses to run its day-to-day operations — sales, field work, inventory, service, finance and more — from one place, on the web and on mobile. Your organization configures which apps its people see, and every user works with one account across both surfaces. Orientation for new users starts at [Getting started with xMatix](/docs/getting-started/). ### How do I get the mobile app? From your organization — your administrator sends the installation instructions for your device, because the installation route is set up per organization. Don't go searching for it yourself; if you have no instructions, mobile access likely hasn't been rolled out to you yet, and your administrator can confirm and arrange it. Setup, first sync and sync status are covered in [Using xMatix on mobile](/docs/getting-started/mobile-app/). ### Does it work offline? Yes — the mobile app is built offline-first. Screens read from a local copy of the data your role works with, edits made without a network wait in a durable outbox and sync automatically when connectivity returns, and the sync status screen shows exactly what has and hasn't reached the server. There is no separate offline mode to switch into. The design is explained in [How offline-first mobile works](/docs/concepts/offline-mobile/). ### How is our data isolated from other customers? Every organization gets its own tenant — an isolated environment holding its users, records, configuration and customizations — and the platform enforces that isolation on every read and write, not through configuration anyone could get wrong. No user of another tenant can see your data, and no report, search or integration crosses tenant boundaries. See [Tenants, companies and organizations](/docs/concepts/tenants-and-companies/). ### What can the AI do — and what can't it? Sense, the AI layer, answers questions about your data, surfaces deterministic nudges with plain-language explanations, reads shelf photos, and helps administrators configure the platform. Two hard limits govern all of it: Sense works strictly within the asking user's own permissions — there is no elevated identity behind it — and nothing it proposes changes data without a human confirming. Start at [xMatix Sense](/docs/sense-ai/); the governance story is [How Sense AI is governed](/docs/concepts/sense-governance/). ### How do I import existing data? Through the import wizard: upload an Excel, CSV or JSON file, map its columns to an entity's fields, and run the import in the browser or as a background job, with a per-row result for every line and a retryable history per run. Each run loads one entity, so related data is imported parents-first. The full procedure is [Import data with the import wizard](/docs/administration/data-management/import-data/). ### Can we customize it without writing code? Mostly, yes. Custom entities and fields, form layouts, business rules, approval processes and workflows are all configured in Setup — declarative, previewable, and safe across product updates. Server-side automation scripts are the deliberate exception at the top of the ladder, for logic nothing declarative can express. The rule that keeps a system maintainable — pick the lowest rung that solves the problem — is explained in [the customization ladder](/docs/concepts/customization-ladder/), and the tools are documented in [Customizing xMatix](/docs/customization/). ### What integrations exist? One integration surface with two levels: the Integration Hub (apps, connections, flows) and declarative sync profiles on top that keep entities in step with an external system, with change detection, conflict handling and a per-record ledger. Connectors include a generic HTTP/REST connector, SFTP and message queues, plus named connectors for systems such as [Tally](/docs/integrations/connectors/tally/) and [the Zoho family](/docs/integrations/connectors/zoho/), and a catalog of reviewed manifest connectors for standard REST partners. The current catalog and the model behind it are in [Integrating xMatix with other systems](/docs/integrations/). ### How is xMatix licensed? In three layers: tenant licenses (products, individually licensed features, and packages, enabled per organization with optional seat counts and expiry), per-user seats on those licenses, and module switches. Licensing always composes with security profiles — a user needs both an entitlement and a security grant before anything becomes usable. The full reference is [Licensing: products, features and seats](/docs/administration/licensing/). ### Can user access be scoped to specific companies? Yes, where an organization transacts through multiple legal entities and enables multi-company mode: a user's access can then be limited per company, with viewing and transacting granted separately, while administrators and group-reporting roles can span all companies. Single-company organizations never need this — the mode is off by default and everything works without it. See [Tenants, companies and organizations](/docs/concepts/tenants-and-companies/). ### Where do I get help when something misbehaves? Start with the [troubleshooting hub](/docs/troubleshooting/), which routes every module's troubleshooting page and covers the universal first checks — access, sync, background work. For questions about your organization's specific setup, your administrator is the right contact, and Sense AI chat can answer data questions where your organization has licensed it. The full map of help sources is [Where to get help](/docs/getting-started/help/). ### Where are the release notes? In the [release notes section](/docs/release-notes/) of this Knowledge Center. Monthly release summaries begin with the September 2026 issue; until then, the "Last reviewed" date on each documentation page shows how current it is. ## Related topics - [Getting started with xMatix](/docs/getting-started/) - [Troubleshooting xMatix](/docs/troubleshooting/) - [xMatix release notes](/docs/release-notes/) ---- # Mobile attendance URL: https://xmatix.com/docs/field-sales/attendance/ Last reviewed: 2026-09-01 ## Read the attendance record @[guided-image](_img/attendance-context.png) Mobile punches are consolidated into a dated Resource Availability record. Document Number provides the audit reference, Resource identifies the employee, and Date is the branch-local working day. Check-In and Check-Out hold the day's time boundaries, while their corresponding branch fields preserve where each punch was associated. Availability Type distinguishes attendance-derived time from leave, holiday or another scheduling exception. When reviewing a disputed day, first verify the resource's timezone and branch, then compare the device punch timestamps, offline synchronization time, selfie or location evidence where policy permits, and the resulting first-in/last-out values. An auto-checkout should remain visibly synthetic rather than being mistaken for a manual punch. The screenshot uses visible synthetic demo2 data so readers can follow realistic rows, values and controls together; production exports and screenshots must still remain inside authorized channels. Attendance in xMatix is a mobile check-in/check-out: the executive punches in at the start of the field day — optionally with a selfie and a captured location — and punches out at its end. An administrator decides who is gated and how strictly: for gated users the app can refuse to open at all until the day's check-in is done, or gate only specific screens. Punches build a per-day attendance record, and a background sweep closes the days people forget to close. ## The gate Whether check-in is required comes from the mobile app profile assigned to the user, in one of two modes: **app mode** shows a "Check in to start your day" screen instead of the app itself, and **entity mode** gates only the configured record screens. The check-in window captures the location and, where required, a selfie; a successful — or offline-queued — punch unlocks the app immediately. What counts as a valid check-in is evaluated on the server, per the gates the administrator has enabled: | Gate | What it checks | |---|---| | Location | Distance between the punch location and the executive's branch | | Working day / hours | The executive's business-hours calendar — working days and day start/end | | Holidays | The applicable holiday calendar | | Leaves | Approved leave on the day | ## Punches and the day record Each check-in and check-out is a punch, stamped on the branch-local calendar day — a late-evening check-in lands on the local day it belongs to, not the UTC one, which is what payroll and day reports key on. Punches roll up into a per-day attendance record with first-in and last-out times, and multiple in/out pairs within a day are supported. ## Working offline Check-in does not depend on coverage: an offline punch is queued on the device, unlocks the app at once, and replays to the server when connectivity returns — the selfie upload follows once the punch exists server-side. One honest limit: a queued punch older than three days is rejected on replay, so attendance cannot be back-filled from a device that stayed offline for a week. ## Automatic checkout Forgetting to check out is routine, so an administrator can enable auto-checkout. Once a local day has ended — resolved in the executive's own timezone — any check-in still open from that day is closed with a synthetic checkout punch at 23:59:59, clearly labelled "Auto checkout", and the day record's last-out time is refreshed. The sweep looks back a bounded window (two weeks), so ancient stragglers age out rather than being rewritten. ## Common questions ### What happens if I forget to check out? If your organization has auto-checkout enabled, the day is closed for you at end of day with a punch labelled "Auto checkout" — visibly synthetic, so a supervisor can tell a real 23:59 checkout from a forgotten one. If it is not enabled, the check-in simply stays open until you punch out. ### Can I check in from anywhere? That depends on which gates your administrator enabled. With the location gate on, the punch must be within the configured distance of your branch; other gates can require a working day, non-holiday, and no approved leave. The app tells you which gate refused a punch. ### Is attendance check-in the same as checking in at an outlet? No — they are separate. Attendance is one day-level punch pair governing your working day; visit check-in/check-out happens per outlet inside the visit flow and drives visit reporting. See [Complete a visit](/docs/field-sales/visits/complete-a-visit/). ## Related topics - [Complete a visit](/docs/field-sales/visits/complete-a-visit/) - [Visits and the field day](/docs/field-sales/visits/) - [How offline-first mobile works](/docs/concepts/offline-mobile/) - [xMatix administration guide](/docs/administration/) ---- # Checklists, tasks and visit activities URL: https://xmatix.com/docs/field-sales/checklists-and-tasks/ Last reviewed: 2026-09-02 ## Read the task-template header @[guided-image](_img/visit-task-template-concept.png) The Visit Task Template header defines a reusable bundle before its entries and activities are added. **Name** is the planner-facing identity, **Duration** is descriptive planning metadata, and **Description** explains the outcome users are expected to produce. The current route and territory optimizers do not consume the Duration field, so do not present it as an enforced service-time input. The saved template can be referenced by routes, route groups, plans or individual stops, which determines how widely its work is expanded. Use a stable name and a realistic duration measured from completed visits rather than an aspirational target. Build entries in the order a representative should execute them, mark only genuinely required activities mandatory, and verify every checklist, capture type and related-activity dependency before attaching the template to a live beat. Changes affect newly materialized work according to the generating flow; retain clear version or effective-date discipline when altering a template whose earlier form already appears on historical visits. The work expected at each outlet is defined once, in templates, and expanded onto every visit when a plan is created. A **visit task template** attached to a beat or plan defines tasks and activities; a **checklist template** defines reusable line-by-line checks; and each activity resolves to a governed type. Mobile can use an activity's configured `recordLayout`; the web surface currently falls back to its generic renderer, so test both clients rather than assuming byte-for-byte behavior. ## From template to visit | Object | Role | |---|---| | Visit task template | The set of tasks (and their activities) expected at a stop; attached to the route or plan and expanded onto each visit at plan creation | | Visit task | One unit of work on one visit; can be mandatory, and can be flagged as requiring a device location to start | | Visit activity | The typed capture inside a task — its activity type decides which form opens | | Checklist template | A reusable named checklist; scopable to a customer, a customer group, or an item, with a frequency and a mandatory flag | Mandatory activities are marked in the mobile activity panel and gate the visit's close: a **Productive** outcome requires all of them done, while Non-productive and Cancelled remain available as reasoned escape hatches. ## The activity catalog Activity types are governed: the template stores the type value, and both clients resolve the same capture definition from it. The general and field-sales types are: | Activity type | What it captures | |---|---| | Take Order | Full-screen catalog ordering with customer pricing; creates the order against the visit | | Previsit | A checklist run from a checklist template | | Digital Signature | A signature drawn on the device, attached to the activity | | Customer KYC | Identity capture, including an OTP confirmation from the customer | | General Task | A free start/complete task with notes | | Survey | A configured questionnaire | | Stock Check | Per-product counted stock at the outlet, with remarks and proof photos | | Payment Collection | Amount, payment method with method-specific details, optional invoice allocation, proof photos | | Return Pickup | Items returned with reasons (damaged, expired, wrong item, unsold…), against an invoice, with evidence photos | | Merchandising Audit | Facings counted per product, planogram compliance rating, share of shelf, display observations, photos | | Asset Verification | Condition check of company assets at the outlet, with photos | | Competitor Capture | Competitor product, pricing, promotion and shelf-share observations, with photos | | New Outlet Registration | A structured new-customer capture with address blocks and a storefront photo | | Lead Capture | Opens the tenant's own lead create form | | Product Demo | Demo execution with rating and customer feedback | | Generate Invoice | Invoice creation from the visit | Field-service deployments add their own set (parts consumption, meter readings, proof of delivery and more) from the same catalog. ## Photos and signatures Photo capture is part of the composed activities rather than a separate step: each type declares how many photos it expects (minimum and maximum), and the images attach to the activity as files. Signatures use a drawn signature pad and attach the same way. Both work offline — files queue with the activity and upload on sync. ## Custom types Tenants can add their own activity-type values. A type the catalog does not recognize falls back to a safe generic start/complete task — nothing breaks — and two extension renderers go further: one opens any entity's own create form as the activity, the other hosts a designer-built layout over a record the visit resolves, so a tenant can put custom capture on a visit without code. ## Related topics - [Complete a visit](/docs/field-sales/visits/complete-a-visit/) - [Visits and the field day](/docs/field-sales/visits/) - [Planograms and shelf audits](/docs/field-sales/planograms/) ---- # xMatix Field Sales URL: https://xmatix.com/docs/field-sales/ Last reviewed: 2026-09-02 ## Read the visit record @[guided-image](_img/field-sales-overview.png) The Visit is the execution record that connects route planning to an actual outlet interaction. Partner Account identifies the customer organization, Branch selects the exact outlet, and Account preserves the commercial context used by orders and follow-up work. Timeline carries the planned date and start/end window, Visit Address establishes place, and Related Sources ties the visit back to its visit plan, beat or originating activity. Planners should verify outlet, branch, address, local working window and source plan before releasing the day. Field users should synchronize assignments while online, open the intended visit, then attach check-in/out, tasks, checklists, photos, signatures, orders and notes to that record even when captures temporarily queue offline. At day end, compare actual completion and commercial outcomes with the planned timeline and source. This is an unsaved New Visit header, so no customer has been selected and **Save** is not pressed; the blanks are form state, not redaction. xMatix Field Sales runs the whole route-to-market loop: territories are split into beats, beats generate visit plans, sales executives execute those plans on the mobile app — checking in at each outlet, working through tasks and checklists, taking orders — and the day settles back into the office as orders, collections and van-run reconciliations. The mobile app is offline-first, so a field day with patchy coverage still completes normally. ## How the pieces fit Planning flows downhill. A **territory** is split across executives into **beats** (visit routes) — each beat a named list of outlet stops with a weekly rhythm. Beats generate **visit plans** — one plan per executive per working day. A plan contains **visits**, one per outlet, and each visit carries the **tasks and activities** the executive must complete there: checklists, photos, signatures, an order. Van-sales days add a stock dimension: a load is released onto the van in the morning and reconciled — stock and cash — in the evening. ## What is in this section | Page | What it covers | |---|---| | [Visits and the field day](/docs/field-sales/visits/) | The plan → visit → activity → order model, and how a day runs on mobile | | [Complete a visit](/docs/field-sales/visits/complete-a-visit/) | Step by step: check in, work the tasks, take the order, check out | | [Visit plans](/docs/field-sales/visit-plans/) | The day container: automatic generation from route schedules, and stale-plan cleanup | | [Beats and routes](/docs/field-sales/routes/) | What a beat is: stops, schedules and stored stop orders | | [Route stops](/docs/field-sales/routes/route-stops/) | Add, time, approve and transfer the outlet stops on a beat | | [Optimize a route](/docs/field-sales/routes/optimize-a-route/) | Road-network sequencing of a beat, and the three sequence kinds | | [Territory planning](/docs/field-sales/territory-planning/) | Splitting outlets across executives with balance, shift and capacity constraints | | [Van sales](/docs/field-sales/van-sales/) | Load the van, sell on route, settle cash and reconcile stock | | [Prospecting](/docs/field-sales/prospecting/) | Finding nearby outlets and onboarding a prospect on the spot | | [Attendance](/docs/field-sales/attendance/) | Mobile check-in before the day starts, and automatic checkout | | [Checklists and tasks](/docs/field-sales/checklists-and-tasks/) | Task templates, checklist templates, and the activity catalog reference | | [Planograms and shelf audits](/docs/field-sales/planograms/) | Planogram records, shelf products and audit results on a visit | | [Selling scope](/docs/field-sales/selling-scope/) | Partner account mappings: which items an executive may sell in Take Order, and how to set them up | ## Where the work happens Executives live on the [xMatix mobile app](/products/mobile/): the visit-plans hub, the day's agenda, visit execution and van runs are all mobile screens, built to work offline — see [how offline-first mobile works](/docs/concepts/offline-mobile/). Planners and dispatchers work on the web: authoring beats and templates, running territory and route optimization, releasing van loads and reconciling them at day end. Administrators switch on the automated parts — plan generation, attendance gates, capacity checks — in settings. ## Related topics - [xMatix Field Sales product overview](/products/field-sales/) - [xMatix mobile](/products/mobile/) - [How offline-first mobile works](/docs/concepts/offline-mobile/) - [xMatix Knowledge Center](/docs/) ---- # Planograms and shelf audits URL: https://xmatix.com/docs/field-sales/planograms/ Last reviewed: 2026-09-02 ## Read the planogram record @[guided-image](_img/planogram-concept.png) The planogram header determines which expected shelf can be selected for an audit. Label makes the arrangement recognizable, Account and Account Type establish the outlet scope, and Effective From/To bound the period in which the definition is eligible. Description carries human instructions, while Layout JSON is the structured shelf, position, product and facing model used by analysis and downstream presentation. Avoid overlapping planograms at the same specificity unless the selection rule is deliberate. Validate product identities, own-brand flags, shelf order and facing expectations with merchandising before activating a window, and close the old window instead of overwriting an arrangement already audited. The current server resolver evaluates effective windows against **current UTC**, not the visit date. When a historical result looks wrong, compare the resolution time and outlet scope, then the photo quality and exact selected planogram. A planogram in xMatix is a record of what the shelf is supposed to look like — shelves, positions, products and expected facings — that merchandising audits are judged against. The executive's side of retail execution is the Merchandising Audit activity on a visit: count facings, rate compliance, photograph the shelf. The analysis side — reading those shelf photos and scoring them — is done by Sense AI and produces **shelf audit results** that attach back to the same activity, so the visit record carries both what the rep observed and what the analysis found. ## The planogram record A planogram holds the structured expectation (shelves → positions → product → expected facings), an optional reference photo, a lifecycle status — Draft, Active, Retired — and an effective date window. Only Active planograms inside their window are used for evaluation. Which planogram applies to an audit is a scoping decision among records active at the server's current UTC time: | Scope | Applies to | |---|---| | Outlet | Exactly one customer account | | Outlet class | Every account of a type (e.g. supermarkets) | | Tenant-wide | Everything else — the default when no narrower planogram matches | The narrowest matching scope wins, so a chain-wide standard can coexist with a store-specific exception. ## The audit on the visit The Merchandising Audit activity captures the human read of the shelf: facings counted per product, a planogram-compliance rating, share-of-shelf and hygiene observations, and the shelf photos. It is a normal visit activity — defined by the task template, completed offline if need be, photos queued for upload like any other capture (see [Checklists and tasks](/docs/field-sales/checklists-and-tasks/)). ## Shelf audit results Once the photos sync, analysis produces a **shelf audit result** attached to the activity: a compliance score (0–100) and status — Compliant, Partial, Non-compliant, or Unable to Assess — structured findings such as missing or misplaced products and facing shortfalls, the measured share of shelf overall and per brand, and the total facings detected. Each analysis run is kept as its own result row, so a re-analysis adds history rather than overwriting the earlier judgment. Results are also stamped with the visit and outlet, making compliance and share-of-shelf reportable across routes and time. The executive sees the latest result as a card on the activity itself. One practical note: results exist only after the photos have synced and the analysis has run server-side, so viewing them needs connectivity — unlike the capture, which works offline. ## Shelf products Share-of-shelf numbers are only as meaningful as the product identities behind them. The **shelf product** catalog maps each recognized detection label to a display name for reporting, optionally rolls labels up into clusters, and — decisively — flags which products are **own brand**: that flag is the numerator of share of shelf. How the photo analysis itself works, and how it is administered, is covered with the rest of Sense AI in the [Knowledge Center](/docs/). ## Common questions ### Do I need a planogram to measure share of shelf? No. Share of shelf comes from what is detected in the photos and the own-brand flags — an audit without any applicable planogram still yields share-of-shelf results. The planogram is only needed for the compliance judgment. ### Who maintains planograms? Trade-marketing or sales-ops users on the web: they author the layout, scope it (outlet, outlet class, or tenant-wide), set the effective window and activate it. Executives never pick a planogram — the applicable one is resolved automatically for each audit. ### Why does a result say "Unable to Assess"? The analysis could not reach a confident judgment from the submitted photos. Re-shooting the shelf — closer, straighter, better lit — and letting the activity re-sync typically resolves it; each re-analysis lands as a new result row. ## Related topics - [Checklists and tasks](/docs/field-sales/checklists-and-tasks/) - [Complete a visit](/docs/field-sales/visits/complete-a-visit/) - [Visits and the field day](/docs/field-sales/visits/) - [xMatix Knowledge Center](/docs/) ---- # Discover and onboard nearby outlets URL: https://xmatix.com/docs/field-sales/prospecting/ Last reviewed: 2026-08-31 While you are out on a beat, the plan agenda can show a "Nearby to onboard" feed: outlets around your position that are not on today's plan or route — existing customers you are walking past, and prospect places sourced from external lookups — ranked by distance. From the same cards you can propose an existing customer as a new route stop or onboard a brand-new outlet on the spot, so a gap in coverage becomes a stop instead of a missed observation. ## Prerequisites - The nearby feed enabled on your organization's visit-plan agenda (it is a configuration choice). - Device location permission — the feed is anchored on where you are standing. - Permission to create customer accounts, if you will onboard new outlets. ## Procedure @[guided-image](_img/new-prospect.png) ### Step 1 — Open the nearby feed on your plan Open today's Visit Plan, start or select the correct active stop, and grant precise device location when prompted. The nearby scroller lists **existing customers** not already on the plan or route and **prospects** that are not customers, nearest first. Before acting, confirm the location indicator is current and inspect distance, address and phone on the card; a stale GPS fix can make the ranking misleading even when the records are correct. ### Step 2 — Discover more outlets around you With connectivity available, select **Find Nearby Outlets** once and wait for the server-side places search to finish. Review new cards against visible storefront names and addresses before assuming they are distinct. The platform saves prospect records and deduplicates previous discoveries; run the same search again during testing and verify the count does not increase for unchanged places. If nothing appears, confirm both connectivity and the displayed search origin before widening the radius. ### Step 3 — Add an existing customer to the route On an existing-customer card, open enough context to verify the account and address, then tap **Add to Route** once. The card should change to **Proposed** and the route should gain one pending stop without changing today's visit order. Tell the planner why the stop belongs on the beat; after approval, verify it becomes an approved route stop and appears only in newly generated plans, not retroactively in completed work. ### Step 4 — Onboard a new outlet On a prospect card, tap **Onboard** and review every prefilled name, address, phone and coordinate against the storefront or contact—external place data is a starting point, not verified customer master data. Search for an existing account before saving, complete required commercial fields, and save once. Open the resulting account and verify the prospect links to it, is marked onboarded and no longer appears as available. Use **+ Add outlet** only when discovery has no matching place and validate the hand-entered location before route use. ## Expected result The nearby feed is distance-ranked without duplicating existing route stops, an existing customer becomes one proposed stop for planner review, and an onboarded prospect creates one linked customer account with verified contact and location data. Repeating discovery does not recreate the same place. ## Common problems If the feed is empty, you may genuinely be covered — outlets already on the plan or route are excluded by design — or the surrounding accounts may be missing coordinates, which keeps them out of any distance-ranked list. If Find Nearby Outlets returns nothing, check connectivity: discovery is one of the few visit-flow actions that cannot run offline. ## Common questions ### What is the difference between "Add to Route" and "Onboard"? Add to Route is for a store that is already your customer but not on this beat — it becomes a proposed stop. Onboard is for a store that is not a customer at all — it creates the account first. Both start from the same feed; the card type decides which you see. ### Do onboarded prospects show up again? No. Onboarding flips the prospect's status and links it to the created account, and the feed only offers prospects still waiting. The linkage also means the source place is kept for audit — you can always see which lookup a customer came from. ### Where do prospect places come from? Two sources: on-demand discovery runs from the field, and bulk-loaded lists your organization imports. Both land in the same pool, keyed by their source identity so repeats collapse into one record. ## Related topics - [Beats and routes](/docs/field-sales/routes/) - [Visits and the field day](/docs/field-sales/visits/) - [Visit plans](/docs/field-sales/visit-plans/) ---- # Beats and routes URL: https://xmatix.com/docs/field-sales/routes/ Last reviewed: 2026-09-01 ## Read the beat definition @[guided-image](_img/visit-route-concept.png) A Visit Route is the reusable beat from which daily plans are generated. Name identifies it, Resource assigns the responsible executive, Active and Validity control whether it can produce future work, and Partner Account plus Visit Purpose provide commercial scope. Visit Task Template determines the work copied onto visits, while Week Numbers, Day Numbers and Routing Priority encode the recurring calendar rhythm. Before approval, verify the executive is active, the validity window includes intended service dates, schedule numbers follow your organization's convention, every approved stop has coordinates, and the task duration fits the shift. Treat stop order as explicit versioned data: preserve planned, optimized and observed sequences rather than assuming row order is authoritative. After changing ownership or schedule, inspect upcoming plans for duplicates or gaps because an existing plan for a beat and date deliberately suppresses regeneration. A beat — a **visit route** in xMatix — is the reusable definition of a field journey: a named list of outlet stops, assigned to a sales executive, with a weekly schedule that says which days it runs. Beats are the planning layer; the daily [visit plans](/docs/field-sales/visit-plans/) executives actually work are generated from them. Related beats are collected into **route groups**, which is also the level at which [territory planning](/docs/field-sales/territory-planning/) operates. ## What a route carries | Element | Meaning | |---|---| | Executive | The resource the route belongs to — generated plans are assigned to them | | Stops | The outlets on the beat, each with a sequence number and coordinates | | Schedule | Day-of-week flags, optional week-of-month numbers, optional start time | | Effective window | From/to dates outside which the route generates nothing | | Visit task template | Expanded onto every visit when a plan is created — the work expected at each stop | | Visit purpose | Carried onto generated plans and visits for reporting | ## Stops Each route entry points at an outlet (a customer account), holds its position in the authored order, and carries the outlet's coordinates — the input everything geographic depends on: route optimization, distance on the agenda map, and the nearby-outlets feed. Stops have a status; only **approved** stops generate visits and take part in optimization, so a proposed stop (for example one added from the field through [prospecting](/docs/field-sales/prospecting/)) can wait for a planner's approval before it changes anyone's day. Adding, timing, approving and transferring stops is covered step by step in [Route stops](/docs/field-sales/routes/route-stops/). ## Stop orders are stored, not implied A route does not have just one order. xMatix stores **route sequences** — versioned orderings of the same stops — of three kinds: the **Planned** order as authored, the **Optimized** order computed over road-network data, and the **Mostly Followed** order learned from how executives actually drove the beat. Each new computation is appended as a run with its distance and duration, and the current run of each kind is what planners apply and executives see on the agenda. How to produce and apply them is covered in [Optimize a route](/docs/field-sales/routes/optimize-a-route/). ## Common questions ### What is the difference between a route and a visit plan? The route is the template; the plan is one dated instance of it. Editing a route changes future plans only — days already generated keep the stops and order they were built with. ### What happens when I deactivate a route? It stops generating plans immediately, but nothing historical is touched: past plans, visits and orders remain. Territory planning uses the same mechanism when it replaces a group's routes — old routes are deactivated, not deleted, so history stays intact. ### Can the same outlet be on two routes? Yes — nothing prevents an outlet appearing on multiple beats, which is common during route transitions. Be deliberate about it, though: each route generates its own visits, so an outlet on two active beats gets visited under both. ## Related topics - [Route stops](/docs/field-sales/routes/route-stops/) - [Optimize a route](/docs/field-sales/routes/optimize-a-route/) - [Visit plans](/docs/field-sales/visit-plans/) - [Territory planning](/docs/field-sales/territory-planning/) - [Prospecting](/docs/field-sales/prospecting/) ---- # Optimize a route URL: https://xmatix.com/docs/field-sales/routes/optimize-a-route/ Last reviewed: 2026-08-31 Route optimization reorders a beat's stops over real road distances, so the executive drives the shortest practical loop instead of the order the stops happened to be authored in. It is an **on-demand** action — each run queries a routing service over road-network data and costs a request, so you run it when the beat's stops change, not on a timer. There is no continuous or daily background re-optimization. ## The three sequence kinds Every ordering of a beat's stops is stored as a run, and three kinds coexist: | Sequence | Where it comes from | When it changes | |---|---|---| | Planned | The authored stop order on the route | When a planner edits the route | | Optimized | Road-network optimization on demand; a computed shortest-chain estimate otherwise | When you run the optimization | | Mostly Followed | Learned from execution history: the average position of each stop across the order visits were actually started in | Recomputed as visit history accrues; also per executive, so a rep's own habit is captured separately | Each run records its total distance, estimated duration and how many stops it resequenced, and superseded runs are kept — so you can always compare what the optimizer proposes against what the beat used to be, and against what the field actually does. ## Prerequisites - A beat (visit route) with approved stops, and coordinates on the outlets — stops without coordinates cannot be ordered and will trail at the end in their authored order. - The routing provider configured for your organization (an administrator sets this up). ## Procedure ### Step 1 — Run Optimize Route on the beat Open the intended Visit Route and review its approved stops, start/end locations and coordinate coverage before selecting **Optimize Route**. Resolve obviously wrong coordinates and note the planned distance as a baseline. The confirmation represents a paid road-network request, so submit once and wait for completion. Verify a new sequence-run link appears; if no stops have coordinates, the action should create no run and consume no request. ### Step 2 — Review the run Open the newest run and confirm its kind, created time and stop count identify the request you just made. Compare total distance, estimated duration and moved-stop count with Planned, Mostly Followed and earlier Optimized runs. Inspect the ordered stop list for duplicates, omissions and implausible jumps; ungeocoded stops should trail in authored order. Activate the run only when the route is operationally credible, then verify it is visibly marked current while history remains intact. ### Step 3 — Let new plans pick it up Generate one disposable future plan after activating the sequence. Open its visits and verify their order matches the route's current sequence, including how ungeocoded stops are handled. Compare an existing plan created before activation and confirm its order did not change. Delete or clearly label the disposable plan after the check so it cannot be mistaken for real field work. ### Step 4 — Apply a sequence to an existing plan For an existing day, open the exact plan, review completed and remaining visits, and apply the chosen stored sequence only after confirming the executive. Verify the stamped working order changes for the intended visits and completed work remains historically accurate. On mobile, optimize the current day only with a fresh GPS fix; it anchors on the executive's present position and should reorder remaining visits. Reopen the agenda and confirm the first suggested stop and total remaining route are plausible. ## Expected result A new Optimized sequence is stored with plausible distance, duration and moved-stop counts; every geocoded approved stop appears once and ungeocoded stops remain at the end. Newly generated plans adopt the current sequence while existing plans and historical runs remain unchanged. ## Common problems If the optimized order looks partly wrong, check coordinates first: stops without them are placed at the end, unordered by road. If running the action appears to do nothing, the route may have no approved stops — proposed stops are excluded. And remember the scope rule that surprises most people: optimizing the beat changes future plans, not today's, unless you explicitly apply the sequence to the plan. ## Common questions ### Does xMatix re-optimize my routes automatically every day? No. Road-network optimization runs only when someone asks for it — it is a paid, deliberate action. What does refresh in the background is the learning: the Mostly Followed sequence is recomputed as new visit history accrues, without any external requests. ### What is the "Mostly Followed" sequence for? It is the beat as it is actually driven. If the field consistently deviates from the planned order, that deviation usually encodes real knowledge — opening hours, parking, lunch rushes. Mostly Followed makes it visible and appliable instead of leaving it as private habit, and it is computed per executive as well as for the route overall. ### Which order does the executive see on mobile? All three. The plan agenda has a Planned / Optimized / Mostly Followed selector on both the timeline and the map, with a comparison banner showing distance saved and stops resequenced, and the executive remains free to visit in any order. ## Related topics - [Beats and routes](/docs/field-sales/routes/) - [Visit plans](/docs/field-sales/visit-plans/) - [Territory planning](/docs/field-sales/territory-planning/) - [Visits and the field day](/docs/field-sales/visits/) ---- # Route stops URL: https://xmatix.com/docs/field-sales/routes/route-stops/ Last reviewed: 2026-10-10 A route stop is one outlet's place on a beat. It says which customer account is visited, where it sits in the order, what time window it has and how close the executive must be to check in. Stops belong to a [visit route](/docs/field-sales/routes/), the beat. Each time the beat generates a [visit plan](/docs/field-sales/visit-plans/), every approved stop becomes one visit on that plan. Change the stops, and the next plans change with them. ## Overview A visit route on its own is a schedule with nobody to visit. Its stops supply the outlets. A stop carries: - the **Account** being visited, plus a **Stop Name** for how it reads on the beat; - its **Sequence Number**, which is the authored (Planned) order; - an optional **Start Time** and **End Time**, which become the visit's planned slot; - its own **Account Location** coordinates, used for route optimization and as the visit's planned position; - an **Allowed Geofencing Tolerance (KM)** for the check-in distance warning; - a **Visit Purpose**; - a membership **Status**: Approved, Proposed or Rejected. You maintain stops on the web, on the Visit Route record. Executives also create stops from the field app, as proposals that wait for approval. Supervisors move stops between beats with the field app's Outlet Transfer screen. ## When to use it - **Building a new beat:** add one stop per outlet, in the order the beat should run. - **Adding or removing an outlet:** add or delete the stop. Plans generated from then on include it or leave it out. - **Changing an outlet's time window or check-in radius:** edit the stop. - **Reviewing an executive's suggestion:** a stop proposed from the field stays Proposed until someone approves it. - **Rebalancing beats:** move outlets from one beat to another of the same channel partner with Outlet Transfer. Don't delete and re-create them. ## How xMatix handles it When the scheduler generates a plan for a beat, it reads the beat's stops and creates one visit per approved stop. Each visit copies these values from its stop: | Visit receives | From the stop | |---|---| | Account | Account | | Planned start and end time | Start Time and End Time | | Sequence number and Planned sequence | Sequence Number (stops without one go last) | | Visit purpose | Visit Purpose | | Geofencing tolerance | Allowed Geofencing Tolerance (KM) | | Planned position | Account Location, or the account's own Geo Location when the stop has none | The plan's end time is the latest **End Time** among the beat's stops. Each visit's Optimized and Mostly Followed positions come from the beat's current stored [route sequences](/docs/field-sales/routes/optimize-a-route/). Some things do **not** come from the stop. The day a plan is generated comes from the **route's** schedule, and every visit gets the **route's** visit task template. A stop's own Availability switches, **Day Numbers**, **Week Numbers** and **Visit Task Template** are saved with the stop, but plan generation doesn't read them. To visit an outlet on a different rhythm from the rest of the beat, put it on a beat with that rhythm. Visits are copies. Editing or deleting a stop changes plans generated afterwards. Plans that already exist keep the values they were built with. ## Prerequisites - A [visit route](/docs/field-sales/routes/) to hold the stops. - The outlets exist as **active customer accounts**. The stop's Account lookup only offers accounts with Customer Account and Active switched on. - Coordinates for each outlet, either on the stop (**Account Location**) or on the account (**Geo Location**). Optimization uses only the stop's own Account Location. - To create or edit stops, a security profile with access to Visit Route Stop (see Permissions below). ## Procedure ### Step 1 — Open the beat's stops In the **Field Sales** app, open the **Visit Route** list and open the beat. Select the **Visit Route Stops** tab. Its list shows each stop's **Name**, **Stop Name**, **Account**, **Sequence Number** and **Visit Route**. Sort by **Sequence Number** to read the beat in its authored order. ### Step 2 — Add a stop On the **Visit Route Stops** tab, select **New**. The new stop is linked to the beat you started from. Fill in: 1. **Stop Name**: how the outlet should read on the beat, for example the shop's signboard name. 2. **Account**: the customer account to visit. 3. **Account Location**: the outlet's coordinates. Leave it empty to use the account's stored Geo Location for the planned position. Without it, though, the stop can't be placed by route optimization. 4. Expand **Timing Details** and set **Start Time** and **End Time** if the outlet has a fixed slot. Set **Sequence Number** to the stop's position on the beat. Set **Allowed Geofencing Tolerance** if this outlet needs a different check-in radius from the default. Save. A stop created this way is **Approved**, so it's included in the next plan the beat generates. ### Step 3 — Complete the stop's details Open the stop to see its full record. It's grouped into **Basic Details**, **Timeline Performance**, **Reference Details**, **Pattern & Preferences**, **Availability** and **System Information**. Select **Edit** to set **Visit Purpose** (it is copied onto each generated visit) or to add **Remarks**. **Duration** shows the minutes between Start Time and End Time and is calculated for you. ### Step 4 — Set the order of the beat Give each stop a **Sequence Number** in the order the beat should run: 1, 2, 3 and so on. A stop with an empty number comes after all numbered stops. This authored order is the beat's **Planned** sequence. To have xMatix compute a shorter order over road distances, use **Optimize Route Sequence** on the beat. See [Optimize a route](/docs/field-sales/routes/optimize-a-route/). ### Step 5 — Propose a stop from the field (mobile) On a visit plan in the field app, the agenda can show a **Nearby to onboard** feed of outlets around the executive. On an existing customer's card, tap **Add to Route**. On a prospect's card, tap **Onboard** to create the account first. Either way the app creates a **Proposed** stop on the plan's beat, and the card changes to **Proposed**. Without a connection the proposal is saved on the phone and synced later ("will sync"). A proposed stop changes nothing in today's plan. Details are in [Prospecting](/docs/field-sales/prospecting/). ### Step 6 — Approve or reject proposed stops A proposed stop generates no visits and is left out of optimization until its **Status** is **Approved**. Open the stop, select **Edit**, and set **Status** to **Approved** to put the outlet on the beat, or to **Rejected** to decline it. The delivered stop forms and list don't show **Status**, so an administrator first adds it to the layout and list view (see Configuration below). After approval, the outlet appears in plans generated from then on. It isn't added to plans that already exist. ### Step 7 — Transfer outlets to another beat (mobile) To move outlets between beats, use the field app's **Outlet Transfer** screen. Choose the **From Beat**, the **To Beat** and the **Outlets**, then select **Submit**. Submit only files a request, and the outlets stay where they are. The submitter's manager opens the transfer requests and selects **Approve** or **Decline**. Approving needs a connection. On approval the stops move to the new beat and keep their visit history. The confirmation says the outlets moved, and how many were skipped because their account was already on the target beat. A decline leaves the outlets on their beat ("Request declined. The outlets stay on their beat."). ### Step 8 — Remove a stop To take an outlet off a beat, open the stop and select **Delete**, then confirm. Deletion can't be undone. Plans generated afterwards leave the outlet out, and existing plans keep their visit for it. To move an outlet to another beat instead, use Outlet Transfer (Step 7) so its history stays attached. ## Fields | Field | What it means | Notes | |---|---|---| | Stop Name | The name the outlet carries on this beat | Shown on the stops list. Stops proposed from the field take the outlet's name. | | Account | The customer account visited at this stop | Only active customer accounts can be picked. Copied onto each generated visit. | | Account Location | The stop's own coordinates | Becomes the visit's planned position. If empty, the account's Geo Location is used. Route optimization uses only this field. | | Sequence Number | The stop's position in the authored order | Sets the Planned sequence of generated visits. Number every stop: an empty number sorts last, and 0 sorts before 1. | | Start Time | The planned start of the visit at this outlet | Copied as the visit's planned start time. | | End Time | The planned end of the visit at this outlet | Copied as the visit's planned end time. The latest End Time on the beat sets the plan's end. | | Duration | Minutes between Start Time and End Time | Calculated and read-only. Empty unless both times are set. | | Allowed Geofencing Tolerance (KM) | How far from the outlet a check-in can be before the field app warns | Copied onto each visit. **The field app reads this number in metres** despite the KM label: enter 150 for 150 m. Empty means 100 m. | | Visit Route | The beat this stop belongs to | Set from the beat you created the stop on. Changed only by Outlet Transfer. | | Visit Task Template | A task template recorded on the stop | Not used for plan generation: visits get the route's template. | | Visit Purpose | Why this outlet is visited | Copied onto each generated visit. Values: Field Service, Order Capture, Courtesy Visit, Service Touch, Payment Collection, Asset Deactivation, Sale Order, Quote or Invoice Collection, New Asset Data Collection (FIR), Order Delivery, Product Demo. | | Day Numbers | Day numbers recorded on the stop | Not read by plan generation. The route's schedule decides the day. | | Week Numbers | Week-of-month numbers recorded on the stop | Not read by plan generation. The route's schedule decides the week. | | Remarks | Free-text notes | Stops proposed from the field say "Onboard request from Visit Plan agenda". | | Monday Available … Sunday Available | Seven availability switches | Recorded on the stop. Plan generation uses the route's own day switches, not these. | | Status | The stop's membership of the beat | Approved, Proposed or Rejected. New stops created on the web are Approved. Field proposals are Proposed. Only Approved stops (or older stops with no status) generate visits. | ## Business rules - **Only approved stops count.** Plan generation and route optimization use only stops whose Status is Approved, or older stops with no status. A beat whose stops are all Proposed or Rejected generates no plans. - **One visit per approved stop per plan.** Every approved stop on the beat becomes a visit on every plan the beat generates. - **Duplicate proposals are refused.** Saving a Proposed stop for an account that is already on the beat, at any status, fails with "This account is already on the route (or already proposed)." Stops added directly as Approved aren't checked, so an administrator can put the same account on a beat twice on purpose. - **Changes apply going forward.** Visits copy stop values at generation time, so editing, approving or deleting a stop doesn't change plans that already exist. - **Transfers move the stop itself.** Outlet Transfer re-points the stop to the target beat rather than deleting and re-creating it, so past visits, stored sequences and the onboarding trail stay with it. Moved stops are numbered after the target beat's highest Sequence Number, and both beats' stored sequences are recomputed. Open plans that already contain the moved outlets aren't rewritten. - **Transfer limits.** A transfer is refused when: - the target beat is inactive or deleted; - the beats have different channel partners; - with HQ grouping on, the beats are in different HQs (Resource Groups); - either beat is outside the user's Outlet Transfer scope; - a visit at one of the outlets is Started, In Progress or Paused. - **Transfer skips duplicates.** An outlet whose account is already on the target beat is skipped and reported, and the rest still move. - **Check-in distance is a warning.** In the field app, starting a visit outside the stop's tolerance shows a "You're … from the store" warning. The visit still starts, marked "Visit started (off-site)". ## Example A beat called *North Market — Tuesday* covers six outlets. The planner adds a seventh, *Sunrise Provisions*. They open the beat, select **New** on **Visit Route Stops**, and enter Stop Name *Sunrise Provisions*, the account, and its coordinates. Under **Timing Details** they set Start Time 11:30, End Time 11:50, Sequence Number 4 and a tolerance of 150. They save, then edit the stop to set Visit Purpose to *Order Capture*. The next Tuesday's plan has seven visits. Sunrise Provisions is fourth in the Planned order, has an 11:30–11:50 slot, has purpose Order Capture, and warns the executive if they start the visit more than 150 m away. Last Tuesday's plan still has six visits. That afternoon the executive walks past *Lakeview Stores*, an existing customer, and taps **Add to Route** in the Nearby to onboard feed. A Proposed stop appears on the beat. The planner reviews it on Wednesday and sets Status to Approved. Lakeview Stores first appears on the following Tuesday's plan. ## Training ### Practice exercise In a sandbox, open any active visit route that has at least one stop. 1. Add a stop for an active customer account. Give it Sequence Number 1, Start Time 09:00, End Time 09:30 and a tolerance of 200. 2. Open the stop and confirm **Duration** shows 30. 3. Add a second stop for the same account with the Status field set to Proposed (your administrator may need to add Status to the form). **Expected result:** step 1 saves and the stop appears on the Visit Route Stops tab. Step 3 is refused with "This account is already on the route (or already proposed)." The next plan generated for the beat contains a visit for the account, planned 09:00–09:30 and first in the Planned order. ### Quick reference - One stop = one outlet on one beat = one visit per generated plan. - Only **Approved** stops generate visits and take part in optimization. - **Sequence Number** sets the Planned order. Stops without a number go last. - **Start Time / End Time** become the visit's planned slot. The latest End Time sets the plan's end. - The tolerance field is read in **metres** by the field app. Empty means 100 m. - The day and the task template come from the **route**, not the stop. - Edits change future plans only. - Move outlets with **Outlet Transfer**. Don't delete and re-create them. ## Permissions | To… | You need | |---|---| | See, create, edit and delete stops | Access to the Visit Route Stop entity in your [security profile](/docs/administration/security-profiles/). The delivered **Sales Executive**, **Sales Manager**, **Standard User** and **System Admin** profiles grant full access. | | Approve an outlet transfer (the **Transfer Stops** action on the beat) | The Transfer Stops action permission. It's delivered on **Sales Executive**, **Sales Manager** and **System Admin**. You also need both beats inside your Outlet Transfer scope. | | Change the Outlet Transfer rules or preview a user's scope | `setup.featurehub.settings.manage` | Which stops a user can see also follows [record security](/docs/administration/record-security/). A user without access to the entity doesn't see the **Visit Route Stops** tab's records. A transfer outside the user's scope is refused with a message that explains why, for example "You can only transfer outlets from your own beats." ## Configuration ### Show Status for approvals The delivered Visit Route Stop forms and the stop list don't include **Status**. To review field proposals, add Status to the stop's layout and to the list view used on the Visit Route Stops tab, then filter on **Proposed**. See [Customizing xMatix](/docs/customization/). ### Account lookup The stop's Account picker uses the **Customer Account** lookup filter (Customer Account and Active both on). Change it only if stops really must point at other accounts. ### Outlet Transfer rules Go to **Setup → Feature Hub → Sales → Settings**, **Outlet Transfer** group. These four rules decide what the field app's transfer screen offers and what the server accepts. A rule change applies the next time a user opens the screen. | Setting | Options | Default | What it changes | |---|---|---|---| | Beats a user can transfer from | Own beats · Own and team beats · All beats | Own beats | Own beats are those assigned to the user's resource, or to a position they hold today. Managers who approve their team's transfers need **Own and team beats**. | | CP Code list | From the beats · Assigned to the user | From the beats | Where the channel-partner list comes from. A beat with no channel partner can never be transferred. | | HQ | Resource Group · No HQ | Resource Group | With Resource Group, outlets move only between beats in the same resource group, and a beat without one can't be transferred. No HQ drops that check. | | Beats outlets can move to | Within the same scope · Any beat under the same CP and HQ | Within the same scope | Whether outlets can be handed to other users' beats. | To check a user's transfer scope, go to **Setup → Access Control → Users**, open the user, then the **Access Diagnostics** tab and its **Outlet Transfer** card. See [User accounts](/docs/administration/users/user-accounts/). ### Field app screens The Nearby to onboard feed and the Outlet Transfer screen are parts of the mobile layout that an administrator places and configures. See [Prospecting](/docs/field-sales/prospecting/) for the feed. ## Common problems ### "This account is already on the route (or already proposed)." You, or the field app, tried to save a Proposed stop for an account that already has a stop on this beat, whatever that stop's status. Open the existing stop instead. If it is Proposed or Rejected, change its Status rather than adding another. ### An outlet I added isn't on today's plan Plans copy the stops when they are generated, and an existing plan for a beat and date isn't regenerated. The outlet appears from the next generated plan. Also check the stop's Status: a Proposed or Rejected stop generates no visits. ### A beat suddenly generates no plans Check that it still has at least one Approved stop. A beat whose stops are all Proposed or Rejected (or deleted) is skipped by the scheduler. Also check the route itself: it must be active and inside its effective dates. See [Visit plans](/docs/field-sales/visit-plans/). ### The check-in warning fires although the executive is at the shop The tolerance is read in metres. A value of 1 entered as "1 km" means 1 metre. Enter the radius in metres, for example 200. Also check the stop's **Account Location**: if it's wrong, every check-in looks off-site. ### An outlet keeps visiting on the wrong day Plan days come from the route's schedule, not the stop's Availability switches, Day Numbers or Week Numbers. Move the outlet to a beat that runs on the right days, using Outlet Transfer. ### Optimization leaves some stops at the end Stops without their own **Account Location** can't be placed on the road network, so they trail in authored order. Fill in the coordinates on the stop. ### Outlet Transfer is refused The message says why: - "Outlets can only be transferred between beats of the same CP." or "…of the same HQ." The target beat is under a different channel partner or resource group. - "The beat you are transferring to is inactive." Pick an active beat. - "A visit is in progress at …. Finish or cancel it before transferring." Wait until the visit ends. - "You can only transfer outlets from your own beats." Your Outlet Transfer scope doesn't include the beat. An administrator can widen **Beats a user can transfer from**. - "… selected outlet(s) are no longer on this beat. Reload and try again." Someone moved them already. ## Common questions ### Does changing a stop change today's plan? No. A plan copies its stops' account, times, sequence, purpose, tolerance and location when it is generated, and an existing plan for a beat and date is never regenerated. Your change applies from the next plan the beat generates. The same goes for approving a proposed stop, deleting one, or transferring outlets: plans already generated keep the visits they were built with. ### Can one outlet be on two beats? Yes. Nothing stops the same account having stops on several beats, and each active beat then generates its own visit to it. Within one beat, xMatix refuses a field proposal for an account already there. A stop added directly on the web isn't checked, so watch for accidental duplicates. ### Why can't I visit one outlet every week on a fortnightly beat? The schedule belongs to the beat. The stop's own Availability switches, Day Numbers and Week Numbers are saved with the stop, but plan generation reads only the route's schedule. Every approved stop is visited every time the beat runs. Put an outlet with a different rhythm on a beat that has that rhythm. ### What happens to an outlet's history when it moves to another beat? It goes with it. Outlet Transfer re-points the existing stop to the new beat instead of deleting it, so past visits, stored sequences and the record of how the outlet was onboarded stay linked. Deleting a stop and creating a new one on another beat would start the outlet's history again. ## Related topics - [Beats and routes](/docs/field-sales/routes/) - [Optimize a route](/docs/field-sales/routes/optimize-a-route/) - [Visit plans](/docs/field-sales/visit-plans/) - [Prospecting](/docs/field-sales/prospecting/) - [Territory planning](/docs/field-sales/territory-planning/) - [Visit Route Stop — entity reference](/docs/reference/entities/visit-route-stop/) - [Visit Route — entity reference](/docs/reference/entities/visit-route/) ---- # Selling scope and partner account mappings URL: https://xmatix.com/docs/field-sales/selling-scope/ Last reviewed: 2026-10-10 A partner account mapping is a dated rule that allows or blocks items, or whole item groups, for one sales executive, optionally narrowed to a selling company, branch, customer or group. Take Order reads these rules to decide which products the executive may sell. Together with the selling company's store, they make up the executive's **selling scope**. The rules sit between your master data (resources, partner assignments, stores, item groups) and order taking: you set them up once per executive and territory, and they apply every time that executive opens Take Order for a customer. ## Overview Two things decide what an executive sees in Take Order: 1. **The store.** The selling company's store sets the full range. Only items the store stocks can be offered. 2. **The partner account mappings.** These narrow that range for one executive. Rows marked as blocked remove items. Rows marked as allowed turn the range into a whitelist. xMatix works out the selling scope on the server and sends the device only the result: the allowed, blocked and stocked item lists. Because of this, the executive needs no read access to the mapping rows, the resource record or the item group memberships behind the result. A rule an administrator writes therefore applies to the executive it names, even though that executive may not be able to open the rule. Mobile Take Order and web Take Order ask for the same answer and apply the same rule to each item. Once the selling company's store is found, one executive selling to one customer sees the same range on both. ## When to use it - An executive may sell only part of the catalogue, for example one brand's item group, in a territory. - An item must be kept away from one customer, one customer group or one distributor for a period, for example while a listing is disputed. - A distributor has agreed exclusions with you, and those should apply only while that distributor's terms are in force. Do not use partner account mappings to store lists such as "frequently ordered items". Every row that names an item takes part in the allow/block decision. Writing top-N rows here changes what executives may **sell**. Frequently ordered items are calculated by Take Order itself. ## How xMatix handles it When an executive opens Take Order for a customer, xMatix resolves the scope step by step. 1. **The executive's resource.** xMatix looks for the active **Resource** whose **User** is the signed-in user. If none exists, the catalogue is not scoped. 2. **The selling company and branch.** If the visit carries a partner account (and branch), those are used. Otherwise xMatix uses the resource's **Default Partner Account** and **Default Branch** when both are set. If they are not both set, it uses the first current **Partner Resource** assignment, ordered by **Assignment Sequence Number**. If there is no current assignment either, it uses whichever default is set. Orders are stamped with the same partner account and branch when they are saved, so the catalogue and the saved order always agree. 3. **The mapping rows that apply.** xMatix collects every mapping whose **Resource** is this executive's resource. It keeps only the rows that are in date today and whose every filled condition matches: | Condition on the row | Matches when | |---|---| | **Partner Account** | It is the selling company | | **Partner Account Group** | The selling company is an active member of that account group | | **Branch** | It is the selling branch | | **Account** | It is the customer the order is for | | **Account Group** | The customer is an active member of that account group | | **From Date** / **To Date** | Today falls inside the window; a blank date leaves that end open | A blank condition matches anything. A filled condition cannot match when xMatix does not know the value, for example an **Account** condition when Take Order is opened without a customer. 4. **Allow and block.** Among the matching rows, only those that name an **Item** or an **Item Group** affect the catalogue. An item group means all of its active member items. - **Is Allowed = No** blocks those items. A block always wins over an allow. - **Is Allowed = Yes** allows them. As soon as at least one matching allow row exists, the executive sees **only** allowed items. - **Is Allowed blank** means "not stated". The row neither allows nor blocks. - A row that names no item and no item group allows or blocks nothing, so it never empties the catalogue. 5. **The store.** xMatix looks for the selling company's store in this order: 1. a **Store** whose **Partner Account** is the selling company; 2. a **Partner Store** link for that company, preferring links for the selling branch or links with no branch; 3. a **Store** whose **Partner Account Group** is a group the company belongs to. If more than one store qualifies, the newest is used. The items in the store's categories are the full range. Each item is then judged in this order: 1. Not stocked by the store: hidden. 2. Blocked: hidden. 3. Allowed list in force and the item is not on it: hidden. 4. Otherwise: shown. The scope always fails open, so an executive is never locked out of ordering: - **No resource or a failed request.** The full catalogue is shown when the user has no active resource or when the request fails. On mobile, the scope is not stored for offline use, so Take Order opened without a connection also shows the full catalogue. - **No selling company, no store or an empty store.** The store does not narrow the range when no selling company is found, the company has no store, or the store's categories hold no items. On mobile, the executive's matching allow and block rows still apply to the whole catalogue. On the web, the mappings are not applied, and the catalogue follows the web's own store lookup for the order (see [Catalogue and pricing](/docs/commerce/catalogue-and-pricing/)). The scope governs what may be **added** to an order. Lines already on an order stay on it when you edit the order, even if the executive's mappings have changed since. ## Prerequisites - **We run multiple companies** is switched on under **Setup → Feature Hub → Administration → Org Settings**. When it is off, partner account mappings are hidden, along with the other partner-only records. - Each executive has an active **Resource** linked to their user, with a **Default Partner Account** (and **Default Branch** where you use branches) or a current **Partner Resource** assignment. - The selling company has a store whose categories contain items. - The item groups and account groups you plan to name exist and have active members. ## Procedure ### Step 1 — Open partner account mappings Partner account mappings are not part of any app's navigation in the standard setup. An administrator adds **Partner Account Mappings** to an app under **Setup → Design Studio → Apps** with **Manage Items**. The list opens on the **All Partner Account Mapping** view, with the columns **Name**, **Partner Account Group**, **Account**, **From Date** and **To Date**. ### Step 2 — Create a mapping Choose **New**. The New form asks for **Partner Account**, **Partner Account Group** and **Account**. Under **Mapping Controls** it asks for **Item**, **Item Group**, **From Date** and **To Date**. **From Date** is required. The **Partner Account** lookup lists only active accounts marked as partner accounts. The **Account** lookup lists only active customer accounts. Save, and the record is given a document number in the **PAM** series. ### Step 3 — Set the resource and the allow/block flag In the standard data model, **Resource** and **Is Allowed** are inactive and appear on none of the standard forms. A row without a **Resource** never takes part in Take Order's selling scope, whatever else it names. A row whose **Is Allowed** is blank neither allows nor blocks. Before you rely on a mapping, confirm with your administrator how your organization fills these two fields. ### Step 4 — Review or change a mapping Open a mapping from the list. The record page shows a **Details** tab with: - an **Information** section: **Partner Account**, **Branch**, **Partner Account Group**, **Account**, **Item**, **Item Group**, **From Date**, **To Date**; - a **System Information** section: **Created By**, **Owner**. When you edit the record in the standard layout, **Item Group** and **From Date** are both required. Changes take effect the next time Take Order resolves the scope. ### Step 5 — End a mapping To stop a rule from a given date, set its **To Date**. This keeps the row as history. **Delete** removes the row outright. **Clone** copies a row as the starting point for a similar one. ## Fields | Field | What it means | Notes | |---|---|---| | Name | The record's document number | Generated on save in the PAM series; it says nothing about what the row maps | | Partner Account | The selling company the rule applies to | Lookup limited to active partner accounts. Blank = any company | | Partner Account Group | A group of selling companies | Matches when the selling company is an active member. Separate from Account Group, which groups customers | | Account | The customer the rule applies to | Lookup limited to active customer accounts. Blank = any customer | | Account Group | A group of customers | Matches when the customer is an active member. Shown on the preview layout only | | Branch | The selling branch the rule applies to | Blank = any branch. Hidden when **We operate from multiple locations** is off | | Item | One item allowed or blocked by the rule | A row with no Item and no Item Group does not change the catalogue | | Item Group | A group of items allowed or blocked by the rule | Expands to the group's active members. Required when editing in the standard layout | | From Date | First day the rule applies | Required on the form. A row with no From Date applies from the beginning | | To Date | Last day the rule applies | Blank = open-ended | | Resource | The sales executive the rule governs | Inactive in the standard data model. The selling scope reads only rows naming the executive's resource | | Is Allowed | Whether the matched items are allowed (Yes) or blocked (No) | Inactive in the standard data model. Blank = not stated; neither allows nor blocks | | Owner | The user who owns the record | Defaults to the creator; drives record-level security | The field reference lists every stored column: [Partner Account Mapping — entity reference](/docs/reference/entities/partner-account-mapping/). ## Business rules - **Numbering.** New rows are named from the **Partner Account Mapping Document Name Settings**: series **PAM**, an eight-digit counter and a day-month-year date part. - **No save-time validation.** Beyond the required fields on the form, xMatix does not check a mapping when it is saved. Conflicting or overlapping rows are allowed. Their effect is settled when the scope is resolved: block beats allow. - **Dates are inclusive.** A row applies on its **From Date** and on its **To Date**. - **Allow-list mode is per executive and context.** It switches on only when at least one row matching *this* customer, company and branch allows an item or item group. The same executive can therefore have a whitelist for one customer and the full store range for another. - **Partner business transfers leave mappings behind.** When a partner's business is handed over with **Transfer Partner Business**, the outgoing partner's mapping rows are neither moved nor copied. They encode terms agreed with that partner. Set up the incoming partner's own rows as part of the handover. ## Example A beverage distributor's executive covers two retail chains for one company. The company's store stocks 400 items. The administrator sets up three rows for the executive's resource: | Row | Account Group | Item Group | Is Allowed | From Date | To Date | |---|---|---|---|---|---| | 1 | (blank) | Juices | Yes | 1 April | (blank) | | 2 | (blank) | Carbonated | Yes | 1 April | (blank) | | 3 | Chain B outlets | Energy drinks | No | 1 April | 30 June | When the executive opens Take Order for an outlet in Chain A, rows 1 and 2 match. Allow-list mode switches on, and the catalogue shows only juices and carbonated drinks the store stocks. For an outlet in Chain B, all three rows match. Any energy drink that is also in the Carbonated group is blocked, because a block always wins. From 1 July, row 3 is out of date and Chain B sees the same range as Chain A. ## Training ### Practice exercise In a sandbox, pick an executive with an active resource whose selling company has a store with items. Create two mappings for that resource: - one allowing a small item group; - one blocking a single item from that group for one customer. Then open Take Order as the executive: - For a different customer, you should see only the item group's members that the store stocks. - For the named customer, you should see the same list without the blocked item. - On mobile, scanning the blocked item's barcode for that customer should report that it isn't available to you because it is blocked for your account mapping. ### Quick reference - No mapping rows = the full store range. - One matching allow row that names items = only allowed items. - A block always beats an allow. - Blank Is Allowed = "not stated"; the row does nothing. - A blank condition matches anything; a filled one must match. - Rows without a Resource never affect Take Order. - From Date and To Date are inclusive; a blank To Date never expires. - No store, no resource or no connection = the full catalogue. - Existing order lines are never removed by a scope change. ## Permissions The standard **Sales Executive**, **Sales Manager**, **Standard User** and **System Admin** security profiles grant full access to partner account mappings: read, create, edit and delete. Record access follows the standard sharing policy for the entity. Records are user-owned, with hierarchy access, manual sharing and team access switched on. See [Record security](/docs/administration/record-security/). Take Order needs no read access to the mappings. The scope is resolved on the server for the signed-in user, from that user's own resource, so it cannot be used to look at another executive's scope. ## Configuration | What | Where | Effect | |---|---|---| | Multi-company switch | **Setup → Feature Hub → Administration → Org Settings → We run multiple companies** | Off hides partner account mappings along with the other partner-only records | | Branch switch | **Setup → Feature Hub → Administration → Org Settings → We operate from multiple locations** | Off hides the **Branch** field on mappings | | Navigation | **Setup → Design Studio → Apps → Manage Items** | Adds **Partner Account Mappings** to an app menu | | Numbering | Document name settings for the entity | Series, counter length and date format of the **Name** | | Lookup filters | **Customer Account Filter** on Account, **Partner Account Filter** on Partner Account | Limit the two lookups to active customer and active partner accounts | | Executive's selling company | The **Resource**: **Default Partner Account**, **Default Branch**; **Partner Resource** assignments with dates and **Assignment Sequence Number** | Decides which company and branch the mappings are matched against | | Store range | **Store**, **Partner Store**, store categories and their items | Sets the full range the mappings narrow | | Groups | **Item Group Members**, **Account Group Members** | Decide which items an item-group row covers and which customers or companies an account-group row matches | | Record access | **Setup → Access Control → Policies** | The entity's sharing policy | ## Common problems ### Take Order shows the whole catalogue The scope declined to narrow it. Check these causes in order: - The executive has no active resource linked to their user. - The resource has no default partner account and no current partner assignment. - The selling company has no store. - The store's categories hold no items. - The device was offline. Each of these shows the full range by design. Without a store, mobile still removes blocked items and applies any allow list, but web does not apply the mappings at all. ### My allow rule has no effect Check the following: - The row names the executive's **Resource**. - **Is Allowed** is Yes rather than blank. - Today is inside the dates. - Every filled condition matches the order's customer, company and branch. - The row names an **Item** or **Item Group**. A row naming neither changes nothing. ### The executive suddenly sees far fewer items An allow row now matches, and allow-list mode is on. Every item not covered by a matching allow row is hidden. Add allow rows for the rest of the range, or narrow the new row's conditions so it applies only where intended. ### A scanned item says it "isn't available to you" The mobile barcode scanner names the reason after the dash: - **blocked for your account mapping**: a matching row with **Is Allowed** = No names the item or a group it belongs to. - **not stocked by your store**: the item is outside the store range. - **not in your allowed items**: allow-list mode is on and no matching allow row covers the item. ### Saving an edited mapping asks for Item Group The standard record layout marks **Item Group** as required when editing. Fill it, or ask your administrator to adjust the layout if your rows name single items. ### The mapping list is missing **We run multiple companies** is off, or the entity has not been added to an app menu. ## Common questions ### Does an executive with no mapping rows see nothing? No. With no matching rows, the executive sees everything the selling company's store stocks. Blocks only remove items. The catalogue narrows to a whitelist only once at least one matching row allows a specific item or item group. A row that states an entitlement without naming items, for example one that only names a customer, does not switch the whitelist on. The design ensures that setting up rows gradually never empties an executive's catalogue by accident. ### What is the difference between Account and Partner Account? **Partner Account** is the selling company, one of your own companies or distributors marked as a partner account. **Account** is the customer the order is for. The same split applies to the two group fields: **Partner Account Group** groups selling companies, and **Account Group** groups customers. Putting a customer group in the partner field, or the other way round, makes the row match the wrong side and usually never match at all. ### Do mappings follow a distributor's territory when it changes hands? No. When a partner's business is transferred, its mapping rows stay with the outgoing partner and no copies are made for the incoming one. Those rows record terms agreed with the previous partner, including exclusions. Create the incoming partner's rows as part of taking the territory on, then check Take Order for one of the transferred outlets. ### Does the scope apply offline? No. On mobile, the selling scope is fetched from the server each time Take Order opens for a customer and is not stored on the device. Without a connection, the catalogue is not narrowed, so the executive can still take the order. Prices and the catalogue itself remain available offline as usual. ## Related topics - [Complete a visit](/docs/field-sales/visits/complete-a-visit/) - [Creating a sales order](/docs/sales/orders/create-order/) - [Catalogue and pricing](/docs/commerce/catalogue-and-pricing/) - [Branches](/docs/administration/branches/) - [Companies and tenants](/docs/concepts/tenants-and-companies/) - [Record security](/docs/administration/record-security/) - [Partner Account Mapping — entity reference](/docs/reference/entities/partner-account-mapping/) ---- # Territory planning URL: https://xmatix.com/docs/field-sales/territory-planning/ Last reviewed: 2026-09-01 ## Read the route-group context @[guided-image](_img/territory-planning-context.png) Territory planning runs from a Visit Route Group rather than an isolated beat. Name identifies the planning population; Visit Purpose and Visit Task Template provide the service intent and expected stop duration; Partner Account and Branch scope the operating context; and Resource information connects the group to available field capacity. These header choices become the common assumptions under every route the planning run produces. Before running Plan Territory, validate outlet coordinates, executive shift windows, template duration, candidate resources and—when enabled—vehicle weight or volume capacities. Review the result summary instead of treating route creation as proof of feasibility: dropped outlets, missing coordinates, capacity-data gaps, total road time and balance tolerance are explicit exceptions that require a decision. Preserve the run output and reason for manual changes so later comparisons distinguish optimizer behavior from planner intervention. Territory planning answers the question a single-route optimizer cannot: "I have a hundred outlets and five executives in one city — who visits what, and in what order?" The **Plan Territory** action on a route group takes a set of outlets and a set of executives and produces one road-ordered beat per executive, balanced so no one's day is systematically longer than anyone else's. The split itself is the optimization: assignment and stop ordering are solved together over real road travel times. ## Inputs and constraints | Input | How it is used | |---|---| | Outlets | Chosen by explicit list, by account group, or as all outlets of a distribution partner; each needs coordinates | | Executives | One route is created per executive | | Shift windows | Each executive's working hours from their business-hours record (a tenant default applies otherwise); a route must fit inside the shift | | Service time per stop | Learned from history — the mean duration of past visits at that outlet — with a configurable default for outlets never visited | | Balance tolerance | Routes are balanced on **total time** (travel + in-store service), within a configurable tolerance over the perfect split | | Van capacity (optional) | Off by default; when enabled, each executive's van caps their route's load by weight and volume, with per-outlet demand estimated from recent order history | | Max stops per route | Optional hard cap; overflow becomes explicit drops | The travel times between every pair of points come from road-network data, so the split reflects actual driving, not straight-line distance. Because the computation can take a while, the action runs on a background worker and reports back when done. ## What a run produces One visit route per executive, named for the group and the executive, its stops in solver order and pre-approved — plus an audit run per route recording the real road distance and duration. The run summary is deliberately explicit about its own limits: - **Dropped outlets** — when a feasible day cannot include every outlet, the leftovers are reported as dropped rather than silently squeezed in. - **Outlets without coordinates** — excluded up front and listed, never silently skipped. - **Capacity data gaps** — items that lack weight or volume on the item master count as zero load, so the summary flags them: reported loads are optimistic until the item data is filled in. - **Load vs capacity per route** — on capacity-constrained runs, each route reports its estimated load against the van's declared limits. ## Rerun semantics Territory planning is safe to run again. By default a rerun deactivates the group's previous routes — history is preserved, and plans already generated from the old routes are untouched — and creates the new set. Scheduling stays human: the run does not set day-of-week rhythms, so the planner assigns each new beat its weekly schedule before [visit plans](/docs/field-sales/visit-plans/) start generating. ## Common questions ### How is "balanced" measured? By total time — travel plus expected in-store service — not by stop count. Ten quick kiosks near each other can be a lighter day than four supermarkets across town, and the solver knows it, because service time per outlet is learned from actual visit history. ### What happens to outlets that don't fit anyone's day? They are dropped and reported by name. The solver prefers an honest partial answer over an infeasible one; the planner can rerun with more executives, longer shifts, or a smaller selection. ### Do I have to use van capacity? No — it is off by default. Enable it when executives sell from stock (van sales) and the van genuinely limits the day; it needs weight/volume on the item master and a declared capacity on each van to bind. ## Related topics - [Beats and routes](/docs/field-sales/routes/) - [Optimize a route](/docs/field-sales/routes/optimize-a-route/) - [Van sales](/docs/field-sales/van-sales/) - [Visit plans](/docs/field-sales/visit-plans/) ---- # Van sales: load, sell, settle URL: https://xmatix.com/docs/field-sales/van-sales/ Last reviewed: 2026-08-31 Van sales is selling from stock on the vehicle: the dispatcher loads the van in the morning, the executive sells and invoices from it through the day, and the evening settles both sides of the ledger — stock back into the depot and cash against what the invoices say should be there. In xMatix the whole run lives on one **Field Sales** load document, and every stock movement it triggers is a real inventory transfer, so van stock is never an off-books guess. ## The van-run lifecycle | Status | Who acts | What happens | |---|---|---| | Draft | Dispatcher | The load is being built: planned quantity per item | | Released | Dispatcher | Stock moves out of the depot onto the van; the run appears on the executive's mobile | | Taken in | Executive | The executive confirms what physically arrived on the van — received, damaged, short, excess | | Reconciled | Dispatcher | Day end: stock checked back into the depot, cash counted against expected, discrepancies reasoned | The van itself is a mobile storage location with its own stock, and the run links to a **Van Sales** visit plan so the selling day is a normal plan on the mobile app. ## Prerequisites - A van defined as a mobile storage location (with declared weight/volume capacity, if you use the capacity check). - A Field Sales load document for the run, with the depot as source and the van as destination. - For capacity checks: unit weight/volume on the item master — items without them count as zero load. ## Procedure ### Step 1 — Build the load The dispatcher creates the Field Sales load with the correct depot, van, executive and operating date, then adds one planned quantity per item. Compare available depot stock, item units, weight and volume with the physical picking sheet; zero-weight master data can hide overloads. Create or link a Visit Plan whose type is **Van Sales**, route and executive match the load, and date covers the selling day. Verify totals and links before release because later postings use this header. ### Step 2 — Release the load When the physical pick is ready, choose **Release** once and review the capacity result. In Warn mode, document an approved overload before continuing; in Block mode, reduce or split the load until it fits. Release posts the depot outward transfer, so open that transfer and reconcile item, quantity, source and van destination. Confirm depot available stock falls as expected, load status becomes Released and the correct run appears on the executive's mobile—do not retry because synchronization is slow. ### Step 3 — Take in the stock Before the first visit, the executive counts physical stock and records received, damaged, short and excess quantities line by line on the mobile van-run card. Reconcile each line equation before confirming and photograph or note material discrepancies under policy. Confirmation posts the van inward transfer and unlocks the day. If offline, verify the action is queued, avoid a second confirmation, and wait for synchronization; once online, check van inventory and run status against the physical count. ### Step 4 — Sell on route At each outlet, open the visit from the van plan, confirm customer and price context, and create the invoice linked to this run. Verify quantities do not exceed van availability, capture the actual payment method, and issue the customer document before leaving. After synchronization, sold quantities and invoiced totals should roll into the load and **cash expected**. Compare the mobile running summary—loaded, sold, van balance and cash—to physical stock and collections periodically, especially after offline sales. ### Step 5 — Settle and reconcile At day end, synchronize all mobile transactions before counting. The dispatcher records returned, damaged, short and excess quantities per line and compares them with expected closing stock; investigate differences before posting the depot inward transfer. Count cash independently, enter **cash received**, and require a specific discrepancy reason whenever it differs from cash expected. Confirm reconciliation once, then verify depot receipt, van balance, cash variance, journal/payment evidence and run status `Reconciled` all agree with the signed physical handover. ## Expected result The released load moves planned stock from depot to van once, take-in reconciles physical quantities before selling, and each mobile sale reduces van stock and records the expected cash or receivable. Day-end reconciliation returns residual stock, balances cash and records every shortage, excess or damage with a reason. ## Common problems If a release is refused, the load exceeds the van's declared capacity and the check is in Block mode — trim the load or use a bigger van. If the capacity numbers look implausibly comfortable, check the item master: items without unit weight or volume contribute zero, making the load look lighter than it is. If the run does not appear on the executive's phone, it has probably not been released yet — Draft loads are invisible to the field. ## Common questions ### Where does "cash expected" come from? From the run's own invoices — it is the rolled-up collected value of what was sold from the van, not a manually entered target. That is what makes the evening comparison meaningful: expected is what the paperwork says, received is what is in the bag, and the difference must be reasoned. ### What happens to damaged stock? It is recorded per line at both handovers — damage found at take-in and damage found at day-end check-in — and posted with the corresponding transfer, so the depot's books reflect it rather than absorbing it silently. ### Can the executive work the run offline? The stock take-in, the visit flow and day-tracking all work offline and replay from the device outbox. See [how offline-first mobile works](/docs/concepts/offline-mobile/) for the mechanics. ## Related topics - [Visit plans](/docs/field-sales/visit-plans/) - [Visits and the field day](/docs/field-sales/visits/) - [Territory planning](/docs/field-sales/territory-planning/) - [How offline-first mobile works](/docs/concepts/offline-mobile/) ---- # Visit plans URL: https://xmatix.com/docs/field-sales/visit-plans/ Last reviewed: 2026-09-01 ## Read the visit-plan header @[guided-image](_img/visit-plan-concept.png) The Visit Plan materializes a reusable route into one executable field day. Name identifies the day, Status tracks lifecycle, Partner Account and Branch establish scope, and Visit Route records the source beat. Visit Purpose and Visit Task Template explain why the stops exist and what work each receives. Assigned To Resource is the planned owner, while Executed By Resource preserves who actually completed the day when reality differs. Before release, confirm the planned timeline, assigned resource, route, template and visit population all belong to the same operating day and timezone. Do not create a duplicate merely because a cancelled plan did not regenerate: the one-plan-per-beat-per-day guard intentionally treats any existing plan as authoritative. For overdue work, inspect auto-cancel margins and individual visit state before changing status; cleanup should lapse only still-open work and must never rewrite visits that already carry execution evidence. A visit plan is one executive's field day: a dated container holding a visit for each outlet due that day, assigned to the executive who will run it. Plans can be created by hand, created by a van run, or — the usual case at scale — generated automatically from each beat's schedule, so the day's plan simply exists when the executive opens the app in the morning. ## Automatic generation from route schedules Once an administrator enables automatic generation, a background job materializes plans from every active beat. For each date in the generation window it checks the beat's schedule, and when the date matches — and no plan exists yet for that beat and day — it creates a plan named after the route and date, assigns it to the route's executive, and builds the child visits from the route's approved stops, in the route's current stop order, with the visit task template expanded onto each visit. | Schedule element | What it does | |---|---| | Days of week | The beat's weekly rhythm — plans are generated only on its marked days | | Week numbers | Optional week-of-month filter, e.g. "1,3" = first and third week only; empty means every week | | Start time | Stamped as the generated plan's start time on the day | | Effective window | The route generates plans only between its effective-from and effective-to dates | | Advanced expression | A cron-style expression can replace the day flags for rhythms they cannot express | | Lead days | How many days ahead plans are materialized (0–30); the job covers today through today + lead days | Two rules keep generation predictable. First, **one plan per beat per day**: any existing plan for that beat and date — generated, manual, even a cancelled one — suppresses regeneration, so deleting or cancelling a day does not summon a replacement. Second, routes whose plans are owned by an external system can be excluded from generation entirely, so the two sides never produce duplicate days. ## Stale-plan cleanup Field reality leaves plans behind — a leave day, a breakdown, a route change. An administrator can set an auto-cancel margin, after which a sweep tidies up: a plan still open past its end date by more than the margin is marked **Lapsed** and its unfinished visits are **Cancelled**; a separate margin does the same for individual overdue visits. Both margins are off by default (set to zero), and settled work is never touched — only still-open plans and visits are swept. ## Plan types A plan carries a type that shapes its behavior: an **Order Taking** plan is the standard visit day, a **Van Sales** plan is linked to a van load document and adds the stock take-in and settlement flow (see [Van sales](/docs/field-sales/van-sales/)), and a **Field Service** plan is the technician variant. ## Common questions ### Why did no plan appear for my route today? Check the schedule first: today must match the route's day flags (and week numbers, if set), fall inside its effective window, and the route must be active with at least one approved stop. Then check whether a plan for today already exists — even a cancelled one blocks regeneration. Finally, automatic generation itself is a setting an administrator must have enabled. ### I edited the route's stops — do existing plans change? No. Visits are built from the approved stops at the moment the plan is created; plans already generated keep the day they were built with. Your edits show up in the next generated plan. ### Does a generated plan overwrite a plan I created manually? Never. A manual plan for a beat and day counts as that day's plan and suppresses generation for it. ## Related topics - [Beats and routes](/docs/field-sales/routes/) - [Visits and the field day](/docs/field-sales/visits/) - [Van sales](/docs/field-sales/van-sales/) - [xMatix administration guide](/docs/administration/) ---- # Complete a visit on mobile URL: https://xmatix.com/docs/field-sales/visits/complete-a-visit/ Last reviewed: 2026-08-31 A visit runs as check-in → tasks → order → check-out, all on the mobile app. Every step works offline: your saves queue on the device and sync when coverage returns, so you complete the visit the same way whether or not you have a network at the outlet. ## Prerequisites - The xMatix mobile app, signed in, with a visit plan for today that includes the outlet. - If your organization gates the app behind attendance, you must be checked in for the day first — see [Attendance](/docs/field-sales/attendance/). - If your organization requires a device location to start or end visits, location permission for the app. ## Procedure ### Step 1 — Open today's plan Open the visit-plans hub. Today's plan is the highlighted current card — tap it (or its **Continue** button) to open the day's agenda. Confirm that the plan date is today and that the expected outlet appears before continuing; this prevents activity being recorded against an older or future plan. The agenda lists your stops as a timeline or a map, in whichever sequence you have selected: Planned, Optimized, or Mostly Followed. ### Step 2 — Check in at the outlet Open the visit for the outlet you are standing at, verify the account name and address, and tap **Check in**. The app stamps the start time and captures your location where your organization requires one; wait for the live timer or in-progress state before leaving the screen, because that is confirmation the check-in was saved. If a required location cannot be captured, the start is blocked until the device can provide one—restore location permission, move where the phone has a clear fix, and retry rather than starting a different outlet's visit. ### Step 3 — Work the tasks and checklists The visit's activity panel lists everything expected at this outlet—checklists, photos, a signature, stock checks, payment collection—with mandatory activities marked. Open each activity, read its prompt, capture the requested evidence, and tap its completion action; then return to the activity panel and confirm its status changed to complete. Photos and signatures attach to the activity, and every completion queues in the outbox if you are offline, so a pending-sync indicator is acceptable but a still-open activity is not. ### Step 4 — Take the order Open the **Take Order** activity. It opens a full-screen catalog with the customer's prices; add the requested items, review quantities, price, discount and total, and confirm only after the customer agrees. Return to the visit and verify the activity shows the created order or completed state. The catalog and price data are already on your device, so ordering works without a network—the order is created against the visit and shows as queued until coverage returns. ### Step 5 — Check out with an outcome Tap **Check out** only after reviewing the activity panel for unfinished mandatory work. The outcome sheet asks you to declare how it went: **Productive** (visit done, order captured), **Non-productive** (you were on site but could not sell) or **Cancelled** (the visit did not happen). Non-productive and Cancelled require a specific reason—for example, "Store closed"—and a Productive close requires every mandatory activity to be complete. Confirm the visit shows an end time and final outcome; if offline, also confirm the completed visit appears in pending changes rather than reopening it and creating duplicate activity. ## Expected result The visit is closed once with a start time, end time, final outcome and all captured activities linked to the correct outlet. Any order or evidence saved offline remains in the durable outbox and changes from pending to sent when connectivity returns; the back office then sees the same visit, outcome and linked records. ## Common problems If you cannot start or end a visit, the usual cause is a required device location the phone has not produced yet — step outside or wait for a fix. If the Productive option is blocked at check-out, you have mandatory activities still pending; finish them or close the visit as Non-productive or Cancelled with a reason. If the office cannot see your order yet, it is still queued — check the pending-changes screen; the item shows as waiting, sent, or failed with the reason attached. ## Common questions ### Can I complete visits in a different order than planned? Yes. The sequence on the agenda is guidance; you can open any visit on the plan. The system even learns the order you actually follow and offers it back as the "Mostly Followed" sequence. ### What if the outlet is closed when I arrive? Check in, then end the visit as Non-productive or Cancelled with the reason. That is deliberately quick — a closed store should cost you seconds, and the recorded reason keeps coverage reporting accurate. ### Do I lose anything if my battery dies mid-visit? Completed saves are already in the durable outbox on the device and survive a restart. Anything you had not saved yet — an unconfirmed cart, an unfinished checklist — is entered again. See [how offline-first mobile works](/docs/concepts/offline-mobile/). ## Related topics - [Visits and the field day](/docs/field-sales/visits/) - [Checklists and tasks](/docs/field-sales/checklists-and-tasks/) - [Attendance](/docs/field-sales/attendance/) - [How offline-first mobile works](/docs/concepts/offline-mobile/) ---- # Visits and the field day URL: https://xmatix.com/docs/field-sales/visits/ Last reviewed: 2026-09-01 ## Read a visit @[guided-image](_img/visits-day-context.png) Each route stop becomes a Visit that joins customer context to a planned execution window. Partner Account identifies the outlet organization, Branch selects the exact location, and Account supplies the commercial context used by orders and follow-ups. Timeline holds the planned date and start/end times; Visit Address defines place; and Related Sources traces the visit back to its plan, route, template or originating activity. Before the day begins, synchronize and verify outlet, address, local window, mandatory work and source plan. At the outlet, start the intended visit and attach tasks, checklists, photos, signatures, notes and orders to that record, even when the device queues changes offline. End with an explicit Productive, Non-productive or Cancelled outcome and the required reason or completion evidence. After synchronization, reconcile actual timing and outcomes against the plan rather than creating replacement visits that split the audit trail. A field day in xMatix is one **visit plan**: the day's container, listing every outlet the executive should reach. Each stop on the plan is a **visit**, each visit carries the **tasks and activities** to complete at that outlet — checklists, photos, a signature, an order — and the order captured during a visit is linked back to it. The whole day runs on the mobile app, and because the app is offline-first, it runs the same way with or without coverage. ## The hierarchy | Object | What it is | Where it comes from | |---|---|---| | Visit plan | One executive's day: the ordered list of outlets | Generated from the beat's schedule, created manually, or created by a van run | | Visit | One stop: an outlet, a planned position in the day, a status and an outcome | Built from the beat's approved stops when the plan is created | | Task / activity | A unit of work inside a visit: checklist, photo, signature, order, payment… | Expanded from the visit task template attached to the beat or plan | | Order | The commercial result of a productive visit | Captured in the Take Order activity, linked to the visit | ## A day on mobile The **visit-plans hub** is the executive's home screen: the current plan as a hero card, upcoming plans below it, past plans behind them. Opening a plan shows the **agenda** — the stops as a timeline or on a map, switchable between three stop orders: the planned sequence, the road-optimized sequence, and the "Mostly Followed" sequence learned from how the route has actually been driven (see [Optimize a route](/docs/field-sales/routes/optimize-a-route/)). At the outlet, the executive starts the visit — which stamps the time and, where configured, the device location — and works through the activity list. Mandatory activities are marked; a running timer shows the visit in progress. Ending the visit asks for an explicit outcome: **Productive** (which requires the mandatory activities to be done), **Non-productive** or **Cancelled**, the latter two with a reason. That outcome discipline is what makes coverage and strike-rate reporting honest. ## Offline by design Every screen in the flow reads from the data already on the device, and every save — a completed checklist, a captured photo, an order — queues in the device outbox until connectivity returns. Starting and ending visits, completing activities and taking orders all work offline; the queued work syncs in the background and is visible on a pending-changes screen until it lands. The full mechanics are described in [how offline-first mobile works](/docs/concepts/offline-mobile/). ## Common questions ### Do I have to visit outlets in the planned order? No. The sequence is guidance, not a lock — you can open and complete any visit on the plan. The plan agenda even shows you the "Mostly Followed" order learned from actual execution history, precisely because real days deviate from planned ones. What matters for reporting is that every visit ends with an explicit outcome. ### What happens to visits I never reach? They stay open until you cancel them, or until the automatic cleanup does: an administrator can set a margin after which overdue plans lapse and their unfinished visits are cancelled, so stale work does not pile up. See [Visit plans](/docs/field-sales/visit-plans/). ### Where does the order I take go? It is created as a normal sales order, linked to the visit it was captured on. Offline it queues in the outbox first; once synced it is visible to the back office like any other order, and the plan's summary rolls up the day's captured order value. ## Related topics - [Complete a visit](/docs/field-sales/visits/complete-a-visit/) - [Visit plans](/docs/field-sales/visit-plans/) - [Checklists and tasks](/docs/field-sales/checklists-and-tasks/) - [How offline-first mobile works](/docs/concepts/offline-mobile/) ---- # Automatic owner assignment URL: https://xmatix.com/docs/field-service/assignment-rules/ Last reviewed: 2026-09-02 Partner Resource assignment rules can stamp a resource during insert. The active first-party callers are **Lead**, **Opportunity** and **Product Demo**. A helper exists in `QuoteHandler`, but it is not invoked by the Quote save path; Service Order also has no equivalent assignment call. Do not advertise this feature generically for every record that has a resource field. This procedure applies only where your tenant's Partner Resource layout exposes **Assignment Sequence Number**, **Rule Success Criteria** and the **Resource Assignment Rules** child collection. The first-party Partner Resource layouts currently shipped by the platform do not expose those controls. If your tenant has not added them through metadata customization, there is no standard screen to complete this setup; ask the configuration owner to expose and validate the fields before using the steps below. Rules are authored on **partner resources**—the link between a resource and a partner account, optionally narrowed to a branch. When a supported insert carries that partner account and branch, applicable partner resources are ordered by Assignment Sequence Number and evaluated until one matches. Queue-routed work takes a separate path described in [Skills, capacity and work routing](/docs/field-service/skills-and-routing/). ## Prerequisites - Resources for the people who should receive work. - Partner resource records linking each candidate to the partner account (and branch, where assignment should be branch-specific). - Administrator access to edit partner resources and their assignment rules. ## Procedure ### Step 1 — Order the candidates Create or open each partner resource, verify its partner account, optional branch and resource, and assign a **unique** sequence number. Evaluation stops at the first match. Equal sequence numbers have no documented secondary business tie-break, so ties can make the winner database-order dependent. Give specialists lower unique numbers and the fallback the highest unique number. Partner Resource From and To dates are not filtered by this assignment query; do not rely on them to activate or retire a candidate. ### Step 2 — Choose the success criteria The engine recognizes only these exact stored strings: | Criteria | The candidate matches when | |---|---| | `All Rules Are Met` (or an empty value) | Every rule on the candidate passes | | `Any Rule Is Met` | At least one rule passes | | `Always (No Criteria)` | Unconditionally—the catch-all | The shipped Partner Resource picklist currently stores inactive, concatenated variants that do not match those strings. An unrecognized value silently assigns nobody. An empty value enters the all-rules branch, and all/any with no rules still fails. Only use this feature after the configuration owner has exposed the fields and verified the exact stored values through an integration test; place the exact `Always (No Criteria)` fallback last when one is required. ### Step 3 — Write the rules Add each rule with the target record property name, operation and comparison value. The evaluator supports numeric ordering for `double`, `int` and `long`, plus date comparisons. A `decimal` property does **not** enter the numeric branch; it only supports the text-path equals/not-equal behaviour. The field name must resolve on the concrete inserted entity. A misspelled or inapplicable field returns false without a diagnostic fallback. ### Step 4 — Verify with a real record Create a non-production Lead, Opportunity or Product Demo carrying values that deliberately exercise one candidate. Save once and inspect the actual resource field used by that handler. Repeat with boundary, no-match and fallback cases. Include a test for the stored success-criteria value; a label that looks correct in metadata is not sufficient if its stored value differs from the engine string. ## Expected result On the three supported insert paths, a tested exact criteria value and a uniquely ordered matching candidate can stamp the intended resource. Existing records are unchanged. Quote, Service Order, Partner Resource date windows, decimal ordering and inactive/mismatched picklist values are outside that guarantee. ## Common problems If nothing was stamped, first confirm the entity is Lead, Opportunity or Product Demo. Then inspect partner/branch scope, the exact stored success-criteria string, rule field names and supported data types. If the wrong person was stamped, check for a broad earlier candidate and duplicate sequence numbers before changing rule values. ## Common questions ### Do assignment rules re-run when a record is edited? No — assignment happens as the record is created. Changing the record afterwards does not re-trigger the rules; reassignment after creation is a human decision, made on the record or on the [dispatch console](/docs/field-service/dispatch-console/). ### How do assignment rules differ from queue routing? Assignment rules are static stamping: conditions on the record pick an owner from a configured list, once, at creation, with no notion of who is online or how loaded they are. Queue routing is live dispatch: it weighs presence, skills and current load at the moment of routing, and the work arrives as an offer to accept or decline. Use rules for predictable ownership (this partner's records belong to this account manager), routing for shared-pool work. ## Related topics - [Skills, capacity and work routing](/docs/field-service/skills-and-routing/) - [The dispatch console](/docs/field-service/dispatch-console/) - [Configuration reference](/docs/field-service/configuration/) - [Business rules](/docs/customization/business-rules/) — the general record-automation layer ---- # Resource availability and slot holds URL: https://xmatix.com/docs/field-service/availability/ Last reviewed: 2026-09-06 "Is this person free?" is answered by three separate mechanisms in xMatix, and they do not share one engine. **Resource Availability** records hold a person's dated attendance and are what the dispatch console reads. **Branch Time Slots** and their per-date **bookings** are what the web and mobile booking wizards offer and consume. The newer **appointment-scheduling** engine models bookable resources, capacity claims and expiring holds, but no shipped screen calls it yet. This page describes each as it actually behaves, so an administrator knows which record to inspect when an availability outcome looks wrong. ## Dated attendance: Resource Availability A Resource Availability record is one attendance day for one resource: the **Resource**, the **Date**, an **Availability Type**, the branch it belongs to, the check-in and check-out times and branches where they happened, an optional link to the **Leave Request** that caused it, and **Penalty Hours**. The attendance hours and duration on the record are calculated from the punches. Records are created by the mobile check-in flow and by leave processing, and can also be maintained by hand from the list (reached from the **Field Sales** app under **More**). The shipped **Availability Type** values are **Present**, **Leave**, **Weekend**, **Holiday**, **Absent** and **Half Day**. ### How the dispatch console reads it For the selected day the [dispatch console](/docs/field-service/dispatch-console/) loads every Resource Availability row for that date and every Leave Request overlapping it, then classifies each resource: - The availability type is matched by **substring**: anything containing "leave" is leave, "half" is half day, "holiday" is holiday, "week" is week off (which is how *Weekend* is shown as **Week off**). **Any other value — including Absent and any custom value — is treated as present.** - A Leave Request overlapping the day overrides the attendance row and marks the resource on leave **unless its status contains "reject" or "cancel"**. There is no check for an Approved status: a pending leave request already counts as leave. - A resource with no row is inferred **Absent** only when at least one other resource has data that day; on a day with no attendance data at all the console shows no marker rather than painting everyone absent. **Optimize day** and **Get candidates** skip lanes classified leave, holiday or week off. They do **not** skip half day or absent lanes, so review those before accepting an optimized result. Penalty hours are stored on the record but no allocation path reads them. For a dispatch exception, inspect the exact resource, local date, stored availability type and any overlapping leave request's status, then compare with what the Board or Gantt shows. ## Branch time slots: the booking path in use today The **Booking Wizard** widget in the web app and the mobile app books product demos and opportunities into **Branch Time Slots**. A slot belongs to a branch and carries a **Transaction Type** (*Delivery*, *Product Demo At Site* or *Service Appointment*), a start and end time, a **Maximum Capacity**, one capacity per weekday (Monday through Sunday), an **Active** flag, and optional narrowing by item, item group, service type and service job type. A **Branch Time Slot Booking** is the per-date consumption row for one slot: **Booking Date**, **Capacity** and **Capacity Utilized**. How it behaves: - The server returns the slots that match the branch, transaction type, item scope and service type, and are **Active**. A slot whose Active flag was never ticked is stored as empty rather than false and is refused with "The selected time slot is inactive." — tick Active explicitly when creating slots. - **Remaining capacity is calculated in the client.** The wizard takes the weekday capacity (falling back to the maximum capacity when the weekday value is empty) and subtracts the booking row's utilized count. The server does not publish a per-date availability figure. - Confirming a demo or opportunity increments the booking row's **Capacity Utilized**; cancelling or moving it decrements. **The server does not refuse a booking that exceeds capacity** — the number is advisory, and two simultaneous bookings for the last place both succeed. Where a hard limit matters, enforce it operationally and monitor Capacity Utilized against Capacity. - The reservation runs only when the demo or opportunity is **confirmed and not cancelled**; an unconfirmed booking holds nothing. Before publishing a slot, verify its branch, transaction type, times, weekday capacities and that Active is ticked. After a booking, verify the Branch Time Slot Booking row for that date exists and its utilized count moved. ## The appointment-scheduling engine A newer scheduling model exists in the platform: **Appointment Types** (duration, buffers, resource requirements, lead time, advance window, cancellation cutoff, reschedule limit, overbook percentage), **Appointment Slot Templates** released into dated **Appointment Slots**, **Bookable Resources** (a person, asset or facility with a branch, an effective window and a concurrent capacity), **Resource Bookings** (the capacity claims) and **Appointment Holds**. Its records appear in the CRM settings app where the module has been enabled, and its availability and hold endpoints are live in the API. What it enforces when it is called: - **Candidates** for a requirement are bookable resources that are active, of the required kind, inside their effective window, and either organization-wide or in the slot's branch. A person requirement narrowed by skill needs an **active** Resource Skill whose catalog **Skill** name matches — proficiency, skill validity dates and working hours are not applied, and the bookable resource's business-hours reference is stored but read by nothing. - **Capacity** counts overlapping **Hard** resource bookings against the resource's concurrent capacity; soft bookings are ignored. Candidates are offered least-loaded first. A claim spans the appointment plus the type's before and after buffers. - **Holds** take one place on a slot atomically — a full slot refuses the hold — for a configurable lifetime (default 10 minutes), and a sweep expires overdue holds and returns their capacity. What is not yet wired: **no web, mobile or portal screen calls the availability or hold endpoints** — the booking wizards above still use branch time slots — and the hold-to-booking conversion has no caller. So a configured hold duration does not protect any shipped booking flow today, and the engine's tighter checks do not apply to demo and opportunity bookings. When race-free last-slot booking is a requirement, test two simultaneous sessions against the exact flow you deploy. ## Common questions ### Why is a technician still shown on the Gantt when attendance says Absent? Because the console's exclusions are leave, holiday and week off. Absent and Half Day are shown with their own marker but are not excluded, and an unrecognised availability value is classified present. Treat the marker as a warning and move the assignment by hand. ### Why did a pending leave request take someone off the day? Any Leave Request overlapping the day counts as leave unless its status contains "reject" or "cancel". Approval is not required for the console's classification. ### Two people booked the last slot — why did neither get refused? The branch-slot path increments Capacity Utilized without comparing it to Capacity; the remaining figure the wizard shows is computed in the client. Only the newer appointment engine refuses a full slot, and it is not behind the wizard yet. ### Does every booking channel use holds? No. Hold services exist and work when called, but no shipped booking surface calls them. Verify the channel you operate rather than relying on the presence of hold records. ## Related topics - [The dispatch console](/docs/field-service/dispatch-console/) - [Skills, capacity and work routing](/docs/field-service/skills-and-routing/) - [Configuration reference](/docs/field-service/configuration/) - [Troubleshooting field service](/docs/field-service/troubleshooting/) - [The Service module](/docs/service/) ---- # Field service configuration reference URL: https://xmatix.com/docs/field-service/configuration/ Last reviewed: 2026-09-06 Field service allocation runs on a small set of records. This page is the reference for each: where it is maintained, what it holds, and which allocation behaviour reads it — including the fields that are stored but read by nothing yet, so a configured value is never mistaken for an enforced one. ## Where the building blocks live Apart from queues, none of these records has a dedicated Setup screen; they are ordinary entity screens reached from the apps below, and the Setup Copilot or the Data API can maintain them as data. | Record | Where to find it | |---|---| | Resources | **Field Sales** app → **Resources** (also listed in the Payroll and Rewards apps) | | Resource Availability | **Field Sales** app → **More** → **Resource Availabilities** | | Skills, Resource Skills, Skill Lines | **CRM** app → **Settings** → *Skills* tiles | | Resource Groups | **CRM** app → **Settings**; also the Rewards app | | Queues | **CRM** app → **Queues**, or **Setup → Settings → Telephony → Queues** | | Resource Presence | Written by the agent's browser; readable as the Resource Presence entity | | Appointment Types, Bookable Resources, Slot Templates | **CRM** app → **Settings**, where the appointment-scheduling module is enabled | | Service Bays | **Service** app → **Service Bays** | | Dispatch console | A widget placed on an app page by a designer (Field Sales → **Allocation Console** in the shipped model) | | Location tracking | **Setup → Model → Mobile app → Location tracking** tab | ## Resources and skills A **Resource** is the person master: anyone who carries work. The fields allocation reads are **Is Active**, the linked **User** (routing refuses a resource with no user, because accepted work must end in an owner), **Default Branch** and **Default Partner Account** (used to scope the dispatch console), **Business Hours**, **Type** and **Manager**. A **Resource Skill** is one competency held by one resource: a **Name**, an optional link to the **Skill** catalog, a **Proficiency Level**, **Start Date** and **End Date**, and **Is Active**. Three consumers read it differently: | Consumer | What it reads | |---|---| | Queue routing (Skill model) | `Name` equals the requested skill and `Proficiency Level` is at least 1 — nothing else | | Appointment candidate search | `Is Active` and the linked catalog **Skill**'s name — no proficiency, no dates | | Bay and technician allocation | Name, level and the start/end window, scored against the job's **Skill Lines** (the demand side: one skill a job requires at a minimum level) | The **Skill** catalog carries a name, description and a free-text routing **Policy** hint; queue routing does not read the catalog at all. ## Resource groups A **Resource Group** is a named pool with **Resource Group Member** rows. In field service it is the queue's agent pool and one of the dispatch console's scope chips; the same entity is also used by Rewards for incentive groups (**Resource Group Type** *Scheme* or *Incentive*), so keep field-service pools clearly named. ## Queues and presence A **Queue** holds the routing configuration. Administrators maintain queues under **Setup → Settings → Telephony → Queues**; the **New queue** dialog is the whole record: | Field | Meaning | |---|---| | Name, Description | Identification | | Routing model | *Direct*, *Round robin*, *Load balance* (the default when blank) or *Skill-based* — see [work routing](/docs/field-service/skills-and-routing/) | | Channels | The channel types this queue serves (Voice, Email, Chat, SMS, messaging, Web). Recorded on each work item; the route itself does not validate the channel against this list | | Agent pool | The resource group whose members are the candidates | | Active | Feeds membership checks and the supervisor snapshot; the route service does not refuse a route that names an inactive queue, so also stop rules and telephony routes from targeting it | **Resource Presence** is one row per resource, written by the agent's own browser: **Status** (*Available*, *Busy*, *Away*, *Offline* — only Available receives pushed work), a **Status Reason**, and **Max Work Items** (default 5), the load ceiling routing enforces. Presence is a lease renewed every minute; a row not renewed for five minutes is treated as Offline. There is no setup screen for presence; adjust Max Work Items on the record where a resource should carry more or fewer concurrent items. ## Appointment types and bookable resources These records belong to the appointment-scheduling engine described in [Resource availability and slot holds](/docs/field-service/availability/). The engine's API is live, but no shipped web or mobile screen books through it yet, so configure them when you are building on that API and treat the "read by" column as the current truth. An **Appointment Type** defines a bookable kind of work: | Setting | Read by | |---|---| | Default duration (30 minutes), buffer before/after | Availability and the resource claim: buffers extend every claim so back-to-back bookings stay apart | | Resource requirements (JSON: role, kind, skill name, asset category, bay type, count, mandatory) | Candidate search and claiming; malformed JSON reads as no requirements | | Minimum lead time, maximum advance days | The availability query trims what is offered | | Cancellation cutoff, maximum reschedules | Appointment cancel/reschedule validation | | Overbook percent | Applied when slots are released: the allowance is `ceil(capacity × percent / 100)` on each slot | | Auto no-show after (minutes) | The appointment maintenance sweep | | Location modes allowed (Branch, Onsite, Virtual) | Appointment validation | | Requires customer confirmation, reminder offsets, applicable entities | **Stored only — no code reads them yet** | A **Bookable Resource** registers one schedulable unit — exactly one of a person (a Resource), an asset, or a facility (a Service Bay) — with **Kind**, home **Branch** (empty means organization-wide), **Concurrent Capacity** (at least 1), **Is Active** and an effective window. Its **Business Hours** reference is stored but read by nothing; working hours are not applied to candidates. Bay and technician allocation create bookable-resource rows automatically for bays and technicians they allocate, so you will see rows appear without anyone creating them. ## Service bays A **Service Bay** is a physical workshop position. Fields: **Name**, **Branch**, **Service Bay Type** (*Van*, *Plant*, *Workshop*, *Bin*, *Pallet*, *Washing Bay*, *Regular Bay*, *VHC Bay*), **Allow Inventory** (the bay can hold stock), **Is Active**, and the occupancy settings the bay allocator reads: **Allocation Mode** (*Vehicle*, *Labour* or *Both*), **Vehicle Capacity** and **Labour Capacity** (default 1 each), **Auto Release After** (minutes), **Occupancy Stretch Percent** and **Turnaround Minutes**. The type is what an appointment requirement's bay type narrows on. Bay allocation from service orders and time sheets is documented under [Service time sheets](/docs/service/timesheets/). ## The dispatch console The console is the **AllocationConsole** widget, placed on an app page by a designer — one page per work entity. Its design-time properties, by exact name: | Property | Effect | |---|---| | `entity`, `labelField` | The work entity and its display field | | `assignField` | The lookup to the resource that a Board or Gantt drop writes | | `scheduleStartField`, `scheduleTimeField` | The date (and optional separate time) field a Gantt drop and Optimize day set; without `scheduleStartField` drops only reassign and Optimize day does nothing | | `durationField` | Duration in minutes; items without one get a 90-minute block | | `statusField`, `closedStatuses` | Hide items in closed statuses (default: completed, cancelled, closed, expired, rejected) | | `branchField`, `partnerField`, `accountGroupField` | Fields the scope chips filter on | | `geoMode`, `geoPointField`, `geoLookupField`, `geoRelatedEntity`, `geoRelatedPointField` | Location configuration — a coordinate field on the entity, or a lookup to a record that carries one. Without it the Map view is unavailable | | `stopsEntity`, `stopsParentField`, `stopsSequenceField`, `stopsAccountField` | Child stops plotted on the Map | | `views` | Which of `map`, `gantt`, `board` to offer | | `scopeChips` | Which of `partner`, `branch`, `resources`, `resourceGroup`, `accountGroup` to show | | `refreshSeconds` | Auto-refresh interval; values under 5 are ignored | | `itemNoun`, `itemNounPlural`, `title`, `subtitle` | Wording | Live positions come from the location-tracking service, not from the work entity. Operating the console is covered in [The dispatch console](/docs/field-service/dispatch-console/). ## Location tracking Under **Setup → Model → Mobile app**, open the mobile app record and its **Location tracking** tab: | Setting | Default | Meaning | |---|---|---| | Enable location tracking | Off | Off or absent means the app never asks for background location and check-in is not gated on it | | Capture interval | 60 seconds (minimum 30) | How often a fix is recorded while checked in | | Batch size | 20 points (1–200) | Fixes uploaded per request | | Minimum distance | 25 metres (0 reports every fix) | Movement required before a new fix is recorded | Behaviour and the privacy posture are documented in [Location and the travelled path](/docs/field-service/location-and-proof/). ## Automatic assignment Owner-stamping on Lead, Opportunity and Product Demo inserts is configured on **Partner Resource** records — sequence, success criteria and rules — and documented in [Automatic owner assignment](/docs/field-service/assignment-rules/), including the shipped picklist mismatches that stop the criteria from evaluating. ## Common questions ### Why must a resource be linked to a user account? Because allocation ends in ownership, and ownership belongs to users. Routing drops a resource with no linked user before any other check, since work it accepted could never stamp an owner. ### One pool of people, both routing and booking — do I configure them twice? The person is one Resource record, but the engines read different registrations: routing reads resource-group membership, presence and Resource Skill name/level; the appointment engine reads a Bookable Resource with branch, capacity and effective window plus active skills by catalog name; bay allocation reads Skill Lines against Resource Skills with dates. A technician who should be routable, bookable and bay-allocatable needs all three kept in step. ### A field on one of these records has no effect — is it broken? Check the "read by" notes above first. Requires customer confirmation, reminder offsets, applicable entities and the bookable resource's business hours are stored for a later phase and are not enforced today; documenting them as live would be wrong. ## Related topics - [Skills, capacity and work routing](/docs/field-service/skills-and-routing/) - [Resource availability and slot holds](/docs/field-service/availability/) - [The dispatch console](/docs/field-service/dispatch-console/) - [Automatic owner assignment](/docs/field-service/assignment-rules/) - [Location and the travelled path](/docs/field-service/location-and-proof/) - [xMatix administration guide](/docs/administration/) ---- # The dispatch console URL: https://xmatix.com/docs/field-service/dispatch-console/ Last reviewed: 2026-09-06 The dispatch console is one screen for allocating a day's work to resources. Each console page works over one kind of work record — visit plans, cases, service orders and other entities your administrator configures — and offers up to three views of the same allocation problem: a **Board** for who-does-what, a **Gantt** for when, and a **Map** for where. Everything the console does is deterministic: drags write assignments, drops write schedule times, and **Optimize day** fills free slots by fixed rules. Nothing is decided by AI, and every placement can be dragged somewhere else. ## The three views | View | What it shows | What dragging does | |---|---|---| | Board | An unassigned rail plus one column per resource | Drag an item onto a resource to assign it; drag it back to the rail to unassign | | Gantt | An intraday hourly timeline, one lane per resource | Drop onto a lane to assign *and* set the item's date and time from the drop position | | Map | Live resource positions and travelled paths, plus unassigned items as stops on the map | Selection only — use it to see the day, then assign on the Board or Gantt | Above the views sit the scope chips (all resources, or narrowed to a partner, branch, chosen resources, a resource group or an account group), a time window for the items (today, week, month or all), and a collapsible summary strip: resources in scope, how many are **live now** (seen within 15 minutes) and **tracking** (within 60 minutes), how many are **off grid** (no signal for 24 hours), today's items with the unassigned count, and the coverage percentage. When the scope holds more items than the console loads at once, an amber banner says so — narrow the scope rather than dispatching from a subset. An alerts ticker along the bottom calls out unassigned items, stale positions and resources with no recent signal. ## Prerequisites - A console page in your app — an administrator places and configures it per work entity (see the [configuration reference](/docs/field-service/configuration/)). - For the Gantt's scheduling drops, a schedule date-time field configured on the console; without one, drops still reassign but set no time. - For the Map view, a location field configuration on the work entity — without one the Map view is unavailable. Live positions and travelled paths appear where your organization has enabled location tracking (see [Location and the travelled path](/docs/field-service/location-and-proof/)). ## Procedure @[guided-image](_img/dispatch-console.png) ### Step 1 — Scope the console to your patch Open the console page, select the correct work date, and pick a scope chip—your branch, a resource group or a hand-picked set of resources. Wait for the summary strip and Board to recalculate, then verify the resource count, backlog and markers match the patch you intend to dispatch. Stop if an unexpected branch or resource appears; every drag writes a real assignment. Availability markers need careful interpretation. The current resolver treats any leave row whose status is not **Rejected** or **Cancelled** as leave; it is not limited to an Approved status. The optimizer's hard exclusions are leave, holiday and week off. Half-day and absent values are not excluded by the same check, and an unrecognised availability value can fall through to present-like handling. ### Step 2 — Assign on the Board Switch to **Board**, open the unassigned rail and inspect an item's priority, location and required date before moving it. Drag the item onto the intended resource's column and wait until the card settles there; that placement is the visible confirmation that the owner was written. If you moved the wrong item, drag it back to the unassigned rail immediately and confirm its unassigned count increments. A star badge counts resources within 25 km of the item's area based on known location—it is a proximity hint, not an instruction, so availability and skills still require human judgment. ### Step 3 — Schedule on the Gantt @[guided-image](_img/dispatch-console-gantt.png) Switch to **Gantt**, re-check the selected day, and choose the visible window—working hours, an extended day or the full 24 hours. Drop an item onto a resource's lane at the intended start time; the drop position becomes the item's date and time, snapped to 15-minute marks. Verify the card now appears on the correct lane and read its time badge before scheduling the next item. Items whose duration is known stretch across the lane accordingly; items without a duration receive a standard block, so check the underlying record when duration affects travel or capacity. ### Step 4 — Fill the backlog with Optimize day Before using **Optimize day**, verify the visible time window, scoped resources and unassigned queue; those are the boundaries the operation uses. **Get candidates** next to it only suggests the least-loaded available resources without assigning. Run Optimize day once and read the result message before clicking again. The fixed rules skip resources classified as leave, holiday or week off, choose a currently least-loaded lane, place work back-to-back after its last block, snap to 15-minute marks, place at most 20 items per run, and stop when the visible window is full. **Absent and Half Day are not currently automatic exclusions**, so review those lanes before accepting the result. Confirm placed and remaining counts against the Board, then review skill, travel and business constraints manually. ### Step 5 — Watch the day on the Map Switch to **Map** and first read the freshness state—live, recent, stale or off grid—before treating a marker as current. Select resources in the left pane to draw their travelled paths for the day, or switch the pane to plans/items to plot unassigned work as stops. Use this geographic check to spot travel conflicts and field gaps, then return to Board or Gantt to make changes because Map selection itself does not assign. Open an item drawer and verify its owner and scheduled time agree with the placement you made. ## Expected result The scoped backlog, owner assignments and schedule agree across Board, Gantt and each item's detail drawer. The summary shows the revised coverage and unassigned counts, while Map supplies location context without changing ownership. Every optimized placement has been reviewed and any unsuitable slot has been corrected by drag-and-drop. ## Common problems If the Map view is missing entirely, the work entity has no location configuration — that is an administrator setting, not a data problem. If dropping on the Gantt reassigns but never sets a time, no schedule field is configured for this console. If **Optimize day** reports no free slots, the visible window is full for every available lane — widen the window to the extended or full day, or reduce the scope. And if positions are absent or stale, location tracking is either not enabled for your organization or the resources are not currently in a tracked working session. ## Common questions ### Is Optimize day AI-based dispatch? No. It is rule-based slot-filling: lower current load first, back-to-back after the lane's last placed block, and capped per run. Its current availability exclusion covers leave, holiday and week off rather than every attendance value. Every placement is an ordinary assignment a dispatcher can review and move; xMatix does not treat the result as an autonomous verdict. ### Which kinds of work can the console allocate? Any work entity your administrator configures a console for — visit plans, cases, service orders, leads and product demos are typical. Each console page shows one entity's records; an organization that dispatches both cases and service orders runs a console page for each. ### Does the console hide finished work? Yes. Items in closed statuses — completed, cancelled, closed, expired, rejected by default, and your administrator can adjust the list per console — are filtered out, so the rails and lanes only ever show work that still needs a decision. ## Related topics - [Skills, capacity and work routing](/docs/field-service/skills-and-routing/) - [Location and the travelled path](/docs/field-service/location-and-proof/) - [Configuration reference](/docs/field-service/configuration/) - [Visit plans](/docs/field-sales/visit-plans/) - [The Service module](/docs/service/) ---- # xMatix Field Service URL: https://xmatix.com/docs/field-service/ Last reviewed: 2026-09-06 Field service in xMatix addresses a recurring question: *which resource does this work, and when?* This section separates the actual implementation paths: the Allocation Console for manual plan assignment and scheduling, queue routing for presence/capacity offers, dated attendance used by dispatch, branch-slot booking used by current clients, Partner Resource rules used by three insert handlers, and the technician's mobile execution flow. These paths share concepts, but they are not one universally wired availability engine. ## Where Field Service ends and Service begins The work itself — service orders, cases, contracts, SLAs, parts, invoicing — is created and executed through the Service module, and is documented in the [Service section](/docs/service/). Field Service is the allocation layer on top of that machinery: it decides *who* gets a service order, a case or a visit plan and *when*, then follows the technician through the day. When you need to know what a service order contains or how it invoices, read Service; when you need to know how it reached the right technician, read here. One principle holds across every page in this section: **dispatch uses explicit rules, not an autonomous AI verdict**. Routing evaluates stored membership, presence, skill text and capacity, while **Optimize day** fills console lanes with fixed placement rules. Administrators still need to account for current gaps—skill validity dates are not applied by routing, and absent/half-day lanes are not universal optimizer exclusions. A human must review every operational assignment. ## What is in this section | Page | What it covers | |---|---| | [The dispatch console](/docs/field-service/dispatch-console/) | One screen for the day: Map, Gantt and Board views; drag to assign, drop to schedule, Optimize day | | [Skills, capacity and work routing](/docs/field-service/skills-and-routing/) | Queue-based routing: eligibility, the four routing models, accept/decline/transfer/reassign, the supervisor snapshot | | [Resource availability and slot holds](/docs/field-service/availability/) | Dated attendance, current branch-slot booking, newer resource candidates and the limits of hold wiring | | [Automatic owner assignment](/docs/field-service/assignment-rules/) | Partner Resource rules used on Lead, Opportunity and Product Demo inserts, with current metadata caveats | | [The technician's day](/docs/field-service/technician-day/) | The mobile day: check-in, assigned work, checklists, timesheets, check-out | | [Location and the travelled path](/docs/field-service/location-and-proof/) | Live positions and travelled paths where your organization has enabled location tracking | | [Configuration reference](/docs/field-service/configuration/) | Resources, skills, groups, queues, bookable resources, bays, appointment types, console setup | | [Troubleshooting](/docs/field-service/troubleshooting/) | Work not routing, resources not offered, positions not appearing — and what to check | ## Who works where Dispatchers and supervisors use the web console for assigning and scheduling and the routing surfaces for queue backlog and load. Technicians use the mobile app for configured lists, check-in and service execution. Some mobile data is available offline, but start/pause/end work actions normally call the server directly; verify connectivity for those transitions. Administrators configure queues, skills, slots, resources and metadata in setup, with the current wiring limits documented on each page. ## Related topics - [The Service module](/docs/service/) — service orders, cases, contracts and SLAs - [The xMatix mobile app](/docs/mobile/) - [Field Service on the xMatix site](/products/field-service/) — the product overview - [Service network solutions](/solutions/service-networks/) - [See it in a demo](/demo/) ---- # Location and the travelled path URL: https://xmatix.com/docs/field-service/location-and-proof/ Last reviewed: 2026-09-02 Where your organization has enabled location tracking, the mobile app can record positions during the working day, and the [dispatch console's](/docs/field-service/dispatch-console/) Map view presents current-position freshness and travelled paths. Treat that path as operational evidence to compare with visits and attendance—not standalone proof of presence. Device permission, synchronization and server linkage all affect what is retained. Before dispatch, confirm the selected branch resolves to the intended address and that the planned times use the organization's expected timezone. During execution, location or attendance evidence should be collected only under the configured consent, permission and retention policy. Afterward, review exceptions against both the plan and device conditions: missing background permission, an offline sync delay or a paused session can explain a sparse path without proving nonattendance. ## Tracking is organization-controlled Nothing is tracked by default. Location tracking is a setting your organization's administrator turns on deliberately, together with how often a position is captured, how many points are batched per upload, and the minimum movement below which near-duplicate fixes are skipped. When the setting is off — or simply absent — the app does not start any tracking and does not even request background location permission. There is no per-user way to switch tracking on; it is an organizational decision, visible to the people it affects. ## Tracking is session-bound and visible Capture runs only inside a checked-in working session: - It starts at **check-in** — and the check-in screen discloses that the session records location. - **Pausing** the session stops capture; resuming restarts it. Only points captured while actually working belong to the trail. - **Check-out** ends capture for the day. While the trail is being recorded, the device asks for location permission through the standard system prompts and shows the tracking state. The current permission flow requires the configured background/**Always** permission for tracked check-in and deliberately blocks the check-in until it is granted. It does not reliably degrade to a foreground-only tracked session. If an organization enables this feature, publish that operational requirement before the field day begins and provide a support path for devices whose platform policy cannot grant it. ## What is recorded, and who can read it Each captured point carries position, accuracy, speed, heading and a timestamp. Points can be batched on the device and uploaded after connectivity returns. However, the ingest contract accepts a point whose `CheckInPunchId` is absent. The mobile client normally bounds capture to session state, but the server does not fully enforce “every point belongs to a check-in” as an invariant. Investigations should compare the point's resource/time with attendance rather than relying on that optional link alone. Reading is scoped the way record access is scoped: you can read your own trail, and managers can read trails widened by the role hierarchy described in [the security model](/docs/concepts/security-model/). The map reads current positions, a resource path over a time range and a path associated with a visit plan; long paths may be downsampled for display. New position rows are stamped with a retention horizon of 90 days. The audited code does not include a dedicated location-point sweeper that guarantees physical deletion at that horizon. Administrators must therefore monitor the actual retention job or database process in their deployment and must not describe the stamped date alone as verified deletion. ## Common questions ### Is my location tracked whenever the app is installed? The mobile client is designed to start and stop capture with a working session, but the server accepts points without a session identifier. Organization enablement and the required platform permission are still prerequisites for the normal client flow. Treat client behaviour and server validation as separate controls. ### What happens if I deny the location permission? In the current tracked check-in flow, missing background/**Always** permission can block check-in. Follow the device prompt and the organization's consent policy, or contact the administrator; do not promise a foreground-only fallback that the current flow does not implement. ### Who can see where I have been? Yourself, and your management line — access follows the role hierarchy your organization already uses for record ownership, not a separate list. Dispatchers see your position and path on the console only when you fall inside their hierarchy scope. ### How current is the position on the dispatch map? As current as the last uploaded batch. The console labels each resource's freshness — live, recent, stale, or off grid — rather than pretending every dot is real-time, and the capture interval and batch size are organization settings, so freshness reflects your organization's configuration. ## Related topics - [The dispatch console](/docs/field-service/dispatch-console/) - [The technician's day](/docs/field-service/technician-day/) - [The security model](/docs/concepts/security-model/) - [Attendance](/docs/field-sales/attendance/) — the check-in session the trail lives in - [Configuration reference](/docs/field-service/configuration/) ---- # Skills, capacity and work routing URL: https://xmatix.com/docs/field-service/skills-and-routing/ Last reviewed: 2026-09-06 Work routing pushes a queued record — most commonly a case, but also an inbound call or any record a business rule asks to route — to one resource without a dispatcher dragging it. The **queue** names a resource group (the agent pool) and a routing model; the routing service builds the eligible pool from that group, creates a work item (a **Resource Work** record) for the resource it picks, and leaves the item **Pending** when nobody qualifies. The dispatch console, by contrast, is a human placing work by hand — see [The dispatch console](/docs/field-service/dispatch-console/). ## Where routing is configured Queues are ordinary records. Operators see them in the **CRM** app under **Queues**; administrators also maintain them under **Setup → Settings → Telephony → Queues**, where the **New queue** dialog asks for a name, description, routing model, the channels the queue serves and its agent pool (a resource group). The **Active** switch feeds membership checks and the supervisor snapshot, but the route service itself does not refuse a route that names an inactive queue — deactivate a queue *and* stop pointing rules and telephony routes at it. The case-centric view of the same service is on [Queues and omni-channel routing](/docs/support/queues-and-routing/). @[guided-image](_img/routing-queue-list.png) Three things start a route: - The **Route Case** action on a case, which uses the case's own **Queue** (or a queue passed to the action), the case source as channel, and an optional skill name. - A business rule that raises the **Routing requested** event on any entity — the rule supplies the queue, an optional channel, skill and direct resource; a record with no queue and no direct resource is skipped, with a log line, rather than routed nowhere. - An inbound voice call whose telephony route targets a queue (see [Inbound routing](/docs/engagement/inbound-routing/)). ## The eligibility ladder For every route through a queue, a candidate must pass these checks in order; the first empty result leaves the item Pending: 1. **Membership** — the resource is a member of the queue's resource group. 2. **Identity** — the resource is active and linked to a user account, so accepted work can be owned by that user. 3. **Presence** — the resource's presence is **Available** *and* its presence lease is live. Presence is a lease, not a latch: the agent's browser publishes it and renews it every minute; a row not renewed for five minutes reads as **Offline** even if it still says Available. A presence row with no timestamp (seeded or legacy data) always counts as live. 4. **Skill — only on a Skill-model queue, and only when the route names a skill.** A Resource Skill row must have exactly that `Name` and a `ProficiencyLevel` of at least 1. On Direct, Round robin and Load balance queues the skill argument is ignored. 5. **Capacity** — the resource's current open load plus this item's weight must fit within the **Max work items** on its presence record (default 5). Load is the sum of the weights of its **Assigned** and **Accepted** items; every route today carries a weight of 1, so in practice this is a count of open items. The skill check is narrower than the Resource Skill record suggests. It reads only `Name` and `ProficiencyLevel`; it does not consult `SkillId`, `IsActive`, `StartDate` or `EndDate`, and it never compares against a work-specific required level. Keep those fields accurate for governance, but test the route with the exact name string the work supplies — a renamed, expired or inactive certification can still match if its stored name and proficiency satisfy the predicate. When no candidate passes, the item stays Pending for a pull or a supervisor action. That is preferable to silently assigning work to an ineligible user, but it means someone must watch queue backlog and presence. ## Routing models | Model | What the service does | |---|---| | Direct | Honoured when the route names a resource: the item is assigned straight to that resource with no eligibility checks. A queue set to Direct whose route names nobody is selected least-loaded, exactly like Load balance. | | Round robin | Among eligible resources, the one that was pushed work least recently. | | Load balance | Among eligible resources, the one with the lowest current open load. This is also the fallback when a queue has no model set. | | Skill | Applies the name/proficiency predicate above, then picks the least-loaded of the remainder. | Ties are broken by the resource's internal identifier, not by any business priority. Do not read a stable winner between two equal candidates as a configured preference. ## Accept, decline, transfer and reassign - **Accept** marks the item Accepted and, for a case, stamps the case's assignee and record owner to the accepting resource's user. Routing itself never touches ownership — only acceptance does. - **Decline** closes the offer and routes again through the same queue, excluding the decliner — but the repeat route carries **no required skill**, so on a Skill queue the second offer can go to someone without the skill. - **Transfer to a resource** creates an Assigned item for the named resource directly, with no membership, presence, skill or capacity check. **Transfer to a queue** routes through that queue, again with no required skill. - **Reassign** (the supervisor action) re-points the item to the named resource and resets it to Assigned, with no eligibility check at all. Treat transfer and reassign as deliberate human overrides: check the target's presence, skill evidence and load yourself, because the server does not. ## Supervisor checks The supervisor snapshot lists every active queue with its pending backlog and every resource's *effective* presence (an expired lease shows Offline), maximum work items and open load. When work is stuck, compare that snapshot with the queue's group membership, each member's user linkage, and — on a Skill queue — the exact skill-name text. For a declined or transferred item, remember the re-route dropped the skill filter. ## Common questions ### Why did nobody receive the work? No resource passed the ladder at that moment. Check membership and user linkage first, then whether anyone's presence is Available with a fresh heartbeat, then the exact skill-name match on a Skill queue, then load against Max work items. The item is Pending, not lost. ### Does an active, date-valid Resource Skill guarantee routing eligibility? No. The predicate reads the name and whether proficiency is at least 1; the active flag and validity dates are not consulted. Conversely, an administratively expired row can still satisfy it. ### Can a supervisor assign work to someone who is offline or missing the skill? Yes. Reassign and transfer-to-resource are overrides and do not run the ladder. That flexibility is intentional; the supervisor owns the check. ### Can records other than cases be routed? Yes — any entity a business rule raises the Routing requested event for, and inbound calls. The work item links to the record; only case acceptance carries the extra owner-stamping behaviour. ## Related topics - [Queues and omni-channel routing](/docs/support/queues-and-routing/) - [The dispatch console](/docs/field-service/dispatch-console/) - [Automatic owner assignment](/docs/field-service/assignment-rules/) - [Resource availability and slot holds](/docs/field-service/availability/) - [Configuration reference](/docs/field-service/configuration/) - [The Service module](/docs/service/) ---- # The technician's day URL: https://xmatix.com/docs/field-service/technician-day/ Last reviewed: 2026-09-06 The technician's day runs in the xMatix mobile app. Its lists and forms are metadata-driven, so what a given organization's technician sees is the layout its administrator configured; this page describes the platform behaviour underneath — what synchronizes offline, what needs the server, and where work time is actually recorded — without claiming a particular screen. ## Before leaving coverage Synchronize while online and confirm the device holds the jobs expected for the day. Open each job rather than trusting the list title and check its customer or site, address, asset, planned time, instructions, parts and any checklist or evidence requirement. If a dispatcher has reassigned or rescheduled work, synchronize again before travelling. Service orders reach a technician through explicit ownership, a [dispatch console](/docs/field-service/dispatch-console/) assignment, a visit plan or another configured process. They are **not** assigned by the Partner Resource rules — those run only on Lead, Opportunity and Product Demo inserts (see [Automatic owner assignment](/docs/field-service/assignment-rules/)) — so a missing service order is a dispatch question, not a rule question. ## Check-in and the working session Where attendance is enabled, **check-in** starts the working session and **check-out** ends it. Punches are recorded against the technician's own resource and can be captured offline: the app keeps a dedicated punch queue and replays it in order when the network returns, marking replayed punches as taken offline. **Pause** is available when the organization allows it; it freezes the session timer and stops location capture on the device, but there is no server-side pause punch — the session keeps its single check-in. If the organization has enabled [location tracking](/docs/field-service/location-and-proof/), the app asks for background ("Always") location permission and **blocks check-in until it is granted**; there is no foreground-only fallback. Location points are uploaded in batches and may carry the check-in they belong to, but the server accepts a batch without one, so administrators correlating a travelled path with attendance should match on resource and time rather than on that link alone. ## Work execution: the time sheet Work time is recorded on the **service order time sheet**, not on the service order header: 1. On the service order, **Create Time Sheet** creates one time sheet with a line per selected *Work Item* order line (parts lines are skipped) and stamps the technician from the order. 2. On the time sheet, tick the lines being worked and use **Start**. Starting stamps the server's clock as the work start; a date cannot be supplied from the device. 3. **Pause** closes the current segment and requires a **Pause Reason** when the work is set to Paused. 4. There is no separate Resume: **Start** again opens a new segment on the same line and marks the previous one as superseded; paused time is the gap between segments. 5. **End** closes the line. A line that has ended cannot be started again, and a line that is running cannot be started twice. Each stage re-derives the sheet header and the parent service order's **Is Work Started**, **Is Work Paused** and **Is Work Ended** flags from *all* of the sheet's lines, so the order shows work ended only when every line has ended. Bay allocation (**Get Bay Candidates**, **Allocate Bays**) also runs from the time sheet where the workshop uses bays. **These actions are online-only.** The mobile app sends server actions directly and refreshes the record afterwards; unlike record edits, they are not queued for later replay. If connectivity is unavailable when a stage must be recorded, keep the job open, note the actual time by local procedure, and run the action once connected — the timestamp will be the server's time at that moment, so escalate rather than backfilling an invented start. Checklist results, parts and customer evidence belong to the service order or visit the organization configured; confirm the correct line or task before entering them, especially when one order carries several operations. ## What works offline Record creates, edits, deletes and file uploads made in the app are stored locally and forwarded when the network returns, with a **Pending changes** screen showing what is queued, in flight, retrying, or rejected by the server. Attendance punches use their own queue as described above. Server actions — the time-sheet stages, bay allocation and any other action button — need a live connection. A local edit is not complete until synchronization and a subsequent refresh show the server's version. ## End-of-day reconciliation Before check-out: 1. Reconnect and synchronize; clear anything rejected on the Pending changes screen against the source record rather than by re-creating it. 2. Reopen each completed job and verify the time sheet's segments, pause reasons, work status, parts, checklist completion and evidence. 3. Confirm no time-sheet line is still running. 4. Check out and verify the attendance session closed. If the device was offline during work, compare the recorded timestamps with the actual chronology and escalate missing stages instead of inventing times. ## Common questions ### Is every service action offline-safe? No. Record edits and uploads are; server actions — including the time-sheet Start, Pause and End — are not. Treat them as online-dependent unless the exact deployed form has been tested otherwise. ### Where is "Resume"? Use **Start** again on the paused line. It opens a new work segment; the paused interval is computed as the gap between the two segments. ### Do Start and End create the time sheet? No. **Create Time Sheet** on the service order creates it (one line per Work Item line). Start, Pause and End then move the selected lines through their stages; the order's work flags follow the lines. ### Can queue-routed work be declined? An offered routing item can be declined and is re-routed to someone else. Work a dispatcher assigned directly is not an offer and has no decline; coordinate reassignment with dispatch. Note that a decline re-route drops the original required skill, as described in [Skills, capacity and work routing](/docs/field-service/skills-and-routing/). ## Related topics - [The Service module](/docs/service/) - [Service time sheets](/docs/service/timesheets/) - [The xMatix mobile app](/docs/mobile/) - [How offline-first mobile works](/docs/concepts/offline-mobile/) - [Attendance](/docs/field-sales/attendance/) - [Location and the travelled path](/docs/field-service/location-and-proof/) ---- # Troubleshooting field service URL: https://xmatix.com/docs/field-service/troubleshooting/ Last reviewed: 2026-09-06 Every field-service outcome is decided by a small predicate over stored records. This page lists, per symptom, the exact checks in the order the platform applies them — so a diagnosis reads the deciding record rather than guessing from a screenshot. It stays text-only on purpose: a generic list view does not show why routing, booking or location failed. ## Queued work stays Pending The route applies these gates in order and stops at the first that empties the pool: 1. The queue's **Agent pool** (resource group) contains the expected resource. 2. The Resource is **Active** and has a linked **User**. 3. The resource's presence is **Available** *and* fresh — renewed within the last five minutes. A browser that closed without going offline leaves an Available row that expires and reads as Offline; the supervisor snapshot shows the effective status. 4. On a **Skill-based** queue only, and only when the route supplied a skill: a Resource Skill with exactly that `Name` and `Proficiency Level` of at least 1. `Skill Id`, `Is Active`, `Start Date` and `End Date` are not consulted. On other models the skill argument is ignored. 5. Open load (Assigned plus Accepted items) plus 1 fits within the presence record's **Max Work Items** (default 5). Also check: an inactive queue is not refused by the route service, so a rule or telephony route still pointing at it keeps producing Pending items; a decline or transfer-to-queue re-routes **without** the original skill; supervisor reassign and transfer-to-resource skip every gate. Ties between equal candidates are broken by internal id — do not read a documented priority into the winner. Record queue, item, candidates, presence timestamp and load at the same moment. ## A booking slot or candidate is missing First identify the path the screen uses: - The web and mobile **Booking Wizard** (product demos, opportunities) reads **Branch Time Slots** and **Branch Time Slot Bookings** and computes remaining capacity in the client. - The **appointment-scheduling API** (bookable resources, appointment slots, holds) is called by no shipped screen yet. For a missing **branch slot**: the slot must be **Active** (an unticked Active flag is stored empty and refused as inactive), on the right branch, with the exact **Transaction Type** the wizard asks for, and any item, item-group, service-type or service-job-type scope must match. Remaining capacity is the weekday capacity (or Maximum Capacity when the weekday is empty) minus the booking row's **Capacity Utilized**. The server never refuses an over-capacity reservation, so two bookings for the last place both succeed; reproduce a last-slot race on the exact channel before claiming otherwise. For a missing **appointment candidate**: the bookable resource must be active, of the requested kind, inside its effective window, and either branch-less or on the slot's branch; a person requirement with a skill needs an **active** Resource Skill whose catalog Skill name matches (no proficiency, no dates, no working hours). Capacity counts overlapping **Hard** resource bookings — including the type's buffers — against Concurrent Capacity. Holds refuse a full slot and expire after the configured lifetime (default 10 minutes), but hold-to-booking conversion has no caller. ## Dispatch console availability looks wrong The console classifies each resource for the selected day from Resource Availability plus Leave Requests: - Availability type is matched by substring: "leave", "half", "holiday", "week" (*Weekend* shows as Week off). **Anything else — including Absent — is classified present.** - Any Leave Request overlapping the day marks the resource on leave unless its status contains "reject" or "cancel"; approval is not required. - A resource with no row is inferred Absent only when someone else has data that day; otherwise no marker is shown. - **Optimize day** and **Get candidates** skip leave, holiday and week-off lanes only — not half day or absent. Compare the resource, local date, stored availability type and overlapping leave status. If a lane should not receive work, move the assignment by hand and correct the source record; the optimizer is a placement helper, not an attendance boundary. If Gantt drops reassign but never set a time, the console has no `scheduleStartField` configured. If Optimize day places nothing, the visible window is full on every available lane, or there is no unassigned work in scope. If a card shows a 90-minute block for everything, the console has no duration field. ## The dispatch map is empty or stale Check in this order: 1. The console has a location configuration (`geoMode` with its fields); without it the Map view is not offered at all. 2. Location tracking is **enabled** in the mobile app settings; off or absent means the app never captures. 3. The technician granted background ("Always") location permission — without it check-in itself is blocked — and is checked in and not paused. 4. The device has synchronized: read the last upload time and the freshness badge (live within 15 minutes, tracking within 60, off grid after 24 hours). Points may arrive without a check-in reference, so correlate with attendance by resource and time. Points are stamped with a 90-day purge date, but the retention sweep only purges soft-deleted rows and location points are never soft-deleted — verify your deployment's actual purge process before promising a retention period. ## A time-sheet stage is refused or the order's work flags look wrong Work stages live on the **service order time sheet**, not the order: **Start**, **Pause** (needs a pause reason) and **End** on selected lines. The legal order per line is Start → (Pause → Start)* → End; "already started", "already ended" and "cannot end before start" are the rejections. The service order's Is Work Started / Paused / Ended flags are derived from *all* lines on the sheet, so one unfinished line keeps the order out of Work Ended. The `StartWork`, `PauseWork` and `EndWork` actions declared on the service order itself have no server implementation and fail if invoked — use the time-sheet actions. Stages are online-only server actions; a device that was offline cannot backfill a start time. ## A new record did not receive a Partner Resource Only **Lead**, **Opportunity** and **Product Demo** inserts run the rule service; Quote and Service Order do not. For a supported insert, check: 1. Partner Account and Branch scope on the record match a Partner Resource (branch-less resources match any branch). 2. A unique **Assignment Sequence Number** per candidate; the lowest matching wins. 3. The exact stored **Rule Success Criteria** text: `All Rules Are Met` (also the meaning of an empty value), `Any Rule Is Met` or `Always (No Criteria)`. Any other value silently skips that resource. All-rules and any-rules with **no rules** both fail. 4. Rule field names resolve on the inserted entity's own properties; an unresolved name evaluates false. 5. The rule's stored **Operation** is one of `equals`, `notEqual`, `lessThan`, `greaterThan`, `lessOrEqual`, `greaterOrEqual`. The shipped Operation picklist offers only `Equal`, which the engine does not recognise — so with shipped metadata a criteria-based rule can never succeed, and the Rule Success Criteria picklist stores inactive concatenated values (`AllRulesAreMet`) that also do not match. 6. Numeric ordering works for `double`, `int` and `long` properties only; `decimal` fields support equals/not-equal by text. Until the picklists are corrected in your tenant, the working configuration is a Partner Resource whose stored criteria text is exactly `Always (No Criteria)`, placed last by sequence as the fallback. ## What to capture for escalation Capture, as text or an authorized export: the entity and document id, timestamp and timezone, partner and branch, expected and actual resource, queue and routing model, each candidate's presence status and timestamp, load and Max Work Items, the exact skill-name value, availability date, type and leave status, console scope and window, last location upload time, and for time sheets the line ids and their current stage. A workspace screenshot rarely contains the predicate that decided the result. ## Related topics - [Skills, capacity and work routing](/docs/field-service/skills-and-routing/) - [Resource availability and slot holds](/docs/field-service/availability/) - [The dispatch console](/docs/field-service/dispatch-console/) - [Automatic owner assignment](/docs/field-service/assignment-rules/) - [The technician's day](/docs/field-service/technician-day/) - [Location and the travelled path](/docs/field-service/location-and-proof/) ---- # Reconciling a bank account URL: https://xmatix.com/docs/finance/banking/bank-reconciliation/ Last reviewed: 2026-08-31 Bank reconciliation compares an imported statement with posted journal lines on the bank account's linked GL account. xMatix can rank eligible ledger lines and, when an active rule explicitly enables auto-match, confirm an unambiguous top result. Treat the result as an accounting control: verify the source statement, every confirmed pair and the remaining bank-to-book residual rather than relying on a confidence badge alone. ## Prerequisites - A [bank account](/docs/finance/banking/) master linked to its GL account — an account with no GL link cannot reconcile. - The period's bank statement imported, with its lines. - The period's payments, transfers and journals posted — reconciliation matches against *posted* ledger lines only. ## Procedure @[guided-image](_img/new-bank-reconciliation.png) This image is deliberately limited to the new-record header. It proves which fields establish a reconciliation—name, company, bank account, statement and balance fields—but it does not pretend that a blank form is a populated match workspace. ### Step 1 — Open the match workspace Create a reconciliation with a name that identifies the account and statement period, then select the partner account, bank account and imported statement. Before saving, compare the statement identity and closing balance with the source bank file; choosing the wrong statement makes every later comparison meaningless. After opening the saved workspace, verify that its account card and statement-line counts belong to the selected account. Account availability is scoped by partner/branch and requires an active master linked to a GL account classified as **Bank**. ### Step 2 — Understand the rule gates before requesting suggestions Rules are either specific to the selected bank account or global. If at least one account-specific rule exists, global rules are not mixed in. Active rules run in sequence as a cascade: every enabled criterion on a rule is a hard gate, and each later rule narrows the survivors of the earlier rule. Supported criteria are amount, date, reference, transaction direction and document number; tolerances apply to amount and date. With no applicable rule, the current built-in policy requires all of these conditions: signed amount within 100 currency units, date within five days, overlapping statement-reference/ledger-narration text, and the same debit/credit direction. It does not auto-confirm. This is intentionally more precise than calling the fallback an “exact amount” heuristic. An active rule with **Auto Match** enabled can confirm only when its surviving top candidate is unique or strictly outscores the runner-up. Inspect every such result after it appears; auto-match changes data and a scoring lead is not independent proof of identity. ### Step 3 — Review suggested matches Open one unmatched statement line and read its date, signed amount, narration and reference before reviewing candidates. Eligible candidates are posted journal lines on the linked bank GL account that have not already been used by a reconciliation match for that bank account. The service scores each survivor as `100 − (date gap × 10) + 25 when references overlap`; the UI maps 125 or more to **Exact**, 100–124 to **Best**, and lower scores to **Possible**. Open the source journal or originating business record when references are ambiguous. These labels rank candidates; they do not prove that two records represent the same transaction. ### Step 4 — Confirm the match Select the candidate whose direction, amount, date and reference establish the same transaction, then confirm it. The server records the full signed statement amount in the match and changes the statement line to **Matched**; it does not currently persist a partial applied amount from the suggestion card. Verify the match record and counts after the action completes. Do not rely on an **Unmatch** instruction in this release. The checked-in match panel contains a legacy unmatch path aimed at `BankingTransaction`, while the bank-reconciliation server handler exposes suggest, confirm, account, detail and summary actions only. If a match is wrong, escalate it through your approved data-correction process until an implemented reversal action is available; do not create an offsetting fake match. ### Step 5 — Handle what the books never saw For a statement line with no genuine ledger counterpart—bank charges, interest credited or a direct debit—use the match panel's posting path to create the draft journal, complete its contra account and narration, and post it. Suggestions scan posted journals only, so the draft cannot become a candidate until posting succeeds. Return to the statement line and confirm the newly posted journal deliberately. The visible **Ignore** control updates the statement line to **Ignored**, which is useful for filtering a proven duplicate. However, the detailed reconciliation calculation currently treats any statement line without a `ReconciliationMatch` as unmatched even if its workflow status says Ignored. Do not use Ignore as a shortcut to a fully reconciled result, and do not ignore a legitimate timing difference or missing book entry. ### Step 6 — Close the session at zero Review the detailed result after the final line. It calculates the ledger closing balance from all posted lines on the linked GL account, compares it with the statement closing balance, verifies the statement's own opening-plus-movement arithmetic, and counts unmatched lines on both sides. Treat the account as reconciled only when the difference is zero, every statement line has a match, no eligible ledger line remains unmatched and the statement arithmetic agrees. If that state cannot be reached, do not force it—locate the unposted, duplicated, wrongly linked or missing record. ## Expected result The reconciliation has a zero bank-to-book difference, statement arithmetic agrees, every statement line has a match record and no eligible posted ledger line remains unmatched. Newly discovered bank events have traceable posted journals rather than undocumented adjustments. ## Common problems **A payment I know exists is not suggested.** Either it has not posted (only posted lines are candidates), it was already matched to another statement line, or it falls outside the matching rule's amount or date tolerance. Check its posting status first, then widen the rule or match it manually. **The difference will not reach zero.** Work the outstanding lists: bank-side leftovers are usually charges or interest needing a posting (Step 5); book-side leftovers are usually cheques not yet presented or deposits in transit — genuinely outstanding items that will clear on a future statement. **No candidate appears.** Check the bank master has a linked GL account, the expected journal is Posted, the ledger line has not already been matched, and each active rule gate passes. Under the fallback, missing reference overlap alone is enough to exclude a candidate. **Nothing was auto-confirmed.** Auto-match is off in the fallback policy. A configured rule must enable it, and its top survivor must be unique or strictly outscore the runner-up. ## Common questions ### What makes a suggestion "Exact"? It is a score bucket, not a proof standard. A score of 125 or more is labelled Exact, 100–124 is Best, and anything lower is Possible. The score comes from date proximity plus a 25-point reference-overlap bonus after rule gates have already removed ineligible candidates. ### Can I undo a confirmed match? Not through a supported bank-reconciliation server action in the current implementation. The UI's dormant legacy path must not be treated as an available accounting correction. Escalate an incorrect match through the approved operational support/data-correction process and retain the reason. ### How often should we reconcile? As often as you import statements — monthly at minimum, since completed bank reconciliations are one of the advisory checks in the [period close](/docs/finance/period-close/). Teams that import weekly or daily keep the unmatched list short enough that exceptions surface while the trail is still warm. ## Related topics - [Banking](/docs/finance/banking/) - [Recording and applying payments](/docs/finance/payments/) - [Closing a period](/docs/finance/period-close/) ---- # Bank statements and statement lines URL: https://xmatix.com/docs/finance/banking/bank-statements/ Last reviewed: 2026-10-10 A bank statement in xMatix is your copy of what the bank says happened in one of your accounts, and its statement lines are the individual deposits and withdrawals on it. You record them after the [bank account](/docs/finance/banking/) master exists and before you [reconcile the account](/docs/finance/banking/bank-reconciliation/): reconciliation pairs each statement line with a posted ledger line on the bank account's GL account. ## Overview Each **Bank Statement** belongs to one bank account and one statement date. It holds the opening balance and a closing balance, and its **Statement Lines** tab lists the **Bank Statement Line** records. Each line is one bank transaction with a transaction date, a description, the bank's reference, and either a deposit or a withdrawal. Every line carries a **Reconciliation Status** of Unmatched, Matched or Ignored. New and imported lines start as Unmatched, and they change only through reconciliation or a manual edit. ## When to use it - Each time you receive a statement for a bank account you reconcile in xMatix: monthly at minimum, or weekly or daily for busy accounts. - When you need to add a single transaction the bank reported that is missing from an imported file. - When you need to correct a mis-keyed amount, date or reference before you reconcile. ## How xMatix handles it - **One statement per account per date.** A second statement for the same bank account with the same statement date is refused. - **Statements chain together.** If you enter an opening balance, it must equal the closing balance of the account's most recent earlier statement. Otherwise the save is refused. - **The closing balance is calculated.** **Closing Balance** is a calculated field: the opening balance plus the deposits of all the statement's lines, minus their withdrawals. - **A line's amount is signed.** Reconciliation works with deposit minus withdrawal. A deposit pairs with a debit on the bank's GL account, and a withdrawal pairs with a credit. - **Lines are not matched when you create them.** Entering or importing a line pairs it with nothing. Matching is a separate step in [bank reconciliation](/docs/finance/banking/bank-reconciliation/). ## Prerequisites - An active [bank account](/docs/finance/banking/) master. Statements can only be created for active bank accounts. Reconciliation also needs the account to be linked to a GL account. - The statement from your bank, as a document or a spreadsheet, for the period you are recording. - Permission to create bank statements and statement lines (see [Permissions](#permissions)). ## Procedure ### Step 1 — Create the statement Open the bank account, go to its **Bank Statements** tab and choose **New**. Fill in: - **Name**: a unique name such as the account and period. - **Bank Account**: only active bank accounts are offered. - **Statement Date**: the as-at date printed on the bank's statement. A future date is refused. - **Opening Balance**: the bank's opening figure. Save. The statement's **Status** is set to **Imported**. ### Step 2 — Add the statement lines On the saved statement, open the **Statement Lines** tab. Add lines in one of two ways: - **One at a time.** Choose **New** and fill in **Name**, **Transaction Date**, **Deposit** or **Withdrawal**, **Reference** and **Description**. The **Bank Statement** field links the line to its statement. - **In bulk.** Choose **Import**. The **Import Bank Statement Lines** window opens. Pick a **List View**, then choose **Download Format** to get an Excel template whose columns follow that view. Fill in one row per transaction and upload the file. Lines imported from a statement's tab are linked to that statement automatically. Each new line has the status **Unmatched**. ### Step 3 — Check the balances against the bank Open the statement's **Details** tab and compare its **Closing Balance** with the closing balance printed on the bank's statement. Because the closing balance is calculated from the lines, a difference means a line is missing, duplicated, or has the wrong amount or direction. Fix the lines before you start reconciling. ### Step 4 — Correct a line Open the line, or use **Edit** on its row in the **Statement Lines** list. Change the date, amount, reference or description, then save. Correct lines **before** they are matched, because a confirmed match records the line's signed amount at the moment you confirm it. ### Step 5 — Reconcile the lines Open [bank reconciliation](/docs/finance/banking/bank-reconciliation/) for the account and statement. Only lines with status **Unmatched** get match suggestions. When you confirm a match, xMatix records it and sets the line to **Matched**. **Ignore** sets a line to **Ignored**. However, the reconciliation result still counts an ignored line as unmatched, so use Ignore only to filter out a proven duplicate. ### Step 6 — Delete a line or a statement To remove a line, delete the line record. This needs delete access to **Bank Statement Line**. Deleting a statement does **not** delete its lines. Delete the lines first if you want them gone, or they stay in the system with no statement shown. ## Fields ### Bank Statement Line | Field | What it means | Notes | |---|---|---| | Name | The line's identifier. | Required and unique across **all** statement lines, not just this statement. When importing, build it from the statement and a line number so that it never repeats. | | Transaction Date | The bank's value date for the transaction. | Reconciliation compares it with the journal date. A smaller gap ranks a candidate higher. | | Bank Statement | The statement this line belongs to. | Filled in for you when you add or import lines from the statement's **Statement Lines** tab. | | Owner | The user who owns the record. | Required. | | Deposit | Money into the account, per the bank. | Fill in either Deposit or Withdrawal. Enter amounts as positive numbers. | | Withdrawal | Money out of the account, per the bank. | The signed amount is deposit minus withdrawal, so a withdrawal is negative. | | Reference | The bank's reference for the transaction. | Matching compares it with the journal line's narration and the journal's voucher number. Partial overlap in either direction counts, so very short references can overlap unrelated entries. | | Label | An optional display label. | Not used by matching. | | Reconciliation Status | Unmatched, Matched or Ignored. | Defaults to Unmatched. Confirming a match sets Matched, and **Ignore** sets Ignored. It is not reset when a match is removed (see [Common problems](#common-problems)). | | Description | The bank's narration for the transaction. | For your reference. Matching uses Reference, not Description. | ### Bank Statement | Field | What it means | Notes | |---|---|---| | Name | The statement's identifier. | Required and unique. | | Bank Account | The account the statement reports. | Required. Only active bank accounts are offered. | | Statement Date | The as-at date of the statement. | Required. Must not be in the future, and only one statement per bank account per date is allowed. | | Opening Balance | The bank's opening balance. | When entered, it must equal the closing balance of the latest earlier statement for the same account. | | Closing Balance | The balance at the end of the statement. | Calculated as opening balance plus deposits minus withdrawals of the lines. | | Status | The import status. | Always **Imported**. It does not show reconciliation progress. Use the line statuses or the reconciliation result for that. | | Label | An optional display label. | | ## Business rules - **Duplicate statement.** Saving a statement whose bank account and statement date match an existing statement is refused with "A bank statement for this bank account and date already exists." - **Opening balance chain.** The opening balance is checked against the closing balance of the account's latest statement dated strictly earlier. The check is skipped when the opening balance is blank or there is no earlier statement. - **Future dates.** A statement date later than today is refused with "Future-date is not allowed." - **Closing balance.** The closing balance is calculated as (Opening Balance) + sum of (Deposit − Withdrawal) over the statement's lines. - **Line status.** New lines default to Unmatched. Only confirming a match sets Matched, and only the **Ignore** button sets Ignored. Nothing sets a line back to Unmatched automatically. - **No checks on line amounts.** xMatix does not stop a line from having both a deposit and a withdrawal, or negative amounts. Keep one positive amount per line so the direction is unambiguous. - **Deleting.** Deleting a statement does not delete its lines. ## Example On 1 October your finance assistant receives the September statement for the operating current account. It shows an opening balance of 250,000.00 and three transactions: | Transaction Date | Description | Reference | Deposit | Withdrawal | |---|---|---|---|---| | 05-09 | Customer receipt | INV-1042 | 118,000.00 | | | 12-09 | Supplier payment | PAY-0387 | | 64,500.00 | | 30-09 | Bank charges | CHG-SEP | | 350.00 | 1. They create the statement **OPS-CA 2026-09** with **Statement Date** 30 September and **Opening Balance** 250,000.00. That matches the August statement's closing balance, so it saves with status **Imported**. 2. On **Statement Lines** they choose **Import**, download the format, and fill three rows named OPS-CA-2026-09-001 to -003. 3. The **Closing Balance** now reads 303,150.00 (250,000 + 118,000 − 64,500 − 350). That agrees with the bank's printed closing balance. 4. In bank reconciliation, the receipt and the supplier payment are matched to their posted journals and become **Matched**. The bank charge has no journal yet, so they post one from the match panel and then match it. ## Training ### Practice exercise In a sandbox, create a bank statement for a test bank account dated the last day of last month, with an opening balance equal to the previous statement's closing balance (or any figure if it is the first statement). Import three lines using **Download Format**: two withdrawals and one deposit, each with a unique name. **Expected result:** the statement saves with status Imported, the three lines appear on **Statement Lines** with status Unmatched, and the **Closing Balance** equals the opening balance plus the deposit minus the two withdrawals. Then try saving a second statement for the same account and date. It should be refused. ### Quick reference - One statement per bank account per statement date. No future dates. - The opening balance must equal the previous statement's closing balance. - Closing Balance is calculated from the lines. Compare it with the bank's figure. - Every line name must be unique across all statements. - Use either Deposit or Withdrawal on a line, as a positive number. - New lines are Unmatched. Matching happens in bank reconciliation. - Ignored lines still count as unmatched in the reconciliation result. - Deleting a statement leaves its lines behind. Delete the lines first. ## Permissions Access is controlled by the entity permissions for **Bank Statement** and **Bank Statement Line** on each [security profile](/docs/administration/security-profiles/), plus the action permissions for each button: **New**, **Import**, **Edit**, **Delete** and **Clone**. In the shipped profiles, **System Admin** and **Standard User** have full access to both entities and can run every statement and statement-line action, including **New** and **Import**. To restrict who can load statements, withhold the **New** and **Import** action permissions on **Bank Statement Line** from the profile. The **Ignore** button in bank reconciliation saves the line directly, so it needs edit access to **Bank Statement Line**. ## Configuration - **Bank account masters.** Statements can only be created for active bank accounts, and reconciliation needs a linked GL account. Both are set on the bank account (see [Banking](/docs/finance/banking/)). - **Import template.** The columns of the **Download Format** template come from the list view chosen in the import window. With the shipped **ALL Bank Statement Line** view, the template contains Name, Reference, TransactionDate, Deposit, Withdrawal and ReconciliationStatus. To change the template, change the columns of that view or offer another view (see [Importing data](/docs/administration/data-management/import-data/)). - **Security profiles.** Grant or withhold the actions listed under [Permissions](#permissions). - **Matching behaviour.** How lines are paired with ledger entries — rules, tolerances and auto-match — is configured on bank reconciliation, not on the statement (see [Reconciling a bank account](/docs/finance/banking/bank-reconciliation/)). ## Common problems ### "A bank statement for this bank account and date already exists." There is already a statement for that account with the same statement date. Open it and add your lines there, or correct the date if you picked the wrong one. ### "Opening balance … does not match the previous statement's closing balance …" The opening balance you entered differs from the closing balance of the latest earlier statement for the account. Usually that earlier statement has a missing or mis-keyed line, so its calculated closing balance is wrong. Fix the earlier statement's lines first, then save this one. Correcting or back-dating one statement can block saving a later one for the same reason. ### "Future-date is not allowed." The statement date is later than today. Use the as-at date printed on the bank's statement. ### My import fails on some rows Check the **Name** column first. Each line name must be unique across all statement lines, so reusing names from an earlier month (for example 001, 002) collides. Prefix them with the statement. ### A line does not get any match suggestions Suggestions are offered only for lines with status **Unmatched**. A line that is Matched or Ignored gets none. If the line is Unmatched, see [Common problems in bank reconciliation](/docs/finance/banking/bank-reconciliation/#common-problems). ### I deleted a wrong match but the line still says Matched Deleting a reconciliation match does not change the line's status back. Edit the line and set **Reconciliation Status** to Unmatched so that it gets suggestions again, following your approved correction process. ### Lines still appear after I deleted their statement Deleting a statement does not delete its lines. Find them in the bank statement line list and delete them separately. ## Common questions ### Can I type the statement's closing balance myself? The closing balance is a calculated field: the opening balance plus the deposits of the statement's lines minus their withdrawals. Rather than typing the bank's figure, enter all the lines and compare the calculated closing balance with the one printed on the bank's statement. If the two agree, the lines are complete and correct, and reconciliation's check that the statement adds up will pass. If they differ, look for a missing, duplicated or reversed line before you start matching. ### Does the statement's Status change when I reconcile? No. A statement's status is set to Imported when it is created and does not change after that. To see progress, look at the **Reconciliation Status** of the individual lines (Unmatched, Matched or Ignored) or open the account in bank reconciliation. The reconciliation result reports the bank-to-book difference and counts unmatched items on both sides. The account is reconciled only when every statement line has a confirmed match and the difference is zero. ### What does Ignore actually do? **Ignore** sets the line's Reconciliation Status to Ignored, so the line drops out of the Unmatched filter and no longer gets suggestions. It does not create a match. The reconciliation result still counts the line as unmatched, so an ignored line keeps the account from showing as fully reconciled. Use it for a line you have proven is a duplicate, never for a bank charge or a timing difference that needs an entry in the books. ### Can I use a negative amount instead of the Withdrawal column? Use the Withdrawal column. xMatix calculates a line's signed amount as deposit minus withdrawal, and matching relies on that sign to pair deposits with debits and withdrawals with credits. xMatix does not reject a negative deposit, but a line with a negative deposit and a line with a positive withdrawal both come out as money out. Mixing the two conventions makes the statement hard to check against the bank's printout, so keep to one positive amount in the right column. ## Related topics - [Banking](/docs/finance/banking/) - [Reconciling a bank account](/docs/finance/banking/bank-reconciliation/) - [Importing data](/docs/administration/data-management/import-data/) - [Security profiles](/docs/administration/security-profiles/) - [Bank Statement Line — entity reference](/docs/reference/entities/bank-statement-line/) - [Bank Statement — entity reference](/docs/reference/entities/bank-statement/) ---- # Banking in xMatix Finance URL: https://xmatix.com/docs/finance/banking/ Last reviewed: 2026-09-01 The Banking area of the Finance app holds the account masters, imported bank statements, transfers and cheque records that connect external bank activity to the ledger. Its central discipline is simple: a bank account master identifies the external account and links it to the GL account whose posted balance is compared with the bank's statement. ## Start from the account list @[guided-image](_img/bank-account-list.png) The list is the entity-level control point. It shows the saved account name, bank, account number, IFSC, branch, currency and creation date in one place. The demonstration row intentionally remains visible because it is dummy tenant data. Blank IFSC, branch and currency cells are not hidden values; they are evidence that this master is incomplete and should be reviewed before operational use. ## Create the master @[guided-image](_img/new-bank-account-concept.png) The create form shows the complete input contract rather than a made-up example. Give the record a recognizable **Name**, then enter the bank name and account number required by this layout. Add branch name, branch master, partner account, IFSC and currency where they apply. Leave **Is Active** selected only when the master is ready to be used. The linked **GL Account** is the most consequential choice. Reconciliation queries posted journal lines on that account and refuses to produce suggestions when no GL account is linked. Reusing one GL account for unrelated real-world accounts obscures reconciliation, while linking the wrong account compares the statement with the wrong book balance. Before operational use, verify the external identity, denomination, partner/branch scope and GL classification independently. ## Verify the saved record @[guided-image](_img/bank-account-details.png) The **Details** tab separates bank identity, branch details and GL/partner linking. The example is useful precisely because it shows both populated and absent fields: bank name, account number and GL account are present, while currency, IFSC and branch metadata are not. Treat **N/A** as a configuration gap, not as an anonymization mark. @[guided-image](_img/bank-account-statements.png) The **Bank Statements** tab is the saved account's child list. Read statement date, opening balance, closing balance and import status before choosing a statement for reconciliation. Four imported dummy records are visible here; the adjacent insights repeat the account identity but also expose the missing currency and IFSC, making the master-data gap easy to spot. ## Bank accounts Create one **bank account** master per real-world account. Each should link to the GL account that postings debit and credit. The reconciliation service calculates a book balance from posted journal lines on that GL account and a bank-side balance from imported statement closing balances; its difference is the work reconciliation exists to explain. ## Bank statements Import each period's **bank statement** with its lines—date, narration, reference, deposit or withdrawal per line. Statement lines are the bank side of reconciliation. Match them against posted ledger lines on the linked GL account; where the bank reports a genuine event the books do not yet contain, create and post the appropriate journal or payment before confirming a match. For the step-by-step procedure, the field reference and the save-time rules, see [Bank statements and statement lines](/docs/finance/banking/bank-statements/). ## Transfers and vouchers - **Bank transfer** — moves money between two of your accounts, posting a debit to the destination and a credit to the source. - **Expense voucher** — posts a direct expense paid from bank or cash, without routing through a bill. - **Employee reimbursement** — settles an approved employee claim: the payable to the employee is cleared against the bank, and the claim is marked reimbursed. ## The cheque register The cheque register manages physical cheque books: - Register a **cheque range** per book. Issuing a cheque draws the next sequential number from the range, and the register flags itself exhausted when the range runs out. - Each **cheque transaction** then walks a lifecycle: **Issued → Presented → Cleared**, or **Bounced** or **Cancelled**. The terminal states are locked — a cleared or cancelled cheque cannot be moved again — so the register stays a trustworthy audit trail. A bounced cheque is a real event in the books, not just a status: the payment it carried must be unwound so the settled document reopens (see [Payments](/docs/finance/payments/)). ## Payment and deposit batches Bulk runs — a supplier payment run, a day's collections banked together — are grouped into **payment batches** and **deposit batches**. The batch header rolls up the item count and total, giving the reconciliation one figure to match against the single bank movement the batch produced. ## Common questions ### Why do the bank balance and book balance differ? Timing, usually: cheques issued but not yet presented, deposits in transit, and bank charges the books have not recorded yet. The reconciliation session quantifies the difference — matched versus outstanding items on each side — and the account is reconciled when the difference nets to zero. A difference that will not net out points at a missing posting or an unimported statement line. ### Can a company have several bank accounts? Yes. Create a bank account master per real account and normally give each its own GL account. The data model supports many accounts per company/branch, and statements and cheque transactions link to a specific bank-account record. ### Do I have to use the cheque register to record a cheque payment? Recording a payment with mode "cheque" captures the cheque number and date on the payment itself. The register adds sequence control and lifecycle tracking on top — worth it wherever physical cheque books are in active use, optional where cheques are rare. ## Related topics - [Bank statements and statement lines](/docs/finance/banking/bank-statements/) - [Bank reconciliation](/docs/finance/banking/bank-reconciliation/) - [Recording and applying payments](/docs/finance/payments/) - [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) ---- # Budgets and budget control URL: https://xmatix.com/docs/finance/budgets/ Last reviewed: 2026-09-02 A finance budget expresses a plan in the same GL-account structure used by the ledger. The implemented reporting path can compare budget lines with posted actuals. The repository also contains availability and commitment services, but current purchasing and expense handlers do not call them, so this page does not present budget control as an active spend gate. The demo2 Budget create layout currently includes tenant-specific fields that do not correspond cleanly to the core Budget entity. A screenshot would teach the wrong configuration, so this page remains text-only. ## Core budget record The core Budget header stores: - fiscal year; - partner account; - optional business unit and cost centre; - status and active state; and - planned amount. Budget lines carry the GL account, period, business unit, branch, amount, partner account and cost centre used for the comparison. Use those core dimensions when designing layouts or integrations; do not rely on a demo-only Name, Label or Budget Type field as a platform contract. Keep the header and line scope coherent. A line for a different partner, period or organizational dimension can make the statement look incomplete even when both records saved successfully. Before activating a budget, reconcile the sum of its lines with the intended plan and document how null dimensions should be interpreted by the reports used in your deployment. ## Budget vs Actual Budget variance reporting is implemented. It reads the applicable budget amount and compares it with posted ledger actuals for the requested scope. An overrun therefore appears in the variance result after the responsible transaction reaches the ledger. Use the report as the current system of record for budget monitoring: 1. Select the intended fiscal year and organizational scope. 2. Confirm the expected GL accounts have budget lines. 3. Compare actual and budget amounts and investigate scope mismatches before changing the plan. 4. Trace actuals back to posted journals or source documents. ## Availability checks are not a universal gate An availability service can calculate whether a proposed amount fits against budget. The code currently has no production caller from the purchasing, invoice or expense save/post paths audited for this page. A transaction can therefore proceed without consulting that service. If the business requires hard prevention, treat that as an implementation project: identify every committing and posting path, call the check server-side, define override permissions and add integration tests that prove an over-budget transaction is rejected. A report or a standalone service is not itself a control. ## Commitments are not yet end-to-end Commitment methods exist to create, consume and close a budget commitment. The audited document handlers do not wire those methods to purchase-order creation, billing, cancellation or posting. Consequently, this documentation cannot claim that an open purchase order automatically reduces budget availability or that its bill automatically replaces the commitment. Until that workflow is implemented and tested, track commitments through the organization's approved external process and use Budget vs Actual for posted spend. Do not add an unverified commitment amount to a public screenshot or reconciliation. ## Forecast behaviour The current forecast calculation is an actuals-based run rate. It does not calculate “actuals plus open commitments.” Interpret it as a projection from historical posted activity, not a committed-spend forecast. ## Common questions ### What happens when a budget is exceeded? The variance report can show the overrun after posting. Current spending flows are not universally blocked by the budget-availability service, so do not promise pre-transaction prevention unless your deployment has added and tested that integration. ### Can I budget by branch, business unit or cost centre? The line model carries branch, business-unit and cost-centre dimensions in addition to GL account and period. Verify that the report or custom consumer you use applies the same dimension semantics before depending on a finely scoped control. ### Do purchase orders reserve budget automatically? Not in the audited first-party flow. Commitment services exist, but create/consume/close calls are not wired into the relevant document lifecycle. ## Related topics - [Financial statements](/docs/finance/statements/) - [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) - [Working with journals](/docs/finance/journals/) ---- # Chart of accounts, books and periods URL: https://xmatix.com/docs/finance/chart-of-accounts/ Last reviewed: 2026-10-10 The chart of accounts is the list of GL accounts every journal line posts to. Around it sit three structures that decide *how* postings happen: accounting books (parallel valuation perspectives per company), posting definitions (which account each document line hits), and the fiscal calendar (which dates are open for posting). All four are maintained in the Finance app's **Settings** area. ## Read the screen @[guided-image](_img/new-gl-account-concept.png) The account form turns a reporting idea into a ledger master. Begin with a durable **Name** and optional **Account Code**, then select the **Account Type** that matches the economic substance. For statement placement, the statements use **Schedule III Classification** and fall back to Account Type; they never use Posting Type. **Control Type** and **Is Control Account** are separate settings. Control Type lets features such as withholding tax and payroll find the account. Is Control Account makes a customer or supplier mandatory on every line. The create form shows only Control Type; Is Control Account appears on the record page, in the **Applicability** section of the **Details** tab. Tick it only for receivables and payables controls — see [Mark a control account](/docs/finance/gl-accounts/) for the ways to set it. ## GL accounts Each GL account belongs to one company and carries an Account Type, and can carry a Schedule III classification. Statements use Schedule III when present and otherwise fall back to Account Type. The full procedure — seeding a chart from a template, creating and retiring accounts, tagging control accounts and reading an account's ledger — is in [GL accounts](/docs/finance/gl-accounts/). ### Control accounts A control account summarizes a subledger inside the general ledger. Party enforcement applies only when **Is Control Account** is ticked. The withholding, payroll and employee controls carry a Control Type but are kept with Is Control Account cleared. The usual control accounts are: | Control type | Summarizes | | --- | --- | | Accounts Receivable | Customer open items | | Accounts Payable | Supplier open items | | Bank | Bank account activity | | Inventory | Inventory value layers | | Tax payable / tax credit | Output and input tax captured from documents | | Withholding payable | Tax withheld or collected on documents | | Inter-business-unit | Cross-division balances | Reconciliation reports compare each control account's posted balance against the detail it summarizes and flag any difference — see [AR and AP subledgers](/docs/finance/subledgers/). ## Accounting books An accounting book is a valuation perspective for a company. Books can be marked active and primary, but the audited model does not enforce a unique primary book per company. Statement code takes the first active primary book it finds. Configure exactly one by policy and add a validation/report to detect duplicates; otherwise statement selection can depend on query order. Tax and Management books may carry separate valuation policy, but do not assume “primary” is protected by a database uniqueness constraint. ## Posting definitions A posting definition decides which GL account a document line debits or credits. Definitions are keyed by the document type, the posting role (receivable, income, tax and so on) and the tax type, and can be scoped to a specific item, customer or supplier. When a document posts, the most specific matching definition wins; if none matches, the platform falls back to the company's chart by account type. A typical setup seeds definitions for: the AR and AP controls, cash and bank by payment mode, sales income, purchases and inventory, cost of goods sold, and the tax accounts. If no account resolves for a line, the document does not post and the error names the missing role — fix the posting definition rather than posting manually. ## Fiscal years and periods The fiscal calendar gates posting: a journal posts only into a period whose status is **Open**, inside a fiscal year whose status is also **Open**. The full procedure is in [Fiscal years and periods](/docs/finance/fiscal-years/). - Create a **fiscal year** (name, company, start and end date) and generate its periods — one Open period per calendar month of the year. - The exposed Fiscal Period actions implement **Open → Closed**, **Closed → Open**, and **Lock**. There is no first-party Soft Close action, and posting does not include a “soft-closed with permission” branch. - A journal's posting period is derived from its **document or journal date**, validated against the open period — a March invoice entered in April still lands in March. ## Common questions ### What happens when a document line cannot resolve a GL account? The posting fails with a message naming the unresolved role — it never guesses an account. Add or correct the posting definition for that document type and role, then approve the document again. A party is also mandatory on any control-account line, so a receivable or payable line without a customer or supplier fails the same way. ### Can I post into last month? Only while last month's period is Open. A Closed period must be reopened before posting; a Locked period is not accepted. The period comes from the journal date, so backdating targets the earlier period only if that period is Open. ### Do I need more than one accounting book? Most organizations need one active primary book for the statement path. The platform does not enforce that uniqueness, so verify it administratively before adding Tax or Management books. Test each report's book selection and valuation semantics rather than assuming every posting is reused identically. ## Related topics - [GL accounts](/docs/finance/gl-accounts/) - [Working with journals](/docs/finance/journals/) - [AR and AP subledgers](/docs/finance/subledgers/) - [Closing a period](/docs/finance/period-close/) - [Financial statements](/docs/finance/statements/) ---- # Fiscal years and periods URL: https://xmatix.com/docs/finance/fiscal-years/ Last reviewed: 2026-10-10 A **fiscal year** is a company's accounting calendar — a dated window, split into monthly **fiscal periods**, that decides which dates a journal can post into. You create it once a year before the first transaction of the year, generate its periods, close the periods month by month as the books are reconciled, and finish with the year-end close that transfers profit or loss to retained earnings. The fiscal year record is also where the finance statements and statutory schedules for that year are run. ## Overview Every posting in xMatix — a manual journal, or the journal an invoice, bill, payment or stock movement generates — is placed in the fiscal period that covers its date. A period is either **Open**, **Closed** or **Locked**, and only an Open period accepts postings. The fiscal year above it has a status of its own, and a year that is not Open blocks postings into all of its periods, even the Open ones. A fiscal year holds: - **Fiscal periods** — one per calendar month of the year, numbered from 1, each with its own start date, end date and status. - **Fiscal days** (optional) — one row per calendar date, flagged working or non-working from your holiday list and business hours, so a month's working-day count can be read and corrected. ## When to use it - **Going live on Finance** — create the current fiscal year and generate its periods before you post opening balances. - **Before each new year** — create next year's fiscal year ahead of the first document dated in it. - **Each month-end** — close the month's period once it is reconciled (see [Closing a period](/docs/finance/period-close/)). - **Year-end** — post the closing journal with **Close Year**, then close or lock the last periods. - **Reporting** — run the trial balance, profit and loss, balance sheet and the statutory schedules for the year from the fiscal year record (the day-to-day statement screens are described in [Financial statements](/docs/finance/statements/)). ## How xMatix handles it - **Periods are found by date and company.** When a journal posts, xMatix looks for the period whose dates cover the journal date and that belongs to the journal's company. A period with no company applies to every company; if both exist, the company's own period wins. - **A missing calendar is created for you.** If a document posts on a date that no period covers, xMatix creates an April–March fiscal year for that company with twelve Open monthly periods — named, for example, **FY2026-27** — and posts into it. It never reopens a Closed or Locked period to do so. - **Draft journals get their period on save.** A new journal, or a journal whose date changes, is given its period when it is saved; posting looks the period up again from the final date. - **Status gates posting at two levels.** The period must be Open, and the fiscal year must be Open. Otherwise the save or post is refused with a message naming the period. - **Period statuses move only through actions.** **Close Period** (Open → Closed), **Reopen Period** (Closed → Open) and **Lock Period** (Open or Closed → Locked). Locked is final: a locked period can never be reopened. - **Days follow their period.** When a period is closed, reopened or locked, its fiscal days take the same status. ## Prerequisites - The company (the **Partner Account**) the calendar belongs to exists. If your organization runs a single company, the Partner Account field is hidden and you can leave it out. - You have access to Fiscal Years in the Finance app's **Settings** area and the action permissions described under Permissions below. - For **Close Year**: a retained-earnings GL account in the company's [chart of accounts](/docs/finance/chart-of-accounts/). - For **Generate Fiscal Days**: your holidays and default business hours are set up, so working days are flagged correctly. ## Procedure ### Step 1 — Create the fiscal year 1. In the Finance app, open **Settings** and select **Fiscal Years** (under **Company Structure**). 2. Select **New**. 3. Enter the **Name** (required) — for example `FY2026-27` — and choose the **Partner Account** the calendar belongs to. 4. Under **Timeline**, enter the **Start Date** and **End Date**. 5. Save. The year opens with status **Open**. If the end date is not after the start date, the save is refused with *Fiscal year end date must be after the start date.* ### Step 2 — Generate the periods 1. On the fiscal year record, select **Generate Periods** (it may be under the header's overflow of actions). 2. Confirm *Create monthly Open periods for this fiscal year.* xMatix creates one Open period per calendar month from the start date to the end date, labelled by month (for example **Apr 2026**) and numbered 1, 2, 3 and so on. If the year starts or ends mid-month, the first or last period is shortened to match. Generate Periods runs only once per year: if the year already has periods it stops with *Fiscal year already has periods.* ### Step 3 — Generate fiscal days (optional) 1. On the fiscal year record, select **Generate Fiscal Days** and confirm. 2. The action runs in the background and creates a day row for every date of the year, marked working or non-working from your holiday list and the default business hours. Days that already exist are counted and left untouched, so you can run it again safely. If the year has no periods yet, it stops and asks you to generate the periods first. A background job keeps the working-day flag on future days in line with holidays you add, change or remove later. ### Step 4 — Post through the year You do not choose a period on a document — the date does. Keep the current month Open and, as each month is reconciled, close its period from the period record with **Close Period**. The shipped period page shows only Edit and Delete in its header, so an administrator first adds the period actions to the Fiscal Period page layout. The full month-end routine is in [Fiscal periods and period close](/docs/finance/period-close/). ### Step 5 — Close the year 1. Make sure every journal for the year is posted and the **last period is still Open** — the closing journal is dated on the last day of the year and posts into that period. 2. On the fiscal year record, select **Close Year** and confirm *Post the year-end closing entry transferring P&L to Retained Earnings.* Close Year reads the year's profit and loss and posts one **Closing** journal, named `CLOSE-` followed by the year's name. It reverses every income and expense account with a balance and books the net profit (a credit) or loss (a debit) to the retained-earnings account. The journal is posted straight away. Close Year does not change the year's status and does not close any period. > The Close Year button on the record page does not ask for the retained-earnings account, so running it from the button stops with the message *retainedEarningsGLAccountId is required to close the year.* The action has to be run with that account supplied as an argument, for example through the xMatix API. Ask your administrator or implementation partner to run it. ### Step 6 — Close or lock the last periods and the year After the closing journal is posted and checked, close the remaining periods. Lock them once the year's statements are final. To stop all postings into the year at once, edit the fiscal year and set **Status** to `Closed`. ### Step 7 — Run the year's statements On the fiscal year record, the header actions include **Trial Balance**, **Profit & Loss**, **Balance Sheet**, **Generate Cash Flow**, **General Ledger**, **Day Book**, **Bank Book**, **Cash Book**, **Comparative Statement**, **Generate Ar Ageing**, **Generate Ap Ageing** and **Generate Party Statement**. Each one is computed live from the posted ledger for this year and this company. For the full statement screens with date and dimension filters, use the **Statements** area — see [Financial statements](/docs/finance/statements/). ## Fields ### Fiscal year | Field | What it means | Notes | | --- | --- | --- | | Name | The year's name, for example `FY2026-27` | Required. Used in the closing journal's name. | | Partner Account | The company this calendar belongs to | Leave blank only if one calendar should serve every company. Hidden when your organization runs a single company. | | Start Date | First day of the year | Needed before periods or days can be generated. | | End Date | Last day of the year | Must be after the start date. | | Status | The year-level status | Defaults to `Open`. A plain text field, not a picklist: any value other than `Open` blocks postings into every period of the year. xMatix does not change it — Close Year leaves it as it was. | | Label | An optional display name | Not on the create form. | The record header shows **Partner Account**, **Start Date** and **End Date**. The **Details** tab shows the dates and status under **Timeline**, and who created and last changed the record under **System Information**. ### Fiscal period | Field | What it means | Notes | | --- | --- | --- | | Name / Label | The month, for example `Apr 2026` | Set by Generate Periods. | | Fiscal Year | The year the period belongs to | | | Period Number | Position in the year, starting at 1 | The highest number is the last period, used by Close Year. | | Start Date / End Date | The dates the period covers | A journal lands in the period that covers its date. | | Status | `Open`, `Closed` or `Locked` | Changed through the period actions. Only Open accepts postings. | | Partner Account | The company, copied from the fiscal year | | ## Business rules - **End after start.** A fiscal year's end date must be after its start date. - **One generation per year.** Generate Periods refuses a year with no valid dates and a year that already has periods. It does not top up missing months — delete the existing Open periods first if you need to regenerate. - **Monthly only.** Periods are always calendar months; there is no quarterly or 4-4-5 option. - **Posting needs Open twice.** The period covering the date must be Open and its fiscal year's status must be Open. - **Period transitions.** Close Period works only on an Open period; Reopen Period only on a Closed one; Lock Period works on Open or Closed and moves straight to Locked. - **Locked is final.** Any change that would move a period out of Locked is refused with *A locked fiscal period cannot be reopened.* - **Only Open periods can be deleted.** Deleting a Closed or Locked period is refused with *Closed or locked fiscal periods cannot be deleted.* - **Automatic calendar.** A posting date with no covering period creates an April–March year for the company with Open monthly periods. - **No overlap check.** xMatix does not stop two fiscal years for the same company from overlapping. Keep each company's years back to back. - **Year-end close.** Close Year needs a company on the year and at least one period. If the year has no income or expense balances it posts nothing. It does not check whether the year was already closed, so look for an existing `CLOSE-` journal before running it again. ## Example Lakeview Traders runs an April–March year. 1. In March 2026 the finance lead creates **FY2026-27**, Partner Account *Lakeview Traders*, Start Date 1 Apr 2026, End Date 31 Mar 2027, and selects **Generate Periods**. Twelve Open periods appear, **Apr 2026** to **Mar 2027**. 2. They run **Generate Fiscal Days**; the year now shows each month's working days, with public holidays marked non-working. 3. On 5 May they reconcile April and select **Close Period** on **Apr 2026**. A supplier bill dated 28 April arriving on 7 May is refused, because its period is Closed. After approval, the accountant selects **Reopen Period**, posts the bill and closes April again. 4. In April 2027, with all journals for the year posted and **Mar 2027** still Open, the year-end close is run with the *Retained Earnings* account. Journal `CLOSE-FY2026-27` debits every income account, credits every expense account and credits the year's net profit to retained earnings. 5. They close **Mar 2027**, set the year's **Status** to `Closed`, and lock all twelve periods once the audited statements are signed off. ## Training ### Practice exercise In a sandbox where the period actions have been added to the Fiscal Period page (see [Fiscal periods and period close](/docs/finance/period-close/)): 1. Create a fiscal year named `FY-TRAIN` running from 1 Jan to 31 Dec of next year for your test company. 2. Select **Generate Periods**. Expected result: twelve Open periods, January to December, numbered 1 to 12. 3. Select **Generate Periods** again. Expected result: the message *Fiscal year already has periods.* 4. Open the January period and select **Close Period**, then **Reopen Period**. Expected result: Closed, then Open again. 5. Post a manual journal dated in January, then close January and try to post a second January journal. Expected result: the second post is refused because the period is Closed. ### Quick reference - Fiscal years live in Finance → **Settings** → **Fiscal Years**. - One fiscal year per company per year; periods are always monthly. - Generate Periods runs once per year. - The journal date picks the period; you never choose it. - Only Open periods in an Open year accept postings. - Close → Reopen is allowed; Locked is final. - Run Close Year while the last period is still Open. - Close Year posts the closing journal but changes no status. ## Permissions What a user can do with fiscal years is set in their [security profile](/docs/administration/security-profiles/): - **Entity permissions** on Fiscal Year and Fiscal Period decide who can see, create, edit and delete them. - **Server actions** — Generate Periods, Generate Fiscal Days, Close Year, Close Period, Reopen Period, Lock Period and each statement action — need an explicit grant on the profile's **Actions** tab. Standard New, Edit and Delete follow the entity permissions; every other action needs its own grant. Grant the period and year-end actions only to the people who own the close; give report readers just the statement actions. ## Configuration - **Fiscal years** — Finance → **Settings** → **Fiscal Years**. Create one per company per year; the year's dates decide the monthly periods. - **Year status** — the **Status** field on the fiscal year. Set it to `Closed` or `Locked` to stop all postings into the year; set it back to `Open` to allow them. Type the value exactly — any other text also blocks posting. - **Period status** — the Close Period, Reopen Period and Lock Period actions on each fiscal period. Add them to the Fiscal Period page layout first; the shipped page header shows only Edit and Delete. - **Holidays and business hours** — drive the working-day flag on fiscal days. Set them up before you run Generate Fiscal Days; later changes are applied to future days by the background holiday sync. - **Schedule III classifications** — **Seed Classifications** on the fiscal year fills in the statutory statement line on the company's GL accounts from each account's type. By default it fills only accounts that have none. - **Organization shape** — if **We run multiple companies** is off in **Org Settings**, the Partner Account field is hidden on fiscal years. - **Security profiles** — grant the fiscal year and period actions as described under Permissions above. ## Common problems ### "Fiscal period '…' is Closed — posting is not allowed." The document or journal date falls in a Closed or Locked period. Change the date to an Open period if the date is wrong. If it is right and the period is Closed, get approval, use **Reopen Period**, post, then close the period again. A Locked period cannot be reopened. ### "Financial year for period '…' is Closed — posting is not allowed." The period is Open but its fiscal year's **Status** is not `Open`. Check the status for a typo, or set it back to `Open` if the year really should accept postings. ### "Fiscal year already has periods." Generate Periods only runs on a year with no periods. Review the existing periods; to regenerate, delete them (only Open periods can be deleted) and run the action again. ### "Fiscal year requires a valid start and end date to generate periods." Fill in both dates on the fiscal year, with the end date after the start date, and run Generate Periods again. ### "retainedEarningsGLAccountId is required to close the year." Close Year was run without a retained-earnings account. The record-page button does not ask for one; the action has to be run with the account supplied by an administrator or implementation partner. ### Generate Fiscal Days says the year has no periods yet Run **Generate Periods** first. Days always belong to a period. ### Documents posted into a year I did not create A posting dated outside every existing period creates an April–March fiscal year automatically. Rename or adjust it as needed, and create future years ahead of time. ## Common questions ### Can I use a calendar-year or other non-April fiscal year? Yes. The start and end dates are yours to choose — January to December, July to June, or any other range — and Generate Periods creates one period per calendar month inside it. The April–March pattern applies only to the year xMatix creates automatically when a posting date has no period. To avoid that, create each year before the first document dated in it. Periods are always calendar months; quarterly or 4-4-5 periods are not supported. ### Does closing the year close the periods? No. Close Year only posts the closing journal that moves the year's profit or loss to retained earnings. The periods keep their status, and the fiscal year's own Status is unchanged. Close the last periods with **Close Period**, lock them with **Lock Period** once the statements are final, and set the year's Status to `Closed` if you want to stop all postings into the year in one step. ### What is the difference between Closed and Locked? A Closed period refuses postings but can be reopened with **Reopen Period** for an approved correction. A Locked period also refuses postings and can never be reopened — xMatix rejects any change that moves it out of Locked, and it cannot be deleted. Use Closed at month-end and Locked once the period's figures are final, for example after audit or filing. ### Do I need fiscal days? Only if you need working-day counts per month. Postings, period closing and the statements all work from the periods alone. Fiscal days add one row per date, flagged working or non-working from your holidays and business hours, so a month's working days can be counted and individually corrected. ## Related topics - [Closing a period](/docs/finance/period-close/) - [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) - [Working with journals](/docs/finance/journals/) - [Financial statements](/docs/finance/statements/) - [Budgets and budget control](/docs/finance/budgets/) - [Security profiles](/docs/administration/security-profiles/) - [Fiscal Year — entity reference](/docs/reference/entities/fiscal-year/) - [Fiscal Period — entity reference](/docs/reference/entities/fiscal-period/) ---- # Running depreciation URL: https://xmatix.com/docs/finance/fixed-assets/depreciation/ Last reviewed: 2026-09-02 Depreciation in xMatix posts through **Recurring Depreciation** schedules: one record per asset or pool, each run posting a balanced journal—debit depreciation expense and credit accumulated depreciation—until current WDV reaches residual value or the schedule passes its end date. The background processor skips a schedule that is inactive or no longer due. The manual action is different: it calls the run service directly and does not independently reject a second click for the same due date, so treat it as a controlled posting action. ## Prerequisites - Two GL accounts per asset class, correctly typed and classified: a **depreciation expense** account (P&L) and an **accumulated depreciation** account (contra-asset). The classification is what places them on statements and drives the PPE movement note (see [Fixed assets](/docs/finance/fixed-assets/)). - An **Open** fiscal period — depreciation posts under the same [calendar rules](/docs/finance/chart-of-accounts/) as everything else. - The asset's figures: cost, residual value, and the method's rate or period amount. ## Procedure The current demo2 create form does not show a populated schedule, a due run or its generated journal. It is omitted because a blank header would not evidence the procedure below. ### Step 1 — Create the schedule Create one recurring depreciation schedule per asset or per pool depreciated as a unit. Select the partner account and branch, enter the asset name, method, frequency, cost, residual value, current written-down value, start/end dates and both GL accounts. For a new asset, seed written-down value equal to cost; for an existing asset, use its current book value. Save and reopen the schedule to verify the method, amount field, first run date and debit/credit accounts before making it active. **Set the method's matching amount field** — this is the one setup mistake that matters: | Method | Amount field | How the charge is computed | | --- | --- | --- | | Straight-line | Period amount = (cost − residual) ÷ number of periods | The same fixed charge each period | | Written-down value | Rate per period, stored as a fraction (0.10 for 10%) | Rate × current written-down value — a declining charge | A schedule whose computed charge is zero—WDV with no rate or straight-line with no period amount—fails with validation rather than posting a meaningless entry. **Rate Per Period is consumed as a fraction**: enter `0.10` for ten percent unless your tenant layout explicitly implements and verifies a percentage conversion. The checked-in number field does not itself prove that conversion. ### Step 2 — Let it run When Next Run Date arrives, let the scheduler process the Active schedule or invoke the manual post action once under your month-end control. One successful run posts the journal and updates the schedule—current WDV decreases, accumulated depreciation increases and Next Run Date advances. Record the returned journal reference and refresh the schedule before doing anything else. Do not click the manual action again merely because the screen is slow. `RunAsync` checks Active status and value/account validity but does not compare a supplied/manual run date with the already-advanced Next Run Date. A repeated manual invocation can therefore post another period. Background job re-delivery is safer because its processor re-reads Next Run Date and skips a job that is no longer due. Either way, the charge is floored so the final period lands exactly on the residual value — no drift, no over-depreciation. ### Step 3 — Verify the posting Open the generated journal and confirm its type is **Depreciation**, its schedule reference and company/branch dimensions are present, debits equal credits, expense is debited and accumulated depreciation is credited for the independently calculated charge. Return to the schedule and verify written-down value fell and accumulated depreciation rose by that same amount. If any part is wrong, do not edit the posted journal—[reverse it](/docs/finance/journals/), correct the schedule and run again. ### Step 4 — Pause, resume, complete Set the schedule to **Paused** before a period that must not post and confirm its status and next run date remain unchanged after the scheduler runs. Return it to **Active** when charging should resume. A schedule marks itself **Completed** when written-down value reaches residual or its optional end date passes; verify no later journal is created, rather than manually advancing a completed schedule. ### Step 5 — Bring in part-depreciated assets For a mid-life migration, reconcile the legacy fixed-asset register to the GL first, then seed today's truth: current written-down value equals current book value, accumulated depreciation equals depreciation already taken, and next run date is the first period xMatix should charge. Preview or calculate the next charge and verify it continues from the imported carrying value rather than attempting to recreate historical periods. ### Step 6 — Dispose of an asset When an asset is sold, scrapped or written off, work through all three controls and retain their references together: 1. Create the **asset disposal** record in the Fixed Assets app — the asset, date, method and reason, the proceeds, and the resulting gain or loss against net book value. This is the audit record of the event. 2. Use the disposal posting flow and inspect the journal it creates. The current service posts the Disposal journal automatically; do **not** add a second manual journal for the same disposal. Verify accumulated depreciation, proceeds, gross block and gain/loss in the generated entry. 3. Pause or complete the asset's schedule so it stops charging—a disposed asset must not keep depreciating. Verify the disposal date, balanced journal and inactive schedule agree before closing the period. ## Expected result Each controlled run produces one balanced depreciation journal, advances the schedule once and never reduces current WDV below residual value. Paused or Completed schedules are rejected/skipped. Disposal does not automatically identify and stop a name-linked schedule, so explicitly pause or complete it and reconcile the disposal, schedule and GL together. ## Common problems **The schedule did not run.** Check in order: status is active, the run date has arrived (and is within the end date), and both GL accounts are set. A paused or completed schedule is skipped by design. **The run failed with a zero-charge error.** The method's matching amount field is missing — set the rate per period (WDV) or the period amount (straight-line) from Step 1. **It posted the wrong amount.** Reverse the journal, fix the schedule's figures, and run again. Never edit a posted journal — and note that changing the written-down value or the residual mid-life changes every future charge, so re-verify the next run. ## Common questions ### Can a period ever be depreciated twice? The background processor protects against ordinary job re-delivery by re-reading the schedule and skipping it when Next Run Date is later than the job occurrence. The manual action does not perform that due-date guard; a second invocation on an Active schedule can post again and advance another period. Refresh after the first result, retain its journal id and never retry the action blindly. ### How does the last period land exactly on the residual value? The charge is floored: each run charges the lesser of the computed amount and what remains above the residual. Straight-line schedules absorb rounding in the final period; WDV schedules cap the final charge. Closing book value equals residual value, exactly. ### Where does Income-Tax Act depreciation fit in? The schedules post the Companies Act charge to the ledger. The tax book's depreciation is computed separately on the asset blocks — block rate on the block's written-down value, with the 180-day half-rate rule for late additions — as described on [Fixed assets](/docs/finance/fixed-assets/). ## Related topics - [Fixed assets in xMatix](/docs/finance/fixed-assets/) - [Working with journals](/docs/finance/journals/) - [Closing a period](/docs/finance/period-close/) ---- # Fixed assets in xMatix URL: https://xmatix.com/docs/finance/fixed-assets/ Last reviewed: 2026-09-01 Fixed assets in xMatix are two separate layers. The **Asset** record is an operational register with identity, ownership, location, acquisition, lifecycle and stored depreciation-related fields. **Recurring Depreciation** is the finance schedule that actually computes and posts a periodic charge. Saving an Asset or linking a Depreciation Policy does not generate that schedule and does not post a journal. ## Start from the asset list @[guided-image](_img/fixed-asset-list.png) The list shows the entity register rather than a generic finance page. The populated demonstration rows expose name, purchase date, price, parent asset, quantity and status. Blank asset codes and zero quantities are visible data-quality facts; they are not masked values. Open a representative row before deciding that the list price, stored purchase cost and net book value agree. ## Read the screen @[guided-image](_img/new-fixed-asset-concept.png) The create form begins the operational audit trail. **Name** supplies the required record identity; asset code, item, category, subcategory, price, quantity, purchase date, serial number, condition, branch/location and installation dates are separate stored fields. Populate only facts supported by the purchase, receipt or installation evidence. Do not infer that **Price × Quantity** automatically becomes **Purchase Cost** or **Net Book Value**; those are separate fields on the asset model. Status, sale/disposal dates, useful life, salvage value, method, policy and net book value describe stored state, but the master alone does not create a journal. After saving an asset that should depreciate, create and verify a separate recurring schedule with its method, period amount or rate, residual value, current WDV, dates and both GL accounts. The useful control is a three-way reading: the register says what the asset record contains, the schedule says how future runs will be calculated, and posted journal lines prove what reached the ledger. ## Read the saved details @[guided-image](_img/fixed-asset-detail.png) The upper **Details** view covers operational identity and hierarchy. This example is Purchased, links to an item and parent asset, identifies the account and last-service branch, and has no serial number or depreciation policy. Empty fields remain visible so the screenshot does not overstate completeness. @[guided-image](_img/fixed-asset-detail-cost.png) Farther down the same tab, **Purchase and Cost Details** exposes the stored purchase date, purchase cost, useful life and net book value. Here the useful life is zero and no policy appears above, even though net book value is 3,150. Treat that value as a stored field to reconcile, not as proof that a depreciation engine calculated it. Disposal and lifecycle dates are also visible and blank where the event has not occurred. ## The asset register The register lives in the **Fixed Assets** app. Create one asset record per asset you track, carrying: | Facet | Fields | | --- | --- | | Identity | Name, asset code, category and sub-category | | Acquisition | Price, quantity, purchase cost and date as distinct stored fields | | Depreciation intent | Method, useful life, salvage value and an optional linked policy | | Carrying value | Stored net book value, which must be reconciled to posted depreciation | | Lifecycle | Status plus installation, sale, usage-end and disposal dates/values where populated | Operational facets — serial and batch numbers, branch and storage location, install and service dates, parent-child hierarchy — make the register useful well beyond accounting. ## Depreciation policies A **Depreciation Policy** stores a method, rate, useful life, frequency, currency and category/subcategory fields. An Asset can reference a policy, but the current implementation does not generate or update a Recurring Depreciation schedule from it. Use the policy as documented intent and manually verify that the finance schedule carries the approved terms. Do not claim that a category default or statutory useful life has been applied unless the saved asset, policy and schedule all show it. ## Two statutory books The repository contains two distinct calculation models, but their persistence coverage differs: - **Companies Act book** — Recurring Depreciation can post either a fixed straight-line period amount or a written-down-value rate on current WDV, floored at residual value. - **Income-Tax block calculation** — Asset Block stores block code, rate, opening WDV, fiscal year and partner account. A calculation helper supports full-rate additions, half-rate additions and deductions, including the 180-day rule, but those movement inputs are not columns on Asset Block and the checked-in Form 3CD path currently supplies them as zero. Treat this as a calculation/disclosure foundation, not a complete automatically maintained tax subledger. ## The depreciation engine The posting engine is **Recurring Depreciation**—one record per asset or pool, naming the asset in text, its method, amount/rate, current WDV, residual, schedule dates and two GL accounts. A background evaluator finds due Active schedules and the same service backs the manual post action. A successful run posts the charge, advances Next Run Date and completes when current WDV reaches residual or the advanced date passes End Date. The full procedure is on [Running depreciation](/docs/finance/fixed-assets/depreciation/). The register and engine are linked by name and convention, not by an Asset foreign key. Create the schedule deliberately, keep its asset name traceable to the register, and reconcile its current WDV and accumulated depreciation to the Asset and ledger. ## The PPE movement note The Schedule III **property, plant and equipment movement note** is derived from fiscal-period balances on GL accounts whose account types are **Fixed Asset** or **Accumulated Depreciation**, grouped by Schedule III classification. Its reliability therefore depends on correct account types/classification and posted movements; the Asset register itself is not the source of that statement. ## Common questions ### I created an asset but no depreciation posted. Why? Expected — the register is descriptive. An asset record's method, life and value fields document intent; nothing reads them to post. Create a recurring depreciation schedule for the asset and the ledger postings begin. See [Running depreciation](/docs/finance/fixed-assets/depreciation/). ### Do I need both a policy and a schedule? The schedule is what matters to the ledger; the policy is stored intent. Linking the policy does not create a schedule. If you use both, compare method, rate/useful-life intent and frequency manually and retain evidence of that review. ### Where does the tax book's depreciation come from? The block calculation helper accepts opening WDV, full-rate additions, half-rate additions, deductions and a block rate. The saved Asset Block row contains only opening WDV and rate plus scope fields, so additions and deductions must come from a caller or supporting workpaper; they are not automatically maintained on that row. Nothing in this path posts the tax calculation to the ledger. ## Related topics - [Running depreciation](/docs/finance/fixed-assets/depreciation/) - [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) - [Financial statements](/docs/finance/statements/) ---- # GL accounts URL: https://xmatix.com/docs/finance/gl-accounts/ Last reviewed: 2026-10-10 A GL account is one line of a company's chart of accounts: the place every journal line debits or credits, and the unit every financial statement adds up. Each account belongs to exactly one company. Its type decides which documents can find it automatically, its classification decides where its balance appears on the statements, and its control settings decide whether postings to it must name a customer or supplier. You set the chart up once per company, before the first invoice, bill or payment posts. After that, you add an account now and then, retire ones you no longer use, and read balances from the ledger screens. ## Overview The GL accounts list lives in the Finance app. A company usually gets its first chart automatically, from a chart template when an administrator enables finance for the company. Most of the work after that is adjusting the chart to the business: adding accounts, setting the statement classification, and tagging the control accounts the posting services look for. Documents rarely ask you to pick a GL account. Invoices, bills, payments and other documents find their accounts through posting definitions, and fall back to the account type when no definition matches. See [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) for how those pieces fit together. ## When to use it - **Setting up a new company** — review the seeded chart, add what is missing, and tag the control accounts before going live. - **Adding an account** — a new expense head, a second bank account, a separate income stream. - **Fixing statement placement** — an account appears under the wrong heading on the Balance Sheet or P&L. - **Retiring an account** — stop new postings to it while keeping its history. - **Investigating a balance** — see every posted line behind an account's figure for a date range. ## How xMatix handles it - **One company per account.** Every account carries a **Partner Account** — the company that owns it. Account lookups, control-account lookups and the GL Account Ledger all work within one company, so two companies never share an account. - **Account Type drives automatic account choice.** When a document line has no matching posting definition, posting looks for an account of the required type in the document's company. It prefers one whose **Branch** matches the document's branch. Several types are treated as the same during this lookup: Tax Payable is treated as Other Current Liability, Service Income and Other Income as Sales, Purchases as Cost Of Goods Sold, and Rent Expense, Salaries and Employee Wages and General and Administrative Expense all as Expense. Use a posting definition when you need to target one of those accounts specifically. - **Schedule III Classification drives statement placement.** The statements place an account by its **Schedule III Classification**. When that is blank, they derive a classification from the Account Type. **Posting Type** does not change where anything posts or appears. - **Control accounts demand a party.** When **Is Control Account** is ticked, posting refuses any journal line on the account that has no party (customer or supplier), and keeps a balance per party for the subledger. - **Control Type lets features find an account.** Withholding tax, payroll, expenses, company cards and inter-business-unit clearing each look up "the account of control type X" for the company. If none is tagged, the posting stops with a message naming the missing control account. - **Inactive accounts block posting.** A journal line on an account whose **Is Active** is cleared fails to post. An account where the flag was never set is treated as active. - **Default dimensions.** A transaction or journal line that leaves its branch empty inherits the account's **Branch**. The account's **Default Business Unit** is used only as a last resort, after the line, the journal header and the branch have all failed to supply a business unit. - **Hierarchy for reporting only.** An account can have a parent account so the grouped statements roll it up. Posting always goes to the account named on the line, never to its parent. ## Prerequisites - The company exists as an onboarded company. See [Tenants and companies](/docs/concepts/tenants-and-companies/). - You can see the GL Accounts list in the Finance app and have create or edit access to it (see [Permissions](#permissions)). - To seed a chart from a template, you need access to **Setup → Feature Hub → Administration → Org Settings → Companies**. ## Procedure ### Step 1 — Seed the company's chart 1. Go to **Setup → Feature Hub → Administration → Org Settings** and open the **Companies** list. 2. On the company's row, click **Enable finance**. The button only shows while finance is still off for that company. 3. In the **Enable finance** dialog, pick a template from **Select a COA template**. The list shows each template's name, country and version — for example *India — SMB (Services / General)* or *India — Trading (Goods / Inventory)*. 4. Click **Seed Chart of Accounts**. You see "Finance enabled — Chart of Accounts seeded". The company's **Finance** column now shows the template, GL posting is turned on for the company, and the template's accounts appear in GL Accounts. They come with their codes and Schedule III classifications filled in, and the template's control accounts tagged. Accounts whose **Account Code** already exists for the company are skipped, so running it again only adds what is missing. ### Step 2 — Find an account 1. In the Finance app, open **GL Accounts**. The default view, **Chart Of Accounts**, shows **GL Account Name**, **Partner Account**, **Account Number**, **Account Type**, **Posting Type**, **Control Type**, **Account Balance** and **Branch**. 2. Search by name, or filter on **Partner Account** to see one company's chart. 3. Click an account's name to open it. ### Step 3 — Create an account 1. In **GL Accounts**, click **New**. 2. Enter a **Name**. It is required. 3. Choose the **Account Type** (required), and enter an **Account Code** if your chart uses codes. 4. Set **Schedule III Classification** if the account must appear under a heading other than the one its type implies. Leave it blank to use the type's default. 5. Set **Control Type** only for an account a feature looks up by control type (see [Configuration](#configuration)). 6. If you chose Tax Payable, Tax Credit or Other Current Liability, the **Sub Type** field appears. Pick the tax component (CGST, SGST, IGST, UTGST, Cess, VAT, TDS or TCS) when this account holds one component only. 7. Leave **Is Active** ticked. 8. Open the **System Details** tab and choose the **Partner Account** — the company that owns the account. It is required, and only active companies are offered. Optionally choose a **Branch** (only the selected company's branches are offered) and a **Default Business Unit**. 9. Save. The account is immediately available to posting definitions, journal lines and type-based account lookups for that company. ### Step 4 — Mark a control account **Is Control Account** is not on the New or Edit form. It appears on the account's record page, in the **Applicability** section of the **Details** tab. There are three ways to set it: 1. **Use a chart template.** Accounts seeded by **Enable finance** already have it ticked on the receivables and payables controls. 2. **Run Seed Classifications** on a fiscal year of the company (see [Fiscal years and periods](/docs/finance/fiscal-years/)). It ticks the box on every Accounts Receivable and Accounts Payable account of that company that does not have it yet. 3. **Set it by hand.** If your layout lets you change the field on the record page, tick it there and save. If it does not, ask your administrator to add **Is Control Account** to the GL account form layout. Once it is ticked, every journal line on this account must carry a party. Tick it only for customer and supplier controls — receivables and payables. Leave it cleared for tax, withholding, payroll and employee accounts, whose counterpart is not a customer or supplier. ### Step 5 — Change or retire an account 1. Open the account and click **Edit**. The edit dialog has the same tabs and fields as the create form. 2. Change what you need. If the account has a parent or children, the new type or classification must stay in the same statement section (see [Business rules](#business-rules)). 3. To stop postings to the account, clear **Is Active** and save. Any later journal line that names it fails to post, with a message telling you to update the posting definition or journal line. Clearing **Is Active** keeps the account and its history. Before you do, repoint any posting definition that uses the account, or documents relying on it will stop posting. ### Step 6 — Read the account's ledger 1. Open the account. Its record page has **Journals**, **Balances** and **Commitments** tabs listing the records linked to the account, and a **Details** tab with its settings. 2. For a full ledger with running balance, open the Finance app's **Statements** page and choose **GL Account Ledger** under **Ledgers & Valuation**. 3. Pick the **Company**, then the **GL Account**. Optionally narrow by **Branch** or **Party (optional)** — on a receivables or payables control account, the party narrows it to one customer or supplier. 4. Choose a **Period** (Today, Week to Date, Month to Date, Quarter to Date, Year to Date or Custom range…). For a custom range, set **From – To**. 5. Click **Submit**. The ledger shows the opening balance at the start of the window, each posted line with a running balance, and the closing balance. It reads posted journals only — drafts are not included. For every account side by side, use **GL Account Balances** on the same Statements page. ## Fields The New and Edit form has a main **GL Accounts** tab and a **System Details** tab. The record page's **Details** tab groups the account's settings into **Key Information**, **Posting Criteria**, **Applicability** and **System Information** sections. Company, branch and sub type are on the form only; Is Control Account and Item Group are on the record page only. | Field | What it means | Notes | | --- | --- | --- | | Name | The account's name as it appears in lookups, ledgers and statements. | Required. | | Account Type | The economic category of the account. | Required. Drives type-based account lookup and is the fallback for statement placement. Values include Cash, Bank, Accounts Receivable, Accounts Payable, Inventory, Fixed Asset, Accumulated Depreciation, Other Current Asset, Other Current Liability, Tax Credit, Tax Payable, Credit Card, Long Term Liability, Equity, Retained Earnings, Opening Balance Equity, Sales, Service Income, Other Income, Cost Of Goods Sold, Purchases, Expense, Depreciation Expense and more — see the [field reference](/docs/reference/entities/glaccount/) for the full list. | | Account Code | Your chart's code for the account. | Optional, up to 80 characters. Chart templates and **Enable finance** use it to recognise accounts that already exist. | | Posting Type | A broad grouping: Asset, Liability, Equity, Income, Expense or Cost of Goods Sold. | Optional. For display and filtering only; it does not change where anything posts or appears. | | Schedule III Classification | The statement heading the account's balance adds into, for example Trade Receivables, Cash and Cash Equivalents, Revenue from Operations or Other Expenses. | Optional. Blank means "derive from Account Type". An Account Type with no default classification lands under Other Expenses unless you set one here. | | Is Active | Whether the account can be posted to. | Cleared means any journal line on it fails to post. | | Control Type | Which control the account is, for the features that look one up. | Optional. See [Configuration](#configuration) for which values posting recognises. | | Sub Type | The tax component the account holds. | Shown only when Account Type is Tax Payable, Tax Credit or Other Current Liability. Values: CGST, SGST, IGST, UTGST, Cess, VAT, TDS, TCS. When set, a tax amount of that component posts to this account. Blank changes nothing. | | Account Balance | A calculated balance figure shown on the form and in the list. | Read-only. For a balance at a date, use **GL Account Ledger** or **GL Account Balances**, which read the posted ledger. | | Account Group | An optional grouping of accounts. | Optional. | | Partner Account | The company that owns the account. | Required. On the **System Details** tab. Only active companies are offered. | | Branch | The account's default branch. | Optional. Only the selected company's branches are offered. Lines that leave their branch empty inherit it, and type-based lookup prefers an account whose branch matches the document. It does not restrict who can post. | | Default Business Unit | The account's default business unit. | Optional. Used only when the line, the journal header and the branch all leave the business unit empty. | | Item Group | An item group linked to the account. | On the record page's **Applicability** section. | | Is Control Account | Whether the account is a customer or supplier control. | On the record page only. Ticked means every line on the account needs a party. | | Parent GL Account | The account this one rolls up into on grouped statements. | Not on the standard forms; an administrator can add it to the layout. Same company and same statement section required. | ## Business rules - **Posting checks.** When a journal posts, every line needs a GL account. An inactive account stops the post: "GL Account '…' is inactive. Please update the Posting Definition or journal line before posting." A line on a control account with no party stops it too: "Party Account is required on lines posting to a control account." - **Missing control account.** Features that need a control account stop with a message naming it, for example "No TDS Payable control account … is configured." or "No Bank control account is configured for this payroll company." - **Hierarchy rules** — checked whenever an account's parent, type, classification or company changes: - "A GL account cannot be its own parent." - "The selected parent GL account does not exist." - "Parent GL account '…' belongs to a different company." - The parent must be in the same statement section as the child, or you see "A parent must belong to the same statement section as its children." - A link that would loop back on itself is refused with "… would create a cycle in the chart of accounts." - Changing a parent's type or classification is refused if its children would be left in another section: "Re-parent the children first or keep the account in its current section." - **Inherited classification.** A child account whose type has no default classification, and which has no classification of its own, takes its parent's Schedule III Classification when saved. - **Seeding.** - **Enable finance** adds the template's accounts the company lacks, matched by Account Code. On an existing account whose code and name still match the template, it also fills in an empty Control Type. It never overwrites a Control Type that is already set, and never touches a renamed account. - Ticking **GL Posting Enabled** on a company's account record adds a standard starter set of 26 accounts (Cash, Petty Cash, Bank, Accounts Receivable, Inventory, Accounts Payable, GST Payable, Retained Earnings, Sales, Cost of Goods Sold, Rent Expense and others). Each is named after the company — for example *Cash - Larkspur Advisory* — with a four-digit code, and marked **Is System**. **Enable finance** also turns GL posting on. After enabling, check the list: if starter accounts named after the company appear beside the template's, clear **Is Active** on the ones you do not use. - **Is System** only records where an account came from. It does not lock the account. - **Seed Classifications.** On a fiscal year, **Seed Classifications** fills in Schedule III Classification from Account Type for every account of that company that has none. It also ticks **Is Control Account** on Accounts Receivable and Accounts Payable accounts and sets their control type. See [Fiscal years and periods](/docs/finance/fiscal-years/). ## Example A services company has just been onboarded as *Larkspur Advisory*. The finance lead goes to Org Settings → Companies, clicks **Enable finance** and seeds *India — SMB (Services / General)*. The GL Accounts list now shows the company's chart, including Trade Receivables (control account for receivables), TDS Receivable, TDS Payable and Bank Current Account. The company also earns training fees and wants them separate from consulting income. The finance lead clicks **New** and enters: - **Name**: Training Fees. - **Account Type**: Service Income. - **Account Code**: 4120. - **Schedule III Classification**: Revenue from Operations. - **Partner Account** (System Details tab): Larkspur Advisory. Because Service Income is treated as Sales during type-based lookup, the lead also adds a posting definition for training items pointing at Training Fees. Otherwise those invoices could land on the general sales account. Payroll will pay salaries from Bank Current Account. The lead goes to Org Settings → Companies and clicks **Set default bank**. The dialog says "No Bank control account", because the template does not tag the bank account. The lead opens Bank Current Account, sets **Control Type** to Bank, saves, and returns to **Set default bank** to select it. At month end, the lead opens **GL Account Ledger**, picks Training Fees and Month to Date, and clicks **Submit** to check every invoice that posted to it. ## Training ### Practice exercise In a sandbox with at least one onboarded company: 1. Create a GL account *Practice Expense* of type Expense for that company, with no Schedule III Classification. 2. Open the record and confirm the **Details** tab shows Account Type Expense and Is Active ticked. 3. Create a draft manual journal: debit *Practice Expense* 100, credit the company's cash account 100. Post it. 4. Open **GL Account Ledger** for *Practice Expense* with Month to Date, and click **Submit**. 5. Clear **Is Active** on *Practice Expense*, then try to post a second journal that uses it. **Expected result:** step 4 shows one line of 100 with a closing balance of 100. Step 5 fails with "GL Account 'Practice Expense' is inactive. Please update the Posting Definition or journal line before posting." ### Quick reference - Every account belongs to one company — set **Partner Account** on the System Details tab. - **Account Type** drives automatic account choice; **Schedule III Classification** drives statement placement; **Posting Type** drives neither. - Tick **Is Control Account** only on customer and supplier controls; it makes a party mandatory. - Withholding, payroll and expense controls need **Control Type** but not **Is Control Account**. - Clear **Is Active** to retire an account; repoint its posting definitions first. - **Enable finance** is safe to re-run: it only adds missing accounts. - Use **GL Account Ledger** for an account's lines and running balance, **GL Account Balances** for all accounts at once. ## Permissions Access to GL accounts follows the user's [security profile](/docs/administration/security-profiles/): its entity permission on GL Account decides whether the user can see the list, create, edit or delete accounts. The standard System Admin, Standard User, Sales Manager and Sales Executive profiles ship with full access to GL Account. Review that if sales users should not change the chart. On the **Companies** list in Org Settings, the **Onboard company**, **Enable finance**, **Set default bank** and **Withholding tax timing** buttons appear only for users whose profile grants the capability to manage companies. ## Configuration **Chart templates.** **Setup → Feature Hub → Administration → Org Settings → Companies → Enable finance** seeds a company's chart from a template. Two templates ship: *India — SMB (Services / General)* and *India — Trading (Goods / Inventory)*. Both tag the receivables and payables controls (with Is Control Account ticked) and the TDS Receivable, TDS Payable and TCS Payable controls (with Is Control Account cleared). Once enabled, the button disappears from that company's row. **Control types that posting looks up.** Each feature finds its account by an exact match on Control Type within the company, so keep exactly one account per control type per company: | Feature | Control the company needs | | --- | --- | | Withholding on invoices, bills and receipts | Accounts receivable, accounts payable | | TDS on bills and invoices, TCS on sales | TDS payable, TDS receivable, TCS payable | | Payroll payment batches | Bank — see **Default bank** below | | Payroll posting, full and final settlement, statutory challans | Payroll payable and the statutory payables (PF, ESI, professional tax, TDS on salary, LWF), gratuity provision | | Expense claims and advances | Employee payable, employee advance | | Company card transactions, when the card names no payable account | Credit card payable | | Journals spanning several business units | Inter-business-unit clearing — if no account has it, the balancing lines are simply not added | Tick **Is Control Account** only on the receivables and payables controls. The withholding, payroll, statutory, employee and inter-business-unit controls are designed with it cleared, because their lines carry no customer or supplier. Posting matches the stored control-type value exactly, without spaces: AccountsReceivable, AccountsPayable, TdsPayable, TdsReceivable, TcsPayable and so on. The chart templates write exactly those values. The **Control Type** list on the form offers the multi-word ones with spaces (for example *TDS Payable*), and posting does not recognise that spelling. Single-word values such as **Bank** and **Inventory** match either way. So, for multi-word controls, rely on **Enable finance** — run it again to fill in a missing tag — or ask your administrator to set the value through the Setup Copilot or a data import. **Default bank.** **Org Settings → Companies → Set default bank** chooses which Bank control account money leaves from when a disbursement does not name one; payroll's payment batch reads it. Only the company's accounts with Control Type Bank are offered. A company with more than one bank account must set it. **Statement classification.** After importing a chart, run **Seed Classifications** on a fiscal year of the company, then override individual accounts by hand. **Posting definitions.** To target a specific account rather than "the first account of this type", create a posting definition in the Finance app's Settings. See [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/#posting-definitions). **Numbering.** GL accounts ship with a document-name setting (series GLA) that is inactive, so account names are whatever you type. ## Common problems ### Posting fails with "GL Account '…' is inactive" **Cause:** a journal line, or the posting definition behind a document, points at an account whose **Is Active** is cleared. **Fix:** re-activate the account, or change the posting definition or journal line to an active account, then post again. ### Posting fails with "Party Account is required on lines posting to a control account" **Cause:** the line's account has **Is Control Account** ticked and the line has no customer or supplier. **Fix:** add the party to the line. If the account is a tax, withholding, payroll or employee account, **Is Control Account** should not be ticked on it — have it cleared on the record page (see Step 4), because those controls must not demand a party. ### An invoice or bill with TDS or TCS will not post: "No TDS … control account is configured" **Cause:** no account in the company has the matching control type, or it was set with spaces from the form's list. **Fix:** go to Org Settings → Companies and run **Enable finance** again with the company's template; it adds the missing withholding accounts and fills empty tags. If the chart was imported or built by hand, have an administrator set the exact control-type value on the right account. ### "Set default bank" says "No Bank control account" **Cause:** none of the company's accounts has Control Type Bank. Chart templates do not tag the bank account. **Fix:** open the bank account, set **Control Type** to Bank, save, and try again. ### An account appears under the wrong heading on the statements **Cause:** its **Schedule III Classification** is blank and the default for its Account Type is not what you want, or the type has no default and the account fell into Other Expenses. **Fix:** set the **Schedule III Classification** explicitly. The statements change as soon as you save. ### Saving fails with "A parent must belong to the same statement section as its children" **Cause:** the account and its parent resolve to different statement sections. **Fix:** choose a parent in the same section, or correct the type or classification so both land in the same section. ### GL Account Ledger says "GL account has no company; cannot run the ledger." **Cause:** the account has no **Partner Account**. **Fix:** click **Edit** on the account, set **Partner Account** on the **System Details** tab, save, and run the ledger again. ## Common questions ### Should I delete an account I no longer use? Clear **Is Active** instead. A deactivated account keeps its posted history and refuses new postings with a clear message. Before deactivating, repoint any posting definition that uses the account. Otherwise invoices, bills or payments that resolve to it will fail to post until someone changes the definition. Deleting is meant for accounts created by mistake that never received a posting. ### What is the difference between Account Type, Posting Type and Schedule III Classification? **Account Type** is the economic category, and posting uses it to find an account when no posting definition matches. **Schedule III Classification** is the statement heading the balance adds into; when blank, it is derived from the Account Type. **Posting Type** is a broad label for display and filtering, and changing it does not move any posting or any statement line. To move an account on the statements, change its Schedule III Classification. ### When do I tick Is Control Account? Only for accounts that summarise customer or supplier balances — the receivables and payables controls. Ticking it makes a customer or supplier mandatory on every line, and keeps a balance per party for the subledger. Tax, withholding, payroll, employee, bank and credit-card controls also carry a Control Type, but leave Is Control Account cleared on them. Their counterpart is a tax authority, an employee or a bank, so their lines carry no customer or supplier and would otherwise fail to post. ### Do I need a separate chart for each branch? No. The chart belongs to the company, and branches share it. Give an account a **Branch** only when it should be that branch's default. Lines that leave the branch empty inherit it, and type-based lookup prefers the account whose branch matches the document. The branch does not stop other branches from posting to the account. For branch-wise figures, filter the ledger or statements by branch. ## Related topics - [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) - [Working with journals](/docs/finance/journals/) - [AR and AP subledgers](/docs/finance/subledgers/) - [Financial statements](/docs/finance/statements/) - [Fiscal years and periods](/docs/finance/fiscal-years/) - [TDS and TCS](/docs/finance/tax-center/tds-tcs/) - [GL Account field reference](/docs/reference/entities/glaccount/) ---- # xMatix Finance & Accounting URL: https://xmatix.com/docs/finance/ Last reviewed: 2026-09-01 ## Read the accounting context @[guided-image](_img/finance-overview.png) The manual-journal header demonstrates Finance's governing coordinates: partner account, branch, journal type, document date and source reference. The partner account scopes fiscal-period and GL resolution, the date selects the fiscal period, and source provenance explains why the accounting event exists. **Manual** is the create-form default, but it is not reliable evidence that an existing row was entered by hand: document-generated draft journals can carry that value too. Use **Source Entity Name**, **Source Record** and narration to establish provenance. Before posting, verify the period is open, debits equal credits, dimensions are complete and control-account lines carry required party context. Prefer invoice, bill, payment, inventory or asset workflows where they exist, because their journals retain stronger source-to-ledger evidence. xMatix Finance is a double-entry ledger shared by operational documents and direct finance workflows. A business document affects the ledger only when its implemented posting action or service runs; approval by itself is not a universal posting trigger. This section documents the ledger model, the day-to-day procedures, and the statement screens. ## The mental model Four ideas explain most of what you will see in the Finance app: - **The journal is the ledger.** A value movement reaches the ledger as a balanced journal. Posted lines are immutable; the supported correction is a linked reversal rather than an edited line. - **Posting is document-specific.** Invoice, bill, payment, inventory, depreciation and other handlers each define their own posting action and validation. Confirm the generated journal instead of assuming that a status change posted it. Invoice e-invoice and e-way-bill actions also depend on their configured provider path. - **Statements read the posted ledger.** Trial Balance, P&L, Balance Sheet and the other statement services derive their results from posted period balances when the statement is generated. There is no separate report datastore for an accountant to maintain. - **Dimensions are resolved at posting.** Journal-line dimensions can come from the header, GL defaults and the selected branch. Verify the resulting branch and business unit on the saved lines; missing configuration can still leave an intended reporting slice incomplete. ## The Finance app | Area | What it holds | | --- | --- | | Home | The finance landing page | | Documents | Invoices, bills, expense vouchers, payments, journals, GL accounts | | Adjustments | Credit notes and debit notes | | Banking | Bank transfers, bank statements, cheque transactions, cheque registers | | Statements | The fifteen statement screens — see [Financial statements](/docs/finance/statements/) | | Reports and Dashboards | Finance reports and the finance dashboard collection | | Settings | The setup masters: fiscal years, business units, cost centers, bank accounts, budgets, posting definitions, accounting books, inventory valuation policies, revenue recognition schedules and more | What a person sees in the Finance app is governed by their [security profile](/docs/administration/security-profiles/), installed app/page metadata and tenant configuration. Check all three when a screen is absent. ## What is in this section - [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) — GL accounts, accounting books, posting definitions and the fiscal calendar. - [GL accounts](/docs/finance/gl-accounts/) — seed a company's chart, create and retire accounts, tag control accounts and read an account's ledger. - [Fiscal years and periods](/docs/finance/fiscal-years/) — create a fiscal year, generate its periods and days, control posting and close the year. - [Working with journals](/docs/finance/journals/) — manual journals, posting, reversal and recurring journals. - [AR and AP subledgers](/docs/finance/subledgers/) — how documents create open items, settle, and reconcile to control accounts. - [Recording and applying payments](/docs/finance/payments/) — customer receipts and supplier payments. - [Banking](/docs/finance/banking/) — bank accounts, statements and the cheque register. - [Bank reconciliation](/docs/finance/banking/bank-reconciliation/) — the match workspace, suggestions and auto-reconcile. - [Financial statements](/docs/finance/statements/) — every statement screen and what it answers. - [Fiscal periods and period close](/docs/finance/period-close/) — period statuses, month-end close, reopen and lock, and ledger checks. - [Budgets and budget control](/docs/finance/budgets/) — budgets, availability and budget vs actual. - [Revenue recognition](/docs/finance/revenue-recognition/) — deferred revenue schedules and scheduled recognition runs. - [Interest on overdue payments](/docs/finance/interest-on-overdue/) — policies, accrual runs and posting. - [Fixed assets](/docs/finance/fixed-assets/) — the asset register, depreciation policies and asset blocks. - [Running depreciation](/docs/finance/fixed-assets/depreciation/) — recurring depreciation runs and disposals. Payroll accounting and expense claims have their own products — see [xMatix Payroll](/products/payroll/) and [xMatix Expenses](/products/expenses/) — and post into this same ledger. ## Related topics - [xMatix Finance & Accounting product overview](/products/finance/) - [Apps, entities and records](/docs/concepts/apps-entities-records/) — how xMatix screens are organized. - [Administration guide](/docs/administration/) — access, security and data management. ---- # Interest on overdue payments URL: https://xmatix.com/docs/finance/interest-on-overdue/ Last reviewed: 2026-09-06 xMatix can charge interest on overdue receivables automatically: policies define the rate and terms, an accrual run computes a charge per overdue item, and posting a charge raises a customer **debit note** — a document the customer can book against — that carries the interest into receivables, where it ages like any other open item. Every charge carries a calculation note you can re-derive by hand, and the accrual arithmetic is cadence-independent: run it monthly, quarterly or once a year and the total charged is the same to the paisa. ## Prerequisites - Overdue open items — interest is levied on posted receivables, so an invoice that never posted can never be charged (see [Subledgers](/docs/finance/subledgers/)). - An **interest income** GL account for the company. Set this up **before** the first posting run: with none configured, resolution falls back to a generic income account and posts there without complaint, and moving history to a dedicated account later is a manual reclassification. Leave the account's branch empty — a branch-pinned account serves only that branch's charges, and charges on other branches fail to post. ## Procedure @[guided-image](_img/new-interest-run.png) ### Step 1 — Create the policy In the Finance app open **Interest Policies** and create one. Give it a clear effective date range and scope, then save and reopen it to confirm the stored rate, period, method and priority. The essentials are: | Setting | Meaning | | --- | --- | | Direction and scope | Receivable; company-wide, or pinned to one customer for negotiated terms | | Rate and period | Enter the rate as the contract quotes it — 2% per month and 24% per annum are the same policy | | Method | Simple, or compound with a compounding frequency | | Basis | Outstanding balance (default, and the accurate one — a part-payment reduces accrual from its date), original amount, or current open amount | | Day count | The convention for converting days to interest — 365, 360, actual/actual and others | | Grace days | Accrual starts the day after grace ends | | Minimum days overdue | A tolerance on top of grace — below it, nothing is charged | | Minimum charge | A de-minimis floor; a below-floor charge is skipped and the interest keeps accruing to a later run | | Maximum charge | A cumulative ceiling as a percentage of the document's face value | | Charge on settled items | On by default — a late payer still owes for the days it was late | When several policies could apply, the narrowest wins: customer-and-company beats customer, beats company, beats tenant-wide, with priority as the tie-break. The usual pattern is one company-wide policy plus per-customer overrides. To change a rate cleanly from a date, end-date the current policy and create a successor effective the day after—accrual windows split at the boundary. Check there is neither an overlap nor a one-day gap before proceeding. ### Step 2 — Preview before charging anyone In the Finance app open **Interest Runs** and create one. The **Scope** section holds a **Name**, an auto-generated **Label** (as-of date and direction), the **As Of Date**, the **Direction** (*Receivable*) and four optional scope fields — **Company**, **Party**, **Branch** and **Business Unit**. Turn **Is Preview** on, save, and run **Compute Interest Run**. A preview cannot post and does not consume the accrual window. Read the run message, reconcile evaluated/charged/skipped counts, spot-check principal and overdue days against several invoices, and confirm the expected policy won by reading each charge's rate and calculation note. Each charge's **calculation note** re-derives the amount in words — window, principal, rate, day count, result — so verifying one by hand takes a minute. ### Step 3 — Run the accrual, or schedule it After the preview is approved, create or compute a real run (Is Preview off) with the exact same as-of date and scope, or let the administrator's scheduled accrual job do so. Compare its summary total and charge count with the approved preview before review. Cadence is a business preference: contiguous windows prevent gaps and overlaps, a missed month is absorbed by the next run, and rerunning through the same date should report items already charged rather than create duplicates. ### Step 4 — Review, waive or cancel Review every material or exceptional charge before posting and record the commercial reason for any intervention. Two tools have opposite effects: - **Waive a charge** — the **Waive Interest Charge** action on the charge, with a reason — when the interest is commercially agreed away. Waiving is permanent — the window stays consumed and those days are never re-charged. - **Cancel the run** — **Cancel Interest Run**, with a reason — when the whole computation is wrong. Cancelling releases the days, so a later run re-charges them correctly. If you might want the days back, cancel—never waive. After either action, verify the run total and charge status changed as intended before anyone posts it. ### Step 5 — Post to the ledger Run **Post Interest Run** on the reviewed run once and wait for the per-charge result (a preview run refuses to post). Each successful charge raises and posts a customer debit note: receivables is debited, interest income credited, with tax legs where applicable. Open a sample note and verify customer, source invoice, principal window, tax and amount before accepting the batch. Mixed-tax invoices are flagged for review, and invoices with no captured tax detail are skipped for manual handling rather than charged at a guessed rate. Posting processes the remaining Draft charges and leaves a failed charge available for correction and retry. Already completed charges are not the retry population. If no Draft charge remains, invoking the posting operation again produces a validation error rather than a no-op success; use the stored run/charge statuses to decide whether a retry is appropriate. ### Step 6 — Verify Read the final run message and reconcile items evaluated, charges computed, skips by reason, failures and total posted. Confirm every posted charge carries a debit-note link, failed charges remain retryable, and the interest appears on the customer's statement and ageing. At month-end, tie the interest-income GL movement to posted charges for the same dates and investigate any difference before period close. ## Expected result The approved real run matches its preview except for documented data changes, waived charges retain their consumed windows, and cancelled runs release theirs. Each successful receivable charge has one posted debit note and open item, failures remain visible for retry, and the interest-income control total reconciles to the run. ## Common problems **The run computed zero charges.** Read the run message — it names the reason per item. The common ones are all correct behavior: items within grace or tolerance, items already charged to date, and charges below the minimum (which keep accruing and land on a later run). An actual configuration gap shows up as "no active policy applies" — check the policy's active flag, direction, effective dates and scope. **A charge failed to post.** Almost always the interest income account (missing, or branch-pinned — see Prerequisites) or a closed fiscal period. Fix the cause and post again; already-posted charges are skipped automatically. **Interest went to the wrong income account.** The resolution fallback posted it to a generic income account because no dedicated interest income account existed at the time. Configure the account now for future runs; the posted history can be moved with a manual reclassification [journal](/docs/finance/journals/). ## Common questions ### Does previewing a period cost us the revenue for it? No. Preview charges are excluded from the accrual watermark, so the days a preview covered remain chargeable by the next real run. Preview freely — it is the intended rehearsal step. ### Why is the interest posted as a debit note rather than a plain journal? Because the customer needs a document to book against, and because downstream records classify the transaction by its source document. The debit note gives the interest a document number, its own open item that ages normally, and a clean trail from charge to note to journal. ### Can interest be charged on interest? Not by stacking charges — interest open items are excluded from the accrual's scope, so a posted charge never becomes the principal of a later one. Contractual interest-on-interest is expressed properly instead: set the policy's method to compound with the agreed rest. ### What about interest we owe suppliers? The platform permits a Payable-direction run to post; this is not technically limited to disclosure. Whether it should be posted is an accounting-governance decision. Verify the supplier's supporting document and the organization's policy before doing so—the current handler will not enforce that evidence requirement for you. ## Related topics - [AR and AP subledgers](/docs/finance/subledgers/) - [Recording and applying payments](/docs/finance/payments/) - [Working with journals](/docs/finance/journals/) ---- # Working with journals URL: https://xmatix.com/docs/finance/journals/ Last reviewed: 2026-09-02 Most operational documents create journals through their posting handlers. Manual journals cover opening balances, accruals, corrections and reclassifications. Posting requires balanced debit and credit lines and an Open period. Posted lines are guarded against editing; use reversal for corrections rather than changing ledger history. ## Find and verify an existing journal @[guided-image](_img/journal-list.png) The list is the safest starting point because it exposes document date, status, source entity and narration together. In the example, rows with **Journal Type Name = Manual** also say **Auto-generated journal** and identify an expense source. That is why journal type must not be used as the sole test of manual entry. Open the source-linked record when provenance matters. @[guided-image](_img/journal-detail-lines.png) The **Lines** tab is the accounting evidence. Read every GL account, debit, credit and narration, then independently total each side. The populated draft shown here has two expense debits of 3,000 and 1,500 and one bank credit of 4,500, so the visible lines balance before posting. @[guided-image](_img/journal-detail-details.png) The **Details** tab explains the header and source relationship. Its financial summary agrees at 4,500 on each side, while **Source Entity Name** and **Source Record** lead back to the expense voucher. The record is still Draft, so blank posting fields are expected and this image must not be read as proof that the journal reached the ledger. ## Prerequisites - Finance access that includes journals — granted through your [security profile](/docs/administration/security-profiles/). - An **Open** fiscal period covering the journal date (see [the fiscal calendar](/docs/finance/chart-of-accounts/)). - The GL accounts you intend to post to. ## Procedure @[guided-image](_img/new-journal.png) ### Step 1 — Create the journal In the Finance app open **Journals** and create a new journal. Select the required Partner Account, optional Branch and a Document Date inside the fiscal period you intend to affect. Journal Type Name defaults to **Manual**. The create layout does not ask for a human-entered journal name or reference; the platform generates the journal identity. **Source Entity Name** and the **References** tab are system provenance, not a replacement for an external evidence reference. Save the Draft header, reopen it and verify the generated identity, organization and date before adding lines. ### Step 2 — Add balanced lines Add one line per account movement with the GL account, either a debit or credit amount, and a narration that explains the business reason. Stamp branch and business unit where applicable; statement dimension filters work only when postings carry those dimensions. A control-account line must name its customer or supplier. Before posting, compare debit and credit totals, scan for reversed signs or duplicate lines, and confirm the displayed difference is zero. ### Step 3 — Post it Use **Post** only after a second-person review where your control process requires one. Wait for the status to change from Draft to **Posted**, then reopen the journal and verify its number, fiscal period, totals, posting timestamp and line dimensions. The posting service updates period and account balances in the same unit of work. If posting is refused, correct the named cause—fewer than two lines, an invalid debit/credit side, unbalanced totals, an inactive or missing GL account, a non-open period or a control-account line without a party—and retry the same draft instead of creating another journal. ### Step 4 — Correct with a reversal Open the posted journal and choose **Reverse**, supply the reversal date and reason, and confirm the date falls in the period where the correction should land. The system posts a linked mirror journal—every debit becomes a credit and vice versa—while retaining the original. Verify the two journals link to each other and net to zero, then create a fresh journal if the correct transaction still needs posting. Never compensate by editing history or by entering an unlinked opposite journal. ### Step 5 — Set up recurring journals For a repeated entry such as rent accrual or a standing allocation, create a recurring journal template with balanced lines, cadence, next run date and optional end date. Materialization is currently driven by the scheduler; there is no first-party on-demand “run now” journal action. After the scheduled run, confirm the expected journal was created once, its date is in an Open period and the template's next-run date advanced. ## Expected result The manual journal posts once with balanced lines into the intended Open period. Corrections appear as linked reversals. Recurring templates create journals only when the scheduler processes them, so monitor both generated output and next-run state. ## Common problems **The journal will not post.** Check the three gates in order: debits equal credits, the journal date falls in an Open period, and every control-account line names a party. The error message tells you which gate failed. **It posted to the wrong period.** The period comes from the journal date. Reverse the journal, then re-enter it dated inside the period you intended — assuming that period is still open. **A recurring journal did not appear.** Check the template is active and its next run date has arrived. A template whose next run date is in the future has simply not come due. ## Common questions ### Can I edit or delete a posted journal? Posted journal lines are protected and the supported accounting correction is a linked reversal. The current header guard is narrower: it rejects changing the status of a posted journal but does not comprehensively reject every other header-field edit at the handler layer. Operational permissions and layouts should therefore keep posted headers read-only as well; do not interpret the backend line guard as blanket header immutability. ### Which period does a journal land in? The period containing its journal date, validated against the fiscal calendar at posting time. Entering a journal today with last month's date posts it into last month — provided that period is still open. This is the same rule documents follow, so a backdated invoice and a backdated journal behave identically. ## Related topics - [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) - [AR and AP subledgers](/docs/finance/subledgers/) - [Closing a period](/docs/finance/period-close/) ---- # Recording and applying payments URL: https://xmatix.com/docs/finance/payments/ Last reviewed: 2026-09-06 A Payment records money received or paid and can allocate that amount against eligible open documents. In the current handler, an ordinary new payment whose finance partner can be resolved is GL-approved and posted during the insert flow. There is no guaranteed clerk-records/controller-approves gap, so complete the review before saving. ## Prerequisites - The intended account must resolve to the finance partner used by posting. - The documents to settle must already be eligible for the Open Documents query. - Cash and other payment accounts must be mapped through the posting configuration used by the handler. - The operator must understand the payment-mode gaps described below before choosing Bank, Cheque or Electronic Transfer. ## Procedure @[guided-image](_img/new-payment.png) ### Step 1 — Select the account and inspect the candidates Create a Payment and select **Account** first. Wait for the “updated” indicator, then compare the returned document number, type, date, document amount and open amount with the remittance. The result can contain orders as well as invoices, depending on the open-transaction source. Do not allocate by age alone when the remittance identifies a specific document. If the grid says no account context is available, stop and correct the account selection or finance-partner setup. Saving without a resolvable partner is not a substitute for a valid settlement context. ### Step 2 — Enter the amount and allocations Enter the total payment Amount. Select the intended open rows and enter an allocation amount for each. Compare Document Amount, Adjusted Amount and Open Amount before continuing. A partial allocation can leave an open balance; an allocation of zero does not settle the row. Keep the sum of entered allocations consistent with the payment evidence. Any deliberate unapplied amount should be supported by the business process used in your deployment and verified after posting. ### Step 3 — Choose the payment mode carefully The widget offers Cheque, Cash, Bank and Electronic Transfer, but the current UI and posting code do not use one shared set of values: - **Cash** posts the money side to the Cash account type and is the least ambiguous first-party mode. - The visible **Bank** choice is not one of the posting handler's explicit modes; it falls through to the cash-account path. It also renders card-oriented fields. Do not use it as proof that a bank GL account will be selected. - **Electronic Transfer** posts to the Bank account type, but the current widget exposes no transfer-reference input — **Transaction Reference** is saved empty and has to be filled on the record afterwards. - **Cheque** parks the money in the Cheques-In-Hand suspense account until the cheque clears (falling back to Bank when no suspense account is configured), and the save records a linked cheque transaction (issued or received) in the cheque register; the widget writes the mode to both `ModeOfPayment` and the legacy `PaymentMode` field so that automation sees it. Verify the cheque transaction exists after saving. - The posting handler also recognizes **Card** (Bank for money received, Credit Card for money paid) even though the visible selector offers Bank. Never put a full card number in documentation or support screenshots. Until those contracts are aligned and tested, use the mode approved for the deployed tenant and verify the resulting GL account and evidence record immediately after save. ### Step 4 — Review before Save Re-check the account, direction of payment, total, selected mode and every allocation. Saving can trigger approval/posting in the same insert transaction when the finance partner resolves. After Save succeeds, open the resulting Payment and verify: 1. status and generated document number; 2. ledger direction and selected cash/bank account; 3. each allocation and remaining open balance; and 4. any cheque or transfer evidence that the chosen mode was expected to create. If any of those differs, use the supported correction or reversal flow for the deployment. Do not create a second payment merely to make the screen look right. ## Payment batches The current Payment Batch service only exposes an aggregate-total helper; the audited code has no first-party handler, action or scheduled job that executes a bulk payment run. This guide therefore does not describe a batch procedure. Treat any tenant-specific batch screen as custom until its posting and retry behaviour is verified. ## Common problems **Open Documents remains empty.** Confirm the selected account resolves to the expected finance partner and that the source documents are posted and still open. The empty initial state is not evidence that there are no receivables or payables. **Bank posted to cash.** The visible Bank value currently misses the posting handler's explicit cases and falls through to cash. Correct the mode contract or posting implementation before using the option operationally. **A cheque is missing from the cheque register.** The register entry is created during the GL posting of a payment whose `PaymentMode` is Cheque; a payment created outside the standard form (an import or an integration that set only `ModeOfPayment`) skips it. Verify the payment itself, then fix the source rather than re-entering the cash movement. **The payment posted immediately.** That is the current normal insert path when the finance partner resolves; a separate controller approval is not guaranteed. ## Common questions ### Can a customer make a partial payment? The allocation model supports entering less than the open amount. Verify the source document's remaining balance after posting; do not rely solely on the unsaved grid calculation. ### When does a document stop appearing as open? When the posting and allocation state consumed by the open-transaction query shows no remaining balance. Recording an unapplied payment is not the same as settling a particular row. ### Is there a review stage between Save and posting? Not reliably in the current ordinary insert path. Review before Save and test any tenant-specific approval metadata against the actual handler behaviour. ## Related topics - [AR and AP subledgers](/docs/finance/subledgers/) - [Banking](/docs/finance/banking/) - [Bank reconciliation](/docs/finance/banking/bank-reconciliation/) ---- # Fiscal periods and period close URL: https://xmatix.com/docs/finance/period-close/ Last reviewed: 2026-10-10 A **fiscal period** is one month of a company's fiscal year, and its status — **Open**, **Closed** or **Locked** — decides whether anything can still post into that month. Periods are created from the [fiscal year](/docs/finance/fiscal-years/); this page covers what happens to them afterwards: reconciling the month, checking the period's ledger, closing it, reopening it for an approved correction, and locking it once the figures are final. ## Overview Every journal in xMatix — a manual entry, or the journal an invoice, bill, payment, expense claim or stock movement generates — belongs to exactly one fiscal period: the period of the journal's company whose start and end dates cover the journal date. Other finance records also pin themselves to a period, among them currency revaluations, revenue recognition schedule lines, TDS transactions, budget lines and payroll periods. A period moves through three statuses: | Status | Accepts postings | Can be changed back | Can be deleted | | --- | --- | --- | --- | | Open | Yes | — | Yes | | Closed | No | Yes, with **Reopen Period** | No | | Locked | No | No — Locked is final | No | Each period record also carries two ledger tools: **Verify Ledger**, which checks the period's stored balances against the posted journals, and **Rebuild Balances**, which recalculates those balances from the posted journals. ## When to use it - **Month-end** — once a month is reconciled, close its period so nothing more can post into it. - **An approved late entry** — reopen a Closed period, post the correction, and close it again. - **Final sign-off** — after audit or a statutory filing, lock the period so it can never be reopened. - **Before trusting a balance** — run Verify Ledger when a trial balance or party balance for the month looks wrong, and Rebuild Balances when it reports drift. ## How xMatix handles it - **The date picks the period.** You never choose a period on a document. When a journal is saved or posted, xMatix finds the period of the journal's company that covers the journal date. A period with no company applies to every company; when both exist, the company's own period wins. - **Two gates.** Posting needs an **Open** period inside a fiscal year whose own **Status** is also `Open`. Either one failing stops the save or the post with a message naming the period. - **Drafts get their period on save.** A new journal, or a journal whose date changes, is given its period when it is saved, and posting looks the period up again from the final date. A draft whose date is unchanged keeps the period it already has, so editing the narration of an old draft is not blocked by a period closed since. - **A missing month is filled in for you.** If a posting date has no period at all, xMatix creates an April–March fiscal year for the company with twelve Open monthly periods and posts into it. It never reopens a Closed or Locked period to do so. - **Actions move the status.** **Close Period** (Open → Closed), **Reopen Period** (Closed → Open) and **Lock Period** (Open or Closed → Locked). Every action updates the period's fiscal days to the same status. - **No built-in close checklist.** Close Period changes the status only. It does not check for draft journals, failed postings or unreconciled banks — that review is yours to do before you close. ## Prerequisites - The fiscal year and its periods exist — see [Fiscal years and periods](/docs/finance/fiscal-years/). - Your security profile has permission on Fiscal Period and grants the period actions you need (see Permissions). - The **Close Period**, **Reopen Period**, **Lock Period**, **Verify Ledger** and **Rebuild Balances** buttons are on the fiscal period record page. The page that ships with xMatix shows only **Edit** and **Delete** in its header; an administrator adds the period actions to the layout once (see Configuration). ## Procedure ### Step 1 — Finish and reconcile the month Before you close, make sure the month is complete: 1. Post every document and journal dated in the month, and deal with any journal still in Draft — post it, re-date it or delete it. 2. Resolve failed postings. 3. Complete the month's [bank reconciliation](/docs/finance/banking/bank-reconciliation/). 4. Tie the receivable and payable control accounts to their open items (see [AR and AP subledgers](/docs/finance/subledgers/)), and review open expense claims and advances. 5. Post the month's inventory valuation adjustments, if you run them. 6. Keep the reports you relied on, with the date you ran them, so a reviewer can reproduce the result later. ### Step 2 — Verify the period's ledger 1. Open the fiscal period record — for example **Apr 2026** of your fiscal year. 2. Check its **Start Date**, **End Date**, **Fiscal Year** and **Status** (`Open`). 3. Select **Verify Ledger**. xMatix re-adds the posted journals of the period and compares them with the stored figures. The result reports: - how many GL balances it checked and how many did not match; - how many party balances it checked and how many did not match; - how many posted journals do not balance (debits not equal to credits); - how many open items have an open amount that differs from their original amount minus their posted allocations; - a list of the first 100 findings. Verify Ledger changes nothing. The open-item check covers all open items, not only the ones dated in this period. ### Step 3 — Rebuild balances if Verify Ledger found drift If GL or party balances are reported as mismatched, select **Rebuild Balances** on the same period. xMatix recalculates the period's GL and party balances from its posted and reversed journals, saves them, and then runs Verify Ledger again and shows that result. Mismatches should now read zero. Rebuild Balances does not change journals, and it does not correct open-item amounts or unbalanced journals — those findings need the source document or journal fixed. ### Step 4 — Close the period On the period record, select **Close Period**. The **Status** becomes `Closed`, and the period's fiscal days become Closed too. From now on any document or journal dated in the month is refused. Close Period works only on an Open period. On any other status it stops with *Period is Closed; only Open periods can transition to Closed.* (the message names the current status). ### Step 5 — Reopen for an approved correction If a valid entry still belongs in a Closed month: 1. Get the correction approved under your close policy. 2. On the period record, select **Reopen Period**. The status returns to `Open`. 3. Post the correction, repeat the checks from Steps 1 to 3, and select **Close Period** again. Reopen Period works only on a Closed period. A Locked period cannot be reopened. ### Step 6 — Lock the period after final sign-off When the month's figures are final — after audit or filing — select **Lock Period**. An Open period is closed and locked in one step; a Closed period is locked directly. The status becomes `Locked` and stays that way: xMatix refuses any later change that would move it out of Locked, whether by an action or by editing the record. ### Step 7 — Close the year Year-end is a separate step on the fiscal year, not on a period: **Close Year** posts the closing journal on the last day of the year, so run it while the last period is still Open, then close and lock the remaining periods. See [Fiscal years and periods](/docs/finance/fiscal-years/). ## Fields The fiscal period record page shows **Partner Account** in the header, then two panels. | Field | What it means | Notes | | --- | --- | --- | | Partner Account | The company the period belongs to | Copied from the fiscal year by Generate Periods. Blank means the period applies to every company. Hidden when your organization runs a single company. | | Fiscal Year | The year the period belongs to | Shown under **Key Information**. | | Period Number | Position in the year, starting at 1 | The highest number is the year's last period, which Close Year posts into. | | Name | The month, for example `Apr 2026` | Set by Generate Periods; it is also the label used in posting error messages. | | Start Date | First day the period covers | Shown under **System Information**. | | End Date | Last day the period covers | A journal lands in the period whose dates cover its journal date. | | Status | `Open`, `Closed` or `Locked` | New periods start `Open`. Change it with the period actions, not by editing — see Business rules. | The **New** form for a period asks for **Fiscal Year**, **Partner Account**, **Start Date**, **End Date** and **Period Number**. Normally you do not add periods by hand; **Generate Periods** on the fiscal year creates them all. ## Business rules - **Only Open accepts postings.** A document or journal dated in a Closed or Locked period is refused when it is saved or posted. - **The year gates too.** An Open period in a fiscal year whose **Status** is anything other than `Open` also refuses postings. - **Transitions.** Close Period: Open → Closed. Reopen Period: Closed → Open. Lock Period: Open or Closed → Locked. Each refuses any other starting status. - **Locked is final.** Any change that would move a period out of Locked is refused with *A locked fiscal period cannot be reopened.* - **Delete only Open periods.** Deleting a Closed or Locked period is refused with *Closed or locked fiscal periods cannot be deleted.* - **Fiscal days follow the actions.** Close, Reopen and Lock set the period's fiscal days to the period's new status. - **Editing Status directly is not checked like the actions.** Only a move out of Locked is blocked, and the period's fiscal days are not updated. Use the actions so the days stay in step. - **No overlap check.** xMatix does not stop two periods for the same company from covering the same dates. Keep each company's periods back to back. - **Balances only change through posting.** The stored GL and party balances of a period are written by posting and by Rebuild Balances; they cannot be edited directly. ## Example Riverbend Textiles closes its books by the fifth working day of each month. 1. On 4 May the accountant posts the last April supplier bills, deletes two abandoned Draft journals, and completes the April bank reconciliation. 2. They open the period **Apr 2026** and select **Verify Ledger**. The result shows 214 GL balances checked with 1 mismatch. They select **Rebuild Balances**; the repeated check shows 0 mismatches. 3. They select **Close Period**. **Apr 2026** now reads `Closed`. 4. On 9 May a sales invoice dated 29 April is refused with *Fiscal period 'Apr 2026' is Closed — posting is not allowed.* The finance lead approves a late entry; the accountant selects **Reopen Period**, posts the invoice, reruns Verify Ledger and closes April again. 5. After the quarterly filing in July, the finance lead selects **Lock Period** on April, May and June. ## Training ### Practice exercise In a sandbox with a fiscal year whose periods are generated, and with the period actions added to the period page: 1. Open the first period of the year and select **Verify Ledger**. Expected result: a summary of balances checked, mismatches and findings; nothing changes. 2. Select **Close Period**. Expected result: Status `Closed`. 3. Try to save a manual journal dated in that period. Expected result: it is refused because the period is Closed. 4. Select **Close Period** again. Expected result: a message that only Open periods can transition to Closed. 5. Select **Reopen Period**, then save the journal. Expected result: Status `Open`, and the journal saves. 6. On a period you will not use again, select **Lock Period**, then try **Reopen Period**. Expected result: the reopen is refused. ### Quick reference - The journal date and company pick the period; you never choose it. - Only an Open period in an Open year accepts postings. - Close Period: Open → Closed. Reopen Period: Closed → Open. - Lock Period: Open or Closed → Locked, and Locked is final. - Close Period runs no checks — reconcile first. - Verify Ledger checks and changes nothing; Rebuild Balances recalculates the period's balances. - Only Open periods can be deleted. - Use the actions, not Edit, to change a period's status. ## Permissions Access is set in each user's [security profile](/docs/administration/security-profiles/): - **Entity permissions** on Fiscal Period decide who can see, create, edit and delete periods. - **Server actions** — Close Period, Reopen Period, Lock Period, Verify Ledger and Rebuild Balances — each need a grant on the profile's **Actions** tab. A user without the grant cannot run that action. In the profiles that ship with xMatix, **System Admin** and **Standard User** include all five period actions, and **Sales Executive** includes **Close Period**. Review these grants and keep Close, Reopen and Lock for the people who own the close. ## Configuration - **Put the period actions on the record page.** The shipped fiscal period page header shows only **Edit** and **Delete**. Edit the Fiscal Period **View** layout and add **Close Period**, **Reopen Period**, **Lock Period**, **Verify Ledger** and **Rebuild Balances** to the page header's actions — see [Design a form layout](/docs/customization/layouts/design-a-form-layout/). Until you do, the actions exist and can be granted, but there is no button to run them. - **Fiscal years and periods** — Finance → **Settings** → **Fiscal Years**. The year's dates decide the periods; see [Fiscal years and periods](/docs/finance/fiscal-years/). - **Year status** — the **Status** field on the fiscal year. Anything other than `Open` stops postings into every period of the year. - **Security profiles** — grant the period actions as described under Permissions. - **Organization shape** — if **We run multiple companies** is off in **Org Settings**, the Partner Account field is hidden on periods. ## Common problems ### "Fiscal period '…' is Closed — posting is not allowed." The document or journal date falls in a Closed (or Locked) period. If the date is wrong, change it to a date in an Open period. If it is right, get approval, select **Reopen Period**, post, and close the period again. A Locked period cannot be reopened. ### "Financial year for period '…' is Closed — posting is not allowed." The period is Open, but its fiscal year's **Status** is not `Open`. Check the year's status for a typo, or set it back to `Open` if the year should accept postings. ### "Fiscal Period cannot be null!" when saving a journal Despite its wording, this message appears when the journal's fiscal period is Closed. Treat it like the Closed-period message above: correct the journal date or reopen the period. ### "Fiscal Period is required" on a journal The journal has no **Journal Date**, so xMatix cannot work out its period. Enter the date and save again. ### "Period is …; only … periods can transition to …" The action does not fit the period's current status — for example Close Period on a period that is already Closed, or Reopen Period on a Locked one. Check the **Status** and pick the matching action. ### "A locked fiscal period cannot be reopened." Someone tried to change a Locked period's status. Locked is final; record any correction in an Open period instead. ### "Closed or locked fiscal periods cannot be deleted." Only Open periods can be deleted. If the period is Closed and really must go, reopen it first; a Locked period cannot be deleted. ### I cannot find the Close Period button The shipped period page shows only Edit and Delete. Ask your administrator to add the period actions to the Fiscal Period page layout and to grant them in your security profile. ## Common questions ### Does Close Period check that the month is reconciled? No. Close Period only changes the status — it does not look for draft journals, failed postings, unreconciled bank statements or balance drift. Do that review first: work through Step 1, run **Verify Ledger** on the period, and use **Rebuild Balances** if it reports mismatched GL or party balances. Keep the reports you relied on so the close can be reviewed later. Once you are satisfied, close the period; if something turns up afterwards, an approved **Reopen Period** lets you correct it. ### What is the difference between Closed and Locked? Both refuse postings. A Closed period can be reopened with **Reopen Period** for an approved correction, then closed again. A Locked period can never be reopened or deleted — xMatix refuses any change that moves it out of Locked, whether through an action or by editing the record. Close each month at month-end, and lock it only when its figures are final, for example after audit or a statutory filing. ### Is there a soft close that lets some users still post? No. Posting accepts only the Open status, for every user. To let a correction in, reopen the period, post it and close the period again. ### Is it safe to run Rebuild Balances? Yes. It only rewrites the period's stored GL and party balances from the posted journals — the journals themselves are untouched — and then re-runs Verify Ledger so you can see the result. It does not fix an unbalanced journal or a wrong open-item amount; those need the underlying document corrected. ## Related topics - [Fiscal years and periods](/docs/finance/fiscal-years/) - [Working with journals](/docs/finance/journals/) - [AR and AP subledgers](/docs/finance/subledgers/) - [Financial statements](/docs/finance/statements/) - [Bank reconciliation](/docs/finance/banking/bank-reconciliation/) - [Security profiles](/docs/administration/security-profiles/) - [Fiscal Period — entity reference](/docs/reference/entities/fiscal-period/) ---- # Revenue recognition URL: https://xmatix.com/docs/finance/revenue-recognition/ Last reviewed: 2026-09-02 The finance model contains Revenue Recognition Schedule and Revenue Recognition Schedule Line records. A due-line processor can post an existing unrecognized line by debiting deferred revenue and crediting revenue. What is not currently wired is the step that materializes schedule lines from a saved schedule header or source invoice/contract. The demo2 create form shows only header configuration and cannot prove that period lines exist or will be generated. It is omitted rather than presenting a partial model as an unattended accounting workflow. ## Implemented pieces - `RevenueRecognitionService.BuildStraightLine` can calculate an even period plan in memory. - A schedule can reference deferred-revenue and revenue GL accounts and own explicit schedule lines. - `VoucherPostingService.PostRevenueRecognitionLineAsync` validates an unrecognized positive line, creates the recognition journal and links it back to that line. - The subscription evaluator finds due, unrecognized lines on active schedules, and the processor posts them. - Already recognized lines are rejected, which protects a materialized line from a second posting. ## Missing end-to-end connection No production caller was found that invokes the straight-line builder and persists its calculated rows when a schedule is created. An invoice or contract also does not automatically create those lines in the audited flow. The scheduler cannot post a header by itself; it needs Revenue Recognition Schedule Line records that already exist. Before using this feature operationally, implement or verify a server-side creation path that: 1. validates total amount, dates, period count and both GL accounts; 2. calls the appropriate plan builder; 3. persists one line per intended period with fiscal-period context; 4. proves the rounded line sum equals the deferred total; 5. makes creation idempotent; and 6. adds an integration test from source document through generated lines to posted journals. Until that path exists, use an approved manual-journal schedule or tenant-specific implementation and reconcile it independently. Do not rely on saving the standard schedule header. ## Due-line posting Where lines have been created by a verified integration, the scheduled processor can post those whose due date has arrived. Verify each generated journal's date, organization, deferred account, revenue account, amount and schedule-line link. A missed scheduler run can be caught up because due unrecognized lines remain eligible, but the actual posting date and open fiscal period still matter. There is no first-party “generate lines” or general on-demand recognition action documented by the audited handlers. An internal service method is not the same as a supported UI action. ## Common questions ### Does creating a schedule automatically spread the amount? Not in the audited production wiring. A calculation helper exists, but no save handler persists its result as schedule lines. ### Can the scheduler post an empty schedule? No useful recognition occurs. The evaluator operates on due Revenue Recognition Schedule Line rows, not the header's dates alone. ### Can a line post twice? The line poster refuses a line already marked recognized. Still test transaction/retry behaviour in the deployment that creates the lines and runs the subscription job. ## Related topics - [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) - [Working with journals](/docs/finance/journals/) - [Closing a period](/docs/finance/period-close/) ---- # Financial statements URL: https://xmatix.com/docs/finance/statements/ Last reviewed: 2026-08-15 The **Statements** area of the Finance app holds fifteen statement screens, every one derived live from the posted ledger the moment you open it. There is no refresh step and no saved copy to go stale: post a journal and every statement reflects it. This page lists each screen and the question it answers. ## How the statements work - **Live queries.** A statement is computed from posted journals plus each GL account's statement classification (see [Chart of accounts](/docs/finance/chart-of-accounts/)). Reclassify an account and the statements move with it. - **Flow versus balance.** Flow statements (P&L, Cash Flow) report over a from–to window; balance statements (Balance Sheet, Trial Balance) report as of a single date. The date controls on each screen match its kind. - **Dimensions.** Filter by branch or business unit for a division-wise view — or clear the filter for the consolidated one. Same ledger, different filter. - **Publish to snapshot.** Because statements are live, a statement you have filed or circulated can be **published** — a published statement is snapshotted as-at that moment and is not altered by later reclassification. ## The statement screens | Statement | What it answers | | --- | --- | | Profit and Loss | Income against expense for a period, with the prior period alongside — did we make money, and where? | | Profit and Loss (Schedule III) | The same result in the Indian statutory Schedule III layout, ready for filing and board packs | | Horizontal Profit and Loss | The T-form presentation — income and expenditure side by side | | Balance Sheet | Assets against equity and liabilities as of a date — what do we own and owe? | | Balance Sheet (Schedule III) | The statutory Schedule III presentation of the same position | | Horizontal Balance Sheet | The T-form presentation — assets on one side, equity and liabilities on the other | | Trial Balance | Every account's debit and credit balance; total debits must equal total credits — the first thing to check when anything looks wrong | | Changes in Equity | How equity moved over the year — capital, reserves and retained earnings | | Cash Flow | Where cash came from and went, indirect method, reconciling to the change in cash | | Fund Flow | Sources and applications of funds between two balance-sheet dates — the working-capital view of the same story | | Budget vs Actual | Budgeted against posted actuals per account, with the variance (see [Budgets](/docs/finance/budgets/)) | | Financial Ratios | Liquidity, solvency, profitability and efficiency ratios, computed from the ledger | | Risk Ratios | The company's financial risk — liquidity stress, leverage, debt-servicing capacity, cash-flow adequacy | | Financial Projection | A forward-looking income statement built from the projection assumptions maintained in Settings | | Inventory Valuation Statement | Inventory value and movement, tying stock to the inventory control account | ## Reading the statutory layouts The Schedule III screens place each account by its Schedule III classification, so their correctness is a classification question, not a formatting one. An account showing up under the wrong head — or not at all — means its classification needs correcting in the chart of accounts; the statement will be right the moment the account is. ## Common questions ### Why did a statement change since I last looked? Because the ledger did. Statements are computed live from posted journals, so any posting into the window you are viewing — a backdated document, a reversal, a depreciation run — moves the figures. When you need a figure that holds still, publish the statement: the published snapshot is fixed as of that moment. ### What is the difference between the P&L and the Schedule III P&L? The numbers are the same; the arrangement differs. The standard P&L groups by account type for management reading; the Schedule III screen arranges the identical ledger into the statutory format prescribed for Indian companies. Use whichever the audience expects — they cannot disagree with each other. ### Why doesn't my Trial Balance balance? A posted ledger always balances, so an unbalanced TB means the view is cut short — most often a dimension filter that catches one side of journals whose lines carry inconsistent branch or business-unit stamps. Clear the filters; if the full TB balances, the fix is stamping dimensions consistently on journal lines. ## Related topics - [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) - [Closing a period](/docs/finance/period-close/) - [Budgets and budget control](/docs/finance/budgets/) ---- # AR and AP subledgers URL: https://xmatix.com/docs/finance/subledgers/ Last reviewed: 2026-09-02 The receivables and payables subledgers answer the question the general ledger cannot: *who* owes *what*, and since when. Open Transaction records can be sourced from orders, service orders, bills and other posting flows, as the populated demo2 register shows. Settlement allocations reduce those obligations; reconciliation must still be verified rather than assumed from the model. ## Read the screen @[guided-image](_img/open-transactions-concept.png) The Open Transactions register is the operational face of the subledger. **Name** identifies the open item, **Document Date** fixes when the obligation entered the books, and **Direction** separates receivables from payables. **Source Entity** is the route back to the invoice, bill, payment or adjustment that created the balance, while **Due Date** supplies the ageing clock. Together these fields let a reviewer answer not only how much remains unsettled, but why it exists and when action is expected. Use search and filters to isolate one party, direction, source or due-date window, then open the source before correcting anything. The register is derived settlement evidence, so an unexplained item should normally be resolved at its originating document or through an explicit allocation, credit note or payment—not by disguising the balance with a manual control-account journal. The screenshot uses visible synthetic demo2 data so readers can follow realistic rows, values and controls together; production exports and screenshots must still remain inside authorized channels. ## How documents post Posting handlers can create ledger and open-item effects for their document types. A GL account must resolve for each posting role. Party enforcement on a control-account line depends on the account's stored `IsControlAccount` flag; choosing a visible Control Type without setting that flag is not sufficient. Payment inserts can also post immediately when their finance partner resolves, rather than waiting for a universal approval stage. | When this posts | Also captured | | --- | --- | | Sales invoice | Output tax detail, any tax collected at source, and the cost-of-goods journal for delivered lines | | Vendor bill | Input tax detail and any tax withheld at source | | Payment | Tax withheld at payment, where the applicable section deducts at payment time | Withholding entries adjust the open item directly — tax withheld on a bill reduces what you owe the supplier, and tax collected on an invoice grows what the customer owes — so the open balance always reflects what is actually payable or collectible. ## Open items and settlement Each posted receivable or payable becomes an **open item** carrying the document number, due date, original amount and open amount. Receipts and payments settle open items through **settlement allocations**: an allocation records how much of which payment was applied to which item. Partial settlements are normal — an item stays open for its remainder until allocations cover it fully. See [Recording and applying payments](/docs/finance/payments/) for the procedure. ## Ageing, statements and credit limits The subledger drives three everyday tools: - **Ageing** — open items bucketed by how long past due they are, per customer or supplier. - **Party statement** — the running account of documents and payments for one party. - **Credit-limit checks** — where the calling order/invoice flow invokes the check and its required configuration resolves. The current checks are conditional and can fail open when prerequisites are absent, so verify each deployed source path before treating the limit as a hard control. Overdue receivables can also accrue interest under a policy — see [Interest on overdue payments](/docs/finance/interest-on-overdue/). ## Reconciling to the control accounts The AR and AP control accounts are intended to summarize the subledgers inside the general ledger. Reconciliation compares posted GL balance with the detail it summarizes and investigates the signed difference. The unexposed `PeriodCloseService` includes an open-items-to-allocations check, but the current Fiscal Period Close action bypasses that service; close owners must run and retain this reconciliation themselves. ## Common questions ### Why doesn't the AR control account equal my ageing? Run the control-account reconciliation report — it shows the signed difference and lets you chase it down. The usual causes are documents approved but not yet posted, and manual journals written directly against the control account without a matching open item. Prevention beats cure: keep manual postings off the control accounts and let documents own them. ### An invoice is missing from the ageing. Why? It never posted to the ledger, so it has no open item. The ageing is built from open items, not from the invoice list — an invoice still in draft, or one whose posting failed, is invisible to it. Check the invoice's posting status; once it posts, the open item and its ageing bucket appear. ### Can I post a manual journal to a receivable or payable account? Treat a manual posting to a receivable or payable account as a last resort. When the account is correctly flagged `IsControlAccount`, the line must carry the party. The journal still does not automatically create or settle the corresponding Open Transaction, so it can create a reconciliation difference. Prefer the source document that fits the business event. ## Related topics - [Recording and applying payments](/docs/finance/payments/) - [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) - [Interest on overdue payments](/docs/finance/interest-on-overdue/) - [Closing a period](/docs/finance/period-close/) ---- # Annual returns: preparing and filing GSTR-9 URL: https://xmatix.com/docs/finance/tax-center/annual-returns/ Last reviewed: 2026-10-09 GSTR-9 is the annual GST return for one GSTIN and one financial year, and in xMatix you do not re-key it: **Compute GSTR9** adds up the year's already-filed GSTR-1 and GSTR-3B returns, the GSTR-2B statements and your own tax ledger into the statutory tables. You then fill the rows that no monthly return carries, review the differences, run the pre-file checklist, and either file through your GSTN integration or file on the government portal and record it with **File To GSTN**. GSTR-9 comes last in the GST year: it depends on all twelve months of [GSTR-1](/docs/finance/tax-center/gstr-1/) and [GSTR-3B](/docs/finance/tax-center/gstr-3b/) being filed first. ## Overview Each **GSTR 9 Return** record covers one GSTIN and one financial year (April to March). The standard record page has: - **A page header** showing the record's Name and five statistics — **AATO**, **GSTIN**, **Status**, **Financial Year** and **Computed At** — with the buttons **Compute GSTR9** and **File To GSTN**. - **Summary** — the annual grid, with a switch between three views: - **Annual Summary** — every row of the form, grouped into its statutory tables (Part II Tables 4 and 5, Part III Tables 6, 7 and 8, Part V Tables 10–14, Part VI Tables 15 and 16), with the taxable value, IGST, CGST, SGST and cess the return will carry, a **Δ** (variance) column and an **Actions** column. - **Table 9 — Tax paid** — tax payable, paid in cash and paid through each credit ledger, and any shortfall, for each of the eight Table 9 descriptions. - **Validation** — the pre-file checklist and its findings. - **Table 17/18 - HSN Summaries** — the outward HSN summary (Table 17) and the inward HSN summary (Table 18). - **Details** — GST Registration, Legal Name, Owner and Modified By. ## When to use it Work on GSTR-9 once the financial year is over and every month's GSTR-1 and GSTR-3B for the GSTIN is **Filed** in xMatix — either filed through your integration or recorded as filed after you filed on the portal. You can compute earlier to see where the year stands, but the checklist will not pass until all twelve months are filed. An Input Service Distributor (ISD) registration does not file GSTR-9, so no GSTR-9 is created for it (see [GSTR-6](/docs/finance/tax-center/gstr-6/)). ## How xMatix handles it **The record is created for you.** When GST returns are provisioned for any month of a financial year — by the **Provision GST returns** scheduled job, or the **Provision GST Returns** action on a GST Registration or a monthly GST fiscal period — xMatix also creates that year's GSTR-9 for every active registration that is not an ISD. The first month creates it; the other eleven find it and add nothing. A provisioned return is **Draft**, named for example "GSTR9-29AAAAA0000A1Z5-2025-26", with Period From 1 April and Period To 31 March. See [The GST console](/docs/finance/tax-center/gst-console/). **Status moves forward through the actions:** | Status | Set by | What it means | | --- | --- | --- | | Draft | Provisioning, or creating the record | Nothing computed yet | | Computed | Compute GSTR9 | The rows are built. Running Compute again on a Validated return takes it back to Computed | | Validated | The pre-file checklist, when it finds no blocking errors | Ready to file | | Filed | File To GSTN, or a successful File GSTR-9 on GSTN | A frozen statutory snapshot | **Four lanes on every row.** Each row keeps its figures in four lanes, so you can always see where a number came from: | Lane | Meaning | | --- | --- | | Computed (shown as **Filed** in the lane comparison) | The rollup of what you filed during the year — the primary figure | | Books | The same figure from your own tax ledger, for comparison. Only five rows have one: 4N, 6A, 6B, 7E and 8F | | Override | Your entry or adjustment, always with a reason | | Final | What goes on the return and into the export — the Computed figure unless you override it | The grid shows the Final lane. On a row with a Books lane, expand the row to see the Filed, Books and Variance lanes side by side. The **Δ** column shows a tick when the filed rollup agrees with the books, the difference (Computed minus Books) when it does not, and a dash on rows with no Books lane. On 7E and 8F it shows **n/c** (not compared), because those books figures stay zero unless your purchase tax lines classify credit as blocked or ineligible. **What feeds what.** Only returns whose status is **Filed** are read. A GSTR-1 or GSTR-3B still in Draft contributes nothing. | Part of the form | Source | | --- | --- | | Table 4 and Table 5 — outward supplies | The books side of the year's filed GSTR-1 returns, leaving out rows marked to be ignored. Supplies to unregistered persons go to 4A; B2B invoices to 4B, or to 5C when the recipient pays tax under reverse charge; SEZ supplies to 4D (with tax) or 5B (without); deemed exports to 4E; exports to 4C (with tax) or 5A (without); credit notes to 4I and debit notes to 4J; exempt, nil-rated and non-GST supplies to 5D, 5E and 5F | | 4G — inward supplies on reverse charge | Table 3.1(d) of the filed GSTR-3B returns | | Table 6 — ITC availed | The ITC tables of the filed GSTR-3B returns | | Table 7 — ITC reversed | The reversal rows of the filed GSTR-3B returns, sorted into 7A–7H by the reversal reason: section 17(5) or blocked credit → 7E, TRAN-II → 7G, other TRAN → 7F, Rule 37A → 7A1, Rule 37 → 7A, Rule 39 → 7B, Rule 42 → 7C, Rule 43 → 7D, anything else → 7H | | 8A — ITC as per GSTR-2B | The portal-side ITC summary of the year's GSTR-2B statements | | Table 9 — tax paid | The table 6.1 payment rows recorded on each filed GSTR-3B. A tax head xMatix does not recognise lands under Other | | Table 17 — outward HSN | The books-side HSN summaries of the filed GSTR-1 returns, combined by HSN code and rate | | Books lane | Your tax ledger lines for the GSTIN whose document date falls between Period From and Period To | | Sub-totals and differences | Calculated from other rows, for example 4H = 4A + … + 4G1 and 4N = 4H + 4M | | Every other row | Your entry — created as zero for you to complete | Table 18 (inward HSN) is not built from any source; its list stays empty. **Rows you complete yourself.** These rows start at zero and show a **Needs input** tag until you enter a value: 4F, 4G1, 4K, 4L, 5C1, 5H, 5I, 5J, 5K, 6A1, 6K, 6L, 6M, 8C, 8E, 8F, 8G, 8H1, 8J, 10, 11, 12, 13, 14, 15A–15G and 16A–16C. **Your entries flow into the totals.** When you enter or override a row, xMatix recalculates every sub-total that depends on it in the same step — a figure entered on 4F moves 4H, 4N and 5N straight away. A sub-total you overrode yourself keeps your figure. The Computed and Books lanes are never changed by your entries, so the variance always compares what you filed with your books. **Recomputing keeps your work.** Compute GSTR9 can be run as often as you like before filing. It rebuilds every row you have not overridden and refreshes the Computed and Books lanes on the rows you have, but keeps your Override and Final figures and your reasons. It also rebuilds Table 17. **Some rows are read-only.** 6A (total ITC availed per GSTR-3B), 8A (ITC as per GSTR-2B) and every Table 9 row come from the portal's own records and show a lock. A difference there is settled by paying through the government's DRC-03 process, never by editing the return. Calculated rows (marked **ƒ**) cannot be overridden either; change the rows they add up instead. **The form is defined per year.** Which rows exist, and how each figure is produced, is held as data for each financial year rather than built into the product. The first time a year is computed, xMatix creates that year's form definition. A future change to the form can be applied to a new year while earlier years keep computing as they did. ## Prerequisites - The GSTR-9 for the GSTIN and year exists (provisioned, or created by hand — see Step 1). - All twelve months' GSTR-1 and GSTR-3B for the GSTIN are **Filed** in xMatix. - The table 6.1 payment rows are recorded on each month's GSTR-3B — without them Table 9 computes as zeros. - You know the year's figures that no monthly return carries: advances, amendments, ITC of the previous year availed this year, transitional credit, next-year spill-over, refunds and demands, and the other Part V and Part VI items. - **To file through GSTN:** your administrator has set up the GSTR-9 integration flow and placed the GSTN buttons on the form (see [Configuration](#configuration)), you have the GSTN action permissions, and the GSTIN's GST Registration has a live GSTN session. ## Procedure ### Step 1 — Open the return Open the year's GSTR-9 from the annual row of the [GST console](/docs/finance/tax-center/gst-console/), or from the **GSTR 9 Return** list. Check the GSTIN, Financial Year and Status in the page header. If no return exists for the year, provision any month of the year, which creates it. You can also click **New** and enter the **GSTIN** and **Financial Year** (for example 2025-26). xMatix links the return to that year's annual GST fiscal period, creating the period if it does not exist, writes the year as "2025-26" and fills **Period From** and **Period To** with 1 April and 31 March if you left them blank. Only one GSTR-9 is allowed per GSTIN and year. @[guided-image](_img/annual-return-concept.png) ### Step 2 — Compute the return Click **Compute GSTR9**. The **Annual Summary** fills with every row of the form, Status becomes **Computed**, and **Computed At** is stamped. The return's **Prerequisite Status** records how many months are filed, for example "Complete: 12/12 GSTR-1 and 12/12 GSTR-3B filed." or "Incomplete: 11/12 GSTR-1 and 12/12 GSTR-3B filed." It is not on the standard form; you see it on the first card of the **Validation** view. If the figures look empty, use the reload button at the top of the Annual Summary. ### Step 3 — Review the computed figures Work through the tables in the **Annual Summary**: - Switch on **Hide zero rows** to see only the rows that carry figures. The count next to the switch tells you how many rows have values. - Compare Table 4 and Table 5 with your sales registers, Table 6 and Table 7 with your ITC records, and 8A with the year's GSTR-2B. - Expand 4N, 6A or 6B to see the filed rollup next to your books. A red **Δ** means the filed returns and your ledger disagree; find the cause in the source documents before you file. ### Step 4 — Enter the rows only you know On each row tagged **Needs input**, click **Enter value**. In the dialog, the current figures are filled in; enter the **Taxable value** (not shown for Tables 6, 7 and 8, which carry tax only), **IGST**, **CGST**, **SGST** and **Cess**, and a **Reason** of at least five characters. Click **Save**. The row is tagged **Overridden**, and every sub-total above it is recalculated. The dialog saves all five figures together, so check each one before you save. ### Step 5 — Adjust a computed figure, if you must If a computed figure is wrong and you cannot correct its source, click **Override** on the row, enter the figures and a reason, and click **Save**. The row is tagged **Overridden**; hover over the tag to see the reason and the version number. To change an override later, click **Edit** on the row. Prefer correcting the source: fix the transaction, re-file or amend the monthly return as the law allows, and compute again. An override records that the annual figure no longer matches what you filed. ### Step 6 — Check Table 9 Switch to **Table 9 — Tax paid**. For each description — integrated tax, central tax, state/UT tax, cess, interest, late fee, penalty and other — you see the tax payable, the amount paid in cash, the amount paid through each credit ledger (**IGST cr.**, **CGST cr.**, **SGST cr.**, **Cess cr.**) and the **Shortfall — DRC-03**. The credit-ledger columns say which ledger paid the liability: on the integrated tax row, **CGST cr.** is central-tax credit used to pay integrated tax. Interest, late fee, penalty and other cannot be paid through credit. A shortfall is paid on the portal through DRC-03; the table cannot be edited. ### Step 7 — Enter the annual aggregate turnover Make sure **AATO** (annual aggregate turnover) is filled in on the return. xMatix never fills it for you, because it is your declaration and the statutory thresholds depend on it. It appears in the page header and is included in the export. ### Step 8 — Run the pre-file checklist Switch to **Validation**. Before you run anything, three cards show whether the prerequisite is met, whether the return is computed, and whether the portal-owned rows are locked. Click **Run pre-file checklist**. - **Blocking** findings stop the return from advancing: the return has not been computed, it has no rows, or the prerequisite is not met because not all twelve GSTR-1 and GSTR-3B are filed. - **Finding — does not block filing** reports a Table 9 shortfall to settle through DRC-03, or tax paid beyond the amount payable to verify. - When there are no blocking findings, the message reads "No errors — the return advanced to Validated." and Status becomes **Validated**. If you compute again after validating, Status goes back to **Computed** and you must run the checklist again. Entering or overriding a row does not change the status, so run the checklist again yourself after any late change. ### Step 9 — File through GSTN Use this route when your administrator has set up the GSTR-9 integration and placed its buttons on the form. 1. Make sure the GSTIN has a live session: on its **GST Registration**, request the GSTN OTP, submit it, and wait until it is authenticated. A session is treated as expired 6 hours after authentication. 2. Optionally, click **Get GSTR-9 Auto-Calculated** to fetch the figures the portal has calculated for the year, so you can compare them with yours before saving. 3. Click **Save GSTR-9 to GSTN** and confirm. The return must be Computed or Validated. The Final figures and the HSN tables are sent. A few seconds later, reopen the return: **GSTN Status** reads **Completed** and **Save Reference Id** is filled. A save is queued at GSTN, not final — click **Get GSTR-9 Details** to see what GSTN now holds. 4. Click **File GSTR-9 on GSTN** and confirm. The return must be **Validated**. When GSTN answers with an acknowledgement, the **ARN** is filled, **Filed On** is stamped, **Is Filed** is set and Status becomes **Filed**. Each of these buttons only prepares the request on the return; your tenant's integration sends it and writes the answer back, and xMatix reads the answer automatically. The outcome is always in **GSTN Message**. Only one request can be in progress per return; if one is still running, you are asked to wait (requests are abandoned after 5 minutes). If GSTN Message says some rows were not sent because they have no GSTN mapping, enter those rows on the portal before filing (see [Common problems](#common-problems)). ### Step 10 — Or record a filing you made on the portal If you filed GSTR-9 directly on the government portal, click **File To GSTN** on a **Validated** return. This sends nothing to GSTN; it only records the outcome. **Is Filed** is set, Status becomes **Filed** and **Filed On** is stamped. The standard dialog has no ARN or date field, so **Filed On** is the moment you confirm and the ARN stays empty — keep the portal's acknowledgement with your filing records. ### Step 11 — After filing A Filed GSTR-9 is a frozen statutory snapshot. **Compute GSTR9** is refused ("A filed GSTR-9 cannot be recomputed; it is a statutory snapshot."), rows can no longer be entered or overridden, and the return cannot be saved, filed or recorded as filed again. Running the checklist on a Filed return changes nothing. ### Step 12 — GSTR-9A and GSTR-9C (through GSTN only) xMatix does not compute GSTR-9A or GSTR-9C. If your integration is set up, you can send one you prepared elsewhere from the same GSTR-9 record: 1. Paste the return's JSON data (for example, from the government's offline tool) into **GSTN Manual Payload** on the GSTR-9 and save. The GSTIN and return period in it are always replaced with the return's own. 2. Click **Save GSTR-9C to GSTN** (or **Save GSTR-9A to GSTN**), check **Save Reference Id**, then click **File GSTR-9C on GSTN** (or **File GSTR-9A on GSTN**). GSTR-9C can be filed only after the GSTR-9 is Filed, and only once; its acknowledgement goes into **GSTR-9C ARN** and the date into **GSTR-9C Filed On**. **Get GSTR-9 Records for 9C** and **Get GSTR-9C Summary** fetch the portal's figures into **Portal 9C Records** and **Portal 9C Summary**. ## Fields | Field | What it means | Notes | | --- | --- | --- | | Name | The record's name, for example "GSTR9-29AAAAA0000A1Z5-2025-26" | Set by provisioning; required | | GSTIN | The GSTIN the annual return is for | Must be a well-formed 15-character GSTIN. Decides which monthly returns and ledger lines are read | | Legal Name | The registered legal name | Not filled by provisioning; enter it if your process needs it | | Financial Year | The year covered, written like 2025-26 | Required when creating a return by hand. Decides which months, and which year's form definition, are used. Cannot be moved to another year once the return is past Draft | | Period From, Period To | The coverage dates | Filled with 1 April and 31 March. They set the date range for the Books lane | | Status | Where the return is in its lifecycle | Draft → Computed → Validated → Filed, written by the actions. Do not set it by hand | | AATO | Annual aggregate turnover | Your declaration; never filled by xMatix. Included in the export | | Prerequisite Status | Whether all twelve months are filed | Written by Compute GSTR9, for example "Complete: 12/12 GSTR-1 and 12/12 GSTR-3B filed." | | Computed At | When Compute GSTR9 last ran | | | Filed On | When the return was filed | Stamped by File To GSTN or by a successful filing through GSTN | | Is Filed | Yes once the return is filed by either route | Set together with Status Filed | | ARN | The acknowledgement number for the GSTR-9 filing | At most 120 characters. Filled automatically when you file through GSTN | | GST Registration | The GST Registration the return is filed under | Its GSTN session is used by the GSTN actions; its GSTIN must match the return's | | GSTN Operation | The last GSTN request made from this return | | | GSTN Status | Where that request is: Requested, Responded, CallFailed, Completed or Failed | Requested starts the integration. Never edit it by hand | | GSTN Requested (UTC) | When the request was made | A request is treated as abandoned after 5 minutes | | GSTN Message | The outcome of the last request, or GSTN's refusal in its own words | | | GSTN Manual Payload | JSON data for GSTR-9A or GSTR-9C, which xMatix does not compute | Pasted by you before saving or filing those forms | | Portal Auto-Calculated, Portal Details | The portal's auto-calculated GSTR-9, and the GSTR-9 as saved on the portal | Filled by the Get actions | | Portal 8A Token, Portal 8A Details | The portal's Table 8A request token and the Table 8A details | Filled by Create GSTR-9 Table 8A and Get GSTR-9 Table 8A | | Portal 9C Records, Portal 9C Summary | The portal's GSTR-9 records for 9C, and its GSTR-9C summary | Filled by the GSTR-9C Get actions | | Save Reference Id | The reference GSTN issued for the last save | A save is queued, not final | | GSTR-9C ARN, GSTR-9C Filed On | The acknowledgement and date of the GSTR-9C filing | Separate from the GSTR-9 ARN | Each row of the annual grid is a **GSTR 9 Summary** record, and each HSN line a **GSTR 9 HSN Summary** record. The full field lists are in the [GSTR 9 Return entity reference](/docs/reference/entities/gstr9-return/), the [GSTR 9 Summary reference](/docs/reference/entities/gstr9-summary/) and the [GSTR 9 HSN Summary reference](/docs/reference/entities/gstr9-hsn-summary/). ## Business rules - **Saving a return.** A GSTR-9 is refused when its GSTIN is not a valid 15-character GSTIN, when it has neither a financial year nor an annual period, when its year does not match its period, when another GSTR-9 already exists for the same GSTIN and year, or when it is moved to another year after leaving Draft. - **Only filed months count.** Compute reads GSTR-1 and GSTR-3B whose status is Filed, for the return's GSTIN, in the twelve months of the financial year. - **Prerequisite.** It is complete only when every one of the twelve months has a filed GSTR-1 and a filed GSTR-3B. If fewer than twelve monthly periods exist for the year, the status says so ("only 5/12 GST periods exist"). - **Compute is repeatable.** It rebuilds every row you have not overridden, keeps your overrides and reasons, refreshes Table 17, and sets Status to Computed. It is refused on a Filed return. - **Overrides need a reason** and are refused on locked rows and on a Filed return. Your entries flow into the sub-totals that depend on them. - **The checklist** blocks on an uncomputed return, a return with no rows or an incomplete prerequisite. A Table 9 shortfall is reported but does not block. A clean run sets Status to Validated. - **Filing needs Validated.** File To GSTN and File GSTR-9 on GSTN are both refused unless Status is Validated, and both are refused on a return that is already Filed. - **Saving to GSTN needs Computed or Validated**, a GST Registration for the GSTIN with a session less than 6 hours old, and computed rows to send. - **The export and the GSTN save use the Final lane**, so they carry your entries and overrides. - **Filed is one-way.** Nothing in the product turns a Filed return back to an earlier status. ## Example A distributor files GSTR-9 for GSTIN 29AAAAA0000A1Z5 for 2025-26. All twelve GSTR-1 and GSTR-3B returns were filed on the portal and recorded as filed in xMatix. 1. In April 2026, the provisioning job created "GSTR9-29AAAAA0000A1Z5-2025-26" in Draft. 2. After the year closes, the accountant opens it and clicks **Compute GSTR9**. Prerequisite Status reads "Complete: 12/12 GSTR-1 and 12/12 GSTR-3B filed." and Status is Computed. 3. 4B shows taxable B2B supplies of ₹4,80,00,000. Expanding 4N shows a **Δ** of ₹12,500: the books ledger carries more tax than the filed returns. The accountant traces it to a sales invoice posted in the books but left out of a filed GSTR-1, and agrees with the tax advisor how to report it before going on. 4. They click **Enter value** on 4F, enter advances of ₹2,00,000 with IGST ₹36,000 and the reason "Advance received in March, invoice issued in April". 4H, 4N and 5N update immediately. 5. They enter 6A1 (previous-year ITC availed this year) and the Table 15 refund figures, and type AATO ₹5,20,00,000 on the return. 6. Table 9 shows a nil shortfall on every description. 7. On **Validation** they click **Run pre-file checklist**. There are no blocking findings, and Status is Validated. 8. The finance manager authenticates the GSTIN, clicks **Save GSTR-9 to GSTN**, checks the saved figures with **Get GSTR-9 Details**, and clicks **File GSTR-9 on GSTN**. The ARN appears and Status is Filed. ## Training ### Practice exercise In a sandbox tenant with a GSTIN whose year is only partly filed: 1. Open the year's GSTR-9 and click **Compute GSTR9**. 2. Switch to **Validation** and click **Run pre-file checklist**. 3. Back on **Annual Summary**, click **Enter value** on 4F, enter a taxable value of 1,00,000 and IGST of 18,000 with a reason, and save. 4. Hover over **Override** on row 6A. **Expected result:** - After step 1, Status is Computed and Prerequisite Status starts with "Incomplete:". - In step 2, a **Blocking** finding says the prerequisite is not met, and Status stays Computed. - After step 3, 4F is tagged **Overridden**, and 4H and 4N each rise by the amounts you entered. - In step 4, the button is disabled and its tooltip explains that the row is auto-filled from the portal. ### Quick reference - One GSTR-9 per GSTIN and year; provisioning creates it, never for an ISD. - Only Filed GSTR-1 and GSTR-3B are read — file the twelve months first. - Compute GSTR9 as often as you like before filing; overrides survive. - Fill every row tagged Needs input; your entries flow into the totals. - 6A, 8A and Table 9 are locked; settle a Table 9 shortfall through DRC-03. - Enter AATO yourself — xMatix never guesses it. - Run the pre-file checklist to reach Validated; compute again and you must re-validate. - Filing needs Validated: File GSTR-9 on GSTN, or file on the portal and click File To GSTN. - A Filed return is frozen for good. ## Permissions Each button is a server action that a [security profile](/docs/administration/security-profiles/) must grant. In the standard profiles: | Action | System Admin | Standard User | Sales Manager | Sales Executive | | --- | --- | --- | --- | --- | | Compute GSTR9 | Yes | Yes | No | Yes | | Get Records (an older name for the same compute) | Yes | Yes | Yes | No | | Get GSTR9 (loads the annual grid) | Yes | Yes | No | No | | Override GSTR9 Line (Enter value, Override, Edit) | Yes | Yes | No | No | | Validate GSTR9 (Run pre-file checklist) | Yes | Yes | No | No | | Export GSTR9 JSON | Yes | Yes | No | No | | File To GSTN | Yes | Yes | Yes | No | | The GSTN actions (Save, File and Get for GSTR-9, 9A and 9C, Read GSTN Reply) | Yes | No | No | No | When the GSTN actions were added to an existing tenant, profiles that could already compute GSTR-9 received the Get and Read GSTN Reply actions, and profiles that could already use File To GSTN received the Save and File actions. Because saving or filing at GSTN is a statutory act, grant those only to the people who sign the return. A user without an action does not get that button. A user without **Get GSTR9** sees an error instead of the grid. Reading the record also depends on the profile's access to the GSTR 9 Return entity, which all four standard profiles have; see [Why can't a user see a record?](/docs/administration/user-cant-see-x/). ## Configuration - **Provisioning.** The **Provision GST returns** scheduled job (**Setup → Administration → Jobs**) creates the year's GSTR-9 with the first month it provisions, for every active registration that is not an ISD. **Provision GST Returns** on a GST Registration or a monthly GST fiscal period does the same on demand. It refuses an annual period: provision any month of the year instead. See [The GST console](/docs/finance/tax-center/gst-console/). - **GST registrations.** Each GSTIN needs an active GST Registration. Registrations with **Enable ISD** get no GSTR-9. To file through GSTN, the registration must be authenticated with GSTN through its OTP actions; a session lasts about 6 hours. - **The monthly returns.** GSTR-9 is only as good as its sources: make sure each month's GSTR-1 and GSTR-3B is filed, and that each GSTR-3B carries its table 6.1 payment rows and reversal reasons, because the reason text decides which Table 7 row a reversal lands in. - **GSTN integration** (**Setup → Process Studio → Integrations**). Filing through GSTN needs one integration flow, in the integration app that holds your GSP connection, with an entity-event trigger on **GSTR 9 Return** updates where **GSTN Status** becomes Requested. That one flow carries every GSTR-9, 9A and 9C request: it sends the request prepared on the return and writes the reply back to **GSTN Response Payload** and **GSTN Status** (Responded or CallFailed). Use the same GSP connection and partner credentials as your other GST return flows. Without the flow the buttons still respond, but nothing reaches GSTN and GSTN Status stays at Requested. See [Outbound integrations](/docs/integrations/outbound/). - **The form.** The standard page header shows only **Compute GSTR9** and **File To GSTN**; the checklist runs from the grid's **Validation** view. If your filers use GSTN, add the GSTN buttons you need (for example **Save GSTR-9 to GSTN**, **File GSTR-9 on GSTN**, **Get GSTR-9 Auto-Calculated**, **Get GSTR-9 Details**, **Read GSTN Reply**) to the page header, and **GSTN Status**, **GSTN Message**, **Save Reference Id** and **GSTN Manual Payload** to the **Details** tab, in the form designer. Add **Export GSTR9 JSON** if you want the JSON export, and **AATO** and **ARN** to **Details** if your users should edit them there. The annual grid can be set to start with zero rows hidden. - **The form definition.** Each financial year's rows are held as **GSTR 9 Config** records, created the first time the year is computed. A shipped correction to a row updates your records automatically unless the record is marked **Is Customized**, which protects a deliberate change. Change these records only when you know the statutory form well; a mistake surfaces as a compute error naming the row. - **Security profiles.** Grant the actions as described in [Permissions](#permissions). - **Mobile.** The GSTR 9 Return has a mobile layout showing the summary rows and the header details. Whether it is reachable in the field app depends on your mobile app configuration. ## Common problems ### Every figure is zero The monthly returns are not Filed in xMatix. Only Filed GSTR-1 and GSTR-3B are read. File them, or record the filings you made on the portal, and compute again. ### Table 9 is empty although tax was paid all year The table 6.1 payment rows were never recorded on the monthly GSTR-3B returns. Record them there and compute again. ### "Prerequisite not met: Incomplete: … (all 12 GSTR-1 + GSTR-3B must be filed)." At least one month's GSTR-1 or GSTR-3B is not Filed for this GSTIN, or a month's period does not exist ("only n/12 GST periods exist"). Provision and file the missing months, then compute again. ### "A GSTR-9 return for … already exists for this financial year; use it instead of creating a second one." Each GSTIN has one GSTR-9 per year. Open the existing one. ### "'…' is not a valid 15-character GSTIN." The GSTIN on the return is malformed. Correct it before saving. ### "This GSTR-9 is … and cannot be moved to another financial year; its summary was computed for the original one." Once a return has been computed, it stays with its year. Use the return for the other year. ### The Override button is disabled The row is locked (6A, 8A and Table 9 come from the portal's records) or calculated from other rows (marked ƒ). Change the rows it adds up, or settle a Table 9 difference through DRC-03. ### "A reason is mandatory when overriding a GSTR-9 line (audit trail)." Every entry and override needs a reason. Type one and save again. ### Reset on an overridden row fails The annual grid shows **Reset** on overridden rows, but the reset action is not included in the standard configuration, so the request is refused. To undo an override, click **Edit** and enter the figures shown in the **Filed** lane, with a reason that says you are reverting. The row stays marked Overridden. ### "GSTR-9 '…' is 'Computed'; run ValidateGSTR9 and reach Validated before filing." File To GSTN needs a Validated return. Run the pre-file checklist and clear its blocking findings. The GSTN route says "Run Validate and reach Validated before filing." for the same reason. ### "A filed GSTR-9 cannot be recomputed; it is a statutory snapshot." The return is Filed. Nothing on it can change; corrections go through the means the law provides, outside this return. ### "… is not authenticated with GSTN. Request an OTP and complete authentication on the GST registration first." The GSTIN has no GSTN session, or it has expired ("The GSTN session for … has expired"). Authenticate the GST Registration again. "No GST registration found for …" means the GSTIN has no GST Registration record; "This return is for … but its GST registration is …" means the return's GST Registration belongs to another GSTIN. ### "… is already with GSTN for this return. Wait for it to finish …" A request from this return is still running. Wait a few seconds and reopen the return. If **GSTN Status** is still Requested after 5 minutes, the integration flow did not run or did not write back; your administrator should check the flow's trigger and run history. You can then try again. ### GSTN Status is Failed GSTN or the gateway refused the request. **GSTN Message** gives the reason in GSTN's own words, for example "GSTN refused the request (…): …". Fix the cause and run the action again. If a reply arrived but was not read, click **Read GSTN Reply**. ### GSTN Message says some rows were "Not sent (no GSTN key mapped yet; enter these on the portal)" Rows 4G1, 5C1, 6A1, 6A2, 7A1, 8H1 and 14 cannot be sent to GSTN from xMatix. Enter the rows listed in the message on the portal before filing. Also note that the portal splits 6B, 6C, 6D and 6E into inputs, capital goods and input services, which the filed GSTR-3B does not record. xMatix sends 6B and 6E each as one inputs line, and 6C and 6D together as one line. The totals are right but the split is not, so correct it on the portal if it matters to you. ### Saving GSTR-9C or GSTR-9A asks you to paste its JSON The message says xMatix does not compute that form. Saving or filing GSTR-9A or GSTR-9C needs its JSON in **GSTN Manual Payload**. Paste it, save the return and run the action again. ### "GSTR-9C is filed after GSTR-9. File the GSTR-9 first." File the GSTR-9, then the GSTR-9C. ## Common questions ### Does xMatix prepare GSTR-9C? No. xMatix computes GSTR-9 only. The Books lane gives you a books-versus-filed comparison on a few rows, but the reconciliation with audited financial statements that GSTR-9C needs is prepared outside the product. If your GSTN integration is set up, you can save and file a GSTR-9C you prepared elsewhere from the GSTR-9 record, by pasting its JSON into GSTN Manual Payload. ### Why did my entry on 4F change 4H, 4N and 5N? Because those sub-totals include 4F. Whenever you enter or override a row, xMatix recalculates every sub-total that depends on it, so the return stays consistent and the export carries the right totals. The Computed lane of those sub-totals does not change, so the variance still compares what you filed with your books. A sub-total that you overrode yourself keeps your figure. ### Will computing again lose my entries? No. Compute GSTR9 rebuilds only the rows you have not overridden. On the rows you have, it refreshes the Computed and Books lanes but keeps your figures and your reason, and the sub-totals are recalculated from them. If the return was Validated, it goes back to Computed, so run the pre-file checklist again before filing. ### Can I file GSTR-9 before all twelve months are filed? Not from xMatix. The pre-file checklist blocks until every month's GSTR-1 and GSTR-3B for the GSTIN is Filed, and both filing routes need a Validated return. You can compute at any time to see the year so far, but treat those figures as provisional. ### What does the Export GSTR9 JSON action produce? JSON built from the Final lane: the GSTIN, the financial year, the annual aggregate turnover and, for every row code, its taxable value, IGST, CGST, SGST and cess. It is a first-cut payload for review and hand-off, not the complete layout of the government's offline tool, so do not upload it to the portal as it is. To send the return to GSTN, use Save GSTR-9 to GSTN, which builds GSTN's own format from the same Final lane, including the HSN tables. ## Related topics - [The Tax Center](/docs/finance/tax-center/) - [The GST console](/docs/finance/tax-center/gst-console/) - [GSTR-1 — outward supplies](/docs/finance/tax-center/gstr-1/) - [GSTR-2B — inward supplies and ITC](/docs/finance/tax-center/gstr-2b/) - [GSTR-3B — the summary return](/docs/finance/tax-center/gstr-3b/) - [Input tax credit management](/docs/finance/tax-center/itc-management/) - [GSTR 9 Return entity reference](/docs/reference/entities/gstr9-return/) - [Outbound integrations](/docs/integrations/outbound/) ---- # E-invoicing: stage and record IRP results on an Invoice URL: https://xmatix.com/docs/finance/tax-center/e-invoicing/ Last reviewed: 2026-09-02 The implemented e-invoice flow starts on an xMatix **Invoice**. Its server action builds and stores an e-invoice payload on that Invoice and marks the request Pending. A separately configured integration must submit the payload to an Invoice Registration Portal/GSP and record the response. IRN, acknowledgment, QR and signed-response fields remain on the source Invoice. This distinction is important: although the domain also contains an `EInvoice` entity, the reviewed runtime action does not create or update a separate EInvoice record. A blank New E-Invoice form therefore does not represent the supported generation workflow and is intentionally not shown here. ## Fields on the source Invoice The active services read and write these Invoice fields: | Stage | Invoice fields | | --- | --- | | Staging | `EINVPayload`, `EINVStatus` | | Successful writeback | `EINVIRN`, `EINVAckNo`, `EINVAckDate`, `EINVQRCode`, `EINVSignedInvoice`, `EINVResponse`, generated status | The built-in response recorder is a success path: it requires a nonblank IRN and then sets the Invoice to Generated. It does not expose a companion failure-recording method, so the integration design must define where rejected-provider evidence is retained. The Generate action refuses to stage a second request once the Invoice already has an IRN. That is the implemented duplicate-generation guard. ## Before enabling the integration The repository includes a ClearTax connector manifest as an example integration definition, but the Finance action does not automatically select, authenticate or execute that connector. Configure and test an Integration Hub flow explicitly for each filing context, including how it: 1. detects or receives an Invoice whose `EINVStatus` is Pending; 2. submits `EINVPayload` to the intended provider; 3. maps successful responses back to the same Invoice and retains failed-provider responses in an explicitly designed error/audit path; and 4. prevents duplicate or out-of-order writeback. Also validate the staged payload against the provider before production use. The current payload builder fills core document, GSTIN, place-of-supply, value and tax fields, but currently leaves seller and buyer legal name/location/PIN values null, leaves line Unit null, and marks every line `IsService = false`. An integration may enrich those values, but the built-in staging code by itself does not. Do not assume the word “staged” means the payload is portal-complete for every invoice type. ## Procedure ### Step 1 — Validate the Invoice Open the source Invoice and verify the issuing branch and GST registration, buyer GSTIN, document number and date, place of supply, HSN/SAC, quantities, values and per-head tax. The e-invoice action itself checks whether an IRN already exists, but it does not currently require the Invoice to be Approved or Posted. Make approval/posting state part of your operational control before anyone invokes Generate. ### Step 2 — Stage the payload Run the Invoice's e-invoice generation action once. It serializes the request into `EINVPayload` and marks `EINVStatus` Pending. Inspect the staged payload or integration trace and confirm it references the same Invoice ID and filer GSTIN. Staging is not portal submission. If no bound workflow consumes the Pending Invoice, it will remain Pending indefinitely and no IRN will appear. ### Step 3 — Let the configured flow submit and write back Allow the tested integration flow to send the staged payload and call the response-recording path for that Invoice. On success, verify all of the following together: - IRN; - acknowledgment number and date; - signed QR payload; - signed Invoice/provider response; and - generated status. On failure, retain the exact provider response in the integration's controlled error/audit path, correct the source or mapping that caused it, and stage again only when it is safe to do so. The built-in response recorder cannot record a failure because it requires an IRN. ### Step 4 — Verify the output and control edits Preview the final Invoice document and verify that its IRN, acknowledgment and QR agree with the provider response. The current e-invoice service does **not** impose a general edit lock on an Invoice after IRN generation; it only refuses another generation request when IRN is present. Use permissions, document lifecycle controls and your correction process to prevent content edits that would make the Invoice disagree with its registered payload. ## Expected result One source Invoice contains the staged request and the response fields written by the configured integration. A complete success has an IRN, acknowledgment number/date and signed QR evidence that agree with the printed Invoice. No separate EInvoice record or automatic Invoice edit lock should be expected from the current action. ## Common problems ### The Invoice remains Pending The staging action completed, but no integration consumed it or wrote back a response. Inspect the configured workflow run and its connection; creating a separate EInvoice record will not advance the Invoice. ### The provider rejects missing party or item detail Inspect the actual staged JSON. Several legal-name/address values and line Unit are currently left blank by the built-in builder, and every line is marked as goods. Correct the integration mapping or product implementation for the provider's required schema before retrying. ### Generate is unavailable or refuses to run If IRN is already populated, the duplicate-generation guard is working. The service does not implement portal cancellation; follow your statutory cancellation/correction process and control the Invoice record separately. ### Can a registered Invoice still be edited? The e-invoice service does not currently add a global edit lock. Treat permission/lifecycle control as a required implementation and audit check rather than assuming IRN writeback freezes every Invoice field. ## Related topics - [E-way bills](/docs/finance/tax-center/e-way-bills/) - [Connect a system](/docs/integrations/connect-a-system/) - [GSTR-1 — outward supplies](/docs/finance/tax-center/gstr-1/) ---- # E-way bills: generate and cancel from the Invoice URL: https://xmatix.com/docs/finance/tax-center/e-way-bills/ Last reviewed: 2026-10-05 An e-way bill in xMatix starts on an **Invoice**. The **E-Way Bill** action opens a panel that collects the transport details and creates (or updates) an `EWayBill` register row linked to that Invoice. A GSP integration then submits it to the portal and writes the result back; the generated number and date appear on the Invoice itself (`EWayBillNumber`, `EWayBillDate`). **xMatix does not call the GSP/NIC portal itself.** Until an integration is configured to answer, a request stays **Waiting for GSP**. That is expected, not an error. The domain model can describe other source documents, but the runtime actions exist on Invoice only. Delivery orders and transfers do not use this flow yet. ## The lifecycle | Status | Meaning | Next step | | --- | --- | --- | | **Draft** | Request staged; the panel shows *Waiting for GSP* | The integration records the number, or the error | | **Generated** | The portal issued the number; it is mirrored onto the Invoice | Cancel within 24 hours, if needed | | **Failed** | The portal rejected the request; the reason is shown in the panel | Correct the data and generate again (the same row is reused) | | **CancelRequested** | A cancellation is staged | The integration confirms it, or reports the refusal | | **Cancelled** | The portal accepted the cancellation; the Invoice number is cleared | A new e-way bill can be generated | | **Expired** | Past its Valid Upto | A new e-way bill can be generated | One Invoice never gets two open requests. Generating again while a request is **Draft** or **Failed** updates that same row, and generating while a valid **Generated** bill exists is refused until it is cancelled or has expired. ## Procedure ### Step 1 — Validate the Invoice and transport facts Open the Invoice and confirm the issuing registration, recipient, document number and date, taxable value and tax. Determine the real route distance, transport mode and vehicle number. ### Step 2 — Generate Open **E-Way Bill** on the Invoice and choose **Generate**. Enter: | Field | Rule | | --- | --- | | Distance (km) | Required, 1–4000 | | Transport Mode | Road, Rail, Air or Ship | | Vehicle Number | Required for Road; 6–15 letters and digits (spaces and hyphens are removed) | | Transporter ID | Optional; a 15-character GSTIN | | Transporter Name | Optional | The request is staged as **Draft** with its Part A payload (document type Tax Invoice, sub-supply Supply, value = invoice lines plus tax). The panel waits briefly for the GSP's answer, then says to check back later. If the answer arrives later, reopening the panel shows it. ### Step 3 — Let the integration answer When the integration records a number, the panel shows **Generated** with the EWB number, date and Valid Upto, and the Invoice carries the number. Valid Upto comes from the portal when the integration passes it; otherwise it is calculated as one day for each 200 km (or part), with a minimum of one day. Confirm the statutory rule and the portal's returned validity. ### Step 4 — Cancel within 24 hours (if needed) While a bill is **Generated** and less than 24 hours old, **Cancel E-Way Bill** is available. The panel shows how long is left. Pick the NIC reason (Duplicate, Order Cancelled, Data Entry Mistake, Others) and add remarks; remarks are required for Others. The bill becomes **CancelRequested** until the integration confirms it. After 24 hours, cancellation must be handled on the portal. ## Placing the panel The seeded Invoice action **E-Way Bill** opens the Invoice layout named **EWayBill**, which hosts the E-Way Bill widget. If a tenant customised that layout before this release, the update leaves it alone. In that case, open Studio → Layouts → Invoice → EWayBill and drag **E-Way Bill** onto it from Entity Components. The widget can also be placed on the Invoice view layout. ### A custom Generate form The widget property **Generate Form Layout** takes an EWayBill **Create** layout. When it is set, the Generate dialog shows that layout instead of the built-in form, so a tenant can add, remove, reorder or require fields, or add reactions, without a code change. When it is empty, the built-in form is used. Build a dedicated layout containing only the request fields: `DistanceKm`, `TransportMode`, `VehicleNumber`, `TransporterId`, `TransporterName`, `DocumentType`, `SubSupplyType` and `ChallanType`. The last three override the defaults (Tax Invoice, Supply, none). Do not attach the seeded `EWayBillCreate` layout, which is the full record form. Any other field on the layout, including custom fields, is not applied, and the panel names it in a warning. The statutory checks (distance, vehicle for Road, GSTIN format) are enforced by the action whatever the layout marks as required. The mobile app has the same panel, with the same rules and the same Generate Form Layout property. On mobile the attached layout is used only when it has a mobile design; otherwise the built-in form is shown. Generating and cancelling need a connection. Permissions: `EWayBill` and `CancelEWayBill` are granted to the profiles that raise invoices. `RecordEWayBill` and `RecordEWayBillCancel` are granted to **SystemAdmin only**, because they set the e-way bill number. Grant them only to the profile the integration runs as. ## Integration contract These are the Invoice server actions an integration uses (`POST /{version}/data/Invoice/{id}/{action}` with `{ "args": { … } }`): | Action | Called by | Args | Effect | | --- | --- | --- | --- | | `EWayBill` | users (the panel) | `distanceKm`, `transportMode`, `vehicleNumber?`, `transporterId?`, `transporterName?` | Stage or update the Draft; returns `eWayBillId`, `status` | | `RecordEWayBill` | integration | `eWayBillId?`, `ewbNumber`, `generatedDate`, `validUpto?`, `partBPayload?`, `gspResponse?` — **or** `error` | Draft → Generated (number copied onto the Invoice), or Draft → Failed | | `CancelEWayBill` | users (the panel) | `reasonCode` (1–4), `remarks?` | Generated → CancelRequested | | `RecordEWayBillCancel` | integration | `eWayBillId?`, `cancelledDate?`, `gspResponse?` — **or** `error` | CancelRequested → Cancelled (Invoice number cleared), or back to Generated | `eWayBillId` defaults to the Invoice's latest e-way bill. Recording the same number twice is a no-op, so a retried delivery is safe. Pass dates as UTC ISO-8601: the 24-hour cancel window is measured against the server's UTC clock. What the integration does: 1. Find **Draft** rows (`EWayBill.Status = Draft`). `PartAPayload` holds the Part A JSON; transport details are on the row. 2. Submit them to the portal, then call `RecordEWayBill` on the source Invoice (`SourceRecordId`) with the number, or with `error`. 3. Find **CancelRequested** rows. `GspResponse` holds `{"cancelRequest": {"ewbNo", "cancelRsnCode", "cancelRmrk", "requestedAt"}}`, which is the NIC cancel payload. 4. Submit the cancellation, then call `RecordEWayBillCancel`. `GspResponse` holds the raw portal response after a successful generation, `{"error": "…", "response": …}` after a failure, and the cancel request while a cancellation is pending. ## Common problems ### The panel stays on "Waiting for GSP" No integration has answered the Draft. Check the integration run. Generate stays available while waiting, so wrong details can be corrected; the same row is updated each time. ### "E-way bill … is already generated for this document" A valid bill exists. Cancel it within 24 hours or let it expire before generating a new one. ### "An e-way bill can only be cancelled within 24 hours of generation" This is the NIC rule. Handle it on the portal. ### Failed, with a reason The portal rejected the request. Correct the Invoice or transport details and generate again. ### The dialog shows IRN / QR fields instead of e-way bill details The tenant's Invoice **EWayBill** layout was customised before this release. Place the E-Way Bill widget on it, as described in *Placing the panel*. ### Only EWB No and EWB Date appear in the details The user's profile cannot read the EWayBill entity. Grant read access, or accept the reduced view. ## Related topics - [E-invoicing](/docs/finance/tax-center/e-invoicing/) - [Invoicing and payments](/docs/sales/invoicing-and-payments/) - [Connect a system](/docs/integrations/connect-a-system/) ---- # The GST console URL: https://xmatix.com/docs/finance/tax-center/gst-console/ Last reviewed: 2026-09-02 The **GST Console** behavior is implemented by the first-party `TaxCenterWidget`. When a tenant AppPage embeds that widget, it answers a narrow operational question: for the selected GST registration and financial year, which return records exist and what state do their stored values indicate? It links to return records and scoped lists; it does not process, reconcile or file a return by itself. The widget's route is not universal because AppPage provisioning is tenant configuration. This page is therefore intentionally text-only rather than showing a route that may not exist for the reader's tenant. If a Tax Center URL returns Not Found, use the underlying GSTR entity lists and actions until an administrator provisions and grants the AppPage. ## Choose the scope The console uses three coordinates: - **GST registration.** The picker loads `GSTRegistration` records and keeps those that are active and have a nonblank GSTIN. The current query does not separately prove that a registration is the tenant's own filing registration, so administrators must keep the registration master accurate and select the filer GSTIN deliberately. - **Financial year.** The picker is built from the tenant's stored `GSTFiscalPeriod` rows, grouped into Indian April-to-March financial years and ordered newest first. It is not a fixed current-year-plus-or-minus list. If no fiscal-period rows exist, the control falls back to the current financial year. - **Filing period.** The timeline shows the annual row first and available months in descending order. When no stored periods exist for the selected year, the console generates a twelve-month navigation scaffold; that scaffold does not mean return records have been provisioned. Changing any coordinate refreshes the filing cards. Always confirm the GSTIN and displayed period before opening a card, particularly in a tenant with several registrations. ## Read the filing cards For a regular monthly period, the console presents: | Card | Values summarized | | --- | --- | | GSTR-1 | The matching return's processing value and filing state | | GSTR-2B | The invoice value of the statement as pulled from GSTN, and whether it is Synced, Awaiting GSTN Data or Not Synced | | GSTR-3B | The matching return's liability and filing state | For an active registration flagged as an **Input Service Distributor**, the monthly set is GSTR-6 instead of the regular trio. The annual row presents GSTR-9. When exactly matching records exist, a card opens the corresponding record. If no exact record can be resolved, it opens the entity list scoped to the selected GSTIN and period so the absence is visible rather than silently inventing a record. GSTR-2B is a statement GSTN drafts, not a return you file, so its card shows a sync state rather than a filing state, and it reads the **portal side** of the statement: - **Synced** once the statement has been pulled from GSTN. The card shows the statement's invoice value, with its taxable value and tax beneath. - **Awaiting GSTN Data** before the statement's expected Generation Date, with "GSTN releases it on …". - **Not Synced** after that date if the statement has not been pulled yet. No amount is shown rather than a misleading ₹0.00. See [GSTR-2B](/docs/finance/tax-center/gstr-2b/) for pulling the statement. The recent-filing activity table reads GSTR-3B records. Filing date, acknowledgment and return status come from those records; **Filed By** is currently displayed as a dash because the widget does not resolve a filing user. ## Where records come from Return provisioning is available in three places, all existence-checked, so repeating it for the same registration and period does not create duplicate headers: - **Provision GST Returns** on a GST registration — that registration, for the **current month**. - **Provision GST Returns** on a GST fiscal period — every active registration, for **that period's month**. Use it to provision an earlier month. It works on monthly periods only; a quarterly, annual or Locked period is refused. Creating a period with **New** does not create any returns — this action does. - The scheduled **Provision GST returns** job — every active registration, for the **current month** unless a `{"month","year"}` payload names another. - A regular monthly period provisions GSTR-1, GSTR-2B and GSTR-3B. - An ISD monthly period provisions GSTR-6. - Provisioning any normal-filer month also ensures that one GSTR-9 exists for that financial year; repeated months are no-ops for the annual header. - "Current month" is the month in India time. Returns for a month are filed in the next one, but they open with the month so that GSTR-1 builds up while it runs and a bad buyer GSTIN or missing HSN surfaces while it can still be fixed. Nothing pre-creates every month and year merely because the console was opened. There is one current edge case to understand: the widget presents an annual GSTR-9 card even for an ISD registration, while the provisioning service does not create GSTR-9 for an ISD. That card can therefore lead to an empty scoped list. Treat that as absence of a provisioned annual record, not as a completed filing. ## Recommended workflow 1. Select the filer registration and verify its GSTIN and registration type. 2. Select a financial year derived from the stored fiscal periods. 3. Select the annual row or the required month; do not mistake a generated timeline scaffold for provisioned returns. 4. Read each card as a summary only, then open it and verify the record's own GSTIN and period. 5. Run processing, reconciliation and filing-record actions from the return surface described on that return's documentation page. 6. Return to the console and refresh to confirm the summary changed as expected. ## Common questions ### Why is the GSTIN picker empty? No active `GSTRegistration` record with a nonblank GSTIN was returned. Correct or create the registration master and verify the user's permission to read it. ### Why is a financial year missing? The normal choices come from stored `GSTFiscalPeriod` rows. Provision or create the required fiscal periods; the single fallback year shown when no rows exist is only a navigation default. ### Why do I see months but no return record? The console can synthesize the twelve-month timeline when fiscal-period data is absent, and a card can fall back to a scoped list when no exact header exists. Run the appropriate provisioning action or scheduled job for the required registration and period. ### Why does GSTR-2B say Not Synced when the statement has rows? The card counts only the portal side: documents pulled from GSTN with **Pull From GSTIN**. Rows built from your own purchases by **Process GSTR2B** are the books side and do not make the card Synced. Open the statement, run **Pull From GSTIN**, and refresh the console. ## Related topics - [GSTR-1 — outward supplies](/docs/finance/tax-center/gstr-1/) - [GSTR-2B — inward supplies and ITC](/docs/finance/tax-center/gstr-2b/) - [GSTR-3B — the summary return](/docs/finance/tax-center/gstr-3b/) - [Annual returns](/docs/finance/tax-center/annual-returns/) ---- # GSTR-1: preparing the outward-supplies return URL: https://xmatix.com/docs/finance/tax-center/gstr-1/ Last reviewed: 2026-09-02 GSTR-1 is the detailed outward-supplies return: it reports sales at the document level, table by table. xMatix never asks you to key invoices into it — every posted sales invoice, credit note and debit note has already captured its tax lines, and the return is **materialized** from those lines. Your work is to process, review, reconcile and file. ## Prerequisites - The period's sales documents approved and posted — an unposted invoice has no tax lines and cannot appear in the return. - The GSTIN's return record for the period, provisioned via the [GST console](/docs/finance/tax-center/gst-console/). - Permission to run the GSTR-1 actions. ## Procedure @[guided-image](_img/new-gstr-1.png) ### Step 1 — Process the return Open the return from the GST console and verify its GSTIN, fiscal period and Draft status before running **Process GSTR-1 Data**. Record the source-document cut-off and wait for the processing summary; do not navigate away while the first materialization is running. The processor reads output-tax lines for exactly that GSTIN and period and routes each document into its statutory table: | Return table | Filled from | | --- | --- | | B2B (incl. SEZ, deemed export) | Invoices to registered buyers, one row per invoice with per-rate tax detail | | B2C Large | Inter-state B2C invoices over the per-invoice threshold in force for the period | | B2C Small | All other B2C supplies, aggregated by place of supply and rate | | Exports | Export invoices, split by with/without payment of tax | | Credit / debit notes | Posted sales credit and debit notes — credit notes net the liability down | | Nil-rated / exempt | Supplies with taxable value and no tax, aggregated (you can re-split the figure across the statutory columns; your split is preserved) | | HSN summary | Every supply grouped by HSN/SAC and rate, credit notes netted | | Documents issued | Not derived — maintain this table yourself; it needs your document series, which tax lines do not carry | Processing is **incremental**: unchanged data is skipped, while changes merge into existing rows so prior row decisions survive. After each run, reconcile processed/skipped/failed counts and confirm the data watermark or last-processed time advanced. Use **Rebuild** only for an approved repair because it deliberately discards prior reconciliation decisions. ### Step 2 — Review the summary Review every statutory summary block—document count, taxable value and IGST/CGST/SGST/cess—and drill into material or unusual totals to their source documents. Tie the net outward liability to the sales/tax control reports for the same GSTIN and period. The grand total correctly excludes HSN summary and documents-issued tables to avoid double-counting, and credit notes are netted; account for those rules explicitly in the reconciliation rather than adding all displayed blocks together. ### Step 3 — Reconcile books against the portal Import or refresh the portal side, then open **Reconciliation**. Confirm the portal period and GSTIN match the books snapshot before interpreting results. The view pairs rows on statutory natural keys—buyer GSTIN plus invoice number for B2B, note number/type for notes and equivalent keys elsewhere—and assigns a status: | Status | Meaning | | --- | --- | | Matched | Both sides agree within a one-rupee tolerance | | Mismatch | Both sides have the document; amounts differ | | Missing in GSTN | Your books have it; the portal side does not | | Missing in books | The portal side has it; your books do not | ### Step 4 — Record decisions on the differences Open every Mismatch or Missing row to its source evidence before choosing an action. Two actions resolve filing differences without touching the ledger: - **Carry forward** reports the selected documents in the **next** period's filing instead of this one — the usual answer for a document the portal never received before you filed. The next period picks it up automatically, even if its return has not been provisioned yet. - **Ignore** drops the documents from this filing outright. Verify the row's decision tag plus the ignored/carried-out/carried-in summary counts. The current Carry Forward and Ignore actions persist the selected row flags, but they do **not** collect a reason, reviewer or approval audit field; retain that evidence in your approved workpaper if your control process requires it. Aggregated rows such as B2C Small and HSN have no document identity and cannot take a row decision. If carry-forward is refused because the next period is already filed, stop and process the statutory amendment rather than forcing the document out of both periods. ### Step 5 — File and record the filing After an authorized reviewer approves the final totals and exception register, file on the GST portal. Then run the GSTR-1 filing-record action with the filing date and verify that `IsFiled` is set, Status becomes **Filed**, and processing is disabled. This action records the state in xMatix; the GSTR-1 header has no acknowledgment, ARN or portal-reference field and the action does not retain one. Keep the portal acknowledgment in your controlled filing evidence. A filed GSTR-1 is a statutory snapshot: later ledger changes cannot regenerate it, and corrections use an amendment in a later period rather than reopening this return. ## Expected result The return contains the correct GSTIN and fiscal-period outward supplies, reconciles books to portal with every difference either resolved or explicitly decided, and ties to the approved tax controls. Recording the filing date freezes the xMatix snapshot and prevents accidental reprocessing; portal acknowledgment evidence must be retained outside the GSTR-1 header. ## Keeping it fresh automatically The same processing can run unattended: schedule the **GSTR-1 processing job** (`finance.gstr1.process`) on a recurrence from the Schedules screen. In discovery mode it processes every unfiled return whose period is open, across all filer GSTINs; it skips unchanged periods, preserves reconciliation decisions, and skips filed returns rather than failing on them. The run summary reports processed, skipped and failed counts on the Jobs screen. ## Common problems **An invoice is missing from the return.** Work through the source document: is it posted (drafts capture nothing)? Is its document date inside the period? Was it issued under the same GSTIN the return is for? Was it ignored or carried forward in a reconciliation decision — the summary's excluded-document counts will say. **Processing is refused.** The return is filed. That is the guard working; raise the correction as an amendment in the next open period. ## Related topics - [The GST console](/docs/finance/tax-center/gst-console/) - [GSTR-3B — the summary return](/docs/finance/tax-center/gstr-3b/) — Compute prefers a filed same-period GSTR-1 but can fall back to a Draft one. - [Troubleshooting the Tax Center](/docs/finance/tax-center/troubleshooting/) ---- # GSTR-2B: the inward ITC statement URL: https://xmatix.com/docs/finance/tax-center/gstr-2b/ Last reviewed: 2026-10-10 GSTR-2B is the monthly statement of input tax credit (ITC) that GSTN drafts for you from what your **suppliers** filed. In xMatix a **GSTR2B** record holds that statement for one GSTIN and one month, in two versions side by side. The **portal side** is the statement as GSTN drafted it, which you fetch with **Pull From GSTIN**. The **books side** is the same statement built from your own posted purchases with **Process GSTR2B**. Comparing the two shows which credits your suppliers have reported and which they have not. The portal side then feeds table 4A of [GSTR-3B](/docs/finance/tax-center/gstr-3b/). ## Overview A GSTR-2B statement is not a return you file. GSTN generates it, usually on the 14th of the month after the return period, and you bring it in and check it. The record therefore has no filing status and no Submit or File button. The record page has: - a header with the **Pull From GSTIN** and **Process GSTR2B** buttons, and the GSTIN, GST Fiscal Period, Generation Date and Last Processed values; - a **GSTR2B Statement & Reconciliation** tab with two inner tabs: - **Overview**: four reconciliation count cards, then the section-by-section summary; - **Reconciliations**: the document-by-document comparison; - a **Details** tab showing GST Fiscal Period, Last Processed, Processed Invoice Value and Cutoff Date. The statement is split into the sections GSTN uses: | Section | What it holds | Books side? | | --- | --- | --- | | B2B | Invoices from registered suppliers | Yes, built from your posted bills | | B2B Amendments (B2BA) | Amendments to earlier B2B invoices | Portal side only | | Credit / Debit Notes (CDNR) | Supplier credit and debit notes | Yes, built from your posted purchase returns | | Credit / Debit Note Amendments (CDNRA) | Amendments to earlier notes | Portal side only | | ISD Credits and ISD Credit Amendments | Credit distributed to you by an Input Service Distributor | Portal side only | | Import of Goods (Overseas) and Import of Goods (SEZ) | Bills of entry for imported goods | Portal side only | | E-Commerce (9(5)) and E-Commerce Amendments | Supplies made through an e-commerce operator | Portal side only | | ITC Summary | GSTN's own totals of ITC available and ITC not available | Portal side only | Your purchase ledger can only produce B2B and credit/debit notes. The other sections exist only on the portal side. ## When to use it Use it every month for every regular GST registration, after the month's bills and purchase returns are posted and once GSTN has generated the statement. Bring in the portal side and finish reconciling before you process that month's GSTR-3B, because GSTR-3B takes its ITC from the portal side of this statement. An Input Service Distributor registration gets no GSTR-2B. It files [GSTR-6](/docs/finance/tax-center/gstr-6/) instead. ## How xMatix handles it - **Statements are created for you.** GST return provisioning creates one GSTR-2B per active regular registration per month, together with that month's GSTR-1 and GSTR-3B. It is labelled with the period, for example "GSTR-2B Aug 2026", and its Generation Date is set to the 14th of the following month, the date GSTN is expected to release it. Provisioning never creates a second statement for the same GSTIN and period. See [The GST console](/docs/finance/tax-center/gst-console/). - **Two independent sides.** Process GSTR2B only ever changes the books side, and Pull From GSTIN only ever replaces the portal side. You can repeat either one as often as you need without disturbing the other. - **Processing is incremental.** If no purchase tax line for the period has changed since the last run, Process GSTR2B makes no changes. Otherwise it updates the documents that changed, adds new ones and removes ones that no longer exist, so documents that did not change keep their identity. - **The pull is triggered automatically, too.** When a GST registration completes GSTN authentication, xMatix requests a pull for that GSTIN's statement in the earliest open GST period, if there is one. - **The statement cannot be deleted.** It is a statutory statement, so deletion is refused. - **Processing can run on a schedule.** The **Process GSTR-2B data** job runs Process GSTR2B unattended. It does not fetch from GSTN. ## Prerequisites - An active **GST Registration** for the GSTIN, and a monthly GST fiscal period for the month. - The month's bills and purchase returns posted, each against a supplier account that carries the supplier's GSTIN. - To pull from GSTN: - the GST Registration has a GSTN username; - your administrator has set up the GSP integration that fetches GSTR-2B (see [Configuration](#configuration)); - you can receive the OTP that GSTN sends for the registration. - A security profile that grants the GSTR2B actions you need (see [Permissions](#permissions)). ## Procedure ### Step 1 — Open the statement Open the GST console, choose the GSTIN, financial year and month, and click the **GSTR-2B** card. Or open the GSTR2B list and open the row for the GSTIN and GST Fiscal Period. The list shows Name, GSTIN, GST Fiscal Period, Generation Date and Cutoff Date. Check the GSTIN and period in the record header before you do anything else. If no statement exists for the month, run **Provision GST Returns** on the GST Registration or on the GST fiscal period (see [The GST console](/docs/finance/tax-center/gst-console/)). An administrator can also create one with **New**. @[guided-image](_img/new-gstr-2b.png) **New** asks for **GSTIN**, **GST Fiscal Period**, **Generation Date** and **Cutoff Date**. The Name is numbered automatically. If the GSTIN is not a valid 15-character GSTIN, the save is refused with "'…' is not a valid 15-character GSTIN." ### Step 2 — Process the books side Click **Process GSTR2B** in the record header. xMatix reads the purchase tax lines that meet all of these conditions: - they belong to this GSTIN; - they carry a supplier account; - their document date falls in the statement's month. It then builds the books side: - one B2B supplier per supplier GSTIN, with one invoice per bill; - one credit/debit-note supplier per supplier GSTIN, with one note per purchase return. Each invoice carries its taxable value, the four tax heads and the invoice value (taxable value plus tax). A bill line with no tax (exempt, nil-rated or zero-rated) is kept with a taxable value only. A bill marked as an SEZ supply is typed as SEZ with payment when it carries integrated tax, and SEZ without payment when it does not. When the run finishes: - **Last Processed** shows the time of the latest source change it took in; - **Processed Invoice Value** shows the books side's total value; - the Overview tab shows the books-side figures. If nothing changed since the last run, nothing is rewritten. ### Step 3 — Pull the statement from GSTN Click **Pull From GSTIN**. The dialog shows the GSTN authentication panel for the statement's GSTIN and period. 1. If the GSTIN has no live session, click **Send OTP**, type the six-digit code GSTN sends, and click **Confirm**. Wait for **Authenticated with GSTN**. 2. When the session is live, the panel shows the session summary. Click **Proceed**. 3. xMatix answers "Checking generation status and fetching from GSTN. This runs in the background — reopen this action in a few seconds to import what comes back." The fetch runs in the background. When GSTN's reply arrives, xMatix normally imports it at once. Each portal section, including the ITC Summary, is replaced with what GSTN returned, and the Generation Date is updated to the date GSTN gives. If the reply could not be imported straight away, wait a few seconds and click **Pull From GSTIN** again: the second click imports the reply already received. If GSTN refuses the request, nothing is imported and the portal rows from the last good pull stay as they were. The reason is recorded in the statement's **Pull Message** (see [Common problems](#common-problems)). **Re-authenticate** in the panel starts a new GSTN session. GSTN allows one session per username, so this ends the existing session, including one someone else is using. ### Step 4 — Review the summary Open **GSTR2B Statement & Reconciliation → Overview**. The summary has one row per section, with Total Transactions, Taxable Amount, IGST, CGST, SGST and Cess, and a Total row. B2B, Credit / Debit Notes, ISD Credits, both import sections and E-Commerce always appear. The amendment sections appear only when they have documents. Click a section row to open the supplier or document list behind it. The record's Overview shows the **books side**. The GST console's GSTR-2B card shows the **portal side**: - **Synced**, with the statement's invoice value and a "Taxable … · Tax …" line, once portal rows exist; - **Awaiting GSTN Data** before the expected Generation Date; - **Not Synced** after that date if the statement has not been pulled. Never add books and portal figures together. They are two versions of the same statement. ### Step 5 — Reconcile the two sides Click one of the four count cards (**Matched Transactions**, **Mismatched Transactions**, **Missing in Books**, **Missing in GSTN**) or open the **Reconciliations** tab. Each sub-tab lists documents with party details, invoice number, transaction date, the tax heads and the total. The GSTN figures are on the top line and your books on the bottom line. | Status | Meaning | What to do | | --- | --- | --- | | Matched | The document is on both sides and the taxable value, every tax head and the value agree exactly | Nothing | | Mismatch | The document is on both sides but at least one amount differs | Compare the bill with the supplier's invoice; correct the bill, or ask the supplier to amend | | Missing in Books | GSTN has it, your books do not | Post the missing bill, or check that the bill has the right supplier GSTIN, number, date and month | | Missing in GSTN | Your books have it, GSTN does not | Follow up with the supplier; the credit is only available once they report the invoice | Documents are paired as follows: - B2B invoices: supplier GSTIN, invoice number and invoice date; - credit and debit notes: supplier GSTIN, note number and note type; - ISD credits: ISD GSTIN, document number and date; - overseas imports: bill-of-entry number and date; - SEZ imports: supplier GSTIN, bill-of-entry number and date; - e-commerce documents: operator GSTIN, invoice number and date. The amendment sections are not reconciled. The **Missing in Books** and **Missing in GSTN** tabs offer row buttons: **Add In Books**, **Ignore** and **Vendor Follow-up**. No GSTR-2B action stores what you choose there, so the statement does not change and the row stays where it is after the grid refreshes. Take the actual step (post the bill, contact the supplier) in your normal process. ### Step 6 — Hand over to GSTR-3B When the portal side is in place and the differences are understood, run **Process GSTR3B** on the month's GSTR-3B. It reads only the **portal side** of this statement, and only the documents GSTN marks as ITC available. See [GSTR-3B](/docs/finance/tax-center/gstr-3b/). ## Fields These are the fields of a GSTR2B record. The four pull fields at the end are not on the standard form; your administrator can add them. | Field | What it means | Notes | | --- | --- | --- | | Name | The statement's reference | Generated automatically. Provisioned statements are named after the GSTIN and period. | | Label | Display name, for example "GSTR-2B Aug 2026" | Set by provisioning | | GSTIN | Your own GSTIN, the recipient of the supplies | Must be a valid 15-character GSTIN. Decides which purchase tax lines are processed and which GST Registration session is used for the pull. | | GST Fiscal Period | The monthly GST period the statement covers | Required by both Process GSTR2B and Pull From GSTIN. Read-only on the Details tab. | | Generation Date | When GSTN generates or generated the statement | Provisioning sets the 14th of the next month as the expected date; a pull replaces it with GSTN's own date | | Cutoff Date | The last date of supplier filings the statement includes | Supplier filings after it appear in a later month's statement. Read-only on the Details tab. | | Last Processed | When the books side last changed | Written by Process GSTR2B; read-only | | Processed Invoice Value | Total value (taxable value plus tax) of the books side | Written by Process GSTR2B; read-only. It is not the ITC amount and not the GSTN figure. | | Pull Status | Where the latest GSTN pull stands: PullRequested, Fetched, FetchFailed or Imported | Blank until the first pull. Not on the standard form (see [Configuration](#configuration)). | | Pull Message | GSTN's or xMatix's message for the latest pull | Shows why a pull failed. Not on the standard form. | | Pull Return Period | The period sent to GSTN, as MMYYYY | Set from the GST Fiscal Period when a pull is requested | | Generation Status | GSTN's generation status for the period: Processing, Completed or Error | Display only, and may stay blank; it does not control the pull | ## Business rules - **Validation.** A GSTIN that is not a well-formed 15-character GSTIN is refused on save. A blank GSTIN can be saved, but neither Process GSTR2B nor Pull From GSTIN will run on it. - **No deletion.** Deleting a statement fails with "A GSTR-2B is a statutory auto-drafted ITC statement and cannot be deleted." - **Period protection.** A GST fiscal period that a GSTR-2B refers to cannot have its Month, Year or Type changed. - **Books side source.** Only purchase tax lines that carry a supplier account are used. Bills go to B2B and purchase returns go to credit/debit notes. A document's ITC Availability is Y when any of its tax lines is ITC-eligible. - **Skip-if-unchanged.** A run is skipped when the period's purchase tax lines have the same latest change time and the same count as at the last run. Deleting a document lowers the count, so the next run picks it up. - **Portal side replacement.** A successful pull replaces every portal section and the ITC Summary. A refused or malformed reply replaces nothing. - **Period check on import.** A reply fetched for a different period than the statement's is refused, so one month's data can never land on another month's statement. - **Session rules.** A pull needs: - a GST Registration for the GSTIN; - a completed GSTN authentication less than 6 hours old. - **One pull at a time.** A second request within 5 minutes of the first is not sent again. After 5 minutes a stuck request can be sent again. - **Effect on GSTR-3B.** Table 4A is built from the portal side only: - imports go to 4A(1); - ISD credits go to 4A(3); - reverse-charge invoices go to 4A(4); - all other B2B invoices and amendments go to 4A(5). Only documents marked ITC available count. A document with IMS status **R** (rejected) is left out. The ITC Summary's not-available figures feed 4D(2). ## Example A trading company has GSTIN 27ABCDE1234F1Z5. Its August 2026 GSTR-2B is provisioned on 1 August with Generation Date 14 September. 1. During August the team posts 42 bills and 2 purchase returns. 2. On 15 September the accountant opens the statement and clicks **Process GSTR2B**. The books side shows 42 B2B invoices from 17 suppliers, 2 credit notes, and a Processed Invoice Value of ₹18,40,500.00. 3. They click **Pull From GSTIN**, enter the OTP, and click **Proceed**. A few seconds later the GST console card shows **Synced**. 4. In **Reconciliations** the cards read 38 Matched, 1 Mismatch, 2 Missing in Books and 3 Missing in GSTN. - **Mismatch:** the supplier invoiced ₹1,180.00 of tax where the bill shows ₹1,108.00. The bill is corrected. - **Missing in Books:** one bill was dated 1 September by mistake, and one is an overseas import that only GSTN can report. - **Missing in GSTN:** three suppliers have not filed yet. The team emails them. 5. After the corrections, **Process GSTR2B** runs again, and only the corrected documents change. 6. On 18 September the accountant runs **Process GSTR3B**. Table 4A takes its credit from the portal side. ## Training ### Practice exercise In a sandbox with a regular GST registration and an open monthly GST period: 1. Post two bills in that month against supplier accounts that have GSTINs. 2. Open that month's GSTR-2B and click **Process GSTR2B**. 3. Confirm that Last Processed is filled and that the Overview shows a B2B row with two documents. 4. Click **Process GSTR2B** again without changing anything. **Expected result:** the second run changes nothing. If no GSP integration is configured in the sandbox, every document appears under **Missing in GSTN**, because there is no portal side to match against. ### Quick reference - One GSTR-2B per GSTIN per month; provisioning creates it. - Books side = Process GSTR2B; portal side = Pull From GSTIN. - Neither action touches the other side. - The record's Overview shows books; the GST console card shows the portal side. - Matched means every amount agrees exactly. - B2B pairs on supplier GSTIN, invoice number and invoice date. - Imports, ISD and e-commerce documents always show as Missing in Books. - GSTR-3B 4A reads the portal side only. - The statement cannot be deleted. ## Permissions Each button is a server action that a [security profile](/docs/administration/security-profiles/) must grant. In the standard profiles: | Action | System Admin | Standard User | Sales Executive | | --- | --- | --- | --- | | Process GSTR2B | Yes | Yes | No | | Pull From GSTIN | Yes | Yes | No | | Get GSTR2B (the Overview summary) | Yes | Yes | No | | Get GSTR2B Reconciliation (the Reconciliations tab) | Yes | Yes | No | | New | Yes | Yes | No | | Edit | Yes | Yes | Yes | A user without an action does not get that button. A user without the two Get actions cannot load the statement tab. Because Pull From GSTIN opens a live GSTN session, grant it only to the finance profile that works with GST. See [Why can't a user see a record?](/docs/administration/user-cant-see-x/). ## Configuration - **GST Registrations.** - Every active registration with a GSTIN that is not an Input Service Distributor gets a monthly GSTR-2B. - The registration needs its GSTN username, and **Request GSTN OTP** / **Submit OTP** establish the session the pull uses. A session lasts about 6 hours. - **GST fiscal periods.** - Each statement hangs off a monthly GST fiscal period. - The automatic pull after authentication and the scheduled processing job both work on **Open** periods. - **Provisioning.** The **Provision GST returns** scheduled job and the **Provision GST Returns** action on a GST Registration or GST fiscal period create the statements. See [The GST console](/docs/finance/tax-center/gst-console/). - **Scheduled processing** (**Setup → Administration → Jobs**). - The **Process GSTR-2B data** job runs Process GSTR2B on every statement whose period is Open, or for a named month, year and GSTIN. - It skips unchanged periods, makes up to 3 attempts, and runs one at a time per tenant. - It runs only when a schedule is set. - Schedule it before GSTR-3B processing. - **GSP integration** (**Setup → Process Studio → Integrations**). Pulling the statement needs an integration app with: - a connection to your GSP gateway; - a flow with an entity-event trigger on **GSTR2B** updates where Pull Status is PullRequested. The flow posts the request xMatix prepares and writes GSTN's reply back to the statement. Without the flow, Pull From GSTIN still responds, but nothing reaches GSTN and Pull Status stays at PullRequested. See [Outbound integrations](/docs/integrations/outbound/). - **The form.** The standard form does not show **Pull Status** or **Pull Message**. Add both to the **Details** tab in the form designer so users can see whether a pull succeeded and why GSTN refused one. - **Numbering.** Names for statements created with **New** come from the **GSTR-2B Headers Name Setting** document-numbering setting (series GSTR2B). See [Templates and numbering](/docs/administration/templates/). - **Mobile.** The GSTR2B record has a mobile layout with the **Pull From GSTIN** button and the header fields. Whether it is reachable in the field app depends on your mobile app configuration. ## Common problems ### A bill is missing from the books side Process GSTR2B only takes a bill when all of these are true: - it is posted, and its tax lines were recorded; - its document date is in the statement's month; - it is against a supplier account; - it was recorded under the statement's GSTIN. Fix the bill, then click **Process GSTR2B** again. ### Imports, ISD credits or e-commerce documents appear under Missing in Books That is expected. Your purchase ledger cannot produce those sections, so they exist only on the portal side. ### The same invoice appears under both Missing in Books and Missing in GSTN The two sides disagree on the invoice number or the invoice date, so they did not pair. Correct the bill to match the supplier's invoice and process again. ### "This statement has no GSTIN, so it cannot be pulled from GSTN." Enter the statement's GSTIN, save, and try again. ### "… is not authenticated with GSTN. Request an OTP and complete authentication first." The registration has no live session. In the Pull From GSTIN dialog, click **Send OTP** and complete the code. The same fix applies to: - "The GSTN session for … has expired"; - "… has no session app key"; - "… has no recorded authentication time". If the message is "No GST registration found for …", create the GST Registration for that GSTIN. ### "A fetch is already in progress for this statement." A pull was requested less than 5 minutes ago. Wait, then click **Pull From GSTIN** again to import the reply. ### The pull ended but nothing changed Look at **Pull Message**: - "The portal response is an error, not data", followed by GSTN's code and text: GSTN refused the request. The previous portal rows were kept. Fix the cause (often an expired session or a statement GSTN has not generated yet) and pull again. - "Fetched from GSTN but not imported yet: …": run **Pull From GSTIN** once more to import the reply. ### "This statement is for return period …, but the portal data was fetched for …" The reply belongs to another month. Pull again from the correct statement. ### "… has no linked GST fiscal period; set the return period before processing." Set the GST Fiscal Period on the statement, then process again. Pull From GSTIN refuses the same case with "This statement is not linked to a fiscal period, so its return period cannot be determined." ### Add In Books, Ignore or Vendor Follow-up does not change anything These buttons do not record a decision on a GSTR-2B statement. Post the missing bill, or follow up with the supplier, through your usual process. ## Common questions ### Why do the record and the GST console show different totals? They show different sides. The record's Overview summarises the books side, built from your own bills and purchase returns. The GST console card shows the portal side, the statement GSTN actually drafted. A difference between the two is exactly what the Reconciliations tab breaks down document by document. Processed Invoice Value on the Details tab is also the books total. It is the gross value of the documents, not the ITC amount. ITC available and not available are GSTN's own figures, held in the statement's ITC Summary once it is pulled. ### Will processing again overwrite what I pulled from GSTN? No. Process GSTR2B only touches the books side, and Pull From GSTIN only replaces the portal side. You can process the books after every correction without pulling again, and pull again without reprocessing. Each pull replaces the portal side with GSTN's latest reply, so a pull after GSTN regenerates the statement brings in the new version. A failed pull leaves the last good portal data in place. ### Does xMatix record IMS accept or reject decisions? When GSTN's reply carries an IMS status for a document, xMatix keeps it in the document's IMS Status field. GSTR-3B leaves out any document with IMS status R (rejected) from table 4A. The GSTR-2B screen itself has no action to accept or reject a document. The row buttons on the Reconciliations tab do not store a decision. Make IMS decisions on the GSTN portal, then pull the statement again. ### When should I pull the statement? Pull after GSTN generates it. The GST console shows "GSTN releases it on …" until the expected Generation Date. Supplier filings after the Cutoff Date go into the next month's statement. A document missing from GSTN this month may therefore appear next month, once the supplier files it. ## Related topics - [The GST console](/docs/finance/tax-center/gst-console/): provisioning statements and reading the GSTR-2B card. - [GSTR-3B](/docs/finance/tax-center/gstr-3b/): where the statement's ITC lands. - [Input tax credit management](/docs/finance/tax-center/itc-management/): what happens to the credit after the statement. - [GSTR-1](/docs/finance/tax-center/gstr-1/): the outward return your customers' GSTR-2B is drafted from. - [AR and AP subledgers](/docs/finance/subledgers/): the bills and purchase returns behind the books side. - [GSTR2B entity reference](/docs/reference/entities/gstr2-b/) ---- # GSTR-3B: preparing, saving and filing the summary return URL: https://xmatix.com/docs/finance/tax-center/gstr-3b/ Last reviewed: 2026-10-09 GSTR-3B is the monthly summary return for one GSTIN: you declare total outward supplies, input tax credit (ITC) and the tax payable for the month, rather than listing individual documents. In xMatix, a **GSTR 3B** record is prepared after the month's [GSTR-1](/docs/finance/tax-center/gstr-1/) and [GSTR-2B](/docs/finance/tax-center/gstr-2b/) are in place. **Process GSTR3B** fills the boxes from those two returns and your own tax ledger. You then review the return, complete the boxes xMatix cannot know, and either file through your GSP integration (**Save to GSTN**, **Check Save Status**, **Submit File to GSTN**) or file on the government portal yourself and use **Record Manual Filing**. A Filed GSTR-3B feeds the annual [GSTR-9](/docs/finance/tax-center/annual-returns/). ## Overview Each GSTR 3B record covers one GSTIN and one monthly return period. It has two tabs: - **Overview** shows the return in form layout: tables 3.1, 3.1.1, 4A, 4B, the derived 4C net ITC line, 4D and 6.1, each with taxable value, integrated tax, central tax, state/UT tax and cess, and a **Total Amount** row. Every statutory line is shown, even before the return is processed (at ₹0.00). Clicking a line, or **View All** under a table, opens the records behind that table for this return. - **Details** holds the header fields: Label, GSTIN, Return Period, Status, Filed On, Ack Number, GSP Reference Id, Computed At, Is Nil Return and Processed Invoice Value. The record header carries the buttons **Process GSTR3B**, **Save to GSTN**, **Check Save Status**, **Submit File to GSTN** and **Record Manual Filing**. ## When to use it Use GSTR-3B every month for each active, regular (non-ISD) GST registration. An Input Service Distributor registration files [GSTR-6](/docs/finance/tax-center/gstr-6/) instead and gets no GSTR-3B. Work on a month's GSTR-3B after the month's sales and purchase documents are posted, its GSTR-1 is processed and its GSTR-2B statement is loaded. ## How xMatix handles it **Records are created for you.** xMatix does not offer a **New** button for GSTR-3B. The **Provision GST returns** scheduled job, or the **Provision GST Returns** action on a GST Registration, creates one Draft GSTR-3B per active registration per month (together with GSTR-1 and GSTR-2B). The return is named after the GSTIN and period and labelled, for example, "GSTR-3B Aug 2026". Running provisioning again never creates a duplicate. See [The GST console](/docs/finance/tax-center/gst-console/). **Process GSTR3B rebuilds the derived boxes in one pass.** It first refreshes the Rule 37 tracker from your purchase bills. It then picks its sources, replaces every row it derived last time, and sets Status to **Computed** and stamps **Computed At**. The sources are: - **GSTR-1:** the same-GSTIN, same-period GSTR-1, preferring a Filed one. When none is Filed, the latest Draft is used. - **GSTR-2B:** the latest same-GSTIN, same-period statement by generation date. | Box | What xMatix puts there | Source | | --- | --- | --- | | 3.1(a) | Taxable outward supplies: B2B (except SEZ), B2C large and B2C small. Credit notes reduce it and debit notes add to it | The selected GSTR-1, books side only | | 3.1(b) | Zero-rated supplies: exports and SEZ supplies (with or without payment) | The selected GSTR-1 | | 3.1(c) | Nil-rated and exempt supplies (value only) | The selected GSTR-1's nil/exempt rows | | 3.1(d) | Inward supplies liable to reverse charge | Your tax ledger: input tax lines flagged reverse charge, dated in the month | | 3.1(e) | Non-GST outward supplies | Manual — never computed | | 3.1.1 (i) and (ii) | E-commerce supplies under section 9(5) | Manual — never computed or cleared | | 4A line (1) | Import of goods, including from SEZ (IGST and cess) | The GSTR-2B statement, portal side | | 4A line (2) | Import of services | Manual — never computed | | 4A line (3) | ISD credits marked available | The GSTR-2B statement, portal side | | 4A line (4) | Reverse-charge B2B credits marked available | The GSTR-2B statement; invoices with IMS status Reject are excluded | | 4A line (5) | All other B2B credits marked available | The GSTR-2B statement; invoices with IMS status Reject are excluded | | 4B(1) | ITC you blocked (for example under section 17(5)) | Your tax ledger: input lines with ITC eligibility Blocked, dated in the month | | 4B(2) | Rule 37 reversals: bills still unpaid 180 days after the bill date | The Rule 37 tracker | | 4C | Net ITC available (4A minus 4B) | Calculated on screen and when sent to GSTN; not stored | | 4D(1) | Rule 37 reclaims: earlier reversals whose bill was paid this month | The Rule 37 tracker | | 4D(2) | ITC the statement shows as not available (disclosure only) | The GSTR-2B statement's ITC summary | | 6.1 | Tax payable per head (IGST, CGST, SGST, Cess) | The tax in 3.1(a), 3.1(b) and 3.1(d), gross of ITC | Three design points explain most questions: - **Outward figures follow the GSTR-1 exactly.** Documents you marked Ignore or Carry Forward on the GSTR-1 are left out of 3.1, just as they are left out of the filed GSTR-1. A carried-forward document counts once, in the period it was carried into. - **Reversals and reverse charge come from your ledger, not the statement.** GSTR-2B cannot know which credits you blocked or your reverse-charge workings, so 3.1(d) and 4B(1) are read from your own tax lines. - **4A lines (3) and (4) are in xMatix order.** On the government form, line (3) is reverse charge and line (4) is ISD. xMatix puts ISD credits on its line (3) and reverse-charge credits on its line (4), and the Overview labels follow that order. **Save to GSTN** sends 4A lines by position. So if you have both ISD and reverse-charge credit, check these two lines on the portal before you file. If they are wrong, correct them there, or file on the portal and record the filing with **Record Manual Filing**. **Rows you enter by hand are never overwritten.** Every derived row is marked as auto-filled. Reprocessing replaces only those rows; a row without the mark survives every recompute. Table 6.1 is updated in place: Process GSTR3B refreshes only **Payable** and keeps whatever was recorded as paid in cash or through each credit ledger. **Saving to GSTN is a two-stage exchange.** The GSTN save is asynchronous: **Save to GSTN** only queues the return, and **Check Save Status** fetches GSTN's verdict. **Submit File to GSTN** is allowed only after GSTN has accepted the save. None of these buttons talks to GSTN directly. Each one prepares the request on the return, and your tenant's GSP integration flows send it and write the answer back. ## Prerequisites - The month's GSTR 3B record exists (provisioned) and carries a valid 15-character GSTIN and a Return Period. - Sales and purchase documents for the month are posted, so the tax ledger is complete. - The month's [GSTR-1](/docs/finance/tax-center/gstr-1/) is processed. Filed is preferred; a Draft is used only when no Filed GSTR-1 exists. - The month's [GSTR-2B statement](/docs/finance/tax-center/gstr-2b/) is loaded, portal side included. - Supplier payments are posted against their bills, so the Rule 37 tracker sees which bills are settled. - **To file through the GSP:** your administrator has configured the GSTR-3B integration flows (see [Configuration](#configuration)), you have the **Save to GSTN**, **Check Save Status** and **Submit File to GSTN** permissions, and the filer GSTIN's GST Registration has a live GSTN session. ## Procedure ### Step 1 — Open the return Open the month's GSTR-3B from the [GST console](/docs/finance/tax-center/gst-console/) filing card, or from the GSTR 3B list. On **Details**, check the Label, GSTIN and Return Period, and that Status is **Draft** (or **Computed** if it has been processed before). ### Step 2 — Process the return Click **Process GSTR3B**. When it finishes, Status is **Computed** and **Computed At** shows the time. Open **Overview** and refresh it. The derived lines are now filled. If your administrator scheduled the **Process GSTR-3B data** job, this may already have happened overnight. Reprocessing is always safe on an unfiled return: it rebuilds only the derived rows. ### Step 3 — Review every box against its source For each filled line, reconcile the total to the source named in the table above: - 3.1 to the selected GSTR-1's summary; - 4A to the GSTR-2B statement; - 3.1(d) and 4B(1) to your tax ledger for the month; - 4B(2) and 4D(1) to the Rule 37 tracker. Click a line to see the records behind it. Pay particular attention to 4A lines (3) and (4) (see [How xMatix handles it](#how-xmatix-handles-it)). If a figure is wrong, fix the source and click **Process GSTR3B** again; do not edit a derived row. Examples are a missing bill, a wrong ITC eligibility on a tax line, or a document that should be ignored on the GSTR-1. ### Step 4 — Complete the boxes xMatix cannot know Add these yourself as rows on the matching table: - 3.1(e) non-GST outward supplies; - table 3.1.1 (e-commerce supplies under section 9(5)); - 4A line (2) import of services; - a Rule 42/43 proportional reversal in 4B(1) (see [Input tax credit management](/docs/finance/tax-center/itc-management/)); - any extra 4D disclosure; - in 6.1, the amounts paid in cash and through each credit ledger, plus any interest, late fee or penalty heads. Rows you add are kept when the return is reprocessed. In the standard configuration these tables open as read-only lists. If you cannot add a row, ask your administrator (see [Common problems](#common-problems)). ### Step 5 — File through the GSP: save, check, file 1. Make sure the filer GSTIN has a live session: on its **GST Registration**, click **Request GSTN OTP**, then **Submit OTP** with the code you receive, and wait for **Auth Status** to show Authenticated. A session is treated as expired 6 hours after **Authenticated**. 2. On the GSTR-3B, click **Save to GSTN** and confirm **Save this return to GSTN?** The return's 3.1 rows and 4A/4B/4D rows, with the derived 4C net line, are queued for GSTN. Save Status becomes SaveRequested, then **Submitted** once the gateway issues a reference; the reference appears in **GSP Reference Id**. 3. Click **Check Save Status**. xMatix asks GSTN what it did with the save; reopen the return a few seconds later. The verdict is one of: - **Accepted**: GSTN committed the return, and Status becomes **Saved**. - **RejectedByGstn**: **GSTN Response** lists one line per rejected box. - Still **Submitted**: GSTN is still processing. Click **Check Save Status** again. 4. When Save Status is **Accepted**, click **Submit File to GSTN** and confirm **File this return with GSTN?** When GSTN answers, **Ack Number** is filled, Status becomes **Filed**, and **Filed On** is stamped. Table 6.1 is **not** sent to GSTN. Pay the tax and offset liabilities on the portal, where your electronic cash and credit ledgers are held. ### Step 6 — Or record a filing you made on the portal If you filed the GSTR-3B directly on the government portal, click **Record Manual Filing**. Enter the **Ack Number (from the GSTN portal)** (required, at most 20 characters) and **Filed On** (defaults to now if left empty). The return becomes **Filed**. This button sends nothing to GSTN; it only records the outcome. ### Step 7 — After filing A Filed return is a frozen statutory snapshot. Process GSTR3B, Save to GSTN and Submit File to GSTN are refused on it, and the scheduled job skips it. GSTR-9 reads only Filed GSTR-3B returns. Corrections go through a later period's return. ## Fields @[guided-image](_img/new-gstr-3b.png) | Field | What it means | Notes | | --- | --- | --- | | Label | The return's display name, for example "GSTR-3B Aug 2026" | Set by provisioning; required on the form | | GSTIN | The filer's GST identification number | Must be a well-formed 15-character GSTIN; checked whenever the record is saved | | Return Period | The monthly GST fiscal period this return covers | Required. Decides which GSTR-1, GSTR-2B and ledger lines are read | | Status | Where the return is in its lifecycle | Written by the actions: Draft → Computed → Saved → Filed. The list also offers Pushed to GSTN and GST Payment Made, which no action sets | | Filed On | Date the return was filed | Stamped by Submit File to GSTN, or entered in Record Manual Filing | | Ack Number | The acknowledgement GSTN issued for the filing | At most 20 characters. Required for Record Manual Filing | | GSP Reference Id | The reference GSTN issued for the latest save | Not a receipt — only Check Save Status can tell whether GSTN accepted the save | | Computed At | When Process GSTR3B last ran | Read-only in practice | | Is Nil Return | Your marker that the month is a nil return | Informational: no action reads it, and Save to GSTN still refuses a return with no rows | | Processed Invoice Value | A header total field | Not filled by Process GSTR3B; a blank value does not mean processing failed | | Save Status | Where the GSTN save/file exchange is | Not on the standard web form; see the table below. Never edit it by hand | | GSTN Response | GSTN's or the gateway's last message for this return, including the per-box error list on a rejection | Not on the standard web form; shown on the mobile layout | | Is Filed | Yes once the return is filed by either route | Set together with Status Filed | **Save Status values** | Value | Meaning | What to do | | --- | --- | --- | | (empty) | Never sent to GSTN | — | | SaveRequested | Save to GSTN was clicked; the save flow is running | Wait; after 5 minutes you may click again | | Submitted | GSTN queued the save and issued a GSP Reference Id | Click Check Save Status | | SubmitFailed | The gateway refused the save, or GSTN returned an unrecognised status | Read GSTN Response, fix, save again | | StatusRequested | Check Save Status is fetching GSTN's verdict | Reopen the return in a few seconds | | Accepted | GSTN committed the return (Status Saved) | Submit File to GSTN | | RejectedByGstn | GSTN processed the return with errors, or refused it | Read GSTN Response, fix the source, reprocess, save again | | FileRequested | Submit File to GSTN was clicked; the file flow is running | Wait for the acknowledgement | | Filed | GSTN filed the return and issued an acknowledgement | Nothing — the return is final | | FileFailed | GSTN refused the file call | Read GSTN Response; the return is not filed and can be filed again | The full field list, including the box tables, is in the [GSTR 3B entity reference](/docs/reference/entities/gstr3-b/). ## Business rules - **GSTIN check.** Creating or saving a GSTR-3B with a malformed GSTIN is refused: "'…' is not a valid 15-character GSTIN." - **Processing preconditions.** Process GSTR3B is refused on a Filed return ("A filed GSTR-3B cannot be recomputed.") and when the GSTIN or Return Period is missing. - **Source selection.** Process GSTR3B takes a Filed GSTR-1 before a Draft one, then the most recent filing date. It takes the GSTR-2B statement with the latest generation date. It reads only the books side of GSTR-1 and only the portal side of GSTR-2B, so the two sides are never added together. - **Ledger rows are by document date.** 3.1(d) and 4B(1) read input tax lines for the GSTIN whose document date falls in the return month. - **Rule 37 tracker.** Each purchase bill with eligible ITC for the GSTIN, dated on or before the month end, gets a tracker row. - The row records the ITC (IGST, CGST, SGST), a due date 180 days after the bill date and, once the bill's open amount is zero, the latest payment date. - A bill still unpaid at month end after its due date is reversed in 4B(2), once. - When it is later paid, it is reclaimed in 4D(1) in the month of payment, once. - Reprocessing a month never reverses or reclaims the same bill twice. - **6.1 payable is gross.** Payable per head is the tax on 3.1(a) + 3.1(b) + 3.1(d). ITC is a way of discharging it, not a deduction from it. Reverse-charge tax is folded into each head's single total. - **Save to GSTN** is refused when: - the return is filed; - the return has no rows to send; - the GSTIN has no GST Registration or no live GSTN session; - a save, file or status check started less than 5 minutes ago. - **What Save to GSTN sends.** It sends 3.1 and 4A/4B/4D, plus the 4C net line when 4A has figures. Tables with no figures are left out, so a re-save never blanks a table saved earlier. Table 6.1 is never sent. - **Submit File to GSTN** is refused unless Save Status is **Accepted**. It rebuilds the request from the rows as they are at that moment. - **Record Manual Filing** is refused when the return is already Filed, has no valid GSTIN, has no Ack Number or one longer than 20 characters, or while a GSP filing is in progress (Save Status FileRequested). - **Filed is one-way.** Nothing in the product turns a Filed return back to an earlier status. - **Scheduled processing.** - The **Process GSTR-3B data** job processes unfiled returns in Open periods, or in a month, GSTIN or single return you name. - It skips a return whose GSTR-1 or GSTR-2B has not been processed yet, with the reason "waiting for GSTR-1" or "waiting for GSTR-2B". - It sets Status to Computed on every run, including on a return that was Saved. Save Status is not changed. ## Example A trading company holds GSTIN 29AAAAA0000A1Z5 and is preparing its August 2026 GSTR-3B in September. 1. The scheduled provisioning created "GSTR-3B Aug 2026" in Draft on 1 August. The August GSTR-1 has been processed and filed. The August GSTR-2B statement has been loaded. 2. The accountant opens the return and clicks **Process GSTR3B**. Overview shows: - **3.1(a):** taxable value ₹8,00,000 with IGST ₹54,000, CGST ₹45,000 and SGST ₹45,000. This already nets a ₹20,000 credit note. - **4A line (5):** IGST ₹30,000, CGST ₹20,000, SGST ₹20,000. - **4B(2):** CGST ₹3,000 and SGST ₹3,000 for a supplier bill dated 10 February 2026 that is still unpaid. Its 180-day due date was 9 August. - **6.1:** payable IGST ₹54,000, CGST ₹45,000, SGST ₹45,000. 3. The accountant checks 3.1(a) against the GSTR-1 summary and 4A against the GSTR-2B statement, and confirms with purchasing that the February bill is genuinely unpaid. 4. The company has no import of services, e-commerce or non-GST supplies this month, so no manual rows are needed. 5. The finance manager authenticates the GSTIN on its GST Registration, clicks **Save to GSTN**, then **Check Save Status**. A few seconds later Save Status is **Accepted** and Status is **Saved**. 6. The finance manager pays the net liability on the portal, clicks **Submit File to GSTN**, and the return comes back **Filed** with an Ack Number. 7. The supplier is paid on 15 September. When the September GSTR-3B is processed, the same CGST ₹3,000 and SGST ₹3,000 appear in 4D(1) as a reclaim. ## Training ### Practice exercise In a sandbox tenant with one active GST registration: 1. Post two sales invoices and one purchase bill in the current month, then process the month's GSTR-1 and load its GSTR-2B. 2. Open the month's GSTR-3B and click **Process GSTR3B**. 3. Find the invoices' tax in 3.1(a) and the bill's credit in 4A, if the bill's supplier appears in the GSTR-2B statement. 4. Click **Process GSTR3B** a second time. 5. Click **Record Manual Filing** with an Ack Number of your choosing, then try **Process GSTR3B** once more. **Expected result:** - After the first run, Status is Computed and Computed At is set. - After the second run, the figures are unchanged. - After Record Manual Filing, Status is Filed, Filed On is set, and the last Process GSTR3B is refused with "A filed GSTR-3B cannot be recomputed." ### Quick reference - GSTR-3B records are created by provisioning, not with a New button. - Process GSTR3B rebuilds only auto-filled rows; your own rows survive. - 3.1 comes from GSTR-1 (Filed preferred), 4A from the latest GSTR-2B, and 3.1(d) and 4B(1) from your tax ledger. - Fix the source and reprocess; never edit a derived row. - Check 4A lines (3) and (4) on the portal before filing through the GSP. - Save to GSTN, then Check Save Status until Accepted, then Submit File to GSTN. - Record Manual Filing is only for a return you filed on the portal yourself. - Table 6.1 is never sent — pay and offset on the portal. - Filed cannot be undone; corrections go in a later period. ## Permissions Each button is a server action that a [security profile](/docs/administration/security-profiles/) must grant. In the standard profiles: | Action | System Admin | Standard User | | --- | --- | --- | | Process GSTR3B | Yes | Yes | | GetGSTR3B (the Overview summary) | Yes | Yes | | Record Manual Filing | Yes | Yes | | Save to GSTN | Yes | No | | Check Save Status | Yes | No | | Submit File to GSTN | Yes | No | A user whose profile lacks an action does not get that action. Because the three GSP actions transmit a real return to GSTN, grant them deliberately, and only to the finance profile that files returns. Reading the record also depends on the profile's access to the GSTR 3B entity; see [Why can't a user see a record?](/docs/administration/user-cant-see-x/). ## Configuration - **GST registrations.** - Each **GST Registration** that is active and has a GSTIN gets a monthly GSTR-3B. A registration with **Enable ISD** gets a GSTR-6 instead. - The registration's **Provision GST Returns** action creates the current month's returns on demand. - **Request GSTN OTP** and **Submit OTP** establish the GSTN session that all three GSP actions need. A session lasts about 6 hours. - **GST fiscal periods.** Each return hangs off a monthly GST fiscal period. Provisioning creates the period, Open, if it does not exist. The scheduled processing job works on Open periods unless it is given a month. - **Scheduled jobs** (**Setup → Administration → Jobs**): - **Provision GST returns** creates the Draft headers for the current month in India time. - **Process GSTR-3B data** runs Process GSTR3B on unfiled returns once their GSTR-1 and GSTR-2B are processed. It makes up to 3 attempts and runs one at a time per tenant. - Both run only when a schedule is set for them. - Schedule GSTR-3B processing after GSTR-1 and GSTR-2B processing. - **GSP integration** (**Setup → Process Studio → Integrations**). Filing through the GSP needs, in one integration app: - a connection to your GSP gateway and its secrets; - three flows, each with an entity-event trigger on **GSTR 3B** updates: - the save flow, for Save Status SaveRequested; - the return-status flow, for StatusRequested; - the file flow, for FileRequested. All three must use the same GSP partner credentials, because only the partner that received a save reference can redeem it. Without the flows the buttons still respond, but nothing reaches GSTN and Save Status stays at the requested value. See [Outbound integrations](/docs/integrations/outbound/). - **Security profiles.** Grant **Save to GSTN**, **Check Save Status** and **Submit File to GSTN** on GSTR 3B to the profile that files returns (see [Permissions](#permissions)). - **The form.** The standard web form does not show **Save Status** or **GSTN Response**. Add both to the **Details** tab in the form designer so filers can see where the GSTN exchange stands and why GSTN rejected a save. - **Entering manual rows.** - The box tables (GSTR 3B Table 3.1, Table 3.1.1, Table 4A ITC, Table 4B ITC, Table 4D ITC and GSTR 3B Payment) ship without New or Edit actions or entry forms. - If your team keys manual figures in xMatix, add a New action and form to the tables they use. - Rows entered that way must have **Is Auto Filled** (**Auto Filled** on the 4B and 4D tables) off, or the next Process GSTR3B treats them as derived and replaces them. - **Mobile.** The GSTR 3B record has a mobile layout with the same five buttons, the header fields and GSTN Response. Whether it is reachable in the field app depends on your mobile app configuration. ## Common problems ### Box 3.1 is zero or lower than my sales Process GSTR3B uses the same-GSTIN, same-period GSTR-1, preferring a Filed one. Check that the GSTR-1 for this GSTIN and month was processed. Also check which documents on it you marked Ignore or Carry Forward, because those are excluded from 3.1 on purpose. Reprocess the GSTR-3B after fixing the GSTR-1. ### A credit I expected is missing from 4A 4A reads only the latest GSTR-2B statement for the month, portal side, and only lines marked available. An invoice with IMS status Reject is excluded. If the supplier has not reported the invoice, it is not in the statement and cannot be in 4A. Blocked credit appears in 4B(1), not 4A. ### "A filed GSTR-3B cannot be recomputed." The return is Filed and frozen. Corrections go through a later period's return. ### Process GSTR3B fails because the return period or GSTIN is not set The return is missing its Return Period or GSTIN. Provisioned returns always have both; a cloned or imported record may not. Work on the provisioned return for that GSTIN and month instead, or ask your administrator to complete the two fields. ### A figure I typed into a derived row disappeared Process GSTR3B (or the scheduled job) replaced it, because derived rows follow their sources. Correct the source document instead, or record the figure on a row that is not auto-filled. ### I can't find where to enter a manual figure In the standard configuration the box tables are read-only lists. Ask your administrator to add an entry form (see [Configuration](#configuration)). ### Processed Invoice Value is blank after processing That is expected: Process GSTR3B does not fill it. Use Status, Computed At and the Overview figures to confirm the run. ### "… is not authenticated with GSTN. Request an OTP and complete authentication first." The filer GSTIN has no GSTN session, or the session has expired ("The GSTN session for … has expired"). Run **Request GSTN OTP** and **Submit OTP** on its GST Registration, then try again. If the message is "No GST registration found for …", the GSTIN on the return has no GST Registration record. ### "This return has no computed rows to push." Process GSTR3B has not been run, or produced nothing. Process the return first. For a genuine nil month, file on the portal and use **Record Manual Filing**; the Is Nil Return switch does not change what Save to GSTN sends. ### "A push is already in progress for this return." A save, file or status check was started less than 5 minutes ago. Wait. If Save Status is still SaveRequested, StatusRequested or FileRequested after 5 minutes, the integration flow did not run or did not write back. Your administrator should check the flow's trigger and run history. You can then click again. ### "GSTN will not file a return it has not committed." Submit File to GSTN needs Save Status **Accepted**. Run **Save to GSTN**, then **Check Save Status** until it reports Accepted. ### "There is no queued save to check" Check Save Status works only when Save Status is Submitted. Save the return first. If the message says GSTN issued no reference id, read GSTN Response for the reason and save again. ### Save Status is RejectedByGstn GSTN Response starts with "GSTN processed the return with errors." or "GSTN refused the return." and lists each rejected box. Correct the source, click **Process GSTR3B**, then **Save to GSTN** again. ### GSTN Response says the status answer could not be read The gateway refused the status call. The usual causes are an expired session, or a return-status flow running with different partner credentials from the save flow. Re-authenticate and click **Check Save Status** again. If it persists, ask your administrator to check the flows. ### Status went back from Saved to Computed The scheduled processing job reprocessed the return; it does this to every unfiled return. If the figures changed, run **Save to GSTN** and **Check Save Status** again before you file, so GSTN holds what you file. ### Make Challan does nothing xMatix does not generate GST payment challans. Create the challan and pay on the government portal. ## Common questions ### Do I have to file GSTR-1 before processing GSTR-3B? No, but it is the safer order. Process GSTR3B prefers a Filed GSTR-1 for the same GSTIN and month and falls back to a Draft one only when none is Filed. Because a Draft can still change, figures computed from it can move. The scheduled job is stricter about readiness but not about filing: it waits until the month's GSTR-1 and GSTR-2B have both been processed, then computes whether or not GSTR-1 is Filed. Reprocess the GSTR-3B whenever the GSTR-1 changes, and always before you save it to GSTN. ### What is the difference between Submit File to GSTN and Record Manual Filing? Submit File to GSTN files the return through your GSP integration. It is available only after GSTN has accepted the save, and it writes back GSTN's acknowledgement itself. Record Manual Filing transmits nothing: it records a filing you already completed on the government portal, using the acknowledgement number you type in. Both end the same way, with Status Filed, Is Filed set, Filed On and Ack Number. Use one route per return; Record Manual Filing is refused while a GSP filing is in progress. ### Does xMatix pay my GST or offset my credit? No. Table 6.1 shows the gross tax payable per head, derived from table 3.1, and has fields for amounts paid in cash and through each credit ledger. However, xMatix does not hold your electronic cash and credit ledger balances, so it neither calculates the offset nor sends table 6.1 to GSTN. Pay tax, create challans and offset credit on the government portal. Record the amounts on the 6.1 rows if you want them on file, because GSTR-9 reads those rows for its tax-paid table. ### Can I un-file a GSTR-3B? No. Filed is one-way in xMatix, as it is at GSTN. Processing, saving and filing are all refused on a Filed return, and nothing in the product moves it back to an earlier status. If you find an error after filing, correct the source documents and report the adjustment in a later period's return. Before using Record Manual Filing, check the acknowledgement number against the portal, because a wrong entry cannot be undone from the screen. ### Why does 4A line (3) show my ISD credit when the form says reverse charge? xMatix numbers the 4A lines with ISD credit on line (3) and reverse-charge credit on line (4). The government form has them the other way round. The Overview labels follow the xMatix order, but Save to GSTN sends lines by position. If you have both kinds of credit in a month, compare the two lines on the portal after the save and before filing. Alternatively, enter 4A on the portal and use Record Manual Filing. ## Related topics - [GSTR-1 — outward supplies](/docs/finance/tax-center/gstr-1/) - [GSTR-2B — inward supplies and ITC](/docs/finance/tax-center/gstr-2b/) - [Input tax credit management](/docs/finance/tax-center/itc-management/) - [Annual returns](/docs/finance/tax-center/annual-returns/) - [The GST console](/docs/finance/tax-center/gst-console/) - [Tax Center troubleshooting](/docs/finance/tax-center/troubleshooting/) - [GSTR 3B entity reference](/docs/reference/entities/gstr3-b/) - [Security profiles](/docs/administration/security-profiles/) ---- # GSTR-6: distributing and filing Input Service Distributor credit URL: https://xmatix.com/docs/finance/tax-center/gstr-6/ Last reviewed: 2026-10-09 GSTR-6 is the monthly return of an **Input Service Distributor (ISD)**: the registration that receives tax invoices for services shared across your business, such as audit, advertising or head-office software, and passes the input tax credit (ITC) on to your other registrations under the same PAN. In xMatix, a **GSTR 6** record is created for each ISD registration every month. You run three steps on it — **Process GSTR6** reads the credit you received from your tax ledger, **Distribute ISD Credit** splits it between your registrations, and **Calculate ITC** checks that everything received was distributed. You then either file through your GSP integration or file on the government portal yourself and use **Record Manual Filing**. An ISD registration files GSTR-6 instead of GSTR-1, GSTR-2B and GSTR-3B, and does not file the annual GSTR-9. ## Overview Each GSTR 6 record covers one ISD GSTIN and one monthly return period. The standard record page has five tabs: - **ISD Source Document** — the credit received in the month (form tables 3 and 6): one row per inward invoice or note, with its eligible and ineligible tax. - **ISD Distribution** — one ISD invoice or ISD credit note per received document and credit pool, with its serial number and the form table it reports under (8 for eligible credit, 9 for ineligible credit). - **ISD Recipient Allocation** — how each distribution was split between your registrations: the ratio, the tax as received and the tax as passed on. - **Detail** — the header fields: Name, ISD Account, ARN, Status, Total Documents, Total ITC Distributed, Total ITC Received, Filed At and Period. - **Reconciliation** — the return summary by form table, and your books compared with the auto-drafted GSTR-6A on the portal. The page header shows the record's Name, Period, Total ITC Received and Total ITC Distributed, and carries the buttons **Record Manual Filing**, **Process GSTR6**, **Distribute ISD Credit** and **Calculate ITC**. ## When to use it Use GSTR-6 every month for each GST Registration that has **Enable ISD** switched on. A registration without it files GSTR-1, GSTR-2B and GSTR-3B instead (see [GSTR-3B](/docs/finance/tax-center/gstr-3b/)). Work on a month's GSTR-6 once the month's purchase bills for the ISD GSTIN are posted, so their input tax is in the ledger, and once the recipient turnover figures for the period are on file. ## How xMatix handles it **Records are created for you.** The **Provision GST returns** scheduled job, or the **Provision GST Returns** action on a GST Registration or a GST fiscal period, creates one Draft GSTR-6 per active ISD registration per month. It is named after the GSTIN and period and labelled, for example, "GSTR-6 Aug 2026". Running provisioning again never creates a duplicate. See [The GST console](/docs/finance/tax-center/gst-console/). **Three steps, in order.** Each step moves the record's Status forward: | Step | What it does | Status afterwards | | --- | --- | --- | | Process GSTR6 | Reads the month's input tax lines for the ISD GSTIN from your tax ledger and rebuilds the ISD Source Document rows. Each document's tax is split into an eligible pool and an ineligible pool. Fills Total Documents and Total ITC Received | Processed | | Distribute ISD Credit | Splits every pool between your recipient registrations and rebuilds the ISD Distribution and ISD Recipient Allocation rows. Fills Total ITC Distributed | Distributed | | Calculate ITC | Checks that the ITC received equals the ITC distributed (form table 4) and that every distribution reached its recipients in full. Stamps Computed At | Computed, when balanced | **Rebuilding is safe and repeatable.** Process GSTR6 and Distribute ISD Credit replace only the rows they built last time; rows imported from the portal are never touched. Running either step again takes the return back to Processed or Distributed and clears Computed At, so run **Calculate ITC** again afterwards. **How the credit is split (Rule 39).** - **Who receives it.** The recipients are the **ISD Recipient Turnover** records that are **Is Operational**, carry a Recipient GSTIN with the same PAN as the ISD (a record without a GSTIN is also included), and are effective in the return month by their **Effective From** and **Effective To** dates (a blank date is open). When one GSTIN has several such records, only the one with the latest Effective From, then the latest Financial Year, counts. - **Pro-rata.** Each pool is split in proportion to each recipient's **Turnover**. If no recipient has a turnover on file, the pool is split equally. - **Attributed.** If a received document names an **Attributed Recipient**, its whole credit goes to that recipient. The recipient must be an operational recipient for the period, matched by its Account. - **Tax heads.** IGST stays IGST. A recipient in the same state as the ISD receives CGST as CGST and SGST as SGST. A recipient in another state, or one marked **Is SEZ**, receives CGST and SGST as IGST. Each allocation keeps both the amounts as received and the amounts as distributed. - **Eligible and ineligible credit stay apart.** Credit you blocked in the ledger is distributed as ineligible (form table 9), so the recipient cannot claim it. Eligible credit is distributed under table 8. **ISD document serials (Rule 54).** Every ISD invoice and ISD credit note gets a serial of at most 16 characters. If an active **ISD Document Series** exists for the financial year and document type, the serial is its **Prefix** followed by the next number, and the series' **Last Serial Number** and **Next Serial Number** move on. Without one, xMatix numbers the run ISDIN1, ISDIN2… for invoices and ISDCN1… for credit notes, starting from 1 on every run. **Filing through the GSP is a staged exchange.** The GSTN save and submit are asynchronous. **Save to GSTN** queues the return, **Check Save Status** fetches GSTN's verdict, **Submit to GSTN** freezes the saved return at GSTN, and **Submit File to GSTN** files it. None of these buttons talks to GSTN directly. Each one prepares the request on the return, and your tenant's GSP integration flows send it and write the answer back. ## Prerequisites - The GST Registration for the ISD GSTIN is active, has a GSTIN and has **Enable ISD** switched on, and the month's GSTR-6 has been provisioned. - The month's purchase bills for the ISD GSTIN are posted, with the right ITC eligibility on each tax line. - **ISD Recipient Turnover** records exist for every registration that should receive credit: same PAN as the ISD, **Is Operational** on, a **Turnover**, and effective dates covering the month. - Optionally, an active **ISD Document Series** for the financial year for ISD invoices and one for ISD credit notes, so serials continue across months. - **To file through the GSP:** your administrator has configured the GSTR-6 integration flows and placed the GSP buttons on the form (see [Configuration](#configuration)), you have the GSP action permissions, and the ISD GSTIN's GST Registration has a live GSTN session. ## Procedure ### Step 1 — Open the return Open the month's GSTR-6 from the [GST console](/docs/finance/tax-center/gst-console/) filing card, or from the **All GSTR 6** list. On **Detail**, check the Name, Period and Status. A newly provisioned return is **Draft**. ### Step 2 — Process the received credit Click **Process GSTR6**. The **ISD Source Document** tab now lists one row per inward document for the month, with its supplier GSTIN, document number, taxable value, tax and the eligible and ineligible split. Status becomes **Processed**, and **Total Documents** and **Total ITC Received** are filled. If your administrator scheduled the **Process GSTR-6 data** job, this step may already have run overnight. ### Step 3 — Attribute documents to a single recipient (optional) If a received document relates to one registration only, open it on the **ISD Source Document** tab and set its **Attributed Recipient** to that registration's account. Its whole credit then goes to that recipient. Do this after Process GSTR6, because processing again rebuilds the documents and clears the attribution. ### Step 4 — Distribute the credit Click **Distribute ISD Credit**. The **ISD Distribution** tab lists one ISD invoice or ISD credit note per document and pool, and **ISD Recipient Allocation** shows each recipient's share. Status becomes **Distributed** and **Total ITC Distributed** is filled. If any pool has no recipient to go to, the whole run is refused and the previous distribution is left as it was (see [Common problems](#common-problems)). ### Step 5 — Calculate ITC Click **Calculate ITC**. When the ITC received and distributed agree within ₹1, and every distribution has been allocated in full, Status becomes **Computed** and **Computed At** is stamped. If they do not agree, Status stays **Distributed** (a return that was Computed goes back to Distributed) and the return cannot be saved or recorded as filed. ### Step 6 — Review and reconcile Open the **Reconciliation** tab. The summary shows table 3 (eligible and ineligible ITC received), table 6 (amendments, when there are any) and tables 8 and 9 (distribution), with integrated, central, state/UT tax and cess for each line. Click a line to see the records behind it. To compare with the suppliers' filings, click **Pull From GSTIN** to fetch the auto-drafted GSTR-6A, then click it again once the fetch has finished to import it. The reconciliation then pairs your documents with the portal's by supplier GSTIN and document number and shows each as Matched, Partial, MissingInBooks or MissingInGstin. Amounts within ₹1 count as matching. A missing document usually means the supplier has not reported it yet, or it is not posted in your books. ### Step 7 — File through the GSP: save, check, submit, file 1. Make sure the ISD GSTIN has a live session: on its **GST Registration**, click **Request GSTN OTP**, then **Submit OTP** with the code you receive, and wait for **Auth Status** to show Authenticated. A session is treated as expired 6 hours after authentication. 2. On the GSTR-6, click **Save to GSTN**. The received invoices and notes and the distribution to each recipient are queued for GSTN. Save Status becomes SaveRequested, then **Submitted** once the gateway issues a GSP Reference Id. 3. Click **Check Save Status** and reopen the return a few seconds later. Save Status becomes **Accepted**, or **RejectedByGstn** with the reasons in GSTN Response. If it is back at Submitted, GSTN is still processing; click again. 4. When Save Status is **Accepted**, click **Submit to GSTN**. This freezes the return at GSTN. Save Status becomes FreezeQueued. Click **Check Save Status** again until it shows **Frozen**. 5. Click **Submit File to GSTN**. The first click fetches GSTN's summary of the return. Click it again once the summary has arrived (Save Status SummaryFetched) to file. When GSTN answers, the ARN is filled, Status becomes **Filed**, Is Filed is set and Filed At is stamped. Once the return is frozen at GSTN, the three processing steps are refused, so make every correction before step 4. ### Step 8 — Or record a filing you made on the portal If you filed GSTR-6 directly on the government portal, click **Record Manual Filing** on a **Computed** return. Enter the **ARN (from the GSTN portal)** (required, at most 120 characters) and **Filed On** (defaults to now if left empty). The return becomes **Filed**. This button sends nothing to GSTN; it only records the outcome. ### Step 9 — After filing A Filed return is a frozen statutory snapshot. Process GSTR6, Distribute ISD Credit and Calculate ITC are refused on it, it cannot be saved or filed again, and the scheduled job skips it. Corrections go through a later period's return. ## Fields | Field | What it means | Notes | | --- | --- | --- | | Name | The record's name, for example "GSTR6-29AAAAA0000A2Z4-082026" | Set by provisioning; required | | ISD Account | The account that represents the ISD | Optional; not used by the calculation | | ARN | The acknowledgement reference GSTN issued for the filing | At most 120 characters. Written by Submit File to GSTN, or entered in Record Manual Filing | | Status | Where the return is in its lifecycle | Written by the actions: Draft → Processed → Distributed → Computed → Filed. The dropdown on the form offers only Draft, Submitted and Filed; do not set Status by hand | | Total Documents | Number of received documents found by Process GSTR6 | Read-only in practice | | Total ITC Distributed | Total credit passed on to recipients | Filled by Distribute ISD Credit and Calculate ITC | | Total ITC Received | Total tax on the received documents | Filled by Process GSTR6 and Calculate ITC | | Filed At | When the return was filed | Stamped by either filing route | | Period | A date in the return month | Used to find the month only when the return has no GST fiscal period linked | | GSTIN | The ISD's GST identification number | Set by provisioning. Must be a well-formed 15-character GSTIN. Not on the standard form | | GST Fiscal Period | The monthly GST fiscal period the return covers | Set by provisioning; decides which ledger lines are read. Not on the standard form | | GST Registration | The ISD's GST Registration | Its GSTN session is used by the GSP actions | | Computed At | When Calculate ITC last ran | Cleared when the return is processed or distributed again | | Is Filed | Yes once the return is filed by either route | Set together with Status Filed | | Late Fee Payable | Late fee for the return (form table 10) | Filled from the portal by Pull From GSTIN | | Late Fee Paid | Late fee paid (form table 10) | Not on the standard form | | Refund Claimed | Refund claimed from the electronic cash ledger (form table 11) | Not on the standard form | | Save Status | Where the GSTN exchange is | See the table below. Never edit it by hand | | GSP Reference Id | The reference GSTN issued for the latest save or submit | Not a receipt — only Check Save Status tells you whether GSTN accepted it | | GSTN Response | GSTN's or the gateway's last message, including the list of rejected documents | | | Pull Status | Where the GSTR-6A pull is | PullRequested, Fetched, FetchFailed or Imported | **Save Status values** | Value | Meaning | What to do | | --- | --- | --- | | (empty) | Never sent to GSTN, or the books were rebuilt after the last save | Save to GSTN | | SaveRequested | Save to GSTN was clicked; the save flow is running | Wait; after 5 minutes you may click again | | Submitted | GSTN queued the save | Click Check Save Status | | SubmitFailed | The gateway refused the save | Read GSTN Response, fix, save again | | StatusRequested | Check Save Status is fetching GSTN's verdict | Reopen the return in a few seconds | | Accepted | GSTN committed the saved return | Submit to GSTN | | RejectedByGstn | GSTN processed the return with errors, or refused it | Read GSTN Response, fix the source, rebuild, save again | | FreezeRequested, FreezeQueued | Submit to GSTN was clicked; GSTN is freezing the return | Click Check Save Status | | Frozen | GSTN has frozen the return | Submit File to GSTN | | SummaryRequested, SummaryFetched | The filing summary is being fetched, or has arrived | Click Submit File to GSTN again once it has arrived | | FileRequested | The file flow is running | Wait for the ARN | | Filed | GSTN filed the return and issued an ARN | Nothing — the return is final | | FileFailed | GSTN refused the file call | Read GSTN Response; click Submit File to GSTN again | The full field list is in the [GSTR 6 entity reference](/docs/reference/entities/gstr6/). ## Business rules - **GSTIN check.** Saving a GSTR-6 with a malformed GSTIN is refused: "'…' is not a valid 15-character GSTIN." - **Processing reads the ledger by document date.** Process GSTR6 reads input tax lines whose own GSTIN is the ISD GSTIN and whose document date falls in the return month. The month comes from the linked GST fiscal period, or from Period when none is linked. Lines are grouped into one received document per source document. - **Eligible or ineligible.** A tax line counts as eligible only when its ITC eligibility is Eligible; every other line goes to the ineligible pool, with the first blocked reason found. - **Recipient coverage comes first.** Distribute ISD Credit checks that every pool has a recipient before it changes anything. If one does not, nothing is rebuilt. - **Table 4 equality.** Calculate ITC sets Computed only when ITC received and distributed differ by at most ₹1 and every distribution reconciles to its allocations (allowing ₹0.02 per allocation for rounding). - **Saving needs Computed.** Save to GSTN is refused unless Status is Computed, when the return has nothing to send, when the GSTIN has no GST Registration or no live GSTN session, and while a save, submit, summary or status check started less than 5 minutes ago. Amendment rows (tables 6A, 6B, 6C) are not sent. - **Submitting needs Accepted.** Submit to GSTN is refused unless Save Status is Accepted. - **Filing needs Frozen.** Submit File to GSTN is refused unless the return is Frozen at GSTN (or its summary is being fetched, or a previous file attempt failed). It is never repeated automatically while a filing is in progress. - **Rebuilding voids a save.** Processing or distributing again after a save that is Submitted, Accepted, RejectedByGstn or SubmitFailed clears Save Status and GSP Reference Id; GSTN Response reads "The books were rebuilt after the last save to GSTN; save the return again." - **Frozen means frozen.** From Submit to GSTN onwards, the three processing steps are refused and the scheduled job skips the return. - **Record Manual Filing** is refused when the return is already Filed, has no valid GSTIN, is not Computed, has no ARN or one longer than 120 characters, or while a GSP filing is in progress (Save Status FileRequested). - **Filed is one-way.** Nothing in the product turns a Filed return back to an earlier status. - **Pulling the GSTR-6A.** The first click on Pull From GSTIN requests the portal's invoices, notes, ITC and late fee for the period; the second imports them. Invoices and notes become portal-side source documents, replacing only the earlier portal rows of the same section. The late-fee section sets Late Fee Payable. A section the portal refused is not imported and its earlier rows are left alone. Amended sections are not pulled. Authenticating an ISD registration also requests the pull for its open-period return. ## Example A company has a head office ISD registration, GSTIN 29AAAAA0000A2Z4, and two operating registrations under the same PAN: 29AAAAA0000A1Z5 in the same state and 27AAAAA0000A1Z3 in another state. Their ISD Recipient Turnover records show turnovers of ₹60,00,000 and ₹40,00,000, both operational and effective for the year. An ISD Document Series for 2026-27 ISD invoices has the prefix "ISD/26-27/" and Next Serial Number 14. 1. In August 2026 the head office posts an audit firm's bill with CGST ₹9,000 and SGST ₹9,000, all eligible. 2. On "GSTR-6 Aug 2026" the accountant clicks **Process GSTR6**. One ISD source document appears; Total ITC Received is ₹18,000 and Status is Processed. 3. They click **Distribute ISD Credit**. One ISD invoice, ISD/26-27/14, reports under table 8. The allocations are: - 29AAAAA0000A1Z5, ratio 0.6: CGST ₹5,400 and SGST ₹5,400, kept as received because it is in the same state. - 27AAAAA0000A1Z3, ratio 0.4: received as CGST ₹3,600 and SGST ₹3,600, distributed as IGST ₹7,200 because it is in another state. 4. They click **Calculate ITC**. Received and distributed are both ₹18,000, so Status is Computed. 5. They pull the GSTR-6A and see the audit bill as Matched on the Reconciliation tab. 6. The finance manager authenticates the ISD GSTIN, saves, checks until Accepted, submits, checks until Frozen, and clicks Submit File to GSTN twice. The ARN appears and Status is Filed. ## Training ### Practice exercise In a sandbox tenant: 1. Switch on **Enable ISD** on a GST Registration and run **Provision GST Returns** on it. 2. Create two **ISD Recipient Turnover** records with GSTINs under the same PAN, **Is Operational** on and turnovers of 3,00,000 and 1,00,000. 3. Post a purchase bill for the ISD GSTIN in the current month with ₹1,000 of eligible IGST. 4. On the month's GSTR-6, click **Process GSTR6**, **Distribute ISD Credit** and **Calculate ITC**. 5. Switch **Is Operational** off on both turnover records and click **Distribute ISD Credit** again. **Expected result:** - After step 4, the allocations are IGST ₹750 and ₹250, and Status is Computed. - In step 5, the run is refused because no operational recipient is effective for the period, and the earlier allocations are still there. ### Quick reference - GSTR-6 records are created by provisioning for registrations with Enable ISD. - Always run Process GSTR6 → Distribute ISD Credit → Calculate ITC, in that order. - Recipients come from ISD Recipient Turnover: operational, same PAN, effective in the month. - Cross-state and SEZ recipients receive CGST and SGST as IGST. - Set an Attributed Recipient after processing, not before. - Only a Computed return can be saved to GSTN or recorded as filed. - Save → Check Save Status → Submit → Check Save Status → Submit File to GSTN (twice). - Once frozen at GSTN, the books can no longer be rebuilt for that month. - Record Manual Filing is only for a return you filed on the portal yourself. ## Permissions Each button is a server action that a [security profile](/docs/administration/security-profiles/) must grant. In the standard profiles: | Action | System Admin | Standard User | | --- | --- | --- | | Process GSTR6 | Yes | Yes | | Distribute ISD Credit | Yes | Yes | | Calculate ITC | Yes | Yes | | Get from GSTR6 and Reconcile GSTR6 (the Reconciliation tab) | Yes | Yes | | Record Manual Filing | Yes | Yes | | Save to GSTN | Yes | No | | Check Save Status | Yes | No | | Submit to GSTN | Yes | No | | Submit File to GSTN | Yes | No | | Pull From GSTIN | Yes | No | A user whose profile lacks an action does not get that action. Because the GSP actions transmit a real return to GSTN, grant them deliberately, and only to the finance profile that files returns. Reading the record also depends on the profile's access to the GSTR 6 entity; see [Why can't a user see a record?](/docs/administration/user-cant-see-x/). ## Configuration - **GST registrations.** - Switch on **Enable ISD** on the GST Registration of each ISD GSTIN. It then gets a monthly GSTR-6 instead of GSTR-1, GSTR-2B and GSTR-3B, and no GSTR-9. - **Provision GST Returns** on the registration creates the current month's return on demand; on a GST fiscal period it creates that month's returns. - **Request GSTN OTP** and **Submit OTP** establish the GSTN session that the GSP actions need. A session lasts about 6 hours. - **ISD Recipient Turnover.** One record per recipient registration and period: Recipient GSTIN, Account, State Code, Turnover, Financial Year, Quarter, Effective From, Effective To, Is Operational, Is Registered and Is SEZ. When a new year's turnover takes over, give the old record an **Effective To**, or both may be considered and only the latest counts. **Is SEZ** makes the recipient receive IGST. - **ISD Document Series.** One active record per financial year and Series Type (ISDInvoice or ISDCreditNote), with a Prefix and the Last and Next Serial Number. Keep the prefix short: prefix and number together are cut to 16 characters. - **Scheduled jobs** (**Setup → Administration → Jobs**): - **Provision GST returns** creates the Draft returns for the current month in India time. - **Process GSTR-6 data** runs Process GSTR6 on unfiled returns in Open periods, or for a month or GSTIN you name. It does not distribute or calculate. It skips Filed returns and returns frozen at GSTN, makes up to 3 attempts and runs one at a time per tenant. - Both run only when a schedule is set for them. Because a nightly reprocess takes a return back to Processed and voids an unsubmitted save, run Distribute ISD Credit and Calculate ITC again before saving. - **GSP integration** (**Setup → Process Studio → Integrations**). Filing through the GSP needs, in one integration app, a connection to your GSP gateway and its secrets, and six flows with an entity-event trigger on **GSTR 6** updates: - the save flow, for Save Status SaveRequested; - the submit flow, for FreezeRequested; - the return-status flow, for StatusRequested; - the summary flow, for SummaryRequested; - the file flow, for FileRequested; - the pull flow, for Pull Status PullRequested. The return-status flow must use the same GSP partner credentials as the save flow, because only the partner that received a reference can redeem it. Without the flows the buttons still respond, but nothing reaches GSTN and Save Status stays at the requested value. See [Outbound integrations](/docs/integrations/outbound/). - **The form.** The standard page header shows Record Manual Filing, Process GSTR6, Distribute ISD Credit and Calculate ITC. If your filers use the GSP, add **Save to GSTN**, **Check Save Status**, **Submit to GSTN**, **Submit File to GSTN** and **Pull From GSTIN** to the header, and **Save Status**, **GSTN Response** and **Pull Status** to the **Detail** tab, in the form designer. - **Security profiles.** Grant the GSP actions on GSTR 6 to the profile that files returns (see [Permissions](#permissions)). - **Mobile.** The GSTR 6 record has a mobile layout showing the header fields. Whether it is reachable in the field app depends on your mobile app configuration. ## Common problems ### "… ITC pool(s) have no recipient to distribute to" Distribute ISD Credit found a pool with nothing to land on. If the message says "no operational ISD recipient under this ISD's PAN is effective for the period", check the ISD Recipient Turnover records: **Is Operational** on, a Recipient GSTIN with the ISD's PAN (characters 3 to 12), and Effective From and Effective To covering the month. If it says "its attributed recipient is not an operational ISD recipient", the document's Attributed Recipient has no operational turnover record for its account. ### The split between recipients looks wrong An older turnover record for the same GSTIN may still be open. Only the latest record per GSTIN counts, but check that the right one is effective and give the old one an **Effective To**. Also check **Is SEZ** and the state in each Recipient GSTIN, which decide whether CGST and SGST become IGST. ### Calculate ITC does not reach Computed The ITC received and distributed differ by more than ₹1, or a distribution was not fully allocated. Run **Distribute ISD Credit** again and then **Calculate ITC**. If you processed again after distributing, the distribution no longer matches the documents. ### "… is Filed and cannot be re-processed; create an amendment instead of regenerating the filed period." The return is Filed and frozen. Corrections go through a later period's return. ### "… has no GSTIN; set the filer GSTIN before processing." or "… has no return period" The record is missing its GSTIN or its period. Provisioned returns always have both; a record created with **New** or cloned may not, because the standard form has no GSTIN field. Work on the provisioned return for that GSTIN and month. ### "… is not authenticated with GSTN. Request an OTP on its GST registration and complete authentication first." The ISD GSTIN has no GSTN session, or it has expired ("The GSTN session for … has expired"). Run **Request GSTN OTP** and **Submit OTP** on its GST Registration, then try again. "No GST registration found for …" means the GSTIN on the return has no GST Registration record. ### "This return is '…'. Run Process GSTR6 Data, Distribute ISD Credit and Calculate ITC until it reaches Computed, then save it to GSTN." Save to GSTN needs Status Computed. Run the three steps until Calculate ITC sets it. ### "A push is already in progress for this return." A save, submit, summary or status check started less than 5 minutes ago. Wait. If Save Status is still at a requested value after 5 minutes, the integration flow did not run or did not write back. Your administrator should check the flow's trigger and run history. You can then click again. ### "GSTN will only freeze a return it has committed." Submit to GSTN needs Save Status **Accepted**. Click **Check Save Status** until it reports Accepted. ### "Only a return frozen at GSTN can be filed." Submit File to GSTN needs the return Frozen. Submit it and check the status until it shows Frozen. ### "… has been submitted to GSTN … and is frozen there; its books can no longer be rebuilt" Expected after Submit to GSTN. File the return, and carry corrections into a later period. ### "A filing is already in progress for this return." A file request has already been sent. Check the return's status on the government portal before doing anything else, because a second request could file it twice. ### Save Status went blank and GSTN Response says the books were rebuilt Someone, or the scheduled job, processed or distributed the return after it was saved, which voids the save. Run the steps to Computed and save again. ### Pull From GSTIN imported nothing The message "The portal response is an error, not data" means GSTN refused that section; the earlier portal rows were kept. Check the session and try again later. ## Common questions ### Who can receive ISD credit? Only registrations under the same PAN as the ISD. xMatix enforces this by comparing the PAN inside each Recipient GSTIN with the ISD's GSTIN, and ignores operational turnover records under another PAN. A recipient record without a GSTIN cannot be checked this way and is included. The recipient must also be operational and effective in the return month. Keep the ISD Recipient Turnover records accurate, because they decide both who receives credit and in what proportion, and the same records are shared by every ISD in your tenant. ### What is the difference between Submit File to GSTN and Record Manual Filing? Submit File to GSTN files the return through your GSP integration. It is available only after GSTN has frozen the return, and it writes back the ARN itself. Record Manual Filing transmits nothing: it records a filing you already completed on the government portal, using the ARN you type in. Both end the same way, with Status Filed, Is Filed set, Filed At and ARN. Use one route per return; Record Manual Filing is refused while a GSP filing is in progress. ### Why did my Status go back from Computed to Processed? Processing or distributing again rebuilds the return's rows, so the earlier check no longer applies. Status goes back to Processed or Distributed and Computed At is cleared. The scheduled Process GSTR-6 data job does this to every unfiled, unfrozen return in an Open period. Run Distribute ISD Credit and Calculate ITC again. If you had already saved the return to GSTN, save it again too, so GSTN holds what you will file. ### Does ISD credit reach the recipients' GSTR-3B automatically? Not from this return. GSTR-6 records what the ISD distributed. Each recipient sees the credit through its own GSTR-2B statement from the portal, which xMatix loads into the recipient's [GSTR-2B](/docs/finance/tax-center/gstr-2b/); from there it feeds the recipient's GSTR-3B. ### Can I un-file a GSTR-6? No. Filed is one-way in xMatix, as it is at GSTN. Processing, distributing, calculating, saving and filing are all refused on a Filed return, and nothing in the product moves it back. If you find an error after filing, correct it in a later period's return. Before using Record Manual Filing, check the ARN against the portal, because a wrong entry cannot be undone from the screen. ## Related topics - [The Tax Center](/docs/finance/tax-center/) - [The GST console](/docs/finance/tax-center/gst-console/) - [GSTR-2B — inward supplies and ITC](/docs/finance/tax-center/gstr-2b/) - [GSTR-3B — the summary return](/docs/finance/tax-center/gstr-3b/) - [Input tax credit management](/docs/finance/tax-center/itc-management/) - [Tax Center troubleshooting](/docs/finance/tax-center/troubleshooting/) - [GSTR 6 entity reference](/docs/reference/entities/gstr6/) - [Security profiles](/docs/administration/security-profiles/) ---- # The Tax Center URL: https://xmatix.com/docs/finance/tax-center/ Last reviewed: 2026-10-09 The **Tax Center** brings the India-compliance records and actions in xMatix Finance into one area. Posted sales and purchase documents supply the underlying tax transactions; return processors then build the supported GST tables for a registration and period. Review the generated figures against their source records and portal data before treating any return as ready to file. ## Start with the GST Console The first-party **TaxCenterWidget** is the intended operational starting point for GST returns when a tenant has an AppPage that embeds it. Choose an active GST registration and a financial year, select a monthly or annual period, and use the filing cards to open the matching return record. The widget summarizes records already held in xMatix; it does not itself submit a return to a government portal. For a regular registration, a monthly row presents GSTR-1, GSTR-2B and GSTR-3B. An Input Service Distributor (ISD) registration presents GSTR-6 for a month. The annual row presents GSTR-9. AppPage availability is tenant configuration: if no Tax Center route has been provisioned, use the return entity lists and actions directly. See [The GST console](/docs/finance/tax-center/gst-console/) for the precise selection, status and provisioning behavior. ## What is implemented | Area | Current product behavior | | --- | --- | | GSTR-1 | Processes books-side outward supplies, compares books and portal-side rows, records carry-forward or ignore decisions, and records a Filed state and filing date | | GSTR-2B | Processes books-side inward supplies and compares them with portal-side statement rows; imported IMS status can affect GSTR-3B, but xMatix does not currently expose a supported Accept/Reject decision action | | GSTR-3B | Computes supported tables from the selected GSTR-1, GSTR-2B and tax-ledger sources, preserves manual rows, and either files through a configured GSP integration (save, status check, file) or records a filing made on the portal | | GSTR-6 | For an Input Service Distributor registration: builds the credit received from the tax ledger, distributes it to your registrations under the same PAN, checks that everything received was distributed, reconciles against the portal's GSTR-6A, and either files through a configured GSP integration or records a filing made on the portal | | GSTR-9 | Rolls up the annual tables from the year's filed monthly returns, GSTR-2B and ledger, takes your entries and overrides with a reason, runs a pre-file checklist, and either files through a configured GSTN integration or records a filing made on the portal | | E-invoicing | Stages an e-invoice payload from an **Invoice** and stores status, IRN, acknowledgment and signed response fields back on that Invoice; external submission requires an explicitly configured integration flow | | E-way bills | Creates a Draft **EWayBill** from an **Invoice**; an external flow must submit it and write generated details back before it is authority to move goods | | TDS/TCS | Provides withholding transactions, challan preparation/posting/CSI verification/correction actions, quarterly-return processing and related certificate records | | Form 26AS | Provides statement, line and reconciliation entities plus a server reconciliation engine; attaching a statement file does not parse it into lines automatically | These distinctions matter when reading a record screen. A saved header, Draft row or staged payload proves only that xMatix has prepared or stored data. It does not prove that a portal accepted a filing or generated an external number. ## A reliable review sequence 1. Confirm the legal registration, PAN/TAN where applicable, and statutory period. 2. Confirm the source invoices, bills, credit notes, payments or withholding rows are posted and belong to that scope. 3. Run the supported processor or compute action and reconcile its result to source control totals. 4. Load portal-side data through an explicit import or integration where the workflow requires it, then investigate every difference. 5. Complete manual rows and retain the external evidence required by your filing process. 6. Record filing state only after the external filing has actually occurred. Do not repair an unexpected return total by silently changing a derived row. Correct the source transaction or use the documented manual or override mechanism for that return, then recompute and retain an explanation. ## What is in this section - [The GST console](/docs/finance/tax-center/gst-console/) — registrations, stored fiscal years, monthly and annual filing cards, and provisioning. - [GSTR-1 — outward supplies](/docs/finance/tax-center/gstr-1/) — books processing, reconciliation decisions and the Filed marker. - [GSTR-2B — inward supplies and ITC](/docs/finance/tax-center/gstr-2b/) — pulling the statement from GSTN, building the books side, and reconciling the two. - [GSTR-3B — the summary return](/docs/finance/tax-center/gstr-3b/) — which sources Process GSTR3B selects, which rows remain manual, and how to save, file or record the filing. - [GSTR-6 — Input Service Distributor return](/docs/finance/tax-center/gstr-6/) — receiving, distributing and filing ISD credit, and the recipient and serial-number setup it needs. - [Input tax credit management](/docs/finance/tax-center/itc-management/) — what currently feeds ITC figures and which service-only capabilities are not exposed as a runtime workflow. - [Annual returns](/docs/finance/tax-center/annual-returns/) — preparing GSTR-9 from the filed months, entering and overriding rows, the pre-file checklist, and filing through GSTN or on the portal. - [E-invoicing](/docs/finance/tax-center/e-invoicing/) — Invoice staging, integration hand-off and Invoice-field writeback. - [E-way bills](/docs/finance/tax-center/e-way-bills/) — Invoice-only Draft creation and integration-dependent generation. - [TDS & TCS](/docs/finance/tax-center/tds-tcs/) — withholding, challans, returns and certificates. - [TDS returns](/docs/finance/tax-center/tds-returns/) — computing, validating, exporting and filing the quarterly TDS, TCS and salary statements. - [TDS reconciliation](/docs/finance/tax-center/tds-reconciliation/) — the Form 26AS engine, its import limitation, and the deductor-side comparison. - [Troubleshooting](/docs/finance/tax-center/troubleshooting/) — source-grounded checks for missing or unexpected values. Screens and actions remain permission-gated. If an implemented page or action is absent, first confirm the user's [security profile](/docs/administration/security-profiles/) and that the relevant metadata action has been configured for the tenant. ## A note on statutory content Rates, thresholds, due dates and portal rules change. This documentation describes the behavior implemented in the reviewed source; it is not tax advice and must not be used as the authority for a current statutory figure or deadline. Confirm current requirements with the government portal and your tax advisor. ## Related topics - [xMatix for India GST compliance](/solutions/india-compliance/) - [xMatix Finance & Accounting](/products/finance/) - [Closing a period](/docs/finance/period-close/) ---- # Input tax credit management URL: https://xmatix.com/docs/finance/tax-center/itc-management/ Last reviewed: 2026-09-02 Input tax credit in the current product is visible through posted purchase tax transactions, GSTR-2B data and the ITC tables computed on GSTR-3B. xMatix also contains lower-level services for a separate ITC-ledger lifecycle, Rule 42 calculation, supplier reconciliation and statutory time-limit checks, but those services do not currently have a runtime action, page or scheduled caller. This page separates the workflow you can use today from those unexposed capabilities. ## The implemented path ### 1. A posted purchase supplies the books evidence Posted bills and purchase documents create input `TaxTransaction` rows. Those rows carry the GST registration, document, tax head, value and eligibility information used by the supported processors. A Draft or unposted bill contributes no tax transaction and therefore cannot appear in the books side of GSTR-2B or the ledger-derived portions of GSTR-3B. Review source eligibility carefully. A tax transaction classified as blocked or ineligible is evidence for reversal/disclosure; it must not be treated as available credit merely because a supplier reported the document. ### 2. GSTR-2B supplies the statement comparison [GSTR-2B processing](/docs/finance/tax-center/gstr-2b/) builds the books side from your bills and purchase returns, and **Pull From GSTIN** brings in the portal side from GSTN through your GSP integration. The statement's Reconciliations tab then compares the two sides document by document. GSTR-2B documents can carry the IMS status GSTN reports. GSTR-3B leaves out a document with IMS status **R** (rejected). The GSTR-2B screen has no action that records an accept or reject decision of its own; make IMS decisions on the GSTN portal and pull the statement again. ### 3. GSTR-3B computes the supported credit rows GSTR-3B Compute currently uses these sources: | GSTR-3B area | Implemented source | | --- | --- | | 4A — available ITC | Matching GSTR-2B section data, excluding rows stored with IMS status `R` | | 4B — reversal | Input `TaxTransaction` rows classified as blocked, plus reversals produced by the Rule 37 tracker | | 4D — disclosure/reclaim | Rule 37 reclaims and GSTR-2B amounts marked not available | Rule 42/43 proportional reversal remains a manual GSTR-3B row. Compute preserves manual rows while refreshing only rows marked as auto-filled. ## The implemented Rule 37 tracker Rule 37 tracking is wired into GSTR-3B Compute. For eligible input-tax rows linked to a Bill, the tracker derives a due date 180 days after the source document date and stores whether a reversal or reclaim has already been associated with a period. - If the Bill remains unpaid after that due date, Compute can produce the temporary reversal in GSTR-3B. - A Bill is treated as paid when its open amount is no longer positive; direct payment records linked by Bill ID also contribute to the settlement evidence used by the tracker. - After payment, a later Compute can produce the reclaim. - Stored reversed-in and reclaimed-in period markers prevent the same Bill from being reversed or reclaimed repeatedly. This behavior depends on settlement being recorded against the Bill. A payment that is posted elsewhere but not applied to the Bill can leave its open amount outstanding and therefore cannot prove payment to the tracker. ## Capabilities that are not currently exposed The source contains service methods for period availment, Rule 42 reversal, net-ITC calculation and supplier-level ITC-to-GSTR-2B reconciliation. A GST time-limit service also contains statutory cut-off calculations. The current runtime has no handler action, UI caller or scheduled caller for those operations. Another unused GST-return service references the net-ITC method, but that service itself is not part of a live workflow. Consequently, do not currently claim that xMatix: - automatically posts every eligible credit into a separate `ITCLedger` lifecycle; - automatically calculates or posts a Rule 42/43 reversal; - enforces the statutory availment cut-off during a live save or return action; or - exposes the service-level supplier reconciliation as an operational screen. Those classes are implementation groundwork, not user-facing evidence. A generic entity form for GSTR-2B would not demonstrate these services, so this page intentionally has no screenshot until an exact ITC-management surface is wired into the product. ## Recommended operating procedure 1. Post purchase documents only after checking GSTIN, document date, tax heads and eligibility classification. 2. Process the matching GSTR-2B books side and load the portal statement through your controlled import or integration. 3. Investigate reconciliation differences at document level; separately retain evidence for any imported IMS status. 4. Review bill settlement and open amounts before GSTR-3B Compute so Rule 37 has reliable payment evidence. 5. Compute GSTR-3B, then tie 4A, 4B and 4D to the exact GSTR-2B and tax-transaction sources named above. 6. Calculate Rule 42/43 outside the unexposed service, enter the approved manual return row and retain the workpaper. 7. Apply statutory time-limit review as a manual control until a runtime validation explicitly exposes the existing time-limit logic. ## Common questions ### Why did a Rule 37 reversal appear? Trace the referenced Bill. Its due date has passed and xMatix still sees a positive open amount or no qualifying settlement evidence. Correct an incorrectly unapplied payment at the Bill; do not delete the return row to hide the source-state problem. ### Why did a paid Bill not reclaim? Confirm the payment is applied to that Bill and that its open amount is no longer positive. Then Compute an open GSTR-3B period and inspect the tracker's stored reversed/reclaimed period markers. ### Where do I run ITC availment or Rule 42? There is currently no supported runtime action for the service-level ITC availment or Rule 42 methods. Use the implemented GSTR-2B and GSTR-3B flow, and maintain the Rule 42 calculation and approval as a manual workpaper and manual GSTR-3B row. ## Related topics - [GSTR-2B — inward supplies and ITC](/docs/finance/tax-center/gstr-2b/) - [GSTR-3B — the summary return](/docs/finance/tax-center/gstr-3b/) - [Recording and applying payments](/docs/finance/payments/) ---- # Reconciling TDS — Form 26AS and the deductor tie-out URL: https://xmatix.com/docs/finance/tax-center/tds-reconciliation/ Last reviewed: 2026-09-02 xMatix contains two different TDS comparisons: - **Deductee-side Form 26AS reconciliation** compares tax-credit rows reported by deductors with the internal tax-credit adapters for the same financial year. - **Deductor-side TDS reconciliation** compares tax your company deducted with Filed quarterly-return lines and Deposited/Verified challans. They answer different questions and use different code paths. Do not use one comparison's status or screen actions as evidence for the other. ## Form 26AS: current supported boundary The data model contains `Form26ASStatement`, `Form26ASLine` and `Form26ASReconciliationEntry`. The backend statement handler exposes `PerformForm26ASReconciliation`, which can replace and rebuild persisted result entries for one statement. There is currently **no Form 26AS file parser or Form26ASLine handler** in the runtime. Creating a statement header or attaching its file does not populate line rows, validate them, or calculate Total/Valid/Error row counts. The current New Form 26AS screen shows only that generic header, so it is not useful evidence of the documented import/reconciliation workflow and is intentionally omitted. ### Step 1 — Create the statement and retain the source Create one statement header for the exact financial year in `YYYY-YY` or `YYYY-YYYY` form and attach the downloaded file as evidence if your tenant uses File Assets. A file attachment is archival evidence only; saving it does not parse the file. Set header status and row-control totals only through a controlled import process that can substantiate those values. The reconciliation engine updates matched/mismatch/missing/extra counts and Reconciled At; it does not calculate Total Rows, Valid Rows or Error Rows. ### Step 2 — Populate Form26ASLine explicitly Use a reviewed data import or integration to create `Form26ASLine` rows linked by `Form26ASStatementId`. At minimum, map and validate PAN, TAN, section code, financial year, amount paid and TDS amount. Retain deductor name, transaction date, quarter and booking status where the source supplies them. Because no line handler currently validates an inserted row, your import must assign `ValidationStatus` deliberately: - rows marked **Invalid** are excluded by the reconciliation engine; - rows marked **Valid** are included; and - rows left Pending or blank are also included because the engine excludes only the explicit Invalid value. Reconcile imported row count and tax totals to the original file outside the generic header form before continuing. ### Step 3 — Run the persisted backend reconciliation Where the tenant's metadata exposes the statement action, run **Perform Form 26AS Reconciliation** on the intended header. The backend refuses a statement still marked Parsing or one without a valid financial year. No seeded action definition was found during this review, so an absent button can mean the handler exists but the tenant metadata has not exposed it. The engine normalizes and groups both sides by: `PAN + TAN + section code + financial year` It sums Amount Paid and TDS per key and compares both values with zero-rupee tolerance. It replaces prior reconciliation entries, clears old line reconciliation states and records: | Result | Meaning | | --- | --- | | Match | Both grouped values are identical | | Unmatched | The key exists on both sides, but Amount Paid or TDS differs | | Missing in 26AS | Internal tax-credit data has the key; the imported statement does not | | Missing in books | The imported statement has the key; the internal adapters do not | After the action commits, verify the persisted `Form26ASReconciliationEntry` rows and header counts, not just what a widget happens to render. ### Step 4 — Investigate and rerun Trace each non-match to the source credit and imported lines. Correct books only when the books are wrong; otherwise obtain a deductor correction and import the authoritative portal change. A rerun replaces the previous result set, so compare before/after counts and retain evidence of the correction. ## Important limitation of the current Form 26AS widget The `Form26ASReconciliation` widget is a separate client-side comparison. It does **not** call `PerformForm26ASReconciliation` or read the persisted reconciliation entries described above. It currently: - groups the two sides by TAN only; - classifies a match by rounded TDS equality, without comparing Amount Paid or the full PAN/TAN/section/FY key; - loads all TDS transaction rows because its intended TDS/source filter is disabled; and - keeps Customer Correction, Books Correction, Add in Book, Ignore and Follow-up selections only in React screen state. Those visible action labels are lost on reload and are not an audited remediation record. Use the widget as an exploratory view only. For a statutory tie-out, use the controlled line import and persisted backend result, or clearly document that the backend action is not exposed in the tenant. ## Deductor-side books, returns and challans The **TDS Reconciliation** widget uses the server's deductor-side engine. For one partner account, financial-year start and Nature (TDS or TCS), it compares: - non-reversed, positive withholding transactions in the financial year; - deductee lines from **Filed** quarterly returns; and - Deposited or Verified challans and the amounts Filed returns utilized. It reports quarter totals, deductions not reported, Filed return lines whose live books row is absent, carried deductions and deposited-versus-utilized challan differences. Unlike the Form 26AS widget's local labels, its offered remediation paths call server services—for example challan allocation/deposit, adding an eligible deduction to an open return, creating a correction route, or moving a deposited unreported row to a later open return. Each action still enforces its own state and required inputs; a refused action must be resolved from the reason returned by the server. Run this comparison after deposits and return filing states are current. Read each two-line row carefully: return evidence and books evidence remain separate even when the quarter's grand totals happen to agree. ## Expected result For Form 26AS, every source line was loaded by an explicit controlled import and the persisted engine compared the full statutory key with exact values. For deductor reconciliation, live withholding rows, Filed return lines and paid challans are tied by quarter, with every exception either remediated through a supported server action or retained with an owner and evidence. ## Common questions ### Why did attaching the Form 26AS file create no lines? No runtime parser is implemented. Populate `Form26ASLine` through a controlled import or integration and link every row to the statement. ### Why do the widget buckets disagree with persisted counts? They are different algorithms. The widget groups by TAN and compares TDS client-side; the backend groups by PAN, TAN, section and financial year and compares both Amount Paid and TDS. ### Why was a Pending Form 26AS line included? The backend excludes only `ValidationStatus = Invalid`. Pending or blank rows remain eligible, so the import must set validation status reliably. ### How exact is the backend comparison? Exact to the rupee value stored: the tolerance constant is zero for both grouped Amount Paid and grouped TDS. ## Related topics - [TDS & TCS](/docs/finance/tax-center/tds-tcs/) - [Import data](/docs/administration/data-management/import-data/) - [Closing a period](/docs/finance/period-close/) ---- # TDS returns: computing, validating and filing the quarterly statement URL: https://xmatix.com/docs/finance/tax-center/tds-returns/ Last reviewed: 2026-10-10 A **TDS Return** is the record for one quarterly withholding statement of one company: the non-salary TDS return, the TCS return or the salary TDS return for a financial-year quarter. It sits at the end of the withholding cycle described in [TDS & TCS](/docs/finance/tax-center/tds-tcs/). Bills, invoices, payments and payroll record the deductions, deposit challans pay them, and the TDS Return gathers the quarter's deductions and challans into the statement you upload on the government portal. After filing, the same record produces the deductee certificates. ## Overview xMatix does not calculate tax on the return. **Compute Return** copies what the withholding register already recorded for the quarter into two sets of child rows: one challan row per paid deposit challan and one deductee row per deduction, each linked to the challan that paid it. **Validate Return** runs a pre-file checklist over those rows. **Export e-Return File** turns the computed return into the caret-delimited statement text that the government's return-preparation and validation utilities accept. You file on the portal, then **Mark Filed** records the acknowledgment number and filing date and locks the return against recomputing. **Generate Certificates** then builds the certificate register from the filed return. Every return moves through the same statuses: **Draft → Computed → Validated → Filed**. ## When to use it - Once a quarter, for each company that deducts or collects tax, after the quarter's deposit challans are paid and their CIN details are recorded. - When a filed statement has to be corrected — through **Create Correction**, never by editing the filed return. - At year end, the Q4 salary return also carries the per-employee annual salary computation that the salary certificate is built from. ## How xMatix handles it **Which form, which data.** The **Form Code** decides where the return reads from: | Form Code | Statement | Reads from | Certificate it produces | |---|---|---|---| | 140 | Resident non-salary TDS | TDS rows in the withholding register | One non-salary TDS certificate (Form 131) per deductee | | 143 | TCS | TCS rows in the withholding register | One TCS certificate (Form 27D) per collectee | | 138 | Salary TDS | Posted payroll runs with a TDS deduction, and the paid TDS payroll statutory challans | Form 16 register rows, from the Q4 return only | | 144 | Non-resident | — | Can be selected, but **Compute Return** refuses it | **Which deductions belong to the quarter.** Quarter 1 is April–June, 2 is July–September, 3 is October–December and 4 is January–March of the financial year that starts in **Fy Start Year** (2026 means FY 2026-27). A non-salary or TCS return takes the company's withholding rows of that nature dated inside the quarter, leaves out reversed rows and rows with no tax (except nil-deduction certificate rows, which are reported), and includes any deduction that was moved into this quarter from an already-filed one. A salary return takes posted payroll rows with TDS whose payroll period ends inside the quarter. **Which challans count.** Only challans with the status **Deposited** or **Verified** become challan rows. A deduction allocated to a challan that is still Draft, or not allocated at all, becomes a deductee row with no challan — validation reports it as undeposited. **Due date.** A new return gets the statutory due date for its quarter: 31 July (Q1), 31 October (Q2), 31 January (Q3) and 31 May (Q4), the last two in the following calendar year. A due date you type yourself is kept as long as it falls on or after the end of the quarter, so an official extension survives recomputing. ## Prerequisites - The company account carries its **TAN**. Without it the scheduled job does not treat the company as a deductor, and validation fails the return. - The quarter's deductions are posted on bills, invoices, payments or payroll — see [TDS & TCS](/docs/finance/tax-center/tds-tcs/). - The quarter's deposit challans are posted (status Deposited or Verified) and carry the BSR code, deposit date and challan serial. For the salary return, the payroll TDS challans are marked Paid. - Deductee PANs are recorded on the vendor, customer or employee records, and ideally verified (see Step 3). - Your security profile allows the TDS Return actions you need (see Permissions). ## Procedure ### Step 1 — Find or create the quarter's return 1. Open the **Finance Setup** app and, under **Withholding Tax (TDS)**, open **TDS Returns**. The **All TDS Returns** view lists every return; **Open Returns** lists those not yet Filed. 2. If the monthly compliance job runs in your organisation, the Draft returns for Forms 140, 143 and 138 already exist for each company with a TAN. They are labelled like *Form 140 · FY 2026-27 Q2*. 3. To create one yourself, select **New** and fill **Name**, **Form Code**, **Fy Start Year** and **Quarter**. **Return Type** defaults to **Regular** and **Status** to **Draft**; leave them. Save. 4. Open the saved return and check that the company is set (**Partner Account Id** on the **Filing & Validation** tab). **Compute Return** cannot run without it. The record page opens on the **Overview** tab, which shows readiness, deposit coverage and filing tiles, the checklist findings and the deductees grouped by challan. **Return**, **Totals**, **Filing & Validation**, **Related** and **Attachment** tabs hold the rest. ### Step 2 — Compute the return 1. On the return, select **Compute Return** and confirm. 2. xMatix removes any earlier challan and deductee rows and rebuilds them from the register, then fills **Deductee Count**, **Challan Count**, **Total Tax Deducted**, **Total Tax Deposited** and **Computed On**. If **Tan** is empty it is copied from the company account. 3. The status becomes **Computed** and any earlier validation result is cleared. You can compute as often as you like until the return is Filed. Recompute after posting a late bill, depositing a challan or correcting a PAN. ### Step 3 — Bring PAN verification results in (optional) **Import PAN Verification** reads the bulk PAN verification result file downloaded from the department's portal. For each line that carries a PAN and a verdict, it stamps every vendor, customer and employee record with that PAN as *Verified*, *Invalid* or *Name Mismatch*. Lines it cannot read are counted and skipped. The action has no file dialog of its own on the shipped page: it expects the file's content to be supplied with the action, so it is normally run by an integration or automation. Run without a file, it stops with a message that the file content is needed. ### Step 4 — Validate the return 1. Select **Validate Return**. It runs only on a Computed or Validated return. 2. Read the result on the **Overview** tab checklist, or in **Validation Status** and **Validation Results**. 3. **Validation Status** is **Pass** (no findings), **Warnings** (only warnings) or **Fail** (at least one error). The status becomes **Validated** only when there is no error; with errors it stays **Computed**. 4. Fix each finding at its source — the party record, the challan, the payroll run — then compute and validate again. The checks are listed under Business rules. ### Step 5 — Export the e-return file 1. Select **Export e-Return File**. It works on a Computed, Validated or Filed return. 2. xMatix renders the statement — a file header line, a batch header line, then the challan and deductee records (and, on a Q4 salary return, the annual salary detail records). Amounts are plain decimals and dates are written day-month-year. 3. Where file storage is available, the file is also saved on the return's **Attachment** tab. Exporting again adds a new version of the same file rather than a duplicate. 4. Run the file through the government's validation utility and upload it on the portal. xMatix does not upload it for you. ### Step 6 — Record the filing 1. After the portal accepts the statement, select **Mark Filed**. 2. In the dialog, enter **Ack Number** (required) and **Filed On**. If you leave **Filed On** empty, today's date is used. 3. Confirm. xMatix stamps the acknowledgment and date, computes **Late Fee** if the filing date is after **Due Date**, and sets the status to **Filed**. **Mark Filed** accepts a Computed return as well as a Validated one, so it does not force a passing validation. Make validating part of your own filing routine. ### Step 7 — Generate and issue certificates 1. On the Filed return, select **Generate Certificates** and confirm. 2. xMatix creates one certificate per deductee and writes the certificate number back onto each underlying deduction, so the register, the certificate and the deduction all cite the same number. 3. For a salary return, run it on the **Q4** return of the year: the salary certificate is annual and xMatix refuses to generate it from Q1–Q3. 4. You can regenerate while the certificates are Draft — the Draft set is replaced. Once any certificate is marked Issued, the register for that return is locked. ### Step 8 — Correct a filed return 1. On the Filed return, select **Create Correction** and confirm. 2. xMatix creates a new Draft return with **Return Type** *Correction*, **Original Return Id** pointing to the filed one, the same form, company, quarter, TAN and due date, and a name ending in *-C1* (then *-C2*, …). The original stays Filed and unchanged. 3. Fix the source data, then compute, validate, export and mark the correction filed exactly as in Steps 2–6. ## Fields | Field | What it means | Notes | |---|---|---| | Name | The return's identifier | Required. The compliance job names returns by form, financial year, quarter and company. | | Form Code | Which quarterly statement this is | `138`, `140`, `143` or `144`. Decides the source data and the certificate kind. Any other value is refused on save. | | Fy Start Year | The calendar year in which the financial year starts | 2026 means FY 2026-27. | | Quarter | Quarter of the financial year | 1 (Apr–Jun) to 4 (Jan–Mar). Other values are refused on save. | | Tan | The deducting company's TAN | Copied from the company account by the compliance job or by Compute Return when empty. Must be four letters, five digits and a letter. | | Return Type | Regular or correction statement | `Regular` (default) or `Correction`. A Correction must have Original Return Id. | | Original Return Id | The filed return a correction amends | Set by Create Correction. | | Status | Where the return is in its life | `Draft`, `Computed`, `Validated`, `Filed`. Set by the actions — do not change it by hand. | | Deductee Count | Number of deductee rows | Set by Compute Return. | | Challan Count | Number of challan rows | Set by Compute Return. | | Total Tax Deducted | Tax on all deductee rows | Set by Compute Return. Also the cap for the late fee. | | Total Tax Deposited | Part of that tax covered by paid challans | Set by Compute Return. Lower than Total Tax Deducted means something is undeposited. | | Late Fee | Late-filing fee | Set by Mark Filed: ₹200 per day after the due date, capped at Total Tax Deducted. Zero when filed on or before the due date. | | Due Date | Statutory filing due date | Defaulted from the quarter; a later date you enter is kept. | | Computed On | When the return was last computed | Set by Compute Return. | | Filed On | Date the return was filed on the portal | Entered in Mark Filed. | | Ack Number | The portal's acknowledgment for the filing | Required by Mark Filed. | | Validation Status | Outcome of the last validation | `Pass`, `Warnings` or `Fail`. Cleared by Compute Return. | | Validation Results | The individual findings of the last validation | Each finding has a code, severity, message and count. | | Partner Account Id | The deducting company | Required by Compute Return. Shown on the Filing & Validation tab. | | Label | Display name | Defaults to Name when left empty. | ## Business rules **Save checks.** Form Code must be 138, 140, 143 or 144; Quarter must be 1–4; Return Type must be Regular or Correction, and a Correction must reference its original; Tan, when filled, must be four letters, five digits and a letter; Status must be one of the four statuses. **Action guards.** - **Compute Return** is refused on a Filed return ("create a Correction statement instead"), on Form 144, and when the company, financial year or quarter is missing. - **Validate Return** needs a Computed or Validated return. - **Export e-Return File** needs a Computed, Validated or Filed return. - **Mark Filed** needs a Computed or Validated return and an acknowledgment number. - **Create Correction** and **Generate Certificates** need a Filed return. **The pre-file checklist.** Validate Return reports each rule with the number of rows affected: | Check | Severity | What it means | |---|---|---| | TAN missing or malformed | Error | Set the TAN on the company account. | | Missing or invalid PAN structure | Error | A deductee row has no PAN or a PAN not shaped like five letters, four digits and a letter. | | PAN marked Invalid or name-mismatched | Error | The imported verification result rejected the PAN. A Verified stamp on any record with the same PAN clears it. | | PAN never verified | Warning | A well-formed PAN with no verification result. | | PAN coverage below 85% | Error | Fewer than 85% of deductee rows carry a valid PAN. | | Deduction not deposited | Error | A deductee row with tax has no paid challan. Post the challan, then recompute. | | Challan over-used | Error | Deposits mapped to a challan row exceed its tax amount. | | CIN incomplete | Error | A challan row lacks the BSR code, tender date or challan serial. | | Short deposit | Warning | A deductee row was deposited for less than the tax deducted. | | Negative amounts | Error | A row with a negative amount paid or tax. | | Lower-deduction certificate number missing | Warning | A row deducted under a lower or nil deduction certificate has no certificate number. | | Annual salary detail missing (Q4 salary only) | Error | The Q4 salary return has deductee rows but no per-employee annual rows. | | Annual salary detail not computed (Q4 salary only) | Warning | An employee's annual row has no tax computation, usually because the year's tax slab rules are not set up. | | Short deduction (Q4 salary only) | Warning | An employee's TDS for the year is below the computed liability. | **Late fee.** ₹200 for every day from the day after the due date up to and including the filing date, never more than the return's total tax deducted. **What a Filed return protects.** Recomputing is refused, and certificate generation and the year-end books-versus-returns reconciliation read only Filed returns. The save checks do not lock a Filed return's other fields, and the record can still be edited or deleted by a user whose profile allows it. Keep edit and delete rights narrow (see Permissions). **Salary returns.** The Q4 salary return also builds one annual row per employee paid in the year, with gross salary, exemptions, deductions, taxable income, tax, rebate, surcharge, cess, TDS deducted and deposited, and the shortfall or excess, computed under the employee's chosen tax regime. ## Example A company deducts TDS on contractor and rent bills. For Q2 of FY 2026-27 (July–September): 1. On 1 October the compliance job creates the Draft return *Form 140 · FY 2026-27 Q2*, with due date 31 October 2026. 2. The September challans are posted with their CIN details on 7 October. On 10 October the accountant selects **Compute Return**: 42 deductee rows, 6 challan rows, Total Tax Deducted ₹3,18,400, Total Tax Deposited ₹3,18,400. 3. **Validate Return** gives **Warnings**: three PANs have never been verified. The accountant runs the bulk PAN verification on the portal, the result is imported, and a second validation gives **Pass**. Status: Validated. 4. **Export e-Return File** produces the statement text, which passes the government's validation utility and is uploaded on 24 October. 5. **Mark Filed** with the acknowledgment number and Filed On 24 October: Late Fee ₹0, status Filed. 6. **Generate Certificates** creates 18 certificates — one per deductee — which are issued to the vendors. Had the return been filed on 3 November, Mark Filed would have recorded a late fee of ₹600 (three days). ## Training ### Practice exercise In a sandbox company that has a TAN, one posted bill with TDS dated in the current quarter, and that bill's deduction on a posted deposit challan with full CIN details: 1. Create a TDS Return for Form 140 and the current financial year and quarter, and check the company on the Filing & Validation tab. 2. Compute it. **Expected:** status Computed, Deductee Count at least 1, Total Tax Deposited equal to Total Tax Deducted. 3. Validate it. **Expected:** Pass or Warnings, status Validated. 4. Post a second bill with TDS in the same quarter but do not deposit it, then compute and validate again. **Expected:** Fail with the undeposited-deduction error; status stays Computed, and Total Tax Deposited is below Total Tax Deducted. 5. Export the e-return file. **Expected:** the statement text, and a file on the Attachment tab where storage is available. ### Quick reference - One return per company, form and quarter — the job creates the Draft ones. - Post challans and record their CIN before computing. - Compute freely until Filed; it always rebuilds from the register. - Computing clears the last validation — validate again afterwards. - Errors keep the return Computed; warnings still let it reach Validated. - Mark Filed needs the acknowledgment number and computes the late fee. - Certificates come from a Filed return; salary certificates only from Q4. - Fix a filed return with Create Correction, never by editing it. ## Permissions Each button is a server action that a security profile grants separately: **Compute Return**, **Validate Return**, **Export e-Return File**, **Mark Filed**, **Create Correction**, **Generate Certificates** and **Import PAN Verification**, plus **New**, **Edit** and **Delete** for the record itself. The shipped standard-user and system-administrator profiles include all of them. A user whose profile lacks an action cannot run it; a user without access to the Finance Setup app or the TDS Return list does not reach the returns at all. If a button is missing for someone, start with [why a user can't see something](/docs/administration/user-cant-see-x/). Because a Filed return is not locked against generic editing or deletion, give **Edit** and **Delete** only to the people who own TDS compliance. See [security profiles](/docs/administration/security-profiles/). ## Configuration - **Company TAN.** Set on each company account. It is what makes a company a deductor for the compliance job and what every return quotes. - **Deductee PAN and type.** Set on vendors, customers and employees. Missing or invalid PANs fail validation. - **Monthly compliance job.** The **Provision TDS/TCS compliance** job (Finance category) drafts the month's deposit challans and creates the Draft Form 140, 143 and 138 returns for every company with a TAN for the quarter that month belongs to. It runs for the previous calendar month unless a month and year are given, can be started manually, and never creates a second Regular return for the same company, form and quarter. It runs on a schedule only when your organisation has a schedule set up for it. - **Due dates.** Statutory dates are defaulted. To record an official extension, enter the extended date in **Due Date** before marking the return filed. - **Record page.** The shipped view puts the **TDS Overview** widget on the first tab. On a copied or custom layout, add it from the Studio toolbox under **Entity Components → TDS Overview**; it works only on TDS Return and TDS Challan layouts. See [design a form layout](/docs/customization/layouts/design-a-form-layout/). - **Salary returns** depend on payroll: posted payroll runs, TDS payroll statutory challans marked Paid, and, for the Q4 annual rows, the year's tax regime and slab rules — see [Income tax in payroll](/docs/payroll/income-tax/). - **Reconciliation.** Year-end books-versus-returns checks and their fixes, including moving a deposited but unreported deduction into the next open return, run from the TDS Reconciliation page — see [TDS reconciliation](/docs/finance/tax-center/tds-reconciliation/). ## Common problems ### "A Filed return cannot be recomputed" The return is Filed. Use **Create Correction** and compute the correction instead. ### "Return needs a company" The return has no company. Open it, set **Partner Account Id** on the Filing & Validation tab, save and compute again. ### Compute Return refuses a Form 144 return The non-resident form can be stored but not computed. Use Form 140, 143 or 138. ### "Compute the return before validating it" or "before exporting the e-return file" The return is still Draft. Run **Compute Return** first. ### "Only a Computed/Validated return can be marked Filed" The return is Draft or already Filed. Compute it first; a Filed return cannot be filed again. ### "Recording a filing needs the portal acknowledgment number" Enter **Ack Number** in the Mark Filed dialog. ### Validation says deductions are not deposited, but I paid the challan Only Deposited or Verified challans count. Post the challan with its deposit date, make sure the deduction is allocated to it, then recompute and validate. ### "Certificates are generated from a Filed return" or "Form 16 is an annual certificate" Mark the return Filed first. For salary, generate certificates from the Q4 return of the year. ### "Certificates for this return have already been issued" At least one certificate is Issued, so the register is locked and cannot be regenerated. ### The Q4 salary return has annual rows with no tax computed The year's tax regime and slab rules are missing for those employees. Set them up and recompute. ## Common questions ### Does xMatix file the TDS return on the portal? No. xMatix computes the statement, checks it and exports the e-return file. You validate that file with the government's utility and upload it on the portal yourself. Afterwards, **Mark Filed** records the acknowledgment number and filing date on the return and computes any late fee. From that point the return is locked against recomputing, and certificates can be generated from it. ### Why is Total Tax Deposited lower than Total Tax Deducted? Some deductions are not linked to a paid challan. Either the deduction was never allocated to a challan, or its challan is still Draft. Only Deposited and Verified challans are reported. Prepare and post the missing challans, record their CIN, then compute again. Validation lists the affected rows as undeposited deductions until this is fixed. ### Can I change figures on the return directly? Don't. The return reports what the withholding register and challans recorded, and every compute rebuilds the rows from them, so manual changes are overwritten. Correct the bill, payment, party PAN or challan instead, then recompute. For a filed return, use Create Correction. ### What happens to deductions posted after the return was filed? Recomputing a Filed return is refused, so the filed statement does not change. Report a late deduction through a correction statement, or use the reconciliation page's move-to-next-return fix to report it in the next open quarter. ## Related topics - [TDS & TCS](/docs/finance/tax-center/tds-tcs/) — the full withholding cycle, challans and setup. - [TDS reconciliation](/docs/finance/tax-center/tds-reconciliation/) — Form 26AS and the books-versus-returns check. - [Tax Center troubleshooting](/docs/finance/tax-center/troubleshooting/) - [Income tax in payroll](/docs/payroll/income-tax/) - [TDS Return — entity reference](/docs/reference/entities/tds-return/) ---- # TDS & TCS: the withholding compliance cycle URL: https://xmatix.com/docs/finance/tax-center/tds-tcs/ Last reviewed: 2026-09-02 When you pay a contractor, book a rent bill, or sell above a section's threshold, income-tax law can require your company to hold back tax (**TDS**) or collect it (**TCS**) and pass it to the government. xMatix connects posting-time withholding, monthly challan actions, quarterly-return computation and certificates through the withholding register. Review each transition and its evidence; shared source data reduces re-keying but does not eliminate the need for reconciliation or access controls. ## Read the challan @[guided-image](_img/tds-tcs-concept.png) The challan form separates statutory classification from money and payment proof. Period year and month, nature, section code, payment code and major/minor heads say which obligation is being deposited. Tax amount is shown separately from interest, late-deduction interest and fees so reviewers can explain why the total differs from the underlying withholding. Synthetic demo2 values remain visible in this guide so the complete control structure can be understood; real registration, banking and payment identifiers must not be published. The Deposit & CIN section closes the loop from liability to evidence. Due date explains timeliness, deposit date proves when cash moved, bank GL account provides the book side and BSR code, challan serial or CIN fields provide the government acknowledgement. Before marking the challan paid, reconcile its tax amount to the undeposited register, its total to the bank posting and its statutory codes to the period's obligation. The controlled challan actions treat posted amounts as immutable, but the generic TDS Challan save validator does **not** currently freeze a Deposited or Verified row. A user with generic edit permission can change fields, including amounts or status, without using Correct Challan. Restrict generic edit access after posting and audit any such change; do not rely on the status alone as a technical lock. ## One-time setup - **Provision the statutory catalog.** On the TDS Sections screen, **Provision Statutory Catalog** loads the sections with their rates, thresholds and deduction points as *data*. When a Finance Act changes them, re-provisioning updates the catalog — rates are never hard-coded. - **Record the company's TAN** on the company account; every challan, return and certificate quotes it. - **Classify your parties.** On each vendor and customer: the **PAN** (without a valid one, the law forces deduction at the penal higher rate, and the return reports it with the corresponding remarks code), the **deductee type** (individual, company, firm…) which selects the rate on dual-rate sections, optionally a **default TDS section** that pre-tags new bill lines (a section you pick on the line always wins), and a **TDS applicable** switch for genuinely exempt parties. - **Record lower/nil-deduction certificates.** A certificate from the assessing officer is captured with its number, section, certified rate, amount limit and validity. It is applied automatically while valid and within its limit — consumption is tracked, and an exhausted or expired certificate stops applying on its own. Certificate rows carry the proper remarks code on the return. ## Day to day — it happens at posting - **Vendor bills and payments** deduct at whichever point the section prescribes — bill, payment, or the earlier of the two — and never twice. The vendor's payable is reduced, so you naturally pay the net. - **Customer invoices** collect TCS on top: the receivable is increased by the collected amount, and a receipt against an invoice can trigger collection for sections that collect at payment time. Reversing an invoice reverses its collection cleanly. - **Thresholds are assessed cumulatively** across the financial year per party and section, so deduction starts exactly when the yearly total crosses the line. - **Every event lands in the TDS Transactions register** — party, PAN, section, rate, amount, and later the challan and certificate references. The **TDS Summary** and **TCS Summary** screens in the Tax Center are reporting views over this register. Salary TDS is computed by payroll and deposits through its own statutory challans alongside PF and ESI; its quarterly return is part of the same return pipeline below. ## Monthly — deposit challans **Prepare Monthly Challans** drafts one challan per payment code and per major head — company deductees and others deposit under different heads, so one code can correctly produce two challans — covering every undeposited deduction of the month. Re-running is safe: late-posted bills top up the existing draft, nothing duplicates. After paying at the bank, **Post Challan** with the deposit date records the payment in the ledger, marks every covered deduction deposited, and computes both statutory interest legs when applicable — late deduction and late deposit — as of the deposit date. Record the bank's **CIN** (BSR code, tender date, serial number); the quarterly return cannot validate without it. **Verify Against CSI** matches your recorded CINs against the portal's challan-status file and flips matched challans to *Verified*. A deposited challan whose head, code or CIN was corrected at the bank or portal is updated with **Correct Challan**: the corrected values are applied, every action-driven change is kept in a correction log, a changed CIN goes back for re-verification, and an already-filed return that quoted old values can be identified for correction. The Correct Challan action deliberately accepts only head, payment/section code, CIN fields and deposit date—not amounts. That restriction belongs to the action contract, not to every save path. Generic entity editing can currently bypass the intended amount immutability. Use permission and audit controls to keep Deposited/Verified challans out of generic edit flows until the handler enforces a record-wide lock. ## Quarterly — the returns The quarter's return headers (the vendor-TDS, TCS and salary forms) are drafted for you — by the scheduled compliance job or manually — and each moves through **Draft → Computed → Validated → Filed**. The step-by-step procedure, every field and the full pre-file checklist are in [TDS returns](/docs/finance/tax-center/tds-returns/). 1. **Compute** assembles every deduction of the quarter and maps each to its depositing challan. Recompute freely until filing; it always rebuilds from the live register. 2. **Validate** runs the pre-file checklist early, so problems surface on your side: missing or invalid PANs, department-rejected PANs (these block filing), deductions not yet deposited, incomplete CINs, challan over-use or short deposit, and missing certificate numbers on lower-deduction rows. 3. **Export** renders the computed return as the caret-delimited e-return statement text that the government's return-preparation and validation utilities accept — the last step before uploading on the portal. 4. **Mark Filed** records the portal acknowledgment and date; a late filing's fee is computed so the cost is on record. A filed return is locked — corrections go through **Create Correction**, which drafts a linked correction statement you compute, validate and file the same way. **PAN hygiene** is part of the pipeline: run the department's bulk PAN verification and import the results — every party gets stamped *Verified*, *Invalid* or *Name mismatch*, and validation uses those stamps (rejected PANs block; never-verified ones warn). ## After filing — certificates On a filed return, **Generate Certificates** builds the certificate register: one numbered certificate per deductee — the non-salary TDS certificate for the vendor return, the TCS certificate for the collection return, and the salary certificate rows for the salary return — and stamps the certificate number back onto every underlying deduction, so the ledger, the certificate and the deductee's own statement all cite the same reference. Mark certificates *Issued* as you hand them over; issued certificates lock the register. ## The scheduled front half The compliance job (`finance.tds-compliance.provision`) runs the routine's front half unattended for every deductor company: it drafts the month's deposit challans and ensures the quarter's return headers exist. It is existence-checked and idempotent — your team reviews, pays and files. Statutory rates, thresholds and due dates come from the provisioned catalog and the return logic, and change with the law — confirm current rules with your tax advisor. ## Related topics - [TDS returns](/docs/finance/tax-center/tds-returns/) — computing, validating, exporting and filing the quarterly statement. - [TDS reconciliation](/docs/finance/tax-center/tds-reconciliation/) — Form 26AS and the books-to-returns tie-out. - [Bills](/docs/procurement/bills/) — where vendor-side deduction begins. - [Invoicing and payments](/docs/sales/invoicing-and-payments/) — where collection begins. ---- # Troubleshooting the Tax Center URL: https://xmatix.com/docs/finance/tax-center/troubleshooting/ Last reviewed: 2026-09-02 Start with the exact runtime boundary. A return processor can only use records that match its GSTIN, date/period and supported source type. An e-invoice or e-way-bill action can stage data without ever submitting it. A generic form can save fields that a controlled server action would refuse. Distinguishing those states is faster than treating every missing value as the same problem. ## Establish the diagnostic boundary For a GST return, record the return ID and verify GSTIN, fiscal period/return period and lifecycle state. Then choose one known source document and trace it through posting, tax-transaction capture and the expected child table. Do not use a blank GSTR-3B `ProcessedInvoiceValue` as proof of failure: current Compute does not populate that header field. For an integration-dependent document, separate these stages: 1. the xMatix action created or staged local data; 2. a configured integration consumed it; 3. the provider accepted it; and 4. a response was written to the original xMatix record. Evidence from one stage does not prove the next. ## GST Console ### The GSTIN picker is empty The widget retains active `GSTRegistration` records with a nonblank GSTIN. Check the master record and read permission. The query does not independently label “own” versus counterparty registrations, so also verify that only appropriate filer records are active. ### A financial year is missing Normal FY choices are derived from stored `GSTFiscalPeriod` rows. Create or provision the missing periods. When no rows exist, the widget's current-year fallback is only a navigation default. ### Months appear but cards open an empty list The console synthesizes a twelve-month scaffold when stored periods are absent, and a card falls back to a scoped list if no exact return header exists. Provision the required registration/period. For an ISD, remember that the widget still shows annual GSTR-9 while the provisioning service does not create it. ## GSTR-1 and GSTR-2B ### A source document is missing Check in this order: 1. **Posting:** Draft source documents do not contribute tax transactions. 2. **Date:** the document must fall inside the return's period. 3. **GSTIN:** the source and header must belong to the same filing registration. 4. **Source type:** GSTR-1 books data comes from supported outward records; GSTR-2B books data comes from supported purchase records. 5. **Latest processing:** rerun the incremental processor after a late posting. 6. **GSTR-1 row flags:** an Ignore or Carry Forward decision removes the selected books row from the current filing. The clear-decision service is not currently exposed as a handler action, so do not promise an Undo button. ### GSTR-1 processing is refused The return is probably Filed. The Process action validates that state and the service blocks regeneration. Correct the source in the appropriate open-period/amendment process rather than reopening the stored snapshot. ### GSTR-1 has no acknowledgment field This is expected. The filing action stores `IsFiled`, Status and Filing Date only. Retain ARN/portal acknowledgment in your external controlled evidence; it cannot be recovered from the GSTR-1 header. ### GSTR-2B Accept/Reject is missing or disappears on reload The backend supports Get, Process and Reconciliation only. It has no Accept/Reject/reason/reviewer action. Legacy grid choices change local screen state and are not persisted. Only an `ImsStatus` value supplied on the row by an authoritative import/integration affects downstream filtering. ## GSTR-3B ### Box 3.1 is zero even though GSTR-1 is Draft Draft status alone is not the cause. Compute selects a same-GSTIN/same-period GSTR-1, ordering Filed before Draft. If no Filed record exists, it can use Draft. Identify the selected record and confirm that its processed child rows contain the expected supported supplies. ### A different GSTR-1 was selected than expected Multiple headers exist for the same GSTIN and period. Compute prefers Filed, then uses filing date and record identity to resolve ordering. Remove the duplication through an approved data-cleanup process or make the intended record's lifecycle unambiguous before recomputing. ### A credit is missing from 4A Confirm the latest matching GSTR-2B contains the row and inspect its stored IMS status. `R` is excluded. Do not look for an xMatix Reject audit record—the current workflow does not create one. If the credit is ledger-classified as blocked, inspect the 4B reversal evidence separately. ### Processed Invoice Value is blank after Compute This is current behavior. Compute sets Status to Computed and writes child-table rows but does not assign GSTR-3B's `ProcessedInvoiceValue`. Validate the child tables and source totals instead. The scheduled job has a different readiness check: it tests non-null processed values on GSTR-1 and GSTR-2B, not this GSTR-3B field. ### A manual value disappeared Compute clears and rebuilds rows marked auto-filled while preserving manual rows. Confirm that the value was entered in a truly manual row such as 3.1.1 or a Rule 42/43 adjustment, rather than editing an auto-filled row directly. ### A payment row changed after Compute Compute upserts payable for the four tax heads while retaining cash and credit-utilization fields on existing rows. Reconcile the refreshed payable amount with the liability, then verify the retained payment allocation against portal ledgers. ## ITC and Rule 37 ### Where is the ITC availment or Rule 42 action? It is not currently exposed. Source services exist for an ITC-ledger lifecycle and Rule 42 calculation, but no runtime handler, page or scheduled caller invokes them. Use the implemented GSTR-2B/GSTR-3B path and retain a manual Rule 42 workpaper. ### A Rule 37 reversal appeared unexpectedly Inspect the linked Bill, its document date, open amount and applied payments. The GSTR-3B compute path treats an eligible Bill as overdue after 180 days and relies on recorded settlement evidence. A payment not applied to the Bill may leave it appearing unpaid. ### A paid Bill did not reclaim Confirm the Bill's open amount is no longer positive and payment linkage is present. Then Compute an open GSTR-3B and inspect whether the tracker already records reversed-in and reclaimed-in periods. ## E-invoicing ### The Invoice remains Pending The Invoice action staged `EINVPayload`; it did not submit it. Verify that an explicitly configured integration consumes Pending Invoices and writes success back to the same Invoice. The built-in response recorder requires an IRN and has no failure-recording companion, so inspect the integration's own error/audit path for a rejection. ### The provider rejects party address, Unit or service classification Inspect the actual payload. The current builder leaves seller/buyer legal name, location and PIN null, leaves Unit null and sets every line `IsService = false`. The integration or product mapping must enrich/correct those values where required. ### Generate is refused The Invoice already has `EINVIRN`. That is the duplicate-generation guard. It is not a general edit lock and does not perform portal cancellation. ### A registered Invoice can still be edited The e-invoice service does not impose a global Invoice lock after IRN. Restrict edits through permissions and document lifecycle controls, and use the proper statutory correction process. ## E-way bills ### A row remains Draft with no EWB number The Invoice action created local Part A data only. Verify that a configured provider flow submitted it and called the generated-response writeback for that EWayBill ID. The generic entity form does not perform this transition. ### Distance is zero or transporter data is blank Distance defaults to zero, Road is the default mode, and the Invoice action leaves transporter ID/name blank. Supply and validate the transport facts before submission. ### Duplicate Draft rows exist The Invoice action has no existing-row guard. Do not generate another Draft as a retry. Select one intended ID under an approved cleanup process and make the integration write back only to it. ### A past-validity row still says Generated No runtime job changes Generated to Expired, and no cancellation action was found. Use the portal as authority and treat status synchronization/expiry alerting as an integration gap. ## Form 26AS ### Attaching a file creates no lines or row counts No runtime parser or Form26ASLine handler exists. Import `Form26ASLine` explicitly and validate the file outside the generic header form. The backend reconciliation updates match counts, not Total/Valid/Error counts. ### The Form 26AS widget and saved reconciliation disagree They use different algorithms. The widget groups by TAN and compares rounded TDS client-side; the backend groups by PAN, TAN, section and financial year and compares both Amount Paid and TDS with zero tolerance. Widget remediation labels are screen-local and disappear on reload. ## TDS challans and returns ### A Deposited or Verified challan can still be edited The Correct Challan action restricts changes to head/code/CIN/deposit-date fields and logs them, but the generic entity save validator does not freeze a posted row or its amounts. Restrict generic edit permission and audit changes; status alone is not an immutability control. ### One month produced two challans for the same payment code Challans are grouped by payment code and major head. Company and non-company deductees can therefore produce separate valid challans for one payment code. ### Return validation fails Read the exact validation result. Common supported checks include missing/invalid PAN, an undeposited deduction, incomplete CIN, challan over-use/short deposit and missing lower-deduction certificate data. Correct the named source and recompute rather than editing a Filed return line. ### A Filed TDS return needs a change Use the correction-return path. Deductor-side reconciliation can also classify a Filed line with no live books row and offer the relevant server remediation when its state and IDs permit it. ## Still stuck? Confirm both code availability and tenant metadata. Handlers can exist without a metadata action being exposed, and screens/actions are permission-gated. Check the user's [security profile](/docs/administration/security-profiles/) before assuming a missing button is a calculation defect. ## Related topics - [GSTR-1 — outward supplies](/docs/finance/tax-center/gstr-1/) - [GSTR-2B — inward supplies and ITC](/docs/finance/tax-center/gstr-2b/) - [GSTR-3B — the summary return](/docs/finance/tax-center/gstr-3b/) - [TDS reconciliation](/docs/finance/tax-center/tds-reconciliation/) - [E-invoicing](/docs/finance/tax-center/e-invoicing/) - [E-way bills](/docs/finance/tax-center/e-way-bills/) ---- # Where to get help URL: https://xmatix.com/docs/getting-started/help/ Last reviewed: 2026-09-01 ## Use the right help surface Where licensed, **Sense Agent** provides the in-product place to ask a new question in plain language. Start a fresh conversation so the request is not mixed with an earlier topic, describe the app, entity, record or action involved, and include the exact result you expected. Sense operates with your own permissions; it cannot retrieve records or configuration you are not allowed to see. @[guided-image](_img/getting-help-context.png) For a problem report, include the app, entity and view name; the action you attempted; the expected and observed result; the time and time zone; whether the issue repeats; and the exact error text. Add a screenshot only after checking it for customer names, recent records, insights, email addresses, phone numbers and search terms. Demo2 documentation images may show synthetic business records, but screenshots from any other tenant must stay inside authorized support channels. When something in xMatix is unclear — a screen you do not recognize, a record you cannot find, a question about your data — help comes from a few places, each good at different things: this documentation, your organization's administrator, Sense AI chat where your organization has licensed it, and a clear problem report when something is genuinely broken. ## Start with this documentation The [Knowledge Center](/docs/) explains how xMatix works in general: [getting started](/docs/getting-started/) covers signing in, navigation and the mobile app, and the [concepts section](/docs/concepts/) explains the ideas behind the platform — apps, entities, records, tenants. It is the right place for "how does this work?" questions. It cannot answer questions about *your organization's* specific setup — which apps you have, why a field is named the way it is — because those are decisions your organization made. ## Your administrator, for access questions What you can see and do in xMatix is decided by your organization, not by the platform. If an app is missing from your app switcher, a record will not open, or an action you expect is not offered, that is almost always an access question — and your administrator is the person who can check your access and change it. The same goes for account matters: invitations, password trouble your mailbox cannot solve, and getting set up on mobile. ## Sense AI, where your organization has it If your organization has licensed Sense AI, you can open its chat and ask questions in plain language — about your data ("which customers have not ordered this month?") and about the screens you are on. Its answers are grounded in your organization's actual records rather than guessed, and it is permission-aware: it works with the same access you have, so it cannot show you data you could not open yourself. If you do not see Sense AI, your organization has not enabled it for you — that, too, is an administrator question. ## Reporting a problem When something behaves wrongly — an error message, a save that fails, a page that will not load — report it to your administrator with three things: **what** you were doing and what you expected to happen, **where** you were (the app, the list or record, its name or number), and **when** it happened, including whether it happens every time or happened once. That detail is the difference between a report that can be acted on immediately and one that starts with a round of follow-up questions. ## Common questions ### Who do I ask when I cannot see an app or record? Your administrator. Visibility in xMatix is controlled by the access your organization granted you, so a missing app, list, record or action is an access question, not a fault — and administrators are the ones who can check and adjust access. Mention exactly what you expected to see and where you looked; a colleague who *can* see the item is a useful reference point, because it tells the administrator the difference is in the two accounts' access. ### What kinds of questions can Sense AI answer? Questions about your organization's data and the screens you work in, asked in plain language — sums, counts, comparisons, "show me" and "explain this" questions. Its answers are grounded in your organization's records and respect your permissions: it sees only what you can see, so it will not reveal data your access does not cover. It is available only where your organization has licensed it. For access changes or account problems, it will still point you to your administrator. ### What makes a good problem report? What, where, when. Describe what you did and what you expected, name the exact place — app, list, record name or number — and say when it happened and whether you can reproduce it. Include the exact text of any error message. The goal is that someone who is not looking over your shoulder can retrace your steps; reports that allow that get fixed much faster than "it doesn't work". ## Related topics - [Signing in to xMatix](/docs/getting-started/sign-in/) - [Navigating xMatix: apps, lists and records](/docs/getting-started/navigation/) - [Sense AI assistant](/ai/assistant/) - [How xMatix approaches AI trust](/ai/trust/) ---- # Getting started with xMatix URL: https://xmatix.com/docs/getting-started/ Last reviewed: 2026-09-01 ## Read your workspace @[guided-image](_img/getting-started-overview.png) The workspace is organized from broad context to specific work. The top bar names the active app and links to its major areas; the breadcrumb and large heading identify the current entity view; Ask AI opens permission-aware assistance where licensed; page actions create or edit records; and the list toolbar supplies search, filters, refresh and display choices. The grid beneath those controls is the working set defined by the selected view. For a first session, confirm the app name, open the view selector beside the heading, practice searching and filtering, and open a record before creating anything. If a module, record or action is absent, record that exact context and ask your administrator—visibility follows licensing and access rather than every user seeing the same menu. The records shown are synthetic demo2 examples and are intentionally visible so the list, ownership columns and populated workspace can be understood as they appear in use. xMatix is a business platform your organization uses to run its day-to-day operations — sales, field work, inventory, service, finance and more — from one place, on the web and on mobile. This section gets a new user from a fresh invitation to working comfortably in the product. ## What's in this section - [Signing in to xMatix](/docs/getting-started/sign-in/) — your first sign-in from the invitation email, and the sign-in options your organization may have enabled. - [Navigating xMatix: apps, lists and records](/docs/getting-started/navigation/) — how the product is organized and how to find anything. More getting-started pages are being published in the current documentation wave, including mobile-app setup and personalizing your views. ## Who this section is for These pages are written for everyday users. If you administer xMatix for your organization — managing users, security or configuration — the administration guide covers those topics, and the developer section covers APIs and the command-line tools. ## Related topics - [What is xMatix?](/what-is-xmatix/) — a plain-language overview of the platform and its products. - [Implementation guides](/guides/) — longer reads for teams planning a rollout. ---- # Using xMatix on mobile URL: https://xmatix.com/docs/getting-started/mobile-app/ Last reviewed: 2026-09-01 The xMatix mobile app brings your apps, lists and records to your phone or tablet, using the same account you use on the web. It is built offline-first: you can keep working when the connection drops, and your changes sync when you are back online. This page covers getting the app, signing in for the first time, working offline, and reading the sync status. ## Prerequisites - An xMatix account that already signs in on the web — see [Signing in to xMatix](/docs/getting-started/sign-in/). - The app itself, provided by your organization. Your administrator tells you whether your organization uses xMatix on mobile and how to install it. - An internet connection for the first sign-in and the initial download. ## Procedure ### Step 1 — Get the app from your organization Follow only the installation link or managed-app-catalog instructions supplied by your organization. Check the publisher, app name and requested permissions before installing; tenant-branded distribution can differ by organization. Open the app and confirm the xMatix sign-in screen appears. If no instructions were issued, stop and ask the administrator rather than installing an unrelated store listing. ### Step 2 — Sign in with your work account Open the app while connected, enter the exact invited work email and use the same password, one-time-code or passkey method as the web. Complete device verification when prompted. Confirm the expected organization and app navigation appear before allowing data to download; an unexpected tenant means you used the wrong account or invitation, not that a second mobile account is needed. ### Step 3 — Let the first sync finish Keep the app foregrounded, connected and awake during first sync. It downloads permitted apps, layouts, reference data and the configured transaction window. Open sync status and wait until the initial queue is complete with no failed entity. Spot-check one expected customer or item before leaving connectivity; a missing item at this point is usually scope or permission configuration, not an offline fault. ### Step 4 — Work online and offline Use the same lists and touch-friendly forms online or offline. Before a field shift, open the records you expect to need so they are present locally. When connectivity drops, save normally and verify the app marks the change pending; do not repeatedly tap Save. Server-only lookups or posting actions wait for connectivity and should not be interpreted as data loss. ### Step 5 — Check the sync status After reconnecting, open sync status and compare last-sync time, pending count and failed count. Keep the app foregrounded until pending reaches zero. Open every flagged item, read the server validation or conflict, correct and resend—or discard only when the work truly should not reach the server. Confirm a critical record on the web before considering the field work delivered. ## Expected result The user is signed into the intended tenant, initial sync completes without unresolved failures, and expected reference and work records are available locally. Offline saves appear as pending once, then reach zero and become visible on the server after reconnection. ## Common problems If you cannot sign in on mobile, try the web first with the same credentials — if that fails too, it is an account question for your administrator. If a record you can open on the web is missing offline, that is usually the offline scope: the app keeps a configured subset of data on the device, and some record types are online-only. If queued changes are not going out, open the app in the foreground with a working connection and check the sync status for flagged items that need your attention. ## Common questions ### Where do I download the app? From your organization. Your administrator tells you exactly how to install xMatix on your device — the installation route is set up per organization, so follow the instructions you are given rather than searching for the app yourself. If you have no instructions, that usually means your organization has not rolled out mobile access to you yet; your administrator can confirm and arrange it. ### What happens to the changes I make offline? They are saved on your device and queued, then sent automatically when you are back online. If a queued change cannot be applied — the record changed on the server in the meantime, or a validation rule rejects it — the app flags that item in the sync status so you can review it, fix and resend it, or discard it. Until a change has synced, it exists only on your device, so reconnect and check the sync status before you consider the work delivered. ### Will I see the same data as on the web? Your access is the same: one account, one set of permissions, so what you are allowed to see and do on mobile mirrors the web. What is *stored on the device* for offline use is a configured subset — reference data plus recent transactions — so an older or less-used record may need a connection to open even though you have access to it. ## Related topics - [Signing in to xMatix](/docs/getting-started/sign-in/) - [Navigating xMatix: apps, lists and records](/docs/getting-started/navigation/) - [Where to get help](/docs/getting-started/help/) - [xMatix on mobile](/products/mobile/) ---- # Navigating xMatix: apps, lists and records URL: https://xmatix.com/docs/getting-started/navigation/ Last reviewed: 2026-09-06 Everything in xMatix follows the same shape: **apps** group related work, **lists** show the records of one type through a chosen **view**, and each **record** opens into a full page of details, related items and actions. Learn the shape once and every module — Sales, Field Sales, Inventory, Finance, Service — works the same way, because every screen is generated from the same definitions your administrator maintains. ## The building blocks @[guided-image](_img/setup-navigation.png) | Building block | What it is | Example | | --- | --- | --- | | App | A workspace for one area of the business, chosen from the app launcher | Sales, Inventory, Finance | | Entry | One item in an app's top navigation — a record type, a report, a dashboard or a page | Orders, Accounts, Dashboards | | List | All records of one type that your access allows, with search, columns and filters | The Orders register | | View | A saved way of looking at a list — its filters, columns and sorting | All Sale Orders, My open orders | | Record | One item opened as a full page | A single order or customer | ## Switching apps The **app launcher** (the grid icon beside the logo) lists every app you have access to. Type to search apps — and record types inside them — by name, and pin the apps you use every day so they sort first; apps that do not fit the panel sit behind **More**. Choosing an app changes the top navigation to that app's entries and remembers your choice, so you return to the same app next time you sign in. Which apps and entries you see depends on your security profile and licenses, so two colleagues may see different launchers; if something you expect is missing, see [Where to get help](/docs/getting-started/help/). ## Inside an app An app's entries run along the top bar; entries beyond the available width collapse under **More**. Most entries open a list. The list page has a fixed anatomy: - **Breadcrumb and view selector** — the title is the name of the saved view you are looking at (for example **All Sale Orders**), and the arrow beside it switches to another shared view or one of your own personal views. - **Actions** — **New** creates a record; **Edit** and other buttons apply to the current selection; **Ask AI** opens the Sense assistant with this list as context, where Sense AI is licensed for you. - **Recent** — the records of this type you opened most recently, one click away. - **Summary cards** — a few numbers that describe the current view's population and change when the view changes. - **The register** — the records themselves, with a search box, a column chooser, column filters and refresh in its header. Depending on the record type you can also switch the register between a table, a split view (list beside the open record) and a board grouped by status. Use the view selector before search or filters: a record absent from one view may be present in another, while search only narrows the records the view already admits. Column sorting and filtering, and how to save your own view, are covered in [Personalizing lists and views](/docs/getting-started/personalizing/). ## Finding a record The **Search** box in the top bar is context-aware. On a list it searches that record type by name — start typing and matching records appear with a preview on hover; open one to jump to it. Elsewhere it matches record types by name, so typing "inv" offers Invoices and takes you to that list. When you know more than a name, search inside the list and use column filters to narrow by status, date or owner. The **Recent** strip on each list is the quickest route back to something you had open a moment ago. ## Records are where work happens Opening a linked name or document number takes you to the record page: its details laid out as your administrator designed them, tabs for related records (an account's orders, an order's lines and invoices), and the actions that apply to it — save, submit, status changes, printing, and any custom buttons. The actions you see depend on the record's state and on your access: an order offers different actions than a customer, and an approver sees options a viewer does not. Related records open from within the record and can be followed onward; the breadcrumb takes you back. ## Workspace tabs On most organizations the workspace works like a console: each record type keeps its open list and records as **tabs** under the top navigation, and related records opened from inside a record appear as nested tabs within it, so you can keep an order, its account and its invoice open side by side and switch without losing your place. Your administrator can switch the tabbed interface off for the whole organization, in which case links simply navigate and the browser back button returns you. ## Common questions ### Can I change which columns a list shows? Yes. Lists let you choose columns, reorder them, sort and filter, and save the result as a personal view so it is one click away next time. Personal views change only what you see; shared views are published by administrators and keep team-wide lists consistent. See [Personalizing lists and views](/docs/getting-started/personalizing/). ### Why does my colleague see an app or an entry that I don't? Apps, entries and buttons are all subject to your security profile and licenses. Missing apps are usually a license or app-permission question; missing buttons are usually a permission on that record type. Your administrator can check both from your user record. ### How do I get back to something I opened earlier? Three ways: the **Recent** strip at the top of that record type's list, the workspace tab if it is still open, or the top-bar search by name while you are on that record type's list. ## Related topics - [Personalizing lists and views](/docs/getting-started/personalizing/) - [Signing in to xMatix](/docs/getting-started/sign-in/) - [Apps, entities, records and views](/docs/concepts/apps-entities-records/) - [Where to get help](/docs/getting-started/help/) - [What is xMatix?](/what-is-xmatix/) ---- # Personalizing lists and views URL: https://xmatix.com/docs/getting-started/personalizing/ Last reviewed: 2026-09-06 Every list in xMatix can be arranged to match how you work: choose which columns show and in what order, sort and filter the records, pick the view the list should open on, and save an arrangement as a **personal view** you can return to in one click. Everything on this page changes only what *you* see — your colleagues' lists stay exactly as they were, and nothing here changes which records you are allowed to see. ## Prerequisites - A signed-in xMatix session and a list you want to arrange — see [Navigating xMatix: apps, lists and records](/docs/getting-started/navigation/) for how apps, lists and views fit together. - Read access to the record type. Personalizing changes how records are shown; fields your profile cannot read are never offered as columns. ## What you can personalize | Setting | Where | Remembered | | --- | --- | --- | | Which view a list opens on | Star in the view selector (favourite); within a working session the list returns to the view you last picked | Yes — the favourite is durable, the last-picked view lasts for the session | | Visible columns and their order | **Columns** drawer in the register header | Yes, per list, for you | | Sort order | Column header arrows | Yes, per list, for you | | Column filters | Funnel on a column header, or the filter drawer | For the current visit only | | Search text | Search box in the register header | Inside a saved personal view | | Table, split or board layout | Layout toggles in the register header | Yes, per list, for you | | Personal views | **Save current view** in the view selector | Yes — up to 20 per list | ## Procedure @[guided-image](_img/account-view-toolbar.png) ### Step 1 — Open the list and read the current view Open the app and the record type. The list title is the name of the view you are on — for example **All Active Account** — and the arrow beside it opens the view selector. Note the record count in the register header before changing anything, so an over-restrictive filter is easy to spot later. A list opens on your starred favourite view (or the shared default when nothing is starred); while you keep working, leaving for a record and coming back returns you to the view you last picked rather than snapping back to the favourite. ### Step 2 — Choose and reorder columns Select the **Columns** icon in the register header. The drawer lists every column the view can show, with a search box to find one quickly: tick or untick columns, drag them into reading order, and use **Add field…** to bring in a field the view does not list by default. Some lists also offer **Group by** here. **Apply** puts the arrangement in place; **Reset to defaults** returns to the view's own column set. At least one column must stay visible. A field you expect but cannot find is either not on this record type or not readable by your profile. ### Step 3 — Sort and filter Use a column header's arrows to sort, and its funnel to add a condition of the right kind for that field — a status pick, an owner, a date range. Add one condition at a time and watch the record count change; that catches accidental exclusions. The register's search box narrows the filtered result further by the record's name. Sorting and layout are remembered for you; column filters are not — they last for the current visit, so put a filter you use every day into a shared view (ask your administrator) or narrow with search instead. ### Step 4 — Save the arrangement as a personal view Open the view selector and choose **Save current view**. Give it a specific, outcome-based name (up to 60 characters), such as **Customers I own — sorted by last order**. The view stores your search text, sort order, visible columns and column order *on top of* the shared view you started from; saving with a name you already used replaces that view. Each list holds up to 20 personal views, and they are yours alone — they are kept in your user preferences, not in the organization's configuration. ### Step 5 — Switch between views and set a favourite The view selector lists the shared views first, then **Suggested by AI** views when Sense AI has proposed one for this list, then your personal views. Select a view to switch; use the trash icon beside a personal view to delete it. Star a shared view to make it the one this list opens on. After switching, check the view name, record count and visible headers rather than assuming the previous filter still applies — switching views never edits records. ## Expected result The list opens on your favourite view (or, mid-session, the one you last picked) with your columns, order, sort and layout restored; a saved personal view brings back its search, sort and columns in one click. Colleagues see no change. If a personal view seems to show "too many" records, remember that its column filters were not saved — reapply them. ## Common problems If your list looks different from a colleague's, you are most likely on different views or have personalized columns — nothing is wrong. If a shared view changed under you, an administrator updated it for the team; your personal views are untouched, though a personal view built on a shared view inherits that view's new filters. If a column you expect is not offered, the field may not exist on that record type or your profile may not include it. If **Save current view** is missing from the selector, the list you are on does not support personal views (some system registers do not). ## Common questions ### Do my personal views affect what colleagues see? No. Personal views, favourites, column choices and sort orders are stored in your own preferences. Shared views are published by administrators under **Setup → Design Studio → Entities** and are the same for everyone they are shared with. ### Why did my filter disappear when I came back? Column filters are applied for the current visit only; they are not stored in your preferences and a personal view does not capture them. Sort order, columns, layout and your favourite view are remembered. ### Can filtering show me records I normally cannot see? No. Views, filters and columns arrange the records your access already allows — they are a presentation layer, not a permission layer. If a record never appears however you filter, that is an access question for your administrator; see [Where to get help](/docs/getting-started/help/). ## Related topics - [Navigating xMatix: apps, lists and records](/docs/getting-started/navigation/) - [Apps, entities, records and views](/docs/concepts/apps-entities-records/) - [Where to get help](/docs/getting-started/help/) ---- # Signing in to xMatix URL: https://xmatix.com/docs/getting-started/sign-in/ Last reviewed: 2026-09-01 You sign in to xMatix with your work email address. Your organization's administrator sends the invitation; the first sign-in takes a couple of minutes, and after that returning is a single step. ## Prerequisites - An invitation email from your organization's xMatix administrator. - Access to the mailbox for your work email address — sign-in verification codes are sent there. ## Procedure Returning users may first see a remembered-account chooser. Select the intended work identity only on a trusted device; use **Use another account** when the displayed identity is not the invited one. A saved account is a sign-in convenience, not proof that the browser will open the correct tenant, so always verify the workspace after authentication. @[guided-image](_img/sign-in-empty.png) ### Step 1 — Open the invitation Open the latest invitation from your organization's administrator and inspect the destination before following it: the browser should reach the official xMatix sign-in domain over HTTPS. Invitations can expire, so use the newest message. Confirm the page displays xMatix branding and an empty sign-in form; if the domain or certificate is unexpected, stop and contact the administrator. ### Step 2 — Verify your email Enter the work email exactly as invited and choose the enabled method—password or one-time code. For a code, keep the sign-in tab open, retrieve the newest message, and enter the code once before it expires. Never share the code. If no message arrives, check spam/quarantine and confirm the invitation address rather than registering another account. ### Step 3 — Set your password When prompted, create a unique password that satisfies the displayed policy and store it in an approved password manager. Complete the sign-in, then enroll a passkey only on a trusted personal or managed device. Verify the passkey with one successful sign-in before depending on it; keep an approved recovery method available. ### Step 4 — Land in your workspace After authentication, read the organization/workspace name and verify the expected apps appear. Open one permitted non-sensitive list to confirm authorization, then close it. Missing apps indicate role or license configuration, while an unexpected organization indicates the wrong account/tenant—report either without retrying invitations or creating duplicates. ## Expected result The invited work identity authenticates through an approved method and lands in the correct organization with only its granted apps and records. Password recovery and passkey options remain tied to the same account; no duplicate mobile or web identity is created. ## Common problems If the verification code does not arrive, check spam and quarantine folders first, then ask your administrator to confirm the invitation was sent to the right address. If you can sign in but cannot see an app or record you expect, that is an access question for your administrator rather than a sign-in problem. ## Common questions ### Can I sign in on my phone? Yes. xMatix has a mobile app, and your account works in both places — the same email, password or passkey signs you in on the web and on mobile. Your administrator will tell you whether your organization uses the mobile app and where to install it from. Mobile setup is covered in its own getting-started page in this section. ### What happens if I forget my password? Use the reset option on the sign-in page — a verification code is sent to your work email, and after you enter it you can choose a new password. If you registered a passkey, you can keep signing in with it while you reset the password. If your work mailbox itself is inaccessible, contact your administrator. ## Related topics - [Navigating xMatix: apps, lists and records](/docs/getting-started/navigation/) ---- # xMatix Knowledge Center URL: https://xmatix.com/docs/ Last reviewed: 2026-09-01 ## Choose the guide that matches your task Start with the product area and task type: everyday use, administration, customization, troubleshooting or development. The guides below follow that progression. When a page includes a guided image, its numbered markers explain controls that are specific to that subject; when exact clicks or fields matter, the page links to a procedure that states prerequisites, expected results and recovery steps. The Knowledge Center is the documentation home for the xMatix platform: how to use it, how to run it for your organization, how each module works, and how to build on it. Everything below is organized so you can start from your role or jump straight to a module. ## Getting started New to xMatix? Start here — signing in, learning the screens, and working on mobile. - [Getting started with xMatix](/docs/getting-started/) — sign-in, navigation, personalizing views, the mobile app, and where to get help. - [Role guides](/docs/roles/) — curated learning paths for field sales reps, warehouse operators, finance users, administrators, developers and more. ## Administration For the people who run xMatix for their organization. - [Administration guide](/docs/administration/) — users and access, security profiles, record security, restriction rules, licensing, data management, worked security scenarios. ## Platform How the platform itself works and how it bends to your organization. - [Platform concepts](/docs/concepts/) — the ideas the whole platform shares: apps and entities, security, execution order, offline mobile, data lifecycle, AI governance. - [Customization](/docs/customization/) — the no-code-to-code ladder: data model, layouts, business rules, automation scripts, workflows, approvals and expressions. - [Integrations](/docs/integrations/) — connecting external systems: connectors, scheduled sync, health monitoring and credentials. ## Product manuals One section per product, matching the product line-up. - [CRM](/docs/crm/) · [Sales](/docs/sales/) · [Field Sales](/docs/field-sales/) · [Rewards](/docs/rewards/) - [Inventory](/docs/inventory/) · [Procurement](/docs/procurement/) · [Warehouse](/docs/warehouse/) - [Service](/docs/service/) · [Field Service](/docs/field-service/) · [Support](/docs/support/) · [Telephony & Messaging](/docs/engagement/) - [Finance & Accounting](/docs/finance/) · [Tax Center](/docs/finance/tax-center/) · [Payroll](/docs/payroll/) · [Expense Management](/docs/expenses/) - [Commerce](/docs/commerce/) — B2B dealer ordering, [direct-to-consumer selling](/docs/commerce/direct-to-consumer/) and the [screens and records](/docs/commerce/screens/) reference · [Portals](/docs/portals/) · [Mobile App](/docs/mobile/) ## Analytics & AI - [Analytics & Reporting](/docs/analytics/) — reports, dashboards, subscriptions and sharing. - [Data Studio](/docs/data-studio/) — governed datasets, data models, archival and embedded BI. - [xMatix Sense](/docs/sense-ai/) — the AI assistant, the nudge library, AI Studio, Shelf Vision and the Setup Copilot. ## Developer - [Developer documentation](/docs/developer/) — the xMatix CLI, data APIs, the MCP server and connector authoring. ## Help & reference - [Entity reference](/docs/reference/) — every business entity's fields, actions, validations and relationships, and what each one does. - [Troubleshooting](/docs/troubleshooting/) — cross-platform triage and every module's troubleshooting page in one table. - [Frequently asked questions](/docs/faq/) — the questions evaluators and new customers ask most. - [Release notes](/docs/release-notes/) — monthly summaries of what changed, starting September 2026. ## Common questions ### Where should I start if I'm brand new? Start with [Getting started with xMatix](/docs/getting-started/) — it takes you from the invitation email to working comfortably in the product — and then open the [role guide](/docs/roles/) that matches your job, which links the pages worth reading in order. If you administer xMatix for your organization, continue into the [administration guide](/docs/administration/) after that. ### How is this documentation organized? By audience first, then by product. Getting started and the role guides serve everyday users; the administration and customization sections serve the people configuring the platform; each product has its own manual with how-tos, reference pages and troubleshooting; and the developer section covers the programmable surface. Every page states when it was last reviewed. ## Related topics - [What is xMatix?](/what-is-xmatix/) - [Implementation guides](/guides/) - [Engineering blog](/blog/) ---- # Connect an external system URL: https://xmatix.com/docs/integrations/connect-a-system/ Last reviewed: 2026-09-06 This walk-through takes one external system from nothing to a working integration: an app to own it, a secret for its credential, a tested connection, an entity binding, an activated flow, and a first verified run. The same skeleton underlies every integration — including [sync profiles](/docs/integrations/scheduled-sync/), which generate the flow part for you. ## Prerequisites - The integration administration capability, which gates Setup → Process Studio → **Integrations**. Creating an app needs only the capability; everything inside an app also needs a role on that app (creation grants you Admin automatically). - Credentials for the external system — an API key, token, or OAuth client details, depending on the connector. - The name of the xMatix entity you will read from or write to. ## Procedure ### Step 1 — Create the integration app Go to Setup → Process Studio → **Integrations** and select **New**. The creation dialog deliberately asks for one field: **Name**. New apps are Active by default; Active appears when editing the saved app. The API also creates a public id and grants Admin to SystemAdmin plus the caller's resolved security profiles. Give the app a name that identifies the external system and business purpose without embedding a credential. @[guided-image](_img/integration-apps.png) The **New Integration App** dialog above is the whole creation contract: one required Name. Connections, Secrets, Bindings, Flows, Triggers and Members become tabs of the saved app only after the container exists, and the app's **Active** flag (on by default) can be turned off later to stop every run it owns without deleting anything. ### Step 2 — Store the credential as a secret Open the app's **Secrets** tab and select **Add Secret**. Give it a reference name (for example `partner-token`) and paste the value. Secrets are write-only: the value is encrypted, never shown again and never returned by any screen or API. Everywhere else you use the reference — `${secret:partner-token}` — instead of the value. Details and rotation are covered in [credentials and rotation](/docs/integrations/credentials-and-rotation/). ### Step 3 — Create and test the connection On the **Connections** tab select **New Connection**, pick the connector type, and fill in its form — each connector declares its own fields, so a catalog connector shows exactly the inputs it needs, while the generic HTTP/REST connector takes a URL plus headers where you can reference your secret. Then select **Test Connection**. Read the test result for what it actually proves. Credentialed connectors (Salesforce, Zoho) fail the test on bad credentials. The generic HTTP/REST connector counts any non-server-error response as reachable — a 401 or 403 still "passes" — so check the returned status in the details before moving on. ### Step 4 — Bind the entity On the **Bindings** tab, declare which xMatix entity this integration touches and how: direction (Inbound, Outbound or Bidirectional), and write mode (Create, Update or Upsert). Upsert with an external key is what makes re-runs safe — the same external record updates the same xMatix record instead of duplicating it. Bindings can also require approval and staging for inbound data you want reviewed before it is written. ### Step 5 — Build the flow and preview it On the **Flows** tab, create a flow against the binding and give it a draft version. A flow is a step graph—typically source, transform and sink. **Preview** validates the graph, supplies your sample input to source nodes, executes supported pure transforms, and records sink nodes with the input they would receive without executing them. Connector and entity I/O does not occur. Lookup and script preview currently behave as pass-through/no-op transforms, so a successful preview proves graph shape and mapping behavior, not external reachability or full runtime semantics. ### Step 6 — Activate the version Activate the draft. Activation re-validates the graph, deactivates any previously active version (one active version per flow), and freezes the version — an active version is immutable, so later fixes are made in a new draft. This is what makes rollback and "what exactly ran that night" answerable. ### Step 7 — Trigger it and verify On the **Triggers** tab, create a trigger for the flow. For a first smoke test use a Manual trigger and fire it with a small payload; for production, use a schedule (see [scheduled sync](/docs/integrations/scheduled-sync/)) or an entity-event trigger (see [outbound integration](/docs/integrations/outbound/)). Then open the app's **Overview** and confirm the run reached *Succeeded* — and check the records themselves, in xMatix or in the external system, because that is the claim being tested. **Expected result:** the connection test returns the expected status, the active flow run reaches Succeeded, and the intended record appears or changes in the destination system. ## Common problems - **403 opening the app even though you can see the Integrations list.** Listing apps needs only the capability; everything inside an app needs role membership. Ask an app Admin to grant your security profile a role on the Members tab. - **The preview looked right but the real run failed.** Previews execute transforms only. Credentials, reachability and the external system's validation are exercised only by the connection test and a real run — treat the first live run as part of setup. - **Nulls after the mapping step.** The transform's source paths do not match the incoming payload shape. Preview the draft with a captured real payload and fix the paths; for connector reads, also confirm the response's record collection is being extracted rather than the whole envelope. - **Firing a trigger returns "Trigger is paused".** The trigger has its active flag off. Triggers, flows and the app each have independent active flags; all must be on for a run to dispatch. ## Common questions ### Where do the credentials actually live? In the app's secret store, encrypted, bound to that app, and write-only from the moment they are saved. Connections and flow steps hold only `${secret:...}` references, which are resolved at execution time — so exporting or inspecting configuration never exposes a credential, and [rotating a key](/docs/integrations/credentials-and-rotation/) is an in-place update with no configuration edits. ### Do I have to build the flow by hand? Only for bespoke shapes. If the goal is "keep these entities in step with that system", create a [sync profile](/docs/integrations/scheduled-sync/) instead: it discovers the external objects, suggests field mappings, and compiles the flows itself. Hand-authored flows are for everything else — one-way pushes with custom payloads, staged imports with approval, queue and file transports. ### Can inbound data be reviewed before it lands? Yes. Set the binding to require approval (optionally with staging). Inbound runs then park as pending approval with the incoming records visible on the app's Staging tab; an Operator approves or rejects on the Approvals tab, and approval can automatically re-dispatch the parked run so the records are written without re-fetching anything. ## Related topics - [Scheduled sync](/docs/integrations/scheduled-sync/) - [Credentials and rotation](/docs/integrations/credentials-and-rotation/) - [Outbound integration](/docs/integrations/outbound/) - [Troubleshooting integrations](/docs/integrations/troubleshooting/) ---- # Catalog connectors — ClearTax GSP, HubSpot, Shopify, Zendesk URL: https://xmatix.com/docs/integrations/connectors/manifest-apps/ Last reviewed: 2026-08-15 Beyond the engineered connectors, xMatix carries a catalog tier: connectors defined as reviewed configuration for REST partners with standard authentication. To an administrator they use the same picker, generated typed configuration form, [secret references](/docs/integrations/credentials-and-rotation/) and resilient HTTP client as built-in connectors. Their **Test Connection** action is a transport probe: each shipped manifest treats any response below HTTP 500 as reachable, so a green result can include a 401 or 403 and does **not** prove that the credential or business scopes are valid. Confirm those with a safe read as well. ## What a catalog connector provides - **A connection form generated from the connector's declaration** — exactly the fields that partner needs, typed and validated, with secret fields handled as secret references. - **Reads** that fetch the partner's records and hand the record list (not the raw response envelope) to the next flow step. - **Writes** that post a payload to the partner in the shape it expects. - **A test probe** that verifies the configured endpoint can be reached and reports its HTTP status. The current manifests do not treat every 4xx as a failed test. What it does not provide: OAuth token-exchange flows, batch/bulk writes, and paginated multi-page reads. Partners that need those get built-in connectors — which is precisely the boundary between the tiers. ## ClearTax GSP (e-invoicing) For India GST compliance through ClearTax as the GST Suvidha Provider. The current manifest implements two operations: submit an e-invoice to `/einvoice/v2/eInvoice`, and read e-invoice status by IRN. Although the connector's display name mentions e-way bills, no e-way-bill operation is declared in the shipped manifest; do not design a flow around that capability until the manifest adds the endpoint. | Field | Notes | | --- | --- | | GSP host | ClearTax's sandbox or production API host — start on sandbox | | GSTIN | The 15-character GSTIN this connection files for. **One connection per GSTIN** | | Owner id | The ClearTax workspace identifier issued at onboarding | | Auth token | The ClearTax API token, stored as a secret | The one-connection-per-GSTIN rule matters for multi-GSTIN businesses: each registration files separately, with its own credentials, so model each as its own connection. The test calls the configured health path and accepts any status below 500; follow it with a non-destructive e-invoice-status request to prove the owner id, GSTIN and token together. ## HubSpot CRM Reads and writes HubSpot CRM objects — contacts, companies or deals, chosen per connection — over HubSpot's v3 API. Configuration: the object type, a page size, and a **private-app access token** stored as a secret. Writes send the payload as the object's properties, so a flow's transform step maps xMatix fields to HubSpot property names. ## Shopify Admin Reads and writes Shopify **orders** through the Admin API. Configuration: the shop name (the `{shop}` in `{shop}.myshopify.com`), the Admin API version, an Admin API access token (secret), and optionally an order-status filter (any/open/closed) and page size. The typical use is pulling orders into xMatix on a schedule for fulfilment and finance. ## Zendesk Support Reads and writes Zendesk **tickets** over the v2 API. Configuration: your Zendesk subdomain, an agent email, and an API token (secret). Useful for pulling support tickets against customer records, or creating tickets from xMatix events through an [outbound flow](/docs/integrations/outbound/). ## Using them in a flow Catalog connectors slot into [flows](/docs/integrations/connect-a-system/) like any other: a connector-read source pulls the partner's records (already unwrapped to a list), a transform maps fields, and a sink writes into xMatix — or the mirror image for outbound. Reads return one page per run at the configured page size, so for large backfills prefer a one-time [import](/docs/administration/data-management/import-data/) and let the scheduled flow carry the ongoing changes. ## Common questions ### How is this different from the generic HTTP/REST connector? The generic connector is a blank slate: you supply URLs, headers and auth on every use. A catalog connector packages one partner's specifics — host layout, auth scheme, request shapes and where records live in the response — behind a typed form. Required fields are caught in the form, but provider-side credential, scope and payload mistakes still surface in a test read or run. Both paths use the same retry and secret machinery. ### Can these power a sync profile? No — sync profiles require a sync-capable provider (currently the [Salesforce](/docs/integrations/connectors/salesforce/), [Zoho](/docs/integrations/connectors/zoho/) and [Tally](/docs/integrations/connectors/tally/) families). Catalog connectors are used in directly-authored flows: scheduled pulls, event-driven pushes, staged imports. The practical difference is that change detection, conflict handling and the record ledger are yours to arrange — upsert write modes and external keys do most of that work. ### We use a REST system that is not listed — what are our options? Two. Today: the generic HTTP/REST connector reaches any JSON-over-HTTPS API with header-based auth, at the cost of hand-writing the request shapes in your flow steps. Longer-term: partners with clean REST APIs and standard auth are candidates for the catalog — raise it with your xMatix contact, since adding one is a reviewed configuration exercise rather than a product build. ### Is the ClearTax connector all we need for e-invoicing? It is the transport. The connector submits what your flow sends and returns what ClearTax answers; building the compliant e-invoice payload from your invoice data is the flow's transform step, and your ClearTax onboarding (owner id, GSTIN registration, token) is a prerequisite. Plan the payload mapping as part of the implementation. ## Related topics - [Connect an external system](/docs/integrations/connect-a-system/) - [Outbound integration](/docs/integrations/outbound/) - [Credentials and rotation](/docs/integrations/credentials-and-rotation/) - [Integrations overview](/docs/integrations/) ---- # Salesforce connector URL: https://xmatix.com/docs/integrations/connectors/salesforce/ Last reviewed: 2026-08-15 The Salesforce connector is a built-in connector used two ways: directly in [integration flows](/docs/integrations/connect-a-system/) — SOQL reads as a source, record writes and batch upserts as a sink — and as the external system behind [sync profiles](/docs/integrations/scheduled-sync/), where it supports the full bidirectional feature set: inbound, outbound, or both with conflict detection. ## Credentials and connection The service implements Salesforce's OAuth `client_credentials` and legacy `password` grants. The current typed connection form can configure `client_credentials` end to end, so use that path: 1. In Salesforce, create (or reuse) a Connected App with the client-credentials flow enabled, grant the API access it needs, and assign its **Run As** user. Capture the consumer key and consumer secret. 2. Make the Run As user a dedicated integration identity with access only to the objects and fields this connection needs. 3. In the owning integration app, [store the consumer key and secret](/docs/integrations/credentials-and-rotation/). Create the Salesforce REST connection with grant type `client_credentials`, the correct login URL, API version, and the two `${secret:...}` references. 4. Choose **Test Connection**. This connector performs a real token exchange, so rejected credentials fail the test; it does not call a data endpoint, so a pass does not prove object- or field-level access. Follow with schema discovery or a safe read. The service also accepts a raw `password` configuration with username and password-plus-security-token. The Web form currently shows a `refresh_token` choice, but the service does not accept that grant; do not select it until the form and service contract are aligned. A revoked or expired credential is treated as a configuration fault, not a transient error: runs fail with the OAuth error text until the credential is fixed, rather than retrying forever against a locked account. ## In integration flows - **Reads** issue SOQL through the query API — you author the query, so any object and filter Salesforce lets that user see is available. The records collection is handed to the next step ready to map. - **Writes** create, update or upsert records on any sObject, singly or in batches of up to 200 with per-record results — a failed record in a batch is reported individually rather than sinking the batch. - **Inbound keying**: writing Salesforce records into xMatix with the Salesforce `Id` as the external key makes re-runs update the same xMatix rows instead of duplicating them. - The classic pairing is an entity-event trigger pushing xMatix saves out to Salesforce, plus a scheduled flow polling Salesforce changes in — see [outbound integration](/docs/integrations/outbound/). ## In sync profiles Salesforce is the most capable sync provider, and profiles use all of it: | Capability | What it means for you | | --- | --- | | Change feed with deletions | Deltas come from Salesforce's replication feed, which reports both modified and deleted records — so the sync can notice deletions, not just edits | | Watermark on the system modification stamp | Changes are detected on Salesforce's system-level stamp, which also moves on automated updates — a field recalculated by Salesforce itself still syncs | | Roughly 30-day feed depth | The replication feed only reaches back about 30 days. A profile paused longer than that reseeds the affected entities rather than silently missing the gap — expected behavior, visible on the health board | | Keyed upsert by external id | With an external-id field on the Salesforce object holding the xMatix record id, outbound writes match-or-create in one call — re-runs cannot duplicate. Field discovery captures which field to use | | Origin filtering | Delta reads can exclude the integration user's own writes server-side, so the engine re-reads less of its own echo | | Batch size 200 | The ceiling per write call; larger sets are chunked automatically | Schema discovery is live: when you [declare entities and discover fields](/docs/integrations/scheduled-sync/), the object and field lists come from your actual org — standard and custom objects alike, including the custom external-id field if one is deployed. ## Why a dedicated integration user Three reasons, all operational. Origin filtering keys on the acting user, so a shared Run As user would filter out human edits too. Salesforce-side audit trails show exactly what the integration changed. And that user's permissions are the integration's blast radius — scope it to the objects and fields being synced, nothing more. On the xMatix side the profile's sync identity plays the same role with the same reasoning. ## Common questions ### Do custom objects and fields work? Yes. The connector is schema-agnostic: SOQL reads name whatever objects and fields you write, sinks write to any sObject, and sync-profile discovery lists your org's actual schema — custom objects, custom fields and all. The only requirement is that the integration user can see them. ### What happens if someone edits the same record in both systems? In a bidirectional profile, the conflict engine handles it: fields changed on only one side merge through, and genuinely contested fields follow the profile's conflict policy — with field-level merge, they surface as a conflict showing both values side by side for a person to decide. See [sync health and conflicts](/docs/integrations/sync-health/). ### Does deleting a record in Salesforce delete it in xMatix? Only if you ask for that. The replication feed makes deletions *visible* to the sync; whether they propagate is the entity's delete-mode setting, which defaults to None. Delete-versus-edit disagreements always go to a human regardless of policy. ### Sandbox or production first? Sandbox. Point the connection's login URL at your Salesforce sandbox, run the profile until the mappings and conflict policy behave, then repoint credentials and reseed against production. The connection is the only thing that changes. ## Related topics - [Connect an external system](/docs/integrations/connect-a-system/) - [Scheduled sync](/docs/integrations/scheduled-sync/) - [Sync health and conflicts](/docs/integrations/sync-health/) - [Credentials and rotation](/docs/integrations/credentials-and-rotation/) ---- # Tally sync URL: https://xmatix.com/docs/integrations/connectors/tally/ Last reviewed: 2026-08-15 Tally is unlike every other system xMatix connects to: it is a desktop application inside the customer's own network, not a cloud API. The Tally integration is therefore **push-based** — an xMatix add-on loaded into TallyPrime runs on a timer, asks the xMatix service what is needed, and sends the changes. Nothing dials into the customer's network, and Tally's local port is never exposed. In [sync profile](/docs/integrations/scheduled-sync/) terms Tally is a provider like any other; the transport difference shows up mainly in how health is monitored. ## What syncs The current Tally sync is **inbound master data**: Tally → xMatix. | Tally object | Notes | | --- | --- | | Groups | The chart-of-accounts hierarchy | | Ledgers | See the note below — one Tally object, several xMatix entities | | Stock groups and stock items | Including units of measure | | Units | Simple and compound | | Godowns | Tally's warehouse master, mapping to storage locations | | Cost centres and cost categories | | | Currencies | | Vouchers (Tally's transactions — every entry from a sales invoice to a journal) are **not** synced by the current version, and neither is any outbound direction: xMatix does not write into Tally's books. **The ledger note.** A Tally ledger under *Sundry Debtors* is a customer, under *Sundry Creditors* a vendor, and elsewhere a general-ledger account. The sync models this as separate entity declarations sharing the Ledger object, split by a filter on the ledger's parent group — so customers, vendors and GL accounts land in the right xMatix entities. ## How change detection works Tally maintains its own alteration sequence: an integer that increases on every create or edit of a master. The sync uses it as the watermark, which has two pleasant consequences: there is no clock-skew problem (the number is assigned by Tally itself, not read from a desktop clock), and "what changed since last time" is an exact question. Records are keyed on Tally's internal GUID, which survives renames — renaming a ledger updates the paired xMatix record rather than creating a duplicate. Routine Tally housekeeping — rewriting a company, restoring from backup, splitting by financial year — resets that sequence. The connection handshake detects the reset and forces a fresh baseline pass rather than silently syncing nothing from a stale position. Tally deletions leave no trace in the change sequence, so a record deleted in Tally is not detected by the current version; the xMatix record simply stops receiving updates. ## Sites: monitoring a push connection Each Tally installation that reports in is registered as a **site** with its own credential token (rotatable, like any credential). Sites are the reason the [Sync Monitor](/docs/integrations/sync-health/) health board has a Sites column: with a push connection, a stopped client produces *no run and no error* — every conventional signal reads healthy while nothing has synced for a week. The Sites column shows how many sites are reporting and flags any that have gone silent. A silent site nearly always means one of two things: Tally is not running on that machine, or the add-on is not loaded in it. Both are fixed at the Tally end, not in xMatix. ## Requirements - TallyPrime, with the xMatix add-on loaded on each installation that should report. - Tally must be running for data to flow — the add-on lives inside it. Data catches up automatically when Tally reopens, because the sequence watermark marks exactly where it left off. - Site registration and add-on deployment are performed with your implementation team during setup. ## Common questions ### Does xMatix write into Tally? No. The current integration is one-way, Tally → xMatix, and the outbound direction is refused by design rather than merely absent — so a misconfigured profile cannot accidentally post into a customer's books. ### Why is there no schedule on a Tally profile? Because xMatix is not the side that initiates. The add-on inside Tally reports on its own timer; the profile receives. That is also why health for Tally profiles is read from the Sites column rather than from a last-scheduled-run time. ### We restored a Tally backup — is the sync broken now? No, but expect a re-baseline. Restoring (like rewriting or splitting a company) resets Tally's change sequence; the handshake notices and the affected entities re-read from the start. Thanks to the record pairing on Tally GUIDs, the re-read updates existing xMatix records rather than duplicating them. ### Can vouchers or invoices sync from Tally? Not in the current version — masters only. Voucher sync is a different problem (a Tally voucher is a full double-entry document, not a flat record) and is not yet available. ## Related topics - [Scheduled sync](/docs/integrations/scheduled-sync/) - [Sync health and conflicts](/docs/integrations/sync-health/) - [Integrations overview](/docs/integrations/) ---- # Zoho Books, Payroll and People sync URL: https://xmatix.com/docs/integrations/connectors/zoho/ Last reviewed: 2026-08-15 xMatix ships three Zoho connectors — **Zoho Books**, **Zoho Payroll** and **Zoho People** — that plug into [sync profiles](/docs/integrations/scheduled-sync/) as external systems. The shipped Zoho sync is **inbound**: it reads Zoho into xMatix, keeping xMatix records in step with what Zoho holds. That makes it the tool for migrating off Zoho or running xMatix alongside it as the destination of record; it does not push xMatix changes back into Zoho. Declare Zoho entities with direction Inbound. ## Credentials and connection All three products authenticate with Zoho OAuth using a refresh token. Create the connection inside an [integration app](/docs/integrations/connect-a-system/) with: | Field | Notes | | --- | --- | | Client id / client secret | From a Zoho API client registration — store both as [secrets](/docs/integrations/credentials-and-rotation/) and reference them | | Refresh token | Generated for the integration; also a secret. Grant read scopes for the modules you sync | | Data centre | The Zoho region your account lives in (`com`, `in`, `eu`, `com.au`, `jp`, `ca`, `sa`, `ae`, …). OAuth clients are region-bound: a client registered in one data centre is rejected by another | | Organization id | Required for Books and Payroll. These are **different values for the same company** — Payroll has its own organization id; copying the Books one is a classic setup mistake. People needs none | Access tokens are obtained and refreshed automatically, and the correct regional API host is taken from Zoho's own token response — so an account that migrated between data centres still routes correctly. Zoho rate-limit responses are honoured with backoff. ## Zoho Books Books covers contacts and contact persons, items, invoices, credit notes, sales orders, purchase orders, bills, expenses, estimates, customer and vendor payments, chart of accounts, bank accounts, bank transactions, taxes and tax groups, and currencies. The discovery list also exposes journals with a **DO NOT SYNC** warning: importing them is appropriate only for locked-period migration history, because syncing journals into a period where xMatix also posts source documents double-posts the same economics. Document headers are ordinary record declarations. Line detail is available through inbound `Lines` declarations for `invoices/line_items`, `bills/line_items`, `expenses/line_items`, `salesorders/line_items`, `purchaseorders/line_items` and `creditnotes/line_items`. Each changed parent requires a detail API call, every line declaration must map a reference back to its parent, and the parent must run at a lower rank. Invoice, bill and expense response shapes are verified in the implementation; validate the other three against real tenant data before activation because their detail wrappers are still marked provisional in the catalog. Change detection uses Books' last-modified stamp: most modules are read newest-first and the pass stops as soon as it reaches records already synced, so a quiet module costs one page per cycle. A handful of modules publish no usable ordering (chart of accounts, bank accounts, bank transactions, expenses, and the settings collections) — those are read whole each cycle, with the engine's content hash deciding what actually changed. Correct, just heavier, which is worth remembering when choosing a cadence. Per-entity **external filters** are passed to Books as its own native query parameters — for example `status=unpaid` on invoices. Two applied examples: taxes and tax groups share one Zoho collection, split by `tax_type=tax` versus `tax_type=tax_group`; and Books hides inactive rows by default, so add the module's `filter_by` parameter (such as `filter_by=Taxes.All`) when you need them. Books rarely deletes: posted documents are voided, which arrives as an ordinary status change. Keep delete mode None on Zoho entities — an out-of-band deletion in Zoho is not detected. ## Zoho Payroll Payroll modules covered: employees, pay runs, departments, designations, work locations, holidays and salary components. Payroll publishes no modification watermark on any module, so **every cycle reads each module whole** and the ledger's hash comparison finds the changes. That is affordable at payroll volumes on a nightly schedule — put Payroll profiles on a nightly cron, never a 15-minute one, or the re-reads will eat your Zoho organization's daily API allowance. Payroll data is also read-only in spirit as well as direction: a pay run is a signed artifact. The inbound-only design means sync can never mutate one in Zoho. ## Zoho People People is form-based: the external "object" you declare is a **form link name** (for example `P_EmployeeView`), not a table. People offers the cleanest delta of the three — a true modified-since filter — so cycles fetch exactly what changed, in pages of up to 200 records. ## Scheduling guidance | Product | Suggested cadence | Why | | --- | --- | --- | | Books | Hourly | Sorted-scan deltas are cheap, but full-scan modules and the org's daily API budget punish aggressive crons | | Payroll | Nightly | Every cycle is a full scan | | People | 15–60 minutes if needed | True delta filter; cost tracks change volume | ## Common questions ### Can xMatix write back to Zoho? Not through the sync path — Zoho sync profiles are inbound by design, and that is enforced rather than merely conventional. If a specific outbound call to a Zoho API is genuinely needed, it can be hand-authored as an integration flow, but keeping xMatix as the system that receives is the supported shape. ### Which Zoho org id goes in the connection? The one belonging to the product the connection is for. Books and Payroll each issue their own organization id for the same company; using the Books id on a Payroll connection fails requests even though the credentials are right. People connections take no organization id. ### Why did a Books module stop at some records and not others? Check whether the module supports last-modified ordering. Modules that do are read incrementally; those that do not are read whole each cycle. If a specific module's records are missing entirely, also check the entity's external filter — Books ignores unsupported query parameters silently rather than rejecting them, so a mistyped filter narrows nothing while a wrong one can narrow everything. ### What happens when someone deletes a record in Zoho? Nothing, by default — Zoho publishes no deletion feed, and delete mode None (the recommended setting) never propagates deletions anyway. The xMatix record stays. Voided Books documents do sync, as the status change they are. ## Related topics - [Scheduled sync](/docs/integrations/scheduled-sync/) - [Sync health and conflicts](/docs/integrations/sync-health/) - [Credentials and rotation](/docs/integrations/credentials-and-rotation/) ---- # Connection credentials and key rotation URL: https://xmatix.com/docs/integrations/credentials-and-rotation/ Last reviewed: 2026-09-01 Integration credentials — API keys, tokens, OAuth client secrets — live in each integration app's **secret store**. A secret is saved once, encrypted, and bound to its app; from that moment it is **write-only**. No screen, API or export ever returns the value. Everything that needs the credential holds a *reference* (`${secret:name}`) instead, resolved freshly at execution time — which is exactly what makes rotation an in-place update with no configuration edits. ## Prerequisites - The integration administration capability, plus the **Admin role on the app** — secrets are the one part of an app that ConnectionManager does not cover. - The new credential value from the external system, when rotating. ## Procedure ### Step 1 — Store a secret Go to Setup → Process Studio → **Integrations**, open the app that owns the connection, and select **Secrets**. Confirm the app name and your Admin role before choosing **Add Secret**. Use a stable descriptive reference such as `partner-api-token`, paste the value once over a private connection, and save. Reopen the list and verify reference, key id and timestamps appear while the value does not; if the value is ever displayed, stop and report the security defect. ### Step 2 — Reference it Edit each connection or connector step and select or enter `${secret:partner-api-token}` instead of the credential itself. Save, reopen and verify configuration contains only the reference. Search the app's flows and connections for old inline values before activation. One reference may serve several consumers; inventory them because every consumer must be tested during rotation. ### Step 3 — Rotate 1. **Generate the replacement externally first.** Prefer an overlap window and record the old/new key identifiers, owner and rollback deadline. 2. Pause or avoid a high-volume window, open the same secret reference's rotate action, paste the replacement, and save once. Verify the last-rotated timestamp changed; references require no edit or restart because resolution occurs per execution. 3. Run **Test Connection** on every inventoried consumer and preserve the result. A test on only one connection does not prove scopes required by another. 4. Watch one real scheduled or manual read-only cycle on the [health board](/docs/integrations/sync-health/) and verify authentication plus business operation succeeded. ### Step 4 — Revoke the old credential externally Only after every consumer and one live cycle pass, revoke the old key at the provider. Verify a subsequent cycle still succeeds and close the rotation record with timestamps and evidence. If the replacement is mis-scoped, restore the old value under the same reference during the overlap window rather than editing connections. ## Expected result Every connection stores only a write-only secret reference, all consumers resolve the replacement credential without configuration changes, and both connection tests and a live cycle succeed. The former credential is revoked externally only after verification, with an auditable rotation timestamp and rollback evidence. ## OAuth credentials Connectors that authenticate with OAuth ([Salesforce](/docs/integrations/connectors/salesforce/), the [Zoho family](/docs/integrations/connectors/zoho/)) manage their own short-lived access tokens — you never store or rotate those. What you store are the durable pieces: client id, client secret, and the refresh token or integration-user password. Rotate each as its own secret, same procedure. Two behaviors worth knowing: a *revoked* refresh token or deactivated integration user is a configuration fault — runs fail with the provider's OAuth error until you fix the secret, and the platform deliberately does not endlessly retry a credential the provider has rejected; and rotating the *client secret* of a connected/API app usually invalidates refresh tokens minted under the old one, so plan those two rotations together. ## Common problems - **Deleted a secret that was still referenced.** Every connection test and run using the reference now fails at resolution. Re-create the secret under the same reference name with a valid value — the references never changed, so everything recovers immediately. - **Rotated in xMatix before the external system.** Runs fail with auth errors until the external side catches up. No harm done: fix the external side (or paste the old value back) and re-test. - **Rotation "didn't take".** It almost certainly did — check that you rotated the reference the failing connection actually uses (apps can hold several similar-sounding secrets), and read the run's error text, which carries the provider's own verdict. ## Common questions ### Can I read a secret back if I lose it? No — write-only means exactly that; the value is not retrievable by anyone, including platform operators. Losing a credential is handled the same way as rotating it: generate a new one at the provider and upsert it under the same reference. Treat the external provider's console as the system of record for the credential itself. ### Who can manage secrets? Holders of the Admin role on that specific app (membership is granted per security profile on the app's Members tab). Viewer, Operator and ConnectionManager roles cannot add or rotate secrets — ConnectionManager covers connections only. Since secrets are write-only, even Admins only ever see metadata. ### How often should keys rotate? Follow your security policy and the provider's guidance — the mechanics here make rotation cheap, so quarterly rotations or immediate rotation on staff departure are practical rather than painful. The last-rotated timestamp on the Secrets tab is the audit surface: a secret that has never rotated shows it. ### Is the credential exposed anywhere in configuration or logs? Configuration holds only `${secret:...}` references, and run diagnostics redact secret values from step input/output snapshots. The value exists in usable form only inside the executing connector call. ## Related topics - [Connect an external system](/docs/integrations/connect-a-system/) - [Troubleshooting integrations](/docs/integrations/troubleshooting/) - [Security profiles and the grant matrix](/docs/administration/security-profiles/) ---- # Integrating xMatix with other systems URL: https://xmatix.com/docs/integrations/ Last reviewed: 2026-09-01 ## Read the Integration Apps registry @[guided-image](_img/integrations-overview.png) Integration Apps are the ownership boundary for external-system work. An app contains its connections, secrets, bindings, flows, triggers, approvals, staging queues, errors and members, and its active state acts as a kill switch for dispatch. The registry is therefore an inventory of governed integration products, not merely a list of connector credentials. Create one only after naming the external system, data owner, operational owner, security profiles, retry expectations and deactivation plan. Keep secrets out of names and descriptions, test connections separately from business flows, and verify monitoring before enabling schedules or entity events. The screenshot is demo2's genuine empty Integration Apps registry: useful here because this page explains the registry itself, but it is not reused as evidence for connection, flow or sync-profile procedures. xMatix talks to other systems through one integration surface with two levels of control. The **Integration Hub** is the low-level machinery: apps, connections, flows and triggers that move records in and out through connectors. **Sync Profiles** sit on top: a declarative way to say "keep these entities in step with that system" that compiles into Hub flows, adding change detection, conflict handling and a per-record ledger. Both are administered from Setup, and both report into the same monitoring screens. ## The two connector tiers Every connection to an external system uses a **connector** — the component that speaks the other side's protocol. Connectors come in two tiers, and both appear in the same picker when you create a connection: | Tier | What it is | Examples | | --- | --- | --- | | Built-in connectors | Engineered per system, for transports and auth flows that need real logic — OAuth token exchange, bulk APIs, schema discovery, file transfer | Generic HTTP/REST, [Salesforce](/docs/integrations/connectors/salesforce/), the [Zoho family](/docs/integrations/connectors/zoho/), SFTP, message queues | | Catalog (manifest) connectors | Declared as reviewed configuration for REST partners with standard auth — same secrets, retry and typed config form, no custom code | [ClearTax GSP, HubSpot, Shopify, Zendesk](/docs/integrations/connectors/manifest-apps/) | The tier is invisible in day-to-day use: you pick a connector type, fill in its form, test it, and use it in flows. The difference matters only for what a given connector can do — built-in connectors can offer extras like bulk writes and live schema discovery, which the catalog tier does not. ## Integration apps: the unit of ownership Everything in Integration Hub belongs to an **integration app**: connections, secrets, flows, triggers, run history and profile-role assignments. App-scoped endpoints use Viewer, Operator, ConnectionManager and Admin roles. A separate implementation caveat applies to Sync Profiles: their controller currently checks the tenant integration capability but does not enforce the referenced app's membership roles. Treat that as a boundary to remediate and test, not as inherited authorization. Deactivating an app refuses new flow dispatches without deleting configuration. ## Sync flows For ongoing synchronization — rather than a one-off import or a single push — create a **sync profile** (Setup → Process Studio → **Sync Profiles**). A profile declares the external system, the connection, the entities in scope with per-entity direction (inbound, outbound or bidirectional), and the field mappings. It then **compiles** into the Hub flows that execute it. The engine tracks a watermark cursor per entity and direction, pairs records in a ledger, drops unchanged re-reads as echoes, and opens a **conflict** instead of guessing when both sides changed the same field. See [Scheduled sync](/docs/integrations/scheduled-sync/). ## Monitoring Two places, one habit: - Per app: the app's Overview shows recent runs; the Errors tab pre-filters to failures; Staging and Approvals hold anything parked for review. - Across all sync profiles: **Sync Monitor** has Health and Conflicts views. In the profiles-list summary, the value labeled Parked records aggregates record states Conflict, Error and Deferred; the detailed monitor separates those conditions. Do not read that summary number as "explicitly excluded" records. [Sync health and conflicts](/docs/integrations/sync-health/) explains the detailed states. ## Section map | Page | What it covers | | --- | --- | | [Connect an external system](/docs/integrations/connect-a-system/) | App → secret → connection → flow → trigger, end to end | | [Scheduled sync](/docs/integrations/scheduled-sync/) | Sync profiles, entity declarations, mappings and schedules | | [Sync health and conflicts](/docs/integrations/sync-health/) | The monitor screens and how to read a failed run | | [Zoho](/docs/integrations/connectors/zoho/) | Zoho Books, Payroll and People sync | | [Tally](/docs/integrations/connectors/tally/) | Push-based Tally master-data sync | | [Salesforce](/docs/integrations/connectors/salesforce/) | The Salesforce connector in flows and sync profiles | | [Catalog connectors](/docs/integrations/connectors/manifest-apps/) | ClearTax GSP, HubSpot, Shopify, Zendesk | | [Outbound integration](/docs/integrations/outbound/) | How data leaves xMatix, including push-style needs | | [Credentials and rotation](/docs/integrations/credentials-and-rotation/) | Write-only secrets and safe key rotation | | [Troubleshooting](/docs/integrations/troubleshooting/) | Symptom-first fixes | ## Common questions ### Do I need a developer to set up an integration? Not for the common paths. Connecting a system, storing credentials, testing a connection, declaring a sync profile and mapping fields are all administration screens — a flow is authored as a small step graph, and sync profiles generate those graphs for you. Custom transformation logic inside a flow is where technical comfort helps; the [developer documentation](/docs/developer/) covers the programmatic surface. ### Which external systems are supported out of the box? Named connectors ship for Salesforce, Zoho Books, Zoho Payroll, Zoho People, Tally, ClearTax GSP, HubSpot, Shopify and Zendesk. Beyond the named list, the generic HTTP/REST connector reaches any JSON-over-HTTPS API, and SFTP and message-queue connectors cover file and queue transports. The catalog grows by configuration review rather than product releases, so a missing REST partner is a request, not a roadmap item — see [what a catalog connector provides](/docs/integrations/connectors/manifest-apps/). ### What is the difference between an import and a sync? An [import](/docs/administration/data-management/import-data/) is a one-time, file-based load you run and review. A sync profile is standing configuration: it runs on a schedule, detects what changed on each side since the last pass, writes only the differences, and keeps a per-record ledger so the same record is updated rather than duplicated on every cycle. ### Who can see and operate integrations? Two gates stack: the integration administration capability shows the screens, and per-app role membership (granted to security profiles on each app's Members tab) controls what a user can do inside an app — from read-only Viewer up to Admin. A user with the capability but no membership can list apps yet not open them, which is by design. See [security profiles](/docs/administration/security-profiles/). ## Related topics - [Connect an external system](/docs/integrations/connect-a-system/) - [Scheduled sync](/docs/integrations/scheduled-sync/) - [Integration platform overview](/platform/integrations/) - [Import data](/docs/administration/data-management/import-data/) ---- # Outbound integration — how data leaves xMatix URL: https://xmatix.com/docs/integrations/outbound/ Last reviewed: 2026-09-01 This page is intentionally text-only because demo2 has no configured outbound flow or sync contract whose screenshot would prove the behavior below. An empty Sync Profiles register is not evidence of entity-event payloads, connector delivery, retry or loop suppression. Outbound movement is authored as a **flow** delivered through a connector. xMatix does not expose a self-service outbound callback registry where third parties add arbitrary subscription URLs; administrators configure the target connection, trigger and flow. This is narrower than saying the platform has no webhook subsystem: Integration Hub has anonymous **inbound** webhook endpoints and Webhook triggers, including optional HMAC validation and durable ingress recovery. There are three outbound shapes, and choosing between them is most of the design work. ## Shape 1: entity-event flows — push on change An **entity-event trigger** fires a flow when records of an entity are created, updated or deleted. This is the push-style tool: a record is saved, and seconds later a flow is running with that record's identity in hand — typically fetching the full record, mapping it, and writing it to the external system through a connector. The properties that matter: - **The business write commits first.** Trigger failures cannot roll it back or surface as a business-save failure. The post-save handler still performs trigger lookup and queues work after commit, so avoid promising zero response-time overhead; the potentially long flow dispatch is fire-and-forget on a fresh scope. - **The trigger payload is thin**—entity, operation and record id. It does not automatically fetch the record. Add an explicit entity-read/source step when the outbound payload needs current fields, and decide what Delete should send because the row may no longer be readable. - **Loop suppression is origin-specific.** Entity writes made by an entity-event-originated run are suppressed from firing more entity-event triggers, including across its queue boundary. Scheduled, inbound-webhook and manual runs are deliberately allowed to cascade into entity-event flows, so design and test those chains for bounded behavior. - You can scope the trigger to specific operations (for example Create and Update but not Delete). If the requirement reads "call the partner's API whenever an order changes", this is the shape — with the partner-specific connector, or the generic HTTP/REST connector when the target is an arbitrary API endpoint. ## Shape 2: scheduled outbound flows — push on cadence A schedule trigger runs an outbound flow on a cron cadence: read the xMatix records in scope (filtered as needed), map, and write out in batches. This fits targets that want feeds rather than events — nightly exports, hourly batch upserts, systems that rate-limit per call and prefer 200 records at once. Batch-capable connectors ([Salesforce](/docs/integrations/connectors/salesforce/)) report per-record results, so one bad record fails alone rather than sinking the batch. ## Shape 3: outbound sync — a standing contract When the need is "that system should continuously reflect these entities", stop authoring flows and declare a [sync profile](/docs/integrations/scheduled-sync/) with outbound (or bidirectional) entities. The profile compiles the flows itself and adds what hand-authored pushes lack: watermark cursors so each cycle sends only what changed, a per-record ledger pairing xMatix records with their external counterparts, echo suppression so nothing ping-pongs, and [conflict handling](/docs/integrations/sync-health/) when the other side edited too. ## Delivery, retries and idempotency Outbound runs inherit the integration runtime's failure handling: transient faults can retry with backoff and deterministic faults wait for a fix. Manual replay is limited to Failed, Succeeded, DeadLettered and Rejected runs. It requires a surviving flow definition with an active version and either an explicit request body or retained archived InputJson; it runs through the currently active version rather than resurrecting an immutable old executor. Because delivery can repeat after ambiguous timeouts, design the destination for stable-key idempotency. Rapid successive edits to the same record dispatch independent runs, so strict cross-run ordering should not be assumed — another reason keyed upserts (last write of the current state) beat "create a new row per event" designs. ## Common questions ### Can an external system be notified the instant something changes in xMatix? Effectively yes: an entity-event flow fires on save and delivers within seconds through whatever connector you point it at. What xMatix does not offer is self-service subscriptions — the notification is an admin-authored flow inside xMatix, not a URL the external party registers themselves. In practice that is the governance difference, not a latency difference. ### Can xMatix POST to an arbitrary URL? Yes — the generic HTTP/REST connector takes a URL, headers (including secret-referenced auth) and a payload your flow constructs, used as the sink of an entity-event or scheduled flow. The URL is part of reviewed connection configuration, held by the integration app. ### What happens when the target system is down? The business record is already committed before dispatch, so a connector failure does not roll it back. The integration side records or logs the failed dispatch, retries eligible transient categories and dead-letters exhausted work. After recovery, replay only an eligible terminal run with retained input and a valid active flow version, or let a sync profile retry from the cursor that did not advance past uncommitted work. ### Should I push deletes? Cautiously. Entity-event triggers can fire on Delete, and sync entities have delete modes — but the default everywhere is not to propagate deletion, because a wrong delete is the one mistake the other system cannot un-make. Prefer status fields ("cancelled", "inactive") that sync as ordinary updates, and reserve true delete propagation for pairs of systems where you have thought through recovery. ## Related topics - [Connect an external system](/docs/integrations/connect-a-system/) - [Scheduled sync](/docs/integrations/scheduled-sync/) - [What runs when you save a record](/docs/concepts/execution-order/) - [Integration platform overview](/platform/integrations/) ---- # Set up a scheduled sync URL: https://xmatix.com/docs/integrations/scheduled-sync/ Last reviewed: 2026-09-06 A **sync profile** is standing configuration: "keep these entities in step with that external system, on this schedule." You declare the entities, their direction and their field mappings; the profile **compiles** into the integration flows that execute it. On every cycle the engine reads only what changed since its last position (the watermark), pairs records through a ledger so nothing is duplicated, drops unchanged re-reads as echoes, and opens a [conflict](/docs/integrations/sync-health/) instead of guessing when both sides edited the same field. This is a different thing from a Mobile Sync Profile, which governs offline data on devices — the two share a word, not a mechanism. ## Prerequisites - The integration administration capability. - An [integration app with a tested connection](/docs/integrations/connect-a-system/) to the external system. The profile references that app and connection and its generated runs belong there. Current Sync Profiles API endpoints are gated by the tenant integration capability but do not enforce the referenced app's Viewer/Operator membership, so do not describe app roles as an additional sync-profile authorization boundary until that is implemented and verified. - A **sync identity**: the xMatix user the engine reads and writes as. Record-level security bounds what that identity can see, so the profile can never sync more than this user can. Use a dedicated, deliberately-scoped user rather than a person's account. ## Procedure @[guided-image](_img/sync-profiles.png) The **New Sync Profile** dialog asks for Name, Integration app, Connection (enabled once an app is chosen), External system, Sync identity (user id) and an optional six-field UTC Schedule; the Sync Profiles page behind it also shows the Profiles, Active, Open Conflicts, Parked Records and Falling Behind counters you will watch later. Entities, field mappings, status and detailed policy are deliberately absent from this first dialog and are configured on the saved profile's tabs. ### Step 1 — Create the profile Go to Setup → Process Studio → **Sync Profiles** and choose **New Profile**. Give it a specific name, then select an existing integration app, one connection that belongs to that app, the provider and a dedicated sync identity user id. The API verifies app/connection ownership, provider registration, schedule syntax and profile-name uniqueness. Read any provider capability note before saving: no change watermark means full scans, and no delete feed requires a reconciliation sweep. Creation deliberately returns a Draft profile and navigates to its detail page. ### Step 2 — Declare the entities On **Entities**, add one declaration at a time and record its xMatix entity, live external object and direction. Start with **Delete mode: None** unless an approved design proves propagation safe. Add source filters, conflict policy and rank; run **Apply derived ranks** and verify parents precede children. Save and review the declaration matrix for accidental bidirectional scope or unbounded data before mapping. ### Step 3 — Map the fields Use **Discover fields**, inspect every proposal's confidence and rationale, and apply only semantically equivalent fields. On **Mapping**, set direction, transforms and conflict-ignore flags deliberately; audit stamps often belong outside conflict checks, business fields do not. Test value maps, nulls, dates and identifiers with representative samples. Confirm required target fields are populated and sensitive fields are absent before compile. ### Step 4 — Compile Select **Compile**, read every error and warning, and fix the declaration at source. Compile again until the result is accepted and note the generated/versioned flows. An unchanged recompile should write nothing and never move watermarks or history; verify that property before treating compile as safe repeatable configuration. ### Step 5 — Set the schedule and activate On **Schedule**, enter a six-field UTC cron expression—seconds first—and translate the intended business time into UTC, including daylight-saving policy where relevant. Review overlap window and estimated cycle duration; the cadence must not continuously overlap. Leave it blank at creation for manual-only profiles. Current edit behavior has an important limitation: the web form sends `null` when an existing schedule is cleared, while the controller treats `null` as "leave unchanged." After any attempt to make a scheduled profile manual-only, reopen it and verify the Schedule value. Until that path is corrected, pause/deactivate the profile or use a supported PATCH that sends an empty string rather than assuming the blank UI saved. The **overlap window** (default 120 seconds) rewinds the watermark slightly on every pass to absorb clock differences between the two systems; the re-read is cheap because unchanged records are dropped as echoes. Set status **Active** only after compile and schedule review, then verify the Active count on the profiles screen increments and the next-run time matches the intended cadence. ### Step 6 — Watch the first cycles Watch the first cycle from start to completion. Reconcile records in/out, echoes, conflicts, deferrals and failures to the expected sample; inspect the profile's watermark lag and a few paired ledger records. Confirm a second cycle drops unchanged echoes and does not duplicate records. Do not leave the profile unattended with failures or an unbounded baseline. ## Expected result The profile's saved detail shows the intended status and schedule, compile has no blocking errors, and active cycles process entities in dependency order and advance watermarks. Initial and repeat cycles reconcile to expected counts, unchanged echoes are dropped, and conflicts or failures remain visible. For manual-only profiles, explicitly verify Schedule is empty after reopening because a cleared edit can otherwise retain the old cron. ## Common problems - **The profile is Active but nothing runs.** Check the saved schedule is six fields, status and active flag permit execution, generated flows have an active version, and the owning app is active. Schedules do not fire in sandbox tenants. If you recently cleared a schedule, reopen the profile—the current null-update path can leave the old cron stored instead of making it manual-only. - **It runs but syncs nothing.** Three usual causes, in order: the sync identity cannot see the records (record security silently scopes the sync — widen the identity deliberately); the entity declarations are inactive; or an entity needs a reseed, shown on the health board, meaning its incremental position cannot be trusted until a fresh baseline pass. - **Records sync once, then stop.** Look for the record on the profile's **Records** tab. A record parked as Excluded was deliberately stopped (usually via "Ignore always" on a conflict) and stays stopped until you select **Resume**. ## Common questions ### What stops an update loop between the two systems? Content hashing. Every synced record's mapped fields are hashed at each successful sync; a record that comes back unchanged — including the engine's own write echoing back — matches the stored hash and is dropped before anything else is considered. Convergence therefore does not depend on timestamps, clocks, or the other system reporting who wrote what. ### What happens when both sides change the same record? Fields changed on only one side propagate normally under every policy — a disputed field does not discard unrelated edits. Genuinely contested fields follow the profile's conflict policy: field-level merge (recommended) opens a conflict listing only the contested fields for a human decision; the one-side-wins policies decide automatically and record that they did. Deletes contested by edits always go to a human. See [sync health and conflicts](/docs/integrations/sync-health/). ### How fresh is the data? As fresh as the schedule: a 15-minute cron means changes land within roughly 15 minutes plus the run time. The engine is schedule-driven — it does not subscribe to instant change feeds from external systems. For pushing xMatix changes outward the moment they happen, an entity-event flow is the near-real-time tool — see [outbound integration](/docs/integrations/outbound/). ### Can I sync only a subset of records? Yes — per entity, on either side. The xMatix filter scopes which xMatix records are in play, and the external filter is passed to the external system in its own query dialect. Both are part of the declaration, so compile after changing them. ## Related topics - [Connect an external system](/docs/integrations/connect-a-system/) - [Sync health and conflicts](/docs/integrations/sync-health/) - [Zoho connector](/docs/integrations/connectors/zoho/) - [Salesforce connector](/docs/integrations/connectors/salesforce/) ---- # Sync health, conflicts and failed runs URL: https://xmatix.com/docs/integrations/sync-health/ Last reviewed: 2026-08-15 This page is intentionally text-only on demo2: the Sync Monitor has no populated profiles, cycles, conflicts or record ledger to illustrate. An empty board would show navigation without proving any of the operational states described below. Watching sync run is an operations job, so it has an operations home: **Sync Monitor**, at Setup → Platform Operations → Monitoring → **Sync Monitor**, with a **Health** tab ("is anything wrong?") and a **Conflicts** tab ("what needs a decision?"). Each sync profile's own detail page carries the same panels scoped to itself, plus its cycle history and per-record ledger. ## The Health board One row per profile. The columns, and what each is actually telling you: | Column | What it means | | --- | --- | | Status | The profile lifecycle: Draft, Seeding, Active, Paused or Failed | | Watermark lag | How long ago the oldest active cursor advanced. Judged against the profile's own schedule — a nightly profile is not flagged for being an hour old. *Never run* means no cursor exists yet, which is a brand-new or never-seeded profile, not a healthy one | | Last cycle / result | When the last cycle ran and how it ended: Running, Succeeded, PartiallyFailed, Failed or Cancelled | | Failed streak | Consecutive failed cycles. One failure is noise; a streak is an outage | | Open conflicts | Records frozen awaiting a human decision (see below) | | Parked / deferred | The monitor separates records held by a conflict or error from records deferred while a reference is unresolved. On the Sync Profiles list, however, the single **Parked records** total aggregates Conflict, Error **and** Deferred states; use the monitor when you need the distinction | | Reseed required | Entities whose incremental position cannot be trusted — no completed baseline stands behind the cursor — so "nothing changed" means nothing until they are reseeded | | Sites | Only for push-based systems (such as [Tally](/docs/integrations/connectors/tally/)), where a client inside the customer's network sends the data. A site that stops reporting produces no run and no error — this column is the only place that silence becomes visible | The **Needs attention** filter collapses all of that into the day's worklist. From a row, **Open conflicts** jumps to the Conflicts tab scoped to that profile. ## The Conflicts inbox A conflict is a record the engine refused to decide for you. Each row carries a kind: | Kind | What happened | | --- | --- | | Both changed | Both systems changed the same field(s) since the last sync | | Delete vs update | One side deleted the record while the other edited it — always a human decision, under every policy | | Duplicate key | An outbound write collided with an existing external record's key | | Reference unresolved | The record points at something that has no synced counterpart | | Validation rejected | The receiving side refused the write — including guards such as re-opening a record in a terminal status | Expanding a row shows only the contested fields, three columns side by side: the base value at last sync, the xMatix value, and the external value — with the sides that moved highlighted. That is the whole decision, laid out. Resolution actions, per row or in bulk (**Resolve selected**, with a note stored against your user): - **Keep xMatix** — the xMatix values for the contested fields are pushed out on the next cycle; the external edit is discarded. - **Keep external** — the mirror image: the external values are written into xMatix. - **Merged by hand** — you reconciled the values yourself in the records; the engine writes nothing, and if the sides still disagree the conflict reopens next cycle. - **Ignore once** — closes the conflict without writing; the record keeps syncing and will reopen if the disagreement persists. - **Ignore always** — closes the conflict *and parks the record as Excluded*, stopping it from syncing in either direction until someone selects **Resume** on the profile's Records tab. A conflict's **detection count** is a queue-age signal: the engine keeps one open conflict per record and bumps the count each cycle the disagreement is re-seen — a high count means the record has been blocked for that many cycles while nobody decided. ## The Records tab: per-record state The profile's **Records** tab is the ledger explorer — the pairing between each xMatix record and its external counterpart. Record statuses: In sync, Pending out, Pending in, Conflict, Error, Deferred, and Excluded (parked). Search by either side's key to answer "what is the sync doing with this exact record", and use **Resume** to un-park an Excluded record. ## Reading a failed run Sync cycles execute as integration runs, so diagnosis drills from the profile into the Hub: 1. On the profile's **Cycles** tab, find the failing cycle. Its counters — records in/out, echoes dropped, conflicts opened, deferred, failures — usually name the symptom already. 2. Open the owning integration app and check the **Errors** tab (the run list pre-filtered to Failed and DeadLettered). Every run carries its latest error; the error's category classifies it: a deterministic failure, a transient one (retried automatically with backoff before dead-lettering), retries exhausted, an orphaned run reaped by the sweeper, or an operator cancellation. 3. Drill into the run's steps. Failed executions capture each executed step's input and output; successful executions do so only when the flow enables **Capture step data**. Values are secret-redacted, and the snapshots are retained for a configured window (30 days by default), so an older run can legitimately have no step data. When present, the snapshots show *which* step broke and with what data: credentials and reachability point at the connection, nulls after the mapping step point at field paths, a 4xx from the connector points at the external system, and a validation message means xMatix itself refused the write. 4. Fix accordingly, then use **Replay** only when the original status is **Failed**, **Succeeded**, **DeadLettered** or **Rejected**. The original flow version must still exist, and replay needs either an explicitly supplied body or the original run's archived `InputJson`. Dispatch resolves that version's flow definition and executes its currently active version, so a repaired mapping can apply to the retained payload. A run still inside its automatic retry window is not replay-eligible and should be left alone. Auth failures are deliberately not auto-retried — a rejected credential cannot heal by retrying. They persist until someone [rotates or fixes the credential](/docs/integrations/credentials-and-rotation/). ## Common questions ### What is watermark lag, exactly? Each synced entity and direction keeps a cursor: the position in the change stream up to which everything has been durably processed. Watermark lag is the age of the oldest such cursor on the profile. It is the primary health signal because it measures outcome, not activity — a profile can be running on time and still fall behind if its passes keep failing before the cursor advances. ### Why does a profile show healthy cycles but sync nothing? The usual causes: the sync identity's record security has narrowed what the engine can read (it syncs only what that user can see); every read is being dropped as an echo because nothing actually changed; or — for push-based systems — the client on the other side stopped sending, which is exactly what the Sites column exists to reveal. ### Do conflicts block the whole sync? No. A conflict freezes *that record* in both directions; every other record keeps flowing. That is also why the backlog deserves attention — each open conflict is one record standing still, and the detection count shows for how long. ### PartiallyFailed — is that bad? It means the cycle completed but some entities or records inside it failed; the succeeded portion is committed and cursors advanced only where work was actually done. Treat it as a pointer into the Errors tab rather than an outage — but a *recurring* partial failure on the same entity is a real fault to chase. ## Related topics - [Scheduled sync](/docs/integrations/scheduled-sync/) - [Troubleshooting integrations](/docs/integrations/troubleshooting/) - [Credentials and rotation](/docs/integrations/credentials-and-rotation/) ---- # Troubleshooting integrations URL: https://xmatix.com/docs/integrations/troubleshooting/ Last reviewed: 2026-09-01 This page is intentionally text-only. demo2's Sync Monitor currently has zero profiles and zero diagnostic rows, so its screenshot would show navigation but no symptom, failing cycle, conflict or step evidence. Use the live monitor named below when an actual incident exists; do not substitute an empty console image for troubleshooting proof. Work from the symptom. Each section below opens with the most likely cause, then the rest in order of likelihood — and almost every diagnosis starts in the same two places: the app's run history and the [Sync Monitor](/docs/integrations/sync-health/). ## A scheduled flow or profile never runs Most often the cron expression. Schedules are **six fields with a leading seconds field** (`0 */15 * * * *`), in UTC. On integration triggers, an invalid expression — classically a five-field cron — is accepted on save but silently skipped on every tick, so the trigger sits active and never fires. Re-save the trigger with six fields. Then check the active flags, because three stack: the trigger, the flow's version (exactly one active version must exist — a schedule dispatching a flow with no active version fails the run), and the app itself. Also note: schedule triggers do not fire in sandbox tenants, and downtime is not backfilled — after an outage only the latest matured occurrence fires once. ## "You don't have access to this integration app" You have the capability (you can see the list) but no **membership** on this app. Access inside an app is granted per security profile on its Members tab — Viewer, Operator, ConnectionManager or Admin — and new apps start with only the creator and system administrators. Ask an app Admin to grant your profile a role; to *decide approvals* you need Operator or higher, and to manage secrets, Admin. ## The connection test passes, but runs fail with authentication errors For the generic HTTP/REST connector this is expected behavior, not a contradiction: its test proves *reachability* — any non-server-error response passes, including a 401. Open the test details and read the returned status; a 401/403 there means the credential is wrong even though the test shows green. Credentialed connectors (Salesforce, Zoho) genuinely fail their test on bad credentials, so for them a passing test plus failing runs points elsewhere — usually at permissions on the specific records or objects, or at a [credential rotated on one side only](/docs/integrations/credentials-and-rotation/). ## A run failed and I need to know why Read it in three layers on the app's **Errors** tab. Start with category and message. Transient faults can retry with backoff, deterministic failures wait for correction, retries-exhausted work dead-letters, and the orphan sweeper handles runs that never reached a terminal state. Then inspect steps. Step status and errors are always useful, but input/output snapshots exist only when `captureStepData` was enabled for that flow version and the retention sweeper has not removed them; redaction does not create a snapshot that was never captured. Fix the cause before replay. Replay accepts only Failed, Succeeded, DeadLettered or Rejected runs. It needs the original flow definition to still have an active version, plus an explicit body or retained archived InputJson. The new run uses the current active flow version and is linked to the original; it does not execute a deleted historical version merely because that version id remains on the old row. ## Inbound records are duplicating The write is not keyed. An inbound sink without an external key (or with write mode Create) inserts on every run; with **Upsert plus a stable external key** — the source system's record id — re-runs update the same records instead. If duplicates already exist, clean them up first, or the keyed writes will keep updating one of each pair while the others sit stale. Sync profiles do this pairing automatically through their ledger, which is one reason to [prefer a profile](/docs/integrations/scheduled-sync/) for standing synchronization. ## A sync profile runs green but records are not syncing In likelihood order: 1. **The sync identity cannot see them.** The engine reads and writes as the profile's sync identity, bounded by record security — a narrowed identity silently stops syncing what it cannot read. Widen that user's access deliberately. 2. **An entity needs a reseed.** The health board's "Reseed required" column means the cursor has no trustworthy baseline behind it; reseed the entity from the profile. 3. **The records are parked.** Check the profile's Records tab: Excluded records were stopped by an "Ignore always" conflict resolution and stay stopped until resumed; Error records show their last failure inline. 4. **Nothing actually changed.** Echo suppression drops re-reads whose content hash matches the last sync — a cycle full of echoes writes nothing and is healthy. 5. **For push-based systems ([Tally](/docs/integrations/connectors/tally/)): the site went silent.** No run, no error — only the Sites column shows it. The fix is at the client end. ## The same conflicts keep reopening Someone is resolving them without changing the facts. **Merged by hand** records your claim that you reconciled the values yourself — the engine writes nothing, so if the two sides still disagree, the same conflict is redetected next cycle. Either pick a side (Keep xMatix / Keep external, which actually writes), genuinely align the records, or — if this record should simply stop syncing — use Ignore always and accept the parking. A rising detection count is the tell that a conflict is being closed cosmetically rather than decided; a rising *backlog* suggests the conflict policy is stricter than the data needs — field-level merge resolves edits to different fields without human traffic. ## Inbound runs park as "pending approval" and nothing lands The entity binding requires approval — by design. An Operator decides on the app's Approvals tab; approving with **auto-replay** left on re-dispatches the parked run's archived input so the records are written without re-fetching. Approving *without* auto-replay closes the approval but writes nothing, which is the usual cause of "we approved it and still no data". Parked runs are eventually reaped as failed by the orphan sweeper; the approval remains decidable, and approving with auto-replay still recovers the work. ## Everything from one app failed at once A shared dependency moved. In order: a [secret was rotated or deleted](/docs/integrations/credentials-and-rotation/) while still referenced (resolution failures on every run that uses it); the external system revoked the credential (auth errors that do not self-heal — deliberately not auto-retried); or the app was deactivated, which stops schedules and refuses dispatches as its kill switch. The app's Errors tab timestamps make the "at once" moment easy to correlate. ## Common questions ### Does a failed integration ever affect users saving records? An integration failure cannot roll back the business write because entity-event handling occurs after commit and dispatch runs separately. The post-save handler still scans active trigger configuration and queues matching work, so it can add some post-save latency even though connector execution is not coupled to the response. Failures may be visible only in run history or logs, which makes [monitoring](/docs/integrations/sync-health/) essential. ### Is it safe to just replay a failed run? Only after checking eligibility and idempotency. Do not replay a non-terminal run or one still inside its automatic retry window. Confirm archived input is retained (or supply the intended body), a current active version exists, and downstream writes are keyed. For batch runs without per-item completion evidence, replay can reapply the full batch. ### When should I pause versus deactivate? Pause the single trigger (its active flag) to stop one flow; deactivate the app to stop everything it owns — schedules stop, dispatches are refused. Both preserve all configuration, watermarks and history, and neither cancels runs already in flight; those are cancelled individually. Deletion is the only destructive option and takes the app's whole contents with it, so treat it as last resort. ## Related topics - [Sync health and conflicts](/docs/integrations/sync-health/) - [Credentials and rotation](/docs/integrations/credentials-and-rotation/) - [Connect an external system](/docs/integrations/connect-a-system/) - [Where to get help](/docs/getting-started/help/) ---- # Adjusting stock URL: https://xmatix.com/docs/inventory/adjustments/ Last reviewed: 2026-09-06 A stock adjustment corrects on-hand inventory when the system's figure and reality disagree for a known reason: goods were damaged, a batch expired, a shelf count came up short or over, stock was put on hold or lent out. The adjustment is a document — partner account, branch, date, and one line per correction — and it changes nothing until it is posted. At posting, each line becomes an entry in the [inventory ledger](/docs/inventory/ledger/) like any other movement, so the correction, who made it and what it changed are all on record. ## When to use an adjustment — and when not to Use an adjustment when you already know the discrepancy and its cause. Use a **cycle count** instead when the question is "what do we actually have?" — counting is the scheduled program that measures stock and, when its variances are released, generates the adjustment for you with the count linked as evidence (see [Cycle counting](/docs/warehouse/cycle-counting/)). Adjustments are also generated automatically when a part-to-part claim or claim batch is approved, so not every adjustment in the register was typed by hand. This page covers the document itself, which is what every one of those paths ends in. ## Prerequisites - Access to the **Inventory** app (the **Adjustments** entry in its navigation) through your security profile. Posting is a separate entity action, so a profile can allow creating and editing adjustments without allowing **Post Inventory**. - The partner account (the stock-owning company) and branch whose stock is being corrected — both are required and fixed once the adjustment is created. - Items with **Track Inventory** set. A line for a non-tracked item is rejected at posting. For items with **Track Lots** set, the lot being adjusted — a lot-tracked line without a lot is rejected. - Optionally a price list and a price-as-on date, if line unit costs should default from your purchase pricing. ## Procedure @[guided-image](_img/inventory-adjustment-list.png) **Inventory → Adjustments** opens the register (default view **All Adjustments**). The summary cards count the last 30 days' documents as Draft or Adjusted; the table shows document number, document date, partner account, branch, executive and status. Use the search and column filters to find a document before opening it — the document number links to the record, and **New** in the header starts a fresh adjustment. ### Step 1 — Create the adjustment @[guided-image](_img/new-inventory-adjustment.png) Click **New**. The form asks for **Partner Account**, **Branch** and **Document Date** (defaulted to now), plus an **Additional Details** group with **Price List**, **Executive** and **Price As On Date**. Check partner account and branch against the count sheet or incident evidence before saving: neither can be changed afterwards, and neither can the document date — a wrong branch means a new document. If you leave the price list empty it defaults to the default purchase price list, and changing **Price As On Date** later re-prices every line from that list. ### Step 2 — Add lines @[guided-image](_img/inventory-adjustment-lines.png) On the saved adjustment, the **Lines** tab lists the adjustment lines and lets you add them. Each line carries one correction for one item, SKU, lot and storage location: | Field | What to enter | |---|---| | Adjustment Type | Leave empty for a plain correction, or pick the reason: `Excess`, `Shortage`, `Damaged`, `Expired`, `OnHold`, `OnLoan`, `Assemble` or `Disassemble`. The type decides which stock bucket the posting moves — see below. | | Item, SKU | What is being corrected. | | Item Lot, Item Lot Type | Required for lot-tracked items; identifies the exact batch or serial. | | Storage Location | The bin holding the stock, where your branch uses locations. | | Quantity | The magnitude of the correction. For an untyped line the sign matters: positive adds stock, negative removes it. For typed lines enter the quantity found damaged, expired, short, over, held or lent — the direction is implied by the type. | | Unit Cost | Defaults from the matching price-list rule (an adjustment is costed as a purchase-side line); a value typed on a new line is kept. It becomes the unit cost on the ledger entry. | | Remarks | Free text for the evidence reference. | Keep one line per item/lot/location and per reason. Two causes on the same stock — say three damaged and two missing — are two lines, not one netted figure, because each type posts to its own bucket and reports on damage or expiry depend on that. The saved rows show line number, type, item, SKU, lot, storage location, quantity and unit cost, so the whole document can be reconciled against the evidence before posting. `Assemble` and `Disassemble` lines are special: they explode the item's bill of materials into generated component lines of the opposite type, so assembling one kit adds the kit and removes its components in one document. Only the parent line is entered by hand. ### Step 3 — Post to the ledger Review the lines, then run **Post Inventory** from the record header (the *Perform Inventory Posting* action). It posts every line that does not yet have an **Inventory Ledger** reference and stamps the created ledger entry onto the line. Retrying is safe — already-posted lines are skipped — and when nothing is left to post the action stops with *No Adjustment Lines found for Inventory Posting*. What posting does per line: it writes the ledger entry, moves the matching stock bucket at the branch (and the lot's counters for lot-tracked items) and hands the movement to the costing engine. A movement that would take the stock bucket negative is rejected with an *Insufficient stock* message naming the bucket, and nothing is written for that document. Correct the quantity, lot or storage location on the line and post the same document again rather than raising a duplicate. Two controls on the form are not what they look like. The **Perform Inventory Posting** and **Inventory Posted** check boxes on the Details tab are never set by the posting code, and the **Post Inventory** button offered on an individual line has no server behavior — post from the document header only. The definitive proof that a line reached the ledger is its Inventory Ledger reference. ### Step 4 — Verify Open the ledger entry from a posted line, or find the document in **Inventory → Inventory Ledgers**, and confirm source document, branch, lot, storage location, signed quantity and ledger type. Then read the item's balance on **Inventory Stock** to confirm the bucket moved as intended. Later corrections must appear as reversal-and-replacement pairs; the original entry stays. @[guided-image](_img/inventory-adjustment-details.png) The **Details** tab holds the saved header: **Key Information** (partner account, branch, executive, price list, status), **Claim Details** and **Inventory Details** (document date, the originating cycle count where there is one) and **System Information**. It is where you confirm provenance — a cycle count or claim reference means the document was generated, not typed. It does not replace line-level verification. ## What each adjustment type does to stock | Adjustment type | Effect at posting | |---|---| | *(empty)* | Positive quantity increments the positive-adjusted bucket; negative quantity increments the negative-adjusted bucket. Both count fully in available and in-hand stock. | | `Excess` | Adds the quantity to the excess bucket — stock found over the book figure. | | `Shortage` | Adds to the shortage bucket — stock found under the book figure; reduces available stock. | | `Damaged`, `Expired` | Adds to the damaged or expired bucket; reduces available stock, and the reason survives into reporting. | | `OnHold` | Moves stock to the on-hold bucket: still present, no longer available to promise. | | `OnLoan` | Moves stock to the on-loan bucket: lent out, no longer available. | | `Assemble` / `Disassemble` | Books the produced kit (and, through generated component lines, consumes or returns its components). | Each type posts its own ledger entry type, which is why a single document can move stock in both directions and still say why. ## Expected result Each posted line changes only its intended branch, item, lot and location, receives an Inventory Ledger reference, and shows up as one entry (per type) in the ledger with the adjustment line as its source document. Later edits to a posted line's quantity or unit cost — or deleting the line — post reversal entries automatically and, for edits, fresh entries for the new values; the originals remain. ## Common problems **Wrong branch or document date.** Both are locked after creation; create a new adjustment. If lines were already posted on the wrong document, delete or reverse them there first (each deletion posts a reversal) so stock is not corrected twice. **"Insufficient stock" on posting.** The bucket you are decreasing does not hold that much. The usual cause is a line pointing at a different lot or storage location than the one that actually holds the stock — compare the line with the item's stock row before changing the quantity. **Lot required.** The item has **Track Lots** set; add the lot to the line. **"No Adjustment Lines found for Inventory Posting."** Every line already carries a ledger reference. To correct a posted document, edit the posted line (which posts a reversal and a replacement) or raise a new adjustment. **Status looks wrong.** The Draft / Adjusted badge is a convenience label; the posting action neither requires nor updates it. Trust the lines' Inventory Ledger references. ## Common questions ### Can one adjustment both increase and decrease stock? Yes. Lines carry their own type — excess for stock found over, shortage for stock found under, damaged and expired for write-downs with a recorded reason, plus untyped signed corrections — so one document can correct in both directions. Each type posts as its own ledger entry type. ### How do cycle counts and adjustments relate? A cycle count is the measuring program; an adjustment is the correcting document. When a count's variances are released, xMatix creates an adjustment for the count's partner account and branch with one untyped line per discrepancy and separate `Damaged` and `Expired` lines where those were recorded, each carrying the count line's item, SKU, lot, storage location and unit cost. The count is linked on the adjustment's Details tab, and from there the document is posted exactly as described here. ### Why did an adjustment appear that nobody created? Approving a part-to-part claim (or a claim batch) generates an adjustment that writes the approved quantity back into stock, with the claim linked under **Claim Details**. Post it like any other adjustment. ## Related topics - [The inventory ledger](/docs/inventory/ledger/) - [Transferring stock between branches](/docs/inventory/transfers/) - [Item lots and lot types](/docs/inventory/lots/) - [Cycle counting](/docs/warehouse/cycle-counting/) - [Troubleshooting inventory](/docs/inventory/troubleshooting/) ---- # Inventory configuration reference URL: https://xmatix.com/docs/inventory/configuration/ Last reviewed: 2026-09-06 Inventory configuration in xMatix has three layers. The **inventory ledger settings** define which document lines post which stock movements — platform-managed and read-only, with a setup screen that exists so you can *see* the rules. The **item master flags** decide, item by item, whether stock is kept at all and how finely. The **valuation configuration** — accounting books and valuation policies — is yours to author and holds the consequential choices: which books each company keeps and which costing method applies to which stock. This page is the reference for all three, plus the engine-written records you should know not to touch. ## Inventory ledger settings @[guided-image](_img/inventory-ledger-settings-list.png) **Setup → Feature Hub → Inventory → Inventory Ledger Settings** lists the posting rules that connect document lines to the [inventory ledger](/docs/inventory/ledger/). The list shows each rule's **Name**, **Label**, **Entity**, **Parent Entity**, **Ledger Type**, **Active** flag and audit columns; the **View** action opens the remaining fields. Each rule defines one posting behavior: | Field | Meaning | |---|---| | Entity / Parent Entity | The document line the rule watches, and the header document it takes partner account and branch from (a rule without a parent treats the line as its own header). | | Ledger Type | The movement type the posted entry carries — `Inward`, `Sold`, `TransferOutward`, `Adjustment`, `Damaged` and so on. | | Quantity Field | The line field whose value is posted as the movement quantity (a cancelled-quantity field on the line, when present, is subtracted first). | | Incremental / Decremental Quantity Field | The stock and lot counters the quantity is added to or subtracted from — for example `TransferInward`, `Damaged`, `PendingDeliveries`. | | Condition | A formula the line must satisfy for the rule to fire, such as `AdjustmentType == "Damaged"` or `TransferType != "Pending Deliveries Transfer"`. | | On Create / On Update / On Delete | Which save events trigger the rule. Nearly every seeded rule is *update and delete only*, which is why documents post through an explicit action rather than on creation, and why edits and deletes post reversals. | | Sequence | Ordering among rules for the same entity and ledger type — unique within that scope. | | Active | Whether the rule is in force. | The screen is view-only: the rules ship as platform configuration and cannot be created, edited or deleted from the front end. Their value to an administrator is diagnostic — when you need to know why a document type posts (or does not post) a particular movement, the answer is a row here. The seeded set covers goods receipt and inspection lines, bill lines, delivery order lines, invoice lines, credit note lines, adjustment lines, the three kinds of transfer line, fulfilment allocation and picking lines and shipment lines; the [ledger page](/docs/inventory/ledger/) lists the ledger types each posts. ## Item master flags that govern stock keeping Several settings on the item itself decide how inventory treats it. They are edited on the item record's **Details** tab — the **Inventory Settings**, **Behaviour** and **Specification** groups (**Warehouse** app → **Items**, or **Settings** → **Items** in the Inventory, Sales, Procurement and Service apps; see [Items](/docs/inventory/items/)): | Flag | Effect | |---|---| | Track Inventory | The item keeps stock balances and posts ledger movements. Services, charges and other non-stock items leave it off; a line for such an item is skipped by posting. | | Track Lots | Stock is held per item lot; every stock-moving line must name a lot. See [Item lots and lot types](/docs/inventory/lots/). | | Track Asset | Units become serialized asset records after receipt or sale; requires Track Lots. | | SKU Required | Every line must carry one of the item's SKUs; stock balances are then kept per SKU. | | Maximum Lot Quantity | Caps how much a goods receipt may put into a single lot (a SKU-level value takes precedence). | | Inspection On Receipt | Received quantity is held as pending inspection until inspected; the receipt cannot complete while any line has uninspected quantity. | | Primary Unit Of Measure, UOM decimal precision | The base unit stock is expressed in, and the rounding applied to derived quantities. | The item's own **ABC Category**, **FSN Category** and **Inventory Valuation** fields are descriptive labels that no inventory process reads; the operative classification lives on item inventory attributes (see [Item classifications](/docs/inventory/item-classifications/)) and the operative costing method comes from valuation policies (below). **Item lot types** — the commercial grades carried on lines and lots — are maintained in the Inventory settings or Warehouse Settings app; see [Warehouse configuration](/docs/warehouse/configuration/). ## Accounting books @[guided-image](_img/accounting-book-list.png) Accounting books and valuation policies belong to the **Finance Setup** app. Where that app is not on a user's launcher, an administrator maintains them; the lists can also be reached through search. An accounting book is authored per company: | Field | Meaning | |---|---| | Partner Account | The company (legal entity) the book belongs to. | | Book Type | `Statutory`, `Tax` or `Management`. | | Gaap Framework | Indian, international or US standards — governs which cost-flow methods are acceptable. | | Is Primary | The book inventory-cost posting uses and the only one that persists cost layers; the general ledger the statements post to. Keep exactly one active primary per company — the model does not enforce uniqueness, and posting takes the first it finds. | | Is Active | Inactive books are skipped by cost posting. | | Currency | The book's currency. | | Allows LIFO / Allows Standard Cost | Recorded opt-ins for methods a framework restricts. They document the decision; nothing blocks a policy at save time if they are off. | A company with no active primary book has its stock movements posted but not costed — the costing hook returns silently and the valuation statement has no layers to report. ## Valuation policies @[guided-image](_img/valuation-policy-list.png) A valuation policy selects a costing method for a scope within a book. The list shows **Name**, **Valuation Method**, **Costing Level**, **Is Default**, **Is Active** and **Effective From**; the form (see [Inventory valuation and costing](/docs/inventory/valuation/)) has three tabs — Accounting Period, Item & Valuation, Controls — with the scope keys above them. | Field | Meaning | |---|---| | Accounting Book | The book the policy belongs to — resolution happens within one book. | | Valuation Method | The engine resolves the exact tokens `FIFO`, `LIFO`, `MovingAverage`, `WeightedAverage` and `SpecificIdentification`; anything else falls back to `MovingAverage`. The seeded picker offers `Weighted Average` and `Moving Average` with a space, and does not offer specific identification — confirm the stored value. | | Costing Level | A stored descriptor. Cost pools are always keyed by book, item, branch and method; this field does not create batch-, serial- or location-level pools. | | Partner Account, Business Unit, Branch, Item, Item Group, Storage Location | Scope keys; empty means wildcard. Inventory-cost posting resolves with company, branch and item only, so business unit, item group and storage location never match at posting time. | | Effective From / To | The movement-date window the policy applies to; only the start is required. | | Priority | Tie-breaker between equally specific policies (lower wins). Not on the current form layout. | | Is Active | Only an explicit *off* excludes the policy. | | Is Default | Stored, not read by the resolver. | **Resolution:** candidates are filtered to the book, active policies and the effective window; each non-empty scope key must equal the movement's value. Specificity is scored item +16, item group +8, storage location +4, branch +2, business unit +1; the highest total wins, ties go to the lower priority number and then the later Effective From. A fully unscoped active policy is the book-wide fallback; with no match at all the engine uses moving average. **Checks to perform yourself before activating.** Validation helpers exist for the rules below, but the standard save path does not call them, so a contradictory policy can be saved: | Rule | Why | |---|---| | One active primary book per company | Cost posting takes the first active primary it finds. | | No LIFO for Ind AS / IFRS books | Those frameworks do not permit LIFO. | | Specific identification only with lot-tracked items | The method costs the exact lot each movement names. | | No overlapping policies of equal specificity | Resolvable by priority and date, but hard to audit. | | Effective To not before Effective From | An inverted window never matches. | ## Engine-written records — leave them to the engine **Inventory Cost Lots**, **Inventory Cost Consumptions**, **Inventory Opening Lot States** and **Book Valuation Adjustments** are written by the costing engine and rebuilt wholesale whenever a scope is replayed. They are derived state: editing them by hand only makes the stored rows disagree with the algorithm until the next posting overwrites them. Read them through the **Valuation lots** and **Consumption lots** drills on the Inventory Valuation page. **Inventory NRV Assessments** are the exception: no product process computes them today, so if your organization applies lower-of-cost-and-NRV, the rows (estimated selling price, cost to complete, cost to sell, write-down or reversal for the run, fiscal period) are entered against the entity. Period close then posts a journal for each assessment in the period without one and the valuation statement subtracts the outstanding write-down from cost. ## Common questions ### Why can't I edit the inventory ledger settings? Because they define stock truth. A changed posting rule silently changes what every future document does to inventory, so the rules ship as managed platform configuration rather than tenant-editable data. If a posting behavior genuinely needs to differ for your organization, raise it through your implementation or support channel. ### Which book do valuation screens use when I don't pick one? The primary book. The Inventory Valuation page shows a book picker only when the company has more than one book; cost posting always uses the first active primary book for the company. Because uniqueness is not enforced, verify that exactly one active primary exists before trusting the implicit selection. ### Where do I switch lot tracking or inventory tracking on? On the item record — **Track Inventory** and **Track Lots** are item flags, not module settings. Turning Track Lots on for an item with existing untracked stock does not create lots for that stock; plan the change with an adjustment or receipt that establishes the lots. ## Related topics - [Inventory valuation and costing](/docs/inventory/valuation/) - [The inventory ledger](/docs/inventory/ledger/) - [Item lots and lot types](/docs/inventory/lots/) - [Item classifications](/docs/inventory/item-classifications/) - [Warehouse configuration](/docs/warehouse/configuration/) - [xMatix administration guide](/docs/administration/) ---- # xMatix Inventory URL: https://xmatix.com/docs/inventory/ Last reviewed: 2026-09-06 xMatix Inventory tracks what stock you hold, where it is, and what it is worth. Its backbone is the **inventory ledger**: every movement — a receipt, a shipment, a transfer, an adjustment — is recorded as a posted entry, and on-hand stock is the running position those entries have moved rather than a number anyone types. On top of the ledger sit branch-to-branch transfers with a real in-transit state, stock adjustments, lot-level tracking, a perpetual costing engine that values stock under the method your accounting policy chooses, and period balances that roll it all up for comparison. This section explains each piece and the screens where you work with it. ## Where the screens live Inventory work happens in the **Inventory** app. Its navigation bar carries the documents you create and the statements you read: | Navigation entry | What it is for | |---|---| | **Fulfilment Orders** | The fulfilment documents that allocate and pick stock for orders; covered in the warehouse and sales documentation. | | **Inventory Overview Dashboard** | A dashboard page your administrators author for the app in Design Studio; what it shows is whatever they placed on it, so its tiles are a summary view, not a system of record. Read balances and values on Inventory Stock and Inventory Valuation. | | **Transfers** | Move stock between branches or companies: outward release, in-transit tracking, inward receive and posting. | | **Adjustments** | Correct on-hand stock with a document — damage, expiry, shortage, excess, hold, loan — and post it to the ledger. | | **Inventory Stock** | The **Stock Balance** statement: available quantity per item for a company, compared by branch, period or year, with drills into lots and the item ledger. | | **Inventory Valuation** | The **Valuation Statement**: quantity and carrying value per item and accounting book, with drills into cost layers and consumptions, and a rebuild of the period-balance cache. | | **Inventory Ledger** | The append-only list of every posted movement, each linked to the document line that produced it. | | **Reports** | The report library, including the inventory movement analyses. | | **More → Dashboards, Settings** | Further dashboards and the Inventory settings list, including item lot types. | Two lists you will use are not on the navigation bar: **Item Lots** (open from a lot link on a document or ledger entry, from search, or through a stock figure's *Item lot details* drill) and **Item Inventory Attributes** (the per-branch classification and replenishment rows). Accounting books and valuation policies — the configuration that decides *how* stock is valued — belong to the **Finance Setup** app, and the read-only inventory ledger settings live under **Setup → Feature Hub → Inventory**. Both are covered in the [configuration reference](/docs/inventory/configuration/). ## What this section covers The pages are ordered so that each builds on the ones before it: - [The inventory ledger](/docs/inventory/ledger/) — the concept everything else rests on: every movement is a posted entry, corrections post reversals, and the Inventory Stock page is where you read balances. - [Transferring stock between branches](/docs/inventory/transfers/) — the two-document transfer: outward release, the in-transit state, inward receive and posting, the selective variants and the single-step alternative. - [Adjusting stock](/docs/inventory/adjustments/) — correcting on-hand quantities with an adjustment document, the reason types, and when an adjustment is the right tool versus a cycle count. - [Item lots and lot types](/docs/inventory/lots/) — batch- and serial-level tracking: what a lot records, which fields the platform maintains, and how lots follow stock through movements. - [Inventory valuation and costing](/docs/inventory/valuation/) — perpetual costing from the ledger, cost layers and consumptions, accounting books, valuation policies, the Inventory Valuation page and the engine's current limits. - [Inventory period balances](/docs/inventory/period-balances/) — how the ledger rolls up into per-period opening, inward, outward and closing figures in quantity and value. - [Items (the item master)](/docs/inventory/items/) — creating and maintaining items: the required fields, the stock and behaviour flags, units of measure, packages, and why a new item starts inactive. - [SKUs (item variants)](/docs/inventory/skus/) — the variants of an item: adding them, SKU Required, how stock, lines and pricing rules follow the SKU. - [Item classifications](/docs/inventory/item-classifications/) — the ABC and FSN categories, where they are stored, and where auto-ordering, cycle counting and reports read them. - [Inventory configuration reference](/docs/inventory/configuration/) — for administrators: the inventory ledger settings, the item-master stock flags, and the valuation configuration. - [Troubleshooting inventory](/docs/inventory/troubleshooting/) — what to check when stock or valuation looks wrong, and what a closed period blocks. ## Three rules that hold everywhere - **Nothing moves stock until it is posted.** Creating an adjustment, a transfer or their lines records intent only. Stock changes when the document's action runs (**Post Inventory**, **Release Outward**), and the reliable proof that a line reached the ledger is its **Inventory Ledger** reference — not a status label. - **Posted entries are never edited.** Correcting a posted line makes the ledger add negated reversal entries and fresh entries for the new values; the originals stay. Read pairs of opposite entries as history, not as errors. - **A movement that would take a stock counter negative is rejected.** The posting fails with an *Insufficient stock* message naming the counter, and nothing is written. The fix is always on the source document — quantity, lot or location — never on the ledger. ## Who can do what Access to the Inventory app and its screens is granted through the user's security profile and the app's page permissions, like every other xMatix app. Posting, release and receive are entity actions, so a profile can allow a user to create and edit documents without letting them post. Accounting books and valuation policies sit in Finance Setup and normally belong to finance administrators. If a user cannot see a screen described here, start with [why a user can't see something](/docs/administration/user-cant-see-x/). ## Where Inventory ends and neighboring modules begin Inventory owns stock truth: the ledger, transfers, adjustments, lots and valuation. Warehouse operations that act on that stock — cycle counting, picking, putaway, receiving at the bins and fulfilment execution — are covered in the [warehouse documentation](/docs/warehouse/), and replenishment — reorder rules and automatic purchase suggestions — in the [procurement documentation](/docs/procurement/). Goods receipts and sales shipments post their stock effects through the same inventory ledger described here, so the reading skills from this section apply everywhere. ## Related topics - [xMatix Inventory product overview](/products/inventory/) - [xMatix Warehouse documentation](/docs/warehouse/) - [xMatix Procurement](/products/procurement/) - [xMatix documentation home](/docs/) ---- # Item classifications: ABC and FSN URL: https://xmatix.com/docs/inventory/item-classifications/ Last reviewed: 2026-09-06 xMatix items carry two standard inventory classifications: **ABC**, which ranks items by value contribution, and **FSN**, which ranks them by movement speed (fast, slow, non-moving). They are maintained attributes — your team sets them, by hand, import or integration; xMatix does not recompute them — and the platform reads them in two places: automatic purchase-order generation can exclude categories, and cycle counts can scope their item population by them. Reports use them as analysis dimensions. Because those features match the stored text exactly, the value that matters is the one on the **item inventory attribute** for the branch, spelled exactly as listed below. ## Where the classifications live @[guided-image](_img/item-classification-details.png) The **Item** record's **Details** tab has a **Classification** section with **Item Type**, **Item Sub Type**, **Item Segment**, **Item Family**, **ABC Category** and **FSN Category**. These item-wide values are descriptive: no inventory process reads the item master's ABC or FSN category (its seeded FSN vocabulary is even different — `F category`, `S category`, `N category`). Use them as a label for people and reports, not as the control. @[guided-image](_img/item-inventory-attributes-list.png) The **Item Inventory Attributes** list (reachable from the Inventory app's search or the entity's list) is the operative register: one row per item, optionally narrowed by SKU, lot type, partner account and branch, carrying the classification alongside the branch's replenishment policy — minimum and maximum stock level, minimum and maximum order quantity, lot quantity, reorder quantity, lead time and average consumption. An empty partner account or branch means the row applies to all. @[guided-image](_img/item-inventory-attribute-detail.png) Open a row to see its sections: **Information** (partner account, branch, item, SKU, lot type — the scope), **Classification** (minimum and maximum stock level, ABC and FSN category, minimum and maximum order quantity), **Order Suggestions** (reorder quantity, reorder level, suggested order quantity) and **System Information**. Check the scope before interpreting a category: a correctly spelled value on the wrong branch is still the wrong input. | Location | What it holds | Who reads it | |---|---|---| | Item master | Item-wide ABC and FSN labels. | Nobody in code; reporting and people. | | Item inventory attribute | Per-branch (and per-SKU) ABC and FSN alongside replenishment data. | Auto purchase orders, cycle counts, reports. | The branch-level attribute is the one that matters because the same item can legitimately be an A-category fast mover in one branch and a C-category slow mover in another, and replenishment and counting respect that. ## The values | Classification | Values on the attribute | Meaning | |---|---|---| | ABC | `A Category`, `B Category`, `C Category` | Value contribution: A items carry the most working capital and deserve the most attention. | | FSN | `Fast-Moving`, `Slow-Moving`, `Non-Moving` | Movement speed, from items that turn constantly to items that have stopped moving. | The attribute's FSN picker also offers the item-master vocabulary (`F category`, `S category`, `N category`). Auto-order exclusions compare against the hyphenated values only, so use those; a cycle count filter matches whatever text you type into it exactly. ## Where they are used | Feature | How the classification is used | |---|---| | Auto purchase-order exclusions | An auto-order run carries six exclusion flags — exclude A/B/C-category items and exclude fast/slow/non-moving items. An item whose branch attribute matches a flagged category is skipped when the run proposes lines. Typical use: keep `Non-Moving` items out of automatic replenishment so the program does not reorder dead stock. See [xMatix Procurement](/products/procurement/). | | Cycle count scope | A count's scope filters include an ABC class and an FSN class; the count's item population is filtered to attribute rows with exactly that value, treating rows with no partner account or branch as wildcards. This is how count programs give A-category and fast-moving items more frequent attention. See [Cycle counting](/docs/warehouse/cycle-counting/). | | Reports | The report library includes an **FSN–ABC–Branch Inventory Movement Analysis**, and both categories are available as grouping and filter dimensions when building your own reports. | ## The rest of the attribute row The classification shares its row with the branch's replenishment policy, and not every field on that row is read today: | Field | Read by | |---|---| | Minimum Stock Level | Min/max replenishment: a purchase suggestion is raised when available stock falls below it. | | Reorder Quantity | The fixed quantity proposed when min/max triggers; when zero the engine orders up to the minimum stock level instead. | | Minimum / Maximum Order Quantity | Enforced on purchase-order lines (a line outside the range is rejected); the forecast reorder point adds the minimum, and forecasting orders up to the maximum. | | Lot Quantity | A purchase-order line whose quantity is not a multiple of it is rejected. | | Lead Time, Average Consumption | Forecast reorder point = lead time × average consumption + minimum order quantity. Average consumption is an input you maintain, not computed from history. | | Maximum Stock Level, Reorder Level, Suggested Order Quantity | Stored and shown, but read by no process today. Validation only checks that maximum stock is not below minimum stock. | ## Maintaining the classifications honestly Because the platform reads but does not compute these attributes, they are only as good as their upkeep. A workable pattern: run the movement-analysis report on a fixed cadence (quarterly is common), decide reclassifications from the evidence, and apply them by import to the branch-level attributes. Treat a reclassification as the operational change it is — moving an item to `Non-Moving` typically also means excluding it from auto-ordering and reducing its count frequency, and those are exactly the features that read the new value. ## Common questions ### Does xMatix compute ABC or FSN automatically? No. The classifications are attributes your organization maintains; the platform's role is to *use* them consistently — in auto-order exclusions, cycle count scoping and reports — and to give you the movement reporting from which to decide them. Stale values are acted on faithfully, which is why a review cadence matters. ### The item shows one category but the branch behaves differently — why? Auto-ordering and cycle counting read the item **inventory attribute** for the branch, not the item master's classification. The two can differ on purpose. When behavior surprises you, check the attribute row for the item and branch first — and check the spelling: `Non-Moving` is matched, `N category` is not. ### Why is an item ignored by auto-ordering although its category is not excluded? Check for a second attribute row: rows with an empty branch apply to every branch, so an all-branch row carrying an excluded category can catch an item whose branch-specific row does not. ## Related topics - [xMatix Procurement](/products/procurement/) - [Cycle counting](/docs/warehouse/cycle-counting/) - [Inventory configuration reference](/docs/inventory/configuration/) - [The inventory ledger](/docs/inventory/ledger/) ---- # Items (the item master) URL: https://xmatix.com/docs/inventory/items/ Last reviewed: 2026-10-10 An item is the master record for anything you buy, sell, stock or service — a product, a spare part, a charge, a unit of work or a service contract — and every document line in xMatix points to one. Orders, quotes, invoices and delivery orders on the sales side; requisitions, purchase orders, goods receipts and bills on the purchase side; transfers, adjustments and cycle counts in inventory; and service orders all name an item on each line. You create an item once, before anyone can put it on a document. Its flags then decide what happens downstream: whether stock is kept, whether lots, serial numbers or SKUs are required, whether received goods wait for inspection, and whether the item explodes into a package of components. Prices, discounts and taxes are not typed on the item; they are rules that point at it. ## Overview The item record has three kinds of content: - **Identity and classification** — **Name**, **Code**, **Item Type**, **Description**, **HSN/SAC Code** and descriptive groupings such as **Item Sub Type**, **Item Segment** and **Item Family**. - **Behaviour flags** — **Track Inventory**, **Track Lots**, **Track Asset**, **Inspection On Receipt**, **SKU Required**, **Package**, **Only Sold In Package**, **Active** and others. These are what processes actually read. - **Related records** — the item's SKUs, units of measure, package components, lot types, alternates, per-branch inventory attributes, price list rules, tax group rules, stock balances, lots and service contracts. Each is its own record, listed on a tab of the item. The item itself stores no selling price, cost or tax rate. Prices come from dated price list rules, discounts from discount group rules and tax from tax group rules — see [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/). ## When to use it Create an item for every distinct thing that appears on a document line, whether or not it is physical: - **Product** or **Part** — goods you stock, buy and sell. - **Charge Item** — a non-stock charge such as freight or a fee. - **Work Item** — labour or a unit of service work. - **Service Contract** — a contract sold as a line. - **Discounted Item** — a line that takes value off a document rather than adding to it. Do not create separate items for versions of one product that only differ in colour or pack — use [SKUs](/docs/inventory/skus/). Do not create items for batches or serial numbers — use [item lots](/docs/inventory/lots/). Do not create items for a case versus a single unit — add a unit of measure to the item. ## How xMatix handles it - **A new item starts inactive.** **Active** is off by default, and every document line rejects an inactive item with *Item is Inactive.* Switch **Active** on when the item is ready to be used — on the New dialog, on the record, or in your import file. - **Code is the unique key.** **Code** is required and must be unique across your organization. There is no automatic numbering for items; you type the code. - **Every line checks the item.** When a line is added to an order, invoice, delivery order, fulfilment order, purchase order, requisition, goods receipt, inspection, bill, automatic purchase order, adjustment, transfer, cycle count, service order or opportunity, xMatix checks that the item is active, that a SKU is present when the item requires one, and that the SKU belongs to the item. - **Item Type shapes the form.** The **Inventory Settings** group is hidden for **Work Item** and **Service Contract**. On the New dialog, **ABC Category** and **FSN Category** are hidden for Product, Work Item and Service Contract, **Registration Required** shows only for Product and Discounted Item, and **Allow Service** is hidden for Work Item, Charge Item and Service Contract. - **A Discounted Item never moves stock.** When you save an item of type **Discounted Item**, xMatix switches **Track Inventory** off. - **Track Asset needs Track Lots.** Saving an item with **Track Asset** on and **Track Lots** off fails with *Tracking assets requires tracking lots.* - **Some values are copied onto lines.** The item's **Name** fills the line description on order, invoice, opportunity, purchase order and bill lines. Its **HSN/SAC Code** fills a blank HSN/SAC code on invoice and bill lines, and replaces it when the line's item changes. - **Quantities follow the item's units.** A line can be entered in an alternate unit; xMatix converts it to the primary unit using the item's conversion ratios and rounds it to **Primary UOM Decimal Precision**. ## Prerequisites - Your security profile grants create access to items (see [Permissions](#permissions)). - You have decided the item's **Code**, its **Item Type**, and whether it keeps stock, needs lots or serial numbers, and needs SKUs. The stock flags are easiest to get right before the first transaction. - For India GST, you know the item's HSN (goods) or SAC (services) code. ## Procedure ### Step 1 — Open the Items list The **Items** list is on the navigation bar of the **Warehouse** app. In the **Sales**, **Inventory**, **Procurement** and **Service** apps it is under **Settings**. The list opens on a view such as **All Items**; the other shipped views are **All Active Products**, **All Products**, **All Parts** and **All Work Items**. **All Active Products** also shows summary cards for total products, active products, asset-tracked, package and lot-tracked items. ### Step 2 — Create the item Select **New**. The **Create Item** dialog asks for: 1. **Name**, **Code**, **Description** and **HSN/SAC Code** at the top. **Name** and **Code** are required. 2. **Classification** tab — **Item Type** (required), **Item Sub Type**, **Item Segment**, **Item Family**, and where shown **ABC Category** and **FSN Category**. 3. **Inventory Settings** tab — **Track Inventory**, **Track Lots**, **Track Asset**, **Inspection On Delivery**, **Inspection On Receipt** and **Repair Order On Receipt**. 4. **Behavior** tab — **Package**, **Only Sold In Package**, **Active**, **Discontinued**, **Registration Required**, **SKU Required** and **Allow Service**. 5. **Specification** tab — **Primary Unit Of Measure**, **GTIN** and **RF**. Switch **Active** on unless you want to finish setting the item up first. Save. The item record opens. ### Step 3 — Complete the details The record opens on the **Details** tab, whose groups hold every field from the dialog plus a few more: - **Service** — **Service Duration(Minutes)**, **Subscription Duration(Months)**, **Service Rate Basis** and **Markup Rate (%)**. - **Specification** — **Inventory Valuation**, **Maximum Lot Quantity** and **Primary UOM Decimal Precision** in addition to the unit, GTIN and RF. - **System Information** — who created and last changed the item, and when. Select **Edit**, fill what applies, and save. ### Step 4 — Add units of measure, SKUs and other related records Open the **Related** tab. Each list there has a **New** button: - **SKUs** — the item's variants. See [SKUs](/docs/inventory/skus/). - **Item lot types** — the commercial grades the item's lots can carry. See [Item lots and lot types](/docs/inventory/lots/). - **Item components** — the contents of a package item (see Step 6). - **Item units of measure** — alternate units. Give each a **Unit Of Measure** (the code lines use to name it) and a **Conversion Ratio**: how many primary units one of this unit contains. A case of 12 has a ratio of `12`. Optionally set its own **UOM Decimal Precision** or tie it to a **SKU**. - **Item alternates** — substitute items, with an **Alternate Type** and effective dates. - **Item inventory attributes** — per-branch reorder levels, stock limits and classifications. See [Item classifications](/docs/inventory/item-classifications/). ### Step 5 — Check prices, taxes and stock The remaining tabs show records that point at the item: - **Pricing** — the price list rules for the item. You can edit or delete a rule here; create rules from the price list. See [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/). - **Inventory** — the item's inventory attributes, its **Inventory Stock** balances and its **Item Lots**. Stock and lots are read-only here; they change only when documents post. See [The inventory ledger](/docs/inventory/ledger/). - **Service** — item service contracts, maintenance schedules and asset service contracts for serviceable products. See [Asset service contracts](/docs/service/asset-service-contracts/). - **Tax** — the tax group rules that name the item. ### Step 6 — Set up a package, if the item is one Switch **Package** on under **Behaviour**, then add the contents on the **Related** tab's item components list. For each component set the **Component Item**, **Quantity**, and whether it **Is Mandatory**, **Is Selected** (included by default), **Is Bundled** (priced in the package) and **Is Quantity Editable**. **Applicable For** limits a component to sale, purchase or service documents, and **Package Type** decides whether its quantity is multiplied by the package quantity (**Multiple Of Package**) or fixed (**Independent Of Package**). When a line for the package is saved on an order, invoice, quote, opportunity, purchase order or requisition, xMatix adds a child line for each mandatory or selected component whose **Feature Type** is **Product Configurator**. Mark a component's own item **Only Sold In Package** if it must never be invoiced on its own. To choose optional components on a document, use the configurator on that document — see [Product configurator](/docs/crm/product-configurator/). ### Step 7 — Copy an item On the item record select **Clone** and confirm. xMatix copies the item's fields and its owned related records into a new item named after the original with *(Copy)* appended. Because codes must be unique, the copy's **Code** is left empty — enter a new code and save. ### Step 8 — Retire an item To stop an item being used on new lines while keeping its history, open it, select **Edit**, and switch **Active** off. To stop it being bought but keep selling existing stock, switch **Discontinued** on: purchase order, requisition and automatic purchase order lines then reject it with *Discontinued Item Cannot be added*. **Delete** removes the item after a confirmation that it cannot be undone; prefer deactivating an item that already appears on documents. ### Step 9 — Work with items on mobile In the field app, items and SKUs are kept as master data for offline use, so pickers, catalogues and barcode scanning work without a connection. An item opens from a lookup or a catalogue rather than from a menu entry. Its record shows **Name**, **Code**, **Item Type**, **Active** and **SKU Required** in the header, with **SKUs**, **Related**, **Details** and **Activities** tabs, and **Edit** and **Delete** as actions. When you scan a barcode to add a line, the app looks for an item whose **GTIN** matches, then one whose **Code** matches. It refuses an item that is not active, not saleable, not allowed for ordering, or discontinued, and tells you which. ## Fields The fields of the record page, in the order of its **Details** tab. | Field | What it means | Notes | |---|---|---| | Name | The item's name as people read it. | Required. Not unique. Copied into the description of new document lines. | | Code | The item's unique code. | Required and unique across the organization. Typed by hand. Matched by barcode scanning after GTIN. | | HSN/SAC Code | India GST goods (HSN) or services (SAC) code, up to eight characters. | Fills a blank code on invoice and bill lines and flows into GST returns. | | Description | Free-text description. | | | Item Type | What kind of item this is. | Required. `Product`, `Part`, `Charge Item`, `Work Item`, `Service Contract`, `Discounted Item`. Controls which fields the form shows. | | Item Sub Type | A finer grouping. | Picklist; seeded values `Accessories`, `Bikes`, `Clothing`, `Components`. Descriptive. | | Item Segment | A grouping for reporting. | Picklist, seeded `Segment A`–`Segment E`. | | Item Family | A grouping for reporting. | Picklist, seeded `Family A`–`Family E`. Product profitability statements group by it; items without one show as *(no family)*. | | ABC Category, FSN Category | Value and movement classes on the item. | Descriptive only. Cycle counting and automatic ordering read the classes on item inventory attributes instead. | | Service Duration(Minutes) | Standard labour time for a service item. | Converted to hours on quote and service order lines and used for service bay allocation. | | Subscription Duration(Months) | The term of a subscription sold on an invoice. | The subscription ends on the invoice date plus this many months, minus one day. | | Service Rate Basis | How a service line is charged. | `Fixed Price`, `Standard Hours`, `Actual Hours`, `Capped Actual`, `Cost Plus`. Blank means Fixed Price. | | Markup Rate (%) | A markup percentage. | The only price-like value on the item. Selling prices come from price list rules. | | Track Inventory | The item keeps stock. | Off for services and charges: their lines post no stock movement. Forced off for Discounted Item. | | Track Lots | Stock is held per lot. | Every stock-moving line must name a lot. See [Item lots](/docs/inventory/lots/). | | Track Asset | Each unit is serialized as an asset. | Requires Track Lots. Goods receipts and shipments ask for a serial number. | | Inspection On Delivery | Intended for outbound inspection. | No process reads it today. | | Inspection On Receipt | Received stock waits for inspection. | The goods receipt cannot complete while any line has uninspected quantity. | | Repair Order On Receipt | An inspection raises a repair (service) order. | The inspection line cannot complete until that service order is closed. | | SKU Required | Every line must name one of the item's SKUs. | See [SKUs](/docs/inventory/skus/). | | Package | The item is a package of components. | Only package items explode into child lines. | | Only Sold In Package | The item may only be invoiced as part of a package. | Checked on invoice lines only. | | Allow Service | The item can be serviced. | | | Registration Required | The item needs registration. | Shown for Product and Discounted Item. | | Discontinued | The item is no longer bought. | Purchase order, requisition and automatic purchase order lines reject it. Barcode scanning refuses it. | | Active | The item may be used on documents. | **Off by default.** Lines reject an inactive item; item groups refuse to add one. | | Is Subcontracted | The work is normally bought in. | Descriptive only. | | Primary Unit Of Measure | The base unit stock and line quantities are expressed in. | Seeded value `Each`; add values to the picklist for other units. | | Inventory Valuation | A costing method label. | Descriptive only; the costing method used comes from [valuation policies](/docs/inventory/valuation/). | | Maximum Lot Quantity | The most one goods receipt or shipment line may carry. | `0` means no cap. Larger lines are split. A SKU's value above zero takes precedence. | | Primary UOM Decimal Precision | Decimal places for line quantities in the primary unit. | Defaults to `0`, which keeps quantities whole — but never fewer decimals than the item's finest conversion ratio needs. Raise it for items sold in fractions, such as by weight. | | GTIN | The item's trade (barcode) number. | Matched first when a barcode is scanned. | | RF | An RFID tag value, up to 18 characters. | | The [Item entity reference](/docs/reference/entities/item/) lists every stored field, including those not on the shipped form. ## Business rules - **Required on save** — **Name**, **Code** and **Item Type**. **Code** must be unique. - **Track Asset requires Track Lots** — *Tracking assets requires tracking lots.* - **Discounted Item** — **Track Inventory** is switched off on every save. - **Line validation** — every line type listed above rejects an inactive item (*Item is Inactive.*), a missing SKU when **SKU Required** is on (*SKU is required for this item.*) and a SKU of another item (*Invalid SKU selected for this item.*). Invoice lines also reject an **Only Sold In Package** item outside a package (*Item can only be sold as part of a package.*). - **Discontinued** — purchase order, requisition and automatic purchase order lines reject it with *Discontinued Item Cannot be added*. - **Item groups** — adding a member refuses an inactive item (*Item must be active.*) and applies the same SKU checks. - **Units of measure** — a unit needs a **Unit Of Measure** and a **Conversion Ratio** greater than zero. A line in a unit the item does not define fails with *Conversion Ratio is not configured for UOM '…' on this Item.* - **Stock flags** — a stock-moving line for an item with **Track Lots** must name a lot; an inventory adjustment refuses an item without **Track Inventory** (*Domain settings disallow Items that do not support Inventory tracking!*). - **Package components** — mandatory components cannot be removed from a document (*Mandatory package component cannot be removed.*), and a component's quantity must stay within its minimum and maximum and cannot change when **Is Quantity Editable** is off. ## Example A two-wheeler dealer adds a new helmet to its range. 1. The store administrator opens **Warehouse → Items** and selects **New**. 2. They enter **Name** *Full-face helmet, size M*, **Code** `HLM-FF-M`, **HSN/SAC Code** `65061010`, and choose **Item Type** `Part`. 3. On **Inventory Settings** they switch on **Track Inventory**. Helmets are not serialized, so **Track Lots** and **Track Asset** stay off. 4. On **Behavior** they switch on **Active**. On **Specification** they leave **Primary Unit Of Measure** at `Each`. 5. They save, open the **Related** tab and add an item unit of measure `BOX` with **Conversion Ratio** `4`. 6. Pricing adds a price list rule for `HLM-FF-M`, which then appears on the item's **Pricing** tab. 7. A purchase order line for 3 `BOX` is saved with a quantity of 12 in the primary unit. When the goods receipt posts, 12 helmets appear on the item's **Inventory** tab. ## Training ### Practice exercise In a sandbox: 1. Create an item with **Item Type** `Product`, a code such as `TRAIN-ITEM-01`, and leave **Active** off. 2. Add it to a draft order. **Expected:** the line is rejected with *Item is Inactive.* 3. Switch **Active** on and add the line again. **Expected:** it saves. 4. On the item, switch **Track Asset** on with **Track Lots** off and save. **Expected:** *Tracking assets requires tracking lots.* 5. Add a unit of measure `PACK` with ratio `6`, then enter a line for 2 `PACK`. **Expected:** the line quantity is 12. 6. Clone the item. **Expected:** a new record named *… (Copy)* with an empty **Code**. 7. Clean up: delete the draft order and the clone, and switch **Active** off on the practice item. ### Quick reference - Items live in **Warehouse → Items**, or under **Settings** in Sales, Inventory, Procurement and Service. - **Name**, **Code** and **Item Type** are required; **Code** is unique and typed by hand. - New items are **inactive** until you switch **Active** on. - **Track Inventory** decides whether stock is kept; **Track Lots** and **Track Asset** add lot and serial tracking. - Prices, discounts and taxes are rules that point at the item, not fields on it. - Alternate units go in the item's units of measure: ratio = primary units per alternate unit. - **Discontinued** blocks purchasing; **Active** off blocks every new line. - **Clone** leaves **Code** empty for you to fill. ## Permissions Items are governed by the entity permission for Item in the user's security profile. The seeded **Sales**, **Sales Executive**, **Sales Manager**, **Service**, **Standard User** and **System Admin** profiles grant full access — view, create, edit and delete. The seeded **Procurement** and **Parts Manager** profiles carry no item permission, so add one if those users maintain the item master. The **Clone** action is granted separately on security profiles as a server action. Items are shared like other owned records: by default other internal users can read an item, and hierarchy, manual sharing and team access apply. If someone cannot see or change items, start with [why a user can't see something](/docs/administration/user-cant-see-x/). ## Configuration | What | Where | Effect | |---|---|---| | Picklist values for Item Type, Item Sub Type, Item Segment, Item Family and Primary Unit Of Measure | The Item entity's picklist fields in [the data model](/docs/customization/data-model/) | Adds or retires values on the item form. Keep the shipped Item Type values: processes test for them by name. | | The item form and list views | The Item entity's layouts and views (see [entity behavior](/docs/customization/entity-behavior/)) | Which fields the **Create Item** dialog and the record show, and the list columns and summary cards. Several stored fields — such as **Invoice Group**, **Billing Frequency**, **Pricing Method** and **Saleable** — are not on the shipped form; add them to a layout to maintain them. | | Stock flags | Item → **Details** → **Inventory Settings** | See [Inventory configuration](/docs/inventory/configuration/). Settle them before the first transaction. | | Units of measure | Item → **Related** → item units of measure | Alternate units and conversion ratios for every document line. | | SKUs and lot types | Item → **Related** | See [SKUs](/docs/inventory/skus/) and [Item lots](/docs/inventory/lots/). | | Per-branch reorder levels and classes | Item → **Inventory** → item inventory attributes | Drive automatic ordering and cycle counting. See [Item classifications](/docs/inventory/item-classifications/). | | Prices, discounts and taxes | Price lists, discount groups and tax groups | See [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/). | | Store catalogue | Stores and store categories | Which items each store presents. See [Catalogue and pricing](/docs/commerce/catalogue-and-pricing/). | | Importing items | The **Data Import** wizard, entity *Item* | Bulk-create items. Include **Name**, **Code**, **Item Type** and **Active** in the file. A row without a record id creates a new item, so a second import of the same file fails on duplicate codes rather than updating. See [Importing data](/docs/administration/data-management/import-data/). | The item's action list also includes **Show Stock** and **Product Configurator**, which are not placed on the shipped record page. Read stock on the **Inventory** tab, and configure packages from the document that uses them. ## Common problems ### "Item is Inactive." The item's **Active** flag is off — the default for new and imported items. Open the item, select **Edit**, switch **Active** on and save, then add the line again. ### "Tracking assets requires tracking lots." **Track Asset** is on and **Track Lots** is off. Switch **Track Lots** on as well, or switch **Track Asset** off. ### "Discontinued Item Cannot be added" The item is marked **Discontinued**, which blocks purchase order, requisition and automatic purchase order lines. Buy a replacement item instead, or switch **Discontinued** off if the item is being bought again. ### "Conversion Ratio is not configured for UOM '…' on this Item." The line uses a unit the item has no unit of measure for, or whose ratio is zero. Add the unit on the item's **Related** tab with a ratio greater than zero. ### "Item can only be sold as part of a package." The item is marked **Only Sold In Package** and the invoice line is not a component of a package line. Invoice the package item instead, or switch the flag off. ### The Inventory Settings group is missing **Item Type** is **Work Item** or **Service Contract**; these types hide the stock flags. Change the type if the item really is stocked. ### The import created duplicates or failed on the code Imports match on the record id, not on **Code**. A row with an item's record id updates that item; every other row creates a new one, and a second item with an existing code fails on the unique **Code**. To change existing items by import, include each item's record id in the file. Rows are saved one by one, so an import that reports errors has still saved its good rows — fix and re-import only the failed ones. ## Common questions ### Why can't I find a price field on the item? xMatix keeps prices out of the item so that one item can have different prices per price list, customer, branch, SKU and date. Each price is a price list rule that names the item and carries an effective date; the item's **Pricing** tab lists them. Discounts work the same way through discount group rules, and taxes through tax group rules. The only price-like value on the item is **Markup Rate (%)**. See [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/). ### Can I change Track Inventory or Track Lots after an item has been used? The fields stay editable, but the change only affects lines posted afterwards. Stock already posted stays where it is, so switching **Track Lots** on for an item with existing un-lotted stock leaves that stock without a lot, and new stock-moving lines will need one. Decide these flags before the first receipt, or plan an adjustment to move existing stock into lots after the change. See [Adjusting stock](/docs/inventory/adjustments/). ### What is the difference between Active and Discontinued? **Active** off stops the item on every new document line — sales, purchase and inventory alike. **Discontinued** only stops it on purchase order, requisition and automatic purchase order lines, so you can keep selling and moving the stock you have while you stop buying more. Barcode scanning on order screens refuses both. Neither changes existing documents or stock. ### Should a service be an item? Yes. Anything that appears on a document line is an item. Give services the **Work Item** or **Charge Item** type and leave **Track Inventory** off so no stock is expected. For labour, set **Service Duration(Minutes)** so quote and service order lines get their standard hours. ### Are ABC Category, FSN Category and Inventory Valuation on the item used? Not by any process. Cycle counting and automatic ordering read the categories on each item's per-branch inventory attributes, and stock is costed with the method chosen in your valuation policies. The item's own fields are labels you can use in views and reports. ## Related topics - [Item entity reference](/docs/reference/entities/item/) - [SKUs (item variants)](/docs/inventory/skus/) - [Item lots and lot types](/docs/inventory/lots/) - [Item classifications](/docs/inventory/item-classifications/) - [Inventory configuration reference](/docs/inventory/configuration/) - [The inventory ledger](/docs/inventory/ledger/) - [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/) - [Catalogue and pricing](/docs/commerce/catalogue-and-pricing/) - [Product configurator](/docs/crm/product-configurator/) - [Importing data](/docs/administration/data-management/import-data/) ---- # The inventory ledger URL: https://xmatix.com/docs/inventory/ledger/ Last reviewed: 2026-09-06 Every stock movement in xMatix — a receipt, a shipment, a transfer, an adjustment — is recorded as a posted entry in the inventory ledger. On-hand stock is not a figure anyone types; it is the running position that those entries have moved. Once posted, an entry is never edited or deleted: when the source document changes, the ledger posts reversal entries that neutralize the originals and, where needed, fresh entries for the new values. An item's stock history therefore reads like a bank statement — today's balance can be traced back through every movement that produced it. ## Read the screen @[guided-image](_img/inventory-ledger-concept.png) **Inventory → Inventory Ledger** (view **All Inventory Ledgers**) lists every posted movement, newest first. Read a row as a chain of custody: **Ledger Name** is the movement's stable identity, **Source Document** is the document line that caused it, and **Ledger Type** names the kind of movement — `Purchased`, `Inward`, `Allocation`, `TransferOutward`, `Inspection`, `Shortage` and so on, written without spaces. **Partner Account** and **Branch** locate ownership and place; **Item**, **SKU**, **Item Lot** and **Item Lot Type** identify what moved down to the batch or serial where the item is lot-tracked. Search and the column filters narrow the list to one item, source document, branch, type or lot. @[guided-image](_img/inventory-ledger-detail.png) Open a movement to see its read-only record. The header repeats partner account, branch, ledger type and quantity. **Ledger Details** holds the storage location, the source document and its entity and record references, the parent document, the **Inventory Stock Posted** flag and — on a reversal — the **Reverse Inventory Ledger** it neutralizes. **Item Details** holds item, SKU, lot type, lot and the quantity. Read both sections together; no single field explains a stock change on its own. The entry also stores a posting date and the movement's unit cost, which the Item Ledger and the costing engine use even where the detail layout does not display them. ## Every movement is a posted entry Documents across the product post into the one ledger, each with a **ledger type** that names the movement. Which document lines post which movements is defined by the platform-managed **inventory ledger settings** — one rule per source line entity and ledger type, naming the quantity field to post and the stock counters to move. The seeded rules cover: | Source line | Ledger types posted | |---|---| | Goods receipt line, inspection line | `Inward`, `Damaged`, `Shortage`, `Excess`, `Inspection` | | Bill line | `Purchased` | | Delivery order line | `Outward` | | Invoice line | `Sold` | | Credit note line | `SaleReturn`, `PurchaseReturn`, `Damaged`, `Shortage`, `Excess`, `Expired` | | Adjustment line | `Adjustment`, `Excess`, `Shortage`, `Damaged`, `Expired`, `OnHold`, `OnLoan`, `Assemble`, `Disassemble` | | Transfer outward line, transfer inward line, single-step transfer line | `TransferOutward`, `TransferInward`, plus `Damaged`, `Shortage`, `Excess` on receipt discrepancies | | Fulfilment allocation and picking lines (from orders, service orders and fulfilments) | `Allocation`, `Picked` | | Shipment line | `Pipeline` (inbound, informational) | Administrators can read these rules under **Setup → Feature Hub → Inventory → Inventory Ledger Settings** (see the [configuration reference](/docs/inventory/configuration/)); they cannot be changed from the front end. One document line can produce several entries — a goods receipt line posts its inward, shortage, damaged and excess quantities as separate entries — and every entry stays linked to the exact line that produced it, so the group can be found from either side. Posting the entry, moving the branch's stock balance and updating the lot's counters happen in one save. Only items with **Track Inventory** set post at all, and an item with **Track Lots** set must name a lot on the line or the posting is rejected. Most documents post through an explicit action (**Post Inventory**, **Release Outward**, **Perform Receive**) rather than on creation, and the reliable proof that a line reached the ledger is its **Inventory Ledger** reference — not a status field. ## What an entry records | Field | What it holds | |---|---| | Item, SKU, item lot, item lot type | What moved; on transfers, **Related Item Lot** is the lot on the other side. | | Quantity | How much. Direction comes from the ledger type; entries store a magnitude, and reversal entries are negated. | | Ledger type | The kind of movement. | | Partner account and branch | Whose stock moved and where, taken from the source document's header. Transfer entries also carry the related partner account and branch on the other side. | | Storage location | The bin within the branch, after transfer resolution — an inward leg names the destination location; movements onto the transit balance carry none. | | Unit cost | The cost on the movement, from the source line or lot. | | Posting date | When the entry was posted — the posting time, not the source document's own date. | | Source document, source record, parent record | The line that posted the entry and its parent document, as navigable references. | | Inventory stock posted | Whether the quantity was applied to a stock balance. `false` means the row exists but no stock counter matched the rule — a diagnostic flag, not a normal state. | | Reverse inventory ledger | On a reversal entry, the original it neutralizes. | ## Corrections post reversals, not edits The ledger refuses direct edits and deletes with an explicit message: *Inventory ledger entries are immutable and cannot be edited. Reverse the source document's posting to correct it.* If a posted line's quantity or cost is changed, the ledger inserts a negated reversal entry for each original — against the original lot and at the original unit cost — and posts fresh entries for the new values. If a posted line is deleted, it inserts one reversal per original; the originals stay. Each reversal references the entry it reverses, so correction pairs are traceable in both directions. None of this is done by hand: you correct the **source document** — edit the line, delete it, or post a correcting document such as an [adjustment](/docs/inventory/adjustments/) — and the ledger follows. Two reading habits follow. A pair of opposite entries for the same line is a correction that happened, not an error. And counting ledger rows does not count documents: one line can legitimately stand behind several rows. ## Stock balances and the negative-stock guard Each posting updates the **Inventory Stock** row for the partner account, branch, item, SKU and storage location it moves (rows are created on demand and never typed), and the matching item lot's counters. Every counter is a positive magnitude — purchased, sold, transfer inward, damaged, on hold and so on — and **Available** and **In Hand** are calculated from them. A posting that would take the counter it decrements below zero is rejected with *Insufficient stock: … cannot go negative*, and nothing is written for that document; the usual cause is a line drawing from a different lot or storage location than the one holding the stock. Because the guard works per counter, the calculated in-hand or available figure can still read negative when issues have been posted that receipts never covered — treat a negative balance as a data problem to trace through the ledger. Two availability views exist and do not always agree: the stock row's **Available** and **In Hand** (which count purchased quantity) and the Item Ledger's running totals (which treat purchased and pipeline quantity as neutral). Use the stock row and the **Inventory Stock** page for current balances, and the ledger for movement history. ## The Inventory Stock page @[guided-image](_img/inventory-stock-balance.png) **Inventory → Inventory Stock** shows the **Stock Balance** statement: one row per item with the available quantity for the selected company (the picker at the top right) and a total. Its controls follow the finance statements: - **Compare by** — *No comparison* (one **Current** column), *By branch*, *By period* or *By years*, each with a *(movement)* variant that shows opening, change and closing per column. - **Branches** — for *By branch* the branches that become columns; for every other comparison a scope filter (empty means all branches, consolidated). - **Balance as On** — *Current*, week / month / quarter / year to date, previous month, a fiscal-year end, or a custom period. Period presets render opening, change and closing. Clicking a figure opens a drill in a side panel: **Item lot details** for lot-tracked items (the lots behind the balance, with their quantity state), and **View ledger** where your administrator has placed the **Item Ledger** component on a page. The Item Ledger takes a company, item (optionally SKU), branch and a date range — today, week, month, quarter or year to date, or custom — and lists the opening stock, every posted movement in order with a running balance and its source document, and the closing stock; leaving the branch empty consolidates all branches so inter-branch transfers net to zero. When a stock number surprises you, start here: the balance is the sum of the movements behind it, so the movement that explains the surprise is in the list. [Troubleshooting inventory](/docs/inventory/troubleshooting/) gives a working method, and [Inventory period balances](/docs/inventory/period-balances/) explains the period rollup behind the *By period* comparisons. ## Common questions ### Can I edit or delete a ledger entry? No — the ledger blocks direct edits and deletes with an explicit message telling you to correct the source document instead. Change or remove the offending line, or post a correcting document such as an [adjustment](/docs/inventory/adjustments/); the ledger then posts reversal entries automatically. The net quantities end up where an edit would have put them, and the audit trail of the original posting is preserved. ### Why do I see pairs of opposite entries for the same item? A correction happened. When a posted line is changed or deleted, the ledger neutralizes the original entries with reversal entries — each referencing the entry it reverses — and posts fresh entries if there are new values. Read the pair together with its replacement, not row by row. ### Why does the posting date differ from my document's date? The ledger's posting date is stamped when the entry is posted, not copied from the source document. A document created on Monday and posted on Wednesday shows Wednesday in the ledger. Period comparisons and the costing engine work from posting dates. ### Does the ledger show value as well as quantity? Each entry carries the unit cost of its movement, and the Item Ledger shows a simple running line-cost value alongside quantity. The *carrying value* of stock depends on the costing method your valuation policy selects — under FIFO or moving average it is not quantity times the latest cost. Value questions belong to **Inventory Valuation**, which is built on the same ledger; see [Inventory valuation and costing](/docs/inventory/valuation/). ## Related topics - [Transferring stock between branches](/docs/inventory/transfers/) - [Adjusting stock](/docs/inventory/adjustments/) - [Item lots and lot types](/docs/inventory/lots/) - [Inventory valuation and costing](/docs/inventory/valuation/) - [Inventory period balances](/docs/inventory/period-balances/) - [Inventory configuration reference](/docs/inventory/configuration/) - [Troubleshooting inventory](/docs/inventory/troubleshooting/) ---- # Item lots and lot types URL: https://xmatix.com/docs/inventory/lots/ Last reviewed: 2026-09-06 An item lot in xMatix is a specific, identifiable quantity of an item — a received batch, a serial-numbered unit, a consignment — held at one partner account, branch and storage location, with its own dates, costs and quantity counters. Lot tracking answers the questions the item level cannot: which batch expires next month, which serial number went to which customer, what this consignment cost. Items opt in individually with the **Track Lots** flag on the item master; from then on every movement of that item names the lot it touches, and the same posting that moves branch stock moves the lot's counters. ## Read the screen @[guided-image](_img/item-lots-concept.png) The **Item Lots** list (view **All Item Lots**) shows one row per lot: **Name** (the generated lot number), **Partner Account** and **Branch** (who owns it and where it sits), **Item**, **Serial Number** and **Component Number**, the calculated **In Hand** and **Available** quantities, and the created date. The list is not on the Inventory app's navigation bar; open it from a lot link on a document line or ledger entry, from the global search, or through the **Item lot details** drill on a stock figure in **Inventory Stock**. Search and the column filters isolate a serial number, batch, item or branch — the usual starting point for an expiry review or a recall. Read **In Hand** and **Available** together before promising stock. In hand is what is physically present; available removes quantities already allocated, picked, held, on inspection or lent out. A lot can exist physically and still be unsuitable for a new order. @[guided-image](_img/item-lot-detail.png) Open a lot to see the full record as one page of sections: **Key Information** (partner account, branch, storage location, item, SKU, lot type, lot code), **Basic Details** (batch number, serial number, component number, supplier invoice number and dates, date of receipt), **Lot Information** (manufacturing and expiry dates, cost, total cost, related lot), **Quantity Details** (in hand and available) and, below them, **Inventory Information** — the individual quantity buckets (sold, allocated, transit, damaged, shortage and the rest) that postings increment and decrement. A list row is enough to find a lot; the detail page is where hold, expiry and recall decisions are made, and where a stock discrepancy is traced bucket by bucket. ## Lot tracking is per item The item master carries a **Track Lots** flag. Items without it move at item/SKU level only — the right choice where batch identity does not matter. Items with it must name a lot on every document line that moves stock: an adjustment line without one is rejected on save with *Selection of Lot is mandatory for Items that requires Lot Tracking!*, and any other lot-tracked line without one fails at posting with *Product Lot was not selected for the transaction. This is required for Inventory posting.* **Track Asset** (units become serialized asset records) splits every receipt line to a quantity of one, so each serialized unit gets its own lot. The item's (or SKU's) **Maximum Lot Quantity** caps how much a goods receipt may put into a single lot — a larger receipt line is split into several lines, each with its own lot. ## Where lots come from - **Goods receipt** creates lots when the receipt is *received*: one lot per receipt line for every inventory-tracked item (not only lot-tracked ones), copying the line's serial number, component number, unit cost, MRP, SKU, lot type and storage location, and the receipt header's supplier invoice number, supplier invoice and dispatch dates, partner account and branch. **Date Of Receipt** is the receipt's document date. Editing a received line afterwards rewrites its lot from the new values; deleting the line deletes the lot (lot-tracked items only). - **Transfer release and posting** clone the source lot into a new lot at the destination — same batch, serial, registration number, cost and dates, owned by the destination partner and branch — and link the two through **Related Item Lot**. Saving the inward line with a receiving storage location moves the destination lot to that location. - **Field sales (van stock)** lines clone the source lot the same way, so stock loaded onto a vehicle is a linked lot at the vehicle's location. - **Manual entry or import** creates lots directly; the same fields apply. Lots are location-scoped rather than globally unique per batch number: the same physical batch received at two branches, or transferred between them, is two lot records linked by the related-lot reference. ## What a lot records — and what the platform maintains | Group | Fields | Maintained by | |---|---|---| | Identity | Serial number, component number, batch number, lot code, registration number, item, SKU, lot type | Serial and component number come from the goods receipt line. **Batch No**, **Lot Code** and **Registration Number** are not written by receipt — enter them by hand or by import; transfers copy whatever is there to the destination lot. | | Dates | Date of receipt, supplier invoice and supplier dispatch dates, date of manufacture, date of expiry, dispatch, registration, purchase, sale | Receipt sets **Date Of Receipt** and the supplier dates. **Date Of Mfg** and **Date Of Expiry** are yours to capture — nothing populates them automatically, so an expiry review depends on your discipline at receipt time. Expiry is read in one place: a fulfilment order line with a **Limit Expiry Days** value is auto-allocated only from lots whose expiry falls on or before today plus that many days — lots with no expiry date are skipped for such a line. | | Costs | Unit cost, cost, total cost, landed cost, MRP | **Unit Cost** and **MRP** come from the receipt line and travel onto ledger entries. **Cost**, **Total Cost** and **Landed Cost** are not written by any posting path. | | Placement | Partner account, branch, storage location | Set at creation; storage location is rewritten when a transfer inward line is received. | | State | Hold code, transaction-locked, closed, closed-for-sale | **Hold Code** is the operative quarantine: invoicing and fulfilment allocation pick only lots with an empty hold code and available quantity, oldest first (newest first when the resolved method is LIFO). **Is Transaction Locked** is set and cleared by a cycle count with inventory locking; while it is on, any save that touches the lot is rejected with *Item is locked for transaction! Please contact your Administrator for more details.* **Is Closed** and **Is Closed For Sale** are informational — no process reads them; to stop a lot being sold, set a hold code. | ## Lot quantity buckets A lot keeps a position across buckets, updated by the same postings that move branch stock: | Bucket | Meaning | |---|---| | In hand / available | Calculated from the buckets below: what is physically present, and what part of it is free to promise. | | Transit | Released outward on a two-step transfer and not yet posted inward — carried on the destination lot. | | On hold / inspection / on loan | Present but not usable: held by an `OnHold` adjustment, pending incoming inspection, or lent out by an `OnLoan` adjustment. | | Purchased / sold / returns / pending deliveries | Cumulative trade quantities, including sold-but-undelivered stock. | | Adjustment / negative adjusted / damaged / expired / shortage / excess | Corrections and write-downs by reason, from adjustment lines and receipt or transfer discrepancies. | | Transfer inward / outward, allocated, picked, unbilled receipts / dispatches | Logistics states as stock moves through receipts, fulfilment and transfers. | Each posting checks that the bucket it moves does not go below zero and rejects the movement if it would. Because buckets accumulate positive magnitudes, the *calculated* in-hand figure can still read negative when issues have been posted against a lot that never received the matching quantity — a negative **In Hand** on the list is a data problem to investigate through the ledger, not a display error. ## Lot types A **lot type** is a named commercial grade of an item — saleable, sample, promotional — with flags (**Saleable**, **Sample**, **Promo**) and short codes (**Code**, **Price Code**, **Variation Code**, **External Item Code**) used by pricing rules and integrations. Lot types are defined per item under the Inventory or Warehouse settings apps and are carried on document lines, ledger entries and lots. They matter commercially rather than physically: price-list, discount, tax and group rules can target a lot type, so sample stock of an item can price at zero while saleable stock prices normally, without a second item. A lot type is not a lot-numbering scheme and does not switch lot tracking on or off. ## Lots through movements Every movement of a lot-tracked item carries its lot: receipts create lots, shipments and issues draw them down, [adjustments](/docs/inventory/adjustments/) correct them bucket by bucket, and [transfers](/docs/inventory/transfers/) move quantity out of the source lot, through the destination lot's transit counter, and into the destination lot. Each [inventory ledger](/docs/inventory/ledger/) entry records the lot it moved (and, on transfers, the related lot on the other side), so a lot's history reads like the item's — one level finer. The **Inventory Stock** page offers an **Item lot details** drill on any figure for a lot-tracked item, which opens the lots behind that balance. ## Common questions ### Should every item be lot-tracked? No. Lot tracking earns its keep where batch identity has consequences — expiry dates, serial-level warranty, batch-specific costs, recalls. Where any unit is as good as any other, item/SKU-level tracking is simpler and every document gets one field less to fill. The flag is per item, so mix freely. ### Why is the expiry date empty on lots we received? Because goods receipt does not populate it — only the receipt date and the supplier paperwork dates are set automatically. Capture manufacturing and expiry dates on the lot at receipt (or by import) if you rely on expiry reviews or on **Limit Expiry Days** during allocation; transfers then carry them to the destination lot. ### Why does a non-lot-tracked item have lots? Because receiving a goods receipt creates a lot for every inventory-tracked line, whether or not the item tracks lots. For an item without **Track Lots** the lot is a record of the receipt and is not required on later movements; the item's stock is kept at item/SKU level and the lot's counters are only moved by lines that happen to name it. ### What is the difference between a lot and a lot type? A lot is a physical quantity — *this* batch, *this* serial number. A lot type is a classification — saleable, sample, promo — that many lots of an item can share. You track and move lots; you write pricing and scheme rules against lot types. ### How do lots interact with valuation? The costing engine values stock per accounting book, item, branch and method; it does not keep a separate cost pool per lot unless the resolved method is specific identification, which costs each issue at the exact lot it drew (the lot's identity travels as the cost layer's lot key). Setting a policy's costing level to batch or serial does not by itself create per-lot pools. See [Inventory valuation and costing](/docs/inventory/valuation/). ## Related topics - [The inventory ledger](/docs/inventory/ledger/) - [Transferring stock between branches](/docs/inventory/transfers/) - [Adjusting stock](/docs/inventory/adjustments/) - [Inventory valuation and costing](/docs/inventory/valuation/) - [Warehouse configuration](/docs/warehouse/configuration/) ---- # Inventory period balances URL: https://xmatix.com/docs/inventory/period-balances/ Last reviewed: 2026-09-02 Period balances are a rebuilt cache of the inventory ledger by item, branch, accounting book and fiscal period. Each row holds opening, inward, outward and closing quantity and value. A successful rebuild supplies the period columns used by the inventory valuation statement; it does not guarantee a tie when prerequisites are missing or a valuation scope failed. ## The rollup grain | Dimension / measure | Meaning | |---|---| | Item, branch, company | Whose stock, where. | | Accounting book | The book whose costing policies value the period. | | Fiscal period | The period of your financial calendar being summarized. | | Opening / inward / outward / closing quantity | The period's quantity story: what it started with, what came in, what went out, what remained. | | Opening / inward / outward / closing value | The same story in money, at the book's costing method. | | Costing method | The method that produced the values, stamped on the row. | ## How the ledger rolls up Within a period, inward is the sum of the period's positive posted movements and outward the sum of the negative ones; closing is opening plus inward minus outward; and each period's opening is the prior period's closing, chaining back to the start of history. Because the ledger corrects by reversal rather than edit, a correction and its original cancel inside whichever period they were posted in — the rollup needs no special handling for corrections, which is one of the quiet benefits of the reversal model described in [the inventory ledger](/docs/inventory/ledger/). ## Rebuilt on demand, not maintained per posting The value side cannot be kept current by adding to a naive total: under FIFO or moving average, a period depends on cost history. Period balances are therefore a **rebuilt cache**. A rebuild replays the relevant ledger history and rewrites the summarized rows. When it succeeds under valid book and method configuration, it provides a reproducible comparison; configuration or strategy failures must be resolved rather than hidden behind an assumed tie. The consequence to remember: period balances are as fresh as their last rebuild. The valuation statement's period views carry a **Rebuild** action that recomputes the cache and reloads; run it after heavy posting activity, backdated corrections, or a change of valuation policy, and before relying on a period comparison for a decision. ## Where period balances are used The period and year comparisons of the stock position and [valuation statement](/docs/inventory/valuation/) read the cache — each fiscal period becomes a column, in quantity, value or both, optionally as an opening/change/closing movement view. Current stock and the item ledger do **not** go through the cache; they are live reads of stock and ledger, which is why a stale cache shows up as a mismatch between "current" and "this period so far" views — the rebuild resolves it. ## Common questions ### The period comparison doesn't match current stock — which is right? Both, at their own timestamps. Current stock is live; a period column is as of the last rebuild. If the current period's column trails today's figure, postings have happened since the rebuild — run the Rebuild action on the statement and the column catches up. If a *closed* period's figures changed after a rebuild, look for backdated corrections posted into it. ### Why is the value column not just quantity times a price? Because the value is produced by the costing engine under the book's method, exactly as the valuation statement computes it. Under FIFO the closing value reflects which receipt layers survived; under moving average, the average cost as of period end. That is deliberate: a period balance that used a naive price multiplication would disagree with the valuation statement and be unusable for reconciliation. ### Do I need to rebuild after every posting? No. Rebuild when you are about to *use* a period comparison and freshness matters, or after events that change history — backdated documents, corrections into earlier periods, policy changes. Day-to-day posting does not need the cache to be current, because the operational screens read live stock and ledger data. ## Related topics - [The inventory ledger](/docs/inventory/ledger/) - [Inventory valuation and costing](/docs/inventory/valuation/) - [Inventory configuration reference](/docs/inventory/configuration/) - [Troubleshooting inventory](/docs/inventory/troubleshooting/) ---- # SKUs (item variants) URL: https://xmatix.com/docs/inventory/skus/ Last reviewed: 2026-10-09 A SKU is one variant of an item — a colour, a pack or any other version you want to sell, buy and stock separately — with its own code. The item stays the product; its SKUs are the versions of it that document lines, stock balances and pricing rules can tell apart. You create SKUs on the item record once the item exists. From then on, every document line that names the item can also name one of its SKUs: orders, quotes, invoices, delivery orders and shipments on the sales side; requisitions, purchase orders, goods receipts and bills on the purchase side; transfers, adjustments and cycle counts in inventory. Stock is kept per SKU, and price list, discount and tax rules can target a single SKU. ## Overview A SKU record is small. It has an identity — **SKU Code**, **Name** and the parent **Item** — and a few descriptive attributes: **Product Color**, **Primary UOM**, **Maximum Lot Quantity** and the **Default** flag. What makes SKUs matter is everything that refers to them: - **Document lines** carry an **SKU** field next to **Item**. On most lines the SKU picker only offers the SKUs of the item already on the line. - **Stock** is kept per partner account, branch, item, SKU and storage location. Stock received against one SKU is not available to a line that names a different SKU, or no SKU. - **Pricing** — price list rules, discount group rules, tax group rules and trade scheme conditions and benefits — can name a SKU, so variants of one item can be priced and promoted differently. - **Order taking** shows an item's SKUs as variants to pick from. Whether an item's lines *must* name a SKU is decided on the item, by its **SKU Required** flag. ## When to use it Create SKUs when one product exists in versions that you need to count, price or order separately — for example a paint in several colours, or a product sold in more than one finish. Keep a single item without SKUs when every unit is interchangeable: lines then move stock at item level and nobody has to pick a variant. SKUs are not the place for: - **Units of measure** (a bottle versus a case of twelve). Units and their conversion ratios are maintained on the item; they apply to every SKU of the item. - **Batches and serial numbers.** These are item lots — see [Item lots and lot types](/docs/inventory/lots/). A lot belongs to an item and, where you use them, a SKU. - **Commercial grades** such as new versus refurbished. Use item lot types. ## How xMatix handles it - **A SKU belongs to one item.** When a document line is added, xMatix checks that the line's SKU is one of the item's own SKUs and rejects the line with *Invalid SKU selected for this item.* if not. - **SKU Required is enforced on lines.** When the item has **SKU Required** switched on, a line for it without a SKU is rejected with *SKU is required for this item.* Without the flag, the SKU is optional and a line can move stock at item level. - **SKU codes are unique across your organization**, not just within the item. Saving a second SKU with a code that already exists fails with *SKU Code '…' already exists*. The **External** reference used by integrations is unique in the same way. - **The Default flag is a preference, not a rule.** xMatix does not create a default SKU when an item is created, does not stop an item having several defaults, and does not fill the SKU of a line you add by hand from the default. The default SKU is shown first among an item's variants in the published catalogue, and it is the SKU the purchase **frequently ordered** suggestion proposes. - **Stock follows the SKU exactly.** Each movement posts to the stock row for its item and SKU, and fulfilment allocates only stock and lots with the line's SKU. Stock posted with no SKU is a separate balance from stock posted against a SKU. - **Maximum Lot Quantity splits lines.** When a goods receipt or shipment line is added with a quantity above the cap, it is split into several lines, each within the cap. On transfer lines the split happens only when the cap is exactly 1, into lines of one unit. A SKU's value, when above zero, is used in place of the item's. - **Lines are not re-split.** The split happens when the line is added; editing the quantity of an existing line, or changing the cap later, does not split lines again. ## Prerequisites - The item exists. You add SKUs from the item record. - Your security profile grants access to SKU records (see [Permissions](#permissions)). - Decide the codes in advance. Because SKU codes must be unique organization-wide, a convention that includes the item code — for example `PNT-500-RED` — avoids collisions between items. ## Procedure ### Step 1 — Open the item Open the item record from an **Items** list — for example in the **Warehouse** app — or find it with search. SKUs do not have their own menu entry; you reach them through their item, or through search. ### Step 2 — Add a SKU On the item, open the **Related** tab. The first list on it is **SKUs**. Select **New** on that list. The **SKU** dialog asks for: 1. **SKU Code** — the variant's unique code. 2. **Name** — the variant's name as people should read it. 3. **Item** — the parent item. 4. Under **Additional Details**: **Product Color**, **Primary UOM** and **Default**. Save. The SKU appears in the item's **SKUs** list, which shows the name, code, item, unit, colour and default flag. Add one SKU per variant. ### Step 3 — Set a maximum lot quantity, if you need one **Maximum Lot Quantity** is not on the New dialog. Open the saved SKU (or use **Edit** on its row in the item's SKUs list); the field is under **Additional Information** on the SKU record. Enter the largest quantity one line may carry for this variant, or leave it at `0` to use the item's value. ### Step 4 — Decide whether lines must name a SKU On the item's **Details** tab, the **Behaviour** section has **SKU Required**. Switch it on when stock and sales must always be recorded per variant; from then on every new line for the item needs a SKU. Leave it off when the SKU is optional detail. ### Step 5 — Use the SKU on a document line On a line, choose the **Item** first, then the **SKU**. On most lines the SKU picker lists only that item's SKUs. Where the item tracks lots, choose the SKU before the lot: on order, invoice and delivery order lines the lot picker lists only lots of the line's item and SKU. ### Step 6 — Change or remove a SKU Edit a SKU from its record (**Edit**) or from the row action in the item's SKUs list. Changes apply to future lines; lines and stock already recorded keep pointing to the same SKU record. **Delete** removes the SKU after a confirmation that it cannot be undone — before you delete one, check that no document, stock balance or pricing rule still refers to it. ### Step 7 — Work with SKUs on mobile In the field app, an item's record opens on a **SKUs** tab where you can view and edit its variants, and SKU records are part of the master data the app keeps for offline use. A SKU's own record shows **Name**, **SKU Code** and **Item** in the header, with the details and an **Activities** tab below; **Edit** and **Delete** are its actions. ## Fields | Field | What it means | Notes | |---|---|---| | SKU Code | The variant's own code. | Required. Unique across the organization — two items cannot reuse the same code. Order capture matches on it. | | Name | The variant's name. | Required. Shown in pickers and lists. | | Item | The parent item. | Every SKU belongs to one item; lines check the SKU against it. | | Product Color | The variant's colour. | Optional picklist: `Red`, `Blue`, `Yellow`, `Orange`, `Purple`, `Black`, `White`, `Grey`. When set, it is the label the order-taking screen shows for the variant (otherwise the SKU code, then the name). | | Primary UOM | The variant's base unit. | Optional picklist; `Each` is the only seeded value. Unit conversions are maintained on the item, not here. | | Maximum Lot Quantity | The largest quantity one goods receipt or shipment line may carry for this variant. | Defaults to `0`, meaning "use the item's value". Above zero, it takes precedence over the item. On the SKU record only, not on the New dialog. | | Default | Marks the item's preferred variant. | Not enforced as unique and not used to fill lines; see [How xMatix handles it](#how-xmatix-handles-it). | | Owner | The user who owns the record. | Drives record sharing like any other record. | The [SKU entity reference](/docs/reference/entities/sku/) lists every stored field, including the system columns. Its **UOM Conversion** field is not used: it stores no data, and unit conversions belong to the item. ## Business rules - **SKU belongs to the line's item** — checked when lines are added to inventory adjustments, transfers, cycle counts, requisitions, purchase orders, automatic purchase orders, goods receipts, inspections, bills, orders, invoices, delivery orders, shipments, credit notes, fulfilment orders and their allocation and picking lines, service orders and opportunity lines. Item group membership and item aliases apply the same check with their own messages. - **SKU Required** — the same lines reject a missing SKU when the item has **SKU Required** switched on. On item group members the message is *SKU is required for the selected Item.* - **When the check runs** — on order, purchase order, goods receipt, shipment and credit note lines the check runs when the line is added. Changing the SKU of an existing line is not re-checked there, so correct a wrong SKU by replacing the line. - **Unique codes** — SKU Code and External are unique organization-wide. - **Price list rules** — a rule with a SKU applies only to that SKU; a rule with no SKU applies to all of the item's SKUs. Between matching rules, the latest **Date Effective From** wins first; a SKU-specific rule beats a general one only when their start dates are equal. Details: [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/). - **Discount group rules** — a rule naming the item beats one that does not, and then a rule naming the SKU beats one that does not, regardless of dates. - **Tax group rules** — a rule with a SKU applies only to that SKU, a blank SKU matches all. There is no SKU precedence: the order of the tax groups decides which matching rule is used. - **Trade schemes** — a condition or benefit with a blank SKU matches any SKU of the item. - **Lot splitting** — see Maximum Lot Quantity above; goods receipt and shipment lines split above the cap, transfer lines only for a cap of 1. ## Example A paint distributor sells *Weathercoat 1 L* in red, white and grey, and needs stock and prices per colour. 1. The product manager opens the item **Weathercoat 1 L**, switches on **SKU Required** under **Behaviour**, and saves. 2. On the **Related** tab, in the **SKUs** list, they add three SKUs: `WC1-RED` (*Weathercoat 1 L Red*, colour `Red`, **Default** on), `WC1-WHT` (*Weathercoat 1 L White*, colour `White`) and `WC1-GRY` (*Weathercoat 1 L Grey*, colour `Grey`). 3. Pricing adds a price list rule for the item with no SKU at 450, and a second rule for `WC1-GRY` at 480 with the same **Date Effective From**. Red and white price at 450; grey prices at 480. 4. A purchase order line for *Weathercoat 1 L* saved without a SKU is rejected with *SKU is required for this item.* The buyer picks `WC1-WHT` and the line saves. 5. When the goods receipt is posted, stock appears under *Weathercoat 1 L* / `WC1-WHT` only. A sales order line for `WC1-RED` cannot be allocated from it. ## Training ### Practice exercise In a sandbox, pick an item that has no SKUs. 1. Add two SKUs with codes `TRAIN-A` and `TRAIN-B`, give them different colours, and mark `TRAIN-A` as **Default**. 2. Try to add a third SKU on a different item with the code `TRAIN-A`. **Expected:** the save fails because the code already exists. 3. Switch on **SKU Required** on the first item, then add a line for it on a draft purchase order without a SKU. **Expected:** *SKU is required for this item.* 4. Open the line's SKU picker. **Expected:** only `TRAIN-A` and `TRAIN-B` are offered. 5. Clean up: delete the draft order, the two SKUs, and switch **SKU Required** back off. ### Quick reference - SKUs are added from the item: **Related** tab → **SKUs** → **New**. - SKU Code is required and unique across all items. - **SKU Required** on the item makes every new line name a SKU. - **Default** is a preference only — lines you add by hand do not take it automatically. - Stock is kept per SKU; stock without a SKU is a separate balance. - **Maximum Lot Quantity** on a SKU overrides the item's when above zero; set it on the SKU record. - Units of measure live on the item; lots and lot types are separate from SKUs. ## Permissions SKU records are governed by the entity permission for SKU in the user's security profile. The seeded **Sales**, **Sales Executive**, **Sales Manager**, **Service**, **Standard User** and **System Admin** profiles grant full access — view, create, edit and delete. Other seeded profiles, including **Procurement**, carry no SKU permission; add one if those users maintain or need to open SKU records. If someone cannot see or edit SKUs, start with [why a user can't see something](/docs/administration/user-cant-see-x/). ## Configuration | What | Where | Effect | |---|---|---| | SKU Required | Item → **Details** → **Behaviour** | Makes a SKU mandatory on every new line for that item. | | Maximum Lot Quantity | SKU record → **Additional Information**; item → **Details** → **Specification** | Caps the quantity of one goods receipt or shipment line; the SKU value wins when above zero. | | Product Color and Primary UOM values | The SKU entity's picklist fields in [the data model](/docs/customization/data-model/) | Adding a value makes it available on every SKU. | | SKU layouts and the **All SKU** view | The SKU entity's layouts and views (see [entity behavior](/docs/customization/entity-behavior/)) | Which fields the SKU dialog and record show, and the list columns. **Maximum Lot Quantity** can be added to the create layout if your team sets it at creation. | | SKU lookup filters on document lines | The line entity's lookup filters ([entity behavior](/docs/customization/entity-behavior/)) | The seeded *SKU for Item* filters restrict the SKU picker to the line's item. Goods receipt, quote, transfer, inspection, service order, credit note and fulfilment lines ship without one; the line still rejects a SKU of another item when it is added. | | Price, discount and tax rules per SKU | Price lists, discount groups and tax groups | See [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/). | | Importing SKUs | The **Data Import** wizard, entity *SKU* | Bulk-create variants; resolve the **Item** lookup by the item's name or code. See [Importing data](/docs/administration/data-management/import-data/). | ## Common problems ### "SKU is required for this item." The item has **SKU Required** switched on and the line has no SKU. Pick one of the item's SKUs. If the item has no SKUs yet, add them on the item's **Related** tab first. On the order-taking screen, an item with **SKU Required** and no SKUs produces a line the server rejects — add the SKUs before taking orders for it. ### "Invalid SKU selected for this item." The line's SKU belongs to a different item — typically the item was changed after the SKU was chosen, or the line came from an import or integration. Clear the SKU, choose the item, then pick the SKU again from the filtered list. ### "SKU Code '…' already exists" Another SKU — possibly on a different item — already has that code. Codes are unique across the organization; choose a code that includes the item code. ### I received stock but the order can't allocate it Stock is kept per SKU. If the receipt was posted against one SKU (or none) and the order line names another, the stock is in a different balance. Compare the SKU on the goods receipt line with the order line in the [inventory ledger](/docs/inventory/ledger/). ### My SKU-specific price isn't used A newer price list rule without a SKU outranks an older SKU-specific rule. Give the SKU rule the same or a later **Date Effective From**. ### The order screen shows no variant chooser for my item The order-taking screen shows variants when the item has more than one SKU, or one SKU and **SKU Required** switched on. An item with a single optional SKU is ordered at item level. ## Common questions ### Should every item have a default SKU? Not necessarily. Nothing in xMatix requires one, and lines you add by hand do not take it automatically. Mark a default where it helps people: the published catalogue lists the default variant first, and the purchase frequently-ordered suggestion proposes it when you accept an item. Because several SKUs of one item can be marked default without an error, check the flag when you add or copy variants and keep one default per item. ### Can I change an item's SKU Required flag after go-live? Yes. It affects only lines added after the change. Switching it on does not touch existing lines or stock recorded without a SKU — those stay in their item-level balance, so plan an adjustment or transfer if you want existing stock assigned to variants. Switching it off makes the SKU optional again. ### Are SKU codes the same as barcodes? Not necessarily. The SKU Code is your variant code, and a SKU has no separate barcode field. Barcode scanning on the order screens and order capture can match a scanned or typed value against SKU codes, so if your variants carry their own printed codes, using those as SKU codes lets people scan them directly. ### Can two items share a SKU? No. A SKU has exactly one item, and every line checks that its SKU belongs to its item. If two products genuinely share variants, create a SKU on each item with distinct codes. ## Related topics - [SKU entity reference](/docs/reference/entities/sku/) - [Item lots and lot types](/docs/inventory/lots/) - [Inventory configuration reference](/docs/inventory/configuration/) - [The inventory ledger](/docs/inventory/ledger/) - [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/) - [Trade schemes](/docs/sales/trade-schemes/) - [Frequently ordered items](/docs/procurement/frequently-ordered/) - [Product configurator](/docs/crm/product-configurator/) ---- # Transferring stock between branches URL: https://xmatix.com/docs/inventory/transfers/ Last reviewed: 2026-09-06 A stock transfer moves inventory from one branch (and optionally one company) to another. The normal form is a two-step movement made of two documents: an **Outward** transfer that you create and release, and an **Inward** transfer that the release generates at the destination. **Release Outward** posts the source movement and puts the quantity into a dedicated in-transit state; **Inward Receive** records what physically arrived; **Post Inventory** on the inward document takes the quantity out of transit and into the destination branch. Both release and receive have selective variants, so partial dispatches are normal. A **Single Step** transfer books both sides in one posting for moves that do not travel. ## Start from the transfer register @[guided-image](_img/inventory-transfer-list.png) **Inventory → Transfers** (default view **All Transfers**; the same list is a fixed tab of the Warehouse app) shows one row per document: document number and date, **From Partner Account** and **From Branch**, **To Partner Account** and **To Branch**, **Type** (`Outward`, `Inward` or `Single Step`) and **Status**. The summary cards count the last 30 days' documents by type. An outward document and the inward document it generated are two rows here — filter by the destination branch or open either one and follow its **Related Documents** link to reach the other. ## Prerequisites - Access to the **Inventory** (or **Warehouse**) app through your security profile. Release, receive and posting are separate entity actions and can be granted independently of create/edit. - Sufficient on-hand stock at the source branch for each line — a release that would take a stock bucket negative is rejected. - The source and destination branches, and for a cross-company transfer the destination partner account (**To Partner Account** and **To Branch** are mandatory). - A **Received By** user on the document: release refuses to run until one is set. - For lot-tracked items, the source lot on each line — the release clones it into a destination lot automatically. ## Procedure ### Step 1 — Create the outward transfer @[guided-image](_img/new-inventory-transfer.png) Click **New**. The form asks for **From Partner Account**, **From Branch**, **To Partner Account**, **To Branch** and **Type**, with **Transferred By**, **Received By** and **Transfer Time** under **Additional Details**. Choose `Outward` for a two-step movement or `Single Step` when the goods do not travel — you cannot create an `Inward` document by hand; only a release generates one. Set **Received By** now (the destination user who will accept the goods) so the release is not blocked later. Document date and transfer time are stamped at creation and cannot be changed; saving the header moves no stock. ### Step 2 — Add lines @[guided-image](_img/inventory-transfer-lines.png) On the saved transfer, the **Lines** tab holds one **Transfer Outward Line** per item, SKU and lot: the item, the source **Storage Location** the goods leave, the **Item Lot** for lot-tracked items, **Quantity** (the plan), and **Unit Cost** (carried to the destination unchanged). Each line also has a **Transfer Type**: `On Hand Transfer` (the default) moves physical stock through transit; `Pending Deliveries Transfer` re-buckets stock already sold but not delivered and posts no in-transit quantity. Compare the lines against the pick list before releasing — a wrong lot or location is the usual cause of an *Insufficient stock* rejection. The line's quantity trail is where partial movements stay readable: **Released Quantity** is the running total dispatched, **Pending Release Quantity** is what is still on the shelf, **Closed Quantity** is what the destination has confirmed received, and **Pending Inward Quantity** is released but not yet received. ### Step 3 — Release outward At dispatch, run **Release Outward** to release every line's pending quantity, or **Selective Release Outward** to choose lines and enter a **Requested Quantity** per line (up to its pending release quantity; empty releases the line's full pending amount). Each release: - posts a **Transfer Outward** ledger entry per line for the released quantity, reducing the source branch's stock, and adds the same quantity to a transit stock row held against the destination branch with no storage location — goods in transit sit in no bin; - for lot-tracked items, clones the source lot into a destination lot (same batch, serial, cost and dates, owned by the destination partner and branch) and moves the quantity into that lot's transit counter; - creates a new **Inward** transfer at the destination with one **Transfer Inward Line** per released line, cross-linked to this document, carrying the released quantity and unit cost. A second selective release creates a second inward document. The outward document's **Outward Released** flag turns on only when no line has pending release quantity left; until then it can be released again. Release is refused when the document is already fully released, when **Received By** is empty, or when a release would take source stock negative — fix the line and release the same document again rather than raising another transfer. ### Step 4 — While the goods travel The released quantity is in neither branch's on-hand stock. It shows on the destination's transit row (a stock balance with no storage location) and, for lots, in the destination lot's **Transit** counter, and the outward line shows it as **Pending Inward Quantity**. Investigate an overdue transfer here before considering any adjustment. ### Step 5 — Record the inward receipt At the destination, open the generated inward document, count the delivery and choose the receiving **Storage Location** on each line. Then run **Inward Receive** to receive every pending line in full, or **Selective Inward Receive** to choose lines and enter the quantities that arrived and any **Damaged Quantity**. Receiving adds to the line's **Received Quantity**, marks it received and writes the confirmed quantity back to the outward line's **Closed Quantity**. It does **not** post stock: nothing reaches the destination's on-hand until Step 6. Receive what actually arrived, in one pass per line. Once any quantity is received on a line, the unreceived remainder becomes the line's **Shortage Quantity** and its pending quantity drops to zero — a short receipt closes the line rather than leaving it open for a second delivery. The document's **Inward Received** flag turns on when every line has been received, and the receive actions refuse to run again after that. ### Step 6 — Post the received inward quantity Run **Post Inventory** on the inward document (it requires at least one received line). For every inward line without a ledger reference it posts a **Transfer Inward** entry for the line's quantity into the receiving storage location, removes that quantity from transit, and posts separate **Shortage**, **Damaged** and **Excess** entries where those quantities were recorded — so the destination's available stock reflects what arrived, while the shortage stays visible as its own bucket instead of being written off silently. The receiving lot's storage location is updated to the line's location. Posting is idempotent: lines that already carry a ledger reference are skipped. @[guided-image](_img/inventory-transfer-details.png) Use the **Details** tab to reconcile the document: **Related Documents** links the outward and inward documents to each other, **Handover Details** hold Transferred By, Received By and the times, and **Progress Details** — *Outward Released*, *Inward Received*, *IL Posted* — are computed from the lines. A document can be *Inward Received* and not *IL Posted*: that is exactly the state between Steps 5 and 6. ## Single-step transfers A `Single Step` transfer has plain **Transfer Lines** with a source and a **Destination Storage Location**. **Post Inventory** on it posts the outward and inward effects together — source stock down, destination stock up, no transit leg — and clones the lot for lot-tracked items. **Selective Transfer** posts chosen lines for a **Requested Quantity** up to each line's pending quantity. Use it when the move is instantaneous in practice, such as between two branches that are administratively distinct but physically together. ## Expected result Released quantity leaves the source branch and appears in transit exactly once. After receipt and posting, that quantity leaves transit and enters the destination storage location exactly once, with shortage, damage or excess recorded in their own buckets. Every leg is an inventory ledger entry: a **Transfer Outward** entry from the outward line and a **Transfer Inward** entry from the inward line, each linked to the line that posted it, so the movement reconciles end to end. ## Common problems **"Received By is required to release outward document."** Edit the transfer, set **Received By**, release again. **"Insufficient stock" on release.** The line's lot or storage location does not hold the quantity — check the item's stock at the source, then correct the line; do not release another document to force the move. **Stock is "missing" at the destination.** Check both milestones on the inward document: **Inward Received** (quantities received) and **IL Posted** (ledger entries exist). A document received but not posted has stock still in transit — run **Post Inventory**. **"No received lines found for Inventory Posting on Inward Transfer."** Receive at least one line first. **Cannot receive again.** The document's **Inward Received** flag is already on, or no line has pending quantity. If goods arrived after a short receipt closed the line, the remainder is on record as **Shortage Quantity**; bring the late arrival in through a new movement (an adjustment or a fresh transfer) rather than by editing the closed line. **Status looks wrong.** The Status label (`Draft`, `Approved - Inward`, `Released`, `Received`…) is not maintained by the release and receive actions themselves; the **Progress Details** flags and the line quantities are the machine state. Trust them when reconciling. ## Common questions ### Can I release or receive a transfer in parts? Release, yes, repeatedly: each selective release moves only the requested quantities and generates its own inward document; the remainder stays pending on the outward line. Receive, once per line: the received quantity is what arrived and any remainder is recorded as shortage. Post Inventory after each receipt pass so the ledger and the transit balance catch up. ### Which branch does in-transit stock count against? The destination — the stock is on its way to them — but it is a separate transit balance with no storage location, not part of the destination's on-hand or available quantity, until the received inward lines are posted. Neither branch's bin-level stock includes it before then. ### Where is the warehouse view of the same movement? [Branch transfers: the warehouse view](/docs/warehouse/branch-transfers/) explains what each step means at the bins. Note that destination stock becomes visible only after **Post Inventory** on the inward document, not at **Inward Receive**. ## Related topics - [The inventory ledger](/docs/inventory/ledger/) - [Adjusting stock](/docs/inventory/adjustments/) - [Item lots and lot types](/docs/inventory/lots/) - [Branch transfers: the warehouse view](/docs/warehouse/branch-transfers/) - [Troubleshooting inventory](/docs/inventory/troubleshooting/) ---- # Troubleshooting inventory URL: https://xmatix.com/docs/inventory/troubleshooting/ Last reviewed: 2026-09-02 ## Read the ledger before correcting stock The Inventory Ledger is the evidence surface for a discrepancy. Scope it to the relevant branch, item and time range, then read **Ledger Type**, item or lot, quantity, source document and reversal state together. A populated row identifies the transaction that moved stock; a blank adjustment form cannot establish that cause. @[guided-image](_img/inventory-troubleshooting-context.png) Before adjusting, prove the discrepancy from source documents, ledger movements, lot buckets and physical evidence. Use the correct date and reason, then verify the posted adjustment and resulting balance; an adjustment should document a known difference, not conceal a routing, receipt, transfer or allocation defect. Most inventory surprises in xMatix have short explanations, because stock is not a stored opinion — it is the sum of posted ledger entries, and the entries are all readable. This page gives the working method for the three complaints that cover most cases: a stock figure that looks wrong, a valuation that differs from expectation, and a posting refused because the period is closed. In each case the method is the same: find the authoritative record (the ledger, the policy, the fiscal calendar) and read it before changing anything. ## Stock looks wrong Work through these in order and stop when the figure explains itself: 1. **Read the item ledger.** Open the Ledger console's Ledger tab for the company, branch and item, over a range that starts before the figure was last believed correct. The view shows the opening balance, every posted movement with a running balance, and the closing balance — the row where the running balance departs from expectation is the row to investigate, and it links to its source document. 2. **Look for unposted documents.** A document that exists but has not posted moves nothing: an adjustment before **Perform Inventory Posting**, a transfer still pending outward release, or a received inward transfer whose **Perform Inventory Posting** action has not run. The document being visible in a list tells you nothing about stock — the ledger entry does. 3. **Check in-transit.** Stock released outward on a transfer but not yet received inward is in neither branch's bins; it sits in the in-transit bucket. A branch-level check that ignores in-transit will look short by exactly the traveling quantity. See [Transferring stock between branches](/docs/inventory/transfers/). 4. **Don't double-count corrections.** The ledger corrects by reversal: a changed or deleted posted line shows as the original entries, negated reversal entries, and fresh entries. Read such groups together — the pairs cancel. 5. **For lot-tracked items, read the buckets.** A lot's in-hand quantity includes stock that is on hold, on inspection or allocated; "we have 100" and "100 are available" are different statements. See [Item lots and lot types](/docs/inventory/lots/). ## Valuation differs from expectation 1. **Confirm which accounting book you are looking at.** A tax or management book legitimately values the same stock differently from the primary book. The valuation statement's book picker tells you; the default is the primary book. 2. **Find the policy that resolved.** The costing method comes from valuation policy resolution — most specific scope wins, within the book. An item you expect on FIFO may be caught by a narrower moving-average policy or fall through to the default. The [configuration reference](/docs/inventory/configuration/) has the resolution order. 3. **Remember carrying value is not quantity times latest price.** Under FIFO, moving average or specific identification, the value depends on cost history. Decompose the figure in the Valuation console: the Valuation Lots tab shows the surviving receipt layers and their costs; Cost Consumption shows how each issue was drawn. The arithmetic is inspectable down to the lot. 4. **Check for NRV write-downs.** At period close, stock is measured at the lower of cost and net realizable value; a write-down posted there lowers the carrying figure below cost. The NRV Assessment tab shows what was assessed and written down, per period. 5. **Rebuild period balances before trusting period comparisons.** Period and year columns read a rebuilt cache; after heavy posting or backdated corrections, run the Rebuild action on the statement so the columns catch up. See [Inventory period balances](/docs/inventory/period-balances/). ## A posting is refused because the period is closed Postings that create accounting entries resolve a fiscal period from the document date and require that period to be **Open**. Fiscal periods have three states: Open (posting allowed), Closed (posting blocked, but an administrator can reopen the period), and Locked (final — used once statements are published; not reopenable). The fiscal year has the same discipline: an open period under a closed year still blocks. Your options, in order of preference: 1. **Date the document into an open period.** If the transaction genuinely belongs to the current period, use a current document date. 2. **Ask an administrator to reopen the period** when the posting genuinely belongs in it and the period is Closed (not Locked). Reopen, post, close again. 3. **For corrections to already-posted figures,** use the reversal path: reversals post on a current date precisely so that they land in an open period even when the original's period has since closed. What you should not do is force a back-dated posting into a locked period — the lock exists because statements were published from those figures. ## Common questions ### Why can't I just edit the wrong ledger entry? The ledger is append-only by design: corrections post reversal entries rather than editing rows, which is what keeps the stock history auditable. Fix the *source document* — edit or delete the offending line, or post an [adjustment](/docs/inventory/adjustments/) — and the ledger produces the reversal and the corrected entries itself. The net stock effect is identical to an edit; the difference is that the trail survives. ### The stock figure is genuinely wrong — the goods were miscounted. What now? That is what adjustments are for. Post an adjustment for the discrepancy, using the excess/shortage/damaged/expired buckets so the reason is recorded, and the ledger carries the correction like any other movement. If miscounts are frequent rather than occasional, the structural answer is a cycle counting program (see the warehouse section of the [documentation](/docs/)) rather than more adjustments. ### Who can reopen a closed period? An administrator with access to the fiscal calendar. Reopening is a normal, reversible action for a Closed period; a Locked period is deliberately final. If you find yourself reopening periods routinely, the process problem is upstream — documents are being dated or posted too late — and that is the thing to fix. ## Related topics - [The inventory ledger](/docs/inventory/ledger/) - [Transferring stock between branches](/docs/inventory/transfers/) - [Adjusting stock](/docs/inventory/adjustments/) - [Inventory valuation and costing](/docs/inventory/valuation/) - [Inventory period balances](/docs/inventory/period-balances/) ---- # Inventory valuation and costing URL: https://xmatix.com/docs/inventory/valuation/ Last reviewed: 2026-09-06 xMatix values stock with a perpetual costing engine that replays the [inventory ledger](/docs/inventory/ledger/) into **cost layers** (one per receipt, or one pool for the average methods) and **consumptions** (each issue's draw against those layers). The method — FIFO, LIFO, moving average, weighted average or specific identification — is chosen by a **valuation policy** inside an **accounting book**, and the result is read on the **Inventory Valuation** page. This page explains the engine, the configuration that steers it, the reading surface, and the honest limits of the current implementation. ## Read the screen @[guided-image](_img/inventory-valuation-statement.png) **Inventory → Inventory Valuation** shows the **Valuation Statement**: one row per item with **Qty** and **Value** for the selected company, and a total. The controls match the Inventory Stock page — **Compare by** (no comparison, by branch, by period or by years, each with a *(movement)* variant showing opening, change and closing), **Branches** and **Balance as On** (current, to-date presets, previous month, a fiscal-year end, custom) — plus a money-scale selector and, when the company has more than one accounting book, a book picker. **Rebuild** recomputes the period-balance cache the period and year comparisons read (see [Inventory period balances](/docs/inventory/period-balances/)). Clicking a value opens a drill: **Valuation lots** (the cost layers behind the figure, with remaining quantity and unit cost; filter to open lots or all, month/quarter/year to date or all dates) or **Consumption lots** (the issues that drew from those layers, with quantity, unit cost and cost amount), and **View ledger** where an Item Ledger page is configured. ## How the engine costs stock Every inventory posting hands its new ledger rows to the costing hook. For each affected primary book, item and branch the hook deletes the stored layers and consumptions for that scope and rebuilds them by replaying the scope's ledger movements through the resolved method: - **Cost layers** (*Inventory Cost Lot* records): under FIFO, LIFO and specific identification, one layer per receipt with its original quantity, remaining quantity, unit cost and receipt date, linked to the ledger row that created it. Under moving or weighted average, a single pool layer whose remaining quantity is the whole on-hand balance at the running or period average cost. - **Consumptions** (*Inventory Cost Consumption* records): one row per layer an issue drew from, with quantity, unit cost and cost amount. The rows sharing an issue's ledger reference add up to that issue's cost of goods sold, and that is the amount the engine puts on the cost journal. Carrying value at any moment is the sum over surviving layers of remaining quantity times unit cost, less any recorded NRV write-down. Because the scope is rebuilt wholesale, stored layers cannot drift from the algorithm — but they are derived state: the ledger is the fact, the layers are its valuation. Costing is **best-effort by design**. The inventory posting commits first; if costing fails for a scope — most commonly because the company has no active primary accounting book — the movement still commits and the costing error is logged. A ledger movement with no valuation rows behind it therefore means "check the book and policy", not "the stock did not move". ## Costing methods | Method | How issues are costed | Notes | |---|---|---| | FIFO | Oldest receipt layers consumed first. | | | LIFO | Newest layers first. | Not permitted under Ind AS or IFRS; the book's **Allows LIFO** flag records the opt-in. | | Moving average | A perpetual average recomputed at every receipt. | The engine's fallback when no policy matches. | | Weighted average | A periodic average over the replayed window. | | | Specific identification | Each issue costed at the exact lot it drew, keyed by the movement's item lot. | Implemented by the engine but not offered in the seeded method picker. | | Standard cost | — | Named in the catalog; not computed by the engine. | ## Accounting books An **accounting book** is a valuation perspective for one company (partner account): **Book Type** `Statutory`, `Tax` or `Management`; **Gaap Framework** (Indian, international or US standards); **Is Primary**; **Is Active**; currency; and the opt-in flags **Allows LIFO** and **Allows Standard Cost**. Exactly one active primary book per company is the working assumption: inventory-cost posting takes the first active primary book it finds and skips costing when there is none, and only the primary book persists cost layers — a secondary book is derived by replaying the same movements and storing per-period overlay deltas. Uniqueness of the primary flag is not enforced by the model, so check it when a company's valuation looks wrong. Books belong to the **Finance Setup** app; where that app is not on your launcher, an administrator maintains them. ## Valuation policies A **valuation policy** selects the method for a scope within a book. The form has three parts: @[guided-image](_img/new-valuation-policy-concept.png) Above the tabs, **Partner Account**, **Business Unit** and **Branch** are optional scope keys. The **Accounting Period** tab holds **Effective From** / **Effective To** (the policy is ignored for movements dated outside the window, which is how a method change applies prospectively), **Accounting Book** (resolution is filtered to this book first) and **Costing Level** (a free-text descriptor of the intended cost-pool boundary — see the limits below). @[guided-image](_img/valuation-policy-item-method.png) **Item & Valuation** holds the **Item** and **Item Group** scope keys, the **Valuation Method**, and a **Storage Location** scope key. @[guided-image](_img/valuation-policy-controls.png) **Controls** holds **Is Active** (only an explicit *off* excludes the policy from resolution; deactivating is the safe way to retire a rule) and **Is Default**. **Resolution.** For a movement, candidates are filtered to the book, to active policies and to the effective window. Each non-empty scope key must equal the movement's value; an empty key is a wildcard. Among matches, specificity wins: item +16, item group +8, storage location +4, branch +2, business unit +1. Ties go to the lower **Priority** number, then the later **Effective From**. An unscoped active policy is the book-wide fallback; when nothing matches at all the engine uses moving average. **Is Default** is stored but not read by the resolver — an unscoped policy already wins by having the lowest specificity. ## Current limits to know before you rely on it - **Scope keys the live posting path never supplies.** Inventory-cost posting resolves with book, date, company, branch and item only. Policies scoped to a **business unit**, **storage location** or **item group** do not match at posting time; scope by item and branch. - **Costing level does not create pools.** Layers are keyed by book, item, branch and method. Setting **Costing Level** to batch, serial or storage location does not create separate pools; only specific identification is lot-aware, through the movement's lot. - **Method tokens.** The engine compares exact tokens `FIFO`, `LIFO`, `MovingAverage`, `WeightedAverage`, `SpecificIdentification`. The seeded picker offers `Weighted Average` and `Moving Average` with a space; confirm the stored value resolves before relying on an average-cost policy. - **Validation is not wired to save.** Rules for LIFO under Ind AS / IFRS, method-versus-level coherence, effective-window order and overlapping scopes exist as helpers but nothing calls them when a policy is saved. Contradictory policies can be saved; review the set yourself. - **Priority** is a field on the policy but is not on the create form's tabs. - **Net realizable value is not computed automatically.** The lower-of-cost-and-NRV calculation exists as a service, but no product process runs it: *Inventory NRV Assessment* rows (estimated selling price, cost to complete, cost to sell, resulting NRV, write-down or reversal this run, outstanding write-down) have to be entered against the entity. What the platform does do is post them: period close posts a write-down or reversal journal for each assessment in the period that has no journal yet, flags unposted ones in its advisory checklist, and the Valuation Statement subtracts each item's latest outstanding write-down from cost to reach carrying value. ## Common questions ### Why isn't stock value just quantity times the latest cost? Because cost flow matters. Under FIFO the remaining stock is valued at the costs of the *latest* receipts (the oldest were consumed first); under moving average at an average every receipt has shifted; under specific identification at the actual costs of the exact lots on hand. Two items with the same quantity and the same latest purchase price can carry different values. The **Valuation lots** drill shows the layers behind any figure, so the arithmetic is inspectable. ### A movement is in the ledger but has no valuation rows — what happened? Costing is best-effort. Check, in order: that the company has an active primary accounting book; that the policy's stored method token is one the engine recognizes; and the application logs for the costing error. Fix the cause, then post another movement for the item and branch (or re-post) so the scope is rebuilt — the rebuild replays the whole ledger for that scope, so earlier movements are picked up too. ### Where do I see why an issue was costed the way it was? The **Consumption lots** drill on the Valuation Statement. Every issue has consumption rows naming the layer drawn, the quantity and the unit cost — under FIFO an issue spanning two receipt layers shows two rows at two costs. Under the average methods every row points at the single pool layer, so the drill explains the average, not a specific receipt. ### Can two books show different values for the same stock? Yes — that is the point of books. The primary book is the statutory truth that posts to the general ledger; a tax or management book values the same movements under its own policies, stored as per-period overlay deltas on top of the primary. The book picker on the Valuation Statement appears when a company has more than one book. ## Related topics - [The inventory ledger](/docs/inventory/ledger/) - [Inventory period balances](/docs/inventory/period-balances/) - [Item lots and lot types](/docs/inventory/lots/) - [Inventory configuration reference](/docs/inventory/configuration/) - [Troubleshooting inventory](/docs/inventory/troubleshooting/) ---- # Configuring the mobile app URL: https://xmatix.com/docs/mobile/admin-configuration/ Last reviewed: 2026-09-06 Everything users see in the mobile app is authored from web Setup, in three layers. The **app** layer decides what exists: apps, their navigation items, their pages — the same application metadata the web uses. The **layout** layer decides how each screen renders: mobile layouts designed per entity, and mobile variants of app pages. The **Mobile App record** decides how the app behaves as a program on a device: branding, offline policy, local performance tables, check-in gates, feature switches, and who gets which configuration. Configuration is versioned and fetched by devices on sign-in, app switch and foregrounding — behavior changes ship without a new app build, and devices cache the configuration so a cold offline launch still comes up correctly. @[guided-image](_img/mobile-app-list.png) The **Mobile Apps** registry (**Setup → Design Studio → Apps → Mobile Apps**) is the web Setup surface for these behavioral configurations. Each row is one configuration: its **Name**, the stable **Identifier** devices reference, **Status** (only an Active configuration is handed to devices), the number of security **Profiles** it is assigned to (0 means nobody receives it) and the **Version** devices compare on every fetch. Several configurations can coexist — for example one per brand theme or per field team — with the Profiles tab deciding who gets which. ## Layer 1 — Apps and navigation The mobile tab bar is the app's navigation item list, in order: the first few items become bottom tabs (three on a phone, more on tablets) and the rest fall into the More sheet automatically. Items can be entities, designed app pages, or built-in features (Reports, Dashboards); items marked web-only, hidden or inactive are dropped on mobile. There is no reserved Home slot — a home experience is an app page of the Home type placed first in the navigation. An app page renders on mobile only if it has a mobile layout; without one, users see *This page cannot be displayed on mobile yet.* — so authoring the mobile variant is part of shipping a page, not an afterthought. ## Layer 2 — Mobile layouts Mobile layouts are designed per entity from the entity's Layouts screen, which opens the mobile designer. The create layout doubles as the edit layout (edit is create, populated), and a detail layout takes over the record screen; where no designed layout exists, the app synthesizes a serviceable default (hero header, then line items, related records, field groups and activities). Layouts are also where capture and domain widgets enter the app — attachments, barcode quick-add, product and item catalogues, the approval panel, checklists, child grids and the rest appear only where a layout places them. The web-side design concepts carry over; see [Design a form layout](/docs/customization/layouts/design-a-form-layout/) for the shared foundations. ## Layer 3 — The Mobile App record Setup's **Mobile Apps** page (**Setup → Design Studio → Apps → Mobile Apps**) lists your Mobile App records; each is the behavioral configuration for the apps and profiles assigned to it. The editor is organized in tabs: @[guided-image](_img/new-mobile-app-dialog.png) The create dialog asks only for the human-facing name. **Create** saves the shell — version 1, Inactive, no profiles assigned — and opens the tabbed editor, so nothing reaches a device until you finish the tabs below, set the record Active and assign profiles. The **General** tab is the record's identity and lifecycle surface: name, description and active state, with the header's configuration-version badge incrementing after every save. | Tab | Governs | | --- | --- | | General | Name and description of the configuration | | Branding | In-app theme colors and logos | | Offline & Sync | Which entities are kept on devices, and how | | Projected Tables | Dedicated indexed local tables for high-volume entities | | Settings | Feature switches and free-form typed settings | | Update Channel | Which users receive preview app updates | | Check-In | Attendance gating — whether, where and with what checks | | Location Tracking | The check-in location trail — see [Location tracking](/docs/mobile/location-tracking/) | | Apps | Which apps this configuration applies to | | Profiles | Which security profiles receive it, and per-profile check-in requirement | ### Branding Theme tokens (primary, on-primary, soft accent pairs for light and dark, screen background, surface, border, text) and logo uploads for light mode, dark mode and the splash surface. These apply in-app from configuration; the device's app icon and the native splash are part of the installed build itself and change only with a new build — set expectations accordingly when rebranding. ### Offline & Sync One row per entity, scoped to the app's entities, with the columns that define the device footprint: - **Offline** — whether the entity is kept on devices at all, with an optional **Editable offline** grant. - **Class** — *Master* (synced in full, never age-pruned) or *Transaction* (kept for a rolling window). - **Window (days)** — the transaction window per entity, over an app-level default. - **Mode** — *Auto* (syncs on its own), *Manual* (on demand from the device's Sync Status screen), *Off*. - **Pinned** — hydrated even on low-memory devices that otherwise skip transaction data. - **User override** — lets users adjust the mode on their device; an admin *Off* always wins and cannot be overridden back on. - **Push** — flags the entity for server-initiated refresh hints (subject to the push master switch in Settings). Each row can also carry a **related-data tree**: tick the relations (up to three hops) that must hydrate together — an order with its lines and the masters the lines reference — and the device syncs them as one set. Changing an entity's offline policy bumps the configuration version; devices re-sync the affected entity on their next fetch, preserving un-synced local edits. ### Projected Tables For large entities — items, prices — a projected table gives the device a dedicated, indexed local table instead of the general record store: choose the columns to project, which are indexed, and which fields join the full-text search, plus an optional scope filter. The payoff is fast offline search and lookup at catalogue scale; the cost is device storage, so project deliberately. ### Settings Reserved, individually-edited switches: the ongoing-activity surface (a floating session button for resuming started plans and visits), allowing users to pause a visit plan, allowing them to pause a check-in session, nearby-place discovery for prospecting, route optimization for the day's plan, and the master switch for push sync hints. Below them, a free key/value table (string, number, boolean) carries any further settings the platform reads. ### Update Channel The **Update Channel** tab selects Security Teams whose members receive preview over-the-air updates. Everyone else remains on production, and the same installed app changes channel per signed-in user. This controls JavaScript/configuration delivery only; a native capability still requires a new store build. ### Check-In The attendance gate. *Who* is gated is per profile assignment (the Profiles tab's check-in flag); this tab defines *what* a check-in requires and *where* the gate sits — blocking the whole app on open, or only demanding check-in when specific entities are opened. Gates are individually enabled: location within a radius of the branch (default 250 m), a selfie (every check-in or once per day), working day, working hours, holiday and leave checks. The same gates apply at check-out, and punches land in the resource-availability records. ### Location Tracking The location-tracking tab is separate from the check-in validation switches. It controls whether an open check-in session captures background GPS fixes, the capture interval, upload batch size and minimum movement required before another fix is retained. Turning it on also depends on a mobile build that contains the native background-location capability. ### Apps and Profiles The **Apps** tab restricts which mobile-capable metadata apps the configuration exposes. An empty assignment list means no restriction, not no apps. The **Profiles** tab is the opposite: only assigned Security Profiles can use the Mobile App record, and each assignment independently decides whether its users must pass the check-in gate. ## How changes reach devices Every save bumps the configuration's version. Devices compare versions when they fetch — at sign-in, on app switch, on foregrounding — and apply changes immediately: branding repaints, settings take effect, and offline-policy changes trigger a targeted re-sync of the entities involved, never touching queued user edits. The practical rule: configuration changes propagate within a working session, while anything native — app icon, splash, new device capabilities such as background location — waits for users to install an updated build. ## Related topics - [Apps, entities and records](/docs/concepts/apps-entities-records/) - [Design a form layout](/docs/customization/layouts/design-a-form-layout/) - [How the mobile app is organized](/docs/mobile/navigation/) - [Monitoring sync failures](/docs/mobile/admin-sync-monitoring/) ---- # Monitoring mobile sync failures URL: https://xmatix.com/docs/mobile/admin-sync-monitoring/ Last reviewed: 2026-09-06 When a change queued on a device fails terminally — the server rejected it, or it conflicted with a concurrent edit and its retries are exhausted — the device does two things. It flags the change to the user on their Sync Status screen, where it stays until they fix or discard it; and it files a **Mobile Sync Failure** record on the server for you. That second half is this page: the fleet-wide view of what is failing to sync, without waiting for users to report it. The report itself is sent through the same store-and-forward queue as everything else, so a failure that happens offline still reaches you once the device reconnects. Only terminal failures are reported. Transient errors — network drops, timeouts, server hiccups — retry automatically on the device and never appear here; a queue that is merely waiting for connectivity produces nothing. One record is filed per failed attempt, deduplicated, so a change the user fixes and resubmits into a second genuine failure produces a second record rather than noise. ## The record Mobile Sync Failure is an ordinary entity — browse it as a list, filter it, build views and reports over it. Open **Mobile Sync Failures** from the navigation of whichever app your administrator placed it in (it may sit under **More**), or search for it in the App Launcher. Its fields: @[guided-image](_img/mobile-sync-failure-list.png) The list is the fleet-wide triage queue. In the example above nine Open, Rejected failures cluster on three devices: repeated CheckInInspection creates from one device within two minutes, and an Order create that exhausted five attempts — exactly the patterns the triage section below reads. An empty list means no terminal failure is currently recorded in the selected view; it is not the device's live pending queue. | Field | Meaning | | --- | --- | | Name | Summary headline — entity and operation, e.g. *Order Create failed* | | Source Entity | The entity the queued change targeted | | Source Record Id | The record involved — a device-generated id when a create never reached the server | | Operation | Create, Update, Delete, Action, or UploadFile | | Failure Reason | *Rejected* (the server refused it) or *Conflict* (the record changed on the server underneath the edit) | | Attempt Count | How many times the device tried before giving up | | Error Message | The server's error, as the device recorded it | | Payload | The queued change itself, as data (long payloads are truncated) | | Occurred (UTC) | When the change was originally queued on the device | | Last Attempt (UTC) | When the final attempt failed | | Device Id | The reporting device | | User Name | The signed-in user | | App Version | The app build that filed the report | | Resolution Status | Your triage state; new reports arrive as *Open* | Open one report to read its full payload, error and timestamps together before changing **Resolution Status**. The detail is evidence only: editing or resolving this server record does not retry or discard the original device outbox item. ## How to triage Start with **Failure Reason**, because the two values call for different responses. **Rejected** means the server said no and retrying cannot change that — a validation or business rule the user could not evaluate offline, a permission gap, or a reference to something deleted or renamed. Read **Error Message** for the rule, and **Payload** for exactly what the device tried to write; between them the cause is usually plain. Fix the root cause where there is one (a rule that cannot be satisfied offline, a missing permission, stale configuration), then have the user resolve their side: the change is still sitting on their device under *Needs attention*, and their **Fix** and **Retry** actions are described in [Working offline](/docs/mobile/working-offline/). The resolution always completes on the device — the queued change belongs to it, and nothing you do to the report re-sends it. **Conflict** means two people edited the same record and the device's edit lost the race. There is rarely an administrator-side fix; the value of the report is visibility — which records and teams collide, and how often. The user decides on their device whether to keep or discard their version. Recurring conflicts on the same records are a workflow signal: two roles both editing what one should own. Use **Resolution Status** to run the queue: work *Open* records, and record the outcome as you go so the list stays a to-do rather than an archive. The remaining fields are for patterns rather than single cases — the same **Source Entity** across many users points at a rule or configuration problem; clusters on one **Device Id** or an old **App Version** point at a device or an update that has not landed; **Attempt Count** and the two timestamps tell you whether failures are instant refusals or long-suffering retries. ## What this is not This is not a live view of the sync pipeline. Changes that are pending, in flight, or retrying exist only on their devices — visible to each user on their Sync Status screen — and a healthy fleet files nothing here at all. It is also not a recovery mechanism: the report carries the payload as evidence for diagnosis, but replaying data into the system from reports would bypass the user's decision about their own queued edit. Treat an empty Mobile Sync Failure list as the success condition, and the occasional record as a specific, well-documented conversation to have. ## Related topics - [Working offline: sync status and recovery](/docs/mobile/working-offline/) - [Configuring the mobile app](/docs/mobile/admin-configuration/) - [How offline-first mobile works](/docs/concepts/offline-mobile/) - [Troubleshooting the mobile app](/docs/mobile/troubleshooting/) ---- # Work with approvals on mobile URL: https://xmatix.com/docs/mobile/approvals-on-mobile/ Last reviewed: 2026-09-02 Approvals on mobile happen in two places. The approval panel sits on the record itself and carries the whole lifecycle — submitting, the step-by-step timeline, approving and rejecting, reassignment, recall, and the history of past requests. How approval processes themselves are designed — steps, approvers, entry criteria — is web-side configuration, covered in [Approval processes](/docs/customization/approvals/). Where your administrator has added an **Approvals inbox** to a page of your app, that page lists every request waiting for you (for example your team's attendance regularizations, with their date, times and reason) and lets you approve or reject each one there — rejecting asks for a reason. ## Prerequisites - An approval process configured for the record type, and the approval panel present on its mobile layout — both set up by your administrator. - A connection. Approval decisions post to the server directly; the panel is the one part of a record screen that tells you plainly it is *Not available offline* rather than working from device data. - The right relationship to the request for each action: submitting takes access to the record, deciding takes being the pending step's assignee. ## Procedure This procedure deliberately has no web screenshot. The native approval widget is embedded on the mobile record and has its own timeline and action drawers; the web **Approvals** inbox is a different surface from both the record panel and the mobile Approvals inbox widget. Add a visual only when a demo2 mobile record contains the configured approval panel and a safe request state to inspect without acting on it. ### Step 1 — Find the panel on the record Open the exact business record named by the notification or web inbox, verify its identity and current values, and scroll to the approval panel. It shows a submit card for an eligible record with no open request or the live status/timeline. Confirm connectivity and refresh once before concluding a panel is absent; if entry criteria are unmet, it correctly stays quiet. ### Step 2 — Submit for approval Review the record first, tap **Submit for Approval**, enter remarks that state the decision requested and evidence location, and confirm once. Wait for the panel to switch to timeline view and verify the submission entry, first step and assignee. If nothing changes, check connectivity before tapping again so one request is not mistaken for two attempts. ### Step 3 — Read the timeline Read the timeline from submission downward. For each card verify step name, Pending/Approved/Rejected status, actor, timestamp and comments; open completed entries for details. The single Pending card identifies the current assignee and available action. Compare the record values with what was submitted because a pending approval can lock the record and later changes may require recall. ### Step 4 — Approve, reject or reassign If you are the named assignee, open the pending card, re-check supporting evidence, select **Approve**, **Reject** or **Re-assign**, and enter a durable reason. For reassignment, verify the active user's identity before confirmation. Submit once, wait for server response, and confirm the timeline advances, closes as Rejected, or shows the new assignee exactly as intended. ### Step 5 — Recall or revert Use header actions only after confirming the live request status and explaining why the state must change: - **Recall** appears while the request is **Pending** — it withdraws the request, closing it as **Recalled**. Use it when the submission was premature or the record needs rework; you can resubmit after. - **Revert** appears once a request is **Approved**, where the process allows it — it walks the approval outcome back, recording **Reverted**. Like every action here, it takes remarks, and it stays in the history rather than erasing the approval. ### Step 6 — Read past requests Below the live timeline, open **Past requests** and verify the latest closed request shows decision, actor, status and remark. Drill into the complete trail when resubmitting or auditing a record. Recalls, rejections and reversions remain visible; never infer approval from the record's business status alone when the action history is available. ## Expected result The request has one current state, one visible pending step when action remains, and a complete actor/timestamp/comment trail. Decisions made online immediately update the timeline, while recall, reassign, reject, approve and revert remain preserved in past requests. ## Common problems **The panel says "Not available offline".** Expected: approval state lives on the server and decisions must land there atomically, so the panel does not work from cached data. Everything else on the record still works offline; come back to the panel when you have a connection. **You can see the request but not act on it.** The pending step names its assignee — if that is not you, you get the read-only view by design. If the assigned person is unavailable, someone with the step currently assigned can reassign it; otherwise the process's configuration (or an administrator acting on the web) is the path. **There is no panel on a record you expect to approve.** Either the record type has no approval process, the record does not meet the process's entry criteria, or the panel is not on this mobile layout. All three are administrator-side; nothing on the device switches it on. ## Common questions ### Is there an approvals inbox on the mobile app? Only if your administrator has placed one. The **Approvals inbox** is a widget an administrator drops on a page of your app, usually narrowed to one kind of request (for example attendance regularizations); it lists what is waiting for you and lets you approve or reject from the list. Without it, you act on a request from the record it belongs to. Push notifications, where your organization has them enabled for workflow actions, are what bring a waiting approval to your attention; the notification's subject tells you which record to open. ### Can I approve or reject while offline? No. A decision changes the request's state for everyone — approver, submitter, the next step — and queueing it on a device would mean two sources of truth about whether something is approved. The panel therefore requires a connection and says so, rather than pretending. ### What is the difference between Recall and Revert? Direction and timing. Recall is the submitter's exit while the request is still pending — nothing was decided, the request is simply withdrawn. Revert applies after approval, walking the outcome back with a recorded action. Both leave the full trail in past requests. ### Do my remarks go anywhere? Yes — every action takes optional remarks, and they are stored on the request's action trail, visible in the timeline and in past-request details to anyone who can see the record. Treat them as the durable explanation of the decision, because that is exactly how the next reader will use them. ## Related topics - [Approval processes](/docs/customization/approvals/) - [How the mobile app is organized](/docs/mobile/navigation/) - [Working offline: sync status and recovery](/docs/mobile/working-offline/) ---- # Capture data in the field URL: https://xmatix.com/docs/mobile/capturing-data/ Last reviewed: 2026-09-02 Most field work is capture: a new order, a photo of a shelf, a signature on a delivery, a serial number off a carton. The mobile app treats these as first-class, and — with one exception called out below — they all work offline, queueing on the device and syncing later. Which capture tools you see depends on your organization's layouts: forms are designed per record type, and photo, signature, catalogue and scanning widgets appear only where an administrator placed them. ## Prerequisites - The xMatix mobile app, signed in, with the first sync complete. - Create or edit permission on the record type — the **+** button and **Edit** action simply do not appear without it. - Camera capture (photos, selfies, barcodes) asks for camera permission on first use; the app explains what it needs it for. ## Procedure No web screenshot is shown here: the native mobile form chooses a designed mobile Create layout (with a metadata-driven fallback), writes through the device store-and-forward path, and exposes camera, signature and scanner capabilities that a phone-width web create form cannot evidence. The steps below refer to the native controls; a future visual must be captured from an authenticated demo2 mobile build. ### Step 1 — Create or edit a record Open the correct list and tap **+**, or verify a record's identity before choosing **Edit**. Work through each tab/section, confirm partner, branch and account context first, and read required markers and inline errors. Review server-provided defaults rather than assuming they are correct; offline forms may require you to supply values that would otherwise be defaulted. ### Step 2 — Save, online or offline Review the form, tap **Save** once, and read the result: online confirmation means server acceptance; *Saved offline* means a local durable write awaiting sync. Open [Sync Status](/docs/mobile/working-offline/) and verify one pending item. If rejected later, use **Fix**, correct the exact field messages and resend the same queued change rather than recreating the record. One habit worth forming: save early. The form does not keep drafts, so a half-filled form abandoned by navigation loses its input, while a saved record can always be edited again. ### Step 3 — Attach photos and files After saving the parent record, use **Camera**, **Gallery** or **File** in its attachment section. Preview the selected file, verify orientation/content and remove accidental personal data before upload. Two controls matter: - The record must be saved first; the section tells you so on a brand-new form. - This general attachments section talks to the server directly, so it needs a connection — offline it shows *Not available offline*, and an upload attempted without a network fails rather than queues. Photo steps inside visit tasks are the offline-capable counterpart: a photo taken there is copied into safe storage on the device and queued, with the toast *Photo stored · uploads later* telling you exactly what happened. So if your day is built around visits, capture photos through the visit's own photo tasks and connectivity stops mattering — see [Complete a visit](/docs/field-sales/visits/complete-a-visit/). ### Step 4 — Capture a signature Open the required signature task, explain what is being acknowledged, and let the signer review the record before signing. Use **Clear** for an incomplete mark and accept only after visually confirming the final signature. Verify the task shows captured/complete and, when offline, that one signature upload is queued. A rebuild/version warning belongs with the administrator; do not substitute a photo for a required signature. ### Step 5 — Scan barcodes Grant camera permission only when prompted by a configured scanner, centre one code in the frame, and verify the decoded value or item before accepting it. Scanning appears in three places: - **Filling a field.** In line-item editors, columns whose purpose is a code — serial, batch, lot, IMEI, part or barcode fields — carry a scan icon that opens a full-screen scanner and types the code into the field. Pure text entry by camera: it works offline and reads the common retail and industrial symbologies, QR included. - **Building a document by scanning.** Where your organization added the barcode quick-add screen to a document, the camera is live the moment it opens: each scanned product is added as a line at quantity 1, quantities adjust with a stepper (rescanning does not increment — deliberate, so an accidental second read cannot inflate an order), and a search box covers items whose barcode will not read. Scanned items resolve against the item data on your device, so this too works offline; submitted lines queue like any other change. If an item cannot be added, the strip above the viewfinder says why — not active, not for sale, or the code is not in the product list. - **Jumping to a product.** In the order-taking screen, scanning navigates to the product so you can order it — *Point at the product to jump to it*. ### Step 6 — Use the item catalogues Use configured catalogues to search/filter items, then verify SKU, unit, price, offer and quantity before adding a line. Treat **Price on sync** as unresolved and obtain connectivity before promising the amount. Frequently ordered and live stock/scheme panels require a connection; offline catalogues use the last synced data. Review the final document lines and total, save once, and confirm their queue status like any other form. ## Expected result The record is saved once in the correct context with validated fields and verified captured evidence. Offline-capable forms, visit photos and signatures queue durably and later sync; connection-only attachments or live catalogue operations clearly wait rather than pretending to have uploaded. ## Common problems **The attachment upload failed.** Almost always no connection — the general attachments section is the one capture surface that cannot queue. Reconnect and add the file again; nothing was partially uploaded. If you are on a visit, prefer the visit's photo task, which queues. **A barcode scans but the item is not found.** For quick-add, the item is resolved from the data synced to your device — an item outside your offline scope or newer than your last sync will not resolve until you sync. *No connection — try this one again* means the lookup itself needs a retry; *This barcode isn't in the product list* means the code genuinely matches nothing you can sell. **The scan icon or a capture widget is missing.** These appear where your organization's layout puts them. If a colleague has a scanner on the same screen and you do not, you are likely in a different app or on a different layout — a question for your administrator, not a device setting. ## Common questions ### Are my photos compressed or resized? Photos are re-encoded at capture to keep uploads practical, and the server enforces the size limit and permitted file types — an oversized or disallowed file is refused at upload with a clear failure rather than silently shrunk further. ### Do photos I take carry my location? No. The app does not embed coordinates in captured images. Location, where your organization uses it, is recorded separately — as a stamp on check-in punches and specific records, or as the check-in trail described in [Location tracking](/docs/mobile/location-tracking/) — never hidden inside a photo file. ### Can I capture data for a record I have not synced? You can always create new records offline, and edit anything already on your device. What you cannot do offline is open a record that was never synced to the phone — there is nothing local to edit. If a record you need is routinely missing, ask your administrator about the offline scope for that record type. ## Related topics - [Working offline: sync status and recovery](/docs/mobile/working-offline/) - [Complete a visit on mobile](/docs/field-sales/visits/complete-a-visit/) - [Create an order](/docs/sales/orders/create-order/) - [Configuring the mobile app](/docs/mobile/admin-configuration/) ---- # The xMatix mobile app URL: https://xmatix.com/docs/mobile/ Last reviewed: 2026-09-02 ## Native screen evidence The mobile app is a separate React Native product surface. A web entity form squeezed to phone width does not prove the native form, local outbox or device-only controls, so this overview deliberately has no screenshot until an authenticated demo2 mobile-build capture is available. Use the named controls in the procedures below as the source of truth; web Setup screenshots appear only on the administrator pages where the web UI is the actual product being described. Before a field day, open assigned records while connected, confirm required lookups and reference data are present, and check the last successful sync. After saving, use Sync Status to distinguish local persistence from server confirmation and resolve any item marked **Needs attention**. The xMatix mobile app puts your organization's apps, lists and records on a phone or tablet, built offline-first so field work continues through dead zones and syncs when coverage returns. It is provided by your organization — your administrator tells you how to install it — and it signs in with the same account and permissions you use on the web. This section goes deeper than the onboarding material: the screens, the sync machinery you can see and act on, and the configuration behind it all. If you are new to the app, start with [Using xMatix on mobile](/docs/getting-started/mobile-app/) for installing, signing in and the first sync, and [How offline-first mobile works](/docs/concepts/offline-mobile/) for the offline model — local data, the outbox, and how conflicts are handled. The pages here assume that foundation and build on it. ## What's in this section | Page | What it covers | | --- | --- | | [How the mobile app is organized](/docs/mobile/navigation/) | Tabs, the app drawer, lists and records — and why the shape of the app is your organization's configuration | | [Working offline: sync status and recovery](/docs/mobile/working-offline/) | The Sync Status screen in depth — pending changes, fixing rejected edits, conflicts, and the Storage & Database screen | | [Capturing data in the field](/docs/mobile/capturing-data/) | Forms, photos and attachments, signatures, and barcode scanning where your organization has configured them | | [Approvals on mobile](/docs/mobile/approvals-on-mobile/) | The approval panel on a record — submit, approve, reject, reassign, recall, and the request history | | [Sense on mobile](/docs/mobile/sense-on-mobile/) | The Sense Agent chat screen — what it can do on a phone and how access is granted | | [Location tracking](/docs/mobile/location-tracking/) | Organization-controlled location capture during check-in sessions — what is recorded, when, and how it stays visible to you | | [Configuring the mobile app](/docs/mobile/admin-configuration/) | For administrators: mobile layouts, app pages, branding, offline policy and the rest of the Mobile App record in web Setup | | [Monitoring sync failures](/docs/mobile/admin-sync-monitoring/) | For administrators: the records devices file when a queued change fails for good, and how to triage them | | [Troubleshooting](/docs/mobile/troubleshooting/) | Symptom-first help — missing records, stuck changes, sign-in, stale data, storage warnings | ## One account, one set of permissions Nothing in the mobile app runs on a separate identity. You sign in with your work account, and entity, field and record-level security apply exactly as they do in the browser — the app stores and shows only what you are allowed to see. What differs on mobile is *presentation* (layouts designed for a phone) and *availability* (a configured subset of data is kept on the device for offline use). When a record you can open on the web is absent on the phone, the cause is almost always the offline scope, not your access — [Troubleshooting](/docs/mobile/troubleshooting/) walks through how to tell. ## Users and administrators The first six pages are written for people using the app day to day. The two administrator pages cover the other side: everything that shapes the app — which tabs exist, which entities work offline and for how far back, branding, check-in gates, update channels — is authored in web Setup and versioned out to devices, with no app-store release needed for configuration changes. If the app looks different from this documentation, that is usually configuration, and the [configuration reference](/docs/mobile/admin-configuration/) explains which lever is involved. ## Related topics - [Using xMatix on mobile](/docs/getting-started/mobile-app/) - [How offline-first mobile works](/docs/concepts/offline-mobile/) - [Navigating xMatix: apps, lists and records](/docs/getting-started/navigation/) - [xMatix on mobile](/products/mobile/) ---- # Location tracking on mobile URL: https://xmatix.com/docs/mobile/location-tracking/ Last reviewed: 2026-09-02 Where your organization has enabled it, the mobile app can record a location trail during your working session — the path of a field day, used for route review, visit verification and journey planning. The design principle throughout is that tracking is bounded and visible: it runs only while you are checked in, it announces itself on the device while it runs, and it never operates without the operating system's location permission, which stays in your hands. This page explains exactly when it records, what it records, and where the boundaries are. This page deliberately has no web screenshot. The evidence that matters is native and stateful — the pre-check-in disclosure, operating-system permission prompt, active-session notification and check-out transition — and a responsive web page cannot prove any of them. Add a visual only from an authenticated demo2 mobile build in a test check-in session that can be ended immediately after capture. Verify the organization has enabled tracking, review the disclosure before check-in, confirm the operating-system permission and look for the persistent tracking indicator while the session is active. Check-out must end capture; revoking permission must degrade or stop it without silently widening collection. ## When it records — and when it cannot The trail is tied to the attendance check-in session. Recording starts when you check in, and stops when you check out — there is no other trigger. Off shift, before check-in, after check-out, or in an organization that has not enabled the feature, no trail is captured. Where your organization allows pausing a check-in session, pausing also stops location capture until you resume; the session timer and the trail freeze together. The check-in screen tells you before you start: when tracking is enabled, it states that your location will be recorded at roughly the configured interval while you are checked in — including with the app in the background — and that recording stops at check-out. You check in with that disclosure in front of you, not after the fact. ## What is captured While a session is active, the app records position fixes on the cadence your organization configured — typically about once a minute, and only when you have actually moved a minimum distance, so standing at a counter does not generate a stream of identical points. Each fix carries coordinates, their accuracy, a timestamp, and where the device provides them, speed and heading. That is the whole payload: the trail is position over time, not screen activity, not audio, not anything else on the phone. Fixes are batched on the device and sent to the server in groups. Offline, batches queue like any other change and go up when connectivity returns, so a day in poor coverage still produces a complete trail — with nothing extra captured because of the gap. ## Visible while it runs Continuous tracking is deliberately impossible to miss on the device. The operating system shows its own location-in-use indicator, and the app posts a persistent notification for the duration — *xMatix is tracking your visit path* / *Location is recorded while you are checked in.* When the notification is gone, tracking is not running. This is the practical answer to "is it recording right now": look at the phone, not the documentation. ## Permissions stay with you Background tracking requires the OS-level "always allow" location permission, which only you can grant and can revoke later in device settings. When your organization has enabled a session trail, the app treats that background permission as a check-in prerequisite: the check-in screen explains why it is needed, shows the device-settings path, and keeps **Check in** disabled until permission is granted. This prevents a session from starting under a disclosure that the phone cannot actually honor. Your organization may separately require a single location *at the moment of check-in* as an attendance gate; that one-time stamp is governed by its own rule and is distinct from the continuous trail. ## Trail versus stamp It is worth separating continuous tracking from the single location stamps the platform uses elsewhere, because they are governed differently. A check-in punch may carry the location where it happened; a form's geography field fills with *Use my location* when you tap it; a visit activity may stamp the record it creates. Each of those is one point, captured at one deliberate moment, attached to one record. The trail described on this page is the only continuous capture in the app, and it exists only inside a check-in session in organizations that have turned it on. ## Common questions ### Can the app track me after I check out, or off shift? No. Capture starts at check-in and stops at check-out; outside a session there is no recording mechanism running. The persistent notification gives you an independent check — if it is not showing, the app is not tracking. Uninstalling nothing and configuring nothing on the device changes this boundary; it is how the feature is built. ### What if I deny the location permission? If continuous tracking is enabled for the selected mobile app, check-in stays disabled until background location access is granted. If tracking is not enabled, the separate attendance configuration may still require a one-time location fix for the punch. The check-in screen states which requirement is blocking the action; permission changes are made through the operating system and take effect when the app rechecks them. ### Who can see my trail? Your organization, under its own security configuration — trails are organizational records like other work data, visible to the people your organization's roles and permissions allow, typically managers reviewing routes and journey plans. The app itself gives no other party access. If you want the specific answer for your organization, your administrator can tell you which roles see location data. ### Does location tracking drain the battery? It costs something — continuous GPS always does — but the design keeps it modest: fixes on an interval rather than continuously, a minimum-distance filter, balanced accuracy rather than maximum, and batched uploads. A normal working day is well within a phone's budget. If battery is a problem in the field, a power bank solves more than any setting will. ## Related topics - [Attendance](/docs/field-sales/attendance/) - [Complete a visit on mobile](/docs/field-sales/visits/complete-a-visit/) - [Configuring the mobile app](/docs/mobile/admin-configuration/) ---- # How the mobile app is organized URL: https://xmatix.com/docs/mobile/navigation/ Last reviewed: 2026-09-02 ## Native navigation evidence This page intentionally does not show a narrow browser capture. The native tab navigator, **More** sheet, app drawer and offline badges are implemented in the mobile application rather than the responsive web shell, so a demo2 web list would be visually similar but technically the wrong screen. The control names and behavior below are grounded in the native navigator and list implementation; add a visual only when it comes from an authenticated demo2 mobile build. The mobile app is built from the same three ideas as the web: apps group the work, lists show records of one type, and records are where the detail lives — see [Apps, entities and records](/docs/concepts/apps-entities-records/) if those are new. What is different on a phone is the frame around them: bottom tabs instead of a sidebar, an app drawer instead of an app switcher, and screens designed for a thumb. Almost none of that frame is fixed. The tabs you see, their order, their icons, whether there is a Home page at all — all of it comes from how your organization configured the app, which is why your app can legitimately look different from a colleague's or from screenshots in this documentation. ## Tabs come from your app The bottom tab bar is the active app's navigation, in the order your organization arranged it. On a phone the first three items become tabs; on a tablet more fit. Everything beyond the cap collects under a **More** tab, which opens a sheet of tiles rather than navigating anywhere — and if nothing overflows, there is no More tab at all. A tab can be one of three things: - **An entity** — a list of records (customers, orders, visits) with the full list toolkit described below. - **A page** — a screen your organization designed, such as a home page with recent activity, quick actions, KPI tiles and charts. There is no built-in Home screen; if your app opens on a welcome page, that page was authored, and if none was, the app simply opens on its first tab. - **A built-in feature** — currently **Reports** and **Dashboards**, which render on the server and therefore need a connection. Online-only tabs show a small cloud badge while you are offline so you know before tapping. ## The app drawer The grid icon at the top left opens the drawer, which is an app launcher, not a menu. It lists every app available to you as cards; tapping one rebuilds the tab bar from that app's navigation. Star an app to pin it and the grid splits into **Pinned** and **All apps**. The drawer also anchors two things that belong to you rather than to any app: a **Preferences** link (appearance, language, notifications, data and sync) and your account row, which opens your **Profile**. Switching between organizations (**Switch Organization**) and between mobile apps (**Switch App**, when you have more than one) lives on the Profile screen. If your profile grants more than one mobile app, the app asks you to pick one at start-up on a **Choose an app** screen. ## Lists An entity tab opens a list, and the header carries the working set of tools: - **Views** — the same saved views as the web, plus **All**. The view picker sits in the header; your organization's default view is preselected. - **Search** — the magnifier opens a search bar scoped to the list. - **Filter, Sort and Columns** — Filter has its own header icon; Sort and Columns live in the **⋮** menu and show a dot when you have overridden the view's defaults. Your choices are remembered per view. - **Filter pills and summary cards** — where your organization configured them, quick filter pills and KPI summary cards appear under the header. Tapping a summary card filters the list to that bucket; tapping it again clears it. - **Recent records** — chips for records you recently opened, one tap back into any of them. Rows render the way the list was designed — as cards when a card layout exists, otherwise as compact rows — and load a page at a time as you scroll, with a `Page n of m` footer. Pull down to refresh. The **+** button creates a record when you are allowed to; a long press on a row offers its configured actions, including Delete where permitted. All of this works against the data on your device, so a list behaves the same with or without a network — only the freshness differs. ## Records Tapping a row opens the record. If your organization designed a mobile detail layout for the entity, that layout takes over the screen entirely. Otherwise the app builds a sensible default: a hero header with the record's title and status, then tabs for the record's line items, **Related** records, **Details** (the fields, in collapsible groups) and **Activities** where the entity tracks them. The header collapses as you scroll, shows who else is currently viewing the record, and its **⋮** menu carries **Edit**, the entity's configured actions, favouriting, and **Delete** — each appearing only when you are allowed to use it. ## Everything else in the frame The bell in the header opens **Notifications**. The assistant icon opens the **Sense Agent** chat when your account has a Sense AI license — see [Sense on mobile](/docs/mobile/sense-on-mobile/). A small floating pill appears at the top of the screen when you are offline or a sync is running; tapping it opens the Sync Status screen described in [Working offline](/docs/mobile/working-offline/). ## Common questions ### Why does my app look different from a colleague's? Because the shape of the app is configuration, and configuration is scoped. You may be in a different app (check the drawer), your organization may assign different mobile apps to different security profiles, and views, filter pills and summary cards are all authored per entity and per view. Same platform, different fit-out. If something you need is genuinely missing rather than differently arranged, that is a question for your administrator. ### Where is the Home screen? There is no built-in one. A home page is something your organization designs — typically recent activity, quick actions and a few KPIs — and places first in the app's navigation, where it lands in the first tab slot. If your app opens straight onto a list, your organization has not authored a home page for it, and nothing is wrong. ### Why does a tab show a cloud icon sometimes? That tab needs the server right now. Reports and Dashboards render server-side, so they carry a cloud badge whenever you are offline; an entity tab shows the same badge when its data is not kept on your device. Everything without a badge keeps working offline. The badge disappears on its own when the connection returns. ### How do I switch organizations or apps? Open the drawer, tap your account row to open **Profile**, and use **Switch Organization** or **Switch App**. Switch App appears only when your profile grants more than one mobile app. Switching apps swaps the whole frame — tabs, branding, offline configuration — while switching organizations changes whose data you are working in. ## Related topics - [Navigating xMatix: apps, lists and records](/docs/getting-started/navigation/) - [Apps, entities and records](/docs/concepts/apps-entities-records/) - [Working offline: sync status and recovery](/docs/mobile/working-offline/) - [Configuring the mobile app](/docs/mobile/admin-configuration/) ---- # Sense on mobile URL: https://xmatix.com/docs/mobile/sense-on-mobile/ Last reviewed: 2026-09-02 ## Native Sense evidence The native chat screen uses the mobile chat session and transport, not the responsive web assistant. A phone-width web screenshot would therefore misrepresent the navigation chrome, history menu and mobile result cards, so this page stays text-only until an authenticated demo2 mobile-build capture is available. Before relying on an answer, confirm connectivity, read the cited record context and open important results in their source screen. Never place passwords, private keys or unrelated personal data into the composer. The assistant icon in the app's header opens **Sense Agent** — the same Sense assistant you may know from the web, as a full-screen chat built for a phone. It is the same brain behind a different frame: the same agents answer, the same permissions bound what they see, and the same governance applies — Sense on your phone can read exactly what you can read and nothing more. What the assistant can and cannot do is covered in [Asking Sense about your data](/docs/sense-ai/chat/) and [How Sense AI is governed](/docs/concepts/sense-governance/); this page covers what is specific to the mobile surface. ## The chat screen A new chat opens centred on one question — *How can I help today?* — with the invitation to ask about data, records, reports, dashboards, or actions. Answers stream in as they are generated, and the response is not limited to text: Sense returns rich cards with records, figures and actions you can tap. Long-running requests are queued as jobs and keep working while you do something else — a useful property on mobile, where the answer to a heavier question can be waiting when you come back to the screen. The **⋮** menu in the header holds **New chat** and **History**. Conversations are stored with your account on the server, not on the phone, so your history survives the device and reopens where you left off; hiding a conversation removes it from your history list. ## Where Sense appears in the app The chat icon travels with you — it sits in the header on home and page tabs and on entity screens alike, so the assistant is one tap away from wherever a question occurs. Separately from chat, if your organization uses [Sense nudges](/docs/sense-ai/nudges/), those appear in the app too: cards on list and record screens surfacing something worth acting on, with the same dismiss and snooze controls as on the web. Nudges are computed on the server, so like chat they appear when you are connected. ## Access and connectivity Sense on mobile is gated by the same per-user Sense AI license as on the web. Without one, the assistant icon stays out of the header entirely, and reaching the screen another way shows *Sense AI not available* with the advice to contact an administrator — licensing is an organization decision, not a device setting. Sense also needs a connection. The assistant reasons over live data on the server; there is no offline mode for it, by design — a cached answer about moving data would be a wrong answer waiting to happen. This is the practical split to remember on a patchy day: your records, lists and capture keep working offline, and Sense rejoins when the network does. ## Common questions ### Why do I have Sense on the web but not on my phone? You almost certainly do have it — check for the assistant icon in the header rather than the tab bar or drawer, where it does not live. If the icon is genuinely absent while web chat works, the likely cause is that your mobile session has not yet refreshed your entitlements; signing out and back in picks them up. Failing that, ask your administrator to confirm your Sense AI license. ### Is the mobile assistant less capable than the web one? It is the same assistant — same agents, same data access, same permission boundary, and history in common since conversations live on the server. The differences are of surface, not substance: the phone gives Sense one full screen rather than a side drawer, and some things an answer links to (a large report, a dense dashboard) are simply better read on a bigger display. ### Can Sense change my data from the phone? Only the way it can anywhere: by proposing, and you confirming. Actions surface as explicit cards and buttons — nothing runs from a chat message alone, and everything Sense does happens under your identity, inside your permissions, on the record. The governance model is the same on every surface; [How Sense AI is governed](/docs/concepts/sense-governance/) states it in full. ## Related topics - [Asking Sense about your data](/docs/sense-ai/chat/) - [How Sense AI is governed](/docs/concepts/sense-governance/) - [The nudge library](/docs/sense-ai/nudges/) - [How the mobile app is organized](/docs/mobile/navigation/) ---- # Troubleshooting the mobile app URL: https://xmatix.com/docs/mobile/troubleshooting/ Last reviewed: 2026-09-02 Most mobile surprises come down to one of three honest states: the data was never in the device's offline scope, a queued change needs your attention, or a feature genuinely needs the server right now. The app tells you which — on the Sync Status screen, in a badge, in a plainly-worded message — so the method here is always the same: find what the app is saying before changing anything. Each section below is a symptom, in the order people hit them. This cross-symptom page stays text-only because the relevant evidence moves between the native entity list, Sync Status queue, sign-in, metadata refresh and Storage & Database screens. One generic responsive-web screenshot would be unrelated to most symptoms. Capture the exact native screen and state named by the symptom when reporting a real incident; do not reuse a healthy list as proof of an outbox or device-storage problem. For a missing record, first confirm the active app, entity, selected view, recent items and list controls. View selection, search and filters can hide records independently of offline scope, so clear them before escalating to synchronization. Record the app, view, last sync time and connection state; then inspect Sync Status for the entity's offline mode, age window and queued failures. Include the row's reference code when reporting a rejected change, but redact customers, insights and search terms from support screenshots. ## A record shows on the web but not on mobile Your access is not the issue — permissions are identical on both surfaces. What differs is what is *stored on the device*, and that is configured per record type: 1. **Check the record type's row** on the Sync Status screen's offline data card ([how to read it](/docs/mobile/working-offline/)). **Off** means your organization does not keep this type on devices; **Manual** means it syncs when you tap the row; a missing row means the type is outside the offline scope entirely. 2. **Check the age.** Transaction-type records are kept for a rolling window — an order from last year may be older than the window and legitimately absent, while the customer it belongs to (master data) is fully present. 3. **Check the last sync time.** A record created on the web minutes ago arrives with the next sync — pull down to refresh the list, or tap **Sync now**. If the scope itself is wrong for how your team works — a record type you need daily marked Off, a window too short — that is a configuration request for your administrator, who adjusts it centrally in the [Mobile App configuration](/docs/mobile/admin-configuration/). ## My changes haven't reached the server Open the Sync Status screen and read the Changes card — it distinguishes changes that are merely waiting from changes that need you: 1. **Waiting to sync** items need connectivity and the app in the foreground; they send on their own. The floating pill at the top of the screen is red while you are offline. 2. **Needs attention** items are stopped for a reason the row states — rejected with the validation message, conflicted with a concurrent edit, or blocked behind another failed change. Each has its resolution path, walked through step by step in [Working offline](/docs/mobile/working-offline/). 3. **A session that expired** pauses sending without losing anything — sign in again and the queue resumes. When you contact support or your administrator about a failed change, include the `Ref:` code from the row — it locates the same failure in the server logs. ## I can't sign in The distinction that matters is a fresh sign-in versus an existing session. An existing session survives offline: relaunching the app with no network keeps you signed in and working from device data. A *fresh* sign-in — after signing out, or on a new device — needs a connection, because your identity is verified by the server. So: if you signed out in the field with no coverage, you are locked out until you have network again, with your queued data safe but inaccessible until you sign back in. Online and still failing? Try the web with the same credentials. If the web fails too, it is an account matter — password, account status, access — for your administrator, not an app problem. Sign-in itself is covered in [Signing in to xMatix](/docs/getting-started/sign-in/). ## A tab or feature shows a cloud icon or says "Not available offline" That surface needs the server right now, and the badge is the app saying so before you tap. Reports and Dashboards render server-side; the general attachments section, approval actions, Sense chat and a few lookup panels are in the same category. Nothing is broken — reconnect and they return. Everything without the badge keeps working from device data. ## Data or layouts look stale Fresh data and fresh *configuration* travel separately: 1. **Data** — pull down to refresh the list you are looking at, or **Sync now** on the Sync Status screen for a full pass. 2. **Layouts, fields, labels, translations** — these are metadata, refreshed in the background around syncs. To force it, use **Refresh Metadata** under Preferences → Data & Sync; it re-downloads entities, layouts and translations. This is the fix when your administrator says "I changed the form" and your phone still shows the old one. 3. **App behavior and branding** — configuration is fetched at sign-in, app switch and foregrounding; background the app and return, or sign out and in, to pick up a just-published change. ## The app warns about storage Low device storage pauses offline downloads (the sync button renames itself to **Sync changes** — your outgoing changes still send) and shows a banner saying sync is limited. Three remedies, in order of effort: free device space outside the app; run **Optimize database** on the Storage & Database screen, which reclaims reclaimable space and says how much; and if your role does not need some record types offline, switch their rows to Manual or Off where your organization allows it. The Storage & Database screen's per-entity breakdown shows exactly what is taking the space. ## A photo or file I added is missing on the server Two different capture paths behave differently, and knowing which you used answers the question. Photos taken inside visit tasks queue offline — check the Sync Status screen for a *File upload* row still waiting or needing attention. Files added through a record's general attachments section upload directly and need a connection at the moment of upload — if it failed offline, the file was not queued; add it again while online. Details in [Capturing data](/docs/mobile/capturing-data/). ## When to involve your administrator Bring in an administrator when the cause is configuration or account-side: a record type outside the offline scope, a validation rule rejecting legitimate offline work, a missing capture widget or scanner, licensing (Sense), or sign-in failures that reproduce on the web. Give them three things: what the Sync Status screen shows, the `Ref:` code of any failed change, and the app version from Preferences → Advanced → Diagnostics — that combination usually turns a mystery into a lookup, since terminally failed changes also reach them as [sync failure records](/docs/mobile/admin-sync-monitoring/). ## Related topics - [Working offline: sync status and recovery](/docs/mobile/working-offline/) - [Using xMatix on mobile](/docs/getting-started/mobile-app/) - [How offline-first mobile works](/docs/concepts/offline-mobile/) - [Where to get help](/docs/getting-started/help/) ---- # Working offline: sync status and recovery URL: https://xmatix.com/docs/mobile/working-offline/ Last reviewed: 2026-09-02 The offline model — local data, a durable outbox, visible sync — is explained in [How offline-first mobile works](/docs/concepts/offline-mobile/). This page is the practical companion: the **Sync Status** screen where that model becomes something you can read and act on, and the **Storage & Database** screen behind it. You will rarely need either on a good day; you need them the day a change is flagged, a record seems missing, or the phone runs low on space. No web screenshot is used here because Sync Status, the durable device outbox and Storage & Database are React Native screens backed by the device's local store. A phone-width web list would show neither queued changes nor offline retention state, and staging those states through retry, discard or delete actions would be destructive. The named native controls below remain the source of truth until demo2 mobile-build captures can be made from pre-seeded, disposable queue states. ## Prerequisites - The xMatix mobile app, signed in, with the first sync complete — see [Using xMatix on mobile](/docs/getting-started/mobile-app/). - Nothing else. Everything on this page is available to every user; there are no special permissions involved. ## Procedure ### Step 1 — Open the Sync Status screen Open the app drawer, tap **Preferences**, and under **Data & Sync** tap **Sync status**. The row carries a red badge with the number of changes still waiting on your device, so you can see from Preferences whether there is anything to look at. There is a shortcut too: whenever you are offline or a sync is running, a small floating pill appears at the top of the screen — tapping it lands on the same place. ### Step 2 — Read the offline data card The **Offline data** card lists each record type kept on your device with its record count, its last sync time, and live progress while a download runs. A row that failed turns red with the reason — tap it to read the full server response. For record types your organization has marked as user-adjustable, the row carries **Auto**, **Manual** and **Off** choices, so you can stop syncing something you do not use (an admin-disabled record type cannot be switched back on from the device). The **Sync now** button at the top pushes your pending changes up and pulls fresh data down in one pass; while the device is low on storage it renames itself to **Sync changes**, because downloads pause but your outgoing changes still go. ### Step 3 — Read the changes queue The **Changes** card is the outbox. It splits into two groups: - **Waiting to sync** — changes doing fine on their own: **Pending** (not sent yet), **Syncing…** (being sent now) and **Retrying** (a network hiccup; the app retries by itself with a growing wait between attempts). You do not need to do anything here except be online at some point. - **Needs attention** — changes that will not proceed without you: **Rejected**, **Conflict** and **Blocked**. A **Retry all** button re-queues the lot when the underlying cause (say, a permissions fix on the server) has been addressed. Each row shows what the change is (`Create · Order`, `File upload · Visit` and so on), a summary of the values it carries, and — for failed rows — the error and a `Ref:` code you can give your administrator, which finds the same failure in the server logs. ### Step 4 — Fix a rejected change **Rejected** means the server refused the change and retrying alone will not help — typically a validation rule, a permission, or a reference to something that no longer exists. Open the row and read the message; field-level validation errors are listed individually. Then either: - Tap **Fix** (available for creates and edits) — the record form opens pre-filled with the values from the failed change, you correct the offending field, and save. The correction replaces the original queued change under the same identity, so the server applies it once — no duplicate is created however many times you resubmit. - Tap **Discard** if the change should not happen at all. The confirmation is explicit — discarding abandons the queued change and reverts it on your device, and cannot be undone. Failed changes stay on the device until you do one of these; nothing is dropped silently. ### Step 5 — Resolve a conflict or a blocked change **Conflict** — flagged as *Changed on the server since your edit* — means someone else changed the record while your edit was queued. The retry button becomes **Keep mine**, which resends your version. If the conflict keeps coming back, take the deliberate route: your values are visible in the row's summary, so note what you changed, **Discard** the queued change, pull down to refresh the record, and re-apply your edit on top of the current server version. That way you decide with both versions in view. **Blocked** means the change depends on another queued change that failed — a line item waiting on the creation of its order, for instance. Resolve the parent row first; the blocked rows release automatically once it goes through. ### Step 6 — Reset the offline data when the cache looks wrong Under **Maintenance**, **Reset offline data** clears the downloaded data and re-downloads it from the server. It is the right tool when local data looks inconsistent with the web in a way a normal sync does not cure. It is deliberately safe with respect to your work: pending changes are kept and sync as usual — the confirmation dialog tells you how many you have before you commit. ### Step 7 — Check the Storage & Database screen Back in Preferences, **Storage & database** shows what the offline data actually costs: total size on disk, a per-record-type breakdown, and counts of un-synced edits. Two maintenance actions are safe to run any time: **Optimize database** reclaims free space (the screen suggests it when worthwhile and says how much it will recover), and the integrity check verifies the local database. The **danger zone** at the bottom is different in kind: **Delete all offline data** erases everything on the device *including any changes that have not reached the server* — the one action on either screen that can cost you queued work. Read its warning as written, and check the Changes card is empty first unless losing the queue is what you intend. ## Expected result The **Changes** card reaches zero after the device reconnects, no row remains under **Needs attention**, and the record can be opened from another signed-in device or the web experience with the same saved values. If the queue is not empty, do not repeat the business transaction: open the remaining row, use its status and reference code to choose **Fix**, **Retry**, or **Discard**, and confirm the count falls only after that deliberate action. ## Common problems **The queue is not draining.** In order: check you are actually online (the floating pill is red with a wifi-off glyph when not); bring the app to the foreground and tap **Sync now**; and check whether your session has expired — an expired sign-in pauses sending without discarding anything, and the queue resumes the moment you sign in again. **Downloads stopped and the button says "Sync changes".** The device is low on storage. Offline downloads pause to avoid making it worse, but your outgoing changes keep sending. Free up space, or use Optimize database, and downloads resume. **A record type never syncs.** Check its row on the offline data card. **Off** or **Manual** means that is the configured behavior — Manual rows sync when you tap them, Off rows not at all. If the row is missing entirely, the record type is not in your organization's offline scope; that is an administrator setting, not a fault. ## Common questions ### Does sync run when the app is closed? Partially. The operating system grants the app periodic background windows — at best roughly hourly, entirely at the OS's discretion — in which it sends pending changes and refreshes data. Treat that as a bonus, not a guarantee: the dependable way to get a day's work up is to open the app with a connection and let the pill or the Sync Status screen confirm the queue is empty. ### Can retrying or fixing a change create a duplicate? No. Every queued change carries its own identity, and a fix or retry resends under the same identity, which the server recognizes and applies once. This is also why an interrupted sync — connection lost mid-send, app killed mid-sync — resumes cleanly rather than double-applying. ### What can actually delete my pending changes? Exactly two things, both deliberate: tapping **Discard** on an individual change, and **Delete all offline data** on the Storage & Database screen. Signing out does not delete them, restarting the phone does not, **Reset offline data** does not, and an expired session only pauses them. ### What does "Blocked" mean and why can't I retry it directly? The change references something that itself has not synced — usually a record created offline whose creation failed. Sending the dependent change first would fail anyway, so the app holds it and points you at the real problem. Fix or discard the parent change; the blocked ones follow automatically. ## Related topics - [How offline-first mobile works](/docs/concepts/offline-mobile/) - [Using xMatix on mobile](/docs/getting-started/mobile-app/) - [Troubleshooting the mobile app](/docs/mobile/troubleshooting/) - [Monitoring sync failures](/docs/mobile/admin-sync-monitoring/) ---- # Adjustments, loans and advances URL: https://xmatix.com/docs/payroll/adjustments-and-loans/ Last reviewed: 2026-09-05 Not everything in a month's pay comes from the salary structure. A **Payroll Adjustment** is a one-off earning or deduction — a bonus, a penalty, arrears — applied to one employee in one payroll period. A **Loan / Advance** is money given ahead of salary and recovered in installments run by run. Both flow into the run automatically at calculation time; the procedure below covers entering them so they land where you expect, and states what the calculation does and does not read. Both live on the **Payroll** app bar (App Launcher → search *Payroll*): **Payroll Adjustments** and **Loans & Advances**. ## Prerequisites - The **Payroll Period** the item belongs to, already created. - For adjustments that should post to a specific account: a [Payroll Component](/docs/payroll/employees-and-structures/) with the right type and GL mappings to reference — an adjustment without a component has no accounts and will fail the run's posting. - For disbursing loans and advances: an **Employee Loan** or **Employee Advance** control account configured for the company, and the bank GL account the money leaves from. ## Procedure @[guided-image](_img/payroll-adjustment-list.png) ### Step 1 — Enter a payroll adjustment On **Payroll Adjustments**, click **New** and fill: **Resource** (the employee), **Payroll Period**, **Adjustment Type** (Earning or Deduction), **Amount**, **Reason**, optionally the **Payroll Component** it belongs to, and **Is Arrear** where the item relates to an earlier period. What the run does with it when it [calculates](/docs/payroll/payroll-runs/): - Every adjustment on the run's period for the employee is included when its **Approval Status** is *Approved* or blank; a value such as *Pending Approval* or *Rejected* excludes it. No approval process ships for adjustments — the status is set by editing the record — so use it as your own review gate: enter items as Pending Approval and flip them to Approved before Calculate. - A zero amount is ignored. The amount becomes an extra component line on the employee's detail: a deduction when the Adjustment Type is *Deduction* **or** the linked component's type is Deduction; otherwise it follows the component's type (Earning, Reimbursement, Employer Contribution), defaulting to Earning. - The linked component supplies taxability and the GL and payable GL accounts. Without a component the line posts nowhere — the run's **Post** fails naming it — so link a component for anything that must reach the ledger. - Adjustments are never prorated, and **Is Arrear** is recorded for reporting only; the amount is taxed and posted in the period it is entered on. Put the adjustment on the **same Payroll Period record** the run uses, not merely the same month. ### Step 2 — Create the loan or advance @[guided-image](_img/loan-advance-list.png) On **Loans & Advances**, click **New** and fill the header — **Name**, **Resource**, **Partner Account**, **Branch** — and the details: **Principal Amount** and **Installment Amount** (the amount to recover each run); leave **Outstanding Amount** blank. **Interest Rate** and **End Payroll Period** are stored for reference only. After saving, set **Advance Type** (Salary Advance, Travel Advance, Loan, Personal Loan, Vehicle Loan, Education Loan, Home Loan) by editing the record — the create form does not show it. The record starts in **Requested**: a record of intent, invisible to payroll until disbursed. @[guided-image](_img/new-loan-advance.png) ### Step 3 — Disburse it Click **Disburse** on the saved record, naming the bank GL account the money leaves from. Disbursement posts the payout — the control account debited, the bank credited — and raises a receivable open item against the person for the full principal. The control is the record's **Control GL Account** if set; otherwise the company's **Employee Loan** control when Advance Type is exactly *Loan*, and the **Employee Advance** control for every other type (including Personal, Vehicle, Education and Home Loan — set Control GL Account explicitly if those should hit the loan control). The record becomes **Active**, Outstanding Amount equals the principal, and the disbursement date, journal (**GL**) and open item are stamped. Disburse refuses a record that already has a journal, has no Resource, or has a principal of zero. ### Step 4 — Let payroll recover it No further action is needed: every payroll calculation deducts one installment from each of the employee's **Active** loans that has a positive outstanding balance and a positive installment amount — the configured installment, or the remaining balance if that is smaller. The recovery reduces net pay, the loan's Outstanding Amount and the open item in the same pass, and writes a **Loan Recovery** row (amount, outstanding after, run, period) so the register builds itself. When the balance reaches zero the loan sets itself to **Closed**. Three things the recovery does *not* do: it does not wait for **Start Payroll Period** or stop at **End Payroll Period** (an Active loan is recovered in every run of any period), it does not charge interest, and it does not distinguish advance types. If recovery must pause, edit the installment amount to zero or set the Status away from Active for that run, and restore it afterwards. If a run is recalculated, its recoveries are rolled back first — the balance and open item are restored and a loan the recovery had closed is reopened — and then recovered afresh, so a recalculation can neither eat a second installment nor lose one. @[guided-image](_img/loan-advance-detail-recovery.png) ### Step 5 — Review the balance @[guided-image](_img/loan-advance-detail-details.png) The **Details** tab holds the persisted terms and references; **Outstanding Amount** should equal the principal minus the Recovery tab's rows. For a register across employees, use the **Loans & Advances** list (principal, installment, outstanding per arrangement) and the **Loan Recoveries** entity (search the App Launcher), which lists every installment with its run and period. A fiscal-year loan movement schedule exists in the finance engine but is not exposed as a button on the Fiscal Year record. ## Expected result An adjustment appears once, as one extra line on the intended employee's detail for the intended period. A disbursed loan shows **Active**, an Outstanding Amount equal to its principal, a journal and a receivable open item. After each calculated run, the loan's outstanding, its Recovery rows, the payroll deduction line and the control-account balance move by the same installment; any disagreement is a reason to stop before posting and recalculate after the source record is corrected. ## Common problems **The adjustment didn't show up in the run.** Check four things: it is on the same Payroll Period record the run uses, it is on the right Resource, its Amount is not zero, and its Approval Status is Approved or blank — Pending Approval is deliberately excluded. Fix and recalculate; recalculation replaces the pass. **The run posted the adjustment nowhere / Post failed on the adjustment line.** The adjustment has no Payroll Component, so the line has no GL accounts. Link a component and recalculate before posting. **The loan isn't being recovered.** Recovery requires Status **Active** with a positive Outstanding Amount and a positive Installment Amount. A loan still in Requested was never disbursed; a loan with no installment amount has nothing to recover per run. **Disbursement is refused.** The principal must be positive, the record must have a Resource, it must not already carry a journal, and a control account must resolve — on the record or from the company's Employee Loan / Employee Advance control configuration. **The loan hit the wrong control account.** Only the exact type *Loan* selects the Employee Loan control; every other type falls to Employee Advance. Set **Control GL Account** on the record before disbursing. ## Common questions ### Can I recover more or less than the configured installment one month? The calculation takes the configured installment (or the remainder, if smaller). To change the pace, edit the Installment Amount before the run calculates — the change applies from the next calculation. A final short installment needs no action; the recovery never exceeds the outstanding balance. ### How do adjustments differ from editing the salary structure? Scope. A structure change affects every employee on that structure, every period. An adjustment affects one employee in one period and leaves a reasoned record behind. Use adjustments for one-offs and corrections; change structures when the ongoing deal changes. ### What happens to an unrecovered loan when an employee leaves? Enter the outstanding balance as a Deduction line in the [full and final settlement](/docs/payroll/full-and-final/), crediting the loan's control account; the settlement refuses to post if recoveries exceed what is payable. The settlement does not update the loan record itself — edit the loan to zero its outstanding and set it Closed or Written Off afterwards. ### Where does the money show in the ledger? Disbursement: employee loan/advance control debited, bank credited, plus a receivable open item on the person. Each recovery: a deduction line in the payroll accrual crediting that same control, with the open item reduced in step. The control account's balance is therefore the sum of open loan balances — reconcilable, like every control in the [subledger model](/docs/finance/subledgers/). ## Related topics - [Running payroll](/docs/payroll/payroll-runs/) - [Full and final settlement](/docs/payroll/full-and-final/) - [Employees and salary structures](/docs/payroll/employees-and-structures/) - [AR and AP subledgers](/docs/finance/subledgers/) ---- # Payroll run approval URL: https://xmatix.com/docs/payroll/approvals/ Last reviewed: 2026-09-01 Between "the numbers look right" and "the numbers are in the ledger" sits a sign-off. Payroll runs are wired into the platform's [approval engine](/docs/customization/approvals/) with a seeded process, and the connection runs deeper than a status stamp: a payroll run's **final approval posts the accrual to the ledger automatically**, so approving is not an opinion about the run — it is the act that commits it. ## The seeded process xMatix ships an approval process for payroll runs so the gate exists on day one: | Setting | Seeded behavior | | --- | --- | | Entry condition | Runs in **Draft** qualify | | Submission | Auto-submit — a qualifying run enters the process without a separate submit click, and its status shows pending approval | | Steps | One approval step, resolving a specific user as approver | | Recall | The submitter may recall their own pending request | | Notifications | Sent on submission, approval, rejection and revert | Treat the seeded process as scaffolding: the step's approver must be pointed at your payroll approver, and you can reshape it freely in the approval designer — more steps, team or role approvers, entry conditions on amount, timeouts. Everything on the [approval processes](/docs/customization/approvals/) page applies; approvers can act from the web inbox or [on mobile](/docs/mobile/approvals-on-mobile/). ## What each decision does to the run The approval outcome is mirrored onto the run itself, so the run's own status always tells the truth without opening the approval record: | Decision | Effect on the run | | --- | --- | | Approved | Approval status Approved; the run is marked Approved and the accrual **posts to the ledger** — journal, statutory payables, per-employee net-pay open items — landing the run in Posted | | Rejected | Approval status Rejected; the run returns to **Review** for correction and recalculation | | Recalled | The approval status clears; the run returns to **Draft** | | Reverted (sent back a step) | Approval status back to Pending; the run sits in **Review** while the earlier step re-decides | The bridge is idempotent and safe against the one race that matters: a run that is already posted is never posted again by an approval decision, and a rejection or recall arriving after posting does not un-post the ledger — the posted state wins, because the ledger is the record. ## When approval succeeds but posting fails The approval decision and the ledger posting are two acts, and the platform refuses to let a posting problem corrupt the approval record: if posting fails on final approval — a component missing its GL mapping, no Payroll Payable control configured — the approval stands, the failure is logged, and the run remains approved but unposted. The fix is ordinary: resolve the named configuration gap and run **Post** on the run directly. This is also why the run's own **Post** action exists alongside the approval path — the same posting, reachable by hand. ## Common questions ### Can we run payroll without the approval gate? The posting action works directly on a calculated run, so operationally yes — but the gate is the control that separates preparing payroll from committing it, and payroll is exactly where a second pair of eyes pays for itself. If the seeded single step does not fit, reshape the process rather than abandoning it. ### Who should the approver be? Someone who is not the person preparing the run — the platform's maker-checker option can enforce that the submitter cannot approve their own request. Typically the finance controller or HR head approves what the payroll operator prepares. ### The run was approved — why is it not posted? Posting on approval can fail for configuration reasons (an unmapped component, a missing control account) without failing the approval. Check the run: approved but with posting status NotPosted means exactly this. Fix the named gap and post the run directly — see [Troubleshooting payroll](/docs/payroll/troubleshooting/). ### Can we approve on mobile? Yes — payroll runs surface in the same approvals inbox as every other entity, on web and [on mobile](/docs/mobile/approvals-on-mobile/), with the same decisions available. ## Related topics - [Approval processes](/docs/customization/approvals/) - [Running payroll](/docs/payroll/payroll-runs/) - [Approvals on mobile](/docs/mobile/approvals-on-mobile/) - [Troubleshooting payroll](/docs/payroll/troubleshooting/) ---- # Payroll configuration URL: https://xmatix.com/docs/payroll/configuration/ Last reviewed: 2026-08-16 Payroll is the module where configuration *is* the product: every amount a run computes and every account it posts to comes from data an administrator set up. This page is the reference checklist — what must exist before the first run, per legal entity, and what each piece controls. Work it top to bottom; the order matters because later pieces reference earlier ones. ## 1. Control accounts Posting resolves liability accounts by **control type** on the company's GL accounts. Configure one account per type the company uses: | Control type | Used for | | --- | --- | | Payroll Payable | Every employee's net pay (per-employee open items), full-and-final net settlements, payroll-settled expense claims | | PF Payable | Provident-fund deductions and employer contributions; the PF challan clears it | | ESI Payable | State-insurance amounts; the ESI challan clears it | | Professional Tax Payable | PT deductions; the PT challan clears it | | Salary TDS Payable | Income tax deducted on salary; the period TDS challan clears it | | LWF Payable | Labour welfare fund amounts; the LWF challan clears it | | Employee Loan / Employee Advance | Disbursed loans and advances; payroll recoveries clear them | | Bank | Salary payouts, challan deposits, loan disbursements | Also set the company profile's **default bank GL account** if the company holds more than one bank account — the salary payment batch derives its bank from it, and several banks with no default is a deliberate error, not a guess. See [Chart of accounts](/docs/finance/chart-of-accounts/) for the account model. ## 2. Payroll components The component catalog defines every pay element once: component type (Earning, Deduction, EmployerContribution, Reimbursement), taxability, calculation type, statutory type where applicable, proration and display flags, sort order — and the **GL mappings** posting depends on: - Earnings and reimbursements: an expense GL account (debited). - Deductions: a payable GL account (credited). - Employer contributions: **both** — expense debited, payable credited. A component used in a run without its required mapping fails the post by name. Map accounts at component level; every structure using the component inherits them. ## 3. Salary structures Per pay population, a structure with ordered component lines: calculation type and value (fixed, or a percentage of CTC or of a named earlier component), optional min/max clamps, proration flags, effective dates. Sequence matters — a percentage-of-component line must come after the component it references. See [Employees and salary structures](/docs/payroll/employees-and-structures/). ## 4. Employees and compensation Each person on payroll needs an employee record (payroll company, statuses, tax regime, statutory applicability flags) and an active compensation record naming their structure and CTC. Bank account, IFSC, PAN and UAN belong on the person record — the payment batch and statutory filings read them from there. ## 5. Payroll periods One period per pay cycle, with start and end dates (they drive proration and attendance), the pay date (it becomes the accrual's posting date), and the frequency. Statutory challans and the TDS projection are keyed per period, so create periods deliberately rather than ad hoc. ## 6. Statutory rule tables Per legal entity, effective-dated: the PF rule (wage ceiling, rates), the ESI rule (wage threshold, rates), professional-tax slabs per state (with the February variant where the state has one), and LWF rules per state (fixed amounts, frequency). Mechanics on the [statutory page](/docs/payroll/statutory/). All amounts and rates are your data — nothing statutory is hardcoded. ## 7. Income-tax rule tables Per financial year and regime: the regime rules (standard deduction, rebate parameters, surcharge cap, cess, rounding unit, what the regime allows), salary tax slabs (with age bands for the Old regime), surcharge slabs, and the deduction section masters (ceilings, senior variants, regime availability, aggregate cap groups). Rows without a company scope act as a shared pack for every legal entity, with company-specific rows overriding — ship one pack, override only where a company genuinely differs. **If a financial year's tables are missing, TDS projection skips rather than guesses** — seed the new year's tables before its first April run. See [Income tax on salary](/docs/payroll/income-tax/). ## 8. The approval gate The seeded payroll-run approval process needs its single step pointed at your approver, or reshaped entirely — steps, entry conditions, maker-checker. Final approval posts the accrual, so treat approver assignment as part of go-live, not an afterthought. See [Payroll run approval](/docs/payroll/approvals/). ## 9. Access Payroll data is as sensitive as data gets in a business system. Scope who can see and act on runs, payslips, compensation and declarations through [security profiles](/docs/administration/security-profiles/) — separating the payroll operator (prepare, calculate) from the approver (approve, and thereby post) at minimum. ## Go-live checklist | # | Item | Verified by | | --- | --- | --- | | 1 | Control accounts per company, default bank set | A test post and payment resolve without account errors | | 2 | Components mapped to GLs | Post succeeds; no line-named failures | | 3 | Structures built, sequenced, clamped | A test calculation matches a hand-worked employee | | 4 | Employees + compensation complete | Run's skipped count is zero, or explained | | 5 | Periods created for the year | Pay dates land where finance expects the accrual | | 6 | Statutory tables current | PT, PF, ESI, LWF amounts match the authority's current figures | | 7 | Tax tables for the financial year, both regimes | TDS column is non-zero for taxable employees | | 8 | Approval step assigned | A test run reaches the approver's inbox | | 9 | Security profiles scoped | A non-payroll user cannot open runs or payslips | ## Related topics - [Employees and salary structures](/docs/payroll/employees-and-structures/) - [Statutory deductions and challans](/docs/payroll/statutory/) - [Income tax on salary](/docs/payroll/income-tax/) - [Security profiles](/docs/administration/security-profiles/) ---- # Employees and salary structures URL: https://xmatix.com/docs/payroll/employees-and-structures/ Last reviewed: 2026-09-05 Everything a payroll run computes traces back to three records: the **Employee** (who is on payroll, for which company, and under what terms), the **Resource Compensation** record (their cost-to-company and which salary structure applies), and the **Salary Structure** (the component lines that turn that figure into earnings, deductions and contributions). Get these three right and the run is arithmetic; get them wrong and the run tells you — an employee with no usable compensation record or structure is counted as **skipped**, not silently paid zero. ## Where the records live In the **Payroll** app (App Launcher → search *Payroll*), **Resources** on the top bar lists the people; **Employees** is under **More** where your administrator has added it, otherwise search *Employees* in the App Launcher. **Salary Structures**, **Salary Components**, **Payroll Components** and **Resource Compensations** are reached the same way — type the name into the App Launcher search box. All of them are ordinary records: **New** opens the form, the name opens the detail page, and access follows your [security profile](/docs/administration/security-profiles/). ## The employee record @[guided-image](_img/employee-list.png) Begin on the **All Employee** list. Each row is one Employee keyed to one **Resource**, with the employee code and the HR dates. Open a name for the detail page; use **New** only after confirming the person has no Employee record yet. @[guided-image](_img/new-employee-concept.png) The form's required fields are **Name**, **Employee Code**, **Resource**, **Partner Account**, **Branch**, **Employment Type** and **Date Of Joining**. The Details group also carries **Payroll Company**, **Salary Payment Mode** (defaults to BankTransfer), **Department**, **Grade**, **Employment Status** (defaults to Active) and **Pay Type** (defaults to Monthly). @[guided-image](_img/employee-detail.png) After saving, the detail page groups everything payroll will consult: | Group | Fields | How payroll uses them | | --- | --- | --- | | Basic details | Resource, Employee Code, Department, Grade, Employment Type (Full Time, Contract, Consultant, Intern, Permanent), Employment Status (Active, On Notice, Exited), Pay Type (Monthly, Hourly, Daily, Piece Rate), Salary Payment Mode (Bank Transfer, Cash, Cheque) | **Resource** keys every posting, payslip and open item. Only **Employment Status = Exited** changes the calculation — it excludes the person from new runs. Employment Type, Pay Type and Payment Mode are recorded for HR and reporting; the calculation prorates by calendar days regardless of pay type, and the salary payment batch always reads bank details from the Resource. | | Organization details | Partner Account, Payroll Company, Business Unit, Branch, Cost Center | A run includes employees whose **Payroll Company** *or* **Partner Account** equals the run's company. Branch and Business Unit are dimensions carried onto postings. Department and Cost Center are declared as lookups without a backing entity, so they may offer no values. | | Employment dates & status | Date Of Joining, Confirmation Date, Probation End Date, Date Of Exit, Settlement Status (Active, Exit In Process, Settled) | Informational until exit: posting a [full and final settlement](/docs/payroll/full-and-final/) sets Settlement Status to Settled, Employment Status to Exited and fills Date Of Exit from the last working day. | | Statutory & tax details | Tax Regime (Old Regime / New Regime), PF Wage Cap Override, Pf / Esi / Pt / Tds / Lwf Applicable | **Tax Regime** selects the regime the salary-TDS projection applies (New when blank) and **Tds Applicable** unticked skips the projection. The PF, ESI, PT and LWF boxes and the PF wage-cap override are stored as configuration of record but **not read by the calculation** — whether a person pays PF or ESI is decided solely by the components on their salary structure. | The detail page also has a **TDS Calculation Sheet** tab — a read-only worksheet that previews the employee's salary-tax computation without writing a projection (see [Income tax on salary](/docs/payroll/income-tax/)). The payment and filing identity — bank account number, IFSC, PAN, UAN, Aadhaar, designation — lives on the linked **Resource**, not on the Employee. That is deliberate: payroll postings, loans, expense claims and open items are all keyed on the Resource, so one identity reconciles across modules. ## Resource compensation records A **Resource Compensation** ties a Resource to a **Salary Structure** with a **CTC** amount, an **Effective From** date (optionally Effective To), an **Is Active** flag and a **Revision Reason**. When a run calculates, it takes the employee's active compensation record with the **latest Effective From** that names a salary structure — so a raise is a *new* record with a later Effective From, and history is preserved rather than overwritten. Effective To is not consulted: deactivate a record (Is Active off) if it must stop applying before a newer one exists. An employee with no such record is skipped and counted on the run header. The **CTC** figure is the basis for any component whose calculation is a percentage of CTC, and it is what the salary-TDS projection uses as the monthly earning for a brand-new employee who has no calculated months yet — so enter it in the same unit your structures assume. ## Salary structures and their lines A **Salary Structure** is a reusable template — "Field staff", "Managers", "Contract" — holding an ordered list of **Salary Component** lines. The structure header carries Structure Name, Effective From, Pay Frequency (Monthly) and Is Active; of these, only the lines matter to the run — the header's dates and frequency are descriptive. Each line has a **Sequence**, a **Component Name**, a **Calculation Type**, a **Value**, optional **Min Amount** / **Max Amount**, an **Is Active** flag and a link to a **Payroll Component** master. The run loads a structure's active lines in sequence order and computes each: - **Fixed** — the entered Value. - **Percentage** — Value per cent of the compensation record's CTC when **Is Percentage of CTC** is ticked, otherwise Value per cent of the component named in **Percentage Of**, which must appear *earlier* in the sequence (basic pay first, then the allowances that reference it). A basis that cannot be resolved yields zero. - **Slab** on a component whose statutory type is **PT** — resolved against the professional-tax slab table for the gross accumulated by the lines *before* it in the sequence (so place PT after the earnings), with the February amount when the period ends in February. See [Statutory deductions](/docs/payroll/statutory/). - A component whose statutory type is **TDS** takes the month's persisted tax projection instead of a formula. See [Income tax on salary](/docs/payroll/income-tax/). - **Formula** and **Manual** (and Slab on anything other than PT) fall back to the stored Value — the Formula text is not evaluated. After the amount is computed, Min/Max clamps apply and it is rounded to two decimals. Components flagged proratable are then scaled by payable days over calendar days when the employee has loss-of-pay days in the period; the shortfall on earnings and reimbursements is recorded as the employee's loss-of-pay amount. Percentage components that depend on another component always use its full, un-prorated amount as the basis, so proration does not compound through the chain. Two things the line stores but the run ignores: the line's **Effective From / Effective To** window (all active lines apply in every period — deactivate a line to retire it) and, when a Payroll Component master is linked, the legacy per-line **Component Type**, **Statutory Flag**, **Taxable** and **Pro-rata** fields, which the master overrides. ## The payroll component catalog Structure lines do not define ledger behaviour themselves — they reference a **Payroll Component** master, and the master owns what the component *is*: | On the component master | Why it matters | | --- | --- | | Component Code, Component Type: Earning, Deduction, Employer Contribution, Reimbursement | Decides which side of the run's totals the amount lands on — earnings and reimbursements raise gross, deductions raise total deductions, employer contributions cost the employer without touching net — and which side of the accrual journal | | Statutory Type: PF, ESI, PT, TDS, LWF, Gratuity | PT and TDS switch the calculation rule described above; PF, ESI and TDS also roll the amount into the run detail's PF / ESI / TDS totals that the register and challans read | | Taxability: Taxable, Non Taxable, Partially Taxable | Carried onto every calculated line for reporting | | GL Account and Payable GL Account (both required) | The expense account debited and the liability account credited at posting — a missing mapping fails the post by name rather than guessing | | Is Proratable, Sort Order | Whether loss-of-pay days scale the amount; the order of lines on the payslip and register | | Display On Payslip, Is Part Of Gross / CTC / Net Pay, Is Arrear Eligible, Formula Expression, Based On Component Codes | Classification flags. None of these changes the calculation today: totals follow Component Type, and no formula is evaluated | Because the catalog is shared, "Basic", "HRA" or "PF employee contribution" is defined once — its accounts included — and every structure that uses it stays consistent. ## Common questions ### Why was an employee skipped by the run? Because the run could not price them: they have no active Resource Compensation record naming a salary structure, or the structure has no active component lines. The run header shows total, processed and skipped counts, so a skip is visible immediately. Fix the compensation record or the structure and recalculate — recalculation replaces the earlier pass. ### How do I give someone a raise mid-year? Create a new Resource Compensation record for the person with the new CTC and the new Effective From date, leaving the old one in place. The run always picks the active record with the latest Effective From, and the old record remains as history. If the raise also changes the pay mix, point the new record at a different salary structure. ### Where do bank details for salary payment come from? From the Resource record — bank account number and IFSC — read at the moment the payment batch is generated, and shown masked (last four digits) on the payslip. If they are missing, the batch line is still created without them, so keep the Resource current before pay day. ### Can two companies in one tenant have different structures? Yes. Employees carry a Payroll Company, and runs are per company — each legal entity has its own components, structures, professional-tax slabs and control accounts. Salary tax rule tables can be shipped once as shared rows and overridden per company only where they genuinely differ. ### I ticked "Pf Applicable" — why is no PF deducted? Because applicability flags are not consulted by the calculation. PF is deducted only when the employee's salary structure contains a component with statutory type PF — normally a Percentage line based on the basic component, clamped with Max Amount to the wage ceiling. The same applies to ESI and LWF; see [Statutory deductions and challans](/docs/payroll/statutory/). ## Related topics - [Running payroll](/docs/payroll/payroll-runs/) - [Statutory deductions and challans](/docs/payroll/statutory/) - [Payroll configuration](/docs/payroll/configuration/) - [Adjustments, loans and advances](/docs/payroll/adjustments-and-loans/) ---- # Expense claims through payroll URL: https://xmatix.com/docs/payroll/expense-integration/ Last reviewed: 2026-09-01 Expense claims can be reimbursed two ways: paid directly from the bank, or **settled through payroll** so the employee receives one combined payout with their salary. The payroll route is a subledger move, not a recalculation — the claim's expense was already booked when the claim posted, so payroll never re-accrues it as an earning. What moves is the liability: from "we owe this employee a reimbursement" to "it is part of what payroll pays them". No amount is counted twice, and both modules stay reconcilable because everything is keyed on the same person record. ## The claim side An expense claim carries a **reimbursement mode**; claims meant for the salary payout are set to Payroll. The claim lives its normal life in the expenses module — entry, policy checks, approval, posting. Posting the claim books the expense (expense accounts debited, employee payable credited) and raises the employee-payable open item; that posting is the prerequisite for the payroll settlement, because you can only move a liability that exists in the ledger. ## The settlement move On a posted, payroll-mode claim, the **Settle via Payroll** action performs the move: one journal debits the employee payable and credits the Payroll Payable control for the claim's open amount, the employee-payable open item is settled, and the claim is stamped with the payroll run it rode with and marked settled and paid — from the expense module's point of view, the reimbursement is done. The action asks for confirmation and refuses the cases that would corrupt the trail: a claim not yet posted, or one whose employee payable is already settled. | Stage | Ledger effect | | --- | --- | | Claim posted (expenses module) | Dr expense accounts / Cr Employee Payable, open item raised | | Settle via Payroll | Dr Employee Payable / Cr Payroll Payable, open item settled, claim tagged with the run | | Salary payout | The payroll payable is discharged with the salary payment | ## Why it is not an earning A tempting design would add the reimbursement as a pay component — and it would double-count: the expense hit the P&L when the claim posted, so adding it to gross pay would book it again. The settlement move keeps the P&L untouched and shifts only the balance-sheet liability. It also keeps tax clean: a reimbursement settled this way never inflates gross earnings or the TDS basis. The corollary: a payroll-settled reimbursement is not a payslip line, because it never enters the run's calculation. The employee sees the claim reimbursed in the expenses module and the money in the combined payout; the payslip documents the salary calculation only. ## Eligibility, precisely A claim is ready for payroll settlement when all of these hold — worth encoding in your period-close checklist for claims: - Reimbursement mode is **Payroll** (a direct-reimbursement claim should be paid from the bank instead). - The claim is **posted** — approval alone is not enough; the liability must be in the ledger. - It is not already settled or paid, and not already included in a payroll run. - The claimant is on the paying company's payroll, so the liability lands in the right company's payroll payable. For the full claim lifecycle — entry, policies, approval, posting and direct reimbursement — see the [expenses documentation](/docs/expenses/). ## Common questions ### Does the reimbursement show on the payslip? No, and deliberately: it never enters the payroll calculation, so it cannot appear as a calculated line. The claim itself — visible to the employee in the expenses module — is the record of the reimbursement, stamped with the run it was settled alongside. ### When in the payroll cycle should claims be settled? After the claims are posted and before the salary payment goes out, so the combined payout covers them. The settlement is a ledger move independent of the run's own calculate/post sequence — it does not require the run to be in any particular status, and it never changes the run's figures. ### Is the reimbursement taxed? The payroll settlement neither adds to gross earnings nor touches the TDS basis — tax treatment is decided in the expenses module by the claim's own nature and your policies there, not by the payout route. ### What if the claim was settled via payroll by mistake? The move is a posted journal, so the correction is a reversal in the ledger — reverse the settlement journal to restore the employee payable, then reimburse directly. The claim's stamps (settled, paid, included-in-run) identify exactly what to unwind. ## Related topics - [Expenses documentation](/docs/expenses/) - [Running payroll](/docs/payroll/payroll-runs/) - [AR and AP subledgers](/docs/finance/subledgers/) - [Recording and applying payments](/docs/finance/payments/) ---- # Full and final settlement URL: https://xmatix.com/docs/payroll/full-and-final/ Last reviewed: 2026-09-05 When an employee exits, one document closes the relationship: the **Full & Final Settlement**. You enter what the company still owes — salary up to the last working day, leave encashment, gratuity, pending reimbursements — and what the employee owes back — notice recovery, unrecovered loans, final TDS — as lines, and **Post** writes the result once: payable expenses debited, recovery payables credited, and the net owed to the person raised as a Payroll Payable open item. Posting also flips the employee to **Settled** and **Exited**, so the next payroll run leaves them out automatically. The settlement is a posting and closure document, not a calculator: it validates, nets, posts and closes; the amounts themselves are yours to compute per policy. ## Where it lives Open the **Payroll** app from the App Launcher and choose **More → Full & Final Settlements**. The list shows every settlement with its Resource, last working day and net; the name opens the record, whose header carries **Edit**, **Delete** and **Post**, and whose tabs are **Lines** and **Details**. ## Prerequisites - The employee's exit in motion: last working day known, final attendance and unpaid-leave inputs settled. - Outstanding [loans and advances](/docs/payroll/adjustments-and-loans/) reviewed, so the recovery amounts are current. - A Payroll Payable control account configured for the company, and the expense and payable GL accounts at hand for every line you will enter. - The employee's regular payroll stopped after their final normal run — the settlement is instead of, not in addition to, another month's salary. ## Statuses | Status | Set by | | --- | --- | | Draft | Creation; the record is fully editable | | Posted | **Post** — the journal exists, the employee is closed, the record no longer posts | The picklist also offers Approved, In Progress and Paid, but no action sets them; if your process uses them, set them by editing the record and treat them as labels. ## Procedure @[guided-image](_img/full-final-list.png) ### Step 1 — Create the settlement Click **New** and fill the header: **Name**, **Resource** (the exiting person), **Partner Account** (the legal employer), **Branch**, and **Last Working Day**. Leave **Net Settlement** blank — Post computes it. The last working day matters beyond record-keeping: it becomes the posting date of the settlement journal and, if the employee has no exit date yet, their Date Of Exit. @[guided-image](_img/new-full-final.png) ### Step 2 — Enter the payable lines On the saved record's **Lines** tab, click **New** for each amount owed to the employee — salary till the last working day, leave encashment, gratuity, pending reimbursement. Each **F&F Line** has a **Name**, a **Component Type**, an **Amount**, a **Description**, a **GL Account** and a **Payable GL Account**. For a payable line, set Component Type to anything other than *Deduction* (Earning or Payable read naturally) and fill the **GL Account** it should debit — Post refuses a payable line without one. Compute the amounts per your policies and keep one line per component so the posted journal stays readable. ### Step 3 — Enter the deduction lines Add a line for each recovery — notice-period recovery, the outstanding balance of any loan or advance, final tax — with Component Type exactly **Deduction** and the **Payable GL Account** it should credit: the loan's control account for a loan recovery, the salary-TDS payable control for tax. The settlement's net is payables minus deductions and it must not be negative; if recoveries exceed payables, posting is refused, forcing the excess to be handled explicitly (a receivable, a waiver — a decision, not a silent negative salary). @[guided-image](_img/full-final-detail-lines.png) Review every line's type, amount and account, and reconcile the total to what you expect the net to be before posting. ### Step 4 — Post the settlement Click **Post**. Validation runs first — the record is not already posted, it has a Resource, at least one non-zero line exists, every payable line has a GL Account and every Deduction line a Payable GL Account, the net is not negative, and the company has a Payroll Payable control. Any failure names the line. Posting then writes one journal of type Payroll dated on the last working day: payable expenses debited per account, deduction payables credited per account, and the net credited to Payroll Payable — raising a person-keyed open item for exactly the net settlement. The record becomes **Posted**, stores the journal in **GL**, the open item in **Payroll Payable Open Transaction** and the computed **Net Settlement**; a posted settlement refuses to post again. Posting also closes the employee: Settlement Status **Settled**, Employment Status **Exited**, Date Of Exit filled from the last working day if empty — which is what excludes them from every future payroll run. @[guided-image](_img/full-final-detail-details.png) ### Step 5 — Pay the net settlement The net sits on the Payroll Payable control as an open item against the person. The monthly **salary payment batch does not pick it up** — it only settles items raised by a payroll run — so discharge the settlement with a separate payment: post the bank payment (debit Payroll Payable, credit bank) and apply it against the open item as described in [Recording and applying payments](/docs/finance/payments/). Nothing sets the settlement to Paid; record that state in your exit checklist or by editing the Status label. ### Step 6 — Close the recovered loan A Deduction line credited to a loan's control account clears the *ledger* balance, but it does not update the **Loan / Advance** record: its Outstanding Amount, its receivable open item and its Active status stay as they were. Edit the loan to set the outstanding to zero and its Status to Closed (or Written Off) so it does not appear as still recoverable, and note the settlement in its name or description. ## Expected result The settlement is **Posted** exactly once, stores its journal reference, and its net equals total payable lines less total Deduction lines. The employee is **Settled / Exited** from the last working day, future runs exclude them, and the Payroll Payable open item is either outstanding for the exact net or cleared by the separate payment. If any of those facts disagrees, do not create a second settlement — trace the saved journal, open item and payment application first. ## Common problems **Post is refused: "Net settlement is negative; recoveries exceed payables."** The Deduction lines total more than the other lines — commonly a large unrecovered loan against a short final month. Reduce the recovery to what the payables cover and pursue the remainder as a receivable, or add the payable you had not entered yet. **A line fails for a missing account.** Payable lines need a GL Account; Deduction lines need a Payable GL Account. The error names the line. For loan recoveries use the loan's own control account so the control balance clears. **Post is refused: no Payroll Payable control account.** Configure the company's Payroll Payable control in [Payroll configuration](/docs/payroll/configuration/) — the same control the monthly run posts to. **The employee still appeared in this month's run.** The settlement had not been posted when the run calculated — exclusion happens at posting, when Employment Status flips to Exited. Post the settlement, then recalculate the run (recalculation replaces the pass). ## Common questions ### Does the settlement calculate leave encashment, gratuity or notice recovery for me? No. You enter each payable and deduction as a line with its amount and account; the platform validates, nets, posts, raises the open item and closes the employee. Policy arithmetic happens per your rules before the lines are entered — put the basis in the line's Description so the journal stays explainable. ### Can I pay the settlement through the salary payment batch? No. The batch is built from a payroll run's details and settles only open items that run raised. The settlement's net is a separate open item on the same Payroll Payable control and is discharged by its own payment. ### What if something surfaces after posting? The settlement will not repost, and that is deliberate — the ledger already reflects it. Handle a late item the way finance handles any posted document: a correcting journal or payment for the delta, leaving the original settlement intact as the record of what was decided at exit. ### Where does TDS on the settlement go? Enter it as a Deduction line crediting the salary-TDS payable control. Note that **Prepare TDS Challan** on a payroll run sums only posted *run* details, so a settlement's TDS is not included in the drafted challan automatically — add it to the deposit deliberately. See [Statutory deductions and challans](/docs/payroll/statutory/). ## Related topics - [Adjustments, loans and advances](/docs/payroll/adjustments-and-loans/) - [Running payroll](/docs/payroll/payroll-runs/) - [Recording and applying payments](/docs/finance/payments/) - [Employees and salary structures](/docs/payroll/employees-and-structures/) ---- # Income tax on salary URL: https://xmatix.com/docs/payroll/income-tax/ Last reviewed: 2026-09-05 Salary TDS is a projection problem: every month the employer must estimate the employee's tax for the whole financial year and deduct a proportionate slice. xMatix makes that projection explicit and persistent — a **Monthly TDS Projection** record per employee per payroll period — computed from configured tax rule tables and the employee's verified declarations, always under **both** regimes so the comparison is never guesswork, with the elected regime driving the actual deduction. The payroll run's TDS component then reads that record, so deduction and comparison come from one computation. ## Where the records live Open the **Payroll** app (App Launcher → search *Payroll*). **Tax Declarations** is under **More**; **Monthly TDS Projections** and the rule tables — **Tax Regime Rules**, **Salary Tax Slabs**, **Tax Surcharge Slabs**, **Tax Deduction Sections** — are reached by typing their names into the App Launcher search box. A payslip's **Tax Declaration** button opens the employee's declaration directly. Two tax screens deserve a warning. The app bar's **Tax Computation** page renders fixed sample figures — it does not read your payroll data, so do not use it for operations; the real numbers are the Monthly TDS Projection records and the run register. The **TDS Calculation Sheet** tab on an Employee record is a worksheet preview that may render empty for an employee without projectable data. ## Regimes are data, elections are per employee Everything that changes with a Budget lives in per-financial-year rule tables, one set per regime: - **Tax Regime Rules** — the scalar parameters: standard deduction, the rebate's income ceiling and maximum, whether rebate marginal relief applies, the surcharge cap, the cess rate, the rounding unit, and what the regime allows at all (chapter deductions, house-property loss set-off and its cap). - **Salary Tax Slabs** — the progressive bands and marginal rates, by regime and financial year (and age band for the Old regime). - **Tax Surcharge Slabs** — the income thresholds and surcharge rates, capped per regime. - **Tax Deduction Sections** — one row per declarable section: its ceiling, a senior-citizen variant where the law provides one, availability per regime, whether the employer may allow it against salary TDS, and membership of an aggregate-cap group for sections that share one combined ceiling. Rule rows with no company (Partner Account blank) are shared by every legal entity; a company-specific row overrides the shared one. Each employee elects a regime on the Employee record's **Tax Regime** field; where none is recorded, the **New regime applies as the statutory default**. One limitation to know: the projection has no date of birth to work from, so every employee is taxed in the general age band — senior-citizen slabs can be seeded but never apply. ## Declarations: only verified amounts count @[guided-image](_img/tax-declaration-list.png) Employees' deductions and investments are entered as a **Tax Declaration** per financial year — a header (Resource, Partner Account, Financial Year in the form *2026-27*, Regime, Status) with a **Tax Declaration Line** per deduction section carrying the declared amount and, once proof is checked, the verified amount. Status moves Draft → Submitted → Verified or Approved (or Rejected). The projection reads only **Verified** and **Approved** declarations whose Financial Year matches the period's year, and uses the verified amount when present, otherwise the declared one. A declaration sitting in Draft or Submitted contributes nothing — the safe direction: tax is over-deducted, not under-deducted, until proof arrives. There is no employee self-service form; declarations are entered and verified by the payroll operator. ## The monthly projection **Project TDS** on a payroll run computes a projection for every non-exited employee of the company whose **Tds Applicable** flag is on (the run's **Calculate** action does this first, so the deduction always reads a fresh figure). For each employee it: 1. Sums the financial year's already-calculated run details, excluding the current run — gross to date and TDS already deducted. 2. Projects the annual gross: actuals to date plus a monthly figure for each month remaining in the year (April counts twelve, March one). The monthly figure is the average of the calculated months; an employee with no calculated months yet is projected from the **CTC** on their Resource Compensation, treated as a monthly amount. 3. Builds the income facts — projected salary plus the verified declaration claims, each capped by its section's ceiling and by any shared aggregate ceiling its cap group imposes, and dropped if the regime does not allow the section. 4. Computes the full-year tax under **both** regimes in the statutory order: slab tax, less rebate where income is at or under the ceiling, less rebate marginal relief where the regime provides it, plus surcharge with marginal relief at each threshold, plus cess, rounded to the configured unit. 5. Applies the elected regime, spreads the remaining liability over the remaining months — monthly TDS is the annual tax less what is already deducted, divided by the months left — and persists the projection, replacing any earlier one for the same employee and period. The record keeps the whole comparison: **Taxable Income If Old / If New**, **Tax If Old Regime / If New Regime**, **Recommended Regime**, **Annual Saving**, **Applied Regime**, and **On Dearer Regime** — raised only when the employee's elected regime is genuinely dearer — a ready-made review list for HR before proof season closes. If the financial year's rule tables are not seeded, no projection is written and the run's TDS component deducts nothing rather than guessing. The **Revised After Proof** field exists but no code path sets it. When the run calculates, a component whose statutory type is **TDS** reads the month's projection as its amount. Without such a component on the structure, the projection is computed and ignored. ## Depositing and Form 16 The month's deducted TDS posts to the salary-TDS payable control and is deposited per period through **Prepare TDS Challan** on the run — see [Statutory deductions and challans](/docs/payroll/statutory/). **Form 16** buttons appear on the payroll run and on payslips, but neither produces a certificate: the run's button has no server implementation and returns an error, and the payslip's is a screen-only action. Certificates are issued from the Tax Center's TDS return and certificate flow — see [TDS and TCS](/docs/finance/tax-center/tds-tcs/). ## Common questions ### Why did an employee's TDS jump mid-year? The projection trues up every month: annual tax less what has already been deducted, spread over the months that remain. Anything that raises the annual estimate — a raise reflected in the monthly average, a declaration that failed verification and dropped out, rule tables corrected — lands entirely on the remaining months. The projection record shows the inputs, so the jump is explainable. ### An employee never elected a regime — what deducts? The New regime, as the statutory default. The election lives on the Employee record and can be changed; the next projection picks it up. The On Dearer Regime flag exists precisely to catch people defaulted onto a regime that costs them more. ### Employees submitted declarations but tax didn't drop. Why? Almost always status: only Verified or Approved declarations count. Check the status, that the Financial Year label matches the period's year exactly, that the section is one the elected regime allows (most chapter deductions do not apply under the New regime), and that the claim survived its section ceiling and any shared cap group. ### Where do I see both regimes for an employee? On the Monthly TDS Projection record: taxable income and annual tax under each regime, the recommended regime, the saving, and which regime was applied. It is stored, not recomputed on demand, so what you see is exactly what drove the month's deduction. ### TDS is zero for one employee only. Their **Tds Applicable** flag is off, they have no active Resource Compensation to project from, or their annual estimate falls under the rebate ceiling. Open their projection record — if none exists for the period, the first two apply. ## Related topics - [Statutory deductions and challans](/docs/payroll/statutory/) - [Running payroll](/docs/payroll/payroll-runs/) - [Payslips](/docs/payroll/payslips/) - [Payroll configuration](/docs/payroll/configuration/) - [TDS and TCS](/docs/finance/tax-center/tds-tcs/) ---- # xMatix Payroll URL: https://xmatix.com/docs/payroll/ Last reviewed: 2026-09-05 xMatix Payroll turns a month of salary into ledger entries you can defend. A **payroll run** calculates every employee of one company for one payroll period from their assigned salary structure, an approval gate signs it off, the accrual posts into the same double-entry ledger as every other document, and a salary payment batch pays the net salaries in one posting. Everything the run does is an explicit, named action on the run record — nothing happens implicitly, and recalculating replaces the previous pass instead of stacking on top of it. ## Where payroll lives Open the **App Launcher** (the grid icon next to the xMatix logo), search for **Payroll** and select the app. Its top navigation carries the day-to-day records: **Home**, **Resources** (the people payroll pays), **Payroll Runs**, **Payroll Adjustments**, **Loans & Advances**, **Payslips**, **Payroll Periods**, **Tax Computation** (a month-by-month projected-versus-actual salary tax grid per employee), **Reports**, and under **More** the **Full & Final Settlements**, Dashboards and Settings. The configuration records — **Employees**, **Salary Structures**, **Payroll Components**, **Statutory Challans**, **Monthly TDS Projections**, **Tax Declarations** and the statutory rule tables (PF Rules, ESI Rules, Professional Tax Slabs, LWF Rules, Salary Tax Slabs, Tax Regime Rules, Tax Surcharge Slabs, Tax Deduction Sections) — are not on the app's default top bar. Your administrator may have added some of them (Employees, typically) under **More**; otherwise type the entity name into the App Launcher's search box, where every entity you have access to is listed under **All Entities**. Access to each entity is governed by the ordinary [security profile](/docs/administration/security-profiles/) permissions, and the module as a whole is switched on per tenant through the **Payroll** module setting in Administration. ## Read the payroll-run list @[guided-image](_img/payroll-overview.png) **Payroll Runs** is the control surface for the month. The tiles above the table summarise the visible population — open runs this month, total, processed and skipped employees, and the sum of net pay — and the columns carry the same figures per run: **Payroll Period**, **Status**, **Total Resources**, **Processed Resources**, **Skipped Resources**, **Total Net Pay** and **Created Date**. Read a row before opening it: a run whose skipped count is not zero has employees the calculation could not price; a run showing **Pending Approval** with zero resources was submitted before it was calculated. Names open the run's detail page; **New** creates the header for another period. ## The mental model Four ideas explain most of what you will see: - **The employee is a satellite of the person record.** HR lifecycle and payroll configuration live on the **Employee**; the bank account, IFSC, PAN and UAN live on the underlying **Resource** (the person), and every posting, payslip and open item is keyed on that person — so expenses, loans and payroll all reconcile to one identity. - **Salary is a structure, not a number.** A **Salary Structure** lists **Salary Component** lines — earnings, deductions, employer contributions, reimbursements — each with a calculation rule and, through its **Payroll Component** master, a ledger account mapping. The run evaluates the structure; posting follows the mappings. - **The run is the unit of work.** Calculate, review, generate payslips, post (directly or through approval), generate the payment batch, pay — each stage is an action on the run, each is recorded on the run's status, and recalculating an unposted run replaces its previous pass. - **Statutory amounts are configuration, with one honest caveat.** Professional tax is resolved from the configured slab table and salary TDS from a persisted monthly projection computed from the financial year's tax rule tables. Provident fund, state insurance and labour welfare fund, however, are deducted only as ordinary fixed or percentage components on the salary structure: the PF, ESI and LWF rule tables can be recorded but the calculation does not read them. [Statutory deductions and challans](/docs/payroll/statutory/) states exactly what is computed and what is data entry. ## The run lifecycle at a glance | Stage | Action on the run | What changes | | --- | --- | --- | | Draft | New | The header exists for a company and payroll period; nothing is calculated | | Calculated | **Calculate** | Salary TDS is re-projected, every employee is priced, per-employee details and component lines are written, counts and net pay stamped | | Review / Pending Approval / Approved | Submit to the [approval process](/docs/payroll/approvals/) | Final approval posts the run automatically; rejection returns it to Review | | Posted | **Post** (or approval) | One payroll journal dated on the period's pay date; a Payroll Payable open item per employee | | Payment Generated | **Generate Payment** | A draft Salary Payment Batch with one line per employee with positive net pay | | Paid | **Pay** on the batch | One bank journal settles every employee's open item; the run records its batch | Payslips sit beside this chain rather than in it: **Generate Payslips** creates one **Draft** slip per processed employee at any point after calculation. There is no Publish action — **Publish Status** is an editable field on the slip whose only effect is to block recalculation of the run — and no employee self-service screen, so slips are distributed with the **Print Payslip** document; see [Payslips](/docs/payroll/payslips/). ## What is in this section - [Employees and salary structures](/docs/payroll/employees-and-structures/) — the employee master, compensation records, structures and the payroll component catalog. - [Running payroll](/docs/payroll/payroll-runs/) — the full monthly cycle from calculate to payment, with what each action checks. - [Payslips](/docs/payroll/payslips/) — what a payslip carries, generation, printing, and the draft/published gate as it actually works. - [Statutory deductions and challans](/docs/payroll/statutory/) — PT and TDS as computed amounts, PF/ESI/LWF as configured components, and depositing through challans. - [Income tax on salary](/docs/payroll/income-tax/) — regimes, declarations, the monthly TDS projection and the Tax Computation grid. - [Adjustments, loans and advances](/docs/payroll/adjustments-and-loans/) — one-off pay items and installment recovery. - [Full and final settlement](/docs/payroll/full-and-final/) — closing out an exiting employee, and how the net is actually paid. - [Payroll run approval](/docs/payroll/approvals/) — the sign-off gate between review and posting. - [Expense claims through payroll](/docs/payroll/expense-integration/) — reimbursing approved claims with salary. - [Payroll configuration](/docs/payroll/configuration/) — the admin checklist: components, rule tables, control accounts. - [Troubleshooting payroll](/docs/payroll/troubleshooting/) — symptoms, causes and fixes. Payroll posts into the finance ledger — the accrual journal, the payable open items and the payment postings all follow the rules described in the [finance documentation](/docs/finance/). If you are evaluating the product rather than operating it, start with the [xMatix Payroll product overview](/products/payroll/) or [book a demo](/demo/). ## Common questions ### Which records must exist before the first run? A payroll company (the partner account whose payroll it is) with a Payroll Payable control account and a bank account; Payroll Components with GL and payable GL mappings; at least one Salary Structure with active component lines; Employees linked to Resources, with an active **Resource Compensation** record naming that structure; and a **Payroll Period** covering the month. [Payroll configuration](/docs/payroll/configuration/) walks the checklist in order. ### Why does a run show skipped employees? An employee is skipped when the run cannot price them: no active compensation record, a compensation record without a salary structure, or a structure with no active lines. The skipped count is stamped on the run header so the gap is visible before anything posts. ### Is payroll India-specific? The statutory vocabulary is Indian — PF, ESI, professional tax, LWF, salary TDS with Old and New regimes — and the tax rule tables are keyed by Indian financial year. The calculation engine itself (structures, proration by payable days, adjustments, loan recovery, posting) is not tied to a jurisdiction. ## Related topics - [xMatix Payroll product overview](/products/payroll/) - [xMatix Finance documentation](/docs/finance/) - [Approval processes](/docs/customization/approvals/) - [Security profiles](/docs/administration/security-profiles/) ---- # Running payroll URL: https://xmatix.com/docs/payroll/payroll-runs/ Last reviewed: 2026-09-05 A payroll run is the month's unit of work: one record that carries the calculation for every employee of a company for one payroll period, moves through an explicit lifecycle — Draft, Calculated, Pending Approval / Approved, Posted, Payment Generated, Paid — and leaves a journal, per-employee payable items and a salary payment batch behind it. Every stage is a named action button on the run's detail page, so nothing happens implicitly and everything can be reviewed before the next step. Open the **Payroll** app from the App Launcher and choose **Payroll Runs**. The list shows every run with its **Payroll Period**, **Status**, total, processed and skipped resource counts and **Total Net Pay**; a run's name opens the detail page, which shows the action buttons, a lifecycle strip, a **Details** tab, a **Related** tab (the per-employee run details and the run's open items) and a **Run Insights** panel. ## Prerequisites - [Employees with an active compensation record](/docs/payroll/employees-and-structures/) naming a salary structure whose components carry GL and payable GL mappings. - A **Payroll Period** for the month (start date, end date, pay date) for the company being paid — **Payroll Periods** on the app bar. - A Payroll Payable control account for the company, and payable controls for every statutory component you post (see [Payroll configuration](/docs/payroll/configuration/)). - Loss-of-pay inputs settled: unpaid leave for the period approved, [adjustments](/docs/payroll/adjustments-and-loans/) entered and approved, loans disbursed. - If salary TDS should deduct: the financial year's tax rule tables seeded and employee declarations verified (see [Income tax on salary](/docs/payroll/income-tax/)), and a TDS-typed component on the salary structure. ## Actions on the run | Button | What it does | Allowed when | | --- | --- | --- | | **Project TDS** | Recomputes every employee's monthly TDS projection for the run's period | Any time before posting | | **Calculate** | Projects TDS, then replaces the run's calculation pass | Run not posted; no payslip of the run is Published | | **Generate Payslips** | Creates one Draft payslip per processed employee that has none yet | After Calculate | | **Post** | Posts the payroll accrual journal and raises per-employee payable open items | Calculated run, not already posted | | **Generate Payment** | Builds a Draft Salary Payment Batch for the run's positive net pays | Posted run | | **Prepare TDS Challan** | Drafts or refreshes the period's salary-TDS deposit challan from posted TDS | After Post | | **Print** | Renders the run's print document | Any time | Two more buttons appear on the run but do nothing useful: **Post Payroll** is a screen-only action with no server behaviour (use **Post**), and **Form 16** is declared without a handler, so clicking it returns an error rather than a certificate. Form 16 figures come from the Tax Center's TDS flow, not from the run. ## Procedure @[guided-image](_img/new-payroll-run.png) ### Step 1 — Create the period and the run Create the payroll period if it does not exist — its start and end dates set the calendar days used for proration and the window for unpaid leave, and its pay date becomes the posting date of the accrual. Then click **New** on Payroll Runs and fill the three header fields: **Period** (the month), **Status** (leave it at Draft) and **Payroll Period**. The run's payroll company is stamped from your company context on save; the calculation selects employees whose **Payroll Company** or **Partner Account** matches it. A period can carry more than one run — an off-cycle or correction run deposits into the same period's TDS challan. ### Step 2 — Calculate Click **Calculate**. It first refreshes the month's salary-TDS projection for every TDS-applicable employee, then computes the run: 1. Any previous pass is cleared — details, component lines and Draft payslips are retired, and loan installments the old pass recovered are put back on the loans and their open items. 2. Every non-exited employee of the company with a linked Resource is considered (**Total Resources**). Each needs their latest active **Resource Compensation** record naming a salary structure with active lines; otherwise they are counted in **Skipped Resources**. 3. Attendance: calendar days of the period are the total; loss-of-pay days are the approved leave requests overlapping the period whose leave type is marked unpaid (LWP / loss of pay / leave without pay), counting half-days as half. Payable days = total − LOP, and the proration factor is payable over total. 4. Component lines are evaluated in sequence: Fixed uses the value; Percentage takes a percentage of CTC or of an earlier named component's un-prorated amount; a PT component marked Slab is resolved against the professional-tax slab table (February amount when the period ends in February); a TDS-typed component takes the month's projection; Formula, Slab on non-PT components and Manual fall back to the stored value. Min/Max clamps apply, then proration for components flagged proratable — the shortfall on earnings accumulates into the employee's loss-of-pay amount. 5. The period's payroll adjustments for the employee whose approval status is Approved or blank are appended as extra lines, and one installment (installment amount, or the remaining balance if smaller) is deducted for every **Active** loan or advance with a positive balance. 6. One **Payroll Run Detail** per employee is written — gross earnings, total deductions, employer contribution total, net pay, PF / ESI / TDS totals summed from components of those statutory types, payable and LOP days — and the run header gets its counts, **Total Net Pay** and status **Calculated**. Chase the skipped count now, not after pay day. Calculating again **replaces** the previous pass entirely, so recalculation after a fix is always safe while the run is unposted. ### Step 3 — Review @[guided-image](_img/payroll-run-detail-details.png) The **Details** tab keeps the run's period, company, lifecycle status and the calculated control totals together, and the **Run Insights** panel repeats the counts. Reconcile total, processed and skipped resources before relying on net pay, and do not infer posting from Status alone: **Payroll Posting Status** and the linked **GL** journal are the posting evidence. @[guided-image](_img/payroll-run-register.png) The **Related** tab lists the per-employee **Payroll Run Details** — this is the payroll register: paid and LWP days, gross earnings, TDS, PF, ESI, total deductions, employer contribution and net pay, with the component lines behind each row one click away. Compare against last month, verify employees with loss-of-pay days, and confirm the TDS column is not unexpectedly zero (a zero usually means no projection existed, the employee is marked not TDS-applicable, or the structure carries no TDS-typed component — see [Troubleshooting](/docs/payroll/troubleshooting/)). Fix inputs and recalculate as often as needed. ### Step 4 — Generate payslips Click **Generate Payslips**. One **Draft** payslip is created per employee detail — running it again only fills gaps, it never duplicates. Slips are created as Draft and there is no Publish action: **Publish Status** is an editable field on the slip whose only effect is to block recalculation of the run, and no employee self-service screen exists, so distribute slips with **Print Payslip** after pay day. What a slip carries is covered in [Payslips](/docs/payroll/payslips/). The generated slips are listed on **Payslips** (Payroll app bar), each linked to its run and period; filter the list by the run to verify that every processed employee has exactly one slip. Listing them is not a substitute for reviewing the register before generation. ### Step 5 — Post Post the accrual either by submitting the run to the [approval process](/docs/payroll/approvals/) — final approval sets the run **Approved** and posts it immediately; a rejection returns it to **Review**, a recall to **Draft** — or directly with **Post**. Posting builds one journal of type Payroll dated on the period's pay date (falling back to the period end date): each earning and reimbursement line debits its component's GL account, each deduction line credits its payable GL account, employer contributions do both, and each employee's net pay is credited to the company's Payroll Payable control — raising one payable open item per employee for exactly what is owed. A line whose component lacks its required mapping fails the post by name; nothing posts partially. After posting the run is **Posted**, each detail's posting status is Posted, and the run can no longer be recalculated — a correction from here is a reversal of the journal, not an edit. ### Step 6 — Generate the payment and pay it Click **Generate Payment** on the posted run. It builds a **Salary Payment Batch** in Draft — one line per employee with positive net pay, carrying the bank account number and IFSC read from the person (Resource) record — drawing on the company's salary bank: the company profile's default bank GL if set, otherwise its only bank account, with an explicit error naming the candidates when several banks exist and none is the default. The run becomes **Payment Generated**. Review the batch, then click **Pay** on it: one journal settles every employee's Payroll Payable open item against the bank, batch and lines are marked Paid, and the run finishes **Paid** with its batch recorded. No bank payment file is produced — the batch is the accounting record; the transfer itself happens in your banking channel. ## Expected result The run progresses in order from Draft to Paid without duplicate calculation lines or journals. Employee details reconcile to the register, payslips reflect the reviewed calculation, the posted journal equals the run's gross, deduction and net totals, and the final bank journal clears the person-keyed Payroll Payable open items. A mismatch at any checkpoint should be resolved in that stage rather than hidden by a manual journal or a second run. ## Common problems **Calculate is refused.** Two states block it, deliberately: the run is already posted (reverse the accrual first), or a payslip of the run has its Publish Status set to Published (set it back to Draft if the slip has not actually been distributed). **Total Resources is zero.** No employee's Payroll Company or Partner Account matches the run's company, or the employees have no linked Resource. Check the employee records rather than the run. **Post fails naming a component line.** That line's payroll component is missing its GL mapping — an earning without an expense account, a deduction without a payable account, or an employer contribution missing either. An adjustment entered without a payroll component has no accounts at all and fails the same way. Map the account and post again. **Generate Payment is refused.** The run must be posted, at least one employee must have positive net pay, and the company's bank must be resolvable — set the company profile's default bank GL when the company holds several bank accounts. **TDS deducted zero for everyone.** Either no monthly projection existed (usually the financial year's tax rule tables are not seeded) or the salary structure has no component with statutory type TDS. Calculate re-projects automatically, so once both exist, recalculating fixes the run. See [Income tax on salary](/docs/payroll/income-tax/). ## Common questions ### Can I run payroll twice in one period? Yes — a period can hold several runs, and off-cycle or correction runs are normal. Statutory deposits are per period, not per run: **Prepare TDS Challan** sums posted TDS across every posted run of the period, so a correction run lands in the same deposit. ### What order do posting and payslips have to happen in? Payslips can be generated any time after calculation. Posting requires a calculated run; payment requires a posted run. The safe sequence is the one above: calculate, review, generate payslips, post (or approve), generate payment, pay, then print and distribute the slips. ### What does the accrual journal look like? Expenses on the debit side (each earning and employer contribution under its mapped account), liabilities on the credit side (each deduction and contribution under its payable account, and one Payroll Payable credit per employee for net pay). It is a normal [journal](/docs/finance/journals/) — visible in the ledger, reversible like any other, and dated on the period's pay date so it lands in the right accounting period. ### Who is included in a run? Every employee of the run's company whose employment status is not Exited, who is linked to a Resource, and who has an active compensation record naming a salary structure with active lines. Exited employees are settled through [full and final settlement](/docs/payroll/full-and-final/) instead. ## Related topics - [Payslips](/docs/payroll/payslips/) - [Payroll run approval](/docs/payroll/approvals/) - [Statutory deductions and challans](/docs/payroll/statutory/) - [Troubleshooting payroll](/docs/payroll/troubleshooting/) ---- # Payslips URL: https://xmatix.com/docs/payroll/payslips/ Last reviewed: 2026-09-05 A payslip is the per-employee document of one payroll calculation: the month's earnings, deductions and net pay, with year-to-date context. It is generated from the payroll run, not typed, and it carries a **Publish Status** of **Draft** or **Published**. Two things to know up front: the platform ships no self-service screen where employees browse their own slips — payslips are distributed by printing the payslip document — and there is no Publish action; the status is an ordinary field on the record, and its only effect inside the product is to lock the run against recalculation. ## Where they live Open the **Payroll** app (App Launcher → search *Payroll*) and choose **Payslips**. The list shows every generated slip; a slip's document number opens its detail page, which carries **Print Payslip**, **Tax Declaration**, **Edit** and **Delete**. ## Read the screen @[guided-image](_img/payslips-concept.png) **Document Number** is the stable reference; **Partner Account** and **Resource** locate the legal entity and employee; **Payable Days** and **Lop Days** expose the time basis used for proration; gross earnings, total deductions and net pay are the calculation's three headline outcomes. @[guided-image](_img/payslip-detail.png) The detail confirms the run detail, period, publish state, attendance basis, current totals, year-to-date figures and masked payment account on one record. Component-level earnings and deductions are not stored on the slip — they are the run's calculated component lines, reached through the linked **Payroll Run Detail**. ## What a payslip carries | Field | What it is | | --- | --- | | Payroll Run Detail, Payroll Run, Payroll Period | The calculation the slip was generated from; the run detail is also the idempotency key — one slip per detail | | Payable Days, Lop Days | How many days were paid and how many were lost to unpaid leave, copied from the run detail | | Gross Earnings, Total Deductions, Net Pay | The month's totals, copied from the run detail | | YTD Gross, YTD Tax | Running totals for the fiscal year the run's period falls in | | Masked Bank Account | The Resource's salary account shown as a masked prefix plus its last four digits | | Generated Utc | When the slip was created — not the pay date | | Publish Status | Draft or Published (see below) | | File Asset | Reserved for a stored PDF; nothing writes it today | The earning and deduction lines shown by the printed document are projected from the run's calculated component lines rather than copied — so a payslip can never disagree with its run. ## Year-to-date figures YTD Gross and YTD Tax sum the employee's run details across the payroll periods of the **fiscal year containing the run's period** — the company's fiscal calendar if one is defined, otherwise the April-to-March year. A year-to-date figure that summed everything ever paid would quietly grow across years, so the scoping is explicit. ## Generation, printing and the publish field **Generate Payslips** on the payroll run creates one **Draft** slip per employee detail. Running it again is safe — details that already have a slip are skipped, so a partial generation can be completed without duplicates. If the run is recalculated while its slips are Draft, the slips are retired with the old pass; generate again after reviewing. **Print Payslip** on a slip renders the payslip document for printing or saving. It changes no payroll data and does not touch Publish Status. This is how slips reach employees: print or export the document and distribute it through your own channel. **Publish Status** is set by editing the slip (the pencil on the field). Changing it to Published has exactly one effect in the product: the originating run **refuses to recalculate** while any of its slips is Published, because recalculating would contradict a document that has been handed out. Nothing else reads the field — it does not make the slip visible anywhere, send anything, or lock the slip itself. Use it as your own "distributed" marker after the salary has actually been paid. **Tax Declaration** on a slip opens the employee's tax declaration record for the financial year (see [Income tax on salary](/docs/payroll/income-tax/)). ## Payslips and the run lifecycle | Run event | Effect on payslips | | --- | --- | | Calculate (again) | Draft slips of the run are retired with the old pass; blocked entirely if any slip is Published | | Generate Payslips | Missing slips created as Draft; existing ones untouched | | Post / Generate Payment / Pay | No effect on slips | | Publish Status set to Published (by edit) | The run can no longer be recalculated | ## Common questions ### How does an employee get their payslip? By the document you print or export with **Print Payslip** and send through your own channel. There is no employee portal or mobile screen that lists payslips, so Publish Status does not make a slip visible to anyone. ### The payslip is wrong — can we fix it? If the run is unposted and no slip is Published: fix the inputs, recalculate the run, regenerate. If a slip is Published, set it back to Draft first or the run will refuse to recalculate. If the run is already posted, correct forward with a [payroll adjustment](/docs/payroll/adjustments-and-loans/) in the next period — which is also the honest audit trail. ### Where does the year-to-date tax figure come from? It is the sum of salary TDS across the employee's run details for the fiscal year of the run's period — the same figures the period TDS challans deposit. The authoritative annual computation is the [income-tax projection](/docs/payroll/income-tax/). ### Why is the bank account masked? The payslip is a distributable document; the full account number lives on the Resource and is only needed by the payment batch. The slip shows the last four digits — enough for the employee to recognise the account, not enough to misuse. ## Related topics - [Running payroll](/docs/payroll/payroll-runs/) - [Income tax on salary](/docs/payroll/income-tax/) - [Employees and salary structures](/docs/payroll/employees-and-structures/) ---- # Statutory deductions and challans URL: https://xmatix.com/docs/payroll/statutory/ Last reviewed: 2026-09-05 Indian payroll deducts for several statutory schemes — provident fund (PF), employee state insurance (ESI), state professional tax (PT), labour welfare fund (LWF) and income tax at source (TDS, covered on [its own page](/docs/payroll/income-tax/)). In xMatix every one of them rides the salary structure's component machinery and posts to its own payable control account, and each is deposited through a **Statutory Challan**. What differs between the schemes is how the *amount* arises, and this page is precise about that, because the product computes two of them and merely records the other three. ## What the run computes, and what it does not | Scheme | How the amount is produced in a run | | --- | --- | | **PT** | Computed. A component whose statutory type is PT and whose calculation type is **Slab** is resolved at calculation time against the company's **Professional Tax Slabs** for the gross accumulated by the lines before it, using the slab's February amount when the period ends in February. | | **TDS** | Computed. A component whose statutory type is TDS takes the employee's **Monthly TDS Projection** for the period, produced from the financial year's tax rule tables and verified declarations. | | **PF**, **ESI**, **LWF** | Not computed from rule tables. They are deducted only if the salary structure carries a component of that statutory type, and the amount is whatever the line's own calculation yields — typically a **Percentage** of the basic component (PF), a Percentage of gross (ESI) or a **Fixed** amount (LWF), clamped with **Max Amount** where a wage ceiling applies. The **PF Rule**, **ESI Rule** and **LWF Rule** tables can be recorded, and the employee carries PF / ESI / PT / LWF applicability flags and a PF wage-cap override, but the calculation reads none of them. | Practical consequences: an ESI eligibility threshold, a PF wage ceiling or a per-employee PF cap override has to be expressed on the structure itself (a Max Amount, or a separate structure for employees above the ESI threshold), and a rate change in the law is a change to the component lines, not to the rule tables. Employer-side contributions are components of type **Employer Contribution**: they cost the employer without reducing the employee's net, and post as an expense and a payable in the same journal. The run detail sums deduction components typed PF, ESI and TDS into per-employee **PF**, **ESI** and **TDS** totals — the figures the register, the payslip's year-to-date tax and the TDS challan read. ## Where the records live Open the **Payroll** app (App Launcher → search *Payroll*). **Statutory Challans** sits under **More**; the rule tables — **PF Rules**, **ESI Rules**, **Professional Tax Slabs**, **LWF Rules** — and **Payroll Components** are reached by typing their names into the App Launcher search box. ## Professional-tax slabs A **Professional Tax Slab** row belongs to a company (**Partner Account**) and carries a gross-wage band, the monthly PT amount, an optional February amount, a state code, an effective-from date and an active flag. The calculation loads every active slab of the run's company — it does not filter by state — so keep one state's slabs per company, or split payroll companies by state. Revise a slab by adding a new row and deactivating the old one. The PT component must sit *after* the earning lines in the structure's sequence, because the slab is matched against the gross computed so far. ## From deduction to payable control When the run [posts](/docs/payroll/payroll-runs/), every statutory deduction and employer contribution is credited to the **Payable GL Account** mapped on its Payroll Component. Give each scheme its own control account with the matching control type — PF payable, ESI payable, professional-tax payable, salary-TDS payable, LWF payable — so the ledger answers "how much do we owe each authority" as an account balance, and so a challan without an explicit payable account can find the right control by its statutory type. ## Challans: recording what you deposit @[guided-image](_img/payroll-statutory-list.png) A **Statutory Challan** records one deposit to one authority for one payroll period: **Partner Account**, **Statutory Type** (PF, ESI, PT, TDS, LWF, Gratuity), **Payroll Period**, **Amount**, **Challan Number**, **Pay Date**, **Payable GL Account**, **Bank GL Account** and, once posted, the **GL** journal. The record also stores a **BSR Code** and **Challan Serial** for the TDS CIN, although the default form does not show them. Two actions drive the flow: - **Prepare TDS Challan** — on a *posted* payroll run. It sums the TDS of every **posted** run detail in the run's period (so off-cycle and correction runs deposit together) and creates or refreshes the company's TDS challan for that period. It is idempotent per company and period: an unpaid draft has its amount refreshed after late postings; a challan already **Paid** is never touched, and the difference between its amount and the posted TDS is reported so the shortfall can go on the next deposit deliberately. - **Post Challan** — on the challan. It requires an amount above zero and a **Bank GL Account**, resolves the payable control from **Payable GL Account** or, when blank, from the Statutory Type, and writes one journal dated on **Pay Date** (today if blank): payable control debited, bank credited. The challan's Status becomes **Paid** and its **GL** link is filled; a challan with a journal refuses to post again. @[guided-image](_img/payroll-statutory-challan-concept.png) PF, ESI, PT and LWF challans are entered by hand with **New**: choose the company, scheme and period, type the amount you are depositing (reconcile it to the posted payable balance for that scheme and period first), fill the acknowledgement fields, and post. The platform does not compute those deposit amounts — the payable control's balance is the figure to match. @[guided-image](_img/payroll-statutory-detail.png) The status vocabulary is loose: a drafted TDS challan is written as *Pending*, posting writes *Paid*, and the field's picklist offers Draft, Paid and Reconciled — treat the presence of a **GL** journal, not the label, as proof of posting. ## Common questions ### Where do I change a rate when the law changes? For PF, ESI and LWF: on the salary structures' component lines (the percentage or fixed value, and the Max Amount for a ceiling) — the rule tables are not consulted. For PT: add a new Professional Tax Slab row and deactivate the old one. For TDS: in the financial year's tax rule tables (see [Income tax on salary](/docs/payroll/income-tax/)). Runs calculated after the change pick up the new configuration; recalculate an unposted run to apply it. ### An employee's PF should cap at a different wage than the rest — possible? Not through the employee record: the PF wage-cap override there is stored but not read. Put the employee on a salary structure whose PF line carries the different Max Amount. ### Why does the February professional tax differ? Some states collect a different amount in February so the year totals to the statutory annual figure. The slab row carries both the monthly amount and an optional February amount, and the calculation uses the February amount for periods ending in that month. ### One period had two payroll runs — how many TDS challans? One. The challan is per company and period, and Prepare TDS Challan sums posted TDS across all of the period's runs. If a correction run posts after the challan was already paid, the difference is reported rather than silently edited, and you deposit it separately. ### Does a full-and-final settlement's TDS reach the challan? Not automatically — Prepare TDS Challan reads run details only. Add the settlement's TDS deduction to the deposit yourself. See [Full and final settlement](/docs/payroll/full-and-final/). ## Related topics - [Income tax on salary](/docs/payroll/income-tax/) - [Running payroll](/docs/payroll/payroll-runs/) - [Payroll configuration](/docs/payroll/configuration/) - [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) ---- # Troubleshooting payroll URL: https://xmatix.com/docs/payroll/troubleshooting/ Last reviewed: 2026-09-01 Payroll problems cluster by stage: calculation, posting, payment, statutory, payslips. Find the symptom below; each entry states the cause the platform actually acts on and the fix. A useful general rule first: while a run is unposted and its payslips unpublished, **recalculation is free** — it replaces the previous pass completely (loan recoveries restored and re-taken included), so "fix the input, calculate again" is the answer more often than not. ## Calculation ### Employees are missing from the run The run header's skipped count tells you it happened; the causes are exact. An employee is excluded when their employment status is **Exited**, and skipped when no active compensation record with a salary structure exists for them, or the structure has no active lines. Fix the [employee's compensation or structure](/docs/payroll/employees-and-structures/) and recalculate. Also check the employee's payroll company — a run only picks up the employees of its own company. ### Calculate is refused Two deliberate blocks. *"Payroll run is posted"*: the ledger already reflects the old figures — reverse the accrual journal first, then recalculate. *"Payslips are published"*: employees have seen those documents; recalculating would contradict them. Correct forward with an [adjustment](/docs/payroll/adjustments-and-loans/) next period instead. ### An adjustment or loan recovery didn't apply An adjustment must be on the run's period and employee, with approval status approved or empty — pending and rejected adjustments are excluded by design. A loan recovers only while it is **Active** with a positive outstanding balance and a positive installment amount; a Requested loan was never disbursed. Fix and recalculate. ### TDS is zero for everyone The TDS component reads the month's persisted projection, and no projection existed. The usual cause is the financial year's [tax rule tables](/docs/payroll/income-tax/) not being seeded — projection deliberately skips rather than guesses when the year's tables are missing. Seed the tables (both regimes) and recalculate; Calculate re-projects automatically. For a single employee at zero, check their TDS-applicability flag and whether their projected annual income simply falls below tax. ### TDS is zero for one employee whose declarations were "submitted" Only proof-checked declarations count, at their verified amounts. A declaration in Draft or Submitted contributes nothing — verify it and recalculate. Also confirm the claimed sections are allowed under the employee's elected regime. ## Posting ### Post fails naming a component line The named line's payroll component lacks a GL mapping: earnings and reimbursements need an expense account, deductions a payable account, employer contributions both. Map the account on the component master and post again — nothing posted partially. ### Post fails on the control account *"No Payroll Payable control account is configured"*: the company has no GL account with the Payroll Payable control type. Configure it (see [Payroll configuration](/docs/payroll/configuration/)) and post again. The same pattern applies to challans and settlements — each names the missing control type. ### The run was approved but never posted Final approval posts the accrual, but a posting failure does not undo the approval — it is logged and the run stays approved with posting status NotPosted. Fix the named gap (mapping or control account) and run **Post** directly on the run. See [Payroll run approval](/docs/payroll/approvals/). ## Payment ### Generate Payment is refused In order of likelihood: the run is not posted yet (posting is the prerequisite); no employee has positive net pay; or the bank cannot be derived — the error spells out which: the company has no bank control account, the configured default bank is not an active bank account of this company, or several banks exist with no default. Set the company profile's default bank GL and retry. ### Pay reports no open items to settle The batch settles the run's per-employee payroll-payable open items, and they are already settled — typically the batch was paid once already, or the items were settled by a manual payment. Check the open items on the Payroll Payable control for the run before assuming money is unpaid. ### A batch line has no bank account or IFSC The person record was missing bank details when the batch was generated. Update the person record, then regenerate the batch from the run — the lines snapshot bank details at generation time. ## Statutory and payslips ### Prepare TDS Challan finds nothing The challan sums TDS from **posted** run details of the period — an unposted run contributes nothing. Post the run first. If the period's challan is already Paid and a correction run posts later, the difference is reported on the challan result rather than edited into the paid challan; deposit it separately. ### Employees cannot see their payslips They are Draft. Generation never publishes; set the publish status to Published once the payment is out. See [Payslips](/docs/payroll/payslips/). ### Payslip year-to-date looks wrong YTD sums the fiscal year containing the run's period — the company's fiscal calendar, or April-to-March absent one. A figure that seems to include "last year" usually means the fiscal calendar is missing or its dates are wrong; fix the calendar and regenerate the slips (they are drafts until published). ### A posted figure needs correcting Posted payroll follows ledger rules: no edits, reverse and redo — or correct forward with an adjustment in the next period, which keeps the statutory challans of the closed period untouched. If the accrual landed in a closed accounting period, see [Closing a period](/docs/finance/period-close/) for reopening rules. ## Related topics - [Running payroll](/docs/payroll/payroll-runs/) - [Payroll configuration](/docs/payroll/configuration/) - [Income tax on salary](/docs/payroll/income-tax/) - [Payroll run approval](/docs/payroll/approvals/) ---- # Build and publish a portal URL: https://xmatix.com/docs/portals/build-a-portal/ Last reviewed: 2026-09-06 A portal goes from nothing to serving visitors in one sitting: create the site, add its pages, publish the data views the pages read, publish, and check the result as a visitor. This page walks the whole path in the order that avoids backtracking. The step worth the most care is the data views — they decide what the portal can read at all, and publishing one is a security decision as much as a content one. ## Prerequisites - The portal-management capability (`setup.portals.manage`), and the Portals module enabled for your organization. - The entity views you intend to publish already exist — a portal data view serves an entity view (a column set plus a base filter), so shape the view first. See [the data model](/docs/customization/data-model/). - A slug for the portal: lowercase letters, digits and hyphens, up to 63 characters. It becomes the portal's hostname label, so choose it as deliberately as a domain name. ## Procedure @[guided-image](_img/new-portal-dialog.png) The portal shell needs only a readable label and a stable slug. Creating it does not expose content: pages, data views and the site itself each retain their own explicit publication checkpoint. ### Step 1 — Create the site Open **Setup → Feature Hub → Portals → Portals** and click **New**. Give the portal a label — the slug pre-fills from it, and you can adjust it before creating. You land on the portal's detail page: a **General** tab for the site, a **Pages** tab, a **Data Views** tab, and a **Publish** action in the header for when everything below is ready. ### Step 2 — Configure the site On **General**, write a description (visitors see it in the portal footer) and review the serving and signup switches. **Anonymous visitors** off means only signed-in external users can view the portal. **Self-service signup** admits signup requests, while **Create customer on signup** controls whether a successful signup also receives a new consumer Account and Contact; that second switch defaults on. Each new signup receives an email to set a password and membership of this portal. The **Advanced** section holds the theme, navigation and settings documents: theme tokens become the portal's colors, and the navigation document defines the header menu. Leave navigation empty and the published pages, in their sort order, become the menu automatically — a perfectly good place to start. ### Step 3 — Add pages On **Pages**, **Add Page** asks for a label, a path (`/` is the home page; then `/products`, `/support`, and so on), the page type, the audience and a sort order. **Designed** pages are free-form layouts; **Entity list** pages render one published data view. Two audiences exist: **Public** pages serve anonymous visitors and signed-in users alike, **Authenticated** pages serve signed-in external users only. Creating page rows early costs nothing — an unpublished page is invisible to the portal — so lay out the whole page tree now and publish only the finished ones. ### Step 4 — Publish the data views On **Data Views**, click **Publish Data View**: pick the entity, then one of its views, an audience, and a page size cap (50 rows per request by default, up to 250). The view's columns and base filter bound exactly what an authored page can query. Publishing a **Public** view grants the tenant's shared anonymous principal read access to the entity, so treat its result as public information; **Authenticated** views instead run as the signed-in visitor and serve "my records" scenarios. The full semantics are in [Portal pages and data views](/docs/portals/pages-and-data-views/). ### Step 5 — Give the pages content Open a page from the list to edit it. A **Designed** page carries a layout document, drafted on the page and served only once published — it can use layout blocks (grids, tabs, collapsible sections), display widgets, cards and statistics, and the portal data list widget that renders a published data view. An **Entity list** page names its published data view in the page's embed target instead, and renders it as a paged table. Whatever you edit stays a draft: the portal serves only the published snapshot, so a live page can be reworked safely. ### Step 6 — Publish each page Use **Publish draft** on each finished page. Publishing snapshots the current draft as the served version and marks the page **Published**; a page still showing **Draft** or **Empty** is not part of the portal. Re-publishing after later edits is the same action. ### Step 7 — Publish the site Click **Publish** in the page header. The site becomes servable — visitors receive only its published pages and active data views — and its hostname is registered automatically: a single label combining the portal slug and your organization's slug (portal `shop` for organization `acme` serves as `shop-acme`) under the platform's portal domain. No DNS work is needed for this hostname; putting the portal on your own domain is a separate task — see [Publishing, hostnames and custom domains](/docs/portals/publishing-and-domains/). ### Step 8 — Verify as a visitor Open the portal hostname in a private browser window, so you see it without your administrator session. Check the menu, open every page, and read the data lists: what you see is exactly what any anonymous visitor sees — public data views deliberately return identical results for everyone, signed in or not. If a first visit immediately after publishing returns not-found, retry after a minute: hostname registration is picked up on the next lookup. ## Expected result The portal register shows one site with the intended label, stable slug, address and published state. A private browser can open every published public page, authenticated pages still require an external sign-in, and each data list exposes only the columns and rows authorized by its published view. If administrator and visitor results differ unexpectedly, unpublish the affected page or site first, then re-check its audience, view filter and anonymous-access setting before restoring service. ## Common problems **The portal returns not-found even though everything is published.** In order: the site's **Active** switch is off (an inactive site is never served, regardless of publish state), **Anonymous visitors** is off and you are not signed in as an external user, or the Portals module is disabled for the organization. **A page renders "has no published content yet."** The page was published while its draft was empty, or an embed page's target names no data view. Add the content, then **Publish draft** again — publishing snapshots whatever the draft holds at that moment. **A data list shows an error or no rows.** Check that the data view is **Active**, that its underlying entity view returns rows inside the application, and — for a portal created moments ago — that the portal's visitor identity has finished provisioning: open the portal in Setup, save it once, and retry. ## Common questions ### Can one organization run several portals? Yes. Each portal has its own slug, hostname, pages, data views and theme, and they are managed independently on **Setup → Feature Hub → Portals → Portals**. What they share is the tenant-wide anonymous principal and its **Portal Anonymous** profile. Active public data views across all portals collectively manage that profile's entity grants, so review authored public exposure across portals together; see [How portal security works](/docs/portals/security/). ### Do site changes need a re-publish too? No — the site's own settings (theme, navigation, description, switches) apply to the live portal when you save them. The draft/publish gate exists at the page level (content) and the site level (served at all): it is page *content* that never changes without an explicit **Publish draft**. ### What does deleting a portal do? It removes the portal's configuration — the site, its pages and its published data views — but does not delete the organization's tenant-wide anonymous visitor principal or your business records. A portal is a window onto the data, not a copy of it. Deletion cannot be undone, so when you only want the portal offline, retract it with **Unpublish** instead. ## Related topics - [Portal pages and data views](/docs/portals/pages-and-data-views/) - [Publishing, hostnames and custom domains](/docs/portals/publishing-and-domains/) - [How portal security works](/docs/portals/security/) - [Portals on the xMatix site](/products/portals/) ---- # xMatix Portals URL: https://xmatix.com/docs/portals/ Last reviewed: 2026-09-06 A portal is an external-facing website built on your organization's data and published straight from Setup: a customer self-service portal, a product catalog, a partner site. Its visitors are not members of your organization — they are anonymous members of the public and signed-in external users — and the portal is served on its own hostname, entirely outside the application your teams sign in to. This page explains the two ideas every portal task builds on: what a portal is made of, and the publishing model that decides what visitors can see. ## What a portal is made of A portal (**Setup → Feature Hub → Portals → Portals**) is three kinds of configuration: - **The site** — the portal's identity and chrome: a label, a slug (the hostname label the portal is served under), theme tokens, header navigation, and switches for anonymous access and self-service signup. - **Pages** — path-addressed content (`/`, `/products`, `/support`): free-form designed pages, and pages that embed a published data view as a list. Each page declares its audience — public, or signed-in visitors only. - **Data views** — the only general record-query window available to authored portal pages. Each one publishes a single entity view (a column set plus a filter) to the portal; an authored page cannot query an entity for which the portal has no published view. A portal bound to a commerce channel can also use the storefront's purpose-built catalog, cart, checkout and account operations; those are allowlisted workflows rather than access to the general data interface. See [Portal pages and data views](/docs/portals/pages-and-data-views/). One organization can run several portals side by side — each with its own slug, pages, data views and theme. The **Portals** registry lists them with Name, Slug, Address, Published, Status, Anonymous, Pages and Version columns — the complete inventory of external sites your organization serves, so treat every row as security-relevant. The neighbouring **Domains** and **Portal Settings** entries hold custom hostnames and organization-wide portal controls. Create a portal only after naming its owner, audience, hostname and data-exposure purpose; author pages in draft, review each data view before publishing it, test as an anonymous and as a signed-in visitor, and only then publish. ## The publishing model Nothing on a portal is public by accident. Three gates stand between authoring and a visitor's browser, and each is an explicit action: 1. **The site is published.** An unpublished or deactivated site is not served at all. 2. **Each page is published.** Page edits accumulate in a draft; publishing snapshots the draft as the served version. An unpublished page is invisible to the portal, and later edits change nothing until you publish again. 3. **Each data view is published.** Publishing a data view is what grants the portal read access to that entity — and the grant is withdrawn automatically when the last active view of the entity is removed. The full scoping model is in [How portal security works](/docs/portals/security/). Retracting mirrors publishing at every level: unpublish a page and it disappears from the portal; unpublish the site and it stops serving immediately. Nothing is deleted by retracting, so a portal can go dark and come back without rework. ## What's in this section | Page | What it covers | | --- | --- | | [Build and publish a portal](/docs/portals/build-a-portal/) | The end-to-end procedure: site, pages, data views, publish, verify | | [Portal pages and data views](/docs/portals/pages-and-data-views/) | Page types and audiences, and exactly what data a published view exposes | | [Publishing, hostnames and custom domains](/docs/portals/publishing-and-domains/) | Publish and retract, the platform hostname, and serving on your own domain | | [Portal visitors, signup and identity](/docs/portals/visitors-and-signup/) | Anonymous visitors, self-service signup, and what signed-in portal users are | | [How portal security works](/docs/portals/security/) | The scoping model, and how it composes with your organization's security | | [Troubleshooting portals](/docs/portals/troubleshooting/) | Grounded checks for not-found errors, missing pages, empty lists and signup | ## Who can build portals Building portals is an administrator activity: the Setup screens require the portal-management capability (`setup.portals.manage`), and the Portals module must be enabled for your organization. Visitors need nothing — no account for public pages, and an external account (self-created through signup, or invited) for signed-in areas. ## Related topics - [Portals on the xMatix site](/products/portals/) — the product overview - [How portal security works](/docs/portals/security/) - [The xMatix security model](/docs/concepts/security-model/) - [See a portal built in a demo](/demo/) ---- # Portal pages and data views URL: https://xmatix.com/docs/portals/pages-and-data-views/ Last reviewed: 2026-09-02 A portal separates *what visitors see* from *what authored pages can query*. Pages are the first: path-addressed content with a draft/publish lifecycle. Data views are the second: explicit, per-entity publications that are the authored page layer's only general route to your records. Keeping the two apart is what makes authored exposure auditable — the complete answer to "what general record data can these pages query?" is the list on the **Data Views** tab, not something buried in page designs. Purpose-built commerce operations, when a portal is bound to a storefront channel, are a separate allowlisted API surface. This page is intentionally text-only in the current demo2 pass. The tenant's portal registry has no row, so the **Pages** and **Data Views** tabs and their create dialogs cannot be reached without creating production configuration. An empty portal register or an unrelated setup table would not evidence these fields; the descriptions below are grounded in the portal detail implementation and should receive visuals only after demo2 contains an approved disposable portal. ## Portal pages A page is addressed by its site-relative path (`/`, `/products`, `/support/contact`) and carries: - **A type.** **Designed** pages are free-form layout documents. **Entity list** pages embed one published data view as a paged list. Two further types — entity detail and app page embeds — can be authored, but designed pages and entity list embeds are the types that render content on the portal today. - **An audience.** **Public** pages serve anonymous visitors and signed-in users alike; **Authenticated** pages serve signed-in external users only. An anonymous visitor requesting an authenticated page receives a sign-in requirement, not a not-found — the page's existence is not a secret, its content is. - **A draft and a published snapshot.** Edits land in the draft; the portal serves only the snapshot taken at the last **Publish draft**. The two can differ for as long as you like, which is what lets you rework a live page safely. An unpublished page is invisible to the portal entirely. - **Navigation placement.** A sort order positions the page in the menu. If the site has no authored navigation document, the published pages in sort order *are* the menu. - **SEO metadata.** Per-page overrides (title, description) can be recorded on the page for search engines. The **Pages** tab makes route, page type, audience, publication state and navigation order reviewable together. **Add Page** records **Label**, site-relative **Path**, **Page type**, **Audience** and **Order**; creating the row does not publish it. Open the new row to add a draft layout or embed target, then use **Publish draft** only after review. ## Data views: the authored page layer's record window Authored portal pages have no general access to your records. A data view publishes exactly one entity view — the same list views used inside the application, a column set plus a base filter — to one portal, together with: - **An audience**, the crucial setting, because it decides *whose identity executes the query*. **Public** views always run as the portal's anonymous visitor identity — even when the caller is signed in — so a catalog is identical for every visitor. **Authenticated** views require a signed-in external user and run as that person, so ownership and record-security rules scope the rows: this is the "my orders" pattern. - **A page size cap** — the most rows a single request may return (default 50, up to 250). Visitors page through larger results. - **An active switch** — deactivating stops serving immediately without deleting the configuration. The **Data Views** tab is the portal's exposure register: it shows the entity and underlying view together with audience, active state and page cap. **Publish Data View** asks for a readable label, entity, one of that entity's views, audience and page-size cap. The entity and view pair is the data boundary; the audience determines which principal executes it. Review both before choosing **Publish**. ## Exactly what a published view exposes For any data view, the exposure is computable, not discovered: - **Fields:** the columns of the entity view, minus anything field-level security hides from the executing identity. - **Rows:** the records matching the view's base filter, intersected with what the executing identity is allowed to read — the anonymous visitor identity for public views, the signed-in user for authenticated ones. - **Volume:** at most the page size cap per request. Everything else is a hard boundary for authored page queries: entities with no published view are unreachable through this surface, drafts and site settings are never served, and the view's filter cannot be widened from the browser — any filter a visitor's request adds is combined *with* the view's own filter, so it can only narrow the result. ## Publishing and the read grant Publishing a **public** data view is a security action: it grants read access on that entity to the shared **Portal Anonymous** security profile carried by the tenant-wide anonymous principal. The grant is managed for you: when the last active public view of an entity, across all of your portals, is deleted or deactivated, the grant is revoked again. Authenticated views need no anonymous grant; they rely on the signed-in user's own access. Two practical consequences: - The **Data Views** tabs of your portals are, together, the organization's complete public general-query exposure list for authored pages. Review any bound commerce channel separately. - Editing the underlying entity view edits the portal. The view is live configuration, not a snapshot — adding a column or loosening the filter changes what visitors receive on their next request, with no publish step in between. Review view edits with the same care as a publish. ## Common questions ### Does publishing a data view expose the whole entity? The read grant is entity-wide for the anonymous profile, but reach is not: visitors can only query through published views, so what they can actually retrieve is the union of your public views' columns and filtered rows, still subject to record and field security. The practical rule stands regardless: publish a view only when every record its filter matches is fine to treat as public. ### If I edit the entity view later, does the portal change? Yes, immediately — the data view references the live entity view. The draft/publish gate covers page *layouts*, not view definitions. To rework a view a portal is serving, deactivate the data view first, or build the change on a copy of the view and re-point the data view when it is ready (editing a data view lets you switch which view it serves). ### Can two portals publish the same entity? Yes — each portal publishes its own data views, and several can reference the same entity or even the same entity view. The anonymous read grant is shared: it exists while *any* portal has an active public view of the entity, and is revoked when the last one goes. ### Why does a public list look identical to a signed-in user? By design. Public views always execute as the portal's anonymous identity, so a catalog page is consistent for every visitor — being signed in never changes a public surface. Person-specific data belongs on an **Authenticated** view, which runs as the caller. ## Related topics - [Build and publish a portal](/docs/portals/build-a-portal/) - [How portal security works](/docs/portals/security/) - [The data model](/docs/customization/data-model/) - [Security profiles](/docs/administration/security-profiles/) ---- # Publishing, hostnames and custom domains URL: https://xmatix.com/docs/portals/publishing-and-domains/ Last reviewed: 2026-09-06 Publishing is what turns portal configuration into a served website, and the hostname question — where visitors reach it — has two answers: the platform hostname every published portal gets automatically, and custom domains you bring yourself. This page covers the site-level publish and retract actions, then both kinds of hostname. Custom domains are the newest part of the portal stack and may not yet be enabled in every environment; the platform hostname works everywhere. ## Prerequisites - The portal-management capability (`setup.portals.manage`). - A portal ready to serve — pages published, data views active. See [Build and publish a portal](/docs/portals/build-a-portal/). - For a custom domain: control over the domain's DNS zone. Verification and serving both work through DNS records you create. ## Procedure Before publishing, open the portal's **General** tab and confirm the label and slug, keep **Active** aligned with the intended serving state, and review **Anonymous visitors**: with it off, only signed-in external users can view the site. ### Step 1 — Publish the site On the portal's detail page (**Setup → Feature Hub → Portals → Portals**, open your portal), click **Publish** in the header. The portal becomes servable — visitors receive only its published pages and active data views — and its platform hostname is registered automatically: a single label combining the portal slug and your organization's slug (portal `shop`, organization `acme` → `shop-acme`) under the platform's portal domain. There is no DNS work on your side for this hostname. ### Step 2 — Retract when you need to Retracting mirrors publishing at each level. **Unpublish** on the site stops serving to all visitors immediately; **Unpublish** on a single page removes just that page. The site's **Active** switch is the hard kill switch — an inactive site is never served, regardless of publish state. None of these delete anything: republishing restores service from the same configuration. ### Step 3 — Add a custom domain Open **Setup → Feature Hub → Portals → Domains** and click **Add Domain**. Choose the domain type **Portal** (serves a portal site), pick which portal the domain should serve, and enter the hostname — a subdomain such as `shop.example.com` is the dependable choice (see the apex note under Common problems). The domain is recorded, and its row shows the DNS records to create. @[guided-image](_img/portal-add-domain-dialog.png) The Portal domain choice reveals the **Portal site** selector. This relationship is explicit: the domain record routes one hostname to one authored portal, while the portal's publish and active state still decide whether there is anything to serve. ### Step 4 — Create the DNS records In your DNS zone, create the two records from the domain's row: a **CNAME** pointing your hostname at the returned target, and a **TXT** record that proves control of the name. Verification is DNS-based — the certificate for your hostname is issued once the records resolve. ### Step 5 — Verify and serve Use the row's **Refresh** action to re-check; the status updates only when re-checked, so how fast you verify is mostly how fast your DNS changes propagate. Once the domain shows **Verified**, it serves the portal directly — same content, same security, your name in the address bar. The platform hostname keeps working alongside it. ### Step 6 — Remove a domain when retiring it **Remove** detaches the hostname from the platform edge and it stops serving immediately. Delete the CNAME from your DNS zone as well, so the name is not left pointing at nothing. ## Expected result The portal is published and active, its platform hostname serves the expected published snapshot, and every attached custom hostname shows **Verified** before it is announced to visitors. Both names render the same content and enforce the same audience rules. After retirement, the platform no longer serves the removed hostname and the obsolete DNS record is absent; if verification or routing disagrees, keep the platform hostname available while you correct DNS rather than repeatedly deleting and recreating the domain. ## Common problems **Verification never completes.** Almost always the DNS records: one of the two is missing, was created in the wrong zone, or has not propagated yet. Check both records with a DNS lookup tool from outside your own network, then **Refresh** again. **The domain verifies but the portal shows not-found.** The domain is attached, but the portal behind it is not being served — the site is unpublished or inactive. Domains route traffic; they do not publish anything. **An apex domain (example.com, no subdomain) won't verify.** Apex records cannot be CNAMEs in standard DNS. If your DNS provider supports ALIAS/ANAME records or CNAME flattening at the apex, use that; otherwise serve the portal on a subdomain such as `shop.example.com`. ## Common questions ### What is the difference between the Web and Portal domain types? A **Portal** domain serves a portal site directly on that hostname. A **Web** domain is an entry host for the application itself — it redirects your own team onto the app. When you are putting a portal on your own name, pick **Portal**. ### Does unpublishing the site break a verified custom domain? No — the domain stays attached and verified. With the site unpublished, requests to it return not-found until you publish again, so you can retract and restore service freely without re-doing any DNS work. ### Can visitors still use the platform hostname after I add a custom domain? Yes. Adding a custom domain adds a name; it does not replace the platform hostname, and both serve the same published portal. ## Related topics - [Build and publish a portal](/docs/portals/build-a-portal/) - [Troubleshooting portals](/docs/portals/troubleshooting/) - [Portals on the xMatix site](/products/portals/) - [Security and governance on the xMatix site](/platform/security/) ---- # How portal security works URL: https://xmatix.com/docs/portals/security/ Last reviewed: 2026-09-02 Every portal raises the same question: this site is on the public internet and it renders business data — what exactly stops it from serving the wrong thing? The xMatix answer is a scoping model with three load-bearing rules, each enforced by the platform rather than by authoring discipline. Understanding them is what turns "is our portal safe?" from a feeling into a checklist. ## The three rules Demo2 currently has no portal row, so the exact **General**, **Pages** and **Data Views** security gates cannot be captured without creating production configuration. This page therefore stays text-led rather than reusing the empty registry as evidence for controls it does not show. In a configured tenant, **Active** controls whether the site can serve at all, **Anonymous visitors** decides whether the tenant's anonymous principal may enter, and the signup switches create identities without widening a page or data view's audience. 1. **Only published content is served.** Page drafts, unpublished pages, site settings, unpublished or deactivated sites — none of it ever reaches a visitor. What serves is the published snapshot of each page and nothing else. 2. **Authored pages query records only through published data views.** The authored-content surface resolves the site, fetches a published page, queries a published data view and accepts signup; it has no route to the platform's general data interfaces. A commerce portal may additionally call a separately allowlisted storefront surface for catalog, cart, checkout, payment and customer-account workflows. Those operations do not turn a page design into an unrestricted data client. 3. **Every read executes as a real identity.** Anonymous reads run as the portal's visitor identity; authenticated "my records" reads run as the signed-in external user. Either way, the standard security engine — entity permissions, record-level security, field-level security — makes the decision. The portal adds no authorization logic of its own, which means there is no second rulebook to drift out of sync. ## The anonymous identity and its profile Each organization has one synthetic anonymous visitor principal shared by all of its portals. Public requests execute as that external, non-sign-in account, and each portal record points to it so the serving identity remains inspectable. The principal carries the least-privilege **Portal Anonymous** security profile, and publishing is what feeds that profile: publishing a public data view grants read access on that entity, and the grant is revoked automatically when the last active public view of the entity — across all of your portals — is removed or deactivated. Because both the principal and profile are tenant-wide, one warning matters: any access you grant the profile *by hand* applies to every anonymous visitor on every portal in the organization, and manual grants survive the automatic revocation (which only withdraws what publishing added). Treat widening that profile as publishing — do it only when you mean "public". ## How it composes with your organization's security A row reaches a visitor only by passing every layer, from the outside in: - **Site gates** — the site is active, published, and (for anonymous visitors) allows anonymous access. - **Page gates** — the page is active, published, and its audience admits the caller. - **Data view gates** — the view is active, its audience admits the caller, and its page size cap bounds the volume. - **The view definition** — the entity view's columns and base filter shape what the query even asks for. - **The security engine** — entity permissions, record-level rules and field-level security apply to the executing identity, exactly as they would inside the application. For signed-in visitors the last layer is where "my records" comes from: external users' record access defaults to private, so an authenticated view shows a person only the records they own or are linked to, unless your rules deliberately share more. See [Record-level security and sharing](/docs/administration/record-security/). ## What never leaves the platform - Page drafts — the portal serves only published snapshots. - The site's settings document. - Entities without a published data view. - Records and fields the executing identity cannot read. Published page layouts and data views are read-only. Signup deliberately creates identity records, and a portal bound to a commerce channel may also create or update the narrowly scoped records required by cart, checkout, payment and account workflows. Those writes go through their purpose-built storefront controllers and checks; there is still no general record-write endpoint available to an authored page. ## Common questions ### Is everything in a published data view public? For a **Public** view, plan on yes: its rows and columns are served to anyone, identically, by design. The security engine still applies — field-level rules can hide columns, record rules can exclude rows — but the sound practice is not to rely on that as the fence. Publish a public view only when everything its filter matches is fine to treat as public information. ### Can portal visitors change data? Not through a page layout or published data view: both are read-only, and an Authenticated view changes who executes the read rather than granting a write. Signup does create the visitor identity, and commerce portals can write through their explicit cart, checkout, payment and account workflows. If a requirement needs arbitrary record editing, do not infer it from portal sign-in or a data view; that capability is not exposed by the authored portal layer. ### We deleted a data view — is the entity still exposed? Only if another active public view of the same entity exists on any of your portals; the automatic read grant is withdrawn when the last one goes. The **Data Views** tabs across your portals are the complete list of general record-query exposure from authored pages. Purpose-built commerce operations have their own configured catalog and transaction boundaries and must be reviewed separately. ### Does the Portal Anonymous profile show up in our security administration? Yes — it is a normal security profile, visible alongside your others, and that is intentional: portal exposure is auditable exactly where you already audit access. Its publish-managed grants come and go with your data views; anything extra you see on it was added by an administrator and deserves the "is this meant to be public?" question. ## Related topics - [Portal pages and data views](/docs/portals/pages-and-data-views/) - [Portal visitors, signup and identity](/docs/portals/visitors-and-signup/) - [The xMatix security model](/docs/concepts/security-model/) - [Security profiles](/docs/administration/security-profiles/) - [Security and governance on the xMatix site](/platform/security/) ---- # Troubleshooting portals URL: https://xmatix.com/docs/portals/troubleshooting/ Last reviewed: 2026-09-02 Portal complaints have a useful property: the serving rules are strict, so the causes are enumerable. A portal serves only a published, active site; only published, active pages whose audience admits the caller; and only active data views, executed as a real identity. This page works through the four complaints that cover most cases, with the checks in the order they pay off. This page stays text-led because each symptom maps to several distinct admin and visitor states; a single portal screenshot would imply one diagnosis. Follow the named register, tab and state checks below, then capture the exact failing surface for the incident record. Start every portal incident in the registry. Confirm the site exists, then compare Name, Slug and Address, Published, Status, Anonymous, Pages and Version. If no row exists, the hostname cannot legitimately serve a tenant portal; creating a replacement before locating the intended record risks duplicate configuration and conflicting host registration rather than repairing the original. Work outward in serving order: domain and certificate, active published portal, requested page path and audience, published version, active data view, executing visitor identity, and underlying permissions. For signup, also check both enablement switches, invitation delivery and duplicate identity rules. Capture the hostname, path, visitor state, expected version, timestamp and response, but redact customer records and authentication artifacts from broad support screenshots. ## The portal doesn't load at all Work down the list and stop when the behavior explains itself: 1. **The site isn't published.** On **Setup → Portals** the site shows **Draft**, and its detail header offers **Publish** rather than **Unpublish**. An unpublished site is not served at all. 2. **The site is inactive.** The **Active** switch is the kill switch — it beats publish state, so a published-but-inactive site still serves nothing. 3. **Anonymous access is off.** With **Anonymous visitors** off, anonymous requests get not-found; the portal exists only for signed-in external users. 4. **The Portals module is disabled** for the organization — every portal serves not-found while it is off. 5. **You published moments ago.** Hostname registration is picked up on the next lookup, and misses are cached briefly — retry after a minute before digging deeper. ## A page is missing from the portal 1. **It isn't published.** The Pages tab shows each page's state — **Published**, **Draft** or **Empty** — and only published pages exist to visitors. 2. **It is inactive.** An inactive page is skipped even when published. 3. **Its audience is Authenticated** and the visitor is anonymous: the page is absent from the anonymous menu, and a direct visit to its path asks for sign-in rather than rendering. 4. **The authored navigation omits it.** When the site carries a navigation document, that document is the menu — a page can be live but unlinked. Check by visiting its path directly. ## A page renders but is empty 1. **The published snapshot is empty.** The page was published while its draft had no content; publishing snapshots whatever the draft holds. Add the content and **Publish draft** again. 2. **Edits were made but never published.** The portal serves the snapshot, not the draft — this is the single most common "my change isn't showing" cause. 3. **An embed page names no data view** (or misnames one) in its embed target. 4. **The page type has no portal rendering yet.** Designed pages and entity list embeds are the types that render content today; entity detail and app page embed types can be authored ahead of their portal rendering and come up empty. ## A data list shows no rows or an error 1. **"Portal is not ready to serve data."** The portal's visitor identity has not been provisioned yet. Open the portal in Setup and save it once — provisioning is retried on save — then reload the portal. 2. **The data view is inactive** or was deleted. Deactivation stops serving immediately. 3. **The view's filter matches nothing.** Open the same entity view inside the application and confirm it returns rows there before suspecting the portal. 4. **Record security excludes the rows for the executing identity.** What you see inside the application as an internal user is not the reference: public views execute as the portal's anonymous identity, authenticated views as the signed-in visitor, and each is scoped by its own access. The layers are laid out in [How portal security works](/docs/portals/security/). ## Signup does nothing 1. **Signup is disabled on the site.** The **Self-service signup** switch must be on, and the site must be published. 2. **The address already has an account.** By design the visitor still sees the same "check your email" acknowledgement, but no new mail is sent for an existing account — the right move is to sign in with it. 3. **The invite email hasn't arrived yet.** Invites are sent in the background — allow a few minutes and check the spam folder. The email asks the person to set a password; until that step completes, the account cannot sign in. ## Common questions ### The portal shows data we never meant to publish — where do I look? The union of active public data views across *all* of the organization's portals is the complete general-query exposure for authored pages, so check every portal's **Data Views** tab, not just the one you were editing. Then look at the shared **Portal Anonymous** security profile for grants an administrator added by hand — those apply to every anonymous visitor and are not removed automatically. Deactivating a data view stops it serving immediately. If the portal is bound to a commerce channel, review its separately allowlisted catalog and transaction configuration as a second surface. ### I fixed the page but the portal still shows the old version. Saving edits the draft; the portal serves the published snapshot — use **Publish draft** on the page after editing. Site settings (theme, navigation, description) are the exception: those apply to a live portal on save. ### Everything is green in Setup but the custom domain returns not-found. Domains route; publishing serves. Confirm the domain row on **Setup → Domains** shows **Verified**, then confirm the site itself is published and active — a verified domain in front of an unpublished site returns not-found. The DNS-side checks are in [Publishing, hostnames and custom domains](/docs/portals/publishing-and-domains/). ## Related topics - [Build and publish a portal](/docs/portals/build-a-portal/) - [Portal pages and data views](/docs/portals/pages-and-data-views/) - [Publishing, hostnames and custom domains](/docs/portals/publishing-and-domains/) - [How portal security works](/docs/portals/security/) ---- # Portal visitors, signup and identity URL: https://xmatix.com/docs/portals/visitors-and-signup/ Last reviewed: 2026-09-02 Portals serve people who are not members of your organization, and the identity model takes all of them seriously — including the ones who never sign in. Three kinds of visitor exist: anonymous visitors, people in the middle of signing up, and signed-in portal users. This page explains what each one *is* in your organization's terms, because that is what decides what they can see. Sign-in on the portal surface itself is the newest layer of the portal stack and is still rolling out; the identity model below is what it builds on. ## Anonymous visitors are a real identity An anonymous request is not a security exception. The organization has one tenant-wide synthetic visitor principal shared by all of its portals, carrying the least-privilege **Portal Anonymous** security profile. Anonymous reads execute *as that identity*, so the same security engine that protects the application decides what the portal serves; there is no separate rulebook for public traffic. The account itself can never be signed in to — it exists only as the identity anonymous reads run under. The site's **Anonymous visitors** switch controls whether anonymous viewing is allowed at all: switched off, the portal serves signed-in external users only, and anonymous visitors get nothing — not even the page list. ## Self-service signup Demo2 currently has no portal row, so the two signup switches cannot be shown without creating production configuration. An empty registry would not evidence their state, and this page deliberately avoids reusing it. On a configured portal, **Self-service signup** admits signup requests. **Create customer on signup** controls whether a successful signup also provisions the fresh consumer Account and Contact that commerce views need; it defaults on unless an administrator explicitly switches it off. With **Self-service signup** enabled on the site, visitors can create their own account by submitting an email address, optionally with a name and phone number. What happens next: 1. When **Create customer on signup** is on, xMatix first creates a new consumer **Account** and **Contact** from the submitted identity details. It never searches by email and adopts an established customer record, because an anonymous caller must not be able to claim one. 2. An **external account** is created and linked to that newly created Contact. The same save also records membership of the portal the visitor used; the account is not automatically admitted to the organization's other portals. 3. The person receives an email inviting them to **set a password**, which activates sign-in. 4. The response is deliberately uninformative: whether the email was new or already registered, the visitor receives the same accepted acknowledgement, so signup cannot be used to probe which addresses hold accounts. If **Create customer on signup** is explicitly off, signup creates an unlinked external login instead. Commerce reads have no customer account to resolve until an administrator links that login through the invite/linking flow. In both modes, signup never attaches the visitor to an *existing* Account or Contact by email; adopting an established customer remains an administrator action. ## What a signed-in portal user is A signed-in portal user is an **external account**: a real account in your organization with an external audience, created by signup or by an administrator's invite. External accounts are not internal seats — they do not appear among your workforce, and they hold only the access their external-scoped security profiles and record-security rules give them. The account must also have membership of the portal it is entering. In the authored portal layer, being signed in unlocks two things: - **Authenticated pages** — pages whose audience is signed-in users only. - **Authenticated data views** — "my records" surfaces that execute as the signed-in person, so ownership and sharing rules scope the rows to theirs. A customer whose account is linked to their customer record sees their own orders; nobody else's. Public pages and public data views, by contrast, never change with sign-in: they always serve the anonymous identity's view of the data, identical for everyone. If the site is also bound to a commerce channel, the signed-in external account can use the storefront's separately governed account and transaction flows as configured. That commerce surface does not make an Authenticated data view writable and does not bypass the portal-membership check. ## Common questions ### Do portal accounts consume internal user seats? No — external accounts are a separate population from your internal named users, and a visitor creating one does not occupy an internal seat. Portal signups are recorded as usage events so the organization's portal activity is meterable; for how licensing is structured, see [Licensing](/docs/administration/licensing/). ### Why does signup always report success? Because a different answer for already-registered emails would tell strangers which addresses have accounts. New addresses get an account and a set-password email; existing addresses get nothing new — and both see the same acknowledgement. A visitor who already has an account should sign in instead. ### Can someone sign up and still see nothing new? It depends on the site's **Create customer on signup** setting. With the default on, a new signup is linked to the fresh consumer Account and Contact created for it, so commerce surfaces can resolve that new account immediately; it still cannot inherit an established customer's records by matching email. With the switch off, the login is intentionally unlinked and personal commerce surfaces remain empty until an administrator links it. In either case, entity permissions, record rules, data-view audience and portal membership still have to admit the read. ## Related topics - [How portal security works](/docs/portals/security/) - [Invite a user](/docs/administration/users/invite-a-user/) - [Record-level security and sharing](/docs/administration/record-security/) - [Licensing](/docs/administration/licensing/) ---- # Auto-order: rules-based purchase suggestions URL: https://xmatix.com/docs/procurement/auto-order/ Last reviewed: 2026-09-05 An auto order is a worksheet of purchase suggestions computed by explicit stock rules — not a prediction. Three engines cover three buying styles, and every suggested line stores the numbers that produced its quantity, so you can always read *why* before you buy. Nothing is purchased automatically: you review the lines, adjust them, and only then generate the purchase order. Open the **Procurement** app and choose **Auto Orders**. The list is titled **All Auto Purchase Orders**; a saved record has four tabs — **Auto Order Setting**, **Lines**, **Related** and **Details**. ## The engines An auto order's **Auto Order Type** picks its engine. The picklist offers five values; the code implements four of them. | Type | What it does | Suggested quantity | | --- | --- | --- | | Minimum Stock Level | Suggests an item when its available stock at the branch is below the planning row's minimum stock level. Only branch-scoped planning rows are read by this engine. | The row's reorder quantity — or, when no reorder quantity is set, the shortfall up to the minimum. An item with a planning row but no stock record at all is suggested at its reorder quantity or minimum. | | Replenish | Suggests what was consumed — allocated to order or service-order fulfilment at the branch — since the branch's most recent Replenish auto order date. | The allocated quantity since that date: buy back what went out. | | Forecasting | Projects the stock position forward by netting inbound supply and committed demand, then applies a reorder-point rule. | Whatever tops the item back up to its maximum order quantity. | | Template | A reusable Forecasting configuration. It never holds lines; it spawns a fresh, dated Forecasting order that copies its scope, price list, budget and include/exclude flags. | Not applicable — the spawned order runs the Forecasting engine. | | Back Order | Present in the picklist but not implemented by any engine. **Lines** is refused on an order of this type. | None. | All the per-item inputs — minimum stock level, reorder quantity, minimum/maximum order quantity, lead time, average consumption, ABC and FSN categories — come from the item's inventory planning attributes (**Item Inventory Attributes**), which can be scoped per SKU, branch and partner account. See the [configuration reference](/docs/procurement/configuration/). ## How Forecasting projects the pipeline Forecasting is the only engine that looks forward. For every planning row in scope (branch and partner match, or unscoped), it nets the pipeline and applies a fixed min/max rule: ``` projected = available + in-transit shipments + pending purchase orders − open requisitions − open sale orders reorder point = lead time × average consumption + minimum order quantity suggested = maximum order quantity − projected (only when projected ≤ reorder point) ``` The **Inventory Projections** switches on the saved order's **Auto Order Setting** tab choose which pipeline sources count: **Include In-Transit Shipments**, **Include Pending Purchase order**, **Consider Open Sale Order** and **Consider purchase requisition**. Any individual shipment, purchase-order, requisition or sale-order line can opt out of the maths with its *Exclude In Auto Order* flag. Where several planning rows match the same item and SKU, their numeric parameters are averaged. The fifth switch, **Consider High probability quote**, is stored and copied to spawned orders but is not read by the engine — the quote quantity in the projection is always zero. Leave it off; ticking it changes nothing. ## What gets excluded Exclusion flags on the **Auto Order Setting** tab skip whole item categories on every engine: - **Exclude FSN Items:** fast-moving, slow-moving or non-moving items. - **Exclude ABC Items:** A-, B- or C-category items. Categories come from the item's planning row; an item with no row has no category and is never excluded this way — and, having no parameters, it is never suggested either. ## Fit to Budget **Fit to Budget** (field `BudgetAmount`) caps the priced worksheet. After the engine has produced lines and priced them, if the total amount exceeds the budget every priced line's quantity — suggested, derived and pending — is scaled down by the same factor (budget ÷ total) and rounded to two decimals so the order fits. Lines whose price-list lookup returned zero are left untouched: they consume no budget, and trimming them would only hide a missing price. Zero or blank means no cap. The cap is applied by the **Lines** and **Order from Template** actions. The scheduled job prices and totals the lines it generates but does not apply the budget cap, so a scheduled Forecasting order can exceed its budget until someone regenerates it with **Lines**. ## The arithmetic snapshot on every line Every suggested line records its inputs, not just its answer. All engines store **Suggested Quantity**, **Quantity** (what you may edit) and **Pending Quantity** (what a purchase order would take), and — when the header's open-order calculation is on — the **Open Order Quantity** already pending on purchase orders for the same partner, branch, item and SKU. Forecasting lines freeze the full pipeline snapshot: | Field | What it held at suggestion time | | --- | --- | | Projected Quantity | The netted stock position the rule fired on. | | Quantity Available | On-hand stock. | | Pending Shipment / Pending Purchase Order Quantity | Inbound supply that was counted. | | Pending Requisition / Pending Sale Order Quantity | Committed demand that was netted off. | | Minimum / Maximum / Reorder Quantity | The planning parameters used (averaged when several rows matched). | | Lead Time, Average Consumption | The reorder-point inputs, rounded to whole numbers. | Pricing happens after generation: **Unit Cost** comes from the price-list rules of the order's price list (a default purchase price list is assigned when the order is created), **Amount** is unit cost × quantity, and the header's **Total Amount** and **Total Pending Quantity** are rolled up from the lines. The purchase-order quantity nudge in Sense AI uses the same pipeline query service and planning inputs, but it runs at a different time and applies its own divergence threshold, so a nudge and an earlier auto-order snapshot can differ when stock, demand, supply or planning rows changed in between. ## Prerequisites - Inventory planning attributes on the items you want suggested — an engine only considers items it has parameters for, and the Minimum Stock Level engine only reads rows scoped to a branch. - Create permission on auto orders and, for the last step, on purchase orders. - A purchase price list with rules for the items, or every line prices at zero. - For scheduled runs: administrator access to job schedules. ## Procedure @[guided-image](_img/auto-order-list.png) Start from the **All Auto Purchase Orders** list. Identify the worksheet by partner account, branch, supplier and **Auto Order Type** before opening it. The **Order Generated** counter and the **Is Order Generated** flag are the reliable generation state: the **Status** picklist is seeded with *Draft* and *Order Generated* but no engine or action writes it, so rows can show any value their creator set. @[guided-image](_img/new-auto-order.png) ### Step 1 — Create the auto order Choose **New**. The create form asks for **Auto Order Type** and **AI Recommendation**, then **Partner Account**, **Branch** and **Supplier Account** under **System Details**. Document Date is stamped automatically, and partner and branch are validated to belong together. Pick Minimum Stock Level, Replenish or Forecasting for a worksheet you will generate yourself, or Template for a configuration the scheduler should spawn from. **AI Recommendation** is stored but no generation or ordering service reads it; the engines stay deterministic whatever you select. @[guided-image](_img/auto-order-detail-settings.png) ### Step 2 — Set the run options On the saved record open **Auto Order Setting**. Tick the **Inventory Projections** sources a Forecasting run should net, choose the **Exclude FSN Items** and **Exclude ABC Items** categories to skip, and enter a **Fit to Budget** amount if the worksheet must stay within a spend limit. The two **Apply AI Recommendation** selectors (the stored AI Recommendation and the Apply Inventory Attribute Settings preference) are not consulted by the engines — matching planning rows are always averaged. Save the tab. ### Step 3 — Generate the lines Run the **Lines** action (Generate Auto Order Lines). It runs the engine for the order's type against the current stock and pipeline data, prices the lines and applies the budget cap. It deletes any existing lines first, so re-running after changing an option always reflects the change. It is refused on Template and Back Order types and once a purchase order has been generated from the auto order. For a Template, run **Order from Template** instead: it creates a new Forecasting order named after the template and today's date, linked back to the template, generates and prices its lines, and leaves the template itself unchanged. @[guided-image](_img/auto-order-detail-lines.png) ### Step 4 — Read the arithmetic and adjust Open **Lines** and read each snapshot: minimum and maximum quantity, quantity available, suggested quantity, the editable **Quantity**, unit cost and amount. Agree? Leave the line. Disagree? Edit **Quantity** — the suggested quantity stays as the record of what the rule computed. A line's pending quantity is what will actually be ordered; a line whose suggestion netted to zero is skipped at generation. ### Step 5 — Generate the purchase order Run **Purchase Order** (Perform Order Generation) to turn every line with pending quantity into one purchase order for the order's branch and supplier, or **Selective Order** to take chosen lines with a requested quantity per line — each request is validated against that line's pending quantity and capped at its derived quantity. The purchase order links back to the auto order (`Purchase Auto Order` on the order header) and each of its lines to the suggestion line it came from. The auto order is then marked **Is Order Generated** and its lines can no longer be regenerated. ### Step 6 — Schedule recurring suggestion runs (admin) The job **Generate forecast auto-order lines** keeps Forecasting suggestions coming without anyone clicking. On every run it fills Forecasting auto orders that have no lines yet and no generated purchase order, and spawns one dated Forecasting order per day from each Template. An administrator creates a job schedule with a cron cadence to turn it on; **Run now** triggers a run manually. Runs are idempotent — already-filled orders and templates that already spawned today are skipped — and only one run executes at a time per organization. Minimum Stock Level and Replenish orders are generated on demand with **Lines**, never by the schedule. ## Expected result Each generated suggestion line shows its calculated quantity, its price and the snapshot of stock, demand, supply and planning parameters that produced it; the header totals agree with the lines. Reviewed pending quantities release once into a linked purchase order, after which the auto order is read-only for regeneration. Scheduled templates produce at most one dated Forecasting order per day. If the outcome is surprising, compare the stored snapshot with current planning attributes before editing a quantity or creating another order. ## Common problems - **Lines produced nothing.** No planning rows match the order's branch and partner (Minimum Stock Level needs branch-scoped rows), every projected position is above its reorder point, the ABC/FSN exclusions removed everything, or — for Replenish — nothing was allocated since the branch's last Replenish order. - **"Generate Lines is only available for Minimum Stock Level, Replenish, or Forecasting auto orders."** The order is a Template (use **Order from Template**) or a Back Order, which no engine implements. - **"Purchase Order is already generated for this Auto Order."** A generated auto order is closed — create a new one to run the engine again. - **"No Auto Purchase Order Lines with pending quantity to create Purchase Order."** Every line's quantity has been zeroed or already ordered. - **Quantities are smaller than the snapshot suggests.** Check **Fit to Budget**: a budget below the priced total scales every priced line down proportionally. - **Every Unit Cost is zero.** The order's price list has no rule for the items; fix the price list and re-run **Lines**. - **A suggested quantity looks wrong.** Read the line's snapshot before assuming a defect — see [troubleshooting](/docs/procurement/troubleshooting/). ## Common questions ### Is this AI demand forecasting? No. All three engines are fixed, explainable rules over your own stock and document data — there is no machine-learning model and no prediction. The "Forecasting" engine's name refers to projecting the pipeline forward with the arithmetic shown above, and every input it used is stored on the line it produced. The AI Recommendation fields on the form are stored values only. ### Why do open sales orders only matter to the Forecasting engine? Because only Forecasting projects a stock position. Minimum Stock Level compares today's stock to a threshold, and Replenish buys back what was already consumed — neither needs the demand/supply pipeline. Both can still record the quantity already pending on purchase orders when the header's open-order calculation is on. ### Can a suggestion turn into a purchase without review? No. The scheduled job only *generates suggestion lines*; a purchase order exists only when someone runs **Purchase Order** or **Selective Order** on the reviewed worksheet. ### What does the Status column mean? Little. No engine or action assigns it, so it holds whatever was typed or seeded. Use **Is Order Generated** (the **Order Generated** list counter) and whether the **Lines** tab has rows to judge where a worksheet stands. ## Related topics - [Procurement configuration reference](/docs/procurement/configuration/) — planning attributes and exclusion flags - [The purchase order lifecycle](/docs/procurement/purchase-orders/) - [Requisitions: from request to purchase order](/docs/procurement/requisitions/) - [Troubleshooting procurement](/docs/procurement/troubleshooting/) ---- # Supplier bills URL: https://xmatix.com/docs/procurement/bills/ Last reviewed: 2026-09-05 A bill is the supplier's invoice recorded in xMatix — the payable end of the procure-to-pay chain. Bills are released from a purchase order or a goods receipt, or entered directly. The line links differ by path: order-side release always sets the purchase-order-line link and adds the receipt-line link when receipt lines exist; receipt-side release sets only the receipt-line link; a keyed-in bill has neither. Open the **Procurement** app and choose **Bills**. The list is titled **All Bills**; a saved bill has **Lines**, **Details**, **Related** and **Approval** tabs, an **Amounts** panel with a **Payment** summary, a status stepper under the header, and **Post General Ledger** and **Post Inventory** in the record header. ## Where bills come from | Source | Actions | What the bill gets | | --- | --- | --- | | Purchase order | **Release Invoice**, **Selective Release Invoice** | Header: the order's branch, partner account, supplier and document date, linked to the order. Lines: for an order line with receipt lines still to invoice, one bill line per receipt line carrying **both** the purchase-order-line and goods-receipt-line links, the receipt's lot and its pending invoice quantity; for a line with nothing received, one bill line with the order-line link only. Selective takes ticked lines with a requested quantity, validated against the order line's pending invoice quantity. | | Goods receipt | **Release Bill** | Header: the receipt's branch, partner account, supplier and document date, linked to the receipt. Lines: one per receipt line with pending invoice quantity, carrying the **goods-receipt-line link only**, the line's tax group and lot. | | Direct entry | **New** | A header you fill in; lines you add. No source links, so nothing rolls back into an order or receipt and the lines cannot be matched. | Each order line tracks its pending invoice quantity separately from its receipt progress, so billing can run ahead of or behind receiving, and one order can be billed across several invoices. Item lines are priced from the bill's price list when they are created — the unit cost on the order or receipt is not copied — so always compare the lines with the supplier's invoice. ## Read the screen @[guided-image](_img/bill-list.png) The list identifies bills by supplier, branch, date, total and **Status**. **Status** (*Draft*, *Approved*, *Rejected*, *Posted*) is a manual marker: the stepper on the saved bill advances it one step at a time when you click, and neither posting nor payment writes it. Read payment state from the **Amounts** panel and posting state from the **GL Posted** flag on **Details**. @[guided-image](_img/new-bill-concept.png) ### The create form | Field | Where | What it does | | --- | --- | --- | | Document Date | Header | The date the bill is booked in your ledgers; stamped with today. | | Supplier Account | Header | The vendor being paid — the party on the payable. Defaults to the branch's default supplier; locked after save. | | Goods Receipt, Purchase Order | Header | Source links; filled by the release that created the bill. **Purchase Order** is locked after save. | | Type of Bill | Header | *Purchase Bill*, *Expense Bill* or *OTC Purchase Bill* — a classification for reporting. | | Supplier Invoice Date, Supplier Invoice Number, Supplier Invoice Amount | Header / Details | The vendor's own document references, kept apart from your document number and date. | | Executive | Header | The person responsible for the bill. | | Tax Supply Type, Tax Group | Tax & Pricing | The tax lane (*Within State*, *Outside State*, *Exempt*, *Exports*, *SEZ*) and header tax group. | | Discount Group, Price List | Tax & Pricing | Defaulted to the purchase-type discount group and price list; lines discount and price from them. | | Billing Address, Shipping Address | Their tabs | Defaulted from the partner account's addresses. | | Partner Account, Branch | System Details | The organization that owes the money and the branch; both locked after save. | | Due Date, Payment Terms | Details | **Due Date** is copied onto the payable open item when the bill posts and drives ageing. | | GL Posting Type | Details | Which control account the header credits: blank or *Credit* posts to accounts payable; a cash or bank type posts to that account instead. | | Is RCM | Details | Marks a reverse-charge bill: the tax portion is self-assessed when the bill posts. | ### Lines @[guided-image](_img/bill-detail-lines.png) Add lines with **Quick Add** or let a release create them. Each line carries **Quantity**, **Unit Cost** (looked up from the bill's price list on creation, overridable; **Unit Cost 2** takes precedence in the amount when set), discounts, a snapshot of its taxes, **Gross Amount**, and three fields that decide how it posts: - **Goods Receipt Line** — set, the line clears the goods-received-not-invoiced accrual the receipt already raised, so inventory is not debited twice; unset, the line debits inventory or expense according to its **GL Posting Type**. - **GL Posting Type** — *Inventory* or *Expense* for lines that did not come from a receipt. - **TDS Section** — a withholding section. New lines without one inherit the vendor's default section; a section on the line deducts withholding tax when the bill posts. Guards: unit cost cannot be negative; the source links (purchase-order line, goods-receipt line) cannot be changed; the item and SKU of a receipt-sourced line are locked; a line's quantity cannot drop below what has been returned against it, and a line with returned quantity cannot be deleted. ## Posting A bill is a document first and an accounting entry second. Posting is explicit and lives in the record header: - **Post General Ledger** approves the bill for posting and writes one balanced journal: debit goods-received-not-invoiced (receipt-linked lines) or inventory / expense (other lines) plus input tax; credit accounts payable (or the cash/bank account chosen by **GL Posting Type**). It raises a payable open item carrying the **Due Date**, deducts TDS for lines with a withholding section (debit payable, credit TDS payable), records the input-tax transactions used by tax returns, and — for purchases raised against a service order — writes the billed cost back onto the service-order line. Re-posting reverses the previous journal before writing the new one. - **Post Inventory** posts the bill lines that have no inventory-ledger reference yet to the inventory ledger; it refuses with *No Bill Lines found for Inventory Posting* when every line is already posted. Use it for the flows where the bill, not a receipt, is the stock document. Once posted, the bill is an open payable. **Open Amount** and **Adjusted Amount** on the header, and the **Payment** summary in the **Amounts** panel (total, adjusted, open, and the payments and adjustments behind them), show how much supplier payments have settled — not **Status**. ## Reviewing before payment The [three-way match service](/docs/procurement/three-way-match/) is read-only and has no standard screen or payment gate. It counts only bill lines that carry the purchase-order-line link, so a bill released from a goods receipt — or keyed in — is absent from its result even when it is perfectly valid. If your process receives before billing and you want both links, release the invoice from the **purchase order after the receipt exists**. ## Common questions ### Do I have to receive the goods before recording the bill? No. Release the bill from the purchase order while the order line still has pending invoice quantity; the line carries the order-line link only. If the same order is invoiced after receipt lines exist, the order-side release builds the bill lines from the receipt lines and carries both links. ### The supplier's invoice does not match what we received. Record it or not? Record what the supplier actually invoiced — quantity and unit cost on the lines, the supplier's own number, date and amount on the header — then compare the receipt lines' received quantity and the order lines' unit cost with it. The standard product does not block payment automatically; the comparison and the decision are yours. ### Can a manually entered bill be matched? Only if its lines have the purchase-order-line link, which a keyed-in bill does not get. A bill released from a goods receipt is in the same position: it carries the receipt-line link only. ### Why is the unit cost on a released bill different from the order? Because bill lines are priced from the bill's price list when they are created; the order's or receipt's unit cost is not copied (except for description-only charge lines). Correct the unit cost on the bill line to match the supplier's invoice before posting. ### Does Post Adjustments do anything? No. It appears on the bill but is not implemented — running it returns an error. Apply supplier payments and adjustments from the payment side; the bill reflects them in **Open Amount** and **Adjusted Amount**. ## Related topics - [The purchase order lifecycle](/docs/procurement/purchase-orders/) - [Receive goods against a purchase order](/docs/procurement/goods-receipts/) - [Three-way match implementation reference](/docs/procurement/three-way-match/) ---- # Procurement configuration reference URL: https://xmatix.com/docs/procurement/configuration/ Last reviewed: 2026-10-10 Procurement behavior is shaped less by a settings page and more by data your organization already maintains: a switch in Feature Hub, defaults on branches, flags on items, planning attributes per item and branch, and opt-out flags on document lines. This page lists every knob the module actually reads and where it lives. Anything not listed here — permissions, approval processes, business rules, document layouts, document numbering — is the platform's standard machinery and applies to procurement documents like any others; see the [administration section](/docs/administration/). ## Module switch **Setup → Feature Hub → Modules → Procurement → Settings** carries two settings: - **Enable Procurement**, on by default. It is the master switch: when off, the module is unavailable to all users in the organization, including users who hold licenses and seat assignments. - **Route credit limit breaches to an approval process** (group **Credit Limit**), off by default. Off: a new purchase order is refused when your open payables to the supplier already exceed the credit limit set for your partner account and that supplier. On: the block is skipped, and an approval process you configure is expected to govern the override. Suppliers without a positive limit are never blocked. See [Credit limits](/docs/sales/credit-limits/) and [purchase orders](/docs/procurement/purchase-orders/). ## Branch defaults | Setting | Where | Effect | | --- | --- | --- | | Default supplier account | Branch (`DefaultSupplierAccountId`) | When a requisition, purchase order, goods receipt or bill is created for the branch without a supplier, the branch's default supplier is filled in. The column is not part of the standard branch screens, so it is maintained by import or a customized branch layout. | | Purchase-type price list and discount group | Price Lists / Discount Groups | The default *Purchase* price list (and, on orders and bills, discount group) is assigned to new documents; lines take their unit cost and discounts from them. | | Tax groups | Tax Groups | Purchase-order headers need a *Document Level* tax group (the shipped line-level check on purchase-order lines is inactive); other procurement documents apply header taxes from their tax group. | ## Item flags @[guided-image](_img/procurement-item-inventory-settings.png) Open the item record's **Details** tab and scroll to **Inventory Settings** (the **Behaviour** and **Specification** sections below it hold two more). These are the item settings procurement reads: | Flag | Effect on procurement | | --- | --- | | Inspection On Receipt | Received quantity for the item is held under inspection instead of going straight to available stock; **Inspection** on the goods receipt creates inspection lines only for items with this flag, and **Inspection Complete** releases them. See [goods receipts](/docs/procurement/goods-receipts/). | | Track Inventory | The item's receipt lines post to the inventory ledger and create a cost layer at the receipt line's unit cost. | | Track Lots | Receiving creates or matches an item lot per receipt line. | | Track Asset | Receiving creates a serialized asset per received unit (a lot is required). | | SKU Required | Every requisition, order, receipt and bill line for the item must name a SKU. | | Maximum Lot Quantity (Specification; also per SKU) | When a receipt line is created with a larger quantity it is split into several lines of at most this quantity — the SKU's value wins over the item's, and an asset-tracked item is always split to one unit per line. Zero means no split. | ## Inventory planning attributes @[guided-image](_img/procurement-planning-attributes-list.png) **Item Inventory Attributes** are the per-item planning rows that drive [auto-ordering](/docs/procurement/auto-order/) and the quantity rules on purchase-order lines. Each row belongs to an item and can be narrowed by **SKU**, **Item Lot Type**, **Branch** and **Partner Account**; an empty scope column means "applies to all", so an unscoped row combines with a branch-specific one. When several rows match one item, the Forecasting engine averages the numeric parameters and the purchase-line rules use the first matching row. @[guided-image](_img/procurement-planning-attribute-detail.png) The default detail layout shows the row in four sections: **Information** (partner account, branch, item, SKU, lot type), **Classification** (minimum and maximum stock level, ABC and FSN category, minimum and maximum order quantity), **Order Suggestions** (reorder quantity, reorder level, suggested order quantity, maximum order quantity) and **System Information**. **Lead Time** and **Average Consumption** are stored on the row but not displayed by this layout; add them to the layout or maintain them by import if your planners need them on screen. | Parameter | Read by | | --- | --- | | Minimum Stock Level | Minimum Stock Level engine — an item is suggested when available stock at the branch is below it. Only branch-scoped rows count for this engine. | | Reorder Quantity | Minimum Stock Level engine — the suggested quantity; when zero, the shortfall up to the minimum is suggested instead. | | Minimum Order Quantity | Purchase-order lines — a quantity below it is rejected (*Order Quantity N can't be less than the Minimum Order Quantity M for Item 'X'*). Forecasting — added into the reorder point. | | Maximum Order Quantity | Purchase-order lines — a quantity above it is rejected. Forecasting — the level suggestions top up to. | | Lot Quantity | Purchase-order lines — the quantity must be a multiple of it (*Order Quantity N needs to be in multiple of the Lot Quantity M for Item 'X'*). Zero or empty means no rule. | | Lead Time (In Days), Average Consumption | Forecasting — reorder point = lead time × average consumption + minimum order quantity. | | FSN Category | All engines — the auto order's **Exclude FSN Items** flags skip rows whose category is *Fast-Moving*, *Slow-Moving* or *Non-Moving*. The alternative *F/S/N category* values seeded on the same picklist are never matched by the exclusion — use the hyphenated values. Cycle counts also filter on it. | | ABC Category | All engines — **Exclude ABC Items** skips *A Category*, *B Category* or *C Category* rows. Cycle counts also filter on it. | | Maximum Stock Level, Reorder Level, Suggested Order Quantity | Stored and validated, but read by no engine or rule. The order-up-to level Forecasting uses is **Maximum Order Quantity**, and the trigger Minimum Stock Level uses is the minimum stock level. | Saving a row enforces: at least one of minimum or maximum order quantity; maximum order quantity not below minimum; maximum stock level not below minimum stock level; reorder level greater than reorder quantity; and no negative quantities. Items with no matching row are invisible to the engines — no parameters, no suggestion — have no category for the header exclusions, and are not checked against order-quantity limits. ## Per-line auto-order opt-out Shipment lines, purchase-order lines, requisition lines and sale-order lines each carry an **Exclude In Auto Order** flag. A flagged line is left out of the Forecasting pipeline netting and the matching Sense AI nudge math — use it for lines that would otherwise distort the projection, such as a speculative order that may be cancelled. It has no effect on the manual release actions. ## Goods-receipt checklist (PDI tab) The goods receipt's **PDI** tab hosts a checklist widget bound to a checklist template chosen in the layout designer. It is a manual tick-through separate from the inspection lines; change the template on the layout to change what receivers see. ## Scheduled suggestion runs The job **Generate forecast auto-order lines** fills empty Forecasting auto orders and spawns dated orders from Template auto orders. It has no setting of its own: the job schedule *is* the switch and the cadence — create a schedule with a cron expression to turn it on, delete or disable the schedule to stop it, and use **Run now** for a manual run. Only one run executes at a time per organization, and runs skip anything already generated. Note that the scheduled run does not apply an auto order's **Fit to Budget** cap; only the on-demand **Lines** action does. ## Sense AI nudge threshold The purchase-order quantity nudge ignores divergence smaller than a share of the needed quantity (default 25%). The tolerance is tenant-overridable in AI Studio under Nudges, and the nudge respects the Sense AI module and nudge switches in Feature Hub. See the Sense AI section of the [Knowledge Center](/docs/). ## Related topics - [Auto-order: rules-based purchase suggestions](/docs/procurement/auto-order/) - [The purchase order lifecycle](/docs/procurement/purchase-orders/) - [Receive goods against a purchase order](/docs/procurement/goods-receipts/) - [Administration](/docs/administration/) ---- # Frequently ordered item suggestions URL: https://xmatix.com/docs/procurement/frequently-ordered/ Last reviewed: 2026-09-02 On a saved purchase order, the **Get Frequently Ordered Items** action can return a shortlist of recent items for the same partner account and branch. The standard widget presents each candidate with **Accept** and **Dismiss**. Accept pre-fills the order's Quick Add panel with the item, default SKU and quantity `1`; it does not persist a line until the user completes the add/save flow. No screenshot is used here because demo2 has no verified populated suggestion result inside the default 30-day window. An empty or invented panel would not teach the implemented behavior. ## What is ranked The service looks at purchase orders for the **same partner account and branch** whose `Created Date Time` falls inside the lookback window. It groups their purchase-order lines by item and ranks by line occurrences (`Count()`), not by distinct purchase orders. ## Parameters | Parameter | Meaning | Default | | --- | --- | --- | | Duration | Lookback window, in days, over order creation dates. | 30 days | ## What each suggestion returns The top **five** items, each with: | Field | Meaning | | --- | --- | | Item | The item's name and label. | | Default SKU | The item's default SKU, ready to place on the line. | | Order count | How many matching purchase-order **lines** contain the item — the current field name is historical; this is the ranking key. | | Total quantity | The summed ordered quantity across those lines. | ## Behavior notes - An empty result means no purchase orders exist for this partner and branch inside the window — widen the duration or just build the order manually. - Ranking uses line occurrence, not distinct-document count or quantity. Two lines for the same item on one order count as two occurrences. - **Accept** fills Quick Add with quantity `1`; review and commit that line through the normal order UI. **Dismiss** hides the suggestion locally. ## Common questions ### Why don't I see an item we buy all the time? Either it was bought under a different partner or branch, the order's creation date falls outside the window, or five items have more matching line occurrences. The list is strictly the top five groups returned by the service. ### Can the window be changed? Yes — the duration is a parameter of the suggestion (default 30 days). How it is exposed depends on the screen invoking it; the ranking logic is the same at any window length. ## Related topics - [The purchase order lifecycle](/docs/procurement/purchase-orders/) - [Auto-order: rules-based purchase suggestions](/docs/procurement/auto-order/) - [xMatix Procurement overview](/docs/procurement/) ---- # Receive goods against a purchase order URL: https://xmatix.com/docs/procurement/goods-receipts/ Last reviewed: 2026-09-05 A goods receipt records what actually arrived against a purchase order and posts it into stock. You create it by releasing it from the order (or from an inbound shipment), record the real quantities, and run **Receive** to post the lines to inventory. Items flagged for inspection take a detour: their received quantity is held under inspection until you complete the inspection. From the finished receipt you can release the supplier's bill and post the goods-received accrual. Open the **Procurement** app and choose **Goods Receipts**. The list is titled **All Goods Receipts**; a saved receipt has **Lines**, **Related**, **Details** and **PDI** tabs and a status stepper under the header. Its actions — **Receive**, **Inspection**, **Inspection Complete**, **Release Bill** and **Post General Ledger** — are record actions; whether they show as header buttons or in the header's overflow menu depends on your layout. ## Prerequisites - A purchase order (or shipment) with lines that still have pending quantity. - Permission to run the receipt's actions and, for the last steps, to create bills and post journals. - For items that should be quality-checked on arrival, **Inspection On Receipt** enabled on the item record (**Details → Inventory Settings**) — see the [configuration reference](/docs/procurement/configuration/). Items without the flag go straight to available stock. ## The three quantities on a line Every receipt line carries three quantities that are deliberately different numbers: | Quantity | Meaning | Set by | | --- | --- | --- | | Ordered Quantity | What the purchase-order line released onto this receipt. It rolls back up into the order line's **Receipt Quantity**. | Release from the order (the released or requested quantity). | | Supplier Quantity | What the supplier's papers say was sent. Mandatory before receiving; the over-receipt check compares the cumulative supplier quantity of all receipt lines against the order line's quantity net of cancellation. | Release from a shipment, or you. | | Received Quantity | What was physically counted in. | You, before running **Receive**. | From these the line derives **Shortage Quantity** (supplier minus received, floored at zero), **Excess Quantity** (received minus supplier) and, once inspection starts, **Pending Inspection Quantity**. **Damaged Quantity** is typed separately and posts to its own damaged-stock bucket. **Unit Cost** is copied from the order line and becomes the cost of the stock layer the receipt creates — check it before receiving, because the accrual journal and the inventory valuation both use it. ## Header fields | Field | Where | What it does | | --- | --- | --- | | Document Date | Header | The receiving date; stamped with today and locked after save. | | Purchase Order / Shipment | Header | Filled by the release that created the receipt. Which one is set decides which inventory rule posts the line (below). | | Executive | Header | The person responsible for the receipt. | | Supplier Account | Supplier Details | Required. Defaults to the branch's default supplier; locked after save. | | Supplier Invoice Number, Supplier Invoice Date, Supplier Dispatch Date | Supplier Details | The supplier's paperwork references, kept apart from your own document date. | | Transporter Name, Contact Number, Reference Number | Transportation Details | Carrier details for investigating shortages, delays and damage. | | Partner Account, Branch | System Details | The organization and receiving branch; locked after save. | | Status | Stepper under the header | *Draft*, *Receive*, *Start Inspection*, *Complete Inspection*, *Bill*. Advanced by clicking the next step (one step at a time), not by the actions. | ## Procedure @[guided-image](_img/goods-receipt-list.png) Start from **All Goods Receipts** to find the delivery by supplier, branch and date. Because **Status** is a manual marker, open the receipt and judge progress from its lines: a line with an inventory-ledger reference has been received, one with a pending inspection quantity is still under inspection, one with pending invoice quantity is still unbilled. ### Step 1 — Create the receipt from the order On the purchase order, run **Release Receipt** to create a goods receipt for every line with pending quantity, or **Selective Release Receipt** to tick lines and enter a **Requested Quantity** per line (greater than zero, at most the line's pending quantity). The receipt copies the order's branch, partner account and supplier; each line gets the order line's item, SKU and unit cost and an **Ordered Quantity** equal to the released quantity. When the goods travel as a tracked consignment, release the receipt from the inbound **Shipment** instead (**Release Receipt** / **Selective Release Receipt** there); those lines arrive with **Supplier Quantity** filled from the shipment. @[guided-image](_img/new-goods-receipt.png) When lines are created — by a release or by hand — a line whose quantity exceeds the SKU's or item's **Maximum Lot Quantity** is split into several lines of at most that quantity, and an asset-tracked item is split to one unit per line, so a release of 63 tracked units produces 63 receipt lines. You can also create a receipt directly with **New** — the form asks for the header fields above — but a stand-alone receipt has no order-line links, so nothing rolls back into an order and its bill lines cannot be matched to an order. ### Step 2 — Record what actually arrived @[guided-image](_img/goods-receipt-detail-lines.png) On the **Lines** tab enter each line's **Supplier Quantity**, **Received Quantity** and any **Damaged Quantity**, plus lot, serial, MRP and manufacturing/expiry dates where your items track them. The lines' validations refuse a negative ordered quantity, unit cost or MRP, a manufacturing date in the future, an expiry date that fails the seeded manufacturing/expiry rule (its message reads *Date Of Expiry should be less than Date Of MFG*), and — for lines released from an order — a cumulative supplier quantity above the order line's quantity net of cancellation (*Received quantity (N) cannot exceed the ordered quantity (M) for the purchase order line*). ### Step 3 — Receive into stock Run **Receive**. The receive panel lists the lines; tick the ones that arrived and adjust their quantities in place — the values you enter there are applied to the lines before posting. Lines you leave unticked stay pending, so a delivery can be received in several passes. The action: - refuses when the receipt has no lines, when every selected line already has an inventory-ledger reference (*All Goods Receipt Lines have already been posted to Inventory*), or when a selected line has no supplier quantity (*Supplier Quantity is required for Goods Receipt Lines before receiving*); - creates or matches the item lot for each line and, for items that track assets, creates the asset records; - approves the selected lines for inventory posting, which fires the inventory-ledger rules and stamps each line with its ledger reference. Which quantity posts depends on how the receipt was created: a line released **from a purchase order** posts **Received Quantity**; a line released **from a shipment** or on a **stand-alone** receipt posts **Supplier Quantity**, and when the shipment line was already posted to the in-transit (pipeline) bucket the receipt moves that stock into inward stock rather than adding to it. Shortage, damage and excess post to their own stock buckets. Verify the resulting ledger entry rather than assuming the same field posts on every receipt. ### Step 4 — Start the inspection Run **Inspection**. It creates one inspection line for every receipt line whose item has **Inspection On Receipt** enabled and whose pending inspection quantity is positive, copying the item, lot, SKU, storage location, unit cost and quantities with the damaged quantity already netted out. Saving the inspection lines moves the quantity into the inspection stock bucket and writes the started-inspection and damaged quantities back onto the receipt line. Record your findings on the inspection lines; an inspection line can raise a service order for rework with **Create Service Order**. ### Step 5 — Complete the inspection Run **Inspection Complete**. It closes every open inspection line — inspection and adjustment quantities to zero, **Inspection Done** and **Approved** set — and approves them for posting, releasing the inspected quantity from the inspection bucket. Until this step the flagged quantities are not available stock. ### Step 6 — Release the bill **Release Bill** creates a supplier bill for the receipt's lines with pending invoice quantity. The bill copies the receipt's branch, partner account, supplier and document date and links back to the receipt; each bill line links to its receipt line (`Goods Receipt Line`), with that line's pending invoice quantity, tax group and lot. It does **not** carry the purchase-order-line link, so a bill released here clears the receipt but is invisible to the [three-way match service](/docs/procurement/three-way-match/); when you need both links, release the invoice from the purchase order after the receipt exists instead. The bill's item lines are priced from the bill's price list when they are created — see [supplier bills](/docs/procurement/bills/). ### Step 7 — Post the accrual **Post General Ledger** posts the receipt's journal — inventory debited, the goods-received-not-invoiced account credited — for the header **Total Amount** (received quantity × unit cost over the lines) and marks the receipt GL-posted. The bill's own posting later clears that accrual for lines linked to a receipt line. Posting is independent of receiving: run it once the received quantities and unit costs are final. The **PDI** tab hosts a checklist bound to a configured checklist template. It is delivery evidence you tick through by hand and is separate from the inspection lines created by **Inspection**; quality-inspection quantities and completion live on the receipt lines and the inspection records. ## Expected result Supplier, received, damaged, shortage and excess quantities stay separately visible; every posted line has an inventory-ledger reference and a cost layer at the line's unit cost; inspection-required items have inspection lines that were closed by **Inspection Complete**; the receipt has a GL-posted accrual and, if you released one, a bill linked to its lines. The purchase order's receipt counter reflects the ordered quantities you released, not the counted quantities. ## Common problems - **"Supplier Quantity is required for Goods Receipt Lines before receiving."** Fill in the supplier quantity on every ticked line (or in the receive panel), then run **Receive** again. - **"All Goods Receipt Lines have already been posted to Inventory."** Nothing selected is left to receive — check the order for remaining pending quantity and release a new receipt if more is coming. - **"Received quantity (N) cannot exceed the ordered quantity (M) for the purchase order line."** The supplier quantities across this order line's receipts add up to more than was ordered net of cancellation. Correct the supplier quantity, or increase the order quantity first. - **"No Goods Receipt Line requires inspection."** None of the receipt's items has **Inspection On Receipt** enabled, or nothing is pending inspection because it has not been received yet or was already inspected. - **"No Inspection Line found with pending completion."** Every inspection line is already done. - **"No Goods Receipt Lines found to Release Bill."** Every item line has been fully billed already. - **The line posted a different quantity than I counted.** The receipt came from a shipment or was created stand-alone, so **Supplier Quantity** posted instead of **Received Quantity**. Correct the supplier quantity on such receipts before receiving. ## Common questions ### Are all items inspected? No — only items with **Inspection On Receipt** enabled. Everything else goes straight to available stock when received. The flag lives on the item record, so mixing flagged and unflagged items on one receipt is fine: only the flagged lines get inspection lines, and **Inspection** refuses to run on a receipt that has none. ### Can I receive a delivery in several passes? Yes. Tick only the lines that arrived in the receive panel; the rest stay pending on the receipt. At the order level, selective releases let you create separate receipts per delivery as well. ### What if the delivered quantity differs from what was ordered? Record the supplier's papers in **Supplier Quantity** and the physical count in **Received Quantity**; the shortage or excess is derived and posted to its own bucket. The over-receipt check compares cumulative **Supplier Quantity** with the order quantity, while the backend match compares cumulative **Received Quantity** with the ordered quantity — review both when a delivery differs from the order. ### Does the status stepper change when I run Receive or Inspection? No. The stepper only records the value you click; the actions never write it. Use the line-level ledger reference, pending inspection quantity and pending invoice quantity to see where a receipt stands. ## Related topics - [The purchase order lifecycle](/docs/procurement/purchase-orders/) - [Supplier bills](/docs/procurement/bills/) - [Three-way match implementation reference](/docs/procurement/three-way-match/) - [Troubleshooting procurement](/docs/procurement/troubleshooting/) ---- # xMatix Procurement URL: https://xmatix.com/docs/procurement/ Last reviewed: 2026-09-05 The xMatix Procurement module runs the buying cycle end to end: someone asks for items, the request becomes a purchase order, goods arrive and are received into stock — with an inspection step for items that require it — and the supplier's bill is recorded and linked back to what was ordered and received. Alongside that document chain, rules-based auto-ordering suggests what to buy from your own stock and consumption numbers, with the arithmetic behind every suggestion stored on the suggestion itself. Everything lives in the **Procurement** app: **Requisitions**, **Auto Orders**, **Purchase Orders**, **Shipments**, **Goods Receipts** and **Bills** in the app menu, plus reports. Each list opens the saved document, whose tabs (**Lines**, **Details** and document-specific tabs) are where the procedures in this section are carried out. A purchase order proves commercial intent; a goods receipt supplies quantity and condition evidence; a bill supplies payable and tax evidence. The three-way comparison between them exists as a backend service without a standard product screen, so its page documents the contract and limitations rather than a UI. ## The document chain | Document | What it is | | --- | --- | | Requisition | An internal request for items, released into a purchase order — or into a stock transfer when you fulfill it from your own warehouses. | | Purchase order | The commitment to a supplier, and the hub every later document links back to. | | Shipment | An inbound consignment on its way from the supplier; released into a goods receipt on arrival. | | Goods receipt | What actually arrived, posted into stock — with a goods-inspection step for flagged items. | | Bill | The supplier's invoice. Order-side invoice release can preserve both order-line and receipt-line links when receipts exist; receipt-side Release Bill currently preserves only the receipt-line link. | | Auto order | A worksheet of rules-based purchase suggestions that you review and turn into purchase orders. | Documents connect through **release** actions: a requisition releases into a purchase order, and a purchase order releases into a goods receipt or a bill. Goods receipts can also release a bill. Selective variants exist for the requisition and purchase-order paths. Pending counters are derived from downstream line quantities; on purchase-order receipt progress, the current aggregate uses the goods-receipt line's `Ordered Quantity`, so it represents quantity staged onto receipt lines rather than proof that **Perform Receive** posted that quantity. ## In this section 1. [Requisitions: from request to purchase order](/docs/procurement/requisitions/) — raise a requisition and release its lines into an order. 2. [The purchase order lifecycle](/docs/procurement/purchase-orders/) — full and selective releases, pending quantities, supplier schemes. 3. [Receive goods against a purchase order](/docs/procurement/goods-receipts/) — receiving, goods inspection, and releasing the bill. 4. [Supplier bills](/docs/procurement/bills/) — where bills come from and how they stay matched to orders and receipts. 5. [Auto-order: rules-based purchase suggestions](/docs/procurement/auto-order/) — the three replenishment engines and the arithmetic snapshot on every line. 6. [Three-way match implementation reference](/docs/procurement/three-way-match/) — the backend comparison contract, its link requirements and the current absence of a standard screen. 7. [Frequently ordered item suggestions](/docs/procurement/frequently-ordered/) — the ranked shortlist offered while building orders. 8. [Procurement configuration reference](/docs/procurement/configuration/) — the admin settings that shape all of the above. 9. [Troubleshooting procurement](/docs/procurement/troubleshooting/) — stuck receipts, flagged bills, surprising suggestions. ## Related topics - [Procurement product overview](/products/procurement/) - [Inventory product overview](/products/inventory/) — stock levels, warehouses and transfers that procurement replenishes - [Getting started with xMatix](/docs/getting-started/) ---- # Creating, releasing and tracking purchase orders URL: https://xmatix.com/docs/procurement/purchase-orders/ Last reviewed: 2026-10-10 A purchase order is your commitment to a supplier: the items, quantities and prices you are buying, from which branch, and the document every later shipment, goods receipt and bill links back to, line by line. It sits between the [requisition](/docs/procurement/requisitions/) or [auto order](/docs/procurement/auto-order/) that asked for the goods and the [goods receipt](/docs/procurement/goods-receipts/) and [supplier bill](/docs/procurement/bills/) that record what arrived and what you owe. ## Overview Purchase orders live in the **Procurement** app, under **Purchase Orders**, on the web and in the mobile app. The list is titled **All Purchase Orders**. A saved order has a record header with its key figures and buttons, a **Status** stepper, and three tabs — **Lines**, **Related** (the order's shipments, goods receipts and bills) and **Details** — with an **Amount Summary** beside them. @[guided-image](_img/purchase-order-list.png) ## When to use it Raise a purchase order whenever you buy stock or services from a supplier and want the purchase to be received into stock, billed and reconciled against what you ordered. Use it when: - a requisition has been approved internally and needs to go to a supplier; - an auto-order worksheet suggests what to buy; - you are buying directly, without a prior request; - the supplier is another organization on the platform and should receive your order as a sale order (a *dealer order*). ## How xMatix handles it ### Where purchase orders come from | Source | How | | --- | --- | | Created directly | **New** on the list — a header with a supplier, partner account and branch, then lines. | | Released from a requisition | **Release Order** or **Selective Release Order** on the [requisition](/docs/procurement/requisitions/). The order links to the requisition and each line to its requisition line. | | Pulled in while building an order | **Add Requisition** takes every open line of the requisitions you pick; **Selective Requisition Lines** takes chosen lines at a requested quantity. | | Generated from an auto order | **Purchase Order** or **Selective Order** on a reviewed suggestion worksheet — see [auto-order](/docs/procurement/auto-order/). The order shows the worksheet in **Auto Purchase Order**. | ### Line quantities drive the lifecycle Receiving, billing and dealer-order release are tracked independently on every line, and all three draw on the same ordered quantity: | Counter | Meaning | | --- | --- | | Quantity | What was ordered. | | Receipt Quantity | The quantity placed on goods-receipt lines released from this line — staged for receipt, not proof that it was counted in. | | Pending Quantity | Quantity − Receipt Quantity − Cancelled Quantity. Shipment and receipt releases draw on it. | | Invoice Quantity / Pending Invoice Quantity | Quantity billed so far, and what is left to bill (Quantity − Invoice Quantity − Cancelled Quantity). | | Order Quantity / Pending Order Quantity | Quantity sent to the supplier as dealer orders, and what is left. | | Returned Quantity | Quantity returned on credit notes against this line's bills. | | Cancelled Quantity | Quantity struck off the line without receiving or billing it. | The header adds these up as **Total Pending Quantity** and **Total Pending Invoice Quantity** (on **Details → Quantity Details**). Because the counters are independent, an order can be fully staged for receipt but only partly billed, or billed before anything arrives. To check physical arrival and stock, read the goods receipt, not the order. ### Status and document state **Status** is the stage the list cards and the stepper show: *Draft* (the default), *Shipment*, *Goods Receipt* and *Bill* (a *New* value also exists, but nothing sets it). It changes in three ways: - **Release Shipment** sets it to *Shipment*. - Two shipped business rules run whenever the order is saved: when the order has lines and no pending quantity is left, Status becomes *Goods Receipt*; when some quantity has been billed and nothing is left to bill, Status becomes *Bill*. - You can move it yourself with the stepper under the header: forward one step at a time, or back. Releasing a goods receipt or a bill does not change Status by itself. Separately, a read-only **Document State** field records the last release that succeeded: *Draft*, *Dealer Order Created*, *Shipment Released*, *Receipt Released*, *Received* or *Billed*. It is not on the shipped screens; add it to a list view if you want to see it. On the shipped record page, the release, **Dealer Order**, **Product Catalogue**, **Apply Scheme**, **Add Requisition** and **Selective Requisition Lines** buttons show only while Status is *Draft*. Most of them also need some quantity still to bill. Once an order moves past Draft — for example after **Release Shipment** — release the goods receipt from the shipment instead. ### Pricing and taxes New orders get a purchase price list and discount group by default, and each line is priced and discounted from them when it is added. **Unit Cost 2**, when greater than zero, replaces **Unit Cost** in the line amount. Line taxes come from the line's tax group and are copied onto the line when it is saved, so later changes to tax rates do not alter saved lines. Changing **Price As On Date** on the header reprices every line from the price list in force on that date. ## Prerequisites - The supplier is an active account marked as a supplier — only those can be picked in **Supplier Account**. - Your organization (the **Partner Account**) and receiving **Branch** are active and belong together. - A purchase-type price list exists if you want lines priced automatically; otherwise you type each **Unit Cost**. - Items are active and not discontinued. An item that requires a SKU needs one on every line. - Your security profile grants access to Purchase Order and Purchase Order Line, and to the actions you will run (see [Permissions](#permissions)). ## Procedure ### Step 1 — Find a purchase order Open **Procurement → Purchase Orders**. The cards across the top count **All Purchase Orders**, **Draft Purchase Orders**, **Shipment**, **Goods Receipt** and **Billed** orders, and total their **Total Amount**. Switch the view to **Part**, **Product**, **Local** or **VOR** to see one purchase order type, and use search, filters and column sorting to narrow the list. Open an order by its **Document Number**. ### Step 2 — Create the order @[guided-image](_img/new-purchase-order-concept.png) Choose **New**. Fill the top row — **Document Date** (today if you leave it empty), **Purchase Order Type** and **Supplier Account** — then the tabs: 1. **Order Configuration**: check the defaulted **Price List** and **Discount Group**, and pick a **Tax Group** if the order carries header taxes. 2. **Billing Address** and **Shipping Address**: filled from your partner account's addresses when you leave them empty; pick another address or type one. 3. **System Details**: **Partner Account**, **Branch** and **Executive**. Save. The order gets a number such as `PO-10102026-000001` and opens at Status *Draft*. If the branch has a default supplier and you left **Supplier Account** empty, it is filled in. ### Step 3 — Add lines On the **Lines** tab use **New** (the quick-add form), **Product Catalogue** or **Import**. The quick-add form asks for **Item**, **SKU**, **Quantity**, **Unit Cost**, **Tax Group** and **Description**, and shows an **Item 360** panel for the chosen item. A line needs an item, or a description for a non-stock charge such as freight, and a quantity greater than zero. On save the line is priced, discounted and taxed. A package item adds its component lines. The **Amount Summary** updates: line base amount, less scheme and other discounts, plus tax, gives **Total Amount**. To pull in requisitions instead, choose **Add Requisition** (every open line of the requisitions you pick) or **Selective Requisition Lines** (chosen lines at a quantity you enter). The order must already have a supplier and branch, and only requisitions for the same supplier and branch are accepted. @[guided-image](_img/purchase-order-detail-lines.png) ### Step 4 — Apply supplier schemes If your supplier runs promotions, choose **Apply Scheme** to apply a qualifying scheme's benefits — benefit lines and scheme discount — to the order. Scheme discounts appear in **Total Scheme Discount Amount**. Schemes are evaluated again whenever a line's item, SKU, amount or tax group changes. ### Step 5 — Release a shipment or goods receipt - **Release Receipt** asks *"This action will create good receipt record for the current purchase order."* and, on **Yes**, creates one goods receipt for every line with pending quantity. - **Selective Release Receipt** takes only the lines you choose, each with a **Requested Quantity** greater than zero and no more than its pending quantity. - **Release Shipment** creates an inbound shipment for the pending quantities when the supplier ships in consignments. The order's Status becomes *Shipment*; the goods receipt is later released from the shipment on arrival. The new document appears on the **Related** tab. It copies the order's branch, partner account and supplier, and each line links back to its order line at the order's unit cost. Receive the goods on the receipt — see [receive goods against a purchase order](/docs/procurement/goods-receipts/). ### Step 6 — Release the bill - **Release Invoice** asks *"This action will create purchase invoice record for the current purchase order."* and creates a supplier bill for every line with pending invoice quantity. - **Selective Release Invoice** takes chosen lines and requested quantities, checked against **Pending Invoice Quantity**. If goods-receipt lines exist for an order line, the bill gets one line per receipt line, linked to both the order line and the receipt line. If nothing has been received yet, it gets one line linked to the order line. Description-only lines bill at the cost typed on the order; item lines are priced from the bill's price list, so compare the bill with the supplier's invoice before posting. See [supplier bills](/docs/procurement/bills/). ### Step 7 — Send a dealer order to an on-platform supplier When the supplier is another organization on the platform, set **Supplier Branch** on the order, then choose **Dealer Order**. A sale order is created at the supplier's branch for every line's pending order quantity, so the supplier fulfils it from their side. ### Step 8 — Change, clone or delete an order Choose **Edit** to change the header; **Partner Account**, **Branch** and **Document Date** cannot change once saved. To reduce a line, lower its **Quantity** — not below what has already been received — or enter a **Cancelled Quantity** to stop expecting the rest. **Clone** (*"This will create a copy of the current record (including its line items)."*) starts a new order from this one. **Delete** removes the order after a confirmation; a line that already has receipt quantity cannot be deleted. ### Step 9 — Work on mobile The Procurement app is available in the mobile app. You can create purchase orders, add lines with quick add and the product catalogue, and pick from the items your branch orders most often — see [frequently ordered item suggestions](/docs/procurement/frequently-ordered/). ## Fields ### Header | Field | What it means | Notes | | --- | --- | --- | | Document Number | The order number. | Generated on save, for example `PO-10102026-000001`. | | Document Date | The order's business date. | Today if left empty. Also decides the fiscal day the order belongs to. Locked once saved. | | Purchase Order Type | A classification. | *Part*, *Product*, *Local PO*, *VOR PO*, *Subcontracted PO*, *Blanket PO*. Drives the list views; otherwise used for reporting. | | Supplier Account | The vendor. | Only active supplier accounts. Defaulted from the branch's default supplier when empty. | | Supplier Branch | The supplier's branch. | Needed only for **Dealer Order**. Not on the shipped create form. | | Auto Purchase Order | The auto-order worksheet the order came from. | Filled automatically. | | Price List | The purchase price list lines are priced from. | Defaulted on create. | | Discount Group | The discount group line discounts come from. | Defaulted on create. | | Tax Group | Header-level taxes. | Must be a *Document Level* tax group. | | Is Template | Marks the order as a template for auto orders. | Set by **Select as Auto Order Template**; only marked orders can be picked on a new auto order. | | Billing Address, Shipping Address | Where the supplier bills and ships to. | Defaulted from the partner account's addresses. Street, city, state, postal code and country can be typed. | | Partner Account | Your organization placing the order. | Only active partner accounts. Locked once saved. | | Branch | The receiving branch. | Must belong to the partner account and be active. Locked once saved. | | Executive | The person accountable for the order. | A resource. | | Status | The order's stage. | *Draft*, *New*, *Shipment*, *Goods Receipt*, *Bill*. See [Status and document state](#status-and-document-state). | | Requisition, Service Order | The source documents. | On **Details → Key Information**. Filled automatically. | | Tax Supply Type | The tax lane. | *Within State*, *Outside State*, *Exempt*, *Exports*, *SEZ*. For businesses in India it is recalculated on every save. | | Place of Supply, Source of Supply | The states that decide the tax lane. | For businesses in India, Place of Supply is defaulted from the supplier and Source of Supply from the branch; when they differ the order is *Outside State*. | | Price As On Date | The date prices are taken from. | Changing it reprices every line. | | Total Pending Quantity, Total Pending Invoice Quantity | What is left to receive and to bill. | Calculated from the lines. | | Total Line Base Amount, Total Discount Amount, Total Scheme Discount Amount, Total Tax Amount, Total Amount | The money totals. | Calculated. | | Skip Scheme | Turns off scheme evaluation for the order. | Not on the shipped layouts. | | Remarks | Free text. | On **Details → System Details**. | ### Lines | Field | What it means | Notes | | --- | --- | --- | | Item | What you are buying. | Active items only; discontinued items and discounted items are refused. Locked on a line released from a requisition. | | SKU | The item variant. | Required when the item requires a SKU; limited to the item's SKUs. | | Description | Text for the line. | Copied from the item name; enough on its own for a non-stock charge. | | Quantity | The quantity ordered. | Required, greater than zero, and within the item's planning limits. | | Unit Cost | The price per unit. | From the price list, or typed. | | Unit Cost 2 | An override price. | When greater than zero, used instead of Unit Cost. | | Discount, Cash Discount | Percent discounts. | 0 to 100. | | Tax Group | The line's taxes. | Taxes are copied onto the line on save. | | Cancelled Quantity | Quantity you no longer expect. | Reduces pending and pending invoice quantity. | | Exclude In Auto Order | Keeps the line out of the auto-order supply calculation. | See [Purchase orders in the stock pipeline](#purchase-orders-in-the-stock-pipeline). | | Receipt, Invoice, Order and Returned Quantity; the pending quantities | The lifecycle counters. | Maintained by the system. | The full list of stored fields is in the [Purchase Order entity reference](/docs/reference/entities/purchase-order/). ## Business rules - **Numbering.** Orders are numbered `PO-` + the document date as DDMMYYYY + a six-digit counter; lines use `PL-`. - **Locked fields.** Partner Account, Branch and Document Date cannot change once saved with a value. - **Partner and branch.** The branch must belong to the partner account and both must be active; when the partner account has branches, a branch is required. - **Header tax group** must be a *Document Level* group. - **Credit limit.** When a credit limit is set for your partner account and the supplier, a new order is refused while your open payables to that supplier already exceed it — unless the Procurement setting routes breaches to an approval process. - **Line quantity.** Greater than zero. When the item has planning attributes for the order's partner account and branch, the quantity must be at least the **Minimum Order Quantity**, at most the **Maximum Order Quantity**, and a multiple of the **Lot Quantity** — see the [configuration reference](/docs/procurement/configuration/). - **Downstream integrity.** A line's quantity cannot drop below its received plus returned quantity. A line with receipt quantity cannot be deleted. Once a line has returns, its item and SKU are locked. - **Releases.** Every release draws only on pending quantity, and a selective release refuses a requested quantity above it. Partial releases are normal; the rest stays available for another release. - **Status.** Set to *Shipment* by Release Shipment, to *Goods Receipt* and *Bill* by the shipped business rules on save, and otherwise by hand. - **Upstream roll-up.** Quantity on a line released from a requisition or an auto order counts against that source line, so it is not ordered twice. ## Purchase orders in the stock pipeline Pending purchase-order quantities count as inbound supply. The [auto-order](/docs/procurement/auto-order/) engine includes them in its projection so stock already on order is not suggested again, and a Sense AI nudge uses the same numbers to warn when a manually entered quantity diverges from what the pipeline needs. Tick **Exclude In Auto Order** on a line to leave it out. ## Example A tractor dealer's parts branch needs 40 oil filters and 12 hydraulic hoses. The parts executive opens **Procurement → Purchase Orders**, chooses **New**, picks the supplier and type *Part*, and saves. The order is numbered `PO-10102026-000014` at Status *Draft*, with the dealer's purchase price list. They add two lines; the filter's planning attributes set a lot quantity of 10, so 40 is accepted. The Amount Summary shows the total with tax. The supplier delivers 30 filters and all the hoses first. The executive runs **Selective Release Receipt** with 30 filters and 12 hoses, and the stores team receives the goods on the new goods receipt. The filter line now shows 10 pending. When the supplier's invoice arrives, they run **Release Invoice**; the bill takes one line per receipt line. A week later the last 10 filters arrive, and **Release Receipt** creates a second receipt for exactly those. On the next save no quantity is pending, and Status moves to *Goods Receipt*. ## Training ### Practice exercise In a sandbox, as a user with the System Admin or Standard User profile: 1. Create a purchase order for any test supplier, partner account and branch. Expected: a `PO-` number and Status *Draft*. 2. Add a line for a stock item, quantity 10. Expected: the line is priced from the purchase price list and the Amount Summary updates. 3. Run **Selective Release Receipt** for 4 of the 10. Expected: a goods receipt on the **Related** tab, and 6 pending on the line. 4. Try to change the line's quantity to 3. Expected: the save is refused, naming 4 as the minimum. 5. Run **Release Receipt**. Expected: a second goods receipt for 6. 6. Run **Release Receipt** again. Expected: *"No pending quantities found in order lines to create goods receipt."* 7. Try to change the order's Branch. Expected: the save is refused because the field is locked. ### Quick reference - Partner Account, Branch and Document Date lock on save — check them first. - Supplier first, then lines; Add Requisition needs supplier and branch. - Receipt, bill and dealer-order counters are independent. - Selective releases take only the quantities you enter, never more than pending. - Release Shipment moves Status to Shipment; the receipt then comes from the shipment. - Release buttons show only while Status is Draft. - Cancelled Quantity closes what you no longer expect; Exclude In Auto Order hides a line from forecasting. - Check bill prices against the supplier's invoice before posting. ## Permissions Access is set on [security profiles](/docs/administration/security-profiles/): - **Entity access.** The shipped *System Admin*, *Standard User*, *Sales Manager* and *Sales Executive* profiles have full access to Purchase Order and Purchase Order Line, including View All and Modify All. The shipped *Procurement* profile has no purchase-order access: give it entity access before assigning it to buyers. - **Record sharing.** Purchase orders are owned by a user. The organization-wide default is Read Only; see [record security](/docs/administration/record-security/). - **Actions.** Each button is a separately granted action: - *System Admin* has every action except **Selective Release Shipment**, which no shipped profile has. - *Standard User* has the release, dealer-order, requisition, scheme and edit actions, but not **Release Shipment**, **Payment**, **Select as Auto Order Template**, **Product Configurator** or line **Import**. - *Sales Manager* has **New**, the receipt and invoice releases (full and selective) and **Add Requisition**, but not **Clone**, the scheme actions or **Dealer Order**. - *Sales Executive* can edit, clone, delete, apply schemes, add requisitions and run **Dealer Order**, but has no **New** and no receipt or invoice releases. A user without an action does not see its button. Grant missing ones on the profile's **Actions** tab. ## Configuration - **Document numbering.** **Setup → Feature Hub → Platform → Document Settings**: *Purchase Order Name Setting* (series `PO`, separator `-`, date DDMMYYYY, six digits) and the line setting (series `PL`). See [Email templates and document numbering](/docs/administration/templates/). - **Module settings.** **Setup → Feature Hub → Modules → Procurement → Settings**: **Enable Procurement** (the module's master switch) and, in the **Credit Limit** group, **Route credit limit breaches to an approval process** (off by default). Off blocks an order that breaches the supplier credit limit; on skips the block so that an approval process you configure can govern it. Limits are kept per partner account and account — see [Credit limits](/docs/sales/credit-limits/). - **Approval.** No approval process is shipped for purchase orders. To require sign-off, create one in **Setup → Process Studio → Approvals**, and add the approval panel to the record page if users should act on it there. See [Approval processes](/docs/customization/approvals/). - **Status automation.** The two shipped business rules *Set Purchase Order Status To Goods Receipt* and *Set Purchase Order Status To Bill* live in **Setup → Process Studio → Business Rules**; change or deactivate them there. See [Business rules](/docs/customization/business-rules/). - **Picklists.** Status and Purchase Order Type are picklists you can extend in the entity's field settings. The list views filter on Purchase Order Type values, so keep views and values in step. - **Layouts and views.** The create form, record page, header buttons, their visibility conditions and list views are metadata you change in Design Studio. Add **Selective Release Shipment**, **Selective Create Dealer Order**, **Reset Scheme**, **Select as Auto Order Template**, **Supplier Branch** or **Skip Scheme** there if users need them. - **Print formats.** A *Purchase Order Document Report* is shipped, but the shipped record page has no print button. Add a **Print** or **Preview** action that uses it — see [Document reports](/docs/analytics/document-reports/). - **Lookup filters.** The shipped filters limit Supplier Account to active suppliers, Partner Account to active partner accounts, Branch and Billing Address to the partner account's, Item to active items and SKU to the item's SKUs. - **Validations.** *Tax Group Validation* (header must be Document Level) and *Discontinued Item Validation* (lines) are shipped and active. - **Branch defaults, item planning attributes and auto-order opt-outs** — see the [procurement configuration reference](/docs/procurement/configuration/). - **Pricing, discounts and taxes** come from purchase price lists, discount groups and tax groups. ## Common problems ### "No pending quantities found in order lines to create goods receipt." Every line's quantity is already on receipts or cancelled. Open the receipts on the **Related** tab. The same message for a *shipment*, *purchase invoice* or *dealer order* means nothing is left for that release. ### "Requested quantity (…) cannot exceed the pending quantity (…)." A selective release asked for more than is left on a line. Enter at most the pending quantity. *"Requested quantity must be greater than zero."* means a chosen line has no quantity entered. ### The release buttons disappeared On the shipped record page they show only while Status is *Draft* and something is still to bill. If Status moved to *Shipment*, release the receipt from the shipment. If you moved the stepper by mistake, move it back to Draft. ### "Supplier Branch is required to create a dealer order." Edit the order and set **Supplier Branch** to the supplier's branch that should receive the order, then choose **Dealer Order** again. ### "Key fields are not editable once the related objects are added. Field Name : …" You tried to change Partner Account, Branch or Document Date on a saved order. They cannot change; create a new order or clone this one and correct it before saving. ### "Order Quantity … needs to be in multiple of the Lot Quantity … for Item '…'." The item's planning attributes set a lot size; the same applies to the minimum and maximum order quantity messages. Order in the allowed steps, or ask an administrator to adjust the planning attributes. ### "There are downstream transaction. The minimum Quantity required is : …" Receipts or returns already use that much of the line. Use **Cancelled Quantity** to stop expecting the rest, or reverse the downstream document first. *"There are downstream transactions. The record cannot be deleted."* is the same protection when deleting a line. ### "Select an Item or enter a Description." A line needs one of them. Pick an item, or type a description for a charge such as freight. ### "'…' is a Discounted Item, which can't be used on a purchase order." Discount items are for sales documents. Record a supplier discount in the line's own discount, or raise a debit note. ### "Discontinued Item Cannot be added" The item is marked discontinued. Choose its replacement, or ask an administrator to reactivate it. ### "Supplier is required before adding requisitions to this purchase order." Set **Supplier Account** (and **Branch** — the matching message names it) and save before using **Add Requisition**. *"The selected requisition belongs to a different supplier account than this purchase order."* or *"…a different branch…"* means the requisition is for another supplier or branch. ### "Credit limit exceeded for …" Your open payables to this supplier already exceed the credit limit set for them. Settle open bills, raise the limit, or ask an administrator about routing breaches to an approval process. ### "Tax Group Type must be "Document Level"." The header tax group is a line-level group. Pick a document-level group, or clear the header tax group and set taxes on the lines. ### The Blanket view shows every order The shipped **Blanket** view has no filter. An administrator can add a Purchase Order Type filter for *Blanket PO* to the view. ### Check In and Check Out never appear on a subcontracted order Their shipped visibility condition looks for a type value that does not match the *Subcontracted PO* picklist value. An administrator can correct the condition in Design Studio. ## Common questions ### Does releasing a goods receipt change the order's status? Not directly. Release Shipment sets Status to *Shipment*, but releasing a receipt or bill does not. The two shipped business rules move Status to *Goods Receipt* when no quantity is pending and to *Bill* when nothing is left to bill, and they run when the order itself is saved. The read-only **Document State** field records the last release that succeeded. For the true position of each line, read its counters: receipt, invoice and pending quantities are always up to date, whatever the stepper shows. ### Which release path keeps the links the three-way match needs? Use **Release Invoice** or **Selective Release Invoice** on the order after receipt lines exist. That path writes both the order-line and goods-receipt-line links on every bill line it builds from a receipt. **Release Bill** on the goods receipt writes only the receipt-line link, so its lines are not counted by the [three-way match service](/docs/procurement/three-way-match/). ### Why does a line still show pending quantity after the goods arrived? The order's **Receipt Quantity** counts the quantity placed on linked goods-receipt lines, not the counted quantity received. If the goods arrived but the line still shows pending, check that the receipt was released from this order rather than created stand-alone, and compare ordered, receipt and cancelled quantity on the line. If the supplier will not send the rest, enter it as **Cancelled Quantity**. ### Can one order produce several receipts and bills? Yes. Each release adds to the line's receipt or invoice counter, and the remainder stays available for the next release. You can receive in several deliveries and bill in several invoices, in any order. ### How do I cancel a purchase order? There is no cancel action. Enter the undelivered quantity in each line's **Cancelled Quantity**, which removes it from pending receipt, billing and the auto-order pipeline while keeping the history and the links to any receipts and bills already made. When the supplier will send part of it later, cancel only the part you no longer expect. ## Related topics - [Requisitions: from request to purchase order](/docs/procurement/requisitions/) - [Receive goods against a purchase order](/docs/procurement/goods-receipts/) - [Supplier bills](/docs/procurement/bills/) - [Three-way match implementation reference](/docs/procurement/three-way-match/) - [Auto-order: rules-based purchase suggestions](/docs/procurement/auto-order/) - [Frequently ordered item suggestions](/docs/procurement/frequently-ordered/) - [Procurement configuration reference](/docs/procurement/configuration/) - [Troubleshooting procurement](/docs/procurement/troubleshooting/) - [Purchase Order entity reference](/docs/reference/entities/purchase-order/) ---- # Requisitions: from request to purchase order URL: https://xmatix.com/docs/procurement/requisitions/ Last reviewed: 2026-10-10 A requisition is an internal request for items — what your branch needs, how much and by when — raised before anyone commits to a supplier. It is the first document in the procurement chain: you release it into a [purchase order](/docs/procurement/purchase-orders/) to buy the items, or into a stock transfer when another of your branches can supply them. Each line tracks how much of it is still pending, so one requisition can be released several times, in parts, until nothing is left. ## Overview Requisitions live in the **Procurement** app, under **Requisitions**, on the web and in the mobile app. The list is titled **All Requisitions**. A saved requisition has a record header with its key figures and release buttons, three tabs — **Lines**, **Related** and **Details** — and an **Amounts** panel beside them. @[guided-image](_img/requisition-list.png) ## When to use it Raise a requisition when someone needs stock and the decision about where it comes from is made later, or by someone else. Use it when: - a branch, workshop or store wants items and a buyer will place the order; - you want to collect demand from several lines or people and release it to suppliers in batches; - the items might come from your own stock at another branch rather than from a supplier; - you want open requests to count as demand in [auto-order](/docs/procurement/auto-order/) suggestions so the same need is not ordered twice. If you already know the supplier and are ready to commit, you can create the [purchase order](/docs/procurement/purchase-orders/) directly instead. ## How xMatix handles it ### Two ways to fulfil a request | Route | Actions | What is created | | --- | --- | --- | | Buy it | **Release Order**, **Selective Release Order** | A purchase order for the requisition's supplier, partner account and branch, linked back to the requisition. | | Move it from your own stock | **Release Transfer**, **Selective Release Transfer** | An outward stock transfer from the requisition's **From Branch** to its **Branch**, linked back to the requisition. | A buyer working on a purchase order can also pull requisition lines in from the other side, with **Add Requisition** or **Selective Requisition Lines** on the order. ### Line quantities drive the lifecycle Every line carries three counters: | Counter | Meaning | | --- | --- | | Purchase Order Quantity | The quantity on purchase-order lines that were released from this line. | | Stock Transfer Quantity | The quantity on transfer lines that were released from this line. | | Pending Quantity | Quantity − Purchase Order Quantity − Stock Transfer Quantity. Every release draws on it. | The counters are recalculated from the downstream documents, so changing or deleting a purchase-order line or transfer line updates the requisition line too. The header adds the lines up as **Total Pending Quantity** (on **Details → Tax & Price Details**). ### Status **Status** starts at *Draft*. A shipped business rule runs whenever the requisition is saved: when it has lines and no pending quantity is left on any of them, Status becomes *Confirmed*. On the shipped record page Status is read-only, and the list's summary cards count **Draft Requisitions** and **Confirmed Requisitions**. The picklist also holds an *Approved* value that nothing in the shipped product sets. The four release buttons show only while Status is *Draft* **and** **Total Pending Quantity** is greater than zero. **Product Configurator** shows only while Status is *Draft*. ### Pricing and taxes New requisitions get a purchase price list automatically, chosen from the active *Purchase Price* lists that apply to your partner account and branch. When you add a line, **Unit Cost** is taken from that price list unless you type one, and the line's tax group comes from your tax group rules. Line taxes are recalculated whenever the item, SKU, quantity, amount or tax group changes. A line's **Amount** is quantity × unit cost plus the line's tax, and the requisition's **Total Amount** is the sum of the line amounts. The **Amounts** panel shows the base amount, the tax and the total, with the tax split by component. Changing the header **Price List** later does not reprice lines that already exist; it applies to lines you add afterwards. ## Prerequisites - Your organization (the **Partner Account**) and the requesting **Branch** are active and belong together. - For a purchase: the supplier is an active account marked as a supplier. For a transfer: the supplying branch belongs to the same partner account. - Items are active and not discontinued. An item that requires a SKU needs one on every line. - A purchase-type price list exists if you want **Unit Cost** filled in automatically; otherwise you type it. - Your security profile grants access to Requisition and Requisition Line and to the release actions you will run (see [Permissions](#permissions)). Releasing also creates a purchase order or a transfer, so you need create access to those too. ## Procedure ### Step 1 — Find a requisition Open **Procurement → Requisitions**. The cards across the top count **All Requisitions**, **Draft Requisitions** and **Confirmed Requisitions**, and total their **Total Amount**. Switch to the **Purchase** view to see only requisitions that name a supplier. Use search, filters and column sorting to narrow the list, and open a requisition by its **Document Number**. ### Step 2 — Create the requisition @[guided-image](_img/new-requisition.png) Choose **New**. The **Requisition Configuration** dialog opens: 1. The top row: **Document Date** (today if you leave it empty), **Supplier Account** and **From Branch**. Fill **Supplier Account** when the request will be bought, or **From Branch** when another of your branches will supply it. 2. The **Requisition Configuration** tab: **Resource** (the person the request is for), **Required Date**, **Price List** and **Tax Group**. 3. The **System Details** tab: **Partner Account** and **Branch** — the organization and branch raising the request. Save. The requisition gets a number such as `R-10102026-000001` and opens at Status *Draft*. If the branch has a default supplier and you left **Supplier Account** empty, it is filled in. **Partner Account**, **Branch** and **Supplier Account** cannot be changed once saved, so check them before you save. ### Step 3 — Add the lines On the **Lines** tab use **Quick Add**, **Product Catalogue** (pick several items at once) or **Import** (load lines from a file). The quick-add form asks for **Item**, **SKU**, **Quantity**, **Unit Cost**, **Tax Group** and **Description**, and shows the item's details beside them. **Quantity** must be greater than zero. On save the line is priced and taxed, and the **Amounts** panel updates. Adding a package item adds its component lines too; to choose optional components and their quantities, use **Product Configurator** in the header — see [the product configurator](/docs/crm/product-configurator/). @[guided-image](_img/requisition-detail-lines.png) ### Step 4 — Check what is pending Open a line to see its **Quantity Details**: **Quantity**, **Stock Transfer Quantity**, **Purchase Order Quantity** and **Pending Quantity**. The default **Lines** grid shows item, quantity, unit cost, tax and amount; the release dialogs in the next steps show each line's pending quantity. **Total Pending Quantity** on **Details** is the sum for the whole requisition. ### Step 5 — Release to a purchase order - **Release Order** creates one purchase order for every line that still has pending quantity, each at its full pending quantity. - **Selective Release Order** opens a list of the requisition's lines. Tick the lines to release and enter a **Requested Quantity** on each — greater than zero and no more than the line's **Pending Quantity** — then confirm. The new purchase order copies the requisition's **Supplier Account**, **Partner Account** and **Branch** and shows the requisition in its **Requisition** field. Each order line copies the item, SKU and **Unit Cost** and links back to the requisition line. Lines with nothing pending are skipped. The order opens at Status *Draft*; carry on with it as described in [purchase orders](/docs/procurement/purchase-orders/). The requisition's pending quantities go down by what you released. ### Step 6 — Or release to a stock transfer When the items should come from another of your branches, make sure **From Branch** is set, then use **Release Transfer** or **Selective Release Transfer**. They work the same way as the order releases, but create an outward stock transfer from **From Branch** to the requisition's **Branch**, at Status *Draft*, with one line per released requisition line. Carry on with the transfer in the Inventory app — see [stock transfers](/docs/inventory/transfers/). ### Step 7 — Release the rest later A partly released requisition stays at *Draft* with its release buttons available. Return to it at any time and release the remaining quantity — to the same supplier, as a transfer, or by pulling the lines into another purchase order with **Add Requisition** or **Selective Requisition Lines** there. When nothing is left pending, the release buttons disappear and, on the next save, Status becomes *Confirmed*. ### Step 8 — Change, clone or delete a requisition Choose **Edit** to change the header; **Partner Account**, **Branch** and **Supplier Account** stay locked. To reduce a line, lower its **Quantity** — not below what is already on purchase orders. **Clone** asks *"This will create a copy of the current record (including its line items)."* and starts a new requisition from this one. **Delete** removes the requisition after a confirmation; a line that already has purchase-order quantity cannot be deleted. ### Step 9 — Work on mobile Requisitions are part of the Procurement app in the mobile app, with the same create form, record page, quick-add line form and release dialogs, so a requester can raise a requisition from the floor and a buyer can release it from the web. ## Fields ### Header | Field | What it means | Notes | | --- | --- | --- | | Document Number | The requisition number. | Generated on save, for example `R-10102026-000001`. | | Document Date | The request's business date. | Today if left empty. | | Supplier Account | The vendor to buy from. | Only active supplier accounts. Defaulted from the branch's default supplier when empty. Copied to every purchase order released from it. Locked once saved. | | From Branch | The branch that will supply the items for a transfer. | Limited to the partner account's branches. Leave empty for a purchase. | | Resource | The person the request is raised for. | Must be authorized for the partner account and branch. | | Required Date | When the items are needed. | Cannot be earlier than today. | | Price List | The purchase price list lines are priced from. | Defaulted on create. Changing it later does not reprice existing lines. | | Tax Group | Header-level taxes. | Applied when the requisition is created. | | Partner Account | Your organization raising the request. | Only active partner accounts. Locked once saved. | | Branch | The requesting branch, which receives the goods. | Must be active and belong to the partner account; required when the partner account has branches. Locked once saved. | | Status | Where the request stands. | *Draft* (default), *Confirmed*, *Approved*. Set to *Confirmed* automatically; read-only on the record page. | | Tax Supply Type | The tax lane. | *Within State*, *Outside State*, *Exempt*, *Exports*, *SEZ*. For businesses in India it is set from the supplier's tax registration and the place and source of supply. | | Price As On Date | The date prices are taken from for new lines. | Optional; Document Date is used when empty. | | Total Amount | The estimated value of the request. | Sum of line amounts, including line tax. Read-only. | | Total Pending Quantity | What is still left to release. | Sum of the lines' pending quantity. | | Requested By, Purchase Order | Optional references. | On **Details → Request Summary**. The release actions do not fill **Purchase Order**; the purchase order points back at the requisition instead. | ### Lines | Field | What it means | Notes | | --- | --- | --- | | Item | What is requested. | Required. Active items only; discontinued and discounted items are refused. | | SKU | The item variant. | Required when the item requires a SKU; limited to the item's SKUs. | | Item Lot Type | The lot type of the item. | Optional. | | Quantity | How much is requested. | Required, greater than zero. Cannot go below what is already on purchase orders. | | Unit Cost | The expected price per unit. | From the price list, or typed. Copied to the purchase-order or transfer line on release. | | Tax Group | The line's taxes. | From your tax group rules when the line is added. | | Description | Text for the line. | Optional. | | Tax Amount, Amount | The line's tax and value. | Amount = quantity × unit cost + tax amount. | | Purchase Order Quantity, Stock Transfer Quantity, Pending Quantity | The lifecycle counters. | Maintained by the system. | | Requested Quantity | The quantity to release in a selective release. | Entered in the release dialog; not stored as a record of the original request. | | Exclude In Auto Order | Leaves the line out of auto-order calculations. | No effect on the release actions. | The full list of stored fields is in the [Requisition](/docs/reference/entities/requisition/) and [Requisition Line](/docs/reference/entities/requisition-line/) entity references. ## Business rules - **Numbering.** Requisitions are numbered `R-` + the document date as DDMMYYYY + a six-digit counter; lines use `RL-`. - **Locked fields.** Partner Account, Branch and Supplier Account cannot change once saved. - **Partner and branch.** Both must be active and belong together; when the partner account has branches, a branch is required. - **Active accounts.** Partner Account and Supplier Account must be active accounts; Branch must be an active branch. - **Resource.** A resource on the requisition must be authorized for its partner account and branch. - **Required Date** cannot be in the past. - **Line quantity** must be greater than zero, and cannot drop below the line's purchase-order quantity. - **Line deletion.** A line with purchase-order quantity cannot be deleted. The quantity-reduction and deletion checks look at purchase orders only, not at transfers — check **Stock Transfer Quantity** before you reduce or delete a line that was released to a transfer. - **Releases** draw only on pending quantity. A selective release refuses a requested quantity of zero or above the line's pending quantity, and nothing is created when nothing is pending. - **Status** becomes *Confirmed* when the requisition is saved with lines and no pending quantity. - **Packages.** Adding a package item adds its purchase components; component quantities follow the package line and must stay within the component's minimum and maximum, and mandatory components cannot be removed. ## Example A tractor dealer's service workshop needs 20 brake pads and 6 hydraulic filters for next week's jobs. The workshop supervisor opens **Procurement → Requisitions**, chooses **New**, sets **Required Date** to next Monday, leaves **Supplier Account** empty and saves. The branch's default supplier is filled in, and the requisition is numbered `R-10102026-000031` at Status *Draft*. They add two lines with **Quick Add**; the unit costs come from the purchase price list. The buyer sees that the main branch has 10 brake pads in stock. They set **From Branch** to the main branch and run **Selective Release Transfer** with 10 brake pads. A transfer is created, and the brake-pad line now shows 10 pending. Then they run **Release Order**: a purchase order is created for the remaining 10 brake pads and all 6 filters. **Total Pending Quantity** is now 0, the release buttons disappear, and on the next save Status becomes *Confirmed*. ## Training ### Practice exercise In a sandbox, as a user with the System Admin or Standard User profile: 1. Create a requisition for a test partner account and branch, with a supplier and a **Required Date** next week. Expected: an `R-` number and Status *Draft*. 2. Try to set **Required Date** to yesterday and save. Expected: *"Required By Date Should not be Backdated"*. 3. Add a line for a stock item, quantity 10. Expected: **Unit Cost** filled from the purchase price list and the **Amounts** panel updated. 4. Run **Selective Release Order** for 4 of the 10. Expected: a purchase order linked to the requisition, and 6 pending on the line. 5. Try to change the line's quantity to 3. Expected: *"Quantity cannot be less than the already transacted quantity."* 6. Run **Release Order**. Expected: a second purchase order for 6. 7. Check the header. Expected: **Total Pending Quantity** 0, no release buttons, and Status *Confirmed* after the next save. ### Quick reference - Partner Account, Branch and Supplier Account lock on save — check them first. - Supplier Account for a purchase; From Branch for a transfer. - Pending Quantity = Quantity − Purchase Order Quantity − Stock Transfer Quantity. - Selective releases take only the quantities you enter, never more than pending. - Release buttons show only at Draft with something pending. - Status turns Confirmed by itself when nothing is left pending. - A purchase order can pull lines in with Add Requisition. - Exclude In Auto Order keeps a line out of auto-order suggestions. ## Permissions Access is set on [security profiles](/docs/administration/security-profiles/): - **Entity access.** The shipped *System Admin*, *Standard User*, *Sales Manager* and *Sales Executive* profiles have full access to Requisition and Requisition Line. Give other profiles entity access before assigning them to requesters or buyers. - **Record sharing.** Requisitions are owned by a user; see [record security](/docs/administration/record-security/). - **Actions.** Each button is a separately granted action: - **New** and the four release actions: *System Admin*, *Standard User* and *Sales Manager*. *Sales Executive* cannot create or release requisitions. - **Clone**: *System Admin*, *Standard User* and *Sales Executive*. - **Product Configurator**: *System Admin* and *Standard User*. A user without an action does not see its button. Grant missing ones on the profile's **Actions** tab. - **Downstream documents.** A release creates a purchase order or a transfer, so the user also needs access to those entities. ## Configuration - **Document numbering.** **Setup → Feature Hub → Platform → Document Settings**: *Requisition Name Setting* (series `R`, separator `-`, date DDMMYYYY, six digits) and *Requisition Line Name Setting* (series `RL`). See [Email templates and document numbering](/docs/administration/templates/). - **Status automation.** The shipped business rule *Set Requisition Status To Confirmed* lives in **Setup → Process Studio → Business Rules**; change or deactivate it there. Because the release buttons are hidden once Status is not *Draft*, any rule or process you add that changes Status also hides them. See [Business rules](/docs/customization/business-rules/). - **Approval.** No approval process is shipped for requisitions. To require sign-off before release, create one in **Setup → Process Studio → Approvals** — see [Approval processes](/docs/customization/approvals/). - **Validations.** The shipped validations — active partner account, active branch, active supplier account, *Required By Date Should not be Backdated*, and on lines *Discontinued Item Cannot be added* and *Quantity should be greater than 0* — are metadata you can review in the entity's settings. - **Lookup filters.** The shipped filters limit Supplier Account to active suppliers, Partner Account to active partner accounts, Branch and From Branch to the partner account's branches, and the line SKU to the item's SKUs. - **Default supplier.** A branch's default supplier is filled in on new requisitions without one — see the [procurement configuration reference](/docs/procurement/configuration/). - **Pricing and taxes** come from purchase price lists and tax group rules. - **Auto-order.** Pending requisition quantities feed the auto-order engine when the auto order includes purchase requisitions; the line's **Exclude In Auto Order** flag opts a line out. See [auto-order](/docs/procurement/auto-order/). - **Layouts and views.** The create dialog, record page, header buttons and their visibility conditions, release dialogs and list views are metadata you change in Design Studio. Add the line counters to the **Lines** grid there if your users want them on the record page. - **Reports.** A *Requisition Statement* report and a *Requisitions* dashboard are shipped. ## Common problems ### "At least one Requisition Line with quantity greater than zero is required to create Purchase Order." Every line is already fully released, or the requisition has no lines. Check **Pending Quantity** on each line. The transfer actions show the same message with *Transfer* in place of *Purchase Order*. ### "Requested quantity (…) cannot exceed the pending quantity (…)." A line in a selective release asks for more than is pending. Reduce it to at most the pending quantity shown in the dialog. ### "Requested quantity must be greater than zero." A ticked line has a blank or zero **Requested Quantity**. Enter the quantity to release on every ticked line, or untick it. ### "RequisitionLines argument is required for SelectiveReleaseOrder action." No line was ticked in the selective release dialog. Tick at least one line. The transfer version names *SelectiveReleaseTransfer*. ### "Quantity cannot be less than the already transacted quantity." You tried to lower a line below what its purchase orders already carry. Reduce the purchase-order line first, or leave the requisition line as it is. ### "There are downstream transactions. The record cannot be deleted." The requisition line already has purchase-order quantity. Delete the purchase-order lines that were released from it first. ### "Key fields are not editable once the related objects are added. Field Name : …" You tried to change **Partner Account**, **Branch** or **Supplier Account** on a saved requisition. Create a new requisition with the correct values. ### "Required By Date Should not be Backdated" **Required Date** is earlier than today. Choose today or a later date. ### "Resource is not authorized for Partner Account '…'." or "… for branch '…'." The chosen **Resource** is not set up for this partner account or branch. Pick another resource, or ask your administrator to authorize the resource. ### "SKU is required for this item." The item is set up to require a SKU. Pick one of the item's SKUs on the line. ### "Discontinued Item Cannot be added" The item is marked discontinued. Choose its replacement. ### The release buttons are missing They show only while Status is *Draft* and **Total Pending Quantity** is greater than zero. A *Confirmed* requisition has nothing left to release. If Status is *Draft* and something is pending, your profile may lack the release actions — see [Permissions](#permissions). ### The purchase order has no supplier The requisition had no **Supplier Account** when it was released. Set the supplier on the purchase order. ## Common questions ### Can one requisition produce several purchase orders? Yes. Every release creates a new purchase order for whatever you release, so you can run **Selective Release Order** several times, each time for different lines or part quantities, until nothing is pending. Each order takes the requisition's **Supplier Account**, which is locked on the requisition. To buy part of the request from a different supplier, release those lines with **Selective Release Order** and change the supplier on the new purchase order before you continue with it. **Add Requisition** and **Selective Requisition Lines** on a purchase order only offer requisitions for the order's own supplier and branch. ### Does the Status change when I release? Indirectly. Releasing does not set Status itself, but a shipped business rule sets it to *Confirmed* when the requisition is saved with lines and nothing left pending. A partly released requisition stays at *Draft*. To see exactly where a request stands, read **Total Pending Quantity** and each line's counters rather than Status alone. ### Can I mix a purchase and a transfer on one requisition? Yes. Both routes draw on the same **Pending Quantity**, so you can transfer part of a line from another branch and buy the rest. Set **From Branch** before releasing the transfer; the supplier stays on the requisition for the purchase. ### Do open requisitions affect auto-ordering? Yes. When an auto order includes purchase requisitions, the pending quantity of open requisition lines for the same partner account and branch is taken into account, so quantities people have already asked for are not suggested twice. Tick **Exclude In Auto Order** on a line to leave it out. See [auto-order](/docs/procurement/auto-order/). ## Related topics - [The purchase order lifecycle](/docs/procurement/purchase-orders/) - [Auto-order: rules-based purchase suggestions](/docs/procurement/auto-order/) - [Procurement configuration reference](/docs/procurement/configuration/) - [Procurement troubleshooting](/docs/procurement/troubleshooting/) - [Requisition entity reference](/docs/reference/entities/requisition/) - [Requisition Line entity reference](/docs/reference/entities/requisition-line/) - [xMatix Procurement overview](/docs/procurement/) ---- # Three-way match implementation reference URL: https://xmatix.com/docs/procurement/three-way-match/ Last reviewed: 2026-09-02 The repository contains a read-only `ThreeWayMatchService` that compares a purchase order line by line. It is covered by integration tests, but the audited first-party metadata and web application expose no standard screen, report or entity action that calls it. There is therefore no product screenshot or end-user procedure to show. Before users can run this review, a deployment must expose the service through a tested API, report or custom action and decide where its result belongs in the payment process. ## How the comparison works For each purchase-order line, the service calculates: | Result | Calculation | | --- | --- | | Ordered | Purchase-order line `Quantity`. | | Received | Sum of `ReceivedQuantity` on linked goods-receipt lines. | | Billed | Sum of `Quantity` on linked bill lines. | | Receipt variance | Received minus ordered. | | Bill variance | Billed minus received. | | Ordered / billed amount | Purchase-order line amount and the sum of linked bill-line amounts. | Both totals and variances are rounded to four decimal places using midpoint-away-from-zero. A line is `Matched` only when both quantity variances are zero. Otherwise status is `OverReceived` or `UnderReceived`, plus `OverBilled` or `UnderBilled` when applicable; two flags are joined with `+`. The amounts are returned for review, but the service does not calculate a separate amount-variance status. ## Link contract - A receipt contributes only when its line has `PurchaseOrderLineId` set to the order line. - A bill contributes only when its line has `PurchaseOrderLineId` set to the order line. - Soft-deleted purchase-order, receipt and bill lines are excluded. - A header-level Purchase Order or Goods Receipt link is not enough; the service queries line foreign keys. ## Important release-path limitation The current **Goods Receipt → Release Bill** service creates each bill line with `GoodsReceiptLineId` but does **not** copy `PurchaseOrderLineId`. Such a bill is therefore absent from the current three-way billed totals even when the receipt itself came from a purchase order. The **Purchase Order → Perform/Selective Release Invoice** service behaves differently: when eligible receipt lines exist, it creates bill lines with both `PurchaseOrderLineId` and `GoodsReceiptLineId`; without receipts it still creates the purchase-order-line link. If a customization exposes the current match service, use and test this order-side release path when both links are required, or fix the receipt-side mapping before relying on its result. ## What an exposed consumer should show A safe custom consumer should show the purchase-order line, ordered/received/billed quantities, ordered/billed amounts, both variances and status, with links back to every contributing receipt and bill line. It should also disclose bills linked only to a receipt so omission is visible. The service itself performs no save, posting, approval or payment block. ## Common problems - **A bill is absent from an integration's result.** Inspect `PurchaseOrderLineId` on its lines. Direct bills and current receipt-side released bills can lack it. - **Everything is UnderReceived on a fresh order.** The service sums actual `ReceivedQuantity`, not quantity merely staged on a goods-receipt line. - **A line looks correct but is not Matched.** Inspect all non-deleted linked receipt and bill lines; the service sums all of them and rounds the totals to four decimals. ## Common questions ### Does the service block posting or payment? No. It is a read-only query service. A custom payment control would need to call it explicitly and define tested tolerance and override rules. ### Which numbers exactly are compared? Per order line: ordered quantity and amount from the purchase-order line; received quantity from linked goods-receipt lines; billed quantity and amount from linked bill lines. The two status variances are quantity-based. ## Related topics - [The purchase order lifecycle](/docs/procurement/purchase-orders/) - [Receive goods against a purchase order](/docs/procurement/goods-receipts/) - [Supplier bills](/docs/procurement/bills/) - [Troubleshooting procurement](/docs/procurement/troubleshooting/) ---- # Troubleshooting procurement URL: https://xmatix.com/docs/procurement/troubleshooting/ Last reviewed: 2026-09-02 The most common procurement problems are the module's own guardrails talking: a release action refusing because nothing is pending, a receive action refusing because a required quantity is missing, or an auto-order quantity that only looks wrong until you read the arithmetic stored on the line. This page maps each symptom to its cause and fix. This page remains text-only because the standard lists do not display the validation messages or backend three-way result described below. A generic Bills screenshot would look plausible but would not prove any of these conditions. ## A goods receipt won't receive or post - **"Supplier Quantity is required for Goods Receipt Lines before receiving."** Every unposted line needs the supplier quantity filled in before Perform Receive will run. - **"All Goods Receipt Lines have already been posted to Inventory."** The receipt is done. If more goods are coming, release a new receipt from the order's remaining pending quantity. - **Received quantity isn't showing as available stock.** If the item has **Inspection On Receipt** enabled, its received quantity is held under inspection until the inspection completes — that is the design, not a stuck posting. Run **Perform Inspection**, record findings, then **Perform Inspection Complete**. - **"No Goods Receipt Line requires inspection."** The inspection actions only apply to lines whose item carries the inspection flag and which still have quantity pending inspection. If you expected an inspection, check the item's flag ([configuration](/docs/procurement/configuration/)); if you didn't, skip straight past the inspection steps. - **"No Inspection Line found with pending completion."** All inspection lines are already done — the inspection is complete and nothing is being held. ## A bill is missing from a custom three-way result The backend match counts a bill line only when `PurchaseOrderLineId` is present. The current receipt-side **Release Bill** path sets only `GoodsReceiptLineId`; those lines are omitted. Inspect the line links rather than the headers. Order-side **Perform/Selective Release Invoice** carries the purchase-order-line link and, when receipt lines exist, the receipt-line link as well. See the [implementation reference](/docs/procurement/three-way-match/). ## An auto-order suggested an unexpected quantity Don't guess — the line carries its own arithmetic. On a Forecasting line, recompute it from the stored snapshot: ``` projected = quantity available + pending shipments + pending purchase orders − pending requisitions − pending sale orders reorder point = lead time × average consumption + minimum order quantity suggested = maximum order quantity − projected ``` Walk the inputs; one of these is nearly always the answer: - **A pipeline component is missing or unexpectedly zero** — check the order header's include options (in-transit shipments, pending purchase orders, requisitions, open sale orders) and whether the document lines you expected carry the *Exclude In Auto Order* flag. - **Lead time or average consumption is stale** — the reorder point moves with them; update the item's planning attributes. - **Minimum/maximum order quantity is wrong** — the suggestion always fills to the maximum, so an inflated maximum inflates every suggestion. - **Several planning rows match the item** — parameters are averaged across matching rows (branch-scoped plus unscoped, for example); remove or correct the row you forgot existed. - **An item is missing entirely** — no planning attributes for this branch/partner, or a header ABC/FSN exclusion removed it. After fixing inputs, run **Generate Lines** again — it replaces the lines with a fresh calculation. If the auto order refuses with *"Purchase Order is already generated"*, that worksheet is closed; create a new auto order. ## A release action refuses to run - **Requisition → order:** *"At least one Requisition Line with quantity greater than zero is required"* — every line is fully released or zero-quantity. - **Receipt → bill:** *"No Goods Receipt Lines found to Release Bill"* — every line is fully billed already. - **Any selective release rejects a quantity** — you asked for more than that line's pending counter (pending quantity, or pending invoice quantity for bill releases). Enter at most what is pending. - **A purchase-order line looks less pending before goods are physically received** — the current receipt aggregate sums `GoodsReceiptLine.OrderedQuantity`. Releasing quantity onto a receipt can therefore reduce the purchase-order pending counter before **Perform Receive** updates actual `ReceivedQuantity`. Inspect the receipt line and inventory ledger instead of treating the order counter as receipt proof. ## Related topics - [Receive goods against a purchase order](/docs/procurement/goods-receipts/) - [Three-way match: order, receipt and bill](/docs/procurement/three-way-match/) - [Auto-order: rules-based purchase suggestions](/docs/procurement/auto-order/) - [Procurement configuration reference](/docs/procurement/configuration/) ---- # Account Balance — entity reference URL: https://xmatix.com/docs/reference/entities/account-balance/ Last reviewed: 2026-08-16 A decommissioned legacy balance table, dropped alongside the old general-ledger table when the balanced journal ledger shipped. Nothing reads or writes it: account balances now live in GLAccountPeriodBalance (per account, period and dimension) and PartyPeriodBalance (per party inside a control account), both derived from posted journal lines. The metadata row survives only because entity definitions are upsert-only in the seed engine. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Amount` | Amount Signed | Currency | | | | `AmountCrDr` | Amount | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Edit` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Account Group Member — entity reference URL: https://xmatix.com/docs/reference/entities/account-group-member/ Last reviewed: 2026-08-16 One Account's membership of one AccountGroup - the join every group-aware engine actually reads (pricing, discount, tax, scheme, scheme budget and item-component resolution all query this table rather than any field on Account). Rows are either created by hand or generated by the group's rule-driven member rebuild, which stamps each generated row with the run's BatchInstanceId and soft-deletes rows carrying an older one; hand-made rows have no BatchInstanceId and are therefore never swept by that rebuild. UniqueKey is a composite of the group id and account id, written by the rebuild to make the pairing identifiable. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `BatchInstanceId` | Batch Instance | Text | | The rebuild-run tag. Each rule-driven member rebuild stamps a fresh identifier on the rows it inserts and then soft-deletes rows carrying any earlier one, so a row's tag tells you which rebuild produced it. Rows added by hand have no tag and are therefore never removed by the sweep, which is how manual and generated membership coexist in one group. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | Set true on every row the rebuild generates. Consumers disagree about it: the scheme engine and the discount, price and tax resolvers require it to be true, while item-component resolution ignores it entirely - so clearing it hides the membership from most engines but not all. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UniqueKey` | Unique Key | Text | | Composite of the group id and account id written by the member rebuild to make the pairing identifiable; it is not a database uniqueness constraint, so duplicates are possible if rows are created by other means. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete Selected | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Delete in page. | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | NewInline | New | | `UIAction` | UI Action | UIAction | UI Action | ## Related entities - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Account Group Rule — entity reference URL: https://xmatix.com/docs/reference/entities/account-group-rule/ Last reviewed: 2026-08-16 One dynamic-membership condition under an AccountGroup: a field name, an operation and a value, evaluated against the Account entity by the shared group-rule engine when the group's member rebuild runs. Rules are ordered by SequenceNumber (custom logic refers to them by 1-based position) and combined according to the parent group's RuleSuccessCriteria. The same rule shape and engine back ItemGroupRule and CampaignRule. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FieldName` | Field Name | Text | | The Account property this rule tests. | | `FieldValue` | Field Value | Text | | The comparison value, always stored as text and coerced to the target property's type at evaluation time. Numeric comparison is culture-invariant and scale-insensitive, so a stored '10000.00' matches a numeric 10000. For the in and notin operators this is a comma-separated list. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Rule Name | Text | Yes | | | `Operation` | Operation | PickList | | The comparison operator. The engine understands equals, notequal, lessthan, greaterthan, lessorequal, greaterorequal, like (substring), in and notin (comma-separated), plus includes/excludes which always fall back to in-memory evaluation. The seeded picklist exposes only equals and greaterorequal, so most of the engine's operators can only be set outside the standard form. Values: equals, greaterorequal. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SequenceNumber` | Sequence Number | Number | Yes | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete Selected | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Delete in page. | | `New` | New | NewInline | New | | `UIAction` | UI Action | UIAction | UI Action | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Account Group — entity reference URL: https://xmatix.com/docs/reference/entities/account-group/ Last reviewed: 2026-08-16 A named set of Accounts used as a targeting dimension by the pricing, discount, tax, scheme, item-component and incentive engines: instead of naming each account, a PriceList, DiscountGroup, TaxGroup, Scheme, SchemeCondition, SchemeAccountBudget, ItemComponent, KPIConfiguration or IncentivePlan row points at a group and the engine resolves the accounts through AccountGroupMember. AccountGroupType partitions groups by which engine may consume them and each engine matches it as an exact string, so a group typed for one engine is invisible to the others. Membership is either maintained by hand as AccountGroupMember rows or rebuilt from the child AccountGroupRule rows, the latter through the group's Process Member server action. Groups are referenced separately in customer and partner roles (for example DiscountGroup.CustomerAccountGroupId versus PartnerAccountGroupId), so one group can scope either side of a transaction. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountGroupType` | Account Group Type | PickList | Yes | Which engine may consume this group, matched as an exact case-sensitive string by the consuming service. The pricing engine looks for 'Price', discounts for 'Discount', tax for 'Tax', and the scheme engine for 'Scheme' and 'Exclude Scheme'. The seeded picklist does not currently offer 'Tax' or 'Scheme', and offers 'Incentive' and 'Item Feature' which no engine matches on (incentive plans and item features reference a group by foreign key instead), so the picklist and the engines disagree in both directions - check the stored value, not the option list. Values: Discount, Incentive, Item Feature, Price, Exclude Scheme, Tax. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `DynamicMemberType` | Dynamic Member Type | PickList | | How the member rebuild sources its accounts. Values: Field Filter. | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReportId` | Report | Text | | | | `RuleSuccessCriteria` | Rule Success Criteria | PickList | | How the child rules are combined during a member rebuild. An empty value is treated as 'no criteria' and matches every account. Values: Any Rule Is Met. | | `RuleSuccessCustomLogic` | Rule Success Custom Logic | Text | | A boolean expression over the child rules referenced by their 1-based sequence position, used only when the criteria is set to custom logic; that combination forces the whole rebuild to evaluate in memory rather than in SQL. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Delete in page. | | `EditInList` | Edit | Edit | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `New` | New | New | New | | `ProcessMembers` | Process Members | ServerAction (`ProcessMembers`, async) | ProcessMembers | | `UIAction` | UI Action | UIAction | UI Action | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Rule Success Criteria Validation | Error | Selection of Rule Success Criteria is mandatory if the Dynamic Member Type is Field Filter! | Rule Success Criteria is mandatory in case of field filters. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [AccountGroupMember](/docs/reference/entities/account-group-member/) — referenced by via `AccountGroupId` - [TaxGroup](/docs/reference/entities/tax-group/) — referenced by via `PartnerAccountGroupId` - [ItemComponent](/docs/reference/entities/item-component/) — referenced by via `PartnerAccountGroupId` - [Visit](/docs/reference/entities/visit/) — referenced by via `AccountGroupId` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — referenced by via `AccountGroupId` - [ItemConsumptionSchedule](/docs/reference/entities/item-consumption-schedule/) — referenced by via `CustomerAccountGroupId` - [GLAccount](/docs/reference/entities/glaccount/) — referenced by via `AccountGroupId` - [SchemeAccountBudget](/docs/reference/entities/scheme-account-budget/) — referenced by via `PartnerAccountGroupId` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — referenced by via `AccountGroupId` - [DiscountGroup](/docs/reference/entities/discount-group/) — referenced by via `PartnerAccountGroupId` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — referenced by via `PartnerAccountGroupId` - [SchemeLine](/docs/reference/entities/scheme-line/) — referenced by via `RewardAccountGroup` - [PriceList](/docs/reference/entities/price-list/) — referenced by via `PartnerAccountGroupId` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `ExcludeAccountGroupId` - [DiscountGroup](/docs/reference/entities/discount-group/) — referenced by via `CustomerAccountGroupId` - [ItemFeature](/docs/reference/entities/item-feature/) — referenced by via `PartnerAccountGroupId` - [VisitRoute](/docs/reference/entities/visit-route/) — referenced by via `PartnerAccountGroupId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — referenced by via `PartnerAccountGroupId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — referenced by via `AccountGroupId` - [Scheme](/docs/reference/entities/scheme/) — referenced by via `AccountGroupId` - [PriceList](/docs/reference/entities/price-list/) — referenced by via `CustomerAccountGroupId` - [ItemConsumptionSchedule](/docs/reference/entities/item-consumption-schedule/) — referenced by via `PartnerAccountGroupId` - [Scheme](/docs/reference/entities/scheme/) — referenced by via `PartnerAccountGroupId` - [VisitPlan](/docs/reference/entities/visit-plan/) — referenced by via `AccountGroupId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `AccountGroupId` - [Store](/docs/reference/entities/store/) — referenced by via `PartnerAccountGroupId` - [PostingDefinition](/docs/reference/entities/posting-definition/) — referenced by via `AccountGroupId` - [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) — referenced by via `AccountGroupId` - [VisitRoute](/docs/reference/entities/visit-route/) — referenced by via `AccountGroupId` - [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) — referenced by via `PartnerAccountGroupId` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `AccountGroupId` - [AccountGroupRule](/docs/reference/entities/account-group-rule/) — referenced by via `AccountGroupId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Account Location — entity reference URL: https://xmatix.com/docs/reference/entities/account-location/ Last reviewed: 2026-08-16 An aisle, shelf or display at a customer outlet - the unit a merchandising audit is scoped to, classified by locationType and channel. Belongs to an Account (accountId). Note the naming: the metadata entity name is singular AccountLocation (use this in data API calls) while the physical table is data.AccountLocations; it is unrelated to the free-text Account.accountLocation field. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup | | | | `AllowInventory` | Allow Inventory | Boolean | | | | `Channel` | Channel | PickList | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `LocationType` | Location Type | PickList | | Values: Remote. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Account Stock — entity reference URL: https://xmatix.com/docs/reference/entities/account-stock/ Last reviewed: 2026-08-16 A stock observation recorded at a customer or partner account during a field visit, carrying the visit, visit plan, visit task and visit task activity keys that produced it. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup | | The customer or outlet whose shelf was counted, as distinct from the partner account, which is the company that owns the record. | | `AvailableQuantity` | Quantity | Number | | An integer quantity, unlike the decimal quantities used everywhere else in inventory. The merchandising audit deliberately leaves it alone, because a shelf facing count is not the outlet's on-hand stock and conflating the two would corrupt stock reporting. | | `BranchId` | Branch | Lookup | | | | `ConversionRatio1` | Conversion Ratio 1 | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup | | | | `ItemLotTypeId` | Item Lot Type | Lookup | | | | `ItemSKU` | SKU | Lookup | | The SKU reference for the counted product. Note the unusual name: every other entity in the module calls this SKUId, so queries and mappings written by analogy will miss it. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup | | The field resource who performed the count, carried over from the visit so audit findings can be attributed to a rep. | | `UIProps` | UI Props | Text | | | | `UOM` | UOM | PickList | | The primary unit the counted quantity is expressed in. Not populated by the merchandising audit path, which records raw facing counts. | | `UOM1` | UOM1 | PickList | | | | `UOMQuantity` | UOM Quantity | Number | | | | `UOMQuantity1` | UOM Quantity1 | Number | | Carries the counted facing quantity written by the merchandising audit - this, not the available quantity, is the number a planogram audit records. A zero is a genuine finding (the product had no facings), not a blank. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VisitId` | Visit | Lookup | | | | `VisitPlanId` | Visit Plan | Lookup | | | | `VisitTaskActivity` | Visit Task Activity | Lookup | | The specific activity within the visit task that produced this row, and the idempotency key for the audit: re-submitting the same activity reconciles its existing rows by product rather than appending a second set of counts. Note the name has no Id suffix, unlike the sibling visit references. | | `VisitTaskId` | Visit Task | Lookup | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Account — entity reference URL: https://xmatix.com/docs/reference/entities/account/ Last reviewed: 2026-10-10 An account is the single master record for every organization or person you deal with: customers, suppliers, retail outlets and the partner companies in your network that own transactions. One account can hold several roles at once through the Customer Account, Supplier Account and Partner Account switches, and Active decides whether it can be used on new documents. It appears in the CRM, Sales and Support apps, among others. Code and Phone must be unique. A customer account saved with Create Account Contact on gets a primary contact made from its name and email. Merge moves activities, files, collaborators, followers and side conversations onto the surviving account but leaves the duplicate active, and Transfer Partner hands a partner company's outlets, resources, stock and open orders to another partner. Step-by-step procedures are on the Accounts page of the CRM documentation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountCode` | Code | Text, unique | | Labelled Code: your short code for the party. It must be unique across accounts, and it is preferred over Account Number wherever a code is looked up. | | `AccountContactId` | Account Contact | Lookup | | Labelled Account Contact: the account's primary contact, normally created and maintained by Create Account Contact. | | `AccountLocation` | Account Location | Text | | A free-text location note. It holds no coordinates; the map position is Geo Location. | | `AccountNumber` | Account Number | Text | | An older account code, used only when Code is empty. | | `AccountSource` | Account Source | PickList | | How the party was acquired: Web, Phone Inquiry, Partner Referral, Purchase List or Other. For reporting only. Values: Web, Phone Inquiry, Partner Referral, Purchase List, Other. | | `AnnualRevenue` | Annual Revenue | Currency | | An estimate of the party's yearly turnover for segmentation. It defaults to 0 and is not used by credit limits or pricing. | | `ApplyPostTaxDiscount` | Apply Post Tax Discount | Boolean | | Set on a partner (company) account, this is copied by the tax service onto documents raised under that company to make discounts apply after tax rather than before. It is read from the partner side of the transaction, not from the customer. | | `AvailableRewardPoints` | AvailableRewardPoints | Decimal | | Do not quote it as a loyalty balance. | | `BillingAddress` | Billing Address | Text | | | | `BillingCity` | Billing City | PickList | | Free-text billing city held independently of the BillingCityPlaceId lookup, which remains the canonical Place reference. It exists so imports and integrations can land a city name that has no matching Place row, which means the two can disagree. Values: Pune, Mumbai, Chandigarh, Delhi, Calicut, Nagpur, Coimbatore, Amritsar, Siddipet, Vaishali, Rajkot, Bathinda, Kollam, Cuttack, Puducherry, Prithvipur, Perinthalmanna, Noida, Muzaffarnagar, Ballia, Bulandshahr, Meerut, Achhalda, Agra, Haridwar, Tirupati, Mohali, Indore, Nashik, Solapur. | | `BillingCityPlaceId` | Billing City | Lookup → [Place](/docs/reference/entities/place/) | | | | `BillingCountry` | Billing Country | PickList | | Values: India. | | `BillingPostalCode` | Billing Postal Code | Text | | | | `BillingRegion` | Billing Region | Text | | | | `BillingState` | Billing State | PickList | | Values: Haryana, Maharashtra, New Delhi, Punjab. | | `BillingStreet` | Billing Street | Text | | | | `ClaimableAmount` | Claimable Amount | Currency | | | | `CreateAccountContact` | Create Account Contact | Boolean | | When on for a customer account, the account's primary contact is created from its name and email on save and kept in step with them on later saves. The phone number is not copied. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeducteeType` | Deductee Type | PickList | | The statutory withholding classification of the party, which drives dual-rate section resolution (for example the individual/HUF rate versus the rate for other entities) and the deductee code written into withholding return files. Values: Individual, HUF, Company, Firm / LLP, AOP / BOI, Local Authority, Government, Trust. | | `DefaultTdsSectionId` | Default TDS Section | Lookup → [TdsSection](/docs/reference/entities/tds-section/) | | The withholding section defaulted onto new bill and invoice lines for this party; the line's own section remains the override, so a document can legitimately differ from it. | | `Description` | Account Description | Text | | | | `DocumentNameCode` | Document Name Code | Text | | A short code (up to five characters) contributed to generated document numbers: an invoice's document series is the partner account's code concatenated with the branch's code. Meaningful mainly on partner (company) accounts. | | `Email` | Email | Text | | The main email address, format-checked on save. It is copied to the primary contact when the account creates one, and kept in step on later saves while Create Account Contact is on. | | `ExternalId` | External | Text | | Labelled External: the party's identifier in another system. An imported row with this value and no internal id updates the one existing account that carries it. | | `Fax` | Account Fax | Text | | | | `FirstName` | First Name | Text | | | | `GeoLocation` | Geo Location | GeoLocation | | The account's map position, used for nearby-outlet search and route planning in the field app. | | `GSTIN` | GSTIN | LongMultiLineText | | The party's GST identification number, checked for its 15-character format. On documents, a GSTIN on the billing contact address takes precedence over this one. | | `GSTRegistrationType` | GST Registration Type | PickList | | The party's GST registration status and the main input to how a document is taxed. A registration type on the billing contact address takes precedence. Values: GST Registered- Regular, GST Registered- Composition, GST Unregistered, Consumer, Overseas, Special Economic Zone (SEZ), Deemed Exports, Non GST Supply, Out Of Scope. | | `Id` | Id | Guid | Yes | | | `Industry` | Industry | PickList | | Values: Technology, Chemicals, Manufacturing, Construction, Retail, Banking, Electronics, Finance. | | `IsActive` | Active | Boolean | | Labelled Active: whether the account can be used on new documents. Documents that reference an inactive account are refused. Switching it off does not change documents already recorded. | | `IsCustomerAccount` | Customer Account | Boolean | | Labelled Customer Account: you sell to this party. Only customer accounts can be picked as the customer on sales and CRM documents, and only customer accounts get an automatic primary contact. | | `IsDeadOutlet` | Dead Outlet | Boolean | | Labelled Dead Outlet: marks a retail outlet that has stopped ordering. Flagged outlets on the field rep's beat for the day appear on the Dead Outlets card. | | `IsGLPostingEnabled` | GL Posting Enabled | Boolean | | Labelled GL Posting Enabled: switches on general-ledger posting for a partner company. Switching it on for an already-saved partner account creates that company's standard ledger accounts; ticking it on the create form does not. | | `IsPartnerAccount` | Partner Account | Boolean | | Labelled Partner Account: a company in your network that owns transactions, named as the Partner Account on documents. When your organization runs several companies, a partner account must also be set up as a company before documents can be recorded for it. | | `IsPlatinumOutlet` | Platinum Outlet | Boolean | | Labelled Platinum Outlet: marks a high-value retail outlet. Flagged outlets on the field rep's beat for the day appear on the Platinum Outlets card. | | `IsRCM` | Is RCM | Boolean | | Labelled Is RCM: reverse charge applies to this supplier. It is copied to new bills that do not set it themselves. | | `IsRelatedParty` | Related Party | Boolean | | Labelled Related Party: marks the party for related-party disclosure. When on, Related Party Type is required; Related Party To cannot be before Related Party From. | | `IsSupplierAccount` | Supplier Account | Boolean | | Labelled Supplier Account: you buy from this party. Only supplier accounts can be picked as the supplier on procurement documents. | | `IsTaxExempted` | Tax Exempted | Boolean | | | | `Label` | Account Label | Text | | Labelled Account Label: the trading name when it differs from the registered name. Where a display name is shown, Account Label is preferred over Name. | | `LastName` | Last Name | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `MSMEEnterpriseCategory` | MSME Enterprise Category | PickList | | Registered activity: Manufacturing, Service or Trading. Trading enterprises are outside the MSMED delayed-payment relief. Values: Manufacturing, Service, Trading. | | `MSMEEnterpriseType` | MSME Enterprise Type | PickList | | Micro / Small / Medium classification shown on the supplier Udyam certificate. Values: Micro, Small, Medium. | | `MSMEPaymentDueDays` | MSME Payment Due Days | Number | | The payment period agreed with this MSME supplier, from 1 to 45 days. It feeds the MSME Delayed Payments statement on the fiscal year. | | `MSMERegistrationDate` | MSME Registration Date | Date | | Date of MSME / Udyam registration as printed on the certificate. | | `MSMERegistrationStatus` | MSME Registration Status | PickList | | MSME registration standing declared by the supplier. Only Registered attracts the MSMED s.15 payment window and s.16 delayed-payment interest. Values: Registered, Not Registered, Declaration Awaited, Deregistered. | | `MSMEUdyamNumber` | Udyam Registration Number | Text | | Labelled Udyam Registration Number, checked against the format UDYAM-XX-00-0000000. | | `MSMEVerifiedOn` | MSME Verified On | Date | | Date the Udyam number was last verified against the Udyam portal. | | `Name` | Name | Text | | The party's registered or legal name, shown on documents. It is not checked for uniqueness, so search before creating an account. | | `NumberOfEmployees` | Employees | Number | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Ownership` | Ownership | Text | | | | `PAN` | PAN | Text | | The Permanent Account Number, checked for its format (five letters, four digits, one letter). TDS processing and PAN verification key off it. | | `PanVerificationSource` | PAN Verification Source | Text | | | | `PanVerificationStatus` | PAN Verification | PickList | | Labelled PAN Verification: the result of checking the PAN (Verified, Invalid or Name Mismatch), recorded by the Import PAN Verification action on a TDS return or by hand. Empty means never checked. Values: Verified, Invalid, Name Mismatch. | | `PanVerifiedOn` | PAN Verified On | DateAndTime | | | | `ParentId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | Labelled Account: the parent account in the party's own corporate hierarchy, such as a head office above its branches. | | `PartnerOwnerAccountId` | Partner Owner Account | Lookup → [Account](/docs/reference/entities/account/) | | The partner company that owns this outlet. It is hidden when your organization runs a single company and is reassigned by Transfer Partner. | | `Phone` | Phone | Text, unique | | The main phone number. It must be unique across accounts and, in India, be 10 to 15 digits with an optional leading plus sign. A new lead whose phone number exactly matches it links itself to this account. | | `PhotoUrl` | Photo Url | Text | | | | `PlaceOfSupply` | Place of Supply | PickList | | The party's GST state, used when a document and its billing address carry none. It is compared with the branch's state to decide whether a supply is within or outside the state. Values: Maharashtra, Gujarat, Rajasthan, Haryana. | | `PlatinumOutletOrderCount` | Platinum Outlet Order Count | Number | | Order count behind the platinum classification, shown as the badge on the Platinum Outlets card. Computed over the classifier's trailing window -- read-only, because a hand-typed value would state a measurement nobody took. | | `Rating` | Account Rating | PickList | | Labelled Account Rating: Hot, Warm or Cold. For reporting only. Values: Hot, Warm, Cold. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RelatedPartyEffectiveFrom` | Related Party From | Date | | | | `RelatedPartyEffectiveTo` | Related Party To | Date | | | | `RelatedPartyRelationship` | Relationship | Text | | | | `RelatedPartyType` | Related Party Type | PickList | | Values: Director, Key Management Personnel, Relative of Director / KMP, Holding Company, Subsidiary Company, Fellow Subsidiary (Sister Concern), Associate / Joint Venture, Entity Controlled by Director / KMP, Promoter, Other. | | `RewardPoints` | Reward Points | Decimal | | Declared on the account master but written and read by nothing in the platform - loyalty accrual lives on the scheme ledger, not here. Any value present arrived from an import or manual entry. | | `Salutation` | Salutation | PickList | | Values: Ms., Dr., Prof., Mx.. | | `ShippingAddress` | Shipping Address | Text | | | | `ShippingCity` | Shipping City | PickList | | Values: Mumbai, Pune, Chandigarh, Mohali. | | `ShippingCityPlaceId` | Shipping City | Lookup → [Place](/docs/reference/entities/place/) | | | | `ShippingCountry` | Shipping Country | PickList | | Values: India. | | `ShippingPostalCode` | Shipping Postal Code | Text | | | | `ShippingRegion` | Shipping Region | Text | | | | `ShippingState` | Shipping State | PickList | | Values: Haryana, Maharashtra, New Delhi, Punjab. | | `ShippingStreet` | Shipping Street | Text | | | | `Sic` | Sic | Text | | | | `SicDesc` | SIC Description | Text | | The industry classification code itself is held in Sic. | | `Site` | Account Site | Text | | | | `Status` | Status | PickList | | An informational lifecycle value (Draft, Created, Pending Approval, Approved, Rejected), changed with Set Status. No approval process reads it; use Active to stop an account being used. Values: Draft, Created, Pending Approval, Approved, Rejected. | | `TAN` | TAN | Text | | | | `TdsApplicable` | TDS Applicable | Boolean | | Labelled TDS Applicable: off means this party is exempt from tax withholding. | | `TickerSymbol` | TickerSymbol | Text | | | | `Tradestyle` | Tradestyle | Text | | A trading-as name has to go in Label or Site. | | `Type` | Account Type | PickList | | Labelled Account Type: a commercial classification for reporting. The shipped active value is Customer - Direct, the default. It does not switch the customer, supplier or partner role on or off. Values: Customer - Direct. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `Website` | Website | Text | | | | `YearStarted` | Year Started | Text | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Clone | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInList` | Edit | EditInline | Edit in List Header | | `EditPopup` | Edit | Edit | Edit | | `FindDuplicates` | Find Duplicates | ServerAction (`FindDuplicates`), hidden | Finds records that may be duplicates of this account via the shared record-merge engine's duplicate detection; read-only, typically run before Merge. | | `FindMerged` | Merged Records | ServerAction (`FindMerged`), hidden | Lists the accounts that were previously merged into this one, via the shared record-merge engine's history. Read-only and hidden by default; useful for explaining why a duplicate account can no longer be found under its own name. | | `Merge` | Merge | ServerAction (`Merge`) | Merges duplicate accounts into this surviving master via the generic record-merge engine (IRecordMergeService) - the same entity-agnostic Merge that cases use; despite the seeded description mentioning cases, on Account it merges accounts. | | `New` | New | New | New | | `SetStatus` | Set Status | ServerAction (`SetStatus`) | Opens the status form for the account. The server side does not change the status: the handler only reads an optional notify flag from the arguments and returns it, so whatever the status ends up as was written by the form's own field binding, not by this action. | | `SetStatusBulk` | SetStatus | ServerAction (`SetStatus`) | The list-header variant of the status action, requiring a selection. It dispatches to the same server handler, which performs no status change of its own - so on a bulk selection with no form behind it, nothing is updated. | | `SetStatusLine` | Set Status Line | ServerAction (`SetStatus`) | The row-level variant of the status action, opening the same status form from a list row and dispatching to the same server handler, which performs no status change itself. | | `UIAction` | UI Action | UIAction | UI Action | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Last Name Mandatory for Customer Account Validation | `LastName`, Error, inactive | Last Name is mandatory for Customer Accounts. | Last name is mandatory for customer account. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Place](/docs/reference/entities/place/) — looks up via `ShippingCityPlaceId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — looks up via `PartnerAccountId` - [TdsSection](/docs/reference/entities/tds-section/) — looks up via `DefaultTdsSectionId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerOwnerAccountId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — looks up via `SupplierAccountId` - [Contact](/docs/reference/entities/contact/) — looks up via `AccountContactId` - [Account](/docs/reference/entities/account/) — looks up via `ParentId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — looks up via `AccountId` - [Place](/docs/reference/entities/place/) — looks up via `BillingCityPlaceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [BranchPostalCode](/docs/reference/entities/branch-postal-code/) — referenced by via `PartnerAccountId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `SupplierPartnerAccountId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — referenced by via `PartnerAccountId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `PartnerAccountId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — referenced by via `PartnerAccountId` - [ReconciliationMatch](/docs/reference/entities/reconciliation-match/) — referenced by via `PartnerAccountId` - [PayrollPeriod](/docs/reference/entities/payroll-period/) — referenced by via `PartnerAccountId` - [VisitPlan](/docs/reference/entities/visit-plan/) — referenced by via `PartnerAccountId` - [Bill](/docs/reference/entities/bill/) — referenced by via `SupplierAccountId` - [ChequeTransaction](/docs/reference/entities/cheque-transaction/) — referenced by via `PartyAccountId` - [SettlementAllocation](/docs/reference/entities/settlement-allocation/) — referenced by via `PartnerAccountId` - [JournalLine](/docs/reference/entities/journal-line/) — referenced by via `PartyAccountId` - [PeriodClose](/docs/reference/entities/period-close/) — referenced by via `PartnerAccountId` - [Shipment](/docs/reference/entities/shipment/) — referenced by via `PartnerAccountId` - [Claim](/docs/reference/entities/claim/) — referenced by via `SupplierAccountId` - [KPIData](/docs/reference/entities/kpidata/) — referenced by via `PartnerAccountId` - [PartyPeriodBalance](/docs/reference/entities/party-period-balance/) — referenced by via `PartnerAccountId` - [InventoryValuationPolicy](/docs/reference/entities/inventory-valuation-policy/) — referenced by via `PartnerAccountId` - [ProfessionalTaxSlab](/docs/reference/entities/professional-tax-slab/) — referenced by via `PartnerAccountId` - [PayrollComponent](/docs/reference/entities/payroll-component/) — referenced by via `PartnerAccountId` - [ItemCart](/docs/reference/entities/item-cart/) — referenced by via `AccountId` - [ClaimReconciliation](/docs/reference/entities/claim-reconciliation/) — referenced by via `SupplierAccountId` - [CurrencyRevaluationLine](/docs/reference/entities/currency-revaluation-line/) — referenced by via `PartyAccountId` - [AutoOrder](/docs/reference/entities/auto-order/) — referenced by via `PartnerAccountId` - [BankReconciliationLine](/docs/reference/entities/bank-reconciliation-line/) — referenced by via `PartnerAccountId` - [DiscountGroup](/docs/reference/entities/discount-group/) — referenced by via `PartnerAccountId` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `SupplierAccountId` - [SchemeAccountBudget](/docs/reference/entities/scheme-account-budget/) — referenced by via `PartnerAccountId` - [Grade](/docs/reference/entities/grade/) — referenced by via `PartnerAccountId` - [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) — referenced by via `PartnerAccountId` - [InventoryOpeningLotState](/docs/reference/entities/inventory-opening-lot-state/) — referenced by via `PartnerAccountId` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — referenced by via `AccountId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `PartyAccountId` - [RecurringDepreciation](/docs/reference/entities/recurring-depreciation/) — referenced by via `PartnerAccountId` - [SubscriptionUsage](/docs/reference/entities/subscription-usage/) — referenced by via `AccountId` - [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) — referenced by via `PartnerAccountId` - [Quote](/docs/reference/entities/quote/) — referenced by via `AccountId` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `AccountId` - [ProductCatalogue](/docs/reference/entities/product-catalogue/) — referenced by via `PartnerAccountId` - [ITCLedger](/docs/reference/entities/itcledger/) — referenced by via `PartnerAccountId` - [LWFRule](/docs/reference/entities/lwfrule/) — referenced by via `PartnerAccountId` - [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) — referenced by via `AccountId` - [PayrollPaymentBatchLine](/docs/reference/entities/payroll-payment-batch-line/) — referenced by via `PartnerAccountId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — referenced by via `PartnerAccountId` - [ConsolidationGroup](/docs/reference/entities/consolidation-group/) — referenced by via `PartnerAccountId` - [Holiday](/docs/reference/entities/holiday/) — referenced by via `PartnerAccountId` - [Asset](/docs/reference/entities/asset/) — referenced by via `AssetServicedByAccountId` - [Payment](/docs/reference/entities/payment/) — referenced by via `AccountId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `PartnerAccountId` - [PostingDefinition](/docs/reference/entities/posting-definition/) — referenced by via `SupplierAccountId` - [FinanceCase](/docs/reference/entities/finance-case/) — referenced by via `AccountId` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — referenced by via `PartnerAccountId` - [Requisition](/docs/reference/entities/requisition/) — referenced by via `SupplierAccountId` - [AccountBalance](/docs/reference/entities/account-balance/) — referenced by via `AccountId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `SupplierAccountId` - [CampaignMember](/docs/reference/entities/campaign-member/) — referenced by via `PartnerAccountId` - [Store](/docs/reference/entities/store/) — referenced by via `PartnerAccountId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `PartnerAccountId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `AccountId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `AccountId` - [TdsCertificate](/docs/reference/entities/tds-certificate/) — referenced by via `PartyAccountId` - [LandedCost](/docs/reference/entities/landed-cost/) — referenced by via `PartnerAccountId` - [FiscalYear](/docs/reference/entities/fiscal-year/) — referenced by via `PartnerAccountId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `AccountId` - [BankingTransaction](/docs/reference/entities/banking-transaction/) — referenced by via `AccountId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — referenced by via `PartnerAccountId` - [Asset](/docs/reference/entities/asset/) — referenced by via `SellingPartnerAccountId` - [PartyPeriodBalance](/docs/reference/entities/party-period-balance/) — referenced by via `PartyAccountId` - [Visit](/docs/reference/entities/visit/) — referenced by via `AccountId` - [VisitRouteGroup](/docs/reference/entities/visit-route-group/) — referenced by via `PartnerAccountId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — referenced by via `BillingAccountId` - [Employee](/docs/reference/entities/employee/) — referenced by via `PartnerAccountId` - [TdsReturnDeducteeLine](/docs/reference/entities/tds-return-deductee-line/) — referenced by via `PartyAccountId` - [PostingDefinition](/docs/reference/entities/posting-definition/) — referenced by via `AccountId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `PartnerAccountId` - [ItemConsumptionSchedule](/docs/reference/entities/item-consumption-schedule/) — referenced by via `CustomerAccountId` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — referenced by via `PartyAccountId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `RelatedPartnerAccountId` - [ContractLine](/docs/reference/entities/contract-line/) — referenced by via `ShipToAccountId` - [Journal](/docs/reference/entities/journal/) — referenced by via `PartnerAccountId` - [CompanyCardReconciliation](/docs/reference/entities/company-card-reconciliation/) — referenced by via `PartnerAccountId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `PartnerAccountId` - [Lead](/docs/reference/entities/lead/) — referenced by via `AccountId` - [Asset](/docs/reference/entities/asset/) — referenced by via `LastServicePartnerAccountId` - [RevenueRecognitionSchedule](/docs/reference/entities/revenue-recognition-schedule/) — referenced by via `PartnerAccountId` - [InventoryCostConsumption](/docs/reference/entities/inventory-cost-consumption/) — referenced by via `PartnerAccountId` - [VisitRouteStop](/docs/reference/entities/visit-route-stop/) — referenced by via `AccountId` - [ClaimBatch](/docs/reference/entities/claim-batch/) — referenced by via `SupplierAccountId` - [Account](/docs/reference/entities/account/) — referenced by via `PartnerOwnerAccountId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `PartnerAccountId` - [BankAccount](/docs/reference/entities/bank-account/) — referenced by via `PartnerAccountId` - [Employee](/docs/reference/entities/employee/) — referenced by via `PayrollCompanyId` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `PartnerAccountId` - [Scheme](/docs/reference/entities/scheme/) — referenced by via `AccountId` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `ToPartnerAccountId` - [Payment](/docs/reference/entities/payment/) — referenced by via `PartnerAccountId` - [CostCenter](/docs/reference/entities/cost-center/) — referenced by via `PartnerAccountId` - [PFRule](/docs/reference/entities/pfrule/) — referenced by via `PartnerAccountId` - [Payslip](/docs/reference/entities/payslip/) — referenced by via `PartnerAccountId` - [ItemComponent](/docs/reference/entities/item-component/) — referenced by via `PartnerAccountId` - [ContactAddress](/docs/reference/entities/contact-address/) — referenced by via `AccountId` - [RevenueRecognitionScheduleLine](/docs/reference/entities/revenue-recognition-schedule-line/) — referenced by via `PartnerAccountId` - [TaxGroup](/docs/reference/entities/tax-group/) — referenced by via `PartnerAccountId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `PartnerAccountId` - [InventoryNrvAssessment](/docs/reference/entities/inventory-nrv-assessment/) — referenced by via `PartnerAccountId` - [ExpensePolicyRule](/docs/reference/entities/expense-policy-rule/) — referenced by via `PartnerAccountId` - [BankTransfer](/docs/reference/entities/bank-transfer/) — referenced by via `PartnerAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — referenced by via `PartnerAccountId` - [FinanceCase](/docs/reference/entities/finance-case/) — referenced by via `PartnerAccountId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `AccountId` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — referenced by via `PartnerAccountId` - [RecurringJournal](/docs/reference/entities/recurring-journal/) — referenced by via `PartnerAccountId` - [ItemAlias](/docs/reference/entities/item-alias/) — referenced by via `AccountId` - [KPIData](/docs/reference/entities/kpidata/) — referenced by via `AccountId` - [Compensation](/docs/reference/entities/compensation/) — referenced by via `PartnerAccountId` - [Requisition](/docs/reference/entities/requisition/) — referenced by via `PartnerAccountId` - [GSTRegistration](/docs/reference/entities/gstregistration/) — referenced by via `PartnerAccountId` - [TaxDeclaration](/docs/reference/entities/tax-declaration/) — referenced by via `PartnerAccountId` - [PMTask](/docs/reference/entities/pmtask/) — referenced by via `PartnerAccountId` - [BusinessUnit](/docs/reference/entities/business-unit/) — referenced by via `PartnerAccountId` - [TdsChallanAllocation](/docs/reference/entities/tds-challan-allocation/) — referenced by via `PartnerAccountId` - [CycleCount](/docs/reference/entities/cycle-count/) — referenced by via `PartnerAccountId` - [SalaryTaxSlab](/docs/reference/entities/salary-tax-slab/) — referenced by via `PartnerAccountId` - [PayrollAdjustment](/docs/reference/entities/payroll-adjustment/) — referenced by via `PartnerAccountId` - [CurrencyRevaluationLine](/docs/reference/entities/currency-revaluation-line/) — referenced by via `PartnerAccountId` - [Order](/docs/reference/entities/order/) — referenced by via `SupplierAccountId` - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — referenced by via `PartnerAccountId` - [Account](/docs/reference/entities/account/) — referenced by via `ParentId` - [CheckInInspection](/docs/reference/entities/check-in-inspection/) — referenced by via `AccountId` - [PayrollRunComponentLine](/docs/reference/entities/payroll-run-component-line/) — referenced by via `PartnerAccountId` - [BankReconciliation](/docs/reference/entities/bank-reconciliation/) — referenced by via `PartnerAccountId` - [EInvoice](/docs/reference/entities/einvoice/) — referenced by via `PartnerAccountId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — referenced by via `PartnerAccountId` - [TdsCertificate](/docs/reference/entities/tds-certificate/) — referenced by via `PartnerAccountId` - [RecurringJournalLine](/docs/reference/entities/recurring-journal-line/) — referenced by via `PartnerAccountId` - [Lead](/docs/reference/entities/lead/) — referenced by via `PartnerAccountId` - [ClaimGenerationSetup](/docs/reference/entities/claim-generation-setup/) — referenced by via `SupplierAccountId` - [ChequeRegister](/docs/reference/entities/cheque-register/) — referenced by via `PartnerAccountId` - [ItemAlias](/docs/reference/entities/item-alias/) — referenced by via `PartnerAccountId` - [ShipmentAssetLine](/docs/reference/entities/shipment-asset-line/) — referenced by via `SellingPartnerAccountId` - [ItemLot](/docs/reference/entities/item-lot/) — referenced by via `PartnerAccountId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `AccountId` - [Adjustment](/docs/reference/entities/adjustment/) — referenced by via `PartnerAccountId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — referenced by via `PartnerAccountId` - [LandedCostLine](/docs/reference/entities/landed-cost-line/) — referenced by via `PartnerAccountId` - [ExpenseReimbursementBatch](/docs/reference/entities/expense-reimbursement-batch/) — referenced by via `PartnerAccountId` - [ItemConsumptionSchedule](/docs/reference/entities/item-consumption-schedule/) — referenced by via `PartnerAccountId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — referenced by via `SupplierAccountId` - [PaymentBatchLine](/docs/reference/entities/payment-batch-line/) — referenced by via `PartyAccountId` - [ExpenseCategory](/docs/reference/entities/expense-category/) — referenced by via `PartnerAccountId` - [Item](/docs/reference/entities/item/) — referenced by via `ClaimToAccountId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `AccountId` - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — referenced by via `PartyAccountId` - [ItemInventoryAttribute](/docs/reference/entities/item-inventory-attribute/) — referenced by via `PartnerAccountId` - [AccountBalance](/docs/reference/entities/account-balance/) — referenced by via `PartnerAccountId` - [RecurringJournalLine](/docs/reference/entities/recurring-journal-line/) — referenced by via `PartyAccountId` - [BankingTransaction](/docs/reference/entities/banking-transaction/) — referenced by via `PartnerAccountId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `SupplierAccountId` - [ClaimBatch](/docs/reference/entities/claim-batch/) — referenced by via `PartnerAccountId` - [PaymentAdjustment](/docs/reference/entities/payment-adjustment/) — referenced by via `PartnerAccountId` - [ChequeTransaction](/docs/reference/entities/cheque-transaction/) — referenced by via `PartnerAccountId` - [PayrollRun](/docs/reference/entities/payroll-run/) — referenced by via `PartnerAccountId` - [FullAndFinalSettlementLine](/docs/reference/entities/full-and-final-settlement-line/) — referenced by via `PartnerAccountId` - [ProspectPlace](/docs/reference/entities/prospect-place/) — referenced by via `OnboardedAccountId` - [Bill](/docs/reference/entities/bill/) — referenced by via `PartnerAccountId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `PartnerAccountId` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — referenced by via `PartnerAccountId` - [LowerDeductionCertificate](/docs/reference/entities/lower-deduction-certificate/) — referenced by via `PartnerAccountId` - [SchemeConsumption](/docs/reference/entities/scheme-consumption/) — referenced by via `PartnerAccountId` - [ContractLine](/docs/reference/entities/contract-line/) — referenced by via `AccountId` - [Scheme](/docs/reference/entities/scheme/) — referenced by via `PartnerAccountId` - [PostingDefinition](/docs/reference/entities/posting-definition/) — referenced by via `PartnerAccountId` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — referenced by via `CustomerAccountId` - [Asset](/docs/reference/entities/asset/) — referenced by via `AccountId` - [Order](/docs/reference/entities/order/) — referenced by via `PartnerAccountId` - [BookValuationAdjustment](/docs/reference/entities/book-valuation-adjustment/) — referenced by via `PartnerAccountId` - [ExpensePolicyViolation](/docs/reference/entities/expense-policy-violation/) — referenced by via `PartnerAccountId` - [Scheme](/docs/reference/entities/scheme/) — referenced by via `SupplierAccountId` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — referenced by via `PartnerAccountId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `AccountId` - [Order](/docs/reference/entities/order/) — referenced by via `AccountId` - [Quote](/docs/reference/entities/quote/) — referenced by via `PartnerAccountId` - [ExpenseAdvanceSettlement](/docs/reference/entities/expense-advance-settlement/) — referenced by via `PartnerAccountId` - [PostingErrorLog](/docs/reference/entities/posting-error-log/) — referenced by via `PartnerAccountId` - [LoanAdvanceRecovery](/docs/reference/entities/loan-advance-recovery/) — referenced by via `PartnerAccountId` - [MonthlyTdsProjection](/docs/reference/entities/monthly-tds-projection/) — referenced by via `PartnerAccountId` - [TdsReturn](/docs/reference/entities/tds-return/) — referenced by via `PartnerAccountId` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — referenced by via `PartnerAccountId` - [Case](/docs/reference/entities/case/) — referenced by via `AccountId` - [AccountGroupMember](/docs/reference/entities/account-group-member/) — referenced by via `AccountId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `PartnerAccountId` - [Resource](/docs/reference/entities/resource/) — referenced by via `DefaultPartnerAccountId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — referenced by via `AccountId` - [ClaimReconciliation](/docs/reference/entities/claim-reconciliation/) — referenced by via `PartnerAccountId` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — referenced by via `BillingAccountId` - [ContractLine](/docs/reference/entities/contract-line/) — referenced by via `BillToAccountId` - [Visit](/docs/reference/entities/visit/) — referenced by via `PartnerAccountId` - [PeriodCloseCheck](/docs/reference/entities/period-close-check/) — referenced by via `PartnerAccountId` - [BudgetCommitment](/docs/reference/entities/budget-commitment/) — referenced by via `PartnerAccountId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — referenced by via `AccountId` - [Asset](/docs/reference/entities/asset/) — referenced by via `AssetProvidedAccountId` - [ESIRule](/docs/reference/entities/esirule/) — referenced by via `PartnerAccountId` - [VisitRoute](/docs/reference/entities/visit-route/) — referenced by via `PartnerAccountId` - [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) — referenced by via `PartnerAccountId` - [CreditLimit](/docs/reference/entities/credit-limit/) — referenced by via `PartnerAccountId` - [IncentiveResource](/docs/reference/entities/incentive-resource/) — referenced by via `PartnerAccountId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — referenced by via `PartnerAccountId` - [Currency](/docs/reference/entities/currency/) — referenced by via `PartnerAccountId` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `AccountId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `AccountId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `SupplierAccountId` - [Budget](/docs/reference/entities/budget/) — referenced by via `PartnerAccountId` - [GSTR6](/docs/reference/entities/gstr6/) — referenced by via `AccountId` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `PartnerAccountId` - [TdsChallan](/docs/reference/entities/tds-challan/) — referenced by via `PartnerAccountId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `PartnerAccountId` - [BudgetLine](/docs/reference/entities/budget-line/) — referenced by via `PartnerAccountId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `PartnerAccountId` - [PublishedStatement](/docs/reference/entities/published-statement/) — referenced by via `PartnerAccountId` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `PartnerAccountId` - [TaxTransaction](/docs/reference/entities/tax-transaction/) — referenced by via `PartyAccountId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `PartnerAccountId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `AccountId` - [EWayBill](/docs/reference/entities/eway-bill/) — referenced by via `PartnerAccountId` - [StoreDealer](/docs/reference/entities/store-dealer/) — referenced by via `PartnerAccountId` - [ExpenseReceipt](/docs/reference/entities/expense-receipt/) — referenced by via `PartnerAccountId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `AccountId` - [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) — referenced by via `PartnerAccountId` - [AccountingBook](/docs/reference/entities/accounting-book/) — referenced by via `PartnerAccountId` - [Claim](/docs/reference/entities/claim/) — referenced by via `PartnerAccountId` - [Project](/docs/reference/entities/project/) — referenced by via `PartnerAccountId` - [Contact](/docs/reference/entities/contact/) — referenced by via `AccountId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `PartnerAccountId` - [AssetBlock](/docs/reference/entities/asset-block/) — referenced by via `PartnerAccountId` - [LowerDeductionCertificate](/docs/reference/entities/lower-deduction-certificate/) — referenced by via `PartyAccountId` - [BankingTransaction](/docs/reference/entities/banking-transaction/) — referenced by via `SupplierAccountId` - [ExpensePolicy](/docs/reference/entities/expense-policy/) — referenced by via `PartnerAccountId` - [TaxDeclarationLine](/docs/reference/entities/tax-declaration-line/) — referenced by via `PartnerAccountId` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `PartnerAccountId` - [RevenueRecognitionSchedule](/docs/reference/entities/revenue-recognition-schedule/) — referenced by via `PartyAccountId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `PartnerAccountId` - [CampaignMember](/docs/reference/entities/campaign-member/) — referenced by via `AccountId` - [ExpenseReimbursementBatchLine](/docs/reference/entities/expense-reimbursement-batch-line/) — referenced by via `PartnerAccountId` - [ShelfAuditResult](/docs/reference/entities/shelf-audit-result/) — referenced by via `AccountId` - [Shipment](/docs/reference/entities/shipment/) — referenced by via `SupplierAccountId` - [Contract](/docs/reference/entities/contract/) — referenced by via `AccountId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — referenced by via `AccountId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `EmployeeAccountId` - [TaxTransaction](/docs/reference/entities/tax-transaction/) — referenced by via `PartnerAccountId` - [DebitNote](/docs/reference/entities/debit-note/) — referenced by via `AccountId` - [AutoOrder](/docs/reference/entities/auto-order/) — referenced by via `SupplierAccountId` - [PartnerResource](/docs/reference/entities/partner-resource/) — referenced by via `PartnerAccountId` - [Project](/docs/reference/entities/project/) — referenced by via `CustomerAccountId` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `AccountId` - [CheckInInspection](/docs/reference/entities/check-in-inspection/) — referenced by via `PartnerAccountId` - [CreditLimit](/docs/reference/entities/credit-limit/) — referenced by via `AccountId` - [AssetDisposal](/docs/reference/entities/asset-disposal/) — referenced by via `PartnerAccountId` - [PaymentBatch](/docs/reference/entities/payment-batch/) — referenced by via `PartnerAccountId` - [PurchaseOrderRequisition](/docs/reference/entities/purchase-order-requisition/) — referenced by via `PartnerAccountId` - [ItemFeature](/docs/reference/entities/item-feature/) — referenced by via `PartnerAccountId` - [Campaign](/docs/reference/entities/campaign/) — referenced by via `PartnerAccountId` - [PaymentBatchLine](/docs/reference/entities/payment-batch-line/) — referenced by via `PartnerAccountId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — referenced by via `SupplierAccountId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `PartnerAccountId` - [CurrencyRevaluation](/docs/reference/entities/currency-revaluation/) — referenced by via `PartnerAccountId` - [ExchangeRate](/docs/reference/entities/exchange-rate/) — referenced by via `PartnerAccountId` - [Branch](/docs/reference/entities/branch/) — referenced by via `PartnerAccountId` - [GLAccountPeriodBalance](/docs/reference/entities/glaccount-period-balance/) — referenced by via `PartnerAccountId` - [CompanyCard](/docs/reference/entities/company-card/) — referenced by via `PartnerAccountId` - [FinancialStatementLayout](/docs/reference/entities/financial-statement-layout/) — referenced by via `PartnerAccountId` - [PriceList](/docs/reference/entities/price-list/) — referenced by via `PartnerAccountId` - [Planogram](/docs/reference/entities/planogram/) — referenced by via `AccountId` - [SchemeConsumption](/docs/reference/entities/scheme-consumption/) — referenced by via `AccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Accounting Book — entity reference URL: https://xmatix.com/docs/reference/entities/accounting-book/ Last reviewed: 2026-08-16 A parallel valuation perspective for a company — statutory, tax or management — under a named accounting framework. Exactly one book per company is primary: that is the real general ledger the statements post to, while the other books reuse the same ledger and layer a per-book valuation overlay on top rather than keeping a separate set of journals. The book is where a company opts in to cost-flow methods that need explicit acknowledgement, such as last-in-first-out or standard cost in a statutory book, and inventory valuation policies attach to it. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AllowsLifo` | Allows Lifo | Boolean | | An explicit opt-in to last-in-first-out inventory costing for this book, meaningful only outside a statutory framework that forbids it. It exists as a deliberate switch so the choice is a recorded decision rather than a side effect of a valuation policy. | | `AllowsStandardCost` | Allows Standard Cost | Boolean | | An explicit opt-in to standard costing inside a statutory book, acknowledging that the standard has to be trued up to actual cost at period end. Leaving it off is what prevents a valuation policy from quietly using standard cost in the filed accounts. | | `BookType` | Book Type | Text | | Statutory, Tax or Management. The statutory book is the one whose figures are the filed accounts; the other two reuse the same general ledger and differ only through a valuation overlay, so they are perspectives rather than separate sets of journals. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `CurrencyId` | Currency | Lookup → [Currency](/docs/reference/entities/currency/) | | | | `Description` | Description | Text | | | | `GaapFramework` | Gaap Framework | Text | | The reporting framework the book presents under, one of the Indian, international or US standards. It governs which cost-flow methods are acceptable, which is why the last-in-first-out and standard-cost opt-ins exist as explicit switches alongside it. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `IsPrimary` | Is Primary | Boolean | | Exactly one book per company is primary, and that book is the real general ledger the statements post to. Non-primary books do not hold their own journals — they are the primary ledger plus a per-book valuation overlay. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company (legal entity) the book belongs to, following the finance convention that the partner account is the company. Books are per company, and the primary-book rule applies within one company, not across the tenant. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete record | | `DeleteInList` | Delete | Delete | Delete record from the list | | `Edit` | Edit | Edit | Edit record | | `EditInLine` | Edit | EditInline | Edit record inline | | `EditListRow` | Edit | Edit | Edit record from the list | | `New` | New | New | Create a new record | ## Related entities - [Currency](/docs/reference/entities/currency/) — looks up via `CurrencyId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) — referenced by via `AccountingBookId` - [InventoryValuationPolicy](/docs/reference/entities/inventory-valuation-policy/) — referenced by via `AccountingBookId` - [InventoryOpeningLotState](/docs/reference/entities/inventory-opening-lot-state/) — referenced by via `AccountingBookId` - [InventoryNrvAssessment](/docs/reference/entities/inventory-nrv-assessment/) — referenced by via `AccountingBookId` - [BookValuationAdjustment](/docs/reference/entities/book-valuation-adjustment/) — referenced by via `AccountingBookId` - [InventoryCostConsumption](/docs/reference/entities/inventory-cost-consumption/) — referenced by via `AccountingBookId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Adjustment Line — entity reference URL: https://xmatix.com/docs/reference/entities/adjustment-line/ Last reviewed: 2026-08-16 One item-level stock change on an adjustment, for one lot, SKU and storage location. AdjustmentType selects both the quantity semantics and the InventoryStock bucket via seeded InventoryLedgerSetting rules: a null type is a plain adjustment whose signed Quantity increments the Adjustment bucket when positive and the AdjustedOut bucket when negative; typed lines (Expired, Damaged, Shortage, Excess, OnHold, OnLoan, Assemble, Disassemble) post to their named buckets, except that the Disassemble rule increments the Assemble bucket. Lines never post on creation - every seeded rule has OnCreate false - so posting happens through the header action or on later edits and deletes. Assemble and Disassemble lines additionally explode the item's bill of materials into child lines with the opposite type. Items with TrackInventory false are rejected and lot-tracked items require an ItemLotId. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AdjustmentId` | Inventory Adjustment | Lookup → [Adjustment](/docs/reference/entities/adjustment/) | Yes | | | `AdjustmentType` | Adjustment Type | PickList | | Values: Expired, Damaged, OnLoan, Shortage, Assemble, Excess, OnHold, Disassemble. | | `ClaimBatchId` | Claim Batch | Lookup → [ClaimBatch](/docs/reference/entities/claim-batch/) | | | | `ClaimId` | Claim | Lookup → [Claim](/docs/reference/entities/claim/) | | | | `ClaimLineId` | Claim Line | Lookup → [ClaimLine](/docs/reference/entities/claim-line/) | | The Part to Part claim line whose approved quantity this adjustment line writes back into stock. | | `ConversionRatio` | Conversion Ratio | Number | | | | `ConversionRatio1` | Conversion Ratio 1 | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CycleCountLineId` | Cycle Count Line | Lookup → [CycleCountLine](/docs/reference/entities/cycle-count-line/) | | Ties the adjustment line to the counted line that produced it: cycle-count release creates one line for the net discrepancy plus separate lines typed Damaged and Expired when those quantities were recorded. | | `DamagedQuantity` | Damaged Quantity | Calculated (calculated) | | Not an independently entered figure: it is calculated as the line Quantity when AdjustmentType is Damaged and zero otherwise. It exists so the seeded ledger rule for damaged stock has a field to test and post from, which is why entering a quantity here without setting the type has no effect. | | `ExcessQuantity` | Excess Quantity | Calculated (calculated) | | Calculated as the line Quantity when AdjustmentType is Excess and zero otherwise; it is the field the seeded excess ledger rule tests and posts from, not a separately captured quantity. | | `ExpiredQuantity` | Expired Quantity | Calculated (calculated) | | Calculated as the line Quantity when AdjustmentType is Expired and zero otherwise; it is the field the seeded expiry ledger rule tests and posts from, not a separately captured quantity. | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `ILPostingQuantity` | IL Posting Quantity | Calculated (calculated) | | The absolute value of the line quantity, calculated. It gives the ledger a non-negative magnitude to post with, while the direction of the movement is carried by the ledger type and the sign of Quantity. | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | Posted marker: inventory posting only picks up lines where this is still empty, then stamps the created ledger row's id here, which makes reposting idempotent. | | `IsILPosted` | IL Posted | Boolean | Yes | InventoryLedgerId is the field that actually records that the line reached the inventory ledger. | | `IsILPostingApproved` | IL Posting Approved | Boolean | Yes | | | `ItemComponentId` | Item Component | Lookup → [ItemComponent](/docs/reference/entities/item-component/) | | Set on the automatically generated component lines to record which bill-of-materials component the line represents. Generated lines take the opposite adjustment type to their parent and a negated quantity when the parent is an assembly, so the components are consumed as the assembly is built. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | Yes | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Line Number | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentLineId` | Parent Line | Lookup → [AdjustmentLine](/docs/reference/entities/adjustment-line/) | | Points at the Assemble or Disassemble line whose bill of materials was exploded to create this component line. Deleting the parent deletes its children, and only parent lines are user-entered. | | `PriceAsOnDate` | Price As On Date | Date | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `ShortageQuantity` | Shortage Quantity | Calculated (calculated) | | Calculated as the line Quantity when AdjustmentType is Shortage and zero otherwise; it is the field the seeded shortage ledger rule tests and posts from, not a separately captured quantity. | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `TotalCost` | Total Cost | Currency | | Derive the line's value from Quantity and UnitCost instead of reading it. | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | Defaulted from the matching price-list rule's price, because an adjustment line is treated as a cost line rather than a selling-price line; a value typed on a brand-new line is respected, but changing the header's price list or price date re-derives it. Lines released from a cycle count instead inherit the counted line's unit cost, which is usually zero. | | `UnitCost2` | Unit Cost 2 | Currency | | The secondary price from the same price-list rule that sets UnitCost. It is populated alongside it but nothing in the adjustment posting or valuation path consumes it. | | `UOM` | UOM | PickList | | Values: Pack, Litres. | | `UOM1` | UOM 1 | PickList | | Values: Each. | | `UOMQuantity` | UOM Quantity | Number | | | | `UOMQuantity1` | UOM Quantity 1 | Number | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `EditInLineEntity` | Edit | EditInline | Edit | | `New` | New | New | New | | `NewInLine` | Quick Add | NewInline | New | | `PostInventory` | Post Inventory | UIAction | Post from the parent document's Perform Inventory Posting, which picks up every line that has no InventoryLedgerId yet. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Item Required Validation | `ItemId`, Error | Selection of Item is Mandatory. | Selection of Item is Mandatory. | | Quantity Validation On Disassemble | Error, inactive | Quantity can not be positive in case of Disassemble Adjustment Type. | Quantity can not be positive in case of Disassemble Adjustment Type. | | Restrict Negative Quantity | `Quantity`, Error, inactive | Quantity must be greater than 0. | Quantity must be greater than 0. | | Total Cost Rule Validation | `TotalCost`, Error | Total Cost can't be negative | Total Cost can't be negative | | Unit Cost Rule Validation | `UnitCost`, Error, inactive | Unit Cost can't be negative | Unit Cost can't be negative | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Sku For Item | `SKUId` | | ## Related entities - [ItemComponent](/docs/reference/entities/item-component/) — looks up via `ItemComponentId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [ClaimBatch](/docs/reference/entities/claim-batch/) — looks up via `ClaimBatchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [CycleCountLine](/docs/reference/entities/cycle-count-line/) — looks up via `CycleCountLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ClaimLine](/docs/reference/entities/claim-line/) — looks up via `ClaimLineId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — looks up via `ParentLineId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Claim](/docs/reference/entities/claim/) — looks up via `ClaimId` - [Adjustment](/docs/reference/entities/adjustment/) — looks up via `AdjustmentId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `ParentLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Adjustment — entity reference URL: https://xmatix.com/docs/reference/entities/adjustment/ Last reviewed: 2026-08-16 An inventory adjustment document header for one branch and partner account; the item-level changes live on AdjustmentLine. It is created by users or generated from a CycleCount release, a Claim, or a ClaimBatch. Nothing posts when lines are created: stock moves only when the header action Perform Inventory Posting runs, or when a line's quantity or cost is later edited or the line deleted, which post reversals. This is the document that actually changes stock - a CycleCount only measures and then hands its variances to one of these. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | Yes | | | `ClaimBatchId` | Claim Batch | Lookup → [ClaimBatch](/docs/reference/entities/claim-batch/) | | Same claim-driven provenance as claimId, but for adjustments generated from a whole claim batch instead of a single claim. | | `ClaimId` | Claim | Lookup → [Claim](/docs/reference/entities/claim/) | | Provenance for adjustments auto-created from claims: a claim whose Part to Part lines have approved quantity spawns an adjustment linked here, with its lines pointing back via claimLineId. | | `ClaimReconciliationId` | Claim Reconciliation | Lookup → [ClaimReconciliation](/docs/reference/entities/claim-reconciliation/) | | Declared on the entity but not written or read by any first-party code path; adjustments generated from the claims flow are linked through ClaimId or ClaimBatchId instead. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | | | | `CycleCountId` | Cycle Count | Lookup → [CycleCount](/docs/reference/entities/cycle-count/) | | Set when the adjustment was released from a cycle count (PerformReleaseAdjustment). Partner and branch are copied from the count, and edits to them are then blocked as source-populated fields. | | `DocumentDate` | Document Date | Date | | Defaulted to the creation moment and locked afterwards - it is a non-editable key field alongside partner account and branch. | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `InterfaceJobQueueId` | Job Queue | Lookup → [InterfaceQueue](/docs/reference/entities/interface-queue/) | | Declared for an asynchronous posting or integration queue but not written or read by any first-party code path, so it never identifies a real queued job for an adjustment. | | `IsInJobQueue` | In Job Queue | Boolean | | Declared for an asynchronous posting queue but not written or read by any first-party code path; adjustment posting runs synchronously through the header server action. | | `IsInventoryPosted` | Inventory Posted | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | Yes | | | `PerformInventoryPosting` | Perform Inventory Posting | Calculated (calculated) | | A trigger flag that shares its name with the posting server action, but no code reads or clears it, so its value says nothing about whether the document posted. The reliable evidence of posting is InventoryLedgerId being set on the lines. | | `PriceAsOnDate` | Price As On Date | Date | | Changing it re-prices the document: the handler re-runs price-list rule resolution across all adjustment lines whenever this field is modified. | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | Defaulted on creation to the default Purchase price list; drives the unit costs applied when lines are re-priced. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `Status` | Status | PickList | | Values: Draft, Adjusted. | | `TotalQuantity` | TotalQuantity | Calculated (calculated) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditInList` | Edit | EditInline | Edit | | `EditInListRow` | Edit | Edit | Edit | | `New` | New | New | New | | `NewInLine` | New | NewInline, inactive | New In Line | | `PerformInventoryPosting` | Post Inventory | ServerAction (`PerformInventoryPosting`) | Perform Inventory Posting | | `PostAdjustment` | Post Adjustment | ServerAction (`PostAdjustment`) | Post Adjustment | | `UIAction` | UI Action | UIAction | UI Action | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Partner Acc | `BranchId` | | | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [ClaimBatch](/docs/reference/entities/claim-batch/) — looks up via `ClaimBatchId` - [CycleCount](/docs/reference/entities/cycle-count/) — looks up via `CycleCountId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [InterfaceQueue](/docs/reference/entities/interface-queue/) — looks up via `InterfaceJobQueueId` - [ClaimReconciliation](/docs/reference/entities/claim-reconciliation/) — looks up via `ClaimReconciliationId` - [Claim](/docs/reference/entities/claim/) — looks up via `ClaimId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [CycleCount](/docs/reference/entities/cycle-count/) — referenced by via `AdjustmentId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ParentRecordId` - [Campaign](/docs/reference/entities/campaign/) — referenced by via `AdjustmentId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `AdjustmentId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Asset Block — entity reference URL: https://xmatix.com/docs/reference/entities/asset-block/ Last reviewed: 2026-08-16 A pool of assets of one class and one depreciation rate under the Income-tax Act Section 32 block-of-assets scheme — the tax book, kept separate from the Companies Act book that RecurringDepreciation and the fixed-asset schedule maintain. The calculation engine depreciates opening written-down value plus additions minus deductions at the block rate, applying half the rate to additions put to use for fewer than 180 days in the year, with deductions applied against the full-rate pool first. Be aware of a real limitation: the stored row holds only the block rate and opening WDV, with no additions or deductions columns, so the Form 3CD Clause 18 comparison of tax versus book depreciation passes additions and deductions as zero and will understate any year with capital additions. Nothing here posts to the ledger — block depreciation is computed for disclosure, not journalised. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BlockCode` | Block Code | Text | | The Income-tax asset-class code for the pool, such as 04 or 07A. It is used to order and label the block in the Form 3CD depreciation disclosure, falling back to the block's label when left blank. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DepreciationRate` | Depreciation Rate | Currency | | The statutory block rate, held as a fraction rather than a percentage — enter 0.15 for fifteen percent. The Form 3CD builder defensively divides any value greater than one by a hundred, but the calculation engine itself rejects rates outside the open range between zero and one, and a block with an unusable rate is quietly skipped from the disclosure rather than aborting it. | | `FiscalYearId` | Fiscal Year | Lookup → [FiscalYear](/docs/reference/entities/fiscal-year/) | | The assessment year this block snapshot belongs to. Blocks are held one row per year rather than as a single running pool, and the tax-depreciation disclosure selects strictly on this column plus the company, so a block missing it never appears in the report. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | GL Account Name | Text, unique | Yes | The platform record-name key for the block. It carries the display label 'GL Account Name', which is misleading — an asset block has no link to the chart of accounts at all, since Income-tax block depreciation is computed for disclosure rather than journalised. | | `OpeningWdv` | Opening Wdv | Currency | | The pool's written-down value carried into the fiscal year, and the only monetary column on the block. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company the block belongs to. Together with the fiscal year it forms the pair the tax-depreciation disclosure filters on, so this must be the legal entity being audited and not a related party or vendor. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [FiscalYear](/docs/reference/entities/fiscal-year/) — looks up via `FiscalYearId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Asset Disposal — entity reference URL: https://xmatix.com/docs/reference/entities/asset-disposal/ Last reviewed: 2026-08-16 The retirement of an Asset — sale, scrap or donation — carrying the disposal proceeds and the cost/accumulated-depreciation snapshot used to work out gain or loss. It is not just a record: the PostDisposal server action (AssetDisposalHandler, backed by AssetDisposalService) posts a journal that reverses accumulated depreciation, removes the fixed-asset cost, books any proceeds and books gain or loss, then stamps IsGLPosted, GLId and GainLoss on the disposal and sets the linked Asset to Status 'Disposed' with NetBookValue zeroed. Posting demands a Fixed Asset GL account, an Accumulated Depreciation GL account, a Branch, a Partner Account and a PurchaseCost above zero — none of which are exposed as fields in the first-party metadata, so a disposal created purely through the metadata API or UI cannot be posted until those columns are populated another way. Note the docs/finance fixed-assets manuals still describe disposal as record-keeping only; that is out of date. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccumulatedDepreciation` | Accumulated Depreciation | Currency | | The depreciation taken on the asset up to the disposal date, snapshotted here. Posting debits this amount to the accumulated-depreciation GL account to reverse it, and skips that line entirely when the value is zero. | | `AccumulatedDepreciationGLAccountId` | Accumulated Depreciation GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | The asset being retired. Posting the disposal mutates this asset directly — setting its Status to 'Disposed', copying the disposal date and proceeds across, and zeroing its NetBookValue. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Branch the disposal posts under (auto-populated from the linked asset). | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Currency` | Currency | PickList | | | | `DisposalDate` | Disposal Date | Date | | | | `DisposalMethod` | Disposal Method | PickList | | How the asset left the business, seeded with Sale, Scrap and Donation. It describes the mechanism, whereas DisposalReason records why the asset was retired. Values: Sale, Scrap, Donation. | | `DisposalReason` | Disposal Reason | PickList | | Why the asset was retired, seeded with Damaged, Obsolete and Sold — the business justification, as distinct from the DisposalMethod by which it was disposed of. Values: Damaged, Obsolete, Sold. | | `DisposalValue` | Disposal Value | Currency | | The proceeds actually received for the asset. Posting books it to the proceeds GL account, but only when it is above zero and a proceeds account is set — a scrap or donation with no proceeds simply omits that line. | | `FixedAssetGLAccountId` | Fixed Asset GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `GainLoss` | Gain/Loss | Calculated (calculated) | | The profit or loss on retirement, defined as DisposalValue minus NetBookValue — positive is a gain, negative a loss. It is a calculated field, but AssetDisposalService also recomputes and overwrites it at posting time using the same expression, so the stored value after posting is the figure that was actually booked to the ledger. | | `GainLossGLAccountId` | Gain/Loss GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `GLId` | GL Journal | Lookup → [Journal](/docs/reference/entities/journal/) | | | | `Id` | Id | Guid | Yes | | | `IsGLPosted` | GL Posted | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NetBookValue` | Net Book Value | Currency | | The asset's carrying value at the moment of disposal, captured on this record rather than read live from the Asset. If it is left empty, AssetDisposalService falls back to PurchaseCost minus AccumulatedDepreciation when posting. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Company | Lookup → [Account](/docs/reference/entities/account/) | | | | `ProceedsGLAccountId` | Proceeds GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `PurchaseCost` | Purchase Cost | Currency | | The original acquisition cost of the asset, snapshotted onto the disposal. Posting requires it to be greater than zero and credits this amount to the fixed-asset GL account to remove the asset from the gross block. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Status` | Status | PickList | | The disposal's workflow state. The seeded picklist offers Draft, Pending Approval and Disposed, but AssetDisposalService writes the literal 'Posted' once the disposal has been journalised, and that value is not in the picklist. Treat 'Posted' as the terminal, ledger-confirmed state and do not assume the picklist is exhaustive. Values: Draft, Pending Approval, Disposed. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `Edit` | Edit | EditInline | Edit | | `EditEntity` | Edit | Edit | Edit | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | | `PostDisposal` | Post Disposal | ServerAction (`PostDisposal`) | Post Disposal | ## Related entities - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `ProceedsGLAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GainLossGLAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `FixedAssetGLAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `AccumulatedDepreciationGLAccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Asset Maintenance — entity reference URL: https://xmatix.com/docs/reference/entities/asset-maintenance/ Last reviewed: 2026-08-16 A single planned or executed maintenance job for an Asset — the unit that links an entitlement to the work that consumed it. It points at the governing ItemServiceContract, at the Campaign, CampaignItem and CampaignMember that scheduled it, and at the ServiceOrder and ServiceOrderLine it was executed under (those two lookups are labelled 'Executed Under Service Order' / 'Executed Under Service Order Line'). IsMandatory marks a job that must be done; IsExecuted marks one that has been. Use it to answer whether a given service on an asset is due, planned or already carried out. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IsExecuted` | Is Executed | Boolean | Yes | Marks that the maintenance job has actually been carried out, as opposed to merely being planned. Together with IsMandatory it distinguishes an outstanding obligation from completed work. | | `IsMandatory` | Is Mandatory | Boolean | Yes | Marks a job that must be performed rather than one offered optionally — typically a safety or warranty-condition service. It does not by itself schedule anything; it qualifies the obligation. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemServiceContractId` | Item Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | The service-contract template that entitles this maintenance job. It points at the ItemServiceContract template, not at the per-asset AssetServiceContract instance, so it tells you which product-level entitlement the job falls under. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `CampaignBatchInstanceId` | CampaignBatchInstance | LongMultiLineText | | An identifier grouping the maintenance records generated together in one campaign batch run. It is stored as free text rather than a lookup, so it groups records but does not resolve to a campaign entity — use CampaignId for that. | | `CampaignId` | Campaign | Lookup → [Campaign](/docs/reference/entities/campaign/) | | | | `CampaignItemId` | Campaign Item | Lookup → [CampaignItem](/docs/reference/entities/campaign-item/) | | | | `CampaignMemberId` | Campaign Member | Lookup → [CampaignMember](/docs/reference/entities/campaign-member/) | | The CampaignMember record — the campaign's enrolment of this particular asset — that produced this maintenance job. Distinct from CampaignItemId, which identifies the campaign's covered item rather than the enrolled asset. | | `ServiceOrderId` | Executed Under Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | The service order under which this maintenance was executed, labelled 'Executed Under Service Order'. It is the link to the work that discharged the job rather than the work that requested it. | | `ServiceOrderLineId` | Executed Under Service Order Line | Lookup → [ServiceOrderLine](/docs/reference/entities/service-order-line/) | | The specific service order line that carried out this maintenance, labelled 'Executed Under Service Order Line' — a finer-grained link than ServiceOrderId when one order covers several jobs. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `New` | New | NewInline | New | ## Related entities - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [CampaignItem](/docs/reference/entities/campaign-item/) — looks up via `CampaignItemId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — looks up via `ServiceOrderLineId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [CampaignMember](/docs/reference/entities/campaign-member/) — looks up via `CampaignMemberId` - [Campaign](/docs/reference/entities/campaign/) — looks up via `CampaignId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `AssetMaintenanceId` - [Lead](/docs/reference/entities/lead/) — referenced by via `AssetMaintenanceId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `AssetMaintenanceId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Asset Service Contract Line — entity reference URL: https://xmatix.com/docs/reference/entities/asset-service-contract-line/ Last reviewed: 2026-08-16 One covered component on an AssetServiceContract, with the entitled quantity and how much of it has been consumed. Quantity is the entitlement, UtilizedQuantity is what service orders have drawn, and PendingQuantity is a calculated field defined as Quantity minus UtilizedQuantity rather than a stored balance. Query this rather than the header when the question is which parts or labour items an asset's contract still covers. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AssetServiceContractId` | Asset Service Contract | Lookup → [AssetServiceContract](/docs/reference/entities/asset-service-contract/) | | | | `ComponentItemId` | Component Item | Lookup → [Item](/docs/reference/entities/item/) | | The part or labour item this line entitles the customer to under the contract. It is the covered component, not the product the contract was sold against — that is on the header. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PendingQuantity` | Pending Quantity | Calculated (calculated) | | The entitlement still available on this line, calculated as Quantity minus UtilizedQuantity rather than stored independently. It moves automatically as UtilizedQuantity changes, so writing to it directly is not meaningful. | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UtilizedQuantity` | Utilized Quantity | Number | | How much of this line's entitlement has already been drawn down by service orders. It is the stored counter that drives the calculated PendingQuantity. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — looks up via `AssetServiceContractId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Item](/docs/reference/entities/item/) — looks up via `ComponentItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `AssetServiceContractLineId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `AssetServiceContractLineId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `AssetServiceContractLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Asset Service Contract — entity reference URL: https://xmatix.com/docs/reference/entities/asset-service-contract/ Last reviewed: 2026-08-16 The per-asset instance of an entitlement whose terms come from an ItemServiceContract template — this is the record that says a specific Asset is actually covered. AssetServiceContractService matches one to a Service Order or Opportunity on AssetId plus ItemServiceContractId, skipping any contract already flagged IsUtilized, and treats it as lapsed when the document date is past ValidTillDate plus GraceUsageDays, when usage hours reach ValidTillHours plus GraceUsageHours, or when the usage reading reaches ValidTillUsageReading plus GraceUsageReading. Whether an active contract is mandatory is decided by the parent template's ActiveServiceContractRequired and IsScopeRestricted flags, and a template marked SingleUseContract fails a second use once IsUtilized is set. Its lines (AssetServiceContractLine) hold the covered components and the quantity drawn down so far. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ActivatedDate` | Activated Date | Date | | When the entitlement was activated and coverage began, which can be later than the record's creation date — a contract sold with an asset is often activated at installation. | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `BillingAccountId` | Billing Account | Lookup → [Account](/docs/reference/entities/account/) | | The account to bill for work carried out under this entitlement, which is frequently not the asset's owning account — for warranty work it is typically the manufacturer or the selling partner. | | `ContractPostingTreatment` | Contract Posting Treatment | Calculated | | Declared as a calculated field but the first-party seed ships no formula for it, so it resolves to nothing on this entity. The authoritative value lives on the governing ItemServiceContract template, where it is a real picklist of Generate Claims, Generate Invoices and Auto Generate Claims. Read it from the template, not from here. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `DueDate` | Due Date | Date | | When the next service under this contract falls due, as opposed to ValidTillDate which is when the entitlement expires altogether. Due tracking and expiry are separate axes here. | | `DueInHours` | Due In Hours | Number | | | | `DueOnUsageReading` | Due On Usage Reading | Number | | | | `ExternalId` | External | Text, unique | | | | `GraceUsageDays` | Grace Usage Days | Number | | Days of tolerance added to ValidTillDate before the contract is treated as lapsed. It extends the coverage window for matching purposes; it does not move the stated expiry date itself. | | `GraceUsageHours` | Grace Usage Hours | Number | | | | `GraceUsageReading` | Grace Usage Reading | Number | | | | `Id` | Id | Guid | Yes | | | `IsUtilized` | Is Utilized | Boolean | Yes | Marks the entitlement as consumed. Contract matching skips any contract with this set, and when the governing template is flagged SingleUseContract a second attempt to use it fails with 'This is a Single Use contract and has already been utilised'. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemServiceContractId` | Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | The ItemServiceContract template this per-asset contract was instantiated from — labelled simply 'Service Contract'. Contract matching keys on this together with AssetId, and the template's flags decide whether an active contract is required, scope-restricted or single-use. Do not confuse it with ServiceContractItemId, which points at an Item. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PopulateContractLines` | Populate Contract Lines | Boolean | | | | `PostingType` | Posting Type | Text | | How utilisation of this entitlement should be posted commercially. It is stored as free text on this record rather than as a picklist, unlike the template's ContractPostingTreatment which carries the seeded vocabulary. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ServiceContractItem` | Service Contract Item | Lookup → [Item](/docs/reference/entities/item/) | | A lookup-typed field with no relation defined and no counterpart on the domain class — every other lookup on this entity has an EntityRelation and this one does not. It duplicates the label of ServiceContractItemId, which is the field that actually resolves to an Item. Do not read, filter or set this field; use ServiceContractItemId. | | `ServiceContractItemId` | Service Contract Item | Lookup → [Item](/docs/reference/entities/item/) | | A lookup to the Item that represents the contract as a sellable product. Despite the similar label it is unrelated to ItemServiceContractId, which points at the ItemServiceContract template — this one resolves to an Item. | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | | | `ServiceType` | Service Type | Calculated | | Declared as a calculated field with no formula in the first-party seed, so it holds nothing here. The real value is the ItemServiceContract template's ServiceType picklist, seeded with Warranty Repairs and Paid Repairs. | | `SingleUseContract` | Single Use Contract | Calculated | | Declared as a calculated field with no formula in the first-party seed. The flag that is actually enforced is SingleUseContract on the governing ItemServiceContract template, which combines with this record's IsUtilized to block a second use. | | `Status` | Status | PickList | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `ValidTillDate` | Val Till Date | Date | | The calendar expiry of the entitlement. Lapse is judged against this date extended by GraceUsageDays, and the date compared is the document's failure date where one is given, otherwise the document date. | | `ValidTillHours` | Val Till Hours | Number | | The hour-meter ceiling of the entitlement. The contract is treated as lapsed once the service document's usage hours reach this value plus GraceUsageHours. | | `ValidTillUsageReading` | Val Till Usage Reading | Number | | The usage or distance ceiling of the entitlement. Exceeding this value plus GraceUsageReading lapses the contract and produces the failure 'KM reading exceeds service contract usage limit'. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [Account](/docs/reference/entities/account/) — looks up via `BillingAccountId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [Item](/docs/reference/entities/item/) — looks up via `ServiceContractItemId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `AssetServiceContractId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `AssetServiceContractId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `AssetServiceContractId` - [AssetServiceContractLine](/docs/reference/entities/asset-service-contract-line/) — referenced by via `AssetServiceContractId` - [ContractLineitem](/docs/reference/entities/contract-lineitem/) — referenced by via `AssetServiceContractId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `AssetServiceContractId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Asset — entity reference URL: https://xmatix.com/docs/reference/entities/asset/ Last reviewed: 2026-08-16 A tracked physical unit in the install base — the record the service module hangs warranty, maintenance, servicing history and depreciation off. Assets are normally created automatically rather than by hand: AssetService.CreateAssetsAsync runs off a sales Invoice and creates one Asset per InvoiceLine whose Item has TrackAsset set, which requires an ItemLot on the line (it raises 'Item lot is required to create tracked assets' otherwise) and names the asset from the lot's serial number. Lines that belong to a package line become child assets under the package's asset. Service execution writes back here — completing a ServiceOrder updates LastServiceDate, LastServiceBranchId and the last usage readings. The main children are AssetServiceContract (per-asset entitlements), AssetMaintenance (planned and executed jobs), AssetDisposal (retirement) and DepreciationPolicy. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer account that owns the asset. Keep it apart from the other three account lookups on this entity: AssetProvidedAccountId is who supplied it, AssetServicedByAccountId is who is contracted to service it, and SellingPartnerAccountId is the partner who sold it. | | `AssetCategory` | Asset Category | PickList | | Values: IT, Furniture, Office Equipment, Machinary. | | `AssetCode` | Asset Code | Text | | The business code identifying the unit. When an asset is created automatically from an invoice, AssetService fills it from the item lot's serial number, falling back to the lot's supplier invoice number — so it is often but not always the serial number, and SerialNumber remains the reliable field for that. | | `AssetCondition` | Asset Condition | Text | | | | `AssetId` | Root Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | A self-referencing lookup to the top of the asset hierarchy, labelled 'Root Asset'. Despite the name this is not the record's own identifier — that is Id — and confusing the two is an easy mistake on this entity. Use it together with ParentAssetId, which points only one level up, and AssetLevel, which records the depth. | | `AssetLevel` | Asset Level | Number | | The depth of this asset within its parent/child hierarchy, used with ParentAssetId and AssetId to distinguish a top-level unit from its sub-components. | | `AssetProvidedAccountId` | AssetProvedBy | Lookup → [Account](/docs/reference/entities/account/) | | The account that provided or supplied the asset, which need not be the owner in AccountId nor the seller in SellingPartnerAccountId. Its label is the abbreviated 'AssetProvedBy'. | | `AssetServicedByAccountId` | Asset Serviced By | Lookup → [Account](/docs/reference/entities/account/) | | The account contracted to service the asset on an ongoing basis. This is the standing servicing relationship and is distinct from LastServicePartnerAccountId, which is meant to record whoever actually performed the most recent job. | | `AssetSubCategory` | Asset Sub Category | PickList | | Values: LED TV, Tablet, Biometric Machine, Mobile Phone, CCTV Camera, Air Conditioner, Conference Table, Laptop, Desktop, Server, Printer, Scanner, Router, CNC Machines. | | `AverageUsage` | Average Usage | Decimal | | | | `AverageUsageHours` | Average Usage (Hours) | Decimal | | | | `BatchNo` | Batch No | Text, unique | | | | `BranchId` | Last Service Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch that owns or holds the asset. Warning: this field's label reads 'Last Service Branch', but it is not the branch of the most recent service — that is the separate LastServiceBranchId field, whose label confusingly reads 'Branch'. The two labels are transposed relative to the underlying model, and the service-order write-back in AssetService updates LastServiceBranchId, never this field. Select by field name, not by label. | | `CompetitorAsset` | Is Competitor Product | Boolean | | | | `ComponentNumber` | Component Number | Text | | | | `ConsequenceOfFailure` | Consequence Of Failure | PickList | | A criticality rating used to prioritise maintenance, seeded with Insignificant, Minor, Moderate, Major and Critical. It describes the impact if the asset fails, not its current condition — that is AssetCondition. Values: Insignificant, Minor, Moderate, Major, Critical. | | `ContactId` | Contact | Lookup → [Contact](/docs/reference/entities/contact/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrentAmount` | Current Amount | Currency | | | | `CurrentLifecycleEndDate` | Current Lifecycle End Date | Date | | | | `CurrentMrr` | Current Monthly Recurring Revenue | Currency | | | | `CurrentQuantity` | Current Quantity | Number | | | | `CurrentUsageReading` | Current Usage Reading | Decimal | | The asset's usage reading as currently known, distinct from LastUsageReading which is specifically the value captured at the last service. Contract-lapse checks in AssetServiceContractService are evaluated against the reading supplied on the service order or opportunity, not against this field. | | `CurrentUsageReadingHours` | Current Usage Reading (Hours) | Decimal | | | | `DepreciationMethod` | Depreciation Method | PickList | | The depreciation basis for this asset. The seeded picklist values are the display strings 'Straight Line' and 'WDV' (written-down value). Note the fixed-assets manuals and the finance engine's own constants use the different tokens StraightLine and WrittenDownValue, so a filter written from the manual will not match the values stored here. Values: Straight Line, WDV. | | `DepreciationPolicyId` | Depreciation Policy | Lookup → [DepreciationPolicy](/docs/reference/entities/depreciation-policy/) | | The category-level DepreciationPolicy template this asset follows. | | `Description` | Description | LongMultiLineText | | | | `DigitalAssetStatus` | Digital Asset Status | PickList | | The health signal reported by a connected or telemetry-enabled asset, seeded with On, Warning and Error. It reflects device telemetry and is independent of the commercial lifecycle held in Status. Values: On, Warning, Error. | | `DisposalDate` | Disposal Date | Date | | | | `DisposalValue` | Disposal Value | Currency | | | | `GoodsReceiptId` | Goods Receipt | Lookup → [GoodsReceipt](/docs/reference/entities/goods-receipt/) | | | | `Id` | Id | Guid | Yes | | | `InstallationAddressContactAddressId` | Installation Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `InstallDate` | Install Date | Date | | | | `InternalAsset` | Is Internal | Boolean | | Marks a unit the company owns and uses itself rather than one sold to a customer. This is the distinction that separates own-use fixed assets from customer install-base records held in the same table. | | `InUse` | In Use | Boolean | | | | `InvoiceId` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | The sales invoice the asset was created from, set by AssetService on the automatic creation path. It is the audit trail back to the sale, and it is also how the originating invoice line gets its AssetId stamped in return. | | `InvoiceNumber` | Invoice Number | Text | | | | `IsPDIDone` | Is PDI Done | Boolean | | Marks that pre-delivery inspection has been completed. It is set to false when the asset is auto-created from an invoice, and flipped to true in bulk by AssetService.MarkPdiDoneAsync, which is driven from the service orders that carry out the inspection. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | The inventory lot or serialised unit this asset was created from. It is mandatory on the automatic creation path: AssetService rejects asset creation for a tracked item whose invoice line has no item lot, and the lot supplies the asset's name, label and code. | | `Label` | Label | Text | | | | `LastServiceBranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch that performed the most recent service on the asset; AssetService.UpdateAssetFromServiceOrderAsync writes the service order's BranchId here on completion, and asset creation from an invoice seeds it with the invoice's branch. Its label reads 'Branch' while the unrelated BranchId field is labelled 'Last Service Branch' — the two labels are transposed, so match on field name. | | `LastServiceDate` | Last Service Date | Date | | The document date of the most recent completed service order for this asset, written back by AssetService when a service order is saved. On assets created from an invoice it is initially seeded with the invoice's document date rather than an actual service. | | `LastServicePartnerAccountId` | Last Service Partner | Lookup → [Account](/docs/reference/entities/account/) | | Intended to hold the partner account that last serviced the asset. Treat it as unreliable: the service-order write-back in AssetService writes to the name 'LastServicePartnerId', which is not a property of Asset, so the value lands in a custom field of that name rather than in this column. Only the asset-creation path from an invoice populates this field. If you need the last servicing partner, prefer the most recent related ServiceOrder over reading this. | | `LastUsageReading` | Last Usage Reading | Decimal | | The odometer-style usage counter captured at the last service, in the asset's distance or count unit. AssetService validates that a new service order's reading is not lower than this value and rejects the save with 'Usage Reading for the Asset seems incorrect' if it is. When a service order sets ResetUsageReading this field is zeroed and the pre-reset value is kept in UsageReadingResetAt, so it is a since-last-reset counter, not a lifetime total. | | `LastUsageReadingHours` | Last Usage Reading (Hours) | Decimal | | The hour-meter equivalent of LastUsageReading, captured at the last service. It is validated against decreases the same way, and is zeroed with the prior value moved to UsageHoursResetAt when a service order sets ResetUsageHours. | | `LifecycleEndDate` | Lifecycle End Date | DateAndTime | | | | `LifecycleManagedAsset` | Has Lifecycle Management | Boolean | | Marks an asset that is managed on a defined replacement lifecycle, which is what makes the LifecycleStartDate, LifecycleEndDate, CurrentLifecycleEndDate and TotalLifecycleAmount fields meaningful. Those lifecycle fields should be ignored when this flag is false. | | `LifecycleStartDate` | Lifecycle Start Date | Date | | | | `LotNumber` | Lot Number | Text | | | | `ManufactureDate` | Manufacture Date | Date | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `NetBookValue` | Net Book Value | Calculated | | The asset's carrying value. Unlike PurchaseCost and SalvageValue, which are stored currency amounts, this is declared as a calculated field — but the first-party seed ships no formula for it, so it holds nothing unless a tenant supplies one or a process writes it. AssetDisposalService does set it to zero when a disposal is posted. Do not rely on it as an authoritative book value. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentAssetId` | Parent Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | The immediate parent in the asset hierarchy, one level up, as distinct from AssetId which points at the root of the whole tree. AssetService sets it when an invoice line belongs to a package line, so the components of a sold package become children of the package's asset. | | `Phone` | Phone | Text | | | | `Price` | Price | Currency | | | | `ProductCode` | Product Code | Text | | | | `ProductDescription` | Product Description | Text | | | | `ProductFamily` | Product Family | PickList | | | | `ProductSKU` | Stock Keeping Unit | Text | | A free-text stock-keeping-unit code carried on the asset. It is not a reference to the SKU entity — that is the separate SKUId lookup — so joining on this text will not resolve a SKU record. | | `PurchaseCost` | Purchase Cost | Currency | | | | `PurchaseDate` | Purchase Date | DateAndTime | | | | `PutToUseDate` | Put To Use Date | Date | | The date the asset was placed into service, which is the date depreciation is meant to run from. It is deliberately separate from PurchaseDate (when it was bought) and InstallDate (when it was physically installed), and the three can legitimately differ. | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RegistrationDate` | Registration Date | DateAndTime | | | | `RegistrationNumber` | Registration Number | Text | | | | `SaleDate` | Sale Date | Date | | | | `SaleInvoiceNumber` | SaleInvoiceNumber | LongMultiLineText | | | | `SalvageValue` | Salvage Value | Currency | | The residual value the asset is expected to retain at the end of its useful life — the floor that depreciation writes down to, not a disposal proceeds figure. Actual proceeds are recorded in DisposalValue and on the AssetDisposal record. | | `SellingBranchId` | Selling Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `SellingPartnerAccountId` | Selling Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `SerialNumber` | Serial Number | Text | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | The lookup to the SKU record for this asset, populated from the originating invoice line when the asset is auto-created. Use this rather than the free-text ProductSKU field when you need the actual SKU. | | `Status` | Status | PickList | | The asset's lifecycle state. The seeded picklist offers Draft, Purchased, Installed and Obsolete. Be aware that AssetDisposalService writes the literal 'Disposed' here when a disposal is posted to the ledger, and that value is not in the picklist — so filtering on the picklist alone will miss retired assets. Values: Installed, Obsolete, Purchased, Draft. | | `StatusReason` | Status Reason | PickList | | A qualifier on the current Status, seeded with Paused, Not Ready and Off. It explains why an asset is not in service rather than restating the status itself. Values: Paused, Off. | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `SupplierInvoiceDate` | Supplier Invoice Date | Date | | | | `SupplierInvoiceNumber` | SupplierInvoiceNumber | LongMultiLineText | | | | `TestField` | TestField | LongMultiLineText | | | | `TotalLifecycleAmount` | Total Lifecycle Amount | Currency | | | | `UIProps` | UI Props | Text | | | | `UniqueIdentifier` | Uu | Text | | A tenant-defined unique identifier for the unit, separate from SerialNumber and RegistrationNumber. Its label is the truncated placeholder 'Uu', which carries no meaning — go by the field name. | | `UpdatedDateTime` | Modified Date | DateAndTime | | | | `UsageEndDate` | Usage End Date | Date | | | | `UsageHoursResetAt` | Usage Hours Reset At | Decimal | | The hour-meter value at the moment the hours counter was last reset, written when a service order sets ResetUsageHours and LastUsageReadingHours is zeroed. The hours counterpart of UsageReadingResetAt. | | `UsageReadingResetAt` | Usage Reading Reset At | Decimal | | The usage reading at the moment the counter was last reset — written by AssetService when a service order sets ResetUsageReading, at which point LastUsageReading goes to zero. Add this to LastUsageReading to reason about cumulative usage across a reset. | | `UsefulLife` | Useful Life | Number | | The expected life of the asset in years, used for depreciation. The platform ships indicative Companies Act Schedule II lives per asset class as reference data, but this field is the tenant's own override for the individual asset. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Delete2` | Delete | Delete | Delete | | `DeleteListHeader` | Delete | Delete | DeleteListHeader | | `Edit` | Edit | Edit | Edit | | `EditInLine` | EditInLine | EditInline | EditInLine | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | XM_DateOfSaleRuleValidation | `SaleDate`, Error | Date Of Sale cannot be before Manufacturing Date | Date Of Sale cannot be before Manufacturing Date | | XM_LastServiceDateRuleValidation | `LastServiceDate`, Error, inactive | Last Date cannot exceed Current Date | Last Date cannot exceed Current Date | | XM_LastUsageReadingValidation | `LastUsageReading`, Error | Usage Reading Cannot be Negative | Usage Reading Cannot be Negative | ## Related entities - [Contact](/docs/reference/entities/contact/) — looks up via `ContactId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [DepreciationPolicy](/docs/reference/entities/depreciation-policy/) — looks up via `DepreciationPolicyId` - [Account](/docs/reference/entities/account/) — looks up via `AssetServicedByAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `LastServiceBranchId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [Branch](/docs/reference/entities/branch/) — looks up via `SellingBranchId` - [Account](/docs/reference/entities/account/) — looks up via `SellingPartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `LastServicePartnerAccountId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `InstallationAddressContactAddressId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [Account](/docs/reference/entities/account/) — looks up via `AssetProvidedAccountId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — looks up via `GoodsReceiptId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Asset](/docs/reference/entities/asset/) — looks up via `ParentAssetId` - [Depreciation](/docs/reference/entities/depreciation/) — referenced by via `AssetId` - [ContractLineitem](/docs/reference/entities/contract-lineitem/) — referenced by via `AssetId` - [AssetDisposal](/docs/reference/entities/asset-disposal/) — referenced by via `AssetId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `AssetId` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `AssetId` - [CampaignMember](/docs/reference/entities/campaign-member/) — referenced by via `AssetId` - [PMTask](/docs/reference/entities/pmtask/) — referenced by via `Asset` - [Quote](/docs/reference/entities/quote/) — referenced by via `AssetId` - [DepreciationPolicy](/docs/reference/entities/depreciation-policy/) — referenced by via `AssetId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `AssetId` - [ShipmentAssetLine](/docs/reference/entities/shipment-asset-line/) — referenced by via `AssetId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `AssetId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `OriginalAssetId` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — referenced by via `AssetId` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — referenced by via `AssetId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `AssetId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `AssetId` - [Contract](/docs/reference/entities/contract/) — referenced by via `AssetId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `AssetId` - [SubscriptionUsage](/docs/reference/entities/subscription-usage/) — referenced by via `AssetId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `AssetId` - [Asset](/docs/reference/entities/asset/) — referenced by via `AssetId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `AssetId` - [Case](/docs/reference/entities/case/) — referenced by via `AssetId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `DemoAssetId` - [CheckInInspection](/docs/reference/entities/check-in-inspection/) — referenced by via `AssetId` - [Lead](/docs/reference/entities/lead/) — referenced by via `AssetId` - [Asset](/docs/reference/entities/asset/) — referenced by via `ParentAssetId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Auto Order — entity reference URL: https://xmatix.com/docs/reference/entities/auto-order/ Last reviewed: 2026-08-16 A replenishment-planning header that first proposes what to buy and then generates the purchase order from the accepted proposal. AutoOrderType is the discriminator the engine branches on, and only four values are implemented: 'Minimum Stock Level' and 'Replenish' build proposal lines from stock settings and recent allocations, 'Forecasting' runs the projected-stock reorder-point calculation with pipeline netting, and 'Template' is a reusable configuration that spawns a fresh dated Forecasting order rather than holding lines of its own. GenerateAutoOrderLines builds (and on re-run replaces) the proposal, then prices it and applies the BudgetAmount cap; PerformOrderGeneration or SelectiveOrderGeneration turns accepted lines into a PurchaseOrder that links back through PurchaseOrder.PurchaseAutoOrderId. The Include and Exclude flags scope which items and which supply and demand sources the Forecasting calculation may see. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AIRecommendation` | AI Recommendation | PickList | | Nothing in the platform reads or writes it, and no recommendation engine is wired to auto ordering; the suggested quantities come from the deterministic minimum-stock, replenish and forecasting calculations. Values: Einstein 1, DemandSense AI, Einstein 2, AutoProcure AI, SmartReplenish AI, Einstein 3, Einstein 4, InventoryPilot AI. | | `ApplyInventoryAttributeSettings` | Apply Inventory Attribute Settings | PickList | | Values: Auto Min Max Settings, Manual Min Max Settings, Average of Auto & Manual Settings, Prefer Auto. | | `AutoOrderType` | Auto Order Type | PickList | | Values: Back Order, Minimum Stock Level, Forecasting, Template, Replenish. | | `AutoPurchaseOrderId` | Auto Purchase Order | Lookup | | On an order spawned from a template, this points back at the template it was cloned from. The scheduled sweep uses exactly this link to decide whether a template has already produced its order for today, so it is what keeps template generation to one dated order per template per day. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BudgetAmount` | Budget Amount | Currency | | A spend cap applied after the proposal lines are priced: when the priced total exceeds it, every line that carries a non-zero amount has its quantity, suggested, derived and pending quantities scaled down by the same factor so the order fits, with values rounded to two decimals. Empty or zero means no cap, and lines priced at zero (no applicable price rule found) are deliberately left untouched rather than trimmed. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CreateTemplate` | Create Template | Boolean | Yes | A flag with no code behind it anywhere in the platform. A reusable planning configuration is created by setting AutoOrderType to Template, not by ticking this. | | `DocumentDate` | Document Date | Date | | | | `ExcludeACategoryItems` | Exclude A Category Items | Boolean | Yes | Excludes items whose inventory attributes classify them in the A value band from the proposal, applied before any quantity is computed. The three ABC flags and the three fast/slow/non-moving flags are tested against the item's inventory-attribute row, and an item with no such row is never excluded. | | `ExcludeBCategoryItems` | Exclude B Category Items | Boolean | Yes | | | `ExcludeCCategoryItems` | Exclude C Category Items | Boolean | Yes | | | `ExcludeFastMovingItems` | Exclude Fast Moving Items | Boolean | Yes | | | `ExcludeNonMovingItems` | Exclude Non Moving Items | Boolean | Yes | Drops items classified as non-moving from the proposal. Because the movement category comes from the item's inventory-attribute row, an item that has never been classified is not excluded by this flag. | | `ExcludeSlowMovingItems` | Exclude Slow Moving Items | Boolean | Yes | Drops items classified as slow-moving from the proposal. The exclusion is applied by all three line-building engines, matching the item's movement category exactly, and an item with no inventory-attribute row has no category to test and so survives the filter. | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `IncludeHighProbabilityQuote` | Include High Probability Quote | Boolean | Yes | | | `IncludeInTransitShipments` | Include In-Transit Shipments | Boolean | Yes | | | `IncludeOpenSaleOrders` | Include Open Sale Orders | Boolean | Yes | Forecasting only: when set, committed outbound demand from open sale orders is subtracted when projecting stock forward, which lowers the projected quantity and makes replenishment more likely to trigger. Left off, open sale orders are invisible to the calculation. | | `IncludePendingPurchaseOrders` | Include Pending Purchase Orders | Boolean | Yes | | | `IncludePurchaseRequisition` | Include Purchase Requisition | Boolean | Yes | | | `IsOrderGenerated` | Is Order Generated | Calculated (calculated) | Yes | Meant to be the one-shot latch that stops an auto order being converted twice: generation and line regeneration are both refused when it is true, and the scheduled forecast sweep skips orders carrying it. In practice no code path ever sets it to true, so the guard never actually fires and order generation can be re-run against the same auto order. Judge whether a purchase order already came out of it by looking for PurchaseOrder rows whose PurchaseAutoOrderId is this record. | | `LastAutoOrderDate` | Last Auto Order Date | Date | | The replenish engine does need a 'since last run' boundary, but it derives it independently as the latest document date among the branch's replenish auto orders rather than reading this field. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text, unique | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PerformOpenOrderCalculation` | Perform Open Order Calculation | Boolean | Yes | Switches on the on-order netting for the minimum-stock and replenish engines: with it set, each proposal line's OpenOrderQuantity is filled from the outstanding pending quantity of existing purchase-order lines for the same partner, branch, item and SKU. The forecasting engine does not use it - it nets pending purchase orders through its own include flag instead. | | `PerformOrderGeneration` | Perform Order Generation | Boolean | Yes | A legacy trigger boolean. | | `PriceAsOnDate` | Price As On Date | Date | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `ResourceId` | Generated By | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `Status` | Status | PickList | | Carries a seeded draft and generated vocabulary but is never assigned by code; the only place it moves at all is when a template clone copies the template's value verbatim. The meaningful state is held in IsOrderGenerated and in whether proposal lines exist. Values: Draft, Order Generated. | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `TotalAmount` | Total Amount | Calculated (calculated) | | | | `TotalPendingQuantity` | Total Pending Quantity | Calculated (calculated) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditInList` | Edit | EditInline | Edit | | `EditPopUp` | Edit | Edit | Edit | | `GenerateForecastLines` | Lines | ServerAction (`GenerateAutoOrderLines`) | Generate AutoOrder Lines | | `GenerateTemplateOrder` | Order from Template | ServerAction (`GenerateTemplateOrder`) | Generate Order from Template | | `New` | New | New | New | | `PerformOrderGeneration` | Purchase Order | ServerAction (`PerformOrderGeneration`) | Generate Purchase Order | | `SelectiveOrderGeneration` | Selective Order | ServerAction (`SelectiveOrderGeneration`) | Selective Order Generation | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Budget Amount Rule Validation | `BudgetAmount`, Error | Budgeted Amount Can not be Less than 0 | Budgeted Amount Can not be Less than 0 | | Last Auto Order Date Validation | `LastAutoOrderDate`, Error | Last auto order date cannot go beyond today's date | Last auto order date cannot go beyond today's date | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Only Partner Account | `PartnerAccountId` | | | Only Supplier | `SupplierAccountId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [AutoPurchaseOrderLine](/docs/reference/entities/auto-purchase-order-line/) — referenced by via `AutoOrderId` - [PurchaseOrderRequisition](/docs/reference/entities/purchase-order-requisition/) — referenced by via `AutoOrderId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `PurchaseAutoOrderId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Auto Purchase Order Line Relation — entity reference URL: https://xmatix.com/docs/reference/entities/auto-purchase-order-line-relation/ Last reviewed: 2026-08-16 An orphan entity: the metadata and domain type exist but nothing else does. Its metadata field names have also drifted away from the domain type - the metadata declares AutoPurchaseOrderLine, ItemSKU and DocumentNumber where the class declares AutoPurchaseOrderLineId, SKUId and AutoPurchaseOrderLineRelationNumber, and metadata treats PendingQuantity as a calculated field where the class stores it. Treat it as unused scaffolding for tying an auto-order proposal line to a fulfilment order line; the working link between a proposal and the resulting purchase order is PurchaseOrderLine.AutoPurchaseOrderLineId instead. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AutoPurchaseOrderId` | Auto Purchase Order | Lookup | | | | `AutoPurchaseOrderLine` | Auto Purchase Order Line | Lookup | Yes | Named as a plain field here although the domain type declares it as an identifier column linking to the proposal line, one of several places where this table's metadata has drifted from the class. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentNumber` | Document Number | Number | Yes | The metadata name for what the class declares as a per-relation sequence number. Neither is ever assigned, since nothing in the platform creates rows in this table. | | `ExternalId` | External | Text | | | | `FulfillmentOrderLineId` | Fulfillment Order Line | Lookup | | Intended to tie a proposed purchase quantity to the specific demand line it would fulfil, which is what would have made this table a demand-to-supply pegging record. Nothing creates such a link; demand netting in the working replenishment engine is done in aggregate, not line to line. | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup | | | | `ItemLotTypeId` | Item Lot Type | Lookup | | | | `ItemSKU` | Item SKU | Lookup | | The metadata name for what the domain type declares as the SKU identifier, another instance of this unused table's metadata drifting from the class. No code path populates it. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OrderQuantity` | Order Quantity | Number | | The demand quantity this pegging row would have carried. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PendingQuantity` | Pending Quantity | Calculated (calculated) | | Declared here as a calculated field (order quantity minus purchase-order quantity) whereas the domain type stores it as a plain column - a genuine mismatch between the metadata and the class. Because nothing ever writes this table, neither definition is exercised. | | `PurchaseOrderQuantity` | Purchase Order Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SuggestedQuantity` | Suggested Quantity | Number | | | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Auto Purchase Order Line — entity reference URL: https://xmatix.com/docs/reference/entities/auto-purchase-order-line/ Last reviewed: 2026-08-16 One proposed purchase line inside an AutoOrder, together with the frozen explainability snapshot of how that proposal was reached. On the Forecasting path each line records the exact inputs to its own calculation - QuantityAvailable, PendingShipmentQuantity, PendingPurchaseOrderQuantity, PendingRequisitionQuantity, PendingSaleOrderQuantity and the resulting ProjectedQuantity - alongside the planning parameters (LeadTime, AverageConsumption, MinimumQuantity, MaximumQuantity, ReorderQuantity) averaged across the item's inventory-attribute rows. SuggestedQuantity is the engine's recommendation, DerivedQuantity is what may actually be released, PurchaseOrderQuantity accumulates what has been released, and PendingQuantity is the remainder. Order generation reads DerivedQuantity and PendingQuantity, so a line whose suggestion netted to nothing is skipped. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Calculated (calculated) | | The line value, quantity times unit cost, computed after the price rules have resolved the unit cost and recomputed once more if the header's budget cap scaled the quantity down. Lines that no price rule matched stay at zero and are excluded from budget trimming. | | `AutoOrderId` | Auto Order | Lookup → [AutoOrder](/docs/reference/entities/auto-order/) | | | | `AverageConsumption` | Average Consumption | Number | | The item's average consumption per lead-time period from its inventory attributes, averaged across matching rows and rounded to a whole number on the line. It multiplies lead time to form the reorder point, so an item with no consumption figure has a reorder point of just the minimum quantity. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DerivedQuantity` | Derived Quantity | Calculated (calculated) | | | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `LeadTime` | Lead Time | Number | | | | `MaximumQuantity` | Maximum Quantity | Number | | | | `MinimumQuantity` | Minimum Quantity | Number | | The item's minimum order quantity from its inventory attributes, averaged across matching rows. In the forecasting calculation it is a term in the reorder point (lead time times average consumption, plus this), so raising it makes replenishment trigger sooner, not just larger. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `OpenOrderQuantity` | Open Order Quantity | Number | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PendingPurchaseOrderQuantity` | Pending Purchase Order Quantity | Number | | Inbound supply already on order that the forecasting engine added to the projection, captured only when the header's pending-purchase-order include flag is set. It is kept here for explainability but deliberately not copied into OpenOrderQuantity, because it is already netted into ProjectedQuantity and adding it again would double-count on-order supply. | | `PendingQuantity` | Pending Quantity | Calculated (calculated) | | | | `PendingQuoteQuantity` | Pending Quote Quantity | Number | | Do not read a zero here as evidence that no quotations exist. | | `PendingRequisitionQuantity` | Pending Requisition Quantity | Number | | Committed internal demand from open requisitions that the forecasting engine subtracted when projecting stock, captured only when the header's requisition include flag is set. Forecasting is the only engine that reacts to open requisitions at all. | | `PendingSaleOrderQuantity` | Pending Sale Order Quantity | Number | | Committed outbound demand from open sale orders that the forecasting engine subtracted when projecting stock, captured only when the header's sale-order include flag is set. | | `PendingShipmentQuantity` | Pending Shipment Quantity | Number | | Inbound supply already in transit that the forecasting engine added when projecting stock forward, captured only when the header's in-transit include flag is set; otherwise it stays at zero. Part of the frozen calculation snapshot, not a live figure. | | `PriceAsOnDate` | Price As On Date | Date | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `PriceListRuleId` | Price List Rule | Lookup → [PriceListRule](/docs/reference/entities/price-list-rule/) | | | | `ProjectedQuantity` | Projected Quantity | Number | | | | `PurchaseOrderQuantity` | Purchase Order Quantity | Number | | How much of this proposal has actually been released into purchase orders, rolled up from the quantity of purchase-order lines that point back at this line. PendingQuantity is quantity minus this, which is what makes a partially accepted suggestion still releasable later. | | `Quantity` | Quantity | Number | Yes | The working order quantity for the proposal line: it starts equal to SuggestedQuantity and is then scaled down in place if the header's budget cap bites. It is what the line amount is priced from, and it is the quantity rolled up into the proposal's total. | | `QuantityAvailable` | Quantity Available | Number | | The on-hand available stock the forecasting engine read for this item and SKU at generation time, frozen onto the line as part of the explainability snapshot. It is the starting point of the projection, not a live figure - it does not track stock afterwards. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReorderQuantity` | Reorder Quantity | Number | | The reorder quantity from the item's inventory attributes, averaged across the matching attribute rows. Note that the forecasting engine records it for explainability but does not order it: the quantity it proposes is the maximum order quantity minus the projected quantity. The minimum-stock engine, by contrast, does order exactly this quantity when it is set. | | `RequestedQuantity` | Requested Quantity | Number | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `SuggestedQuantity` | Suggested Quantity | Number | | | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | The purchase price resolved for the proposed line by the shared price-rule service after the lines are generated, against the header's price list and as-of date. It is copied onto the purchase-order line when the proposal is released, so an unpriced proposal produces an unpriced order line. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `DeleteinRow` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditinLine` | Edit | EditInline | Edit | | `EditPopUp` | Edit | Edit | Edit | | `New` | New | New | New | | `NewInLine` | Quick Add | NewInline | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Quantity Rule Validation | `Quantity`, Error | Quantity cannot be less than 1. | Quantity cannot be less than 1. | | Unit Cost Rule Validation | `UnitCost`, Error, inactive | Unit cost cannot be negative | Unit cost cannot be negative | ## Related entities - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — looks up via `PriceListRuleId` - [AutoOrder](/docs/reference/entities/auto-order/) — looks up via `AutoOrderId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `AutoPurchaseOrderLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Availability Request — entity reference URL: https://xmatix.com/docs/reference/entities/availability-request/ Last reviewed: 2026-08-16 A minimal first-party record carrying only a name, a RequestType and a Status, with no relationship to any other business entity. It is an empty shell an implementation can adopt rather than a working availability-checking feature, so do not describe it as scheduling or reserving resources or field personnel. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Request Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestType` | Request Type | PickList | | | | `Status` | Status | PickList | | Do not assume a workflow behind it. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInList` | Edit | Edit | Edit in page. | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Bank Account — entity reference URL: https://xmatix.com/docs/reference/entities/bank-account/ Last reviewed: 2026-08-16 Master record for one account the company holds at a bank; many accounts per company and per operating branch are supported. Its linked general-ledger account is what makes reconciliation possible at all — every reconciliation reads posted journal lines on that GL account as the book side, so an account with no GL link cannot be reconciled or even produce match suggestions. Bank statements, cheque registers, cheque transactions, bank transfers and reconciliation matches all hang off it. Save-time rules reject a second account carrying the same account number at the same bank name, and block deletion once the account has any statement or cheque transaction (deactivate it instead). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountNumber` | Account Number | Text, unique | Yes | The account number at the bank. | | `BankName` | Bank Name | Text | Yes | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The company's own operating branch that owns this account, used to scope the reconciliation bank-account list. It is unrelated to the bank branch name captured separately on this record. | | `BranchName` | Branch Name | Text | | Free text naming the bank's own branch, captured for reference alongside the IFSC code. It is not a link to the company's Branch records and nothing validates or reads it. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Currency` | Currency | Text | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | Yes | The general-ledger account this bank account posts to and is reconciled against; reconciliation reads posted journal lines on this GL account as the book side. Leaving it empty makes the account unreconcilable — match suggestion fails outright, and the bank-account list behind the reconciliation screen returns only accounts whose GL account is of type Bank. | | `Id` | Id | Guid | Yes | | | `Ifsc` | Ifsc | Text | | | | `IsActive` | Is Active | Boolean | | Controls whether the account is offered for new work: the reconciliation bank-account list returns only active accounts, and a cheque register cannot be created against an inactive one. It is the intended substitute for deletion, which is blocked once the account has any statement or cheque transaction. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The owning company (legal entity) in a multi-company tenant, not a customer or a supplier. The reconciliation bank-account list filters on it, falling back to the signed-in user's default company when the caller does not pass one explicitly. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `RecalculateTotals` | RecalculateTotals | ServerAction (`RecalculateTotals`) | RecalculateTotals | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | GLAccount Filter | `GLAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ChequeTransaction](/docs/reference/entities/cheque-transaction/) — referenced by via `BankAccountId` - [ReconciliationMatch](/docs/reference/entities/reconciliation-match/) — referenced by via `BankAccountId` - [ChequeRegister](/docs/reference/entities/cheque-register/) — referenced by via `BankAccountId` - [PaymentBatch](/docs/reference/entities/payment-batch/) — referenced by via `BankAccountId` - [BankTransfer](/docs/reference/entities/bank-transfer/) — referenced by via `FromBankAccountId` - [BankStatement](/docs/reference/entities/bank-statement/) — referenced by via `BankAccountId` - [BankReconciliation](/docs/reference/entities/bank-reconciliation/) — referenced by via `BankAccountId` - [BankTransfer](/docs/reference/entities/bank-transfer/) — referenced by via `ToBankAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Bank Reconciliation Line — entity reference URL: https://xmatix.com/docs/reference/entities/bank-reconciliation-line/ Last reviewed: 2026-08-16 One reconciling item inside a reconciliation session — a bank statement line, a ledger journal line, or a hand-typed adjustment such as an outstanding cheque, a deposit in transit or a bank charge. No service creates these rows; they are entered manually on the session (there is a new-inline action) and are read only by the session summary, which totals them into matched and outstanding buckets. It is a different thing from ReconciliationMatch, which is what the automated statement-to-ledger matching actually writes — the two are not kept in step with each other. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | The reconciling amount, totalled by the session summary into the matched and outstanding buckets. It is typed in rather than derived, so it is never checked against the statement line or journal line the row points at. | | `BankReconciliationId` | Bank Reconciliation | Lookup → [BankReconciliation](/docs/reference/entities/bank-reconciliation/) | | | | `BankStatementLineId` | Bank Statement Line | Lookup → [BankStatementLine](/docs/reference/entities/bank-statement-line/) | | Optional link to the bank side of the reconciling item. Like the journal-line link it is kept for traceability and is read neither by the session summary nor by the matching engine. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IsMatched` | Is Matched | Boolean | | The only thing the session summary splits on: true rows are counted and totalled as matched, everything else as outstanding. It is set by whoever entered the line — no matching process writes it, and it is independent of the reconciliation matches produced by the statement-line matching engine. | | `JournalLineId` | Journal Line | Lookup → [JournalLine](/docs/reference/entities/journal-line/) | | Optional link to the ledger side of the reconciling item. | | `LineNumber` | Line Number | Number | | Display ordering within the session. Because no service creates these rows it is not auto-assigned, and nothing enforces that the numbers are unique or contiguous. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Narration` | Narration | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Type` | Type | Text | | Classifies the reconciling item; the intended vocabulary is Matched, OutstandingCheque, DepositInTransit, BankCharge and Other. It is stored as plain text with no seeded picklist and no logic branches on it — the summary uses the matched flag instead. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `NewInline` | New | NewInline | New | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [BankReconciliation](/docs/reference/entities/bank-reconciliation/) — looks up via `BankReconciliationId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [BankStatementLine](/docs/reference/entities/bank-statement-line/) — looks up via `BankStatementLineId` - [JournalLine](/docs/reference/entities/journal-line/) — looks up via `JournalLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Bank Reconciliation — entity reference URL: https://xmatix.com/docs/reference/entities/bank-reconciliation/ Last reviewed: 2026-08-16 A reconciliation session header for one bank account as at a statement date, holding the closing balance per bank and per book plus the difference between them, and owning the BankReconciliationLine reconciling items. It is a manual worksheet rather than a computed one: nothing in the platform populates the two closing balances — the session summary reads whatever is stored on the header, stamps the difference as per-bank minus per-book, and flips the status to Completed when that difference is zero. Its server actions (match suggestions, confirm matches, list bank accounts) operate on bank statement lines and ledger journal lines, not on this session's own lines, so a session can be signed off independently of the matches actually recorded. Completing a session locks nothing: no period is closed, no journal is frozen and nothing is posted to the ledger. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BankAccountId` | Bank Account | Lookup → [BankAccount](/docs/reference/entities/bank-account/) | | The bank account under reconciliation. Note that the match actions resolve the bank account from each statement line's own parent statement rather than from here, so a mismatch between this field and the linked statement's account is never detected. | | `BankStatementId` | Bank Statement | Lookup → [BankStatement](/docs/reference/entities/bank-statement/) | | The statement this session covers. The reconciliation-summary action refuses to run without it, since the statement supplies the bank-side closing balance and the lines to compare. | | `ClosingBalancePerBank` | Closing Balance Per Bank | Currency | | The bank's closing balance for the session, entered by hand. | | `ClosingBalancePerBook` | Closing Balance Per Book | Currency | | The ledger closing balance for the session, entered by hand. Nothing recomputes it from posted journal lines on the bank's GL account, so it is a snapshot of what someone typed rather than a live figure. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Difference` | Difference | Currency | | Stamped by the session summary as closing balance per bank minus closing balance per book. Because both inputs are manually entered, a zero here proves only that the two typed figures agree — it does not prove the statement ties to the ledger. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OpeningBalance` | Opening Balance | Currency | | Recorded on the session header for reference only. No code reads it — the session summary works purely from the two closing balances. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StatementDate` | Statement Date | DateAndTime | | | | `Status` | Status | Text | | Open or Completed. The session summary flips it to Completed once the difference is zero, but it never flips back, so a session completed and then edited to a non-zero difference stays Completed. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `ConfirmMatches` | Confirm Matches | ServerAction (`ConfirmMatches`) | Persists a caller-supplied list of statement-line to journal-line pairs as reconciliation matches, marks each statement line Matched, and reports how many were confirmed against how many were requested. It applies no matching rules and performs no amount, date or direction check on the pairs it is handed, so it will record whatever pairing it is given — only the auto-match path enforces the rules. | | `GetBankAccounts` | Get Bank Accounts | ServerAction (`GetBankAccounts`) | Lists the active bank accounts whose GL account is of type Bank, each with a book balance summed from posted journal lines on that GL account, a bank balance summed across the account's statements, and a count of its statement lines by reconciliation status. Scope precedence matters: an explicitly passed company or branch is honoured verbatim and suppresses the user's defaults, and only when neither is passed does it fall back to the signed-in user's default company and branch. Be careful with the bank balance — it adds up the closing balance of every statement on the account rather than taking the latest one, so an account with several statements reports an inflated figure. | | `GetMatchSuggestions` | Get Match Suggestions | ServerAction (`GetMatchSuggestions`) | Takes a single bank statement line id and returns the posted ledger lines on that account's bank GL account which survive the whole matching-rule cascade, ranked best first by date proximity and reference overlap. Despite the name it is not read-only: if a rule in the cascade has auto-match on and its survivors have an unambiguous winner, the match is confirmed and the statement line flipped to Matched during this call, and only that one confirmed suggestion is returned. It returns nothing for a line that is not Unmatched, and fails outright when the bank account has no linked GL account. | | `GetUnmatchedAgeing` | Get Unmatched Ageing | ServerAction (`GetUnmatchedAgeing`) | Age the unmatched statement and book transactions on a bank account. | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [BankStatement](/docs/reference/entities/bank-statement/) — looks up via `BankStatementId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [BankAccount](/docs/reference/entities/bank-account/) — looks up via `BankAccountId` - [BankReconciliationLine](/docs/reference/entities/bank-reconciliation-line/) — referenced by via `BankReconciliationId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Bank Statement Line — entity reference URL: https://xmatix.com/docs/reference/entities/bank-statement-line/ Last reviewed: 2026-10-10 One transaction on an imported bank statement: the bank's value date, its narration and reference, and a deposit or a withdrawal amount. Lines are added one at a time or imported in bulk from the statement's Statement Lines tab, and they start with the reconciliation status Unmatched. Bank reconciliation treats deposit minus withdrawal as the line's signed amount and pairs it with a posted journal line on the bank account's GL account carrying the same sign. Confirming a pair records a reconciliation match and sets the line to Matched. Deleting the parent statement does not delete its lines. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BankStatementId` | Bank Statement | Lookup → [BankStatement](/docs/reference/entities/bank-statement/) | | The statement this line belongs to. It is filled in automatically when lines are added or imported from the statement's Statement Lines tab, and it links the line to the bank account whose GL account reconciliation reads. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Deposit` | Deposit | Currency | | Money into the account per the bank. The engine works with deposit minus withdrawal as the line's signed amount, so a deposit is positive and pairs with a ledger debit on the bank's GL account. | | `Description` | Description | Text | | The bank's narration for the transaction, kept for reference. The matching criteria compare the Reference field, not this one. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | An optional display label. Matching does not use it. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | GL Account Name | Text, unique | Yes | The line's identifier. It is required and unique across all bank statement lines, not just within one statement, so imported lines should carry names built from the statement and a line number. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | The user who owns the line record. | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The partner account the line is scoped to. It is not on the line's create or view form. | | `ReconciliationStatus` | Reconciliation Status | Text | | Unmatched, Matched or Ignored, defaulting to Unmatched. Only an Unmatched line is eligible for match suggestions, and confirming a match sets it to Matched; nothing sets Ignored automatically, and nothing resets it to Unmatched when the underlying reconciliation match is deleted. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Reference` | Reference | Text | | The bank's reference for the line, and the only text the matching criteria compare — the reference criterion tests it against the journal line's narration and the document-number criterion tests it against the journal's voucher name. Both use a case-insensitive substring test in either direction, so a short or generic reference can overlap unrelated ledger lines. | | `TransactionDate` | Transaction Date | Date | | The bank's value date for the line. The date criterion measures the whole-day gap between it and the journal's date, and a smaller gap also ranks a candidate higher among the survivors. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `Withdrawal` | Withdrawal | Currency | | Money out of the account per the bank, giving a negative signed amount that pairs with a ledger credit on the bank's GL account. The direction criterion compares only the sign, not the magnitude. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInline` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | Edit | | `Import` | Import | UIAction | Opens the dedicated bank-statement-line import layout to load statement lines in bulk against a statement. Imported lines land with reconciliation status Unmatched and are not paired with anything — matching is a separate step run from the reconciliation entity afterwards. | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [BankStatement](/docs/reference/entities/bank-statement/) — looks up via `BankStatementId` - [ReconciliationMatch](/docs/reference/entities/reconciliation-match/) — referenced by via `BankStatementLineId` - [BankReconciliationLine](/docs/reference/entities/bank-reconciliation-line/) — referenced by via `BankStatementLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Bank Statement — entity reference URL: https://xmatix.com/docs/reference/entities/bank-statement/ Last reviewed: 2026-08-16 One imported bank statement for a bank account — its as-at date and the bank's opening and closing balances — owning the statement lines that the reconciliation engine matches against posted ledger lines on the bank's GL account. Save-time rules reject a second statement for the same bank account and date, and reject an opening balance that does not equal the closing balance of that account's most recent earlier statement. Its status is stamped Imported on creation and is never advanced by any code path, so it does not indicate reconciliation progress; read the per-line reconciliation status or run the reconciliation summary instead. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BankAccountId` | Bank Account | Lookup → [BankAccount](/docs/reference/entities/bank-account/) | Yes | The account being reported. It also resolves the GL account the ledger side is read from, so a statement whose bank account has no linked GL account cannot produce any match suggestions. | | `ClosingBalance` | Closing Balance | Calculated (calculated) | | The bank's closing balance, used as the bank side of the reconciliation: the summary reports the difference between the posted ledger balance on the bank's GL account and this value, and it treats the statement as internally consistent only when the opening balance plus the net of all its lines equals it. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OpeningBalance` | Opening Balance | Currency | | The bank's opening balance for the period. It is validated on save against the closing balance of the same account's most recent earlier statement and the save is rejected when they differ, so back-dating or correcting one statement can block saving another. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StatementDate` | Statement Date | Date | Yes | The as-at date of the statement and the key for both save-time rules — at most one statement per bank account per date, and the previous-statement lookup for the opening-balance check takes the latest statement dated strictly before it. | | `Status` | Status | PickList | | Stamped Imported when the statement is created and never advanced by any code path; the Reconciling and Reconciled values that exist in the underlying vocabulary are not even offered in the picklist. It therefore does not track reconciliation progress — use the per-line reconciliation status or the reconciliation summary. Values: Imported. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `AutoReconcile` | Auto Reconcile | ServerAction (`AutoReconcile`) | Declared as a server action but nothing implements it — the bank statement handler only validates saves and supports no server actions at all, so invoking this runs no matching. Automatic matching happens on the bank reconciliation entity's match-suggestion action, driven by matching rules that have auto-match enabled. | | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `SuggestMatches` | Suggest Matches | ServerAction (`SuggestMatches`) | The working equivalent is the match-suggestion action on the bank reconciliation entity, which takes a single bank statement line id. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | XM_BankStatementFutureDateValidation | `StatementDate`, Error | Future-date is not allowed. | Future-dated bank statement validation. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Bank Account Filter | `BankAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [BankAccount](/docs/reference/entities/bank-account/) — looks up via `BankAccountId` - [BankReconciliation](/docs/reference/entities/bank-reconciliation/) — referenced by via `BankStatementId` - [BankStatementLine](/docs/reference/entities/bank-statement-line/) — referenced by via `BankStatementId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Bank Transfer — entity reference URL: https://xmatix.com/docs/reference/entities/bank-transfer/ Last reviewed: 2026-08-16 A movement of funds between two of the company's own bank accounts, posted as a single balanced journal that debits the destination bank's GL account and credits the source's — no party, income or tax leg. Posting is gated twice over, in the action's validation and again authoritatively in the posting service: the status must read Approved, the transfer must not already carry a journal, both bank accounts must have a GL account configured, and the amount must be positive. A successful post stamps the journal id, sets the posted flag and overwrites the status with Posted. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | The transfer value, debited to the destination bank's GL account and credited to the source's in one balanced journal. It must be greater than zero, checked both on save and again at posting time. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The company branch stamped onto the posted journal and each of its lines. It is taken from this field rather than from either bank account, so a transfer left blank here posts journal lines with no branch. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FromBankAccountId` | From Bank Account | Lookup → [BankAccount](/docs/reference/entities/bank-account/) | Yes | The source account, credited when the transfer posts. Its bank account must have a GL account configured or posting fails, and it must differ from the destination or the save is rejected. | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | The journal created by posting. | | `Id` | Id | Guid | Yes | | | `IsGLPosted` | IsGL Posted | Boolean | | Set to true only by a successful posting, alongside the journal link. Together those two are the duplicate-posting guard — the action is refused when either is set — so both would have to be cleared by hand before a second journal could be created. | | `IsGLPostingApproved` | IsGL Posting Approved | Boolean | | The same-named field is live on sales and purchase documents, which is a common source of confusion. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | GL Account Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Reference` | Reference | Text | | Copied into the posted journal's narration and into both journal lines as transfer-in and transfer-out text, making it the main trace from the ledger back to the transfer. | | `Status` | Status | Text | | Draft, Approved, Posted or Reversed by convention, but stored as plain text rather than a picklist. The value is load-bearing: posting is refused unless it reads Approved (case-insensitive), and a successful post overwrites it with Posted. Nothing in the platform ever writes Reversed. | | `ToBankAccountId` | To Bank Account | Lookup → [BankAccount](/docs/reference/entities/bank-account/) | Yes | The destination account, debited when the transfer posts. The save is rejected when it equals the source, and posting fails if this account has no GL account configured. | | `TransferDate` | Transfer Date | Date | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInline` | Edit Inline | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `PerformGLPosting` | Post | ServerAction (`PerformGLPosting`) | Posts the transfer as one balanced journal debiting the destination bank's GL account and crediting the source's, then stamps the journal id, sets the posted flag and overwrites the status with Posted. It is refused unless the status reads Approved and the transfer has no journal yet, and it fails when either bank account lacks a GL account or the amount is not positive. | | `PostGeneralLedger` | Post General Ledger | ServerAction (`PostGeneralLedger`) | A second entry point onto exactly the same posting routine as the Post action, with the same approval and duplicate guards and the same balanced journal. Having both surfaced means the one operation appears twice in the UI; a second attempt is safely refused by the already-posted guard rather than creating a duplicate journal. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | To Bank Account Validation | `ToBankAccountId`, Error, inactive | | To Bank Account Validation | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | From Bank Filter | `FromBankAccountId` | | | To Bank Filter | `ToBankAccountId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [BankAccount](/docs/reference/entities/bank-account/) — looks up via `FromBankAccountId` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [BankAccount](/docs/reference/entities/bank-account/) — looks up via `ToBankAccountId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Banking — entity reference URL: https://xmatix.com/docs/reference/entities/banking-transaction/ Last reviewed: 2026-08-16 A legacy standalone bank-feed row (date, deposit or withdrawal, payee, narration, reference) held directly against a GL account, predating the BankAccount / BankStatement / BankStatementLine chain that the current reconciliation engine works from. Only one of its server actions is live — the bank-reconciliation overview, which reports per-Bank-GL-account book balances and a status histogram computed from these rows. Treat it as legacy: current bank work belongs on BankStatement and BankStatementLine. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Date` | Date | Date | Yes | | | `Deposit` | Deposit | Currency | | Money into the account. The signed amount used everywhere is deposit minus withdrawal, and the bank-reconciliation overview derives a GL account's book balance as the sum of deposits less the sum of withdrawals across these rows. | | `ExternalId` | External | Text | | The identifier the row carried in from the source bank feed or import file. It is stored for traceability only — no de-duplication, matching or lookup logic reads it. | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The bank GL account this feed row belongs to. The bank-reconciliation overview groups by it and derives each account's book balance from the deposits and withdrawals attached here, so a row with no GL account is invisible to that view. | | `Id` | Id | Guid | Yes | | | `IsPosted` | Is Posted | Boolean | Yes | | | `IsRecognized` | Is Recognized | Boolean | Yes | Intended to mark the transaction as tied to a source document, but the only code that would set it is the commented-out reconcile path, so the platform never writes it. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Narration` | Narration | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Payee` | Payee | Text | | | | `ReceivedVia` | Received Via | PickList | | | | `Reference` | Reference | Text | | | | `Status` | Status | PickList | | Any value present was typed by a user or loaded by an import, and the bank-reconciliation overview simply counts whatever values it finds. Values: Pending, Categorized, Ignored, Unmatched, Match, Review, Reconciled, Exception. | | `SubStatus` | Sub-Status | PickList | | Configured as a picklist but no values are seeded for it, so it renders as an empty dropdown. Nothing in the platform reads or writes it. | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `Withdrawl` | Withdrawal | Currency | | Deposit minus this value gives the row's signed amount. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditHeader` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit In line | | `EditInList` | Edit | EditInline | Edit | | `GetBankReconciliation` | Get Bank Reconciliation | ServerAction (`GetBankReconciliation`) | The one working server action on this entity: it returns the GL accounts of the requested type — only Bank is accepted, anything else is rejected — for the signed-in user's default company, each with a book balance computed as total deposits minus total withdrawals across its banking transactions and a count of those transactions by status. It throws rather than returning an empty list when the user has no resource record, or when that resource has no default company and branch. | | `GetMatchSuggestions` | Get Matching Suggestions | ServerAction (`GetMatchSuggestions`) | It is not the reconciliation matcher — that lives on the bank reconciliation entity and works from bank statement lines. | | `IgnoreTransaction` | Ignore Transaction | ServerAction (`IgnoreTransaction`) | | | `New` | New | New | New | | `PostTransaction` | Post Transaction | ServerAction (`PostTransaction`) | | | `ReconcileTransaction` | Reconcile Transaction | ServerAction (`ReconcileTransaction`) | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Bill Line — entity reference URL: https://xmatix.com/docs/reference/entities/bill-line/ Last reviewed: 2026-08-16 One item on a vendor Bill. It mirrors InvoiceLine but is costed rather than priced: BaseAmount is Quantity times UnitCost2 when non-zero else UnitCost. GoodsReceiptLineId decides how the line posts — set, the line clears the goods-received-not-invoiced accrual the receipt already raised, so inventory is not debited twice; unset, the line debits Inventory or Expense according to its GLPostingType. A withholding section on the line drives TDS deduction when the bill is posted. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Amount` | Amount | Calculated (calculated) | | Metadata-calculated as BaseAmount less NetDiscount and NetSchemeDiscount — the net-of-discount, pre-tax line value that rolls into the bill's TotalLineAmount. Unlike the sales-side line it applies the discounts unconditionally, and the post-tax discount switch only affects GrossAmount. | | `ApplyPostTaxDiscount` | Apply Post Tax Discount | Boolean | Yes | | | `BaseAmount` | Base Amount | Calculated (calculated) | | | | `BenefitId` | Scheme Benefit | Lookup → [SchemeBenefit](/docs/reference/entities/scheme-benefit/) | | | | `BillId` | Bill | Lookup → [Bill](/docs/reference/entities/bill/) | | | | `BranchId` | Branch | Calculated (calculated) | | | | `CashDiscount` | Cash Discount | Percent | | A value here therefore does not reduce Amount, GrossAmount or anything posted. | | `CashDiscountAmount` | Cash Discount Amount | Currency | | The explicit counterpart of the cash-discount rate, and equally unused: it appears in no discount formula and in no posting path, so recording it changes nothing about the line's value or the ledger. Treat it as documentation of terms, not as an amount that will be taken. | | `ContractDiscount` | Contract Discount | Percent | | | | `ContractDiscountAmount` | Contract Discount Amount | Currency | | | | `ConversionRatio` | Conversion Ratio | LargeNumber | | | | `ConversionRatio1` | Conversion Ratio 1 | LargeNumber | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `Discount` | Discount | Percent | | | | `Discount2` | Discount 2 | Decimal | | | | `DiscountAmount` | Discount Amount | Currency | | | | `DiscountAmount2` | Discount Amount 2 | Currency | | | | `EligibleReturnQuantity` | Eligible Return Quantity | Calculated (calculated) | | | | `ExternalId` | External | Text, unique | | | | `GeneralLedgerId` | General Ledger | Lookup → [GeneralLedger](/docs/reference/entities/general-ledger/) | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `GLAmount` | GL Amount | Calculated (calculated) | | | | `GLPostingType` | GL Posting Type | PickList | | Decides the debit account for a line that did not come from a goods receipt: 'Inventory' debits the inventory asset account and anything else debits Expense. It is ignored entirely when the line carries a goods-receipt reference, because such a line instead clears the goods-received-not-invoiced accrual. | | `GoodsReceiptLineId` | Goods Receipt Line | Lookup → [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) | | | | `GrossAmount` | Gross Amount | Calculated (calculated) | | Metadata-calculated as Amount plus TaxAmount, less the discounts again when the line is flagged for post-tax discounting. It is the tax-inclusive line value and is what the bill's TotalAmount and TotalLineGrossAmount both roll up. | | `HsnSacCode` | HSN/SAC Code | Text | | | | `Id` | Id | Guid | Yes | | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | | | `InvoiceQuantity` | Invoice Quantity | Calculated (calculated) | | | | `IsCustomerBillable` | Customer Billable | Boolean | Yes | | | `IsGLPosted` | GL Posted | Boolean | Yes | | | `IsGLPostingApproved` | GL Posting Approved | Boolean | Yes | | | `IsILPosted` | IL Posted | Boolean | Yes | | | `IsILPostingApproved` | IL Posting Approved | Boolean | Yes | | | `IsSchemeGenerated` | Scheme Generated | Boolean | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ItemName` | Item Name | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `NetDiscount` | Net Discount | Calculated (calculated) | | | | `NetSchemeDiscount` | Net Scheme Discount | Calculated (calculated) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Calculated (calculated) | | | | `PriceAsOnDate` | Price As On Date | Date | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `PriceListRuleId` | Price List Rule | Lookup → [PriceListRule](/docs/reference/entities/price-list-rule/) | | | | `PurchaseOrderLineId` | Purchase Order Line | Lookup → [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) | | | | `Quantity` | Quantity | LargeNumber | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReturnedQuantity` | Returned Quantity | LargeNumber | | | | `SchemeDiscount` | Scheme Discount | Percent | | | | `SchemeDiscountAmount` | Scheme Discount Amount | Currency | | | | `SchemeLineId` | Scheme Line | Lookup → [SchemeLine](/docs/reference/entities/scheme-line/) | | | | `SchemeRewardPoints` | Scheme Reward Points | LargeNumber | | | | `SkipScheme` | Skip Scheme | Boolean | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `Tax1` | Tax1 | Currency | | | | `Tax1Name` | Tax1 Name | Text | | | | `Tax1Rate` | Tax1 Rate | Currency | | | | `Tax1Type` | Tax1 Type | Text | | | | `Tax2` | Tax2 | Currency | | | | `Tax2Name` | Tax2 Name | Text | | | | `Tax2Rate` | Tax2 Rate | Currency | | | | `Tax2Type` | Tax2 Type | Text | | | | `Tax3` | Tax3 | Currency | | | | `Tax3Name` | Tax3 Name | Text | | | | `Tax3Rate` | Tax3 Rate | Currency | | | | `Tax3Type` | Tax3 Type | Text | | | | `Tax4` | Tax4 | Currency | | | | `Tax4Name` | Tax4 Name | Text | | | | `Tax4Rate` | Tax4 Rate | Currency | | | | `Tax4Type` | Tax4 Type | Text | | | | `Tax5` | Tax5 | Currency | | | | `Tax5Name` | Tax5 Name | Text | | | | `Tax5Rate` | Tax5 Rate | Currency | | | | `Tax5Type` | Tax5 Type | Text | | | | `Tax6` | Tax6 | Currency | | | | `Tax6Name` | Tax6 Name | Text | | | | `Tax6Rate` | Tax6 Rate | Currency | | | | `Tax6Type` | Tax6 Type | Text | | | | `TaxAmount` | Tax Amount | Currency | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `TdsSectionId` | TDS Section | Lookup → [TdsSection](/docs/reference/entities/tds-section/) | | Tags the line with a withholding section. New lines with no section inherit the vendor's default section, and explicit tags plus already-saved lines are never overwritten. When the bill posts, a line with a section triggers a withholding entry that debits the payable and credits the withholding liability, reducing what is owed to the vendor; a failure there rolls back the whole posting. | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | The purchase cost per unit and the price-equivalent on this entity; BaseAmount is Quantity times UnitCost, unless UnitCost2 is non-zero in which case that wins. A validation rule against zero or negative cost exists but ships inactive. | | `UnitCost2` | Unit Cost 2 | Decimal | | An alternate cost taken from the price-list rule's second value, and it takes precedence: BaseAmount uses it whenever it is non-zero and only falls back to UnitCost otherwise. | | `UOM` | UOM | Text | | | | `UOM1` | UOM1 | PickList | | | | `UOMQuantity` | UOM Quantity | LargeNumber | | | | `UOMQuantity1` | UOM Quantity 1 | LargeNumber | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditIn` | Edit | EditInline | EditInLine | | `EditInLine` | Edit | Edit | Edit in page. | | `New` | Quick Add | NewInline | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Unit Cost Rule Validation | `UnitCost`, Error, inactive | Unit Cost should not be less than 0 | Prevents zero or negative unit cost | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Sku For Item | `SKUId` | Sku For Item | ## Related entities - [PriceListRule](/docs/reference/entities/price-list-rule/) — looks up via `PriceListRuleId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Bill](/docs/reference/entities/bill/) — looks up via `BillId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — looks up via `GoodsReceiptLineId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — looks up via `PurchaseOrderLineId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — looks up via `GeneralLedgerId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [TdsSection](/docs/reference/entities/tds-section/) — looks up via `TdsSectionId` - [SchemeLine](/docs/reference/entities/scheme-line/) — looks up via `SchemeLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — looks up via `BenefitId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — referenced by via `BillLineId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `BillLineId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `BillLineId` - [DebitNoteLine](/docs/reference/entities/debit-note-line/) — referenced by via `BillLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Bill — entity reference URL: https://xmatix.com/docs/reference/entities/bill/ Last reviewed: 2026-08-16 The vendor-side counterpart of Invoice and the terminus of procure-to-pay. It is released from a PurchaseOrder or raised against a GoodsReceipt, and its lines carry the quantities being billed. Posting writes one balanced journal — Dr goods-received-not-invoiced, inventory or expense plus input tax credit, Cr Accounts Payable — and raises a Payable OpenTransaction; the same run deducts TDS for any line carrying a withholding section and captures input-GST TaxTransaction rows that feed GSTR-2B reconciliation. Payment state lives in OpenAmount and AdjustedAmount rather than in Status, which is a seeded pick list no code path assigns. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountName` | Account Name | Text | | A free-text denormalised party name limited to twenty characters, which is short enough that most real vendor names are truncated. It is not maintained from the linked supplier account, so it can drift; resolve the vendor through SupplierAccountId instead of reading this field. | | `AdjustedAmount` | Adjusted Amount | Currency | | Running total of PaymentAdjustment amounts applied against this bill; the payment-application path adds each adjustment here and immediately recomputes OpenAmount as TotalAmount minus this value, and reversing an adjustment subtracts it back. It is the mirror image of OpenAmount. | | `AmountPaid` | Amount Pa | Currency | | The field is nevertheless locked against manual edits, so it will normally stay at zero. Use OpenAmount and AdjustedAmount, or the payable open item, to judge how much of a bill has been paid. | | `BillingAddress` | Billing Address | Text | | | | `BillingCity` | Billing City | PickList | | Values: Pune, Mumbai, Chandigarh. | | `BillingCityId` | Billing City | Lookup → [Place](/docs/reference/entities/place/) | | Values: Pune, Chandigarh, Mumbai. | | `BillingContactAddressId` | Billing Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `BillingCountry` | Billing Country | PickList | | Values: India. | | `BillingPostalCode` | Billing Postal Code | Text | | | | `BillingRegion` | Billing Region | Text | | | | `BillingState` | Billing State | PickList | | Values: New Delhi, Maharashtra, Punjab, Delhi, Haryana. | | `BillingStreet` | Billing Street | Text | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `DiscountGroupId` | Discount Group | Lookup → [DiscountGroup](/docs/reference/entities/discount-group/) | | | | `DocumentDate` | Document Date | Date | | | | `DueDate` | Due Date | Date | | When the vendor expects payment. Posting copies it onto the payable open item, and it is the basis for the ageing buckets — overdue days are measured from the due date, falling back to the document date when it is empty, so leaving it blank makes a bill age from its own date. | | `ExternalId` | External | Text | | | | `GeneralLedgerId` | General Ledger | Lookup → [GeneralLedger](/docs/reference/entities/general-ledger/) | | | | `GeneratedById` | Generated By | Lookup | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `GLAmount` | GL Amount | Calculated | | Nominally the header posting amount for a bill, but no calculated formula and no code path populates it. Because a bill that has lines derives its payable leg from the sum of the line amounts plus their tax, the header value is never consulted in practice and the field typically stays at zero. | | `GLPostingType` | GL Posting Type | PickList | | Selects the control account for the header leg: unset or 'Credit' posts to Accounts Payable, while 'Cash', 'Bank' and 'Credit Card' post to those account types instead, and anything else falls back to Accounts Payable. | | `GoodsReceiptId` | Goods Receipt | Lookup → [GoodsReceipt](/docs/reference/entities/goods-receipt/) | | | | `Id` | Id | Guid | Yes | | | `IsBillGenerated` | Bill Generated | Calculated (calculated) | Yes | Use PurchaseOrderId and GoodsReceiptId to establish provenance instead. | | `IsGLPosted` | GL Posted | Boolean | Yes | | | `IsGLPostingApproved` | GL Posting Approved | Boolean | | The posting gate. The posting action sets it before building the journal, and the posting engine reverses any existing journal instead of writing one whenever it is false or the bill is being deleted. It defaults to false, so a newly created bill does not post by itself. | | `IsKPICalculated` | KPI Calculated | Boolean | | | | `IsRCM` | Is RCM | Boolean | | Marks the bill as self-assessed under reverse charge. When set and the bill carries tax, posting diverts the tax portion away from Accounts Payable to a dedicated reverse-charge GST payable account and reduces the payable leg by that amount; posting fails outright if no such account can be resolved. It is also carried through to the input-GST capture as the reverse-charge flag. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OpenAmount` | Open Amount | Calculated | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The owning company or dealer entity rather than the vendor. It scopes posting-rule and account resolution, and posting is skipped altogether unless this account has GL posting enabled. It is non-editable after creation and, when the bill came from a goods receipt, cannot be edited away from the receipt's value. | | `PaymentTerms` | Payment Terms | Text | | | | `PerformGLPosting` | Perform GL Posting | Boolean | Yes | | | `PerformKPICalculation` | Perform KPI Calculation | Boolean | | | | `PlaceOfSupply` | Place of Supply | Calculated (calculated) | | Values: Maharashtra, Gujarat, Rajasthan, Haryana. | | `PriceAsOnDate` | Price As On Date | Date | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `PurchaseOrderId` | Purchase Order | Lookup → [PurchaseOrder](/docs/reference/entities/purchase-order/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `ResourceId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `RoundOff` | Round Off | Currency | | | | `ShippingAddress` | Shipping Address | Text | | | | `ShippingCity` | Shipping City | PickList | | Values: Pune, Mumbai, Chandigarh. | | `ShippingCityId` | Shipping City | Lookup → [Place](/docs/reference/entities/place/) | | Values: Pune, Mumbai, Chandigarh. | | `ShippingContactAddressId` | Shipping Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `ShippingCountry` | Shipping Country | PickList | | Values: India. | | `ShippingPostalCode` | Shipping Postal Code | Text | | | | `ShippingRegion` | Shipping Region | Text | | | | `ShippingState` | Shipping State | PickList | | Values: Maharashtra, New Delhi, Punjab, Delhi, Haryana. | | `ShippingStreet` | Shipping Street | Text | | | | `SkipScheme` | Skip Scheme | Boolean | Yes | | | `SourceOfSupply` | Source of Supply | PickList | | Values: Maharashtra, Gujarat, Rajasthan, Haryana. | | `Status` | Status | PickList | | Values: Draft, Approved, Rejected, Posted. | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | The vendor being paid — the party side of the payable, stamped on the AP control leg of the journal and on the resulting open item, and the account the open-documents lookup filters bills by. It is distinct from PartnerAccountId, the owning company, and cannot be changed after creation. | | `SupplierGSTIN` | Supplier GSTIN | Calculated (calculated) | | | | `SupplierInvoiceAmount` | Supplier Invoice Amount | Currency | | | | `SupplierInvoiceDate` | Supplier Invoice Date | Date | | | | `SupplierInvoiceNumber` | Supplier Invoice Number | Text | | The vendor's own document reference, as printed on their invoice, as opposed to Name which is the internally generated bill number. It is capped at eighteen characters, and it is what GST inward-supply reporting and vendor reconciliation match on. | | `Tax1` | Tax1 | Currency | | | | `Tax1Name` | Tax1 Name | Text | | | | `Tax1Rate` | Tax1 Rate | Currency | | | | `Tax1Type` | Tax1 Type | Text | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `TaxId` | Tax | Lookup → [Tax](/docs/reference/entities/tax/) | | | | `TaxSupplyType` | Tax Supply Type | PickList | | Values: Within State, Outside State, Exempt, Exports, SEZ. | | `TCSEligibleAmount` | TCS Eligible Amount | Currency | | | | `TotalAmount` | Total Amount | Calculated (calculated) | | | | `TotalDiscountAmount` | Total Discount Amount | Calculated (calculated) | | | | `TotalLineAmount` | Total Line Amount | Calculated (calculated) | | | | `TotalLineBaseAmount` | Total Line Base Amount | Calculated (calculated) | | | | `TotalLineGrossAmount` | Total Line Gross Amount | Calculated (calculated) | | | | `TotalLineTaxAmount` | Total Line Tax Amount | Calculated (calculated) | | | | `TotalQuantity` | Total Quantity | Calculated (calculated) | | | | `TotalSchemeDiscountAmount` | Total Scheme Discount Amount | Calculated (calculated) | | | | `TotalTaxAmount` | Total Tax Amount 1 | Calculated (calculated) | | | | `TotalTaxAmount2` | Total Tax Amount 2 | Calculated (calculated) | | | | `TotalTaxAmount3` | Total Tax Amount 3 | Calculated (calculated) | | | | `TransactionType` | Transaction Type | PickList | | Values: Type 1, Type 2, Type 3. | | `TypeOfBill` | Type of Bill | PickList | | Values: Expense Bill, OTC Purchase Bill, Purchase Bill. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete Selected | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditDetail` | Edit | EditInline | edit | | `EditInLine` | Edit | Edit | Edit in page. | | `EditInList` | Edit | EditInline | Edit | | `GetOpenDocuments` | Get Open Documents | ServerAction (`GetOpenDocuments`) | A read-only lookup that returns the open documents available to settle against, scoped to the bill's party and branch and to the payment direction, with an optional search key. It creates nothing — it is the picker behind a settlement screen, not a posting step. | | `GetPaymentAmountSummary` | Payment | ServerAction (`GetPaymentAmountSummary`) | A read-only summary for the bill: its total, how much has been adjusted, what remains open, and the payments and adjustments making up the difference. Returns data for display only and changes nothing. | | `New` | New | New | New | | `PerformGLPosting` | Post General Ledger | ServerAction (`PerformGLPosting`) | PostGeneralLedger | | `PerformInventoryPosting` | Post Inventory | ServerAction (`PerformInventoryPosting`) | This action perform inventory posting. | | `PostAdjustments` | Post Adjustments | ServerAction (`PostAdjustments`) | Bill settlement is recorded as PaymentAdjustment rows or, on the current open-item engine, SettlementAllocation rows against the bill's OpenTransaction. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Only Partner Account | `PartnerAccountId` | | | Only Supplier | `SupplierAccountId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [Place](/docs/reference/entities/place/) — looks up via `BillingCityId` - [Tax](/docs/reference/entities/tax/) — looks up via `TaxId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — looks up via `GoodsReceiptId` - [Place](/docs/reference/entities/place/) — looks up via `ShippingCityId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `ShippingContactAddressId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — looks up via `PurchaseOrderId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [DiscountGroup](/docs/reference/entities/discount-group/) — looks up via `DiscountGroupId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — looks up via `GeneralLedgerId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `BillingContactAddressId` - [DebitNoteLine](/docs/reference/entities/debit-note-line/) — referenced by via `BillId` - [GSTR3BRule37Tracker](/docs/reference/entities/gstr3-brule37-tracker/) — referenced by via `BillId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `BillId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `SourceRecordId` - [PaymentAdjustment](/docs/reference/entities/payment-adjustment/) — referenced by via `BillId` - [Payment](/docs/reference/entities/payment/) — referenced by via `BillId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `BillId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — referenced by via `BillId` - [DebitNote](/docs/reference/entities/debit-note/) — referenced by via `BillId` - [InterestCharge](/docs/reference/entities/interest-charge/) — referenced by via `SourceRecordId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ParentRecordId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `BillId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Book Valuation Adjustment — entity reference URL: https://xmatix.com/docs/reference/entities/book-valuation-adjustment/ Last reviewed: 2026-08-16 A per-book valuation overlay row from the multi-book design: rather than maintaining a parallel ledger, a secondary accounting book's statements are the primary general ledger plus these stored deltas. Each row is the amount by which one inventory-related statement line differs under the secondary book for one period, tagged with the line it lands on and the cause of the difference. Rows are produced by the overlay recomputation service, either on demand or as an advisory step during period close, and are not meant to be authored by hand. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountingBookId` | Accounting Book | Lookup → [AccountingBook](/docs/reference/entities/accounting-book/) | | The secondary book the overlay belongs to. The primary book never has overlay rows because it is the general ledger itself, so these rows only exist where a company runs more than one book. | | `Amount` | Amount | Currency | | A signed delta expressed as the secondary book's value minus the primary book's, rounded to two decimals. A statement line under that book is therefore the primary ledger figure plus the sum of the matching rows, so the sign convention matters when reading one in isolation. | | `AsOfDate` | As Of Date | Date | | The valuation date the delta was computed at, which is normally the end of the period the row is stamped with rather than the day the recomputation happened to run. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FiscalPeriodId` | Fiscal Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Source` | Source | Text | | What produced the difference: a different cost-flow method applied under the secondary book, a net-realizable-value write-down, or the reversal of an earlier write-down. | | `StatementLineType` | Statement Line Type | Text | | Which statement line the delta lands on, drawn from a fixed set covering the inventory asset, cost of goods sold, write-down loss, write-down reversal and the inventory provision contra-asset. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [AccountingBook](/docs/reference/entities/accounting-book/) — looks up via `AccountingBookId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `FiscalPeriodId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Branch Postal Code — entity reference URL: https://xmatix.com/docs/reference/entities/branch-postal-code/ Last reviewed: 2026-08-16 Maps one PostalCode to a Branch that serves it, optionally with the owning company (partnerAccountId) and a coverageType classification. It is the lookup table behind postal-code driven routing: on lead insert the lead service resolves the lead's postal code to a PostalCode row and stamps the lead's branchId and partnerAccountId from the first matching row here, and the nearby-branch search returns the active branches these rows link to a matched code. One code can map to many branches; lead assignment simply takes the first match per code. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CoverageType` | Coverage Type | PickList | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `LastModifiedById` | LastModifiedBy | Guid | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PostalCodeId` | Postal Code | Lookup → [PostalCode](/docs/reference/entities/postal-code/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Clone | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInList` | Edit | Edit | Edit in List Header | | `EditListHeader` | Edit | EditInline | EditListHeader | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [PostalCode](/docs/reference/entities/postal-code/) — looks up via `PostalCodeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Branch Time Slot Booking — entity reference URL: https://xmatix.com/docs/reference/entities/branch-time-slot-booking/ Last reviewed: 2026-08-16 The per-date consumption record of a BranchTimeSlot: one row per slot per bookingDate carrying that date's capacity and capacityUtilized. Documents that booked into the slot on that date point here - delivery orders via their requested delivery booking, product-demo appointments and opportunities via their time-slot booking lookups - so remaining capacity for a date is read from this row, not from the slot definition. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BookingDate` | Booking Date | Date | | | | `BranchTimeSlotId` | Branch Time Slot | Lookup → [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) | | | | `Capacity` | Capacity | Number | | | | `CapacityUtilized` | Capacity Utilized | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete | Delete | Delete | | `DeleteListRow` | Delete | Delete | DeleteListRow | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) — looks up via `BranchTimeSlotId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `OpportunityTimeSlotBookingId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `BranchTimeSlotBookingId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `RequestedDeliveryBranchTimeSlotBookingId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Branch Time Slot — entity reference URL: https://xmatix.com/docs/reference/entities/branch-time-slot/ Last reviewed: 2026-08-16 A bookable capacity window a Branch offers (startTime to endTime), with per-weekday capacity fields (mondayCapacity through sundayCapacity) and a maximumCapacity ceiling. Applicability can be narrowed to an item or item group and classified by serviceType, serviceJobType and transactionType. Slots are consumed by appointment and fulfilment flows: delivery orders reference a requested delivery slot, product-demo appointments and opportunities reference their appointment slot, and per-date consumption is tracked on child BranchTimeSlotBooking rows. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApplicableToItemGroupId` | Applicable To Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | | | `ApplicableToItemId` | Applicable To Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DisplayName` | Display Name | Calculated | | | | `EndTime` | End Time | TimeOnly | | | | `ExternalId` | External | Text | | | | `FridayCapacity` | Friday Capacity | Number | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Active | Boolean | | | | `MaximumCapacity` | Maximum Capacity | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `MondayCapacity` | Monday Capacity | Number | | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SaturdayCapacity` | Saturday Capacity | Number | | | | `ServiceJobType` | Service Job Type | PickList | | | | `ServiceType` | Service Type | PickList | | | | `StartTime` | Start Time | TimeOnly | | | | `SundayCapacity` | Sunday Capacity | Number | | | | `ThursdayCapacity` | Thursday Capacity | Number | | | | `TransactionType` | Transaction Type | PickList | | Values: Delivery, Product Demo At Site, Service Appointment. | | `TuesdayCapacity` | Tuesday Capacity | Number | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `WednesdayCapacity` | Wednesday Capacity | Number | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete Selected | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Maximum Capacity Rule Validation | `MaximumCapacity`, Error | Maximum Capacity cannot be Zero or Negative | Validation for Maximum Capacity should be greater than 0. | | To Duration Rule Validation | `EndTime`, Error | To Duration Cannot be less than From Duration | To Duration Cannot be less than From Duration | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ApplicableToItemGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Item](/docs/reference/entities/item/) — looks up via `ApplicableToItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `AppointmentTimeSlotId` - [BranchTimeSlotBooking](/docs/reference/entities/branch-time-slot-booking/) — referenced by via `BranchTimeSlotId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `RequestedDeliveryBranchTimeSlotId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `BranchTimeSlotId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Branch — entity reference URL: https://xmatix.com/docs/reference/entities/branch/ Last reviewed: 2026-10-09 A branch is one operating location of a company, such as a showroom, depot, service centre or office, and the place documents, stock and people are keyed to. Every branch belongs to one company through Partner Account. When a company has at least one branch, every document for that company must name one of its active branches, and a document whose branch belongs to another company is rejected; a company with no branches cannot carry a branch on its documents. Stock is kept per company and branch, and every storage location belongs to exactly one branch. A branch can carry its own GST registration, whose GSTIN and state are copied onto the branch. A resource's Default Branch fills the branch on documents that person creates, and the branch's Geo Location is the centre of the optional mobile check-in location gate. A new organization starts with no branches; an organization with one location can hide the branch dimension everywhere with the Org Settings switch We operate from multiple locations. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AllowInventory` | Allow Inventory | Boolean | | Records that the branch holds stock. Informational: no built-in process blocks documents based on it. Companies onboarded through partner onboarding get it ticked. | | `AllowPurchase` | Allow Purchase | Boolean | | Records that the branch buys. Informational: no built-in process blocks documents based on it. Companies onboarded through partner onboarding get it ticked. | | `AllowSales` | Allow Sales | Boolean | | Records that the branch sells. Informational: no built-in process blocks documents based on it. Companies onboarded through partner onboarding get it ticked. | | `AllowService` | Allow Service | Boolean | | Records that the branch provides service. Informational: no built-in process blocks documents based on it. Companies onboarded through partner onboarding get it ticked. | | `BranchCode` | Code | Text, unique | Yes | A short identifier for the branch. Required and unique across all branches. | | `BranchType` | Branch Type | PickList | Yes | Whether the branch is a sales or a service location. Required. Values: Sales Branch, Service Branch. The All Sales Branches and All Service Branches views filter on it. Values: Sales Branch, Service Branch. | | `BusinessHoursId` | Business Hours | Lookup → [BusinessHours](/docs/reference/entities/business-hours/) | | The branch's working week and time zone. Mobile attendance working-hours checks and time-zone handling use it for a resource who has no business hours of their own. | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | The business unit the branch belongs to. Shown on the record page only. | | `ContactAddressId` | Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | The branch's postal address, a contact address record. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DefaultInventoryValuationMethod` | Default Inventory Valuation Method | PickList | | Not used by any built-in process and has no values. | | `DocumentNameCode` | Document Name Code | Text | | A short code that, together with the company's code, forms an invoice's document series. Not part of the standard invoice numbering. | | `Email` | E-mail | Text, unique | | The branch e-mail address. Unique across branches when filled. | | `ExternalId` | External | Text, unique | | | | `GeoLocation` | Geo Location | GeoLocation | | The branch's position as latitude and longitude. It is the centre of the mobile check-in location gate for resources whose default branch this is; without it a check-in is allowed and the location is only recorded. Also used as the depot when van loads are planned. | | `GSTIN` | GSTIN | Calculated (calculated) | | The branch's GST identification number. Read-only, derived from the GST registration. | | `GSTRegistrationId` | GST Registration | Lookup → [GSTRegistration](/docs/reference/entities/gstregistration/) | | The GST registration the branch trades under. Choosing or changing it copies the registration's GSTIN and state onto the branch on save and fills an empty Partner Account. Documents raised at the branch file under this registration in preference to the company's default. | | `Id` | Id | Text | Yes | | | `InventoryValidationMethod` | Inventory Valation Method | PickList | | Not used by any built-in process and has no values. | | `IsActive` | Active | Boolean | | Whether the branch can be used. A document saved with an inactive branch is rejected with Branch is Inactive. Clear it to retire a branch while keeping its history. | | `IsHomeDeliveryAvailable` | Home Delivery | Boolean | | Records whether the branch offers home delivery. Informational. | | `IsServicePickupDropAvailable` | Service Pickup Drop | Boolean | | Records whether the branch offers service pickup and drop. Informational. | | `MarketingName` | Marketing Name | Text | | A customer-facing name for the location. Optional. | | `MobileNumber` | Mobile | Number | | The branch mobile number, stored as text so leading zeros are kept. Its dialling prefix is held in a separate country-code field that defaults to +91. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | The branch's name as it appears in lookups and on documents. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentLocationBranchId` | Parent Location | Lookup → [Branch](/docs/reference/entities/branch/) | | A parent branch, for recording a regional or hub-and-spoke structure. No built-in process uses the hierarchy. | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company that owns the branch. Documents are rejected when their branch does not belong to their company, and document Branch pickers list only the branches of the chosen company. Filled from the GST registration when left empty. | | `PayrollBusinessHoursId` | Payroll Business Hours | Lookup → [BusinessHours](/docs/reference/entities/business-hours/) | | Not used by any built-in process; attendance and payroll use Business Hours. | | `Phone` | Phone | LargeNumber | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SalesEmail` | Sales Email | Text | | | | `SalesPhone` | Sales Phone | LargeNumber | | The sales desk number. When filled it must be exactly 10 digits, otherwise saving fails with Phone number provided is not in a valid format. | | `ServiceEmail` | Service Email | Text | | | | `ServicePhone` | Service Phone | LargeNumber | | | | `SourceOfSupply` | Source of Supply | PickList | | The state the branch supplies from, set from the GST registration's state. Sales and purchase documents raised at the branch take it as their place of supply when they leave it empty. Values: Maharashtra, Gujarat, Rajasthan, Haryana. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `Website` | Website | Text | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Clone | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteInList` | Delete | Delete | Delete in a list page | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit In Page | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Phone Number Validation | `SalesPhone`, Error | Phone number provided is not in a valid format. | Check if the Mobile number is in valid format | ## Related entities - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `ContactAddressId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [GSTRegistration](/docs/reference/entities/gstregistration/) — looks up via `GSTRegistrationId` - [BusinessHours](/docs/reference/entities/business-hours/) — looks up via `BusinessHoursId` - [Branch](/docs/reference/entities/branch/) — looks up via `ParentLocationBranchId` - [BusinessHours](/docs/reference/entities/business-hours/) — looks up via `PayrollBusinessHoursId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [TdsChallan](/docs/reference/entities/tds-challan/) — referenced by via `BranchId` - [GLAccount](/docs/reference/entities/glaccount/) — referenced by via `BranchId` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — referenced by via `BranchId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `SupplierBranchId` - [PriceList](/docs/reference/entities/price-list/) — referenced by via `BranchId` - [LandedCost](/docs/reference/entities/landed-cost/) — referenced by via `BranchId` - [CheckInInspection](/docs/reference/entities/check-in-inspection/) — referenced by via `BranchId` - [Holiday](/docs/reference/entities/holiday/) — referenced by via `BranchId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — referenced by via `BranchId` - [KYCDocument](/docs/reference/entities/kycdocument/) — referenced by via `BranchId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `BranchId` - [Shipment](/docs/reference/entities/shipment/) — referenced by via `BranchId` - [Visit](/docs/reference/entities/visit/) — referenced by via `BranchId` - [TaxTransaction](/docs/reference/entities/tax-transaction/) — referenced by via `BranchId` - [StoreDealer](/docs/reference/entities/store-dealer/) — referenced by via `BranchId` - [EWayBill](/docs/reference/entities/eway-bill/) — referenced by via `BranchId` - [PublishedStatement](/docs/reference/entities/published-statement/) — referenced by via `BranchId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `BranchId` - [BranchPostalCode](/docs/reference/entities/branch-postal-code/) — referenced by via `BranchId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `BranchId` - [Claim](/docs/reference/entities/claim/) — referenced by via `BranchId` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — referenced by via `BranchId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `RelatedBranchId` - [CycleCount](/docs/reference/entities/cycle-count/) — referenced by via `BranchId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `BranchId` - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — referenced by via `BranchId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `BranchId` - [Case](/docs/reference/entities/case/) — referenced by via `BranchId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — referenced by via `BranchId` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `ToBranchId` - [PartnerResource](/docs/reference/entities/partner-resource/) — referenced by via `BranchId` - [DebitNote](/docs/reference/entities/debit-note/) — referenced by via `BranchId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `BranchId` - [Asset](/docs/reference/entities/asset/) — referenced by via `LastServiceBranchId` - [DiscountGroup](/docs/reference/entities/discount-group/) — referenced by via `BranchId` - [Journal](/docs/reference/entities/journal/) — referenced by via `BranchId` - [Asset](/docs/reference/entities/asset/) — referenced by via `SellingBranchId` - [Project](/docs/reference/entities/project/) — referenced by via `BranchId` - [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) — referenced by via `BranchId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `BranchId` - [Campaign](/docs/reference/entities/campaign/) — referenced by via `BranchId` - [ServiceBay](/docs/reference/entities/service-bay/) — referenced by via `BranchId` - [GLAccountPeriodBalance](/docs/reference/entities/glaccount-period-balance/) — referenced by via `BranchId` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — referenced by via `BranchId` - [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) — referenced by via `BranchId` - [ItemInventoryAttribute](/docs/reference/entities/item-inventory-attribute/) — referenced by via `BranchId` - [TaxGroup](/docs/reference/entities/tax-group/) — referenced by via `BranchId` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — referenced by via `BranchId` - [AutoOrder](/docs/reference/entities/auto-order/) — referenced by via `BranchId` - [Order](/docs/reference/entities/order/) — referenced by via `BranchId` - [PostingErrorLog](/docs/reference/entities/posting-error-log/) — referenced by via `BranchId` - [PurchaseOrderRequisition](/docs/reference/entities/purchase-order-requisition/) — referenced by via `BranchId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `BranchId` - [Compensation](/docs/reference/entities/compensation/) — referenced by via `BranchId` - [Quote](/docs/reference/entities/quote/) — referenced by via `BranchId` - [PayrollRun](/docs/reference/entities/payroll-run/) — referenced by via `BranchId` - [Payslip](/docs/reference/entities/payslip/) — referenced by via `BranchId` - [Payment](/docs/reference/entities/payment/) — referenced by via `BranchId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — referenced by via `BranchId` - [Position](/docs/reference/entities/position/) — referenced by via `BranchId` - [CampaignMember](/docs/reference/entities/campaign-member/) — referenced by via `BranchId` - [Requisition](/docs/reference/entities/requisition/) — referenced by via `BranchId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — referenced by via `BranchId` - [InventoryOpeningLotState](/docs/reference/entities/inventory-opening-lot-state/) — referenced by via `BranchId` - [ItemLot](/docs/reference/entities/item-lot/) — referenced by via `BranchId` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `BranchId` - [RecurringJournal](/docs/reference/entities/recurring-journal/) — referenced by via `BranchId` - [InventoryCostConsumption](/docs/reference/entities/inventory-cost-consumption/) — referenced by via `BranchId` - [ContactAddress](/docs/reference/entities/contact-address/) — referenced by via `BranchId` - [SchemeConsumption](/docs/reference/entities/scheme-consumption/) — referenced by via `BranchId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `BranchId` - [KPIData](/docs/reference/entities/kpidata/) — referenced by via `BranchId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `SupplierBranchId` - [GSTR6ISDDistribution](/docs/reference/entities/gstr6-isddistribution/) — referenced by via `ISDBranchId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `BranchId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `BranchId` - [BankAccount](/docs/reference/entities/bank-account/) — referenced by via `BranchId` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `BranchId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `RelatedBranchId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `BranchId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `BranchId` - [Employee](/docs/reference/entities/employee/) — referenced by via `BranchId` - [Adjustment](/docs/reference/entities/adjustment/) — referenced by via `BranchId` - [InventoryValuationPolicy](/docs/reference/entities/inventory-valuation-policy/) — referenced by via `BranchId` - [Resource](/docs/reference/entities/resource/) — referenced by via `DefaultBranchId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `BranchId` - [ClaimReconciliation](/docs/reference/entities/claim-reconciliation/) — referenced by via `BranchId` - [Branch](/docs/reference/entities/branch/) — referenced by via `ParentLocationBranchId` - [BookValuationAdjustment](/docs/reference/entities/book-valuation-adjustment/) — referenced by via `BranchId` - [Bill](/docs/reference/entities/bill/) — referenced by via `BranchId` - [EInvoice](/docs/reference/entities/einvoice/) — referenced by via `BranchId` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — referenced by via `BranchId` - [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) — referenced by via `BranchId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `BranchId` - [ShipmentAssetLine](/docs/reference/entities/shipment-asset-line/) — referenced by via `SellingBranchId` - [JournalLine](/docs/reference/entities/journal-line/) — referenced by via `BranchId` - [PostingDefinition](/docs/reference/entities/posting-definition/) — referenced by via `BranchId` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `BranchId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `BranchId` - [Requisition](/docs/reference/entities/requisition/) — referenced by via `FromBranchId` - [Scheme](/docs/reference/entities/scheme/) — referenced by via `BranchId` - [Asset](/docs/reference/entities/asset/) — referenced by via `BranchId` - [Lead](/docs/reference/entities/lead/) — referenced by via `BranchId` - [RecurringDepreciation](/docs/reference/entities/recurring-depreciation/) — referenced by via `BranchId` - [StorageLocation](/docs/reference/entities/storage-location/) — referenced by via `BranchId` - [PayrollPeriod](/docs/reference/entities/payroll-period/) — referenced by via `BranchId` - [FinanceCase](/docs/reference/entities/finance-case/) — referenced by via `BranchId` - [BudgetLine](/docs/reference/entities/budget-line/) — referenced by via `BranchId` - [ResourceAvailabilityData](/docs/reference/entities/resource-availability-data/) — referenced by via `BranchId` - [VisitPlan](/docs/reference/entities/visit-plan/) — referenced by via `BranchId` - [IncentiveResource](/docs/reference/entities/incentive-resource/) — referenced by via `BranchId` - [AssetDisposal](/docs/reference/entities/asset-disposal/) — referenced by via `BranchId` - [InventoryNrvAssessment](/docs/reference/entities/inventory-nrv-assessment/) — referenced by via `BranchId` - [VisitRouteGroup](/docs/reference/entities/visit-route-group/) — referenced by via `BranchId` - [ClaimBatch](/docs/reference/entities/claim-batch/) — referenced by via `BranchId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — referenced by via `BranchId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Budget Commitment — entity reference URL: https://xmatix.com/docs/reference/entities/budget-commitment/ Last reviewed: 2026-08-16 An encumbrance row: budget reserved against a GL account by an approved commitment document (purchase order or requisition) before any actual has posted, so the same money cannot be committed twice between approval and invoicing. BudgetCommitmentService sums CommittedAmount minus ConsumedAmount over rows in Open or PartiallyConsumed status for a company, fiscal year and GL account, and subtracts that open exposure on top of posted actuals in its availability check. Note the current state of the platform: no first-party handler yet creates, consumes or closes these rows — the purchase-order wiring that would populate them is not built, so in practice the table is empty and the actuals-only gate in BudgetControlService is what production code exercises. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | Optional business unit for the reservation. It is applied as a filter only when the caller's availability check itself specifies a business unit; an unscoped check counts commitments across all units. | | `CommitmentDate` | Commitment Date | DateAndTime | | When the budget was reserved. It is recorded for audit and reporting but is not a filter in the encumbrance calculation, which buckets purely by fiscal year — so a commitment dated outside its FiscalYearId still counts fully against that year. | | `CommittedAmount` | Committed Amount | Currency | | The gross amount reserved when the commitment document was approved. It is never reduced as the document is invoiced; the relief is recorded separately in ConsumedAmount, which keeps the original reservation auditable. | | `ConsumedAmount` | Consumed Amount | Currency | | How much of the reservation has since been invoiced and posted as a real actual. Open exposure is CommittedAmount minus this value, floored at zero so an over-consumed row cannot create negative encumbrance; the difference is what the availability check subtracts on top of posted actuals, preventing the same spend being counted twice. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentNumber` | Document Number | Text | | The human-readable number of the originating commitment document, denormalised so a commitment can be reviewed and reconciled without loading its source record. | | `FiscalYearId` | Fiscal Year | Lookup → [FiscalYear](/docs/reference/entities/fiscal-year/) | | The year the encumbrance is charged to, and the bucket the open-commitment sum groups by together with company and GL account. A commitment with a null or mismatched fiscal year is invisible to the availability check even though the row exists. | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The account whose budget is being reserved. The encumbrance query is keyed on this account, so the reservation only ever offsets budget lines for the same GL account — it does not cascade to parent accounts in the chart of accounts. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company whose budget is encumbered, not the supplier on the commitment document. It is a required part of the encumbrance lookup key (company + fiscal year + GL account), so the supplier belongs elsewhere on the source document. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SourceEntityName` | Source Entity Name | Text | | Name of the entity the commitment document lives in (a purchase order or requisition, for example), stored as free text alongside SourceRecordId to form a polymorphic back-pointer with no foreign key. It is descriptive only — the exposure query never filters on it. | | `SourceRecordId` | Source Record | Guid | | Identifier of the commitment document within the entity named by SourceEntityName. | | `Status` | Status | Text | | Lifecycle state with the vocabulary Open, PartiallyConsumed, Closed and Cancelled. Only Open and PartiallyConsumed rows are included in the encumbrance sum — Closed and Cancelled rows stop consuming budget entirely, regardless of their committed and consumed amounts. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDeleteHeader` | Delete | Delete | DeleteHeader | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | EditInLine | | `EditInLineHeader` | Edit | EditInline | EditInLineHeader | | `EditRow` | Edit | Edit | EditRow | | `NewHeader` | New | New | NewHeader | ## Related entities - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [FiscalYear](/docs/reference/entities/fiscal-year/) — looks up via `FiscalYearId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Budget Line — entity reference URL: https://xmatix.com/docs/reference/entities/budget-line/ Last reviewed: 2026-08-16 One budgeted amount for a GL account inside a Budget, optionally pinned to a fiscal period and to business unit, branch, cost-centre and partner dimensions. At most one line may exist per budget + GL account + fiscal period, and the amount must be greater than zero when entered; lines cannot be added or edited once the parent budget is Confirmed or Approved. Variance and forecast group lines by GL account and sum BudgetAmount, deriving the favourable/adverse sign from the account's Schedule III classification rather than from anything on the line; the budget income statement phases a line with no fiscal period evenly across the year's periods. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Branch dimension recorded on the line for reporting and for parity with the ledger's posting dimensions. No first-party budget service filters on it — variance scopes by the header's business unit and cost centre, and the availability gate by business unit only — so budgeting the same account by branch will not by itself produce branch-separated variance. | | `BudgetAmount` | Budget Amount | Currency | | The planned figure, validated to be strictly greater than zero when entered — enter it as a positive magnitude for both income and expense accounts. The favourable-versus-adverse direction is never taken from this value's sign; variance derives it from the account's Schedule III classification (credit-nature accounts are over budget when actual falls short, debit-nature when actual exceeds). | | `BudgetId` | Budget | Lookup → [Budget](/docs/reference/entities/budget/) | | | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | Line-level business unit. It is the only line dimension the availability gate filters on: when a caller supplies a business unit, both the budget side (these lines) and the consumption side (period balances) are narrowed to it. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FiscalPeriodId` | Fiscal Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | | Optional month/period this amount belongs to. Leave it null for an annual line: the budget income statement then spreads the amount evenly across the year's periods, whereas a period-stamped line lands wholly in that period's column. It is also part of the duplicate-line key, so the same GL account may appear once per period plus once more as an unphased annual line. | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The account being budgeted — the grain of every downstream comparison. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | GL Account Name | Text, unique | Yes | The platform record-name key for the line, carrying the display label 'GL Account Name'. It is a plain text key, not a link to the chart of accounts — the account is held in GLAccountId, and nothing in the budget services reads this column. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The owning company, duplicated onto the line. The availability gate matches lines on this column directly rather than walking up to the parent budget, so a line whose company does not match its budget's is skipped by the gate even though variance (which joins via BudgetId) still counts it. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | GL Account Filter | `GLAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `FiscalPeriodId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Budget](/docs/reference/entities/budget/) — looks up via `BudgetId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Budget — entity reference URL: https://xmatix.com/docs/reference/entities/budget/ Last reviewed: 2026-08-16 The planning header for one company (PartnerAccountId) and one fiscal year, optionally narrowed to a business unit and a cost centre; the money itself sits on its BudgetLine children, one per GL account. BudgetService enforces that only one active budget may exist per company + business unit + fiscal year, and freezes a budget once its Status reaches Confirmed or Approved (from then on only Status itself may change, on the header and on its lines). Three services read it: BudgetVarianceService (budget vs posted ledger actuals for the year, scoping actuals to the budget's business unit and cost centre), BudgetControlService (run-rate full-year forecast, plus the availability gate that answers whether an account still has budget for a proposed spend), and the budget-vs-actual income statement. Nothing about a budget posts to the ledger — it is a comparison baseline only. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | Optional business-unit scope for the whole budget: it participates in the one-active-budget-per-scope uniqueness check (a null business unit is a distinct scope from any named one), and when set it restricts the posted actuals that variance, forecast and the budget income statement compare against to that unit's period balances. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FiscalYearId` | Fiscal Year | Lookup → [FiscalYear](/docs/reference/entities/fiscal-year/) | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | Controls whether the budget reserves its scope and counts as authoritative: only active budgets conflict in the one-budget-per-scope uniqueness check, and only active budgets contribute lines to the availability gate. Deactivating is therefore how a superseded plan is retired without deleting it. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company (legal entity) whose plan this is — not a customer or supplier, despite the account lookup. It is one of the three keys of the uniqueness rule (company + business unit + fiscal year) and the key the availability gate and the variance and forecast services filter on, so a budget stamped with the wrong company is invisible to all of them. | | `PlannedAmount` | Planned Amount | Calculated (calculated) | | A stored rollup, not a hand-entered figure: the calculated-field engine recomputes it on every save from the formula summing BudgetAmount across the budget's lines. It is deliberately listed alongside the audit columns in the frozen-budget guard, so this automatic recomputation does not itself count as an illegal edit to a Confirmed or Approved budget. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Status` | Status | PickList | | Workflow state, defaulting to Draft. Confirmed and Approved are treated as locked (case-insensitively): once a budget is in either, the handler rejects any save that modifies a non-audit field other than Status itself, and its lines become read-only too. Reverting to Draft is the documented way back in. Values: Draft, Cancelled, Confirmed. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInline` | Edit Inline | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [FiscalYear](/docs/reference/entities/fiscal-year/) — looks up via `FiscalYearId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Campaign](/docs/reference/entities/campaign/) — referenced by via `BudgetId` - [BudgetLine](/docs/reference/entities/budget-line/) — referenced by via `BudgetId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Business Hour — entity reference URL: https://xmatix.com/docs/reference/entities/business-hours/ Last reviewed: 2026-08-16 A working-hours calendar: timeZoneId (a .NET TimeZoneInfo id, null = UTC), workingDaysMask (a bitmask of working weekdays), and the working-day window as minutes from local midnight (dayStartMinutes/dayEndMinutes). Used by the Case SLA engine for due-date math (via SLAPolicy.businessHoursId or Case.businessHoursId), by branches as their operating hours, and by scheduling (BookableResource working-hours fallback). An unconfigured mask (0) makes the SLA calculator fall back to 24x7. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DayEndMinutes` | Day End (min) | Number | | | | `DayStartMinutes` | Day Start (min) | Number | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `TimeZoneId` | Time Zone | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `WorkingDaysMask` | Working Days (mask) | Number | | Bitmask of working weekdays: bit (1 << DayOfWeek) with Sunday=0 through Saturday=6, so Monday-Friday = 62. 0 = unconfigured, which makes the SLA calculator fall back to 24x7. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | Delete Entity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLineList` | Edit | EditInline | EditInLineList | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — looks up via `BusinessHoursId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Case](/docs/reference/entities/case/) — referenced by via `BusinessHoursId` - [Scheme](/docs/reference/entities/scheme/) — referenced by via `BusinessHoursId` - [Branch](/docs/reference/entities/branch/) — referenced by via `BusinessHoursId` - [Resource](/docs/reference/entities/resource/) — referenced by via `BusinessHoursId` - [Branch](/docs/reference/entities/branch/) — referenced by via `PayrollBusinessHoursId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Business Unit — entity reference URL: https://xmatix.com/docs/reference/entities/business-unit/ Last reviewed: 2026-08-16 An operational division that consolidates one or more Branches for segment accounting and reporting, self-nesting through ParentBusinessUnitId and optionally owned by a partner company through PartnerAccountId. Do not confuse it with the identically named security construct in the metadata schema, which is part of the user org structure and surfaces as the User.BusinessUnits token in lookup filters and expressions; the two are unrelated tables with no link between them. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BusinessUnitCode` | Business Unit Code | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentBusinessUnitId` | Parent Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | Self-reference forming the division hierarchy. It is not walked by any platform code - consumers reference a single business unit directly, so rolling reporting up the tree is left to the report or dataset that needs it. | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The partner company (an Account with the partner flag set) this division belongs to - the company dimension on an otherwise standalone hierarchy. Optional, so a business unit can exist unattached to any company. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `ParentBusinessUnitId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `BusinessUnitId` - [SalaryStructure](/docs/reference/entities/salary-structure/) — referenced by via `BusinessUnitId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `BusinessUnitId` - [Employee](/docs/reference/entities/employee/) — referenced by via `BusinessUnitId` - [PayrollRun](/docs/reference/entities/payroll-run/) — referenced by via `BusinessUnitId` - [BusinessUnit](/docs/reference/entities/business-unit/) — referenced by via `ParentBusinessUnitId` - [InventoryValuationPolicy](/docs/reference/entities/inventory-valuation-policy/) — referenced by via `BusinessUnitId` - [TaxTransaction](/docs/reference/entities/tax-transaction/) — referenced by via `BusinessUnitId` - [GLAccount](/docs/reference/entities/glaccount/) — referenced by via `BusinessUnitId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `BusinessUnitId` - [Project](/docs/reference/entities/project/) — referenced by via `BusinessUnitId` - [Branch](/docs/reference/entities/branch/) — referenced by via `BusinessUnitId` - [PartyPeriodBalance](/docs/reference/entities/party-period-balance/) — referenced by via `BusinessUnitId` - [Budget](/docs/reference/entities/budget/) — referenced by via `BusinessUnitId` - [CostCenter](/docs/reference/entities/cost-center/) — referenced by via `BusinessUnitId` - [BudgetCommitment](/docs/reference/entities/budget-commitment/) — referenced by via `BusinessUnitId` - [PublishedStatement](/docs/reference/entities/published-statement/) — referenced by via `BusinessUnitId` - [BudgetLine](/docs/reference/entities/budget-line/) — referenced by via `BusinessUnitId` - [Journal](/docs/reference/entities/journal/) — referenced by via `BusinessUnitId` - [GLAccountPeriodBalance](/docs/reference/entities/glaccount-period-balance/) — referenced by via `BusinessUnitId` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — referenced by via `BusinessUnitId` - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — referenced by via `BusinessUnitId` - [RevenueRecognitionSchedule](/docs/reference/entities/revenue-recognition-schedule/) — referenced by via `BusinessUnitId` - [ConsolidationGroupMember](/docs/reference/entities/consolidation-group-member/) — referenced by via `BusinessUnitId` - [JournalLine](/docs/reference/entities/journal-line/) — referenced by via `BusinessUnitId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Call — entity reference URL: https://xmatix.com/docs/reference/entities/call/ Last reviewed: 2026-08-16 A telephony call log row (Call Register / CTI) - one row per inbound or outbound call. Generic, not case-specific: it links to or creates ANY record via the polymorphic relatedEntityName/relatedEntityId pair (Case, Order, Appointment, Lead, ...), which drives the screen-pop and the timeline Activity target. A ringing call is routed through the same Omni-Channel substrate as cases (resourceWorkId, queueId); on a terminal status (Completed, Missed, Voicemail, Failed, Declined) the handler computes waitSeconds (ring to answer) and durationSeconds (answer to end) and writes exactly one Call Activity onto the linked record (activityId is the idempotency guard). resourceName/queueName are denormalized display names stamped by the handler so lists and reports need no joins. Transcript text lives in the separate Transcript entity; transcriptStatus on the call is just a pipeline pointer (None/Pending/Ready/Failed). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `ActivityId` | Activity | Lookup, hidden | | | | `AnswerUtc` | Answered | DateAndTime | | | | `CallId` | Call Id | Text | | | | `ContactId` | Contact | Lookup → [Contact](/docs/reference/entities/contact/) | | | | `Direction` | Direction | PickList | | Values: Inbound, Outbound. | | `DurationSeconds` | Duration (s) | Number | | | | `EndUtc` | Ended | DateAndTime | | | | `FromNumber` | From | Text | | | | `Notes` | Notes | MultiLineText | | | | `Outcome` | Outcome | PickList | | Business result of the call (Answered, Missed, Voicemail, Declined, Abandoned, Resolved) - distinct from Status, which is the telephony lifecycle state (Ringing, InProgress, Completed, Missed, Voicemail, Failed, Declined). Values: Answered, Missed, Voicemail, Declined, Abandoned, Resolved, Follow Up Required, Call Back Later, Escalated, No Answer, Wrong Number, Complaint, Sale, Information Provided, Diagnostic Decision, Scheduled Inspection, Case Logged. | | `Provider` | Provider | Text | | | | `QueueId` | Queue | Lookup → [Queue](/docs/reference/entities/queue/), hidden | | | | `QueueName` | Queue | Text | | | | `RecordingUrl` | Recording URL | Text | | | | `RelatedEntityId` | Related record id | Lookup, hidden | | | | `RelatedEntityLabel` | Related record | Text | | | | `RelatedEntityName` | Related entity | Text | | Metadata entity name of the record this call is about - polymorphic with RelatedEntityId, no DB FK; any entity qualifies (Case, Order, Appointment, Lead, ...). Drives the screen-pop and decides where the terminal-call timeline Activity is written. | | `ResourceId` | Agent | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `ResourceName` | Agent | Text | | | | `ResourceWorkId` | Work item | Lookup, hidden | | | | `RingStartUtc` | Ring start | DateAndTime | | | | `Status` | Status | PickList | | Values: Ringing, InProgress, Completed, Missed, Voicemail, Failed, Declined. | | `ToNumber` | To | Text | | | | `TranscriptStatus` | Transcript status | PickList | | Transcription pipeline pointer (None / Pending / Ready / Failed). The transcript text itself is a separate Transcript row linked back to this call via its relatedEntityName/relatedEntityId - never stored on the Call. Values: None, Pending, Ready, Failed. | | `WaitSeconds` | Wait (s) | Number | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `CreateRecordFromCall` | Create record | ServerAction (`CreateRecordFromCall`) | Creates a new record from the call and links the call to it. Default creatable targets are Case, Lead, Opportunity, Order, ServiceOrder and Task, overridable via the Telephony:CreatableEntities setting. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | UIAction | EditEntity | | `EditEntityDetails` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInLineList` | Edit | EditInline | EditInLineList | | `LinkToRecord` | Link to record | ServerAction (`LinkToRecord`) | Links the call to an existing record of ANY entity by setting the polymorphic RelatedEntityName/RelatedEntityId (plus label). Once the call reaches a terminal status, its timeline Activity is written onto that record. | | `New` | New | New | New | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Campaign Item — entity reference URL: https://xmatix.com/docs/reference/entities/campaign-item/ Last reviewed: 2026-08-16 One item or service the campaign offers (campaignId is the parent; itemId the catalog item, with optional itemServiceContractId and quantity). When ProcessOpportunities runs, each member's generated Opportunity gets one OpportunityLine per campaign item; when ProcessAssets runs, each member gets one AssetMaintenance row per item carrying the item, quantity, contract link and the isMandatory flag. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IsMandatory` | Is Mandatory | Boolean | Yes | Marks the campaign item as non-optional; it is copied onto generated records as OpportunityLine.IsCampaignMandatory and AssetMaintenance.IsMandatory. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | Yes | | | `ItemServiceContractId` | Item Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | Optional service-contract product attached to this campaign item; carried onto the OpportunityLine / AssetMaintenance rows the generation actions create. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `CampaignId` | Campaign | Lookup → [Campaign](/docs/reference/entities/campaign/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | Edit Entity | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [Campaign](/docs/reference/entities/campaign/) — looks up via `CampaignId` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — referenced by via `CampaignItemId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `CampaignItemId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Campaign Member — entity reference URL: https://xmatix.com/docs/reference/entities/campaign-member/ Last reviewed: 2026-08-16 One targeted Account and/or Asset in a Campaign - the row the generation actions fan out from. Built by the campaign's ProcessMembers action: it resolves the accounts or assets matching the campaign's rules, inserts one member per match tagged with a fresh batchInstanceId, and soft-deletes the members left over from earlier runs, so membership is a rebuilt snapshot, not an append-only list. Members carry the campaign's partnerAccountId/branchId forward onto every Lead, Opportunity and AssetMaintenance generated from them, and generated records link back via their CampaignMemberId. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `BatchInstanceId` | Batch Instance | Text | | The build-run tag: each ProcessMembers run stamps a fresh id on the members it inserts and soft-deletes the members carrying any older id. A member's tag therefore tells you which rebuild produced it; the same run-tag pattern (CampaignBatchInstanceId) sweeps stale generated Leads/Opportunities/AssetMaintenance on the generation actions. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DueDate` | Due Date | Date | | | | `EmailOptOut` | Email Opt Out | Boolean | Yes | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `MessagingOptOut` | Messaging Opt Out | Boolean | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `CampaignId` | Campaign | Lookup → [Campaign](/docs/reference/entities/campaign/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteRow` | Delete | Delete | DeleteRow | | `Edit` | Edit | EditInline | Edit | | `EditInLine` | Edit In Line | EditInline | Edit member line | | `EditRow` | Edit | Edit | EditRow | | `New` | New | NewInline | New | ## Related entities - [Campaign](/docs/reference/entities/campaign/) — looks up via `CampaignId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — referenced by via `CampaignMemberId` - [Lead](/docs/reference/entities/lead/) — referenced by via `CampaignMemberId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `CampaignMemberId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Campaign Rule — entity reference URL: https://xmatix.com/docs/reference/entities/campaign-rule/ Last reviewed: 2026-08-16 One dynamic-membership condition under a Campaign: fieldName + operation + fieldValue evaluated against the member object (Account or Asset) by the shared group-rule engine when ProcessMembers runs. Rules are combined per the campaign's ruleSuccessCriteria (all / any / custom logic over the rules' 1-based sequence numbers). Same pattern as AccountGroupRule and ItemGroupRule. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FieldName` | Field Name | Text | | The member-object field the rule tests (an Account or Asset field per the campaign's dynamicMemberObject). Rules on real scalar columns are pushed to SQL as parameterized predicates; anything else (custom fields, untranslatable operators) is evaluated in memory. | | `FieldValue` | Field Value | Text | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `ObjectType` | Object Type | PickList | | Values: Account, Asset, Service Order, Opportunity, Lead, Lead, Opportunity, Case, DMS Case. | | `Operation` | Operation | PickList | | Comparison operator understood by the group-rule engine: equals, notequal, lessthan, greaterthan, lessorequal, greaterorequal, like, in, notin, includes, excludes. Numeric comparisons are scale-insensitive ('10000.00' equals 10000). Values: Equals, Less Than, Like, Includes, Not In. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SequenceNumber` | Sequence Number | Number | | Evaluation order of the rule, and the 1-based number the campaign's custom success logic refers to (e.g. '1 AND (2 OR 3)'). | | `CampaignId` | Campaign | Lookup → [Campaign](/docs/reference/entities/campaign/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `EditInLineHeader` | Edit | EditInline | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Campaign](/docs/reference/entities/campaign/) — looks up via `CampaignId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Campaign — entity reference URL: https://xmatix.com/docs/reference/entities/campaign/ Last reviewed: 2026-08-16 An outreach/recall campaign in the service module: it defines who is targeted (rule-built CampaignMember rows over Accounts or Assets, per dynamicMemberObject and the child CampaignRule rows) and what is offered (child CampaignItem rows), then its Process* server actions generate the downstream records - Leads, Opportunities (with lines copied from the campaign items), or AssetMaintenance rows - one per member, plus contract/maintenance-schedule reminder leads driven by the reminderDaysOffset fields. Every Process action requires the campaign to be active and (except ProcessMembers, which checks it internally) inside its start/end date window. Generated records are tagged with a per-run batch instance id and each rerun sweeps the previous run's output, so campaign output reflects the latest member set rather than accumulating. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup | | | | `AdjustedAmount` | Adjusted Amount | Currency | | | | `AdjustmentId` | Adjustment | Lookup → [Adjustment](/docs/reference/entities/adjustment/) | | | | `Amount` | Amount | Decimal | | | | `ApexJobId` | Apex Job | Text | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Currency` | Currency | PickList | | Values: USD. | | `DocumentDate` | Document Date | Date | Yes | | | `DynamicMemberObject` | Dynamic Member Object | PickList | | Which entity the member build targets: Account (also the default when empty) or Asset. Values: Asset, Account. | | `DynamicMemberType` | Dynamic Member Type | PickList | | Values: Field Filter, Report Data. | | `EndDate` | End Date | Date | | | | `ExternalId` | External | Text | | | | `FromEngineSeries` | From Engine Series | Number | | | | `GeneralLedgerId` | General Ledger | Lookup | | | | `GLAccountId` | GL Account | Lookup | | | | `GLAmount` | GL Amount | Decimal | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | Yes | Master switch for the generation actions: every Process* action validates the campaign is active (and, except ProcessMembers, within its start/end dates) before running; the services re-check the same gates when loading the campaign. | | `IsGLPosted` | Is GL Posted | Boolean | Yes | | | `IsGLPostingApproved` | Is GL Posting Approved | Boolean | Yes | | | `ItemMaintenanceScheduleId` | Item Maintenance Schedule | Lookup → [ItemMaintenanceSchedule](/docs/reference/entities/item-maintenance-schedule/) | | | | `ItemServiceContractId` | Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | The service-contract product this campaign follows up on: ProcessContractSchedule scans un-utilized AssetServiceContract rows with this itemServiceContractId falling due inside the reminder window and creates the reminder leads from them. | | `LeadId` | Lead | Lookup → [Lead](/docs/reference/entities/lead/) | | | | `ManualAssetAction` | ManualAssetAction | Boolean | | Controls when the campaign's pending AssetMaintenance items are pulled into an Opportunity or ServiceOrder for the asset: false means they are added automatically when the document is created; true means they are added only when a user explicitly triggers the populate-asset-maintenance flag on the document. The pull matches campaigns whose flag equals the invocation mode, so an automatic pass never picks up manual-only campaigns and vice versa. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `Notes` | Notes | MultiLineText | | | | `OpenAmount` | Open Amount | Decimal | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentCampaignId` | Campaign | Lookup → [Campaign](/docs/reference/entities/campaign/) | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PerformGLPosting` | Perform GL Posting | Boolean | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReminderDaysOffset1` | Reminder Days Offset 1 | Number | | First reminder window in days for the schedule-driven actions: ProcessContractSchedule / ProcessMaintenanceSchedule create a reminder Lead when a contract's due date is exactly today plus this offset (the lead's ReminderOffsetNumber is stamped 1). The largest of the three offsets bounds how far ahead contracts are scanned. | | `ReminderDaysOffset2` | Reminder Days Offset 2 | Number | | Second reminder window in days - a due date exactly today plus this offset produces a reminder Lead stamped ReminderOffsetNumber 2. See reminderDaysOffset1 for the mechanism. | | `ReminderDaysOffset3` | Reminder Days Offset 3 | Number | | Third reminder window in days - a due date exactly today plus this offset produces a reminder Lead stamped ReminderOffsetNumber 3. See reminderDaysOffset1 for the mechanism. | | `ReportId` | Report | Text | | | | `RuleSuccessCriteria` | Rule Success Criteria | PickList | | How the CampaignRule rows combine in the member build: 'Always (No Criteria)' or empty matches every row, 'All Rules Are Met' requires all, 'Any Rule Is Met' requires at least one, 'Custom Logic Is Met' evaluates ruleSuccessCustomLogic. Gotcha: the engine matches these exact strings and treats anything unrecognized as all-rules-must-match - the seeded picklist spelling 'Any Rules Are Met' is NOT the engine's 'Any Rule Is Met' and therefore behaves as ALL. Values: All Rules Are Met, Any Rules Are Met, Always (No Criteria), Custom Logic Is Met. | | `RuleSuccessCustomLogic` | Rule Success Custom Logic | Text | | Boolean expression over the rules' 1-based sequence numbers, e.g. '1 AND (2 OR 3)', used when ruleSuccessCriteria is 'Custom Logic Is Met'. Evaluated in memory by the group-rule engine. | | `ServiceContractId` | Service Contract | Lookup | | | | `ServiceLeadId` | ServiceLead | Guid | | | | `StartDate` | Start Date | Date | | | | `Status` | Status | PickList | | Values: Draft, Start, In Progress, On Hold. | | `ToEngineSeries` | To Engine Series | Number | | | | `Type` | Type | PickList | | Values: Recall - Asset Actions, Marketing;Service. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | EditInline | Edit | | `Edit2` | Edit | EditInline | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `EditRow` | Edit | Edit | Edit | | `New` | New | New | New | | `ProcessAssets` | Process Assets | ServerAction (`ProcessAssets`) | Creates AssetMaintenance rows - one per member per CampaignItem - carrying the member's asset and the item's quantity/contract/mandatory attributes. These are the pending recall/maintenance actions later pulled into Opportunities or ServiceOrders for the asset (automatically or manually per the campaign's manualAssetAction). Requires the campaign active and inside its date window; reruns sweep the previous batch. | | `ProcessContractSchedule` | Process Contract Schedule | ServerAction (`ProcessContractSchedule`) | Generates contract-renewal reminder Leads: scans un-utilized AssetServiceContract rows for the campaign's itemServiceContractId whose dueDate lands exactly on today plus one of the campaign's reminderDaysOffset1/2/3, and creates one lead per hit stamped with the matching ReminderOffsetNumber. Requires the campaign active and inside its date window. Intended to run daily (each day matches the contracts whose due date crosses an offset boundary). | | `ProcessLeads` | Process Leads | ServerAction (`ProcessLeads`) | Creates one Draft Lead per CampaignMember, carrying the member's account/asset/partner/branch links and a back-reference to the campaign and member. Requires the campaign active and inside its start/end window. Each run tags its leads with a batch id and hard-deletes the campaign's leads from earlier runs - so rerunning replaces previously generated (unconverted) leads rather than adding to them. | | `ProcessMaintenanceSchedule` | Process Maintenance Schedule | ServerAction (`ProcessMaintenanceSchedule`) | Requires the campaign active and inside its date window. | | `ProcessMembers` | Process Members | ServerAction (`ProcessMembers`) | Rebuilds the campaign's member list: resolves the Accounts or Assets (per dynamicMemberObject) matching the CampaignRule rows under ruleSuccessCriteria, inserts one CampaignMember per match tagged with a fresh batch id, then soft-deletes members from earlier runs - build and sweep commit in one unit of work so the campaign is never left member-less in between. Run this before any of the generation actions - they all fan out from the current member rows. | | `ProcessOpportunities` | Process Opportunities | ServerAction (`ProcessOpportunities`) | Creates one Opportunity per CampaignMember plus one OpportunityLine per CampaignItem under each (copying item, quantity, contract link and the mandatory flag). Requires the campaign active and inside its date window. Reruns replace: earlier runs' opportunities for this campaign are deleted and the new batch takes their place. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Customer Account Filter | `AccountId` | | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [Campaign](/docs/reference/entities/campaign/) — looks up via `ParentCampaignId` - [Budget](/docs/reference/entities/budget/) — looks up via `BudgetId` - [Lead](/docs/reference/entities/lead/) — looks up via `LeadId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [ItemMaintenanceSchedule](/docs/reference/entities/item-maintenance-schedule/) — looks up via `ItemMaintenanceScheduleId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Adjustment](/docs/reference/entities/adjustment/) — looks up via `AdjustmentId` - [Lead](/docs/reference/entities/lead/) — referenced by via `CampaignId` - [CampaignMember](/docs/reference/entities/campaign-member/) — referenced by via `CampaignId` - [Campaign](/docs/reference/entities/campaign/) — referenced by via `ParentCampaignId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `CampaignId` - [CampaignRule](/docs/reference/entities/campaign-rule/) — referenced by via `CampaignId` - [CampaignItem](/docs/reference/entities/campaign-item/) — referenced by via `CampaignId` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — referenced by via `CampaignId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `CampaignId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `CampaignId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Case Milestone — entity reference URL: https://xmatix.com/docs/reference/entities/case-milestone/ Last reviewed: 2026-08-16 A live SLA timer on a Case - one row per milestone the applied SLAPolicy tracks (kind FirstResponse, Resolution, or a custom MilestoneConfig name). targetUtc is the business-hours-adjusted deadline and shifts forward while the case clock is paused (pausedMinutes accumulates and is added back on resume). Status runs Pending / Warning / Breached / Met / Paused / Cancelled; the SLA scheduler scans these rows for warnings and breaches, and the case handler completes them. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CaseId` | Case | Lookup → [Case](/docs/reference/entities/case/) | Yes | | | `CompletedUtc` | Completed | DateAndTime | | | | `IsBreached` | Breached | Boolean | | | | `Kind` | Kind | Text | | Which milestone this timer tracks: FirstResponse or Resolution (the two built-ins driven by the policy's minute targets), or the name of a custom MilestoneConfig. | | `MilestoneConfigId` | Milestone Config | Lookup → [MilestoneConfig](/docs/reference/entities/milestone-config/) | | | | `PausedMinutes` | Paused (min) | Number | | | | `SLAPolicyId` | SLA Policy | Lookup → [SLAPolicy](/docs/reference/entities/slapolicy/) | | | | `StartUtc` | Start | DateAndTime | | | | `Status` | Status | PickList | | Values: Pending, Warning, Breached, Met, Paused, Cancelled. | | `TargetMinutes` | Target (min) | Number | | | | `TargetUtc` | Target | DateAndTime | | | | `WarningUtc` | Warning At | DateAndTime | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `EditInLine` | Edit | EditInline | Edit in page. | ## Related entities - [Case](/docs/reference/entities/case/) — looks up via `CaseId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Case SLA Event — entity reference URL: https://xmatix.com/docs/reference/entities/case-slaevent/ Last reviewed: 2026-08-16 An immutable audit entry for an SLA state change on a Case: eventType is Applied, Warning, Breached, Paused, Resumed, Met or Cancelled, with occurredUtc and an optional detail. Written by the SLA engine as policies apply and milestones change; feeds the case timeline and SLA-compliance reporting. Links to the case, the milestone (caseMilestoneId) and the policy (slaPolicyId). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CaseId` | Case | Lookup → [Case](/docs/reference/entities/case/) | Yes | | | `CaseMilestoneId` | Milestone | Lookup → [CaseMilestone](/docs/reference/entities/case-milestone/) | | | | `Detail` | Detail | Text | | | | `EventType` | Event Type | PickList | | Values: Applied, Warning, Breached, Paused, Resumed, Met, Cancelled. | | `OccurredUtc` | Occurred | DateAndTime | | | | `SLAPolicyId` | SLA Policy | Lookup → [SLAPolicy](/docs/reference/entities/slapolicy/) | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `EditInLine` | Edit | EditInline | Edit in page. | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Case — entity reference URL: https://xmatix.com/docs/reference/entities/case/ Last reviewed: 2026-10-09 A case is the record of one customer-reported issue or request, tracked from first contact to close. It lives in the Support app. On creation it receives a case number from document numbering (shipped series CS), the status New and an opened time, fills blank contact details from its account, attaches the first matching active SLA policy and records an acknowledgement email on its timeline. It then moves through the lifecycle states New, Assigned, In Progress, On Hold, Waiting on Customer, Waiting on Third Party, Escalated, Resolved, Closed, Reopened and Cancelled. Resolving requires a resolution summary and closing requires a close reason; which moves are allowed is set by editable business rules shipped with the product. Status and assignment changes are written to the case timeline. Cases can be routed through a queue, escalated, merged, copied, and turned into a lead, an opportunity, a service order or an appointment. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer the case is for. When left blank and an asset is chosen, it is filled from the asset's owning account. Blank contact details on the case are filled from this account and its contacts. | | `AccountName` | Account Name | Text | | The account's name, copied from the account when blank. | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | The equipment the issue concerns. Only assets of the selected account are offered; choosing one with no account set fills the account from the asset's owner. | | `AssignedToId` | Assigned To | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | The agent working the case now, as distinct from the record owner. Each change is written to the case timeline. Accepting a case routed from a queue sets both this field and the owner to the accepting agent. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The partner location handling the case. Only branches of the selected partner account are offered. Required before a service order can be raised from the case. | | `BusinessHoursId` | Business Hour | Lookup → [BusinessHours](/docs/reference/entities/business-hours/) | | The working calendar used for this case's SLA time calculations. | | `CaseNumber` | Case Number | Text, unique | | The case's reference, set once at creation from document numbering (shipped series CS followed by the date and a six-digit sequence). It does not change, including when the case is merged into another. | | `CaseReason` | Case Reason | PickList | | The underlying cause category of the issue. Values: Installation, Equipment Complexity, Performance, Equipment Design, Feedback. | | `CaseSource` | Case Source | PickList | | How the case reached the support desk. Routing uses it as the channel when none is given. Values: Voice / Call, Email. | | `Category` | Category | PickList | | The broad kind of issue. SLA policies and business rules can match on it. Values: Service, Refund, Safety, Billing. | | `ClosedWhenCreated` | Closed When Created | Boolean | Yes | Logs an issue that was already settled: when switched on at creation, the case is saved directly as Closed with the closed time stamped. A close reason is still required. | | `CloseReason` | Close Reason | PickList | | Why the case was closed. Required to close a case. The shipped automation rules also react to it: No Response from Customer moves the case to On Hold, Cancelled to Cancelled, and Resolved together with a resolution summary to Resolved. Values: Resolved, Duplicate, No Response from Customer, Not Reproducible, Works as Designed, Cancelled. | | `ConfigurationItemId` | Configuration Item | Lookup | | | | `ContactEmail` | Contact Email | Text | | The address the acknowledgement email is sent to when the case is created. Holds at most 20 characters; a longer address on the account or contact is not copied in. With no address the acknowledgement is recorded as a draft and not sent. | | `ContactId` | Contact | Lookup → [Contact](/docs/reference/entities/contact/) | | The person at the account who raised the case. Only the account's contacts are offered; when blank it defaults to the account's most recently created contact. | | `ContactName` | Contact Name | Text | | The name of the person to reply to, filled from the contact or account when blank. | | `ContactNumber` | Contact Number | Text | | The phone number to reply on, filled from the contact or account when blank. Numbers longer than 10 characters are not copied in. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CsatScore` | CSAT Score | Number | | The customer satisfaction score recorded for the case. | | `CustomerTier` | Customer Tier | PickList | | The commercial importance of the customer. SLA policies can match on it. Values: Platinum, Gold, Silver, Bronze. | | `DateTimeClosed` | Date/Time Closed | DateAndTime | | When the case was closed. Stamped when the status becomes Closed and cleared when the case is reopened. | | `DateTimeOpened` | Date/Time Opened | DateAndTime | | When the case was opened, stamped at creation. The SLA clock starts here, which is why a case created from a lead does not take the lead's dates. | | `Description` | Description | LongMultiLineText | | The full account of the issue: what is observable and what the customer needs. | | `DocumentDate` | Document Date | DateAndTime | | | | `EntitlementId` | Leave Entitlement | Lookup → [LeaveEntitlement](/docs/reference/entities/leave-entitlement/) | | | | `Escalated` | Escalated | Boolean | Yes | Shows the case has been escalated. Set by the Escalated status, the Escalate action, or an SLA breach. | | `FirstResponseDate` | First Response Date | DateAndTime | | When work on the case first started. Stamped the first time the status becomes In Progress, and completes the first-response milestone. | | `FirstResponseDue` | First Response Due | DateAndTime | | The first-response target from the case's SLA policy, in the policy's business hours. Moves forward by any time the clock spent paused. | | `Id` | Id | Guid | Yes | | | `MasterCaseId` | Master Case | Lookup → [Case](/docs/reference/entities/case/) | | On a case that was merged away as a duplicate, the surviving case it was merged into. Such a case is closed with close reason Duplicate and keeps its own case number. | | `Mobile` | Mobile | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | The generated document number the case number is taken from. | | `OriginCaseId` | Origin Case | Lookup → [Case](/docs/reference/entities/case/) | | On a case created with the Duplicate action, the case it was copied from. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | The record owner in the security sense: whose record the case is. Distinct from Assigned To, the agent working it. | | `ParentCaseId` | Parent Case | Lookup | | A broader case this one belongs under. | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The partner account (dealer) handling the customer. Only active partner accounts are offered. Required before a service order can be raised from the case. | | `PerformCreateLead` | Perform Create Lead | Boolean | Yes | Set when a lead has been created from the case. | | `PerformCreateOpportunity` | Perform Create Opportunity | Boolean | Yes | Set when an opportunity has been created from the case. | | `Phone` | Phone | Text | | | | `Priority` | Priority | PickList | | How fast the business should act on the case, as distinct from Severity. SLA policies can match on it, and the shipped rule Set Case Queue To High Priority puts new High-priority cases on a queue. Values: High, Medium, Low. | | `ProductId` | Product | Lookup | | | | `QueueId` | Queue | Lookup → [Queue](/docs/reference/entities/queue/) | | The queue the case is routed through. New cases with a queue are routed automatically after saving; a case without one is not routed, and the Route action refuses to run without a queue or a named agent. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `Reopened` | Reopened | Boolean | Yes | | | `ResolutionDate` | Resolution Date | DateAndTime | | When the case was resolved. Stamped when the status becomes Resolved and cleared when the case is reopened. | | `ResolutionDue` | Resolution Due | DateAndTime | | The resolution target from the case's SLA policy, in the policy's business hours. Moves forward by any time the clock spent paused. | | `ResolutionSummary` | Resolution Summary | Text | | What was wrong and what fixed it. Required before a case can be saved as Resolved. | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | Your organisation's person responsible for this customer. Only active resources are offered. Carried to leads created from the case, and to opportunities as the service advisor. | | `ServiceContractId` | Service Contract | Lookup | | | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | The service order raised from this case. Only one service order can be raised per case. | | `Severity` | Severity | PickList | | How serious the impact of the issue is, as distinct from Priority. SLA policies can match on it. Values: Critical, High, Medium, Low. | | `SLAPolicyId` | SLA Policy | Lookup → [SLAPolicy](/docs/reference/entities/slapolicy/) | | The SLA policy attached when the case was created: the highest-ranked active policy whose match formula is empty or true for the case. It is not re-matched when the case changes later. | | `SlaStatus` | SLA Status | PickList | | The overall SLA state of the case. It becomes OnTrack when a policy attaches; when it reaches Breached, the case is also flagged Escalated. Values: OnTrack, Warning, Breached, Met, Paused. | | `Status` | Status | PickList | | Where the case is in its lifecycle. Defaults to New. Resolved requires a resolution summary and stamps the resolution date; Closed requires a close reason and stamps the closed time; On Hold and the two waiting states pause the SLA clock (configurable per SLA policy); Escalated and Reopened set their flags. Allowed moves are set by the shipped business rules named Block Case Transition From, which administrators can edit. The shipped picklist holds eight of the eleven lifecycle states; Waiting on Customer, Waiting on Third Party and Escalated can be added. Values: New, Assigned, In Progress, On Hold, Resolved, Closed, Reopened, Cancelled. | | `Stopped` | Stopped | Boolean | Yes | True while the SLA clock is paused, either because the status is a pause status of the case's SLA policy (by default On Hold, Waiting on Customer and Waiting on Third Party) or because Pause SLA was run. | | `StoppedSince` | Stopped Since | DateAndTime | | When the current SLA pause began; empty while the clock runs. When the clock resumes, the paused business time is added to the SLA due times. | | `Subcategory` | Subcategory | Text | | | | `Subject` | Subject | Text | | The one-line statement of the issue. Used in the subject of the acknowledgement email. | | `Type` | Case Type | PickList | | The nature of the request. Values: Incident, Problem, Question, Task. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `WebCompany` | Web Company | Text | | | | `WebEmail` | Web Email | Text | | | | `WebName` | Web Name | Text | | | | `WebPhone` | Web Phone | Text | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `AddTeamMember` | Add Team Member | ServerAction (`AddTeamMember`) | Adds a colleague to the case's working team. Does not change the owner or Assigned To. | | `BookAppointment` | Book Appointment | ServerAction (`ProductDemo`) | Book Appointment | | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `CloseSideConversation` | Close Side Conversation | ServerAction (`CloseSideConversation`) | Closes a side conversation on the case. The case itself is not changed. | | `CloseWithReason` | Close | ServerAction (`CloseWithReason`) | Closes the case in one step: takes a close reason (required unless the case already has one) and optionally a resolution summary, sets the status to Closed and stamps the closed time. | | `ConvertToLead` | Convert to Lead | ServerAction (`ConvertToLead`) | Creates a lead from the case with its account, contact, branch, partner account and executive, linked both ways. Does not change the case status and can be run more than once. | | `ConvertToOpportunity` | Convert to Opportunity | ServerAction (`ConvertToOpportunity`) | Creates an opportunity from the case with its account, contact, branch, partner account and asset, the case's executive as service advisor, linked back to the case. Does not change the case status. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Duplicate` | Duplicate | ServerAction (`Duplicate`) | Creates a copy of this case; the copy records this case as its origin case. | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInLineHeader` | Edit | EditInline | EditInLineHeader | | `EmailArticle` | Email Article | ServerAction (`EmailArticle`), hidden | Emails a knowledge article to the case's contact. | | `Escalate` | Escalate | ServerAction (`Escalate`) | Sets the status to Escalated and the Escalated flag, and can reassign the case to a named agent at the same time. | | `FindDuplicates` | Find Duplicates | ServerAction (`FindDuplicates`), hidden | Lists up to 25 open, unmerged cases that share this case's contact, account or phone number. Duplicate-detection rules, where defined, take precedence. | | `FindMerged` | Merged Records | ServerAction (`FindMerged`), hidden | Records that were merged into this record. | | `Follow` | Follow | ServerAction (`Follow`) | Subscribes you to change notifications for the case. | | `Merge` | Merge | ServerAction (`Merge`) | Merges duplicate cases into this one. Their activities, attachments and people move to this case; each duplicate is closed with close reason Duplicate, keeps its own number and points to this case as its master case. | | `New` | New | New | New | | `PauseSla` | Pause SLA | ServerAction (`PauseSla`) | Pauses the SLA clock: marks the case stopped, records when, and logs an SLA clock paused event. | | `RemoveTeamMember` | Remove Team Member | ServerAction (`RemoveTeamMember`) | Removes a colleague from the case's working team. | | `Reopen` | Reopen | ServerAction (`Reopen`) | Reopens a Resolved, Closed or Cancelled case: sets the status to Reopened and the Reopened flag, and clears the closed and resolution dates. Refused for cases in any other status. | | `ReplySideConversation` | Reply Side Conversation | ServerAction (`ReplySideConversation`) | Adds a message to an existing side conversation on the case. | | `ResumeSla` | Resume SLA | ServerAction (`ResumeSla`) | Resumes the SLA clock and logs an SLA clock resumed event; due times move forward by the paused time. | | `RouteCase` | Route | ServerAction (`RouteCase`) | Hands the case to omni-channel routing through its queue, or a queue or agent given with the action; refused when none of these is available. The agent is chosen by the queue's routing model. | | `RunMacro` | Run Macro | ServerAction (`RunMacro`), hidden | Runs a macro's steps against the case, such as field updates and calls to Close, Pause SLA or Resume SLA. | | `StartSideConversation` | Start Side Conversation | ServerAction (`StartSideConversation`) | Opens a private side conversation on the case, for example with a third party, separate from the customer thread. | | `Unfollow` | Unfollow | ServerAction (`Unfollow`) | Stops your change notifications for the case. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | AssetForAccount | `AssetId` | | | Branch For Partner Account | `BranchId` | | | Contact for Account | `ContactId` | | | Partner Account Filter | `PartnerAccountId` | | | Resource Filter | `ResourceId` | | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [BusinessHours](/docs/reference/entities/business-hours/) — looks up via `BusinessHoursId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Contact](/docs/reference/entities/contact/) — looks up via `ContactId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [LeaveEntitlement](/docs/reference/entities/leave-entitlement/) — looks up via `EntitlementId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [CaseMilestone](/docs/reference/entities/case-milestone/) — referenced by via `CaseId` - [Collaborator](/docs/reference/entities/collaborator/) — referenced by via `CaseId` - [SideConversation](/docs/reference/entities/side-conversation/) — referenced by via `CaseId` - [Lead](/docs/reference/entities/lead/) — referenced by via `CaseId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `CaseId` - [Follower](/docs/reference/entities/follower/) — referenced by via `CaseId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Check In Inspection Line — entity reference URL: https://xmatix.com/docs/reference/entities/check-in-inspection-line/ Last reviewed: 2026-08-16 One recorded finding for a single sub-section of the check-in inspection - for example the front bumper within the exterior section - not one line per item or quantity. The Check-In Inspection widget writes exactly one row per sub-section that had at least one issue ticked; sub-sections with nothing ticked produce no row, so the absence of a row means 'nothing reported', not 'not inspected'. Section and SubSection are plain-text copies of the template line that produced them, and Condition holds every ticked issue joined with semicolons, so a row is a set of findings rather than a single condition value. Nothing downstream reads these rows: they do not gate check-out, create damage claims, or feed the service order. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CheckInInspectionId` | Check In Inspection | Lookup → [CheckInInspection](/docs/reference/entities/check-in-inspection/) | | | | `Condition` | Condition | PickList | | Holds every issue ticked for this sub-section joined with semicolons - for example 'Dent;Scratch' - so it is a delimited set, not a single value, and equality comparisons against one condition will miss multi-issue rows. It also does not respect its own picklist: the values come from the free-text issue list on the matching CheckInTemplateLine, plus the literal 'Other' when the inspector uses the free-text option, so any string a template author typed can appear here. Values: Dent, Scratch, Alignment, Torn, Broken. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DamagedRemarks` | Damaged Remarks | Text | | Carries only the free text typed against the 'Other' option for this sub-section, and is written only when 'Other' was ticked and text was entered. General notes about the sub-section go in Remarks instead, so the two are not interchangeable. | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Check In Inspection | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | MultiLineText | | | | `Section` | Section | Text | | A plain-text snapshot of the SectionName on the template line that produced this finding, copied at save time. It is not a foreign key to the template, so renaming a template section later does not change already-saved lines and grouping across time may show both old and new spellings. | | `SubSection` | Sub Section | Text | | A plain-text snapshot of the template line's sub-section, and the effective grain of this entity - the widget writes at most one row per sub-section per save. Like Section it is copied text rather than a link back to the template line. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteListRow` | Delete | Delete | DeleteListRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLineEntity` | Edit | EditInline | EditInLineEntity | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [CheckInInspection](/docs/reference/entities/check-in-inspection/) — looks up via `CheckInInspectionId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Check In Inspection — entity reference URL: https://xmatix.com/docs/reference/entities/check-in-inspection/ Last reviewed: 2026-10-10 The record of a customer's vehicle or machine being taken into custody for a job: when it arrived, the meter readings it came in on, and a walk-around of damage findings (Check In Inspection Line rows) with photos attached per section. It is raised by the Check In action on a service opportunity or service order, or by a field-service visit activity, and is worked on the check-in console, which builds its checklist from the Check In Template of the asset's item. Test drives taken out while the asset is in custody are separate Check In Inspection records of type Test Drive linked to the customer check-in through Parent Check-In Inspection; an inspection is closed when it has a Check-Out Date Time and is then read-only. It is not a goods-receipt inspection. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer the asset belongs to. Filled from the opportunity or service order the check-in was raised from when left empty, and copied onto every test drive. | | `Ageing` | Ageing | Calculated | | A boolean, not an age in days - despite the name it cannot hold a duration. | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | The vehicle or machine checked in. Its item decides which Check In Template the console uses; with no asset, or an asset with no item, no checklist is shown. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CheckInDateTime` | Check-In Date Time | DateAndTime | | When the asset came into custody. Set to the current time on create when left empty, and cannot be earlier than today. Test drives are ordered by it. | | `CheckInInspection` | Check-In Inspection | Number | Yes | Ignore it entirely when building queries, filters or layouts - referencing it will fail rather than return a value. | | `CheckInType` | Check-In Type | PickList | | Why the inspection exists: Customer for the hand-over raised by the Check In action, Test Drive for a drive taken out under a customer check-in, or Service. Check-ins raised by a field-service visit activity carry Field Service, which is not in the shipped picklist. Values: Service. | | `CheckOutDateTime` | Check-Out Date Time | DateAndTime | | When the asset left custody. Set by Checkout or Complete Test Drive on the check-in console and cannot be before the check-in time; an inspection with a value here is closed and read-only. | | `ContactAddressId` | Contact Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | The document date. Cannot be earlier than today. | | `DropoffAddress` | Drop-off Address | MultiLineText | | A free-text address string, entirely separate from the DropOffAddressId identifier field; neither is derived from the other and no code keeps them consistent. Use it as a typed-in note, not as a resolvable address record. | | `DropOffAddressId` | Drop Off Address | Lookup | | A bare identifier with no declared related entity and no navigation on the domain type, so unlike ContactAddressId it does not resolve to an address record and cannot be expanded in a query. | | `DropOffDateTime` | Drop Off Date Time | DateAndTime | | | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `IsDropoffRequired` | Is Drop-off Required | Boolean | Yes | Required yes/no flag recording whether the asset is to be returned to a drop-off address. It is informational: nothing schedules or validates a drop-off from it. | | `MobileNumber` | Mobile Number | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `Name` | Name | Text | Yes | The inspection number, assigned on save from the Check In Inspection document name setting (shipped series CIP with a date part and a six-digit counter). | | `OpportunityId` | Opportunity | Lookup → [Opportunity](/docs/reference/entities/opportunity/) | | The service opportunity the check-in was raised from. Empty account, asset and usage readings are filled from it on create, and its service contract supplies the usage band the readings must sit inside. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PickUpById` | Pick Up By | Lookup | | Intended to name whoever collected the asset, but it is a bare identifier with no declared related entity and no navigation on the domain type, so it does not resolve to a Resource, contact or user. It cannot be expanded or joined - only compared as a raw value. | | `PickUpDateTime` | Pick Up Date Time | DateAndTime | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | A free-text note on the inspection as a whole. Findings carry their own remarks on their lines. | | `ServiceAdvisorId` | Service Advisor | Lookup → [Resource](/docs/reference/entities/resource/) | | The resource handling the customer for this check-in. It is a Resource, not a user account, and is copied onto every test drive. | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | The service order this check-in belongs to. Set when the order's Check In action or a field-service visit raises the check-in; the order's Check In tab lists it. | | `ServiceTypeId` | Service Type (Depreciated) | Lookup | | Deprecated - the label itself carries the marker. It is a bare identifier column with no declared lookup target and no navigation on the domain type, so it cannot be joined to a service-type record; treat any value found here as legacy data. | | `Status` | Status | PickList | | Where the inspection stands: Draft, Checked-In or Checked-Out. Defaults to Checked-In; completing a test drive or checking the asset out on the console sets Checked-Out. Values: Checked-In, Draft, Checked-Out. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UsageReading` | Usage Reading | Number | | The meter reading the asset came in on. Taken from the Check In dialog, or from the opportunity or service order; when the opportunity carries a service contract it must sit inside that contract's usage band. | | `UsageReadingHours` | Usage Reading (Hours) | Number | | The hour-meter reading the asset came in on, for assets measured in running hours. Defaulted and checked against the service contract's usage band in the same way as Usage Reading. | | `VerifiedOk` | Verified Ok | Boolean | Yes | Set automatically each time findings are saved on the console: true when no discrepancy is recorded on the inspection. Never true together with Verified With Discrepancies. | | `VerifiedWithDiscrepancies` | Verified With Discrepancies | Boolean | Yes | Set automatically each time findings are saved on the console: true when at least one discrepancy is recorded on the inspection. Never true together with Verified Ok. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditinLine` | Edit | Edit | Edit in page. | | `EditInLine2` | Edit | EditInline | EditInLine | | `EditInLineHeader` | Edit | EditInline | EditInLineHeader | | `New` | New | NewInline | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | XM_CheckInDateTimeValidationRule | `CheckInDateTime`, Error | CheckInDate Time can not be less then Today. | CheckInDate Time can not be less then Today. | | XM_DocumentDateValidationRule | `DocumentDate`, Error | Document date can not be less than Today. | Document date can not be less than Today. | | Usage Reading Validation Rule | `UsageReading`, Error | Usage Reading cannot be less than zero | Prevents zero or negative usage reading | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Opportunity](/docs/reference/entities/opportunity/) — looks up via `OpportunityId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Resource](/docs/reference/entities/resource/) — looks up via `ServiceAdvisorId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `ContactAddressId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `CheckInInspectionId` - [CheckInInspectionLine](/docs/reference/entities/check-in-inspection-line/) — referenced by via `CheckInInspectionId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Check In Template Line — entity reference URL: https://xmatix.com/docs/reference/entities/check-in-template-line/ Last reviewed: 2026-08-16 One sub-section of a check-in checklist, defining the area being inspected (SectionName plus SubSection) and the list of pre-set issues an inspector can tick. The widget groups all lines of a template by SectionName into tabs, so section names are the grouping key and must match exactly across lines to appear as one tab. A file attachment on the template line doubles as the reference image: the widget loads file assets for each line and shows the first image found in a section as that section's diagram. Templates are authored here, but nothing validates that the issue list is non-empty - a line with no issues simply renders a sub-section with nothing to tick. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CheckInTemplateId` | Check-In Template | Lookup | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `Issues` | Issues | MultiplePickList | | A single string holding all the tickable issues for this sub-section, separated by semicolons - not one issue per row and not a picklist. The widget splits on ';' and trims each fragment to build the checkboxes, so blank fragments are dropped and the exact text typed here is what ends up stored in the saved inspection line's Condition. Values: Defective, Missing, Paint, Loose. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Check-In Template Line Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SectionName` | Section Name | PickList | | The tab-grouping key for the inspection screen: all template lines sharing this exact string are rendered as one section, so spelling or spacing differences split what was meant to be one section into two. Values: Front, Back, Left, Right. | | `SubSection` | Sub-Section | PickList | | Names the specific area inspected within the section and becomes the grain of the saved findings - one CheckInInspectionLine per sub-section that had anything ticked. It is copied as text onto the saved line rather than referenced by id. Values: Fender, Brakes, Seat, Tool-Kit, Mirror. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete In List | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit In line | | `HeaderEdit` | Header Edit | EditInline | Edit | | `New` | New | NewInline | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [CheckInTemplate](/docs/reference/entities/check-in-template/) — looks up via `CheckInTemplateId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Check In Template — entity reference URL: https://xmatix.com/docs/reference/entities/check-in-template/ Last reviewed: 2026-08-16 The reusable inspection checklist for one product type: it carries almost no data of its own beyond a name and ApplicableItemId, and its content is entirely in its CheckInTemplateLine children. It is never instantiated or copied onto an inspection - the Check-In Inspection widget resolves it live at render time by reading the inspection's Asset, taking that asset's ItemId, and fetching the first template whose ApplicableItemId matches. Because nothing is stored on the inspection linking back to the template, editing a template changes what every future inspection screen shows immediately, while findings already saved as CheckInInspectionLine rows keep the section, sub-section and issue text they were captured with. If no template matches the asset's item, the widget renders an error and no inspection can be captured. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApplicableItemId` | Applicable Item | Lookup → [Item](/docs/reference/entities/item/) | | The only selection key for the whole template: the inspection widget resolves the inspection's Asset, reads that asset's ItemId, and picks a template whose ApplicableItemId matches. It fetches just the first match, so if more than one template targets the same item the choice is effectively arbitrary, and a template with no applicable item can never be reached. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Check-In Template Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Item](/docs/reference/entities/item/) — looks up via `ApplicableItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [CheckInTemplateLine](/docs/reference/entities/check-in-template-line/) — referenced by via `CheckInTemplateId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Checklist Line — entity reference URL: https://xmatix.com/docs/reference/entities/check-list-line/ Last reviewed: 2026-08-16 One recorded checklist answer: the runtime row for a ChecklistTemplateLine question (checklistTemplateLineId) with typed value slots (booleanValue, numericValue, decimalValue, currencyValue, dateValue, dateTimeValue, timeValue, textValue, ragValue, email, phone, url). Ownership is polymorphic: relatedEntityType + relatedRecordId name the record the answer belongs to (a VisitTaskActivity by default, or a routed target such as the visit's ServiceOrder), so any entity page can query its answers the same way; relatedGroupKey lets one owner carry several answer groups. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BooleanValue` | Boolean Value | Boolean | | | | `BranchId` | Branch | Lookup | | | | `ChecklistTemplateId` | Checklist Template | Lookup → [ChecklistTemplate](/docs/reference/entities/checklist-template/) | | | | `ChecklistTemplateLineId` | Checklist Template Line | Lookup → [ChecklistTemplateLine](/docs/reference/entities/checklist-template-line/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrencyValue` | Currency Value | Currency | | | | `DataType` | Data Type | Text | | | | `DateTimeValue` | Date Time Value | DateAndTime | | | | `DateValue` | Date Value | Date | | | | `DecimalValue` | Decimal Value | Currency | | | | `Email` | Email | Text | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `NumericValue` | Numeric Value | Currency | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Phone` | Phone | Text | | | | `RAGValue` | RAG Value | Text | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RelatedEntityType` | Related Entity Type | Text | | Logical name of the entity that owns this answer row (for example ServiceOrder, Opportunity, VisitTaskActivity) - matches the metadata entity name. With relatedRecordId it replaces the old per-transaction FK columns, so any entity page renders its checklist answers via the same query. | | `RelatedGroupKey` | Related Group Key | Text | | Mirrors the template line's targetGroupKey so a single owner record can carry multiple groups of answers (for example separate inspection sections) without extra rows per group. | | `RelatedRecordId` | Related Record | Lookup | | Primary key of the owner row named by relatedEntityType - the second half of the polymorphic owner link. | | `Remarks` | Remarks | Text | | | | `ServiceRequestId` | ServiceRequest | Guid | | | | `TextValue` | Text Value | Text | | | | `TimeValue` | Time Value | TimeOnly | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `URL` | URL | Text | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [ChecklistTemplateLine](/docs/reference/entities/checklist-template-line/) — looks up via `ChecklistTemplateLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — looks up via `ChecklistTemplateId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Checklist Template Line — entity reference URL: https://xmatix.com/docs/reference/entities/checklist-template-line/ Last reviewed: 2026-08-16 One question on a ChecklistTemplate: dataType picks the answer control, picklistValues supplies choices, and parent/dependent links build conditional question trees. Normally each answer becomes its own CheckListLine row, but the opt-in target mapping (targetEntityName + targetEntityField, grouped by targetGroupKey) writes the answer to a typed column on a metadata entity instead - lines sharing the same target and group key collapse into a single target row. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ChecklistTemplateId` | Checklist Template | Lookup → [ChecklistTemplate](/docs/reference/entities/checklist-template/) | | | | `ChecklistTemplateLineId` | Checklist Template Line | Lookup | | | | `ColourCode` | Colour Code | PickList | | Values: Red, Amber, Green. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DataType` | Data Type | PickList | | Values: Date, Time, Currency, URL, DateTime, Text, Decimal, RAG, Boolean, Email, Take Picture, Phone, Picklist, Numeric. | | `DefaultValue` | Default Value | Text | | | | `DependentAnswer` | Dependent Answer | Text | | | | `GroupBy` | Group By | Text | | | | `Id` | Id | Guid | Yes | | | `IsMandatory` | Is Mandatory | Boolean | Yes | | | `Length` | Length | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentTemplateLineId` | Parent Template Line | Lookup | | | | `PicklistValues` | Picklist Values | Text | | | | `Reading` | Reading | Decimal | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `TargetEntityField` | Target Entity Field | Text | | The column on targetEntityName that receives this question's answer under the opt-in target mapping. | | `TargetEntityName` | Target Entity Name | Text | | Opt-in answer routing: when set, answers for this question are written to a typed column on the named metadata entity instead of materializing as a separate CheckListLine row. Leaving it null preserves the one-CheckListLine-per-question flow. | | `TargetGroupKey` | Target Group Key | Text | | Groups target-mapped questions: lines on the same template sharing (targetEntityName, targetGroupKey) collapse into a single target row, so related answers land on one record. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `Value` | Value | Text | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `DeleteRow` | Delete | Delete | DeleteRow | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — looks up via `ChecklistTemplateId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [CheckListLine](/docs/reference/entities/check-list-line/) — referenced by via `ChecklistTemplateLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Checklist Template — entity reference URL: https://xmatix.com/docs/reference/entities/checklist-template/ Last reviewed: 2026-08-16 A reusable questionnaire header whose questions are child ChecklistTemplateLine rows. Referenced by visit activity definitions (VisitTaskTemplateActivity.checklistTemplateId) so field reps fill it during visit execution, and answers materialize as CheckListLine rows against the activity or a routed target record. Scoping fields (accountId, accountGroupId, itemId, resourceId, resourceGroupId, partner variants) plus a validity window (fromDate/toDate) and frequency control where it applies; parentChecklistId builds a template hierarchy. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountGroupId` | Account Group | Lookup | | | | `AccountId` | Account Name | Lookup | | | | `Code` | Code | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Frequency` | Frequency | Text | | | | `FromDate` | From Date | Date | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | Yes | | | `IsMandatory` | Is Mandatory | Boolean | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentChecklistId` | Parent Checklist | Lookup | | | | `PartnerAccountGroupId` | Partner Account Group | Lookup | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceGroupId` | Resource Group | Lookup | | | | `ResourceId` | Resource | Lookup | | | | `ToDate` | To Date | Date | | | | `Type` | Type | PickList | | Values: Claim, Training, Generic, Delivery, Training Repository. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — looks up via `ParentChecklistId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [ResourceGroup](/docs/reference/entities/resource-group/) — looks up via `ResourceGroupId` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — referenced by via `ParentChecklistId` - [VisitTaskTemplateActivity](/docs/reference/entities/visit-task-template-activity/) — referenced by via `ChecklistTemplateId` - [CheckListLine](/docs/reference/entities/check-list-line/) — referenced by via `ChecklistTemplateId` - [ChecklistTemplateLine](/docs/reference/entities/checklist-template-line/) — referenced by via `ChecklistTemplateId` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — referenced by via `ChecklistTemplateId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Cheque Register — entity reference URL: https://xmatix.com/docs/reference/entities/cheque-register/ Last reviewed: 2026-08-16 A cheque book issued against a bank account: a number range from start to end with an optional prefix, plus a live counter holding the next number to be drawn. Issuing a cheque takes that counter, stamps it on the new cheque and advances it, flipping the register to Exhausted once it passes the end number. Save-time rules reject a start greater than the end, a range overlapping another register on the same bank account, and a register created against an inactive bank account or an inactive bank GL account. When a company has several usable registers, the automatic draw picks the one with the lowest next number so books are consumed in order. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BankAccountId` | Bank Account | Lookup → [BankAccount](/docs/reference/entities/bank-account/) | | The account the book belongs to. It supplies the bank account stamped on every cheque issued from this register, and it is the scope for the overlapping-range check and for the active bank-account and active GL-account checks. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `EndNumber` | End Number | LargeNumber | | Last number in the book. Passing it flips the register to Exhausted, and a cheque numbered outside the start-to-end span is rejected at save time whenever it names this register. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | A second on/off flag alongside Status, and the two are not kept in step. Only the automatic register lookup consults it — issuing against a register by id checks Status alone — so an inactive register whose status still reads Active can still be drawn from. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NextNumber` | Next Number | LargeNumber | | A live counter holding the number the next issued cheque will take, advanced by one on every draw. It is not a record of the last cheque used, and once it passes the end number the register is flipped to Exhausted. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Prefix` | Prefix | Text | | Prepended to the numeric counter to form the cheque number and the cheque record's name. The range check strips this prefix before parsing, and a cheque number that is not numeric once stripped is not range-checked at all. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StartNumber` | Start Number | LargeNumber | | First number in the book. It is validated against the end number and against overlapping ranges on the same bank account, and it is the fallback the issuing routine uses when no next number has been set yet. | | `Status` | Status | PickList | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [BankAccount](/docs/reference/entities/bank-account/) — looks up via `BankAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [ChequeTransaction](/docs/reference/entities/cheque-transaction/) — referenced by via `ChequeRegisterId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Cheque Transaction — entity reference URL: https://xmatix.com/docs/reference/entities/cheque-transaction/ Last reviewed: 2026-08-16 One cheque and its clearing lifecycle, either drawn by the company or received from a customer. Rows are normally created automatically when a cheque-mode Payment is saved — drawn from an active register when the number was left blank, otherwise recorded as typed — and they link back to that document by source entity name and source record id. Moving the status to Cleared posts the clearing journal that moves the money between the Cheques In Hand account and the bank; moving it to Bounced reverses the originating document's posted journal. Presented and Cancelled are recorded only and trigger no posting, and the rule that a cheque in a terminal state cannot change state lives in the cheque service rather than in save-time validation, so editing the record directly can still move it out of Cleared or Bounced. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | The cheque value, always positive — a save at zero or below is rejected — and the amount of the clearing journal posted when the cheque clears. Direction, not the sign of this figure, decides which way the money moves. | | `BankAccountId` | Bank Account | Lookup → [BankAccount](/docs/reference/entities/bank-account/) | | The company's bank account the cheque is drawn on. It is populated only when the number was drawn from a register — cheques recorded from a payment with a manually entered number are saved with it empty, which also means the duplicate-number check, scoped per bank account, does not apply to them. | | `ChequeDate` | Cheque Date | DateAndTime | | The date written on the cheque face. Save is rejected when it is in the future, and it is the date used when a cheque is generated automatically from a payment. | | `ChequeNumber` | Cheque Number | Text | | The printed cheque number, including the register prefix when one was allocated. It must be unique per bank account, so cheques saved without a bank account escape that check entirely. | | `ChequeRegisterId` | Cheque Register | Lookup → [ChequeRegister](/docs/reference/entities/cheque-register/) | | The cheque book the number came from, set only when the number was allocated automatically. When present it activates the save-time check that the cheque number lies inside that register's start-to-end range. | | `ClearedDate` | Cleared Date | DateAndTime | | Stamped when the status moves to Cleared, defaulting to today when none is supplied, and it becomes the date of the clearing journal. It is stamped once and is not cleared again if the status is later changed. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Direction` | Direction | Text | | Issued for a cheque the company writes, Received for one taken from a customer. It decides which way the clearing journal goes — a received cheque debits the bank and credits Cheques In Hand, an issued one does the reverse — and only issued cheques draw a number from a register. Note that a received cheque is still created with status Issued, so direction and status carry different meanings. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyAccountId` | Party Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer or supplier on the other side of the cheque, taken from the originating payment's account when the cheque is generated. It is a different link from the partner account, which is the owning company. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SourceEntityName` | Source Entity Name | Text | | The entity name of the money document the cheque came from — in practice Payment. Together with the source record id it is the idempotency key that stops a second cheque being created for the same document. | | `SourceRecordId` | Source Record | Guid | | The id of the originating money document. | | `Status` | Status | PickList | | Only Cleared and Bounced do anything — they post the clearing journal and reverse the source document respectively — and the terminal-state lock exists only in the cheque service, not in save-time validation, so editing the record directly can still move a cleared or bounced cheque back out of that state. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInline` | Edit Inline | EditInline | Edit Inline | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Amount Validation | `Amount`, Error | Amount cannot be 0 or Negative | Amount Validation | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Bank Account Filter | `BankAccountId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [ChequeRegister](/docs/reference/entities/cheque-register/) — looks up via `ChequeRegisterId` - [BankAccount](/docs/reference/entities/bank-account/) — looks up via `BankAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Claim Batch Line — entity reference URL: https://xmatix.com/docs/reference/entities/claim-batch-line/ Last reviewed: 2026-08-16 Junction row linking one Claim into one ClaimBatch; it carries no amounts or quantities of its own. ClaimLineService.PopulateClaimLinesInClaimBatch reads these rows to work out which batch line each of the batch's ClaimLine rows belongs to, and writes that id back onto the line. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ClaimBatchId` | Claim Batch | Lookup → [ClaimBatch](/docs/reference/entities/claim-batch/) | Yes | | | `ClaimId` | Claim | Lookup → [Claim](/docs/reference/entities/claim/) | | The claim being pulled into the batch; this is the key the populate action builds its lookup on when deciding which batch line each of the batch's claim lines belongs to. A batch line with a null claim is skipped entirely. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | UIAction | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `New` | New | New | New | ## Related entities - [Claim](/docs/reference/entities/claim/) — looks up via `ClaimId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ClaimBatch](/docs/reference/entities/claim-batch/) — looks up via `ClaimBatchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `ClaimBatchLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Claim Batch — entity reference URL: https://xmatix.com/docs/reference/entities/claim-batch/ Last reviewed: 2026-08-16 A working container that groups many Claims through ClaimBatchLine junction rows so they can be populated and reconciled together instead of one at a time. Its PerformPopulateClaimLines action stamps ClaimBatchId and ClaimBatchLineId onto every member claim's ClaimLine rows, and its PerformReconciliation action runs the same inventory-adjustment and sale-invoice creation the single-claim path runs, then marks the batch reconciled. Despite the name it is not a transmission or submission record: no first-party code sends a batch anywhere, assigns it a document number, or tracks an acknowledgement from the principal — submission to the manufacturer is an out-of-platform or integration-flow concern. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApproveAll` | Approve All | Boolean | Yes | A bulk-approve flag that no code reads. The bulk approve/reject logic only recognises the flag on a Claim record, and the batch's action handler does not support an approve-all action at all, so setting this here has no effect. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `IsClaimLinePopulated` | Claim Line Populated | Boolean | Yes | Set to true when the batch's claim lines have been linked to it. It stays false when the batch has junction rows but no matching claim lines were found, so a false value means 'nothing was linked', not necessarily 'never attempted'. | | `IsReconciled` | Reconciled | Boolean | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PerformPopulateClaimLines` | Perform Populate Claim Lines | Boolean | Yes | Trigger flag for the action that walks the batch's junction rows and stamps ClaimBatchId and ClaimBatchLineId onto every ClaimLine of the member claims. The service clears this flag and sets IsClaimLinePopulated when it finishes — but only if at least one line was actually matched. | | `PerformReconciliation` | Perform Reconciliation | Boolean | Yes | Trigger flag for the batch-level reconcile: it creates an inventory adjustment and a sale invoice from the batch's claim lines using the same rules as the single-claim path, then marks every line as reconciliation-created and flips the batch to reconciled. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RejectAll` | Reject All | Boolean | Yes | A bulk-reject flag that no code reads, for the same reason as ApproveAll on this entity: the bulk logic is implemented only for Claim records. Reject lines individually or on the member claims instead. | | `Remarks` | Remarks | Text | | | | `Status` | Status | PickList | | Batch state, with only two seeded picklist values, one of which ('Status') is a placeholder left over from setup rather than a real state. No code sets or transitions this column, so it reflects only what a user typed. Values: Status, Draft. | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `TotalApprovedAmount` | Total Approved Amount | Currency | Yes | | | `TotalApprovedQuantity` | Total Approved Quantity | Decimal | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | Edit | Edit | | `EditListheader` | Edit | EditInline | edit | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | XM_TotalApprovedAmountValidationRule | `TotalApprovedAmount`, Error | Total Approved Amount Cannot be Negative | Total Approved Amount Cannot be Negative | | XM_TotalApprovedQuantityValidationRule | `TotalApprovedQuantity`, Error | Total Approved Quantity cannot be Negative | Total Approved Quantity cannot be Negative | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `ClaimBatchId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `ClaimBatchId` - [Claim](/docs/reference/entities/claim/) — referenced by via `ClaimBatchId` - [ClaimBatchLine](/docs/reference/entities/claim-batch-line/) — referenced by via `ClaimBatchId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `ClaimBatchId` - [Adjustment](/docs/reference/entities/adjustment/) — referenced by via `ClaimBatchId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Claim Generation Rule — entity reference URL: https://xmatix.com/docs/reference/entities/claim-generation-setup-rule/ Last reviewed: 2026-08-16 One selection condition of a ClaimGenerationSetup, expressed as field path, operation and value with a sequence number. RulePredicate compiles the rows into a single dynamic-LINQ predicate that runs in SQL, combined either by the parent's RuleSuccessCriteria (AND/OR) or by its RuleSuccessCustomLogic formula over the sequence numbers; when the parent also sets FilterExpression, the two are ANDed together. Field names may walk navigations, so conditions like Scheme.IsClaimable or Invoice.Status are valid. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ClaimGenerationSetupId` | Claim Generation Setup | Lookup → [ClaimGenerationSetup](/docs/reference/entities/claim-generation-setup/) | Yes | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FieldName` | Field Name | Text | Yes | The field on the setup's source entity this condition tests; navigation paths are allowed, which is how claimability is usually expressed as a condition on the related scheme rather than on the ledger row itself. The path is compiled into SQL, so it must resolve against the model, not just against the loaded object. | | `FieldValue` | Field Value | Text | | The comparison value, typed by inference rather than declaration — the literal 'null' (any casing) becomes a null comparison, 'true'/'false' become booleans, numeric and GUID-shaped strings are used unquoted, and everything else is treated as text. For the in and not-in operations this is a comma-separated list. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `Operation` | Operation | PickList | Yes | The comparison used. Equals, not-equal, greater-than and less-than compare literally with type inference (true/false, numbers and GUIDs are recognised, everything else is quoted as a string); contains does a substring match forced to string; in and not-in expand a comma-separated value list into an OR chain. Values: Equals, Not Equal, Greater Than, Less Than, Contains, In, Not In. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `SequenceNumber` | Sequence | Number | Yes | Orders the rules and, more importantly, is the identifier the parent's custom-logic formula refers to. Two rules sharing a number make the formula ambiguous, and a number the formula references but that has no rule row makes the run fail. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete the record. | | `Edit` | Edit | Edit | Edit the ClaimGenerationSetupRule. | | `EditInLine` | Edit | EditInline | Edit inline. | | `EditInList` | Edit | EditInline | Edit inline in the list. | | `New` | New | New | Create a new ClaimGenerationSetupRule. | | `NewInLine` | Quick Add | NewInline | NewInLine | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ClaimGenerationSetup](/docs/reference/entities/claim-generation-setup/) — looks up via `ClaimGenerationSetupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Claim Generation Setup — entity reference URL: https://xmatix.com/docs/reference/entities/claim-generation-setup/ Last reviewed: 2026-08-16 One row per automated claim scenario for the config-driven claims.generate engine — it names the source entity, the selection conditions, how rows are grouped into claims, which amount is aggregated, and how source fields map onto the resulting Claim and ClaimLine. ClaimGenerationSetupHandler dry-runs the configured query with Take(1) on every save, so a bad field path or expression fails in the admin's face rather than in the nightly run; the same handler exposes the GenerateClaims action, which enqueues a job for this setup alone. At run time the job either executes one setup (manual trigger) or every active setup in a ScheduleGroup ordered by RunOrder, streaming the source query in BatchSize chunks. Idempotency comes from GenerationKey plus the ProcessedFlagField written back onto consumed source rows. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AggregateFunction` | Aggregate Function | PickList | | Sum produces exactly one claim line per group whose unit price accumulates the amount field across every source row (with quantity fixed at 1); Per Record produces one claim line per source row, mapped individually. The netting leg only ever adjusts the first line, so it is meaningful for Sum setups. Values: Sum, Per Record. | | `AmountFieldName` | Amount Field | Text | | The numeric field on the source row that is summed into the claim's value when AggregateFunction is Sum; the run fails outright if Sum is configured without it. Navigation paths are allowed and the field is eagerly included in the source query. | | `AmountFormula` | Amount Formula | MultiLineText | | An optional expression evaluated per source row before accumulation, with the raw amount available as the variable amount and the source row own fields in scope — so a claimable percentage on the related scheme can scale each contribution. Leave it blank to accumulate the amount field unchanged. | | `AutoSubmitForApproval` | Auto Submit For Approval | Boolean | Yes | When on, each newly written claim is submitted into its approval process straight after the run — and for target-entity setups it submits the target document type instead. Submission failures (no process configured, already pending) are logged into the run summary and never fail the generation run, and it is skipped entirely in simulate mode. | | `BatchSize` | Batch Size | Number | Yes | How many source rows the job pulls per page while streaming the query; it is clamped between 1 and 5000 at run time regardless of what is stored. Groups accumulate across pages, so this affects memory and progress reporting, not the shape of the result. | | `BranchPath` | Branch Path | Text | | Where on the source row to read the branch for the generated claim, defaulting to a direct BranchId when blank. | | `ClaimType` | Claim Type | PickList | Yes | The type stamped onto every claim this setup produces, unless ClaimTypeSource overrides it per source row. Its picklist is the engine's own vocabulary of coded scheme and incentive types, which does not overlap the Claim entity's own ClaimType picklist — so generated claims carry values that the Claim picklist does not offer. Values: Trade Schemes(CLT-04), CLT-04R, QPS Scheme (CLT-04), Cashback(CLT-04), Provision (CLT-04), Structural Rate Difference [Contract Pricing](CLT-08), PSR Incentive (CLT6,7), PSR Salary (CG 1,2), Training Claim, Damage, Shortage, Rate Difference, Reimbursment, Warranty Repairs. | | `ClaimTypeSource` | Claim Type Source | Text | | Leave blank or set to Config to stamp the setup's own ClaimType; set it to 'SourceField:' followed by a field path to have each claim inherit that value from its source row instead. If the path resolves to null the setup's ClaimType is used as the fallback, and the run fails if neither is set. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DateFieldName` | Date Field | Text | | Which date on the source row the window is measured against; navigation paths are allowed, so a line-level source can be windowed by its parent's document date. It only has an effect when DateWindow is set to something other than None. | | `DateWindow` | Date Window | PickList | | Restricts the source query to a rolling period resolved in UTC: last calendar month, the current calendar month, or the last N days ending today (inclusive of today). None disables date filtering altogether, whatever DateFieldName says. Values: None, Last Month, This Month, Last N Days. | | `DateWindowDays` | Date Window Days | Number | | The N used only when DateWindow is the last-N-days option; negative values are clamped to zero, which reduces the window to today alone. | | `FilterExpression` | Filter Expression | MultiLineText | | A dynamic-LINQ predicate applied to the source query, intended as the developer escape hatch alongside the admin-friendly rule rows. When both are present the rule rows and this expression are ANDed together; it is compiled and executed with a single-row dry run every time the setup is saved. | | `GroupingFields` | Grouping Fields | Text | Yes | A comma-separated list of field paths whose values, joined together, form each claim's group key — one claim per distinct combination. It is mandatory: a run with this blank fails immediately. The same key is what merges partial results as the source query is streamed in chunks, and it becomes part of the claim's GenerationKey. | | `HeaderMapping` | Header Mapping | MultiLineText | | JSON object mapping claim header field names to source paths or the same token set as LineMapping. It is evaluated once, from the first source row that opens each group, so it should only carry values that are constant within the group key. | | `IsActive` | Active | Boolean | Yes | | | `LineMapping` | Line Mapping | MultiLineText | | JSON object mapping claim-line field names to source field paths or tokens. Tokens available: an item lookup by name, a literal constant, the aggregated amount, the parent header id, and a format template that interpolates source paths into a string. Anything not starting with a token prefix is treated as a navigation path on the source row; unknown field names fall through into the record's custom-fields bag rather than erroring. | | `Modified By` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `NettingAmountField` | Netting Amount Field | Text | | The field summed on the netting source and subtracted from the claim amount. It is mandatory once a netting source is set — the run throws rather than netting zero if it is left blank. | | `NettingBranchPath` | Netting Branch Path | Text | | | | `NettingDateFieldName` | Netting Date Field | Text | | | | `NettingDateWindow` | Netting Date Window | PickList | | Values: None, Last Month, This Month, Last N Days. | | `NettingFilterExpression` | Netting Filter Expression | MultiLineText | | Dynamic-LINQ predicate narrowing the netting source before summing. It is dry-run validated on save alongside the main query, so a bad expression here fails at save time. | | `NettingPartnerPath` | Netting Partner Path | Text | | | | `NettingSourceEntity` | Netting Source Entity | Text | | Enables the netting leg: after collection, the engine sums a second source per group and subtracts it from the aggregated claim amount, which is how contract-rate differences and credit-note payouts already given are deducted. Candidates whose amount falls to zero or below after netting are dropped and no claim is written for them. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `OwnerResolution` | Owner Resolution | PickList | | How the generated claim's owner is chosen: Resource User assigns the user behind the active PSR/DSR resource matching the claim's partner and branch, Branch Owner assigns the branch record's owner, None leaves the owner as the job's default. Unmatched candidates simply get no owner rather than failing. Values: None, Resource User, Branch Owner. | | `PartnerAccountPath` | Partner Account Path | Text | | Where on the source row to read the partner account for the generated claim; it defaults to a direct PartnerAccountId on the row when left blank. The same value is used to match rows on the netting leg unless a separate netting partner path is given. | | `ProcessedFlagField` | Processed Flag Field | Text | | The boolean on the source row that marks it as already claimed; it is both a filter (the query only takes rows where it is null or false) and a write-back (successfully claimed rows are flagged in the same transaction as the claim). Navigation paths are supported so a parent-level flag can be used. Leaving it blank means sources are re-read every run, which is correct only for regenerate-each-period types such as salary. | | `RuleSuccessCriteria` | Rule Success Criteria | PickList | | How the child rule rows combine when no custom logic formula is given: OR joins them with logical or, anything else (including the default) joins them with logical and. It is ignored entirely once RuleSuccessCustomLogic is filled in. Values: AND, OR. | | `RuleSuccessCustomLogic` | Rule Custom Logic | Text | | A boolean formula over the child rules' sequence numbers, such as '(1 AND 2) OR 3', supporting AND, OR, NOT and parentheses. | | `RunOrder` | Run Order | Number | Yes | Sequencing within a scheduled run: when the job is triggered for a schedule group it executes that group's active setups in ascending order of this number. It is ignored when a single setup is triggered directly. | | `ScheduleGroup` | Schedule Group | PickList | | Names the cron-driven batch this setup belongs to; a job schedule row per group carries the actual cron expression, and the scheduled run picks up every active setup with a matching group. A setup with this blank can still be run manually but will never run on a schedule. Values: Nightly, Monthly (Day 1), Weekly. | | `SimulateMode` | Simulate Mode | Boolean | Yes | Defaults to on. In simulate mode the run computes candidates and reports what it would have created to the jobs ledger but writes no claims and flags no source rows — safe for parallel running against an existing process. A manual trigger can override it per run; leaving it on is the usual reason a correctly configured setup appears to create nothing. | | `SourceEntity` | Source Entity | Text | Yes | The entity name whose rows are scanned for claimable value — resolved against the live model by name, so any first-party or tenant entity works (SchemeLedger, InvoiceLine, CreditNote and Resource are the typical ones). Tenant and soft-delete filters are applied automatically, and every navigation the setup's paths walk is eagerly included. | | `StrategyKey` | Strategy Key | Text | | Selects an alternative collection strategy from the registered catalog for behaviour that genuinely cannot be expressed as configuration. Leave it blank for the standard config-driven pipeline, which is what every shipped scenario uses. | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | The supplier or principal stamped onto every claim this setup generates — a fixed account per setup rather than something read from the source row. | | `TargetEntity` | Target Entity | Text | | Redirects the engine's output away from Claim to another document type (a No-Dues certificate, for example), written through the metadata-driven data service so tenant custom entities work. This mode has no GenerationKey duplicate guard, so ProcessedFlagField becomes mandatory — the setup is refused on save without it. Header, lines and source flags are also not one transaction in this mode, so a mid-run failure can leave a header with unflagged sources. | | `TargetLineEntity` | Target Line Entity | Text | | The line entity written under TargetEntity; each candidate line becomes one row, with the parent token resolving to the created header's id. Leave blank for header-only target documents. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete the record. | | `Edit` | Edit | Edit | Edit the ClaimGenerationSetup. | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit inline. | | `EditInList` | Edit | EditInline | Edit inline in the list. | | `GenerateClaims` | Generate Claims | ServerAction (`GenerateClaims`, async) | Does not generate claims inline — it enqueues a background generation run scoped to this setup alone and returns the job run id, so results appear on the Jobs screen rather than in the response. The enqueue key is bucketed to the minute, so double-clicks collapse into one run while a deliberate re-run a minute later goes through. Whether it actually writes anything still depends on the setup's simulate mode unless the caller overrides it. | | `New` | New | New | Create a new ClaimGenerationSetup. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `Modified By` - [ClaimGenerationSetupRule](/docs/reference/entities/claim-generation-setup-rule/) — referenced by via `ClaimGenerationSetupId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Claim Line — entity reference URL: https://xmatix.com/docs/reference/entities/claim-line/ Last reviewed: 2026-08-16 One claimable item on a Claim, holding the claimed quantity and unit price alongside the approved and rejected splits that everything downstream reads. Lines are written by ClaimLineService when the PerformPopulateLines action runs — from service-order lines flagged 'Generate Claims'/'Auto Generate Claims' with ClaimableQuantity remaining, or from CreditNoteLine rows (the real supplier-return path, TransactionType 'BillReturn') for Purchase, Damaged, Shortage and Excess claims — and by the claims.generate engine, which maps them field-by-field from the setup's LineMapping. The line's own ClaimType, not the header's, steers the follow-ups: 'Part To Part' lines create reject/approve delivery orders when quantities change, and 'Reimbursment' lines with approved quantity let the reconcile action raise a sale invoice. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApproveAmount` | Approve Amount | Calculated (calculated) | | Settlement computes approved value on the fly as UnitPrice times ApproveQuantity rather than reading this column, so it can be blank on fully settled lines. | | `ApproveBaseAmount` | Approve Base Amount | Calculated (calculated) | | | | `ApproveDiscount` | ApproveDiscount | Decimal | | | | `ApproveDiscountAmount` | Approve Discount Amount | Currency | Yes | | | `ApproveNetDiscount` | Approve Net Discount | Calculated (calculated) | | | | `ApproveQuantity` | Approve Quantity | Decimal | | The quantity the principal accepted, and the figure everything financial reads: settlement builds the credit note or adjustment only from lines where it is greater than zero, and multiplies it by unit price for the amount. It is set line by line, or in bulk from the header's ApproveAll flag. | | `BaseAmount` | Base Amount | Calculated (calculated) | | | | `BatchClaimId` | Batch Claim | Lookup → [Claim](/docs/reference/entities/claim/) | | A second claim reference, separate from ClaimId, used to point a line at the claim that represents its batch. No first-party service writes it; ClaimId remains the owning-claim link that all line creation and settlement code uses. | | `BillReturnLineId` | Bill Return Line | Lookup → BillReturnLine | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `ClaimAmount` | Claim Amount | Calculated (calculated) | | An amount column that no first-party code writes or reads — line value is carried by UnitPrice times ClaimQuantity everywhere in the claim, settlement and reconcile paths. Populated only by tenant rules or imports. | | `ClaimBatchId` | Claim Batch | Lookup → [ClaimBatch](/docs/reference/entities/claim-batch/) | | | | `ClaimBatchLineId` | Claim Batch Line | Lookup → [ClaimBatchLine](/docs/reference/entities/claim-batch-line/) | | Stamped onto the line, together with ClaimBatchId, by the ClaimBatch populate action: it records which batch junction row (and therefore which member claim) brought this line into the batch. | | `ClaimId` | Claim | Lookup → [Claim](/docs/reference/entities/claim/) | Yes | | | `ClaimQuantity` | Claim Quantity | Decimal | | | | `ClaimType` | Claim Type | PickList | | Line-level type that drives the downstream documents independently of the header's type. 'Part To Part' lines make ClaimLineHandler raise reject or approve delivery orders whenever the rejected or approved quantity changes, and 'Reimbursment' lines with an approved quantity are what allow the reconcile action to raise a sale invoice. Values: Part To Part, Reimbursment, Shortage, Damaged, Marketing. | | `ComplaintFaultId` | Complaint Fault | Lookup → [ComplaintFault](/docs/reference/entities/complaint-fault/) | | | | `ComplaintId` | Complaint | Lookup → [Complaint](/docs/reference/entities/complaint/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Discount` | Discount | Decimal | | For service-contract claim lines this is written as 100 minus the line's service-contract weightage — that is, the share of the value the contract does not cover — rather than a discount the dealer granted. | | `DiscountAmount` | Discount Amount | Currency | | | | `ExternalId` | External | Text | | | | `GoodsReceiptId` | Goods Receipt | Lookup → [GoodsReceipt](/docs/reference/entities/goods-receipt/) | | | | `GoodsReceiptLineId` | Goods Receipt Line | Lookup → [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) | | | | `Id` | Id | Guid | Yes | | | `InvoiceLineId` | Invoice Line | Lookup → [InvoiceLine](/docs/reference/entities/invoice-line/) | | | | `IsBatchId` | Batch | Boolean | Yes | Do not use it in rules, filters or layouts. | | `IsClaimReconciliationCreated` | Claim Reconciliation Created | Boolean | | A second, similarly named reconciliation flag that no code path in the platform ever sets or reads. Ignore it when reasoning about reconciliation state and use IsReconciliationCreated instead. | | `IsReconciliationCreated` | IsReconciliationCreated | Boolean | | Set to true for every line of a ClaimBatch when that batch's reconcile action completes. The single-claim reconcile path does not set it, so it only ever marks batch-processed lines. | | `ItemCode` | Item Code | Text | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemServiceContractId` | Item Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NetDiscount` | Net Discount | Calculated (calculated) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PurchaseReturnLineId` | Purchase Return Line | Lookup → [PurchaseReturnLine](/docs/reference/entities/purchase-return-line/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RejectAmount` | Reject Amount | Calculated (calculated) | | | | `RejectBaseAmount` | Reject Base Amount | Calculated (calculated) | | | | `RejectDiscountAmount` | Reject Discount Amount | Currency | | | | `RejectNetDiscount` | Reject Net Discount | Calculated (calculated) | | | | `RejectQuantity` | Reject Quantity | Number | | The quantity the principal refused. Changing it on a 'Part To Part' line triggers creation of a reject delivery order so the physical part is returned; no settlement document is produced from rejected quantity. | | `SchemeLedgerId` | Scheme Ledger | Lookup → [SchemeLedger](/docs/reference/entities/scheme-ledger/) | | Link back to the scheme-ledger accrual row a trade-scheme claim line was generated from. | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | | | `ServiceOrderLineId` | Service Order Line | Lookup → [ServiceOrderLine](/docs/reference/entities/service-order-line/) | | | | `SourceLineKey` | Source Line Key | Text | | Line-level idempotency key for engine-generated lines, formed as the parent claim's GenerationKey plus a discriminator (the source row id for per-record aggregation, or '0' for the single summed line). It is also the merge key when the engine accumulates a group across query chunks: two chunks producing the same key have their amounts added rather than duplicated. | | `Status` | Status | PickList | | Values: Draft, Approved, Rejected. | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `TechnicianId` | Technician | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `TotalAmount` | TotalAmount | Decimal | | | | `UIProps` | UI Props | Text | | | | `UnitPrice` | Unit Price | Currency | | Not always a per-unit rate. For service-contract lines it is the source line's unit price, but for weightage lines it holds the whole computed contribution (claimable quantity times unit price times the weightage percentage) against a quantity of one, and for Sum-aggregate engine lines it holds the entire aggregated claim amount for the group, with the netting leg subtracted from it. | | `UnitPrice2` | Unit Price | Currency | | Treat it as unusable here. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Approve` | Approve | UIAction | Approve | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit In Line | EditInline | Edit In Line | | `EditListRow` | Edit List Row | EditInline | Edit List Row | | `New` | New | New | New | | `NewInLine` | Quick Add | NewInline | NewInLine | | `OpenChecklist` | Open Checklist | UIAction | Opens the claim-checklist layout for the line — a manual verification list (warranty form completed, purchase invoice available, purchase from an authorised dealer, no prior claim on the same invoice) rendered as tick-boxes. It is a UI-only action: no server handler implements it, so it records nothing and changes no field on the claim line. | | `Reject` | Reject | UIAction | Reject | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | XM_ApprovedQuantityValidationRule | `ApproveAmount`, Error | Approved Quantity cannot be Negative | Approved Quantity cannot be Negative | | XM_ClaimQuantityValidationRule | `ClaimQuantity`, Error | Claim Quantity cannot be Negative | Claim Quantity cannot be Negative | | XM_RejectedQuantityValidationRule | `RejectQuantity`, Error | Rejected Quantity Cannot be Negative | Rejected Quantity Cannot be Negative | | XM_UnitPriceValidationRule | `UnitPrice`, Error | Unit Price cannot be Negative | Unit Price cannot be Negative | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — looks up via `GoodsReceiptId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — looks up via `SchemeLedgerId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [Claim](/docs/reference/entities/claim/) — looks up via `ClaimId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — looks up via `ServiceOrderLineId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — looks up via `InvoiceLineId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [Resource](/docs/reference/entities/resource/) — looks up via `TechnicianId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ClaimBatch](/docs/reference/entities/claim-batch/) — looks up via `ClaimBatchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ComplaintFault](/docs/reference/entities/complaint-fault/) — looks up via `ComplaintFaultId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [PurchaseReturnLine](/docs/reference/entities/purchase-return-line/) — looks up via `PurchaseReturnLineId` - [Claim](/docs/reference/entities/claim/) — looks up via `BatchClaimId` - [Complaint](/docs/reference/entities/complaint/) — looks up via `ComplaintId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — looks up via `GoodsReceiptLineId` - [ClaimBatchLine](/docs/reference/entities/claim-batch-line/) — looks up via `ClaimBatchLineId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ClaimReconciliationLine](/docs/reference/entities/claim-reconciliation-line/) — referenced by via `ClaimLineId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `ClaimLineId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `ClaimLineId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `ClaimLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Claim Reconciliation Line — entity reference URL: https://xmatix.com/docs/reference/entities/claim-reconciliation-line/ Last reviewed: 2026-08-16 Per-item detail under a ClaimReconciliation, restating the claimed and approved quantities and amounts for one ClaimLine plus a rejection reason and remarks. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApprovedAmount` | Approved Amount | Currency | | The value the principal accepted for this line as recorded during reconciliation. It is a separate manual figure from ClaimLine's own approved quantity and amount, and nothing keeps the two in step. | | `ApproveQuantity` | Approve Quantity | Decimal | | | | `ClaimAmount` | Claim Amount | Calculated (calculated) | | | | `ClaimId` | Claim | Lookup → [Claim](/docs/reference/entities/claim/) | | | | `ClaimLineId` | Claim Line | Lookup → [ClaimLine](/docs/reference/entities/claim-line/) | | The specific claim line this reconciliation line accounts for; it is the join that would let received credit be traced back to what was claimed. No code populates it. | | `ClaimQuantity` | Claim Quantity | Decimal | | | | `ClaimReconciliationId` | Reconciliation | Lookup → [ClaimReconciliation](/docs/reference/entities/claim-reconciliation/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RejectedAmount` | Rejected Amount | Currency | | | | `RejectionReason` | Rejection Reason | PickList | | | | `RejectQuantity` | Reject Quantity | Decimal | | | | `Remarks` | Remarks | Text | | | | `Status` | Status | PickList | | Line state with three seeded values — pending, draft and reclaim, the last meaning the line is to be raised again. Nothing transitions it automatically. Values: Pending, Reclaim, Draft. | | `UIProps` | UI Props | Text | | | | `UnitPrice` | Unit Price | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | UIAction | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | XM_ApprovedQuantityValidationRule | `ApproveQuantity`, Error | Approved Quantity cannot be Negative | Approved Quantity cannot be Negative | | XM_ClaimQuantityValidationRule | `ClaimQuantity`, Error | Claim Quantity Cannot be Negative | Claim Quantity Cannot be Negative | | XM_RejectedQuantityValidationRule | `RejectQuantity`, Error | Rejected Quantity cannot be Negative | Rejected Quantity cannot be Negative | | XM_UnitPriceValidationRule | `UnitPrice`, Error | Unit Price cannot be Negative | Unit Price cannot be Negative | ## Related entities - [Claim](/docs/reference/entities/claim/) — looks up via `ClaimId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ClaimReconciliation](/docs/reference/entities/claim-reconciliation/) — looks up via `ClaimReconciliationId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ClaimLine](/docs/reference/entities/claim-line/) — looks up via `ClaimLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Claim Reconciliation — entity reference URL: https://xmatix.com/docs/reference/entities/claim-reconciliation/ Last reviewed: 2026-08-16 Register head for matching credit actually received from a supplier or principal against the claims that were submitted, holding the credit-note amount, the reconciled amount and the period date. Payment and Adjustment both carry a ClaimReconciliationId pointing back at it. Be aware when advising on it: no first-party service creates, updates or reads these rows — the automated reconcile paths on Claim and ClaimBatch write inventory adjustments, sale invoices and the IsReconciled flags directly and never touch this entity, so in practice it is a manually maintained register. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CreditNoteAmount` | Credit Note Amount | Currency | | The credit actually received from the supplier for this reconciliation period, to be set against the claimed value. No code writes or reads it — it is a manually maintained figure. | | `DocumentDate` | Document Date | Date | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `ReconciledAmount` | Reconciled Amount | Currency | | How much of the received credit has been matched against claims; the gap against CreditNoteAmount is the unmatched residue. Like the rest of this entity it has no automated writer, so it will not update itself when claims settle. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Status` | Status | PickList | | | | `SupplierAccountId` | Supplier | Lookup → [Account](/docs/reference/entities/account/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | Edit | Edit in page. | | `EditListHeader` | Edit | EditInline | Edit | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | XM_CreditNoteAmountValidationRule | `CreditNoteAmount`, Error | Credit Note Amount cannot be Negative | Credit Note Amount cannot be Negative | | XM_ReconciledAmountValidationRule | `ReconciledAmount`, Error | Reconciled Amount cannot be Negative | Reconciled Amount cannot be Negative | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [ClaimReconciliationLine](/docs/reference/entities/claim-reconciliation-line/) — referenced by via `ClaimReconciliationId` - [Payment](/docs/reference/entities/payment/) — referenced by via `ClaimReconciliationId` - [Adjustment](/docs/reference/entities/adjustment/) — referenced by via `ClaimReconciliationId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Claim Settlement Setup — entity reference URL: https://xmatix.com/docs/reference/entities/claim-settlement-setup/ Last reviewed: 2026-08-16 Post-approval settlement configuration, one active row per claim type, consumed by the claims.settle job when an approval process returns Approved on a Claim. It decides which document settles the claim, maps that document's header and line fields from the claim using @approvedAmount and @approvedQuantity tokens so partial approvals settle partially, and controls whether the result is marked for posting, knocked off against the partner's open invoices, and announced as a domain event. A missing row for the claim's type is not an error — the job raises any configured event and exits without creating a document. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApplyToOpenInvoices` | Apply To Open Invoices | Boolean | Yes | After the credit note is saved, knocks it off against the partner's open invoices oldest first, reducing the note's open amount as it is consumed. It runs as a separate step after the document commits, so it can be retried independently if it fails; it does not apply on the adjustment settlement path. | | `AutoGLPosting` | Auto GL Posting | Boolean | Yes | Marks the settlement document for posting as it is created — as the credit note's GL-posting flag, or as the inventory-posting flag on the adjustment path. It sets the flag the document's own handlers act on; it does not itself post anything. | | `ClaimType` | Claim Type | PickList | Yes | The claim type this settlement configuration governs; the settle job looks up the single active setup whose type equals the claim's type, with no fallback. Its picklist offers only the generation engine's coded type vocabulary, so claims carrying the Claim entity's own picklist values (Damaged, Shortage, Service and so on) cannot be matched to a setup through the UI as seeded. Values: Trade Schemes(CLT-04), CLT-04R, QPS Scheme (CLT-04), Cashback(CLT-04), Provision (CLT-04), Structural Rate Difference [Contract Pricing](CLT-08), PSR Incentive (CLT6,7), PSR Salary (CG 1,2), Training Claim, Damage, Shortage, Rate Difference, Reimbursment, Sale, Service, Purchase, Excess, Transport, Part To Part. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `HeaderMapping` | Header Mapping | MultiLineText | | JSON mapping the settlement document's header fields from claim paths or tokens — a literal constant, the claim's total approved amount, or its total approved quantity. It is applied after the built-in defaults, so it can override the amount, dates, status or transaction type the job would otherwise set. | | `IsActive` | Active | Boolean | Yes | | | `LineMapping` | Line Mapping | MultiLineText | | JSON mapping the settlement document's line fields from claim-line paths or tokens, where the approved-amount and approved-quantity tokens resolve per line (unit price times approved quantity, and the approved quantity itself). Only claim lines with an approved quantity above zero produce a settlement line. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RaiseEventName` | Raise Event Name | Text | | Name of the domain event published after settlement for downstream rules and integrations. Publishing is best-effort — if no event publisher is registered on the host, or publishing throws, the settlement still counts as successful and only a warning is logged. It is also raised when the document type is None or no setup matches, making an events-only settlement possible. | | `SettlementDocument` | Settlement Document | PickList | Yes | What the settle job creates from an approved claim. Credit Note builds a credit note from the approved figures; the value 'Adjustment' makes it build an inventory part-to-part adjustment instead (the shortage-claim path) but is not offered by the seeded picklist, so it must be set through the API or a rule; None means events only. Any other value fails the job as unsupported. Values: Credit Note, None. | | `SimulateMode` | Simulate Mode | Boolean | Yes | Defaults to on. In simulate mode the settle job reports the document it would have created and exits without writing anything or stamping the claim — so the claim stays unsettled and will be reconsidered on the next approval event. A per-run payload flag can override it. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `ClaimSettled` | ClaimSettled | ServerAction (`ClaimSettled`) | ClaimSettled | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete the record. | | `Edit` | Edit | Edit | Edit the ClaimSettlementSetup. | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit inline. | | `EditInList` | Edit | EditInline | Edit inline in the list. | | `New` | New | New | Create a new ClaimSettlementSetup. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Claim — entity reference URL: https://xmatix.com/docs/reference/entities/claim/ Last reviewed: 2026-08-16 Header of a claim raised against a supplier, principal or manufacturer for money or stock owed back to the dealer — warranty and service-contract recovery, damage/shortage on inward goods, and trade-scheme/incentive payouts. Three code paths create one: manual entry, ClaimService.CreateClaimsFromServiceOrdersAsync (one claim per service order + invoice group + ItemServiceContract whose ContractPostingTreatment is 'Auto Generate Claims'), and the claims.generate job driven by a ClaimGenerationSetup. Its ClaimLine children carry the claimed, approved and rejected quantities; once an approval process returns Approved, ClaimApprovalDecisionListener enqueues claims.settle, which turns the approved figures into a settlement credit note (or inventory adjustment) and stamps CreditNoteId plus Status 'Settled'. Two vocabularies coexist and do not overlap: the ClaimType picklist on this entity (Scheme, Damaged, Sale, Service, Purchase, Shortage, Excess, Transport, Part To Part) and the ClaimTypes constants the generation/settlement engine uses. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApproveAll` | Approve All | Boolean | | Bulk shortcut read by ClaimLineService.MarkAllClaimLines: when true, every claim line's approved quantity is set to its claimed quantity and its rejected quantity to zero. It is checked before RejectAll in the same if/else, so if both flags are on, approval wins and the rejection is ignored. | | `AsOndate` | As On Date | Date | | Cut-off date used when populating lines without a specific source document: service-order and credit-note lines are only pulled in when their document date is on or before this date. When the claim already names a service order or credit note, that link wins and this date is only a tie-breaker. | | `BillReturnId` | Bill Return | Lookup → BillReturn | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `ClaimBatchId` | Claim Batch | Lookup → [ClaimBatch](/docs/reference/entities/claim-batch/) | | | | `ClaimType` | Claim Type | PickList | | Steers which source documents PerformPopulateLines will pull from: Service reads service-order lines, while Purchase, Damaged, Shortage and Excess all read CreditNoteLine rows (Purchase takes any return type, the others must match the credit note's ReturnType). Values: Scheme, Marketing, Damaged, Sale, Service, Purchase, Shortage, Excess, Transport, Part To Part. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | | | `ExternalId` | External | Text, unique | | | | `GenerationKey` | Generation Key | Text | | Idempotency key for engine-generated claims, composed as claim type, group key and period joined by pipes (for example the year-month '2026-07' as the period). Before writing, claims.generate looks up existing claims by this key and skips any candidate whose key already exists, so re-running a setup within the same period cannot duplicate a claim. Manually created claims leave it blank. | | `GoodsReceiptId` | Goods Receipt | Lookup → [GoodsReceipt](/docs/reference/entities/goods-receipt/) | | | | `Id` | Id | Guid | Yes | | | `InvoiceGroup` | Invoice Group | PickList | | Copied from the originating ServiceOrderLine's own invoice group and used as part of the claim's identity: service-order claim creation keys one claim per invoice group, item service contract and service order, and line population only attaches service-order lines whose invoice group matches the claim's. | | `InvoiceId` | Sale Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | | | `IsLinePopulated` | Line Populated | Boolean | Yes | Intended as the 'lines have been built' marker, but no code path on Claim ever sets it — line population leaves it untouched. Do not rely on it to tell whether a claim has been populated; check for ClaimLine rows instead. | | `IsReconciled` | Reconciled | Boolean | Yes | Set to true by ClaimService.MarkClaimToReconciled at the end of the reconcile action, in the same step that clears PerformReconciliation. It records that the adjustment/invoice follow-ups were attempted; it does not assert that credit was actually received from the supplier. | | `ItemServiceContractId` | Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | The warranty or service contract this claim recovers against. It is part of the claim's identity for service claims — one claim is created per contract per service order per invoice group — and line population only attaches a service-order line when the line's contract, or one of its second/third weightage contracts, matches this one. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PerformPopulateLines` | Perform Populate Lines | Boolean | Yes | Trigger flag whose matching server action builds the claim's lines from the eligible source documents for its claim type. Unlike the ClaimBatch equivalent, neither this flag nor IsLinePopulated is reset or set by the code that runs, so it stays as the user left it and repeated runs are possible. | | `PerformReconciliation` | Perform Reconciliation | Boolean | Yes | Trigger flag for the reconcile action, which creates an inventory adjustment from the claim's Part-to-Part lines, raises a sale invoice from its Reimbursment lines with approved quantity, and then marks the claim reconciled. The service that finishes the run clears this flag back to false. | | `PurchaseReturnId` | Purchase Return | Lookup → [PurchaseReturn](/docs/reference/entities/purchase-return/) | | Legacy link to a PurchaseReturn document. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RejectAll` | Reject All | Boolean | Yes | Bulk shortcut that sets every claim line's rejected quantity to its claimed quantity and zeroes the approved quantity. It only takes effect when ApproveAll is false, and neither flag is cleared afterwards. | | `Remarks` | Remarks | Text | | | | `SchemeId` | Scheme | Lookup → [Scheme](/docs/reference/entities/scheme/) | | Link to the trade scheme a claim originates from. | | `ServiceInvoiceAsOnDate` | Service Invoice As On Date | Date | | | | `ServiceOrderAsonDate` | Service Order As on Date | Date | | | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | | | `Status` | Status | PickList | | Free-text status column backed by a picklist of Draft, Pending Approval, Claim Approved, Claim Rejected and Reconcile. Code writes two values that are not in that list: the generation engine stamps 'Draft' on every claim it creates, and claims.settle sets 'Settled' after the settlement document is written — so a filter or rule built only from the picklist will miss settled claims. Values: Draft, Pending Approval, Approved, Rejected, Settled. | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | The party the claim is made against (the manufacturer, principal or supplier who owes the credit), as distinct from PartnerAccountId, which is the company or dealer entity raising it. The generation engine copies it from the setup's own supplier, and settlement carries it onto the credit note. | | `TotalAmount` | Total Amount | Calculated | | | | `TotalApprovedAmount` | Total Approved Amount | Calculated | | The figure claims.settle settles on: it is used as the settlement document's amount and, when zero or null with no lines present, the job concludes there is nothing to settle. No first-party code computes or rolls it up from the claim lines — the settlement service falls back to summing unit price times approved quantity across lines when it is null, so a stale non-null value here overrides the lines. | | `TotalApprovedQuantity` | Total Approved Quantity | Calculated | | | | `TotalQuantity` | Total Quantity | Calculated | | | | `TotalRejectedAmount` | Total Rejected Amount | Calculated | | Header total for rejected value. No first-party code path writes it, and nothing reads it; it is populated only if a tenant business rule or integration sets it. | | `TotalRejectedQuantity` | Total Rejected Quantity | Calculated | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `ApproveAll` | Approve All | UIAction | Does not itself approve the claim or advance any approval process — it loads the claim's lines and, only if the claim's ApproveAll flag is set, copies each line's claimed quantity into its approved quantity and zeroes the rejected quantity. Running it with the flag off has no effect. | | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInList` | Edit | EditInline | Edit list header | | `New` | New | New | New | | `PerformPopulateLines` | Perform Populate Lines | UIAction | Builds the claim's lines from eligible source documents chosen by the claim's own type: service-order lines flagged for claim generation with claimable quantity remaining (adding extra lines for second and third weightage contracts), or unclaimed credit-note lines for purchase, damage, shortage and excess claims. Populating from credit notes also marks those source lines as claimed. | | `PerformReconciliation` | Perform Reconciliation | UIAction | Runs three steps in order: creates an inventory adjustment from Part-to-Part lines with approved quantity, raises a sale invoice from Reimbursment lines with approved quantity (pulling fulfilment allocations for the related service-order lines), and then marks the claim reconciled while clearing the trigger flag. Note the adjustment step compares the line type with different casing than the seeded picklist value, so in practice the adjustment is usually not created. | | `RejectAll` | Reject All | UIAction | Shares one implementation with the approve-all action: it loads the lines and applies whichever of the claim's ApproveAll or RejectAll flags is set, checking approval first. | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [ClaimBatch](/docs/reference/entities/claim-batch/) — looks up via `ClaimBatchId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — looks up via `GoodsReceiptId` - [PurchaseReturn](/docs/reference/entities/purchase-return/) — looks up via `PurchaseReturnId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Scheme](/docs/reference/entities/scheme/) — looks up via `SchemeId` - [ClaimReconciliationLine](/docs/reference/entities/claim-reconciliation-line/) — referenced by via `ClaimId` - [ClaimBatchLine](/docs/reference/entities/claim-batch-line/) — referenced by via `ClaimId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `ClaimId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `ClaimId` - [Payment](/docs/reference/entities/payment/) — referenced by via `ClaimId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `ClaimId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `BatchClaimId` - [Adjustment](/docs/reference/entities/adjustment/) — referenced by via `ClaimId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `ClaimId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `ClaimId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Collaborator — entity reference URL: https://xmatix.com/docs/reference/entities/collaborator/ Last reviewed: 2026-08-16 A named participant on a record, carrying a team role and an intended access level. It is entity-agnostic by design - rows are keyed by the polymorphic pair of Record and Related Entity Name rather than by a foreign key - but the AddTeamMember and RemoveTeamMember server actions that create and retire them are registered on Case only in first-party metadata, so in practice these are case team members. Be careful with Access Level: no first-party record-level security rule reads it, so adding a collaborator does not by itself grant that person Read or Edit on the record; enforcement would have to come from a tenant-authored security rule. Record merge re-points collaborators onto the surviving record. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccessLevel` | Access Level | PickList | | Read or Edit, expressing the access the collaborator is meant to have, and defaulted to Read when a row is created without one. No first-party record-level security rule reads it, so on its own it grants nothing - a tenant would have to author a security rule that references it. Values: Read, Edit. | | `IsPrimary` | Primary | Boolean | Yes | Marks one team member as the primary one. It is set only from the argument passed to the add-team-member action; nothing reads it afterwards, and nothing enforces that at most one row per record carries it. | | `RecordId` | Record | Lookup → [Case](/docs/reference/entities/case/) | Yes | The record this collaborator belongs to, stored as a bare identifier with no foreign key behind it. It is only meaningful together with the related entity name, since identifiers from different entities share this one column. | | `TeamRole` | Team Role | PickList | | Defaults to Collaborator when a row is created without one. Seeded choices are Owner, Collaborator and Observer, and no first-party code behaves differently depending on which is chosen - it is descriptive only. Values: Owner, Collaborator, Observer. | | `UserId` | User | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | The user identity the row is recorded against; it is supplied as an argument to the add-team-member action and is required. Removal matches on this together with the record, so removing a team member soft-deletes every row for that user on that record. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `EditInLine` | Edit | EditInline | Edit in page. | ## Related entities - [Case](/docs/reference/entities/case/) — looks up via `CaseId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Card Reconciliation — entity reference URL: https://xmatix.com/docs/reference/entities/company-card-reconciliation/ Last reviewed: 2026-08-16 A corporate-card reconciliation session comparing the card statement's closing balance against the Credit Card Payable book balance for one CompanyCard, recording the difference. Mirrors the bank-reconciliation session shape; status is Open or Completed. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ClosingBalancePerBook` | Closing Balance Per Book | Currency | | | | `ClosingBalancePerCard` | Closing Balance Per Card | Currency | | | | `CompanyCardId` | Company Card | Lookup → [CompanyCard](/docs/reference/entities/company-card/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Difference` | Difference | Currency | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StatementDate` | Statement Date | Date | | | | `Status` | Status | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this CompanyCardReconciliation. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this CompanyCardReconciliation. | | `EditInLine` | Edit | EditInline | Edit | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a CompanyCardReconciliation. | | `View` | View | View | View this CompanyCardReconciliation. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [CompanyCard](/docs/reference/entities/company-card/) — looks up via `CompanyCardId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Card Transaction — entity reference URL: https://xmatix.com/docs/reference/entities/company-card-transaction/ Last reviewed: 2026-08-16 One imported corporate-card statement line: date, merchant, amount, and the expense category / expense GL account the employee tags it with, optionally linked to an ExpenseClaimLine and a receipt file. reconStatus tracks the pipeline (Unmatched, Tagged, Posted, Reconciled); the PostCompanyCardExpense action posts it Dr expense / Cr Credit Card Payable and stamps it Posted. Statement import reuses the banking statement-import path. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CompanyCardId` | Company Card | Lookup → [CompanyCard](/docs/reference/entities/company-card/) | Yes | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExpenseCategoryId` | Expense Category | Lookup → [ExpenseCategory](/docs/reference/entities/expense-category/) | Yes | | | `ExpenseClaimLineId` | Expense Claim Line | Lookup → [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) | | Optional link tying the statement line to the ExpenseClaimLine that reported the same spend - the matching key between the employee's claim and the card statement. Card spend posts from this transaction against the card payable; it is not re-posted through the claim. | | `ExpenseGLAccountId` | ExpenseGL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The expense head debited when the transaction posts - required by the posting action, which fails without it. Usually defaulted from the tagged expense category. | | `GLAccountName` | Name | Text, unique | Yes | | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | | | `Id` | Id | Guid | Yes | | | `MerchantName` | Merchant Name | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `ReceiptFileAssetId` | Receipt File Asset | Lookup | | | | `ReconStatus` | Recon Status | Text | | Statement-line pipeline: Unmatched (imported), Tagged (categorised by the employee), Posted (stamped by the posting action together with glId), Reconciled. A transaction with glId set cannot post again. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `TxnDate` | Txn Date | Date | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this CompanyCardTransaction. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this CompanyCardTransaction. | | `EditInLine` | Edit | EditInline | Edit | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a CompanyCardTransaction. | | `PostCompanyCardExpense` | Post | ServerAction (`PostCompanyCardExpense`) | Posts the tagged statement line to the ledger: Dr its expense GL account / Cr Credit Card Payable (the card's account, falling back to the CreditCardPayable control account), stamping glId and reconStatus Posted. No employee payable is involved - card spend is a company liability. Requires an expense GL account, a positive amount, and a line not already posted. | | `View` | View | View | View this CompanyCardTransaction. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `BranchId` | | | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `ExpenseGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ExpenseCategory](/docs/reference/entities/expense-category/) — looks up via `ExpenseCategoryId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — looks up via `ExpenseClaimLineId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [CompanyCard](/docs/reference/entities/company-card/) — looks up via `CompanyCardId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Company Card — entity reference URL: https://xmatix.com/docs/reference/entities/company-card/ Last reviewed: 2026-08-16 A corporate credit card assigned to an employee Resource. Card spend is a company liability, not an employee one: posting a card transaction credits the Credit Card Payable account (the card's own creditCardPayableGLAccountId, falling back to the CreditCardPayable control account) instead of Employee Payable. Statement lines are child CompanyCardTransaction rows and statement-vs-book reconciliation sessions are CompanyCardReconciliation rows; the card's PostCompanyCardPayment action pays the statement from the bank. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AmountDue` | Amount Due | Calculated (calculated) | | | | `AssignedResourceId` | Assigned Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `BankGLAccountId` | Bank GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `CardNumberMasked` | Card Number Masked | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CreditCardPayableGLAccountId` | Credit Card PayableGL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The liability account credited when this card's spend posts and debited when the card bill is paid. When empty, posting falls back to the GL account with ControlType CreditCardPayable; with neither configured, card postings fail. | | `GLAccountName` | Name | Text, unique | Yes | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `IssuingBank` | Issuing Bank | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this CompanyCard. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this CompanyCard. | | `EditInLine` | Edit | EditInline | Edit | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a CompanyCard. | | `PostCompanyCardPayment` | Pay Card Statement | ServerAction (`PostCompanyCardPayment`) | Pays the card statement from the bank: Dr Credit Card Payable / Cr Bank for the given amount. Both bankGLAccountId and amount arguments are required (paymentDate optional); the payable account is the card's own or the CreditCardPayable control account. Creates the payment journal only - it does not settle individual card transactions. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `BankGLAccountId` - [Resource](/docs/reference/entities/resource/) — looks up via `AssignedResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `CreditCardPayableGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [CompanyCardReconciliation](/docs/reference/entities/company-card-reconciliation/) — referenced by via `CompanyCardId` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — referenced by via `CompanyCardId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Compensation Line — entity reference URL: https://xmatix.com/docs/reference/entities/compensation-line/ Last reviewed: 2026-08-16 The incentive calculation worksheet for one participant (incentiveResourceId) under a Compensation header: saving it triggers the incentive engine, which loads the plan's approved IncentiveLine rules, matches PerformanceKPI accruals to the participant by the plan's member type, evaluates each IncentiveTarget against the participant's IncentiveResourceTarget quota, stamps the reached metric onto the matching summary field (noOfSaleOrders, saleAmount, noOfUniqueInvoices, customKPIValue and so on), and applies the qualifying CompensationSlab rewards - writing incentiveAmount, gifts/giftPoints, schemeId or discountGroupId depending on the slab's compensation type. Requires incentivePlanId and incentivePeriodId to be set or processing is skipped. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AchievedValue` | Achieved Value | Currency | | | | `BilledHours` | Billed Hours | Number | | | | `CompensationId` | Compensation | Lookup → [Compensation](/docs/reference/entities/compensation/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CustomKPIFieldName` | Custom KPI Field Name | Text | | | | `CustomKPIValue` | Custom KPI Value | Number | | The summed Custom KPI reading stamped by the engine when a target of type Custom KPI is evaluated for this line. | | `DiscountGroupId` | Discount Group | Lookup → [DiscountGroup](/docs/reference/entities/discount-group/) | | Stamped when the qualifying slab's compensation type is Discount Group: the reward is membership of the referenced discount group. | | `Efficiency` | Efficiency | Percent | | | | `ExternalId` | External | Text | | | | `FinanceProviderId` | Financer | Lookup → [Financer](/docs/reference/entities/financer/) | | | | `FinancerSchemeId` | Financer Scheme | Lookup → [FinancerScheme](/docs/reference/entities/financer-scheme/) | | | | `GiftPoints` | Points | Number | | | | `Gifts` | Gifts | PickList | | Set (together with GiftPoints) when the qualifying slab's compensation type is Gifts - a non-monetary reward description copied from the slab. | | `Id` | Id | Guid | Yes | | | `IncentiveAmount` | Incentive Amount | Currency | | The payout computed by the incentive engine from the qualifying CompensationSlab: fixed amount, per-unit amount times units, or percentage of the reached value depending on the slab's compensation type. Recomputed when the line is processed. | | `IncentivePeriodId` | Incentive Period | Lookup → [IncentivePeriod](/docs/reference/entities/incentive-period/) | | | | `IncentivePlanId` | Incentive Plan | Lookup → [IncentivePlan](/docs/reference/entities/incentive-plan/) | | | | `IncentiveResourceId` | Incentive Resource | Lookup → [IncentiveResource](/docs/reference/entities/incentive-resource/) | | | | `InsuranceSchemeId` | Insurance Scheme | Lookup → [InsuranceScheme](/docs/reference/entities/insurance-scheme/) | | | | `IsCompensationReceived` | Is Compensation Received | Boolean | Yes | Manual acknowledgement flag that the participant received the payout; not set by the incentive engine. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `KPIConfigurationId` | KPI Configuration | Lookup → [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Month` | Month | PickList | | Values: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec. | | `Name` | Name | Text | Yes | | | `NetPayableAmount` | Net Payable Amount | Calculated | | | | `NoofBookings` | No of Bookings | Number | | | | `NoofInvoices` | No of Invoices | Number | | | | `NoofLeads` | No of Leads | Number | | | | `NoOfPurchaseOrders` | No of Purchase Orders | Number | | | | `NoOfSaleOrders` | No of Sale Orders | Number | | | | `NoOfServiceOrders` | No of Service Orders | Number | | | | `NoOfUniqueInvoices` | No Of Unique Invoices | Number | | Stamped by the engine when a No Of Unique Invoices target is evaluated: the count of distinct accounts across the matching KPI rows. | | `NoOfUniqueItems` | No Of Unique Items | Number | | Stamped by the engine when a No Of Unique Items target is evaluated: the count of distinct items across the matching KPI rows. | | `OverrideIncentiveAmount` | Overre Incentive Amount | Currency | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartsAmount` | Parts Amount | Currency | | | | `ProcessLog` | Process Log | Text | | | | `PurchaseAmount` | Purchase Amount | Currency | | | | `PurchaseOrderAmount` | Purchase Order Amount | Currency | | | | `PurchaseOrderQuantity` | Purchase Order Quantity | Decimal | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SaleAmount` | Sale Amount | Currency | | | | `SaleOrderAmount` | Sale Order Amount | Currency | | | | `SaleOrderQuantity` | Sale Order Quantity | Decimal | | | | `SaleQuantity` | Sale Quantity | Decimal | | | | `SchemeId` | Scheme | Lookup → [Scheme](/docs/reference/entities/scheme/) | | Stamped when the qualifying slab's compensation type is Scheme Rewards: the participant's reward is enrollment into the referenced Scheme rather than a direct amount. | | `ServiceAmount` | Service Amount | Currency | | | | `ServiceContractId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `SpentHours` | Spent Hours | Number | | | | `Status` | Status | PickList | | Values: Rejected, Draft. | | `TargetType` | Target Type | PickList | | Values: No of Leads, No of Bookings, No of Invoices, No of Insurances, Amount of Finance. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `Value` | Value | Currency | | | | `WOAmount` | WO Amount | Number | | | | `Year` | Year | PickList | | Values: 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [Compensation](/docs/reference/entities/compensation/) — looks up via `CompensationId` - [Financer](/docs/reference/entities/financer/) — looks up via `FinanceProviderId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — looks up via `KPIConfigurationId` - [DiscountGroup](/docs/reference/entities/discount-group/) — looks up via `DiscountGroupId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — looks up via `IncentivePlanId` - [Item](/docs/reference/entities/item/) — looks up via `ServiceContractId` - [FinancerScheme](/docs/reference/entities/financer-scheme/) — looks up via `FinancerSchemeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [IncentivePeriod](/docs/reference/entities/incentive-period/) — looks up via `IncentivePeriodId` - [InsuranceScheme](/docs/reference/entities/insurance-scheme/) — looks up via `InsuranceSchemeId` - [IncentiveResource](/docs/reference/entities/incentive-resource/) — looks up via `IncentiveResourceId` - [Scheme](/docs/reference/entities/scheme/) — looks up via `SchemeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Compensation Slab — entity reference URL: https://xmatix.com/docs/reference/entities/compensation-slab/ Last reviewed: 2026-08-16 A payout band under an IncentiveLine (incentiveLineId): qualifies when the participant's achievement percent - floor of 100 times reached value over the IncentiveResourceTarget quota - falls between fromPercentage and toPercentage (a null or zero toPercentage means no upper bound; the first matching band in sequence wins). compensationType decides what is written to the CompensationLine: Fixed Amount (incentiveFixedAmount), Amount Per Unit (incentiveAmountPerUnit times units reached), Amount Per Unit Incremental (the same doubled), Percentage On Value (amountPercentage of the reached value, keeping the highest), Gifts (gifts + giftPoints), Scheme Rewards (stamps schemeId) or Discount Group (stamps discountGroupId). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AmountPercentage` | Amount Percentage | Percent | | Used by Percentage On Value: the incentive amount is this percent of the achieved value; when several slabs write an amount, the highest wins. | | `CompensationType` | Compensation Type | PickList | | What the slab pays: Fixed Amount, Amount Per Unit, Amount Per Unit Incremental (per-unit doubled), Percentage On Value, Gifts, Scheme Rewards (stamps a scheme), or Discount Group (stamps a discount group). Percentage On Profit is defined but has no payout branch in the engine. Values: Fixed Amount, Amount Per Unit, Amount Per Unit Incremental, Percentage On Value, KPI Reward Value, KPI Reward Value Percentage, Gifts, Discount Group, Reward Points;, Slab Reward Percentage. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrencyIsoCode` | Currency ISO Code | Text | | | | `DiscountGroupId` | Discount Group | Lookup → [DiscountGroup](/docs/reference/entities/discount-group/) | | | | `ExternalId` | External | Text | | | | `FromPercentage` | From Percentage | Percent | | Lower bound of the achievement band: the slab qualifies when floor(100 x reached / quota) is at least this percent. Paired with ToPercentage; the first matching slab in sequence wins. | | `FromValue` | From Value | Number | | Absolute-value band bound; the engine's slab qualification uses FromPercentage/ToPercentage of the achievement ratio, not this pair. | | `GiftPoints` | Reward Points | Number | | | | `Gifts` | Gifts | PickList | | Values: Amazon Vouchers, iPhone X, Trip to Bali, Trip to Kerela, Discount Voucher. | | `Id` | Id | Guid | Yes | | | `IncentiveAmountPerUnit` | Incentive Amount Per Unit | Currency | | Per-unit payout used by the Amount Per Unit types: multiplied by the achieved value (and doubled for Amount Per Unit Incremental) to produce the incentive amount. | | `IncentiveFixedAmount` | Incentive Fixed Amount | Currency | | | | `IncentiveLineId` | Incentive Line | Lookup → [IncentiveLine](/docs/reference/entities/incentive-line/) | | | | `IncentivePeriodId` | Incentive Period | Lookup → [IncentivePeriod](/docs/reference/entities/incentive-period/) | | | | `IncentivePlanId` | Incentive Plan | Lookup → [IncentivePlan](/docs/reference/entities/incentive-plan/) | | | | `KPIConfigurationId` | KPI Configuration | Lookup → [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) | | | | `MemberResourceType` | Member Resource Type | PickList | | Values: Salesperson, Manager. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PercentageonProfit` | Percentage on Profit | Percent | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReferenceIncentiveTargetId` | Reference Incentive Target | Lookup → [IncentiveTarget](/docs/reference/entities/incentive-target/) | | | | `ResourceRewardFieldName` | Resource Reward Field Name | Text | | | | `SchemeId` | Scheme | Lookup → [Scheme](/docs/reference/entities/scheme/) | | The Scheme granted when CompensationType is Scheme Rewards; copied onto the compensation line. | | `SequenceNumber` | SequenceNumber | Number | | | | `TargetPercentage` | Target Percentage | Decimal | | | | `ToPercentage` | To Percentage | Percent | | Upper bound of the achievement band; null or zero means unbounded above, so a 100-and-up band is expressed as FromPercentage 100 with ToPercentage empty. | | `ToValue` | To Value | Number | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `CreateCompensationSlab` | Create Compensation Slab | ServerAction (`CreateCompensationSlab`) | Seeded as a server action but no server handler implements it - executing it performs no server work; slabs are created directly through the data API. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [IncentivePlan](/docs/reference/entities/incentive-plan/) — looks up via `IncentivePlanId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [IncentivePeriod](/docs/reference/entities/incentive-period/) — looks up via `IncentivePeriodId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [DiscountGroup](/docs/reference/entities/discount-group/) — looks up via `DiscountGroupId` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — looks up via `KPIConfigurationId` - [Scheme](/docs/reference/entities/scheme/) — looks up via `SchemeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [IncentiveLine](/docs/reference/entities/incentive-line/) — referenced by via `IncentiveLineId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `ReferenceIncentiveTargetId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Compensation — entity reference URL: https://xmatix.com/docs/reference/entities/compensation/ Last reviewed: 2026-08-16 The payout header for one participant scope in one IncentivePeriod of an IncentivePlan: groups the CompensationLine detail rows and carries totalIncentiveAmount and a status. The claim pipeline can mark a compensation as claimed via the nav-path processed flag (Compensation.IsClaimed idiom in the claim engine). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrencyIsoCode` | Currency ISO Code | Text | | | | `Id` | Id | Guid | Yes | | | `IncentivePeriodId` | Incentive Period | Lookup → [IncentivePeriod](/docs/reference/entities/incentive-period/) | | | | `IncentivePlanId` | Incentive Plan | Lookup → [IncentivePlan](/docs/reference/entities/incentive-plan/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Status` | Status | PickList | | | | `TotalIncentiveAmount` | Total Incentive Amount | Calculated | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — looks up via `IncentivePlanId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [IncentivePeriod](/docs/reference/entities/incentive-period/) — looks up via `IncentivePeriodId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `CompensationId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Complaint Fault — entity reference URL: https://xmatix.com/docs/reference/entities/complaint-fault/ Last reviewed: 2026-08-16 The diagnosed fault code that a technician assigns against a reported complaint - the 'what was actually wrong' counterpart to the customer-reported Complaint symptom. Rows can be scoped to a specific item or to an item group so the fault list can be filtered by what is being serviced, and they are referenced from ComplaintLine, ServiceOrderLine and ClaimLine. Gotcha for reasoning about service recommendations: changing a ComplaintLine's fault code re-triggers the recommendation recompute, but the recommendation rules themselves match only on ComplaintId, so the fault code never changes which recommendations are produced. It also carries a direct ServiceOrderId, giving two ways to reach a service order (directly, or via the ComplaintLine) - they are not kept in sync by any code. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApplicableToItemGroupId` | Applicable To Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | The broader alternative to ApplicableToItemId, scoping the fault code to a whole item group. Both may be set or both left empty; no code resolves precedence between them or validates the choice at save time. | | `ApplicableToItemId` | Applicable To Item | Lookup → [Item](/docs/reference/entities/item/) | | Restricts this fault code to a single item so fault pick-lists can be narrowed to what is actually being serviced. It is advisory scoping metadata - nothing in the platform enforces that a service line's item matches the fault code chosen. | | `ComplaintId` | Complaint | Lookup → [Complaint](/docs/reference/entities/complaint/) | | Ties the diagnosed fault back to the customer-reported symptom it explains, which is how a fault list is filtered once a complaint is chosen. Note that service recommendations are generated from the complaint alone - this link does not influence which recommendations appear. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | Text | | | | `FaultCode` | Fault Code | Text | | The short diagnostic code for the fault, free text with no enforced format or uniqueness. It is the human-facing code; joins from service and claim lines are always on the record id, never on this string. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Complaint Fault Code Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Edit` | Edit | EditInline | Edit | | `Edit2` | Edit | EditInline | Edit | | `New` | New | NewInline | New | ## Related entities - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ApplicableToItemGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Complaint](/docs/reference/entities/complaint/) — looks up via `ComplaintId` - [Item](/docs/reference/entities/item/) — looks up via `ApplicableToItemId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `ComplaintFaultId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ComplaintFaultCodeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Complaint — entity reference URL: https://xmatix.com/docs/reference/entities/complaint/ Last reviewed: 2026-08-16 A master list of customer-reportable symptoms - the 'what the customer says is wrong' vocabulary - not an individual customer grievance or case. It holds only a code, a name and a description; the actual occurrences are ComplaintLine rows on a service order or estimate, and ClaimLine, ServiceOrderLine and Quote also reference it. Its one active downstream effect is service recommendations: when a ComplaintLine is created or its ComplaintId changes, ComplaintLineService looks up ServiceRecommendationRule rows keyed on the same ComplaintId and generates or prunes ServiceRecommendation rows for the parent service order or estimate. For an individual customer grievance with an SLA and a lifecycle, use the case entities instead. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Code` | Complaint Code | Text | | The short symptom code used to identify this complaint in service documents and in imports; it is a free-text string with no uniqueness or format enforcement, and it is separate from the record's display Name. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | LongMultiLineText | | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Complaint Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Quote](/docs/reference/entities/quote/) — referenced by via `ComplaintId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ComplaintCodeId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `ComplaintId` - [ComplaintFault](/docs/reference/entities/complaint-fault/) — referenced by via `ComplaintId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Consolidation Group Member — entity reference URL: https://xmatix.com/docs/reference/entities/consolidation-group-member/ Last reviewed: 2026-08-16 The junction row placing one business unit into a consolidation group. Membership is expressed only in business units, with no branch, company or tax-registration member axis. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `ConsolidationGroupId` | Consolation Group | Lookup → [ConsolidationGroup](/docs/reference/entities/consolidation-group/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GLAccountName` | Name | Text, unique | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | Edit | | `DeleteListRow` | Delete | Delete | DeleteListRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListRow` | Edit | Edit | EditListRow | | `NewInLine` | New | NewInline | NewInLine | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ConsolidationGroup](/docs/reference/entities/consolidation-group/) — looks up via `ConsolidationGroupId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Consolidation Group — entity reference URL: https://xmatix.com/docs/reference/entities/consolidation-group/ Last reviewed: 2026-08-16 A named set of business units reported together, so statutory and management groupings can differ without maintaining separate ledgers. Passing a group to a statement expands it to its member business units and filters the same posted balances, which makes consolidation here a reporting scope rather than a second set of books. The consolidation report renders a column per member plus a consolidated column, and derives an eliminations column as the consolidated figure minus the sum of the members, surfacing inter-unit clearing that nets to zero across a complete group. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `GLAccountName` | Name | Text, unique | Yes | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [PublishedStatement](/docs/reference/entities/published-statement/) — referenced by via `ConsolidationGroupId` - [ConsolidationGroupMember](/docs/reference/entities/consolidation-group-member/) — referenced by via `ConsolidationGroupId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Contact Address — entity reference URL: https://xmatix.com/docs/reference/entities/contact-address/ Last reviewed: 2026-10-10 A contact address is one entry in an account's address book: a billing address, a shipping address, or one that serves as both. Every contact address belongs to one account and can name the contact person at that address and an associated branch. The account's address marked Is Default fills new documents automatically: a Billing or Both address fills the billing side and a Shipping or Both address the shipping side. Sales orders, invoices and purchase orders fill on first save; bills, delivery orders and service orders also fill on later saves while the address is empty; on all of these the default contact address comes before the account's own address fields. Quotes and opportunities take the account's own address fields first and use the default contact address only for what they leave blank. Filling never overwrites a value already on the document, and the address text is copied, so editing a contact address does not change documents already raised. For India GST, the billing contact address's Place Of Supply and GSTIN fill a sales document's blanks before the account's, and its GST Registration Type, when set, decides the tax supply type instead of the account's. A branch's postal address is also a contact address, and the selling branch's address prints as the seller address on invoices. Activating a partner onboarding application creates a default Both address on the new partner account. Deleting a contact address sends it to the recycle bin. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The account the address belongs to. Required: an address cannot be saved without an account. Documents raised for this account offer its addresses, and the account's default address fills them automatically. | | `AddressType` | Address Type | PickList | | Billing, Shipping or Both. A Billing or Both address can fill a document's billing side and a Shipping or Both address its shipping side when it is the account's default. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | An optional branch the address is associated with. A branch's own postal address is chosen separately, in the Address field on the branch record. | | `City` | City | PickList | | The city as a picklist value maintained by the administrator. Copied to a document's billing or shipping city when the address fills it. Values: Pune. | | `CityPlaceId` | City | Lookup → [Place](/docs/reference/entities/place/) | | The city as a place record from the places master, shown with the label City. Copied to documents along with the text city. | | `ContactId` | Contact | Lookup → [Contact](/docs/reference/entities/contact/) | | The optional contact person at this address. | | `Country` | Country | PickList | | The country as a picklist value maintained by the administrator. Copied to documents when the address fills them. Values: India. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DealerOnboardingId` | Dealer Onboarding | Lookup → [DealerOnboarding](/docs/reference/entities/dealer-onboarding/) | | The partner onboarding application this address was created from. Set automatically when an application is activated and the new partner account has no default address yet; that address is created as a default Both address from the application's address, city, state, PIN code and GST number. | | `GSTIN` | GSTIN | LongMultiLineText | | The GST number registered at this address, for a party registered in more than one state. Copied to sales documents whose own GSTIN is blank, ahead of the account's GSTIN. No format check runs on this field when the address is saved. GST reconciliation names a party from the account that owns an address carrying the row's GSTIN when no account carries it. | | `GSTRegistrationType` | GST Registration Type | PickList | | How the party is registered for GST at this address. When set on a sales document's billing address it decides the tax supply type instead of the account's value: Out Of Scope and Non GST Supply make the supply Exempt, Overseas and Deemed Exports make it Export, Special Economic Zone (SEZ) makes it SEZ, and any other value leaves it to the place-of-supply comparison. Values: GST Registered- Regular, GST Registered- Composition, GST Unregistered, Consumer, Overseas, Special Economic Zone (SEZ), Deemed Exports, Non GST Supply, Out Of Scope. | | `Id` | Id | Guid | Yes | | | `IsDefault` | Is Default | Boolean | | Marks the address that new documents use automatically for the account, on the side its Address Type allows. Off by default. Saving an address as default in the back office does not switch other defaults off, so keep one default per side per account; with two, either may be used. | | `LastModifiedBy` | Last Modified By | Lookup | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | The label that identifies the address in lists and lookups. Required on the mobile form. Addresses created automatically are named after their street. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlaceOfSupply` | Place Of Supply | PickList | | The GST state for supplies billed to this address. Copied to sales documents whose own place of supply is blank, ahead of the account's value, and compared with the branch's source of supply to decide between within-state and outside-state supply. | | `PostalCode` | Postal Code | Text | | The postal or PIN code. Copied to documents when the address fills them. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Region` | Region | Text | | A free-text region or district. Copied to documents when the address fills them. | | `State` | State | PickList | | The state as a picklist value maintained by the administrator. Copied to documents when the address fills them. Values: Maharashtra. | | `Street` | Street | Text | | Street, building and locality, up to 200 characters. Copied to documents when the address fills them. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in list header | | `EditInList` | Edit | EditInline | Edit | | `EditPopup` | Edit | Edit | EditPopup | | `New` | New | New | New | | `NewInLine` | New | NewInline | NewInLine | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Place](/docs/reference/entities/place/) — looks up via `CityPlaceId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Contact](/docs/reference/entities/contact/) — looks up via `ContactId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `ShippingAddressId` - [Branch](/docs/reference/entities/branch/) — referenced by via `ContactAddressId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `BillingContactAddressId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `BillingAddressId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `DeliveryContactAddressId` - [Bill](/docs/reference/entities/bill/) — referenced by via `ShippingContactAddressId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `BillingAddressId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `PickUpAddressId` - [DealerOnboarding](/docs/reference/entities/dealer-onboarding/) — referenced by via `DealerOnboardingId` - [Asset](/docs/reference/entities/asset/) — referenced by via `InstallationAddressContactAddressId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `DropOffAddressId` - [Order](/docs/reference/entities/order/) — referenced by via `ShippingContactAddressId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `BillingContactAddressId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `ShippingAddressId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `ShippingContactAddressId` - [CheckInInspection](/docs/reference/entities/check-in-inspection/) — referenced by via `ContactAddressId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `ShippingContactAddressId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `ShippingContactAddressId` - [Visit](/docs/reference/entities/visit/) — referenced by via `VisitContactAddressId` - [Quote](/docs/reference/entities/quote/) — referenced by via `BillingContactAddressId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `ShippingContactAddressId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `BillingContactAddressId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `BillingContactAddressId` - [Bill](/docs/reference/entities/bill/) — referenced by via `BillingContactAddressId` - [Order](/docs/reference/entities/order/) — referenced by via `BillingContactAddressId` - [Quote](/docs/reference/entities/quote/) — referenced by via `ShippingContactAddressId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Contact — entity reference URL: https://xmatix.com/docs/reference/entities/contact/ Last reviewed: 2026-08-16 An individual person, usually attached to an Account via accountId (an account's people are its Contacts collection; the account's primary contact is pointed at by Account.accountContactId). Created by hand or automatically during lead conversion (ContactService.CreateContactForAccountAsync links a new contact when a converted account has none). reportsToContactId builds a self-referencing org hierarchy. Carries communication-consent flags (doNotCall, emailOptOut, faxOptOut) and is referenced by Leads, Opportunities, Cases, Orders, Invoices, Assets and Contracts. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `AssistantName` | Assistant | Text | | | | `AssistantPhone` | Assistant Phone | Text | | | | `Birthdate` | Birthdate | Date | | | | `ContactCode` | Contact Code | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CreationSource` | Creation Source | PickList | | Values: Auto Create. | | `Department` | Department | Text | | | | `Description` | Description | Text | | | | `DoNotCall` | Do Not Call | Boolean | | | | `Email` | Email | Text | | | | `EmailOptOut` | Email Opt Out | Boolean | | | | `ExternalId` | External | Text | | | | `Fax` | Fax | Text | | | | `FaxOptOut` | Fax Opt Out | Boolean | | | | `FirstName` | First Name | Text | | | | `FirstNameLocal` | First Name (Local) | Text | | | | `GenderIdentity` | Gender entity | PickList | | Values: Female. | | `HomePhone` | Home Phone | Text | | | | `Id` | Id | Guid | Yes | | | `IndividualId` | Indivual | Lookup → [Individual](/docs/reference/entities/individual/) | | | | `IsDefault` | Is Default | Boolean | | | | `LastName` | Last Name | Text | | | | `LastNameLocal` | Last Name Local | Text | | | | `LastStayInTouchRequestDate` | Last Stay-in-Touch Request Date | DateAndTime | | | | `LastStayInTouchSaveDate` | Last Stay-in-Touch Save Date | Date | | | | `LeadSource` | Lead Source | PickList | | Values: Phone, Inquiry. | | `MailingAddress` | Mailing Address | Text | | | | `MobilePhone` | Mobile Phone | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OtherAddress` | Other Address | Text | | | | `OtherPhone` | Other Phone | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Phone` | Phone | Text | | | | `Pronouns` | Pronouns | PickList | | Values: She/Her, They/Them, He/They, Not Listed. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReportsToContactId` | Reports To | Lookup → [Contact](/docs/reference/entities/contact/) | | | | `Salutation` | Salutation | PickList | | Values: Ms., Dr., Prof., Mx.. | | `Title` | Title | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditInList` | Edit | EditInline | Edit In List Views | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [Contact](/docs/reference/entities/contact/) — looks up via `ReportsToContactId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Contract](/docs/reference/entities/contract/) — referenced by via `CustomerSignedById` - [Lead](/docs/reference/entities/lead/) — referenced by via `ContactId` - [Asset](/docs/reference/entities/asset/) — referenced by via `ContactId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `ContactId` - [IncentiveResource](/docs/reference/entities/incentive-resource/) — referenced by via `ContactId` - [Contact](/docs/reference/entities/contact/) — referenced by via `ReportsToContactId` - [Order](/docs/reference/entities/order/) — referenced by via `ContactId` - [Account](/docs/reference/entities/account/) — referenced by via `AccountContactId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `ContactId` - [Case](/docs/reference/entities/case/) — referenced by via `ContactId` - [ContactAddress](/docs/reference/entities/contact-address/) — referenced by via `ContactId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Contract Line — entity reference URL: https://xmatix.com/docs/reference/entities/contract-line/ Last reviewed: 2026-08-16 One covered-scope line of a service/maintenance agreement: the catalog Item covered or supplied, quantity and pricing (unit price, cost price, discount), the count of customer assets covered, contracted hours, and the preventive-maintenance visit cadence. Multi-year agreements are split into one line per contract year (YearNumber against ContractYears). Billing and delivery can be redirected per line via Bill To Account and Ship To Account, which may differ from the owning Account. It is the parent of PMTask (the individual scheduled maintenance visits). Important: in first-party metadata ContractLine has no foreign key to the Contract header — its only relations are to Account, Item and PMTask — so an agent cannot join Contract to ContractLine without tenant customization. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer Account this line serves. This is the line's anchor relationship: ContractLine has no foreign key to the Contract header in first-party metadata. | | `Assetcount` | Asset count | Number | | Number of customer assets covered by this line. A stored count, not a rollup — no first-party code recomputes it from asset records. | | `BilledAmount` | Billed Amount | Decimal | | Amount billed against this line so far. A stored value maintained by entry or import — no first-party handler recalculates it from invoices. | | `BillingTreatment` | BillingTreatment | PickList | | Classification of how the line is billed. Picklist-typed but with no first-party values seeded — the vocabulary is tenant-defined. | | `BillToAccountId` | Bill To Account | Lookup → [Account](/docs/reference/entities/account/) | | Account invoiced for this line when billing is redirected; it may differ from the line's owning Account. | | `ContractHours` | Contract Hours | Number | | | | `ContractYears` | Contract Years | Number | | Total duration of the parent agreement in years; used together with YearNumber when a multi-year agreement is split into one line per year. | | `CostPrice` | Cost Price | Decimal | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Discount` | Discount | Percent | | | | `Id` | Id | Guid | Yes | | | `Ispartssupply` | Is parts supply | Boolean | | Flags a parts-supply line as opposed to a service/maintenance line. Defaults to false; no first-party server logic branches on it. | | `Isunderwarranty` | Is under warranty | Boolean | | Flags that the equipment covered by this line is still under warranty. Defaults to false and is informational in first-party code — no billing logic branches on it. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | Lookup to the catalog Item (service or part) that this line covers or supplies. | | `Lineitemdescription` | Line item description | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `Series` | Series | Text | | | | `ShipToAccountId` | Ship To Account | Lookup → [Account](/docs/reference/entities/account/) | | Account receiving the delivery or service for this line when it differs from the owning Account. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UnitPrice` | Unit Price | Decimal | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `Vendorname` | Vendor name | Text | | Vendor name captured as free text — not a lookup to Account or any supplier entity. | | `VisitFrequency` | Visit Frequency | PickList | | How often preventive-maintenance visits are due under this line. Picklist-typed with no first-party values seeded, and informational only: no first-party scheduler creates PMTask rows from it. | | `YearNumber` | Year Number | Number | | Which contract year this line covers when a multi-year agreement is split into per-year lines; read alongside ContractYears. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `delete` | delete | Delete | Delete | | `New` | New | NewInline | New | ## Related entities - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Account](/docs/reference/entities/account/) — looks up via `ShipToAccountId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Account](/docs/reference/entities/account/) — looks up via `BillToAccountId` - [PMTask](/docs/reference/entities/pmtask/) — referenced by via `ContractLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Contract Line item — entity reference URL: https://xmatix.com/docs/reference/entities/contract-lineitem/ Last reviewed: 2026-08-16 A priced coverage line under an asset service contract, naming the item covered, the covered asset, a date window, quantity and pricing, and an optional year number for multi-year contracts. It supports a hierarchy through ParentContractLineItemId and RootContractLineItemId so bundled or renewed coverage can be nested under an originating line. Do not treat these amounts as billed, invoiced or entitlement-checked. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `AssetServiceContractId` | Asset Service Contract | Lookup → [AssetServiceContract](/docs/reference/entities/asset-service-contract/) | | The owning service contract header - this is the parent relationship for the line, as opposed to the self-references that express nesting between lines. The line also carries its own AssetId, which may be narrower than the contract's coverage. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `Discount` | Discount | Percent | | | | `Enddate` | End date | Date | | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ListPrice` | List Price | Currency | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentContractLineItemId` | Contract Line item | Lookup → [ContractLineitem](/docs/reference/entities/contract-lineitem/) | | Nests this coverage line beneath another one, giving a single level of parentage - typically for a renewal or an add-on hanging off an original line. It is a self-reference on the same entity, not a link to the contract header. | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RootContractLineItemId` | Contract Line item | Lookup → [ContractLineitem](/docs/reference/entities/contract-lineitem/) | | Points at the originating line at the top of a nested chain so the whole family can be gathered in one query without walking parents. Nothing maintains it automatically - if a hierarchy is built by import or by hand, this must be set deliberately. | | `SalesPrice` | Sales Price | Currency | | | | `StartDate` | Start Date | Date | | | | `Status` | Status | PickList | | Free text with no picklist, no default and no state machine behind it - nothing in the platform advances, validates or reads it. Its meaning is whatever the tenant's own process assigns. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `Subtotal` | Subtotal | Currency | | | | `TotalPrice` | Total Price | Currency | | Stored, never computed and never posted - no pricing, tax or rollup code touches this entity. Do not treat it as an invoiced or billable amount. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `YearNumber` | Year Number | Number | | The contract year this line covers, used to split multi-year coverage into one line per year. It is a plain integer with no validation against the line's own start and end dates. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [ContractLineitem](/docs/reference/entities/contract-lineitem/) — looks up via `ParentContractLineItemId` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — looks up via `AssetServiceContractId` - [ContractLineitem](/docs/reference/entities/contract-lineitem/) — looks up via `RootContractLineItemId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ContractLineitem](/docs/reference/entities/contract-lineitem/) — referenced by via `ParentContractLineItemId` - [ContractLineitem](/docs/reference/entities/contract-lineitem/) — referenced by via `RootContractLineItemId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Contract — entity reference URL: https://xmatix.com/docs/reference/entities/contract/ Last reviewed: 2026-08-16 A service/maintenance agreement header for a customer Account, optionally tied to a single Asset. It carries the commercial frame: the coverage window (ContractStartDate/ContractEndDate), the term length in months, the signature block (company and customer signed dates, signatory title, the signing Contact) and a Draft, Pending Approval, Verified, Active status flow. Line-level scope, pricing and visit cadence live on ContractLine — but note that in first-party metadata ContractLine has no foreign key back to Contract, so the two cannot be joined out of the box. Also note this is the Contract Management app's agreement record only: service documents (ServiceOrder, Invoice, Quote, Claim) never reference it — they link to ItemServiceContract or AssetServiceContract instead, so use those entities when tracing a service document's contract coverage. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `ActivatedDate` | Activated Date | Date | | Date the agreement was activated (moved to the Active status), as distinct from ContractStartDate, which is the contractual start of coverage. | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | Optional lookup tying the agreement header to a single covered Asset. Multi-asset coverage is expressed at line level (ContractLine's asset count) and per visit (PMTask.AssetId) instead. | | `BillingAddress` | Billing Address | Text | | | | `CompanySignedDate` | Company Signed Date | DateAndTime | | | | `ContactId` | Contact | Lookup → [Contact](/docs/reference/entities/contact/) | | Lookup to Contact. Note a naming mismatch: the domain model's only Contact reference on Contract is CustomerSignedById (the customer-side signatory), and the seeded Contract-to-Contact relation binds to that column — so treat this lookup as the customer signatory, pairing with CustomerSignedDate and CustomerSignedTitle. | | `ContractEndDate` | Contract End Date | Date | | | | `ContractName` | Contract Name | Text | | Business title of the agreement, held separately from the platform-level record Name field. | | `ContractNumber` | Contract Number | Number | | Numeric identifier of the agreement, stored as an integer and held separately from both the record Name and the ContractName title. | | `ContractStartDate` | Contract Start Date | Date | | | | `ContractTerms` | Contract Terms (Months) | Number | | Committed contract term length in whole months, stored as a number. It complements ContractStartDate/ContractEndDate rather than being derived from them — no first-party code computes or reconciles it against the dates. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CustomerSignedDate` | Customer Signed Date | Date | | | | `CustomerSignedTitle` | Customer Signed Title | Text | | | | `Description` | Description | Text | | | | `Id` | Id | Guid | Yes | | | `LOB` | LOB | PickList | | Line of business the contract belongs to. Picklist with a single seeded value (Automobile); the working vocabulary is tenant-defined. Values: Automobile. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerExpiration` | Owner Expiration | PickList | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ShippingAddress` | Shipping Address | Text | | | | `SpecialTerms` | Special Terms | Text | | | | `Status` | Status | PickList | | Lifecycle stage of the agreement. Seeded picklist values: Draft (the default), Pending Approval, Verified, Active. No terminal state (expired/cancelled) is seeded; tenants add their own. Values: Draft, Pending Approval, Verified, Active. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Edit` | Edit | Edit | Edit | | `New` | New | New | New | | `NewCreate` | New Create | UIAction | New | ## Related entities - [Contact](/docs/reference/entities/contact/) — looks up via `CustomerSignedById` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Conversion Batch Line — entity reference URL: https://xmatix.com/docs/reference/entities/conversion-batch-line/ Last reviewed: 2026-08-16 One source line in a conversion batch, with its outcome and the document it produced. Also the reservation ledger: a non-terminal line holds quantity against its pool. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AttemptCount` | Attempts | Number | | Execution attempts consumed by this line. | | `BatchId` | BatchId | Lookup → [ConversionBatch](/docs/reference/entities/conversion-batch/) | | | | `CompletedUtc` | Completed | DateAndTime | | When the line reached a terminal status. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `ErrorMessage` | Error | LongMultiLineText | | Why execution failed. | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup | | Item on the source line. | | `ItemName` | Item Name | Text | | Item name captured at staging. | | `Label` | Label | Text | | Source line or record number. | | `MaxAttempts` | Max Attempts | Number | | Attempts before the line is parked, so one poison line stops blocking the batch. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ProcessedQuantity` | Processed Quantity | Decimal | | Quantity actually converted. | | `QuantityPool` | Quantity Pool | Text | | Pool this line holds against. Denormalized so the reservation ledger reads without a join to the header. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedQuantity` | Requested Quantity | Decimal | | Quantity asked for, already capped at what was available. | | `ReservedQuantity` | Reserved Quantity | Decimal | | Quantity held against the pool while the line is Pending or Processing. | | `ResultEntityName` | Result Entity | Text | | Entity of the document this line produced. | | `ResultRecordId` | Result Record | Guid | | Id of the document this line produced. | | `ResultRecordNumber` | Result Document | Text | | Document number produced, e.g. the invoice number. | | `Sequence` | Sequence | Number | | Execution order: grouped by source record, then by line number. | | `SourceLineId` | Source Line | Guid | | Id of the source line. Empty in record-level mode. | | `SourceLineNumber` | Source Line Number | Text | | Document number of the source line. | | `SourceRecordId` | Source Record | Guid | | Id of the source document. A generic id rather than a typed key — the trade that lets one table serve every conversion. | | `SourceRecordNumber` | Source Document | Text | | Document number of the source record. | | `StartedUtc` | Started | DateAndTime | | When the line was picked up. | | `Status` | Status | PickList | | Pending, Processing, Succeeded, Skipped, Failed or Cancelled. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `ValidationMessage` | Validation Message | LongMultiLineText | | Why the line was skipped at staging. | ## Related entities - [ConversionBatch](/docs/reference/entities/conversion-batch/) — looks up via `BatchId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Conversion Batch — entity reference URL: https://xmatix.com/docs/reference/entities/conversion-batch/ Last reviewed: 2026-08-16 A staged document conversion (Order → Invoice, Requisition → Purchase Order, …). Created by the batch engine and executed by the scheduler. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ActionName` | Action | Text | | Server action that staged the batch. | | `AttemptCount` | Attempts | Number | | Execution attempts consumed. | | `BatchId` | BatchId | Lookup → [ConversionBatchLine](/docs/reference/entities/conversion-batch-line/) | | | | `CancelledLines` | Cancelled Lines | Number | | Lines cancelled before they ran. | | `ChunkSize` | Chunk Size | Number | | Lines per execution transaction. Bounds lock duration and the work a crash discards. | | `CompletedUtc` | Completed | DateAndTime | | When it reached a terminal status. | | `ConversionKey` | Conversion | Text | | Registered conversion key, e.g. sales.order-to-invoice. The discriminator that lets one table serve every conversion. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `ErrorMessage` | Error | LongMultiLineText | | Why the last attempt failed. | | `FailedLines` | Failed Lines | Number | | Lines that failed and exhausted their attempts. | | `FromDate` | From Date | Date | | Start of the document-date window the submission used. | | `Id` | Id | Guid | Yes | | | `IdempotencyKey` | Submission Key | Text | | Client submission key. The first call creates the batch and later calls append to it, so one submission is one batch however many records it covers. | | `JobRunId` | Job Run | Guid | | Tenant-jobs run that executed the batch. | | `Label` | Label | Text | | Display label, defaulted to the conversion display name. | | `LeaseExpiryUtc` | Lease Expiry | DateAndTime | | Claim expiry. Past this any worker may reclaim the batch — how a dead worker is recovered from. | | `LeaseOwner` | Lease Owner | Text | | Worker holding the claim, as machine:pid. | | `MaxAttempts` | Max Attempts | Number | | Attempts allowed before the batch fails terminally. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NextAttemptUtc` | Next Attempt | DateAndTime | | Earliest the scheduler may retry, after backoff. | | `OptionsJson` | Options | LongMultiLineText | | Conversion options as supplied. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PayloadJson` | Payload | LongMultiLineText | | The staging action arguments verbatim, for replay and forensics. | | `PendingLines` | Pending Lines | Number | | Lines still to convert. | | `PendingQuantityField` | Pending Quantity Field | Text | | Field read off the source line as the pool supply. | | `Priority` | Priority | Number | | Lower runs earlier — lets a stuck queue be jumped without a code change. | | `ProcessingMode` | Processing Mode | PickList | | RecordLevel (every eligible line) or LineLevel (only the lines the user picked). | | `QuantityPool` | Quantity Pool | Text | | Pool the batch holds quantity against. Conversions sharing a pending-quantity field share a pool, so they cannot promise the same units twice. | | `QueuedUtc` | Queued | DateAndTime | | When the batch was staged. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedById` | Requested By | Lookup | | User who submitted the batch. | | `RequestedByName` | Requested By Name | Text | | Display name of the submitter. | | `ScopeAccountId` | Account | Lookup | | Account the submission was scoped to. | | `ScopeBranchId` | Branch | Lookup | | Branch the submission was scoped to. | | `ScopePartnerAccountId` | Partner Account | Lookup | | Company the submission was scoped to. | | `SkippedLines` | Skipped Lines | Number | | Lines with nothing left to convert, or no available quantity. | | `SourceEntityName` | Source Entity | Text | | Entity the batch converts from. Denormalized so a historical batch still renders after its module is removed. | | `SourceLineEntityName` | Source Line Entity | Text | | Line entity of the source document. | | `StartedUtc` | Started | DateAndTime | | When a worker first claimed it. | | `Status` | Status | PickList | | Draft, Queued, Processing, Cancelling, Completed, CompletedWithErrors, Failed or Cancelled. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `SucceededLines` | Succeeded Lines | Number | | Lines that produced a target document. | | `TargetEntityName` | Target Entity | Text | | Entity the batch creates. | | `ToDate` | To Date | Date | | End of the document-date window the submission used. | | `TotalLines` | Total Lines | Number | | Lines staged in the batch. | | `TotalProcessedQuantity` | Processed Quantity | Decimal | | Total quantity actually converted. | | `TotalRequestedQuantity` | Requested Quantity | Decimal | | Total quantity accepted at staging. | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `ValidationMessage` | Validation Message | LongMultiLineText | | Why the batch as a whole was rejected. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `CancelBatch` | Cancel Batch | ServerAction (`CancelBatch`) | Cancels a queued batch outright, or asks a running one to stop at its next chunk. | | `GetConversions` | Get Conversions | ServerAction (`GetConversions`) | Record-less. Returns the registered conversion descriptors. | | `GetHeldQuantities` | Get Held Quantities | ServerAction (`GetHeldQuantities`) | Record-less. Returns quantity held per source line. | | `RetryFailedLines` | Retry Failed Lines | ServerAction (`RetryFailedLines`) | Returns parked failed lines to pending and re-queues the batch. | ## Related entities - [ConversionBatchLine](/docs/reference/entities/conversion-batch-line/) — referenced by via `BatchId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Conversion Definition — entity reference URL: https://xmatix.com/docs/reference/entities/conversion-definition/ Last reviewed: 2026-08-16 Declares one document conversion (Order→Invoice, Requisition→Purchase Order, …) for the conversion batch engine. One row replaces a code change plus a deploy. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BatchActionName` | Batch Action Name | Text | Yes | | | `Category` | Category | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DefaultChunkSize` | Chunk Size | Number | | | | `DefaultMaxAttempts` | Max Attempts | Number | | | | `DefaultMaxLineAttempts` | Max Line Attempts | Number | | | | `Description` | Description | LongMultiLineText | | | | `FailureIsolation` | Failure Isolation | Text | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Active | Boolean | | | | `Label` | Display Name | Text | Yes | | | `LegacyActionNames` | Legacy Action Names | LongMultiLineText | | | | `LineFields` | Line Fields | LongMultiLineText | | | | `ListFields` | List Fields | LongMultiLineText | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OptionsJson` | Options (JSON) | LongMultiLineText | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PendingQuantityField` | Pending Quantity Field | Text | Yes | | | `QuantityPool` | Quantity Pool | Text | | | | `RecordActionName` | Record Action Name | Text | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ScopeFields` | Scope Fields | LongMultiLineText | | | | `SelectionArgsKey` | Selection Args Key | Text | Yes | | | `SourceEntity` | Source Entity | Text | Yes | | | `SourceLineEntity` | Source Line Entity | Text | Yes | | | `SourceLineNavigation` | Source Line Navigation | Text | Yes | | | `SourceLineParentField` | Source Line Parent Field | Text | Yes | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TargetEntity` | Target Entity | Text | Yes | | | `TargetLineEntity` | Target Line Entity | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Cost Center — entity reference URL: https://xmatix.com/docs/reference/entities/cost-center/ Last reviewed: 2026-08-16 A hierarchical cost-allocation dimension (parentCostCenterId builds the tree, optionally under a Business Unit), stamped on expense claims, claim lines and advances for cost control and segment reporting - complementary to Branch and Business Unit. When a claim posts, the cost centre is stamped only on the expense (P&L) journal lines, never on the control or bank lines, so cost-centre sub-balances stay clean on balance-sheet accounts. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `Code` | Code | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentCostCenterId` | Parent Cost Center | Lookup → [CostCenter](/docs/reference/entities/cost-center/) | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this CostCenter. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this CostCenter. | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a CostCenter. | | `View` | View | View | View this CostCenter. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [CostCenter](/docs/reference/entities/cost-center/) — looks up via `ParentCostCenterId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — referenced by via `CostCenterId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `CostCenterId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `CostCenterId` - [CostCenter](/docs/reference/entities/cost-center/) — referenced by via `ParentCostCenterId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Credit Limit — entity reference URL: https://xmatix.com/docs/reference/entities/credit-limit/ Last reviewed: 2026-08-16 The credit ceiling a company (PartnerAccountId) extends to one customer account (AccountId), and the row that actually blocks trading. ArApSubledgerService looks it up by that company-plus-customer pair, sums the customer's live receivable exposure from OpenTransaction rows that are neither Settled nor Reversed, and reports a breach when that exposure plus the proposed document amount exceeds CreditLimitAmount. The Order and Invoice handlers call it on insert only and throw a validation failure on a breach, so an over-limit customer cannot have a new order or invoice saved; edits to existing documents are not re-checked. The check fails open — no limit row, a zero or null amount, or an unavailable subledger all let the document through. Exposure is recomputed live on every check, so the stored utilised and available columns are not what the gate consults. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer whose trading is being capped. | | `AvaliableLimit` | Avaliable Limit | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `CreditDays` | Credit Days | Number | | Intended as the payment terms in days for this customer. | | `CreditLimitAmount` | Credit Limit Amount | Currency | | The ceiling that is actually enforced, and the only column the check reads. It must be greater than zero for a limit to be considered to exist at all — a null or zero value makes the check report no limit and lets every document pass, since the gate deliberately fails open. | | `CreditLimitName` | Name | Text | Yes | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company extending the credit, not the customer receiving it. The gate matches on this alongside the customer, so a limit stamped with a different company from the one on the order or invoice is not found and the document is allowed through unchecked. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Status` | Status | PickList | | Approval state offering Draft, Pending Approval and Approved. Values: Draft, Pending Approval, Approved. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `UtilizedLimit` | Utilized Limit | Currency | | A stored figure for credit already consumed, but no first-party code writes or reads it. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Credit Note Line — entity reference URL: https://xmatix.com/docs/reference/entities/credit-note-line/ Last reviewed: 2026-08-16 One item or charge line of a CreditNote, and like its parent it carries three flavours driven by the parent's TransactionType: a financial line (GL repost on approval only), a SaleReturn line (item/price/tax setup, inventory posting, and return-quantity write-backs to the source InvoiceLine, DeliveryOrderLine and OrderLine), and a BillReturn line (same setup plus write-backs to Bill, PurchaseOrder and GoodsReceipt lines). CreditNoteLineHandler owns those write-backs and recomputes them as a SUM over the lines, so edits and deletes stay correct. Which amount column the ledger reads depends on the parent: the financial CreditNote posting purpose reads GLAmount, while the Return and BillReturn purposes read Amount. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Amount` | Amount | Currency | | The line's net value, and the amount the ledger reads for the two return purposes: a SaleReturn note posts its revenue/AR reversal legs from this column and a BillReturn note posts its GR-IR leg from it. It also rolls up into the parent's calculated Amount. A financial credit note posts from GLAmount instead. | | `ApplyPostTaxDiscount` | Apply Post Tax Discount | Boolean | Yes | Switches the line's discounts from pre-tax to post-tax. When set, every discount rate on the line (trade, cash, contract and scheme) is applied to BaseAmount PLUS TaxAmount rather than to BaseAmount alone, and GrossAmount then subtracts those discounts explicitly. It therefore changes the discount value, not just its presentation. | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `BaseAmount` | Base Amount | Calculated (calculated) | | Calculated as Quantity times the effective unit price — UnitPrice2 when it is positive, otherwise UnitPrice. It is the value before any discount and before tax, and it is the base every discount percentage on the line is applied to. | | `BillId` | Bill | Lookup → [Bill](/docs/reference/entities/bill/) | | | | `BillLineId` | Bill Line | Lookup → [BillLine](/docs/reference/entities/bill-line/) | | The supplier bill line being returned, on a purchase-return (parent TransactionType "BillReturn") line. Purchase returns write quantities back to Bill, PurchaseOrder and GoodsReceipt lines the way sale returns write back to Invoice/DeliveryOrder/Order lines. | | `BranchId` | Branch | Lookup | | | | `ChassisNumber` | Chassis Number | Text | | | | `ClaimableQuantity` | Claimable Quantity | Calculated (calculated) | | Calculated: the line's Quantity when ReturnType is "Damaged", "Shortage" or "Excess", and zero otherwise — the quantity that can be claimed from the supplier. "Expired" is deliberately excluded. Paired with IsClaimed, which records that the claim was raised. | | `ClaimLineId` | Claim Line | Lookup → [ClaimLine](/docs/reference/entities/claim-line/) | | | | `ContractDiscount` | Contract Discount | Percent | | | | `ContractDiscountAmount` | Contract Discount Amount | Currency | | | | `ConversionRatio` | Conversion Ratio | Number | | | | `ConversionRatio1` | Conversion Ratio 1 | Number | | | | `Cost` | Cost | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CreditNoteId` | Credit Note | Lookup → [CreditNote](/docs/reference/entities/credit-note/) | | | | `DamagedQuantity` | Damaged Quantity | Calculated (calculated) | | Calculated, not entered: it is the line's whole Quantity when ReturnType is "Damaged" and zero otherwise. So it does not split a line into good and damaged portions — the whole line is one condition, and a mixed return needs separate lines. | | `DeliveryOrderLineId` | Delivery Order Line | Lookup → [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) | | The delivery-order line the returned goods went out on; the third sale-return write-back target, recomputed as a SUM over the credit-note lines referencing it. | | `DeliveryQuantity` | Delivery Quantity | Number | | | | `Description` | Description | Text | | | | `Discount` | Discount | Percent | | | | `Discount2` | Cash Discount | Percent | | | | `DiscountAmount` | Discount Amount | Number | | | | `DiscountAmount2` | Cash Discount Amount | Currency | | | | `DocumentNumber` | Document Number | Number | Yes | | | `EngineNumber` | Engine Number | Text | | | | `ExcessQuantity` | Excess Quantity | Calculated (calculated) | | Calculated from ReturnType: the line's Quantity NEGATED when ReturnType is "Excess", zero otherwise — so like ShortageQuantity it is normally a negative number, not a positive over-receipt. | | `ExpiredQuantity` | Expired Quantity | Calculated (calculated) | | Calculated, not entered: the line's whole Quantity when ReturnType is "Expired", zero otherwise — the expiry counterpart of DamagedQuantity. | | `ExternalId` | External | Text, unique | | | | `GeneralLedgerId` | General Ledger | Lookup → [GeneralLedger](/docs/reference/entities/general-ledger/) | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | An explicit GL account for this line's income/expense leg. When set it wins over PostingDefinition and account-type resolution, which is how a specific charge is directed to its own account rather than the document's default income account. | | `GLAmount` | GL Amount | Calculated (calculated) | | Calculated as a copy of Amount, and the column the financial (non-return) CreditNote posting purpose reads for this line's income leg. On sale-return and purchase-return notes the posting engine reads Amount directly instead, so the two are equal by construction but only one of them is the documented input for a given purpose. | | `GoodsReceiptId` | Goods Receipt | Lookup → [GoodsReceipt](/docs/reference/entities/goods-receipt/) | | | | `GoodsReceiptLineId` | Goods Receipt Line | Lookup → [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) | | | | `GrossAmount` | Gross Amount | Calculated (calculated) | | Calculated as Amount plus TaxAmount, less the scheme and net discounts when ApplyPostTaxDiscount is set (they are already netted out of Amount otherwise). It is the tax-inclusive line total, the figure the parent's TotalAmount is meant to sum — though that formula names a stale child collection, so sum this column directly. | | `Id` | Record | Guid | Yes | | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | Set when the line has been posted to the inventory ledger, and used as the not-yet-posted marker: the PerformInventoryPosting action posts only lines where this is null, and refuses the invoke outright when no such lines remain. | | `InvoiceId` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | | | `InvoiceLineId` | Invoice Line | Lookup → [InvoiceLine](/docs/reference/entities/invoice-line/) | | The invoice line being returned or credited. It is the key the sale-return write-back uses: when lines are inserted, updated or deleted, the handler recomputes the returned quantity on this InvoiceLine as a SUM over the credit-note lines pointing at it. | | `IsApproved` | Approved | Boolean | Yes | | | `IsClaimed` | Claimed | Boolean | | | | `IsGLPosted` | Is GL Posted | Boolean | Yes | | | `IsGLPostingApproved` | Is GL Posting Approved | Boolean | Yes | | | `IsILPosted` | IL Posted | Boolean | Yes | | | `IsILPostingApproved` | IL Posting Approved | Boolean | Yes | | | `IsSchemeGenerated` | Scheme Generated | Boolean | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `LineNumber` | Line Number | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NetDiscount` | Net Discount | Calculated (calculated) | | Calculated: the sum of the three discount slots — trade (Discount/DiscountAmount), cash (Discount2/DiscountAmount2) and contract (ContractDiscount/ContractDiscountAmount). Each slot resolves the same way: an explicit positive *Amount wins outright, otherwise the rate is applied to BaseAmount, or to BaseAmount plus TaxAmount when ApplyPostTaxDiscount is set. This is the discount figure to report; the individual Discount* columns are inputs. Scheme discount is tracked separately in NetSchemeDiscount. | | `NetSchemeDiscount` | Net Scheme Discount | Calculated (calculated) | | Calculated scheme/promotion discount on the line, kept separate from NetDiscount: an explicit SchemeDiscountAmount wins, otherwise the SchemeDiscount rate is applied to BaseAmount, or to BaseAmount plus TaxAmount when ApplyPostTaxDiscount is set. This is the column the parent's scheme-discount total is meant to sum. | | `OrderLineId` | Sale Order Line | Lookup → [OrderLine](/docs/reference/entities/order-line/) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Calculated | | | | `PendingDeliveryQuantity` | Pending Delivery Quantity | Calculated (calculated) | | Calculated as Quantity minus DeliveryQuantity: what is still to be shipped back to the vendor on a purchase return. The delivery-release actions consider only lines with a positive value here, and SelectiveDeliveryOrder falls back to this quantity when the caller supplies no explicit RequestedQuantity. | | `PriceAsOnDate` | Price As On Date | Date | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `PriceListRuleId` | Price List Rule | Lookup → [PriceListRule](/docs/reference/entities/price-list-rule/) | | | | `PurchaseOrderId` | Purchase Order | Lookup → [PurchaseOrder](/docs/reference/entities/purchase-order/) | | | | `PurchaseOrderLineId` | Purchase Order Line | Lookup → [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) | | | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedQuantity` | Requested Quantity | Decimal | | A virtual (not persisted) quantity used to drive the SelectiveDeliveryOrder action: the caller passes a per-line requested quantity in the action payload and the handler applies it, defaulting to PendingDeliveryQuantity when the value is zero. Do not expect it to hold a value when reading a stored line. | | `ReturnType` | Return Type | PickList | | Classifies why the line is coming back, and it is a driver rather than a label: DamagedQuantity, ExpiredQuantity, ShortageQuantity, ExcessQuantity and ClaimableQuantity are all calculated from it. The values those formulas recognise are "Damaged", "Expired", "Shortage" and "Excess"; anything else (including blank) leaves every one of those quantities at zero, which is the usual case for an ordinary return of good stock. Because the whole line Quantity is attributed to one type, a mixed return needs one line per condition. | | `SchemeBenefitId` | Scheme Benefit | Lookup → [SchemeBenefit](/docs/reference/entities/scheme-benefit/) | | | | `SchemeDiscount` | Scheme Discount | Percent | | | | `SchemeDiscountAmount` | Scheme Discount Amount | Number | | | | `SchemeLineId` | SchemeLine | Lookup → [SchemeLine](/docs/reference/entities/scheme-line/) | | | | `SchemeRewardPoints` | Scheme Reward Points | Number | | | | `ServiceOrderLineId` | Work Orde Line | Lookup → [ServiceOrderLine](/docs/reference/entities/service-order-line/) | | | | `ShortageQuantity` | Shortage Quantity | Calculated (calculated) | | Calculated from ReturnType: the line's Quantity NEGATED when ReturnType is "Shortage", zero otherwise. The sign is deliberate — a shortage is stock never received, so it moves the opposite way to a return of goods — and it means this column is normally negative, not positive. | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `Tax1` | Tax 1 | Currency | | Tax amount in component slot 1. The six generic Tax{i}/Tax{i}Name/Tax{i}Rate/Tax{i}Type slots exist because the posting engine iterates them unconditionally; which real tax sits in slot 1 depends on the tax group applied, so always read Tax1Type rather than assuming a component. | | `Tax1Name` | Tax Name 1 | Text | | | | `Tax1Rate` | Tax Rate 1 | Currency | | | | `Tax1Type` | Tax Type 1 | Text | | The tax component type string for slot 1 (CGST, SGST, IGST, cess and so on). The posting engine loops the six Tax{i} slots and resolves each tax GL account BY this type string, so a component whose type is missing here does not post and the journal comes out short by that tax. | | `Tax2` | Tax 2 | Currency | | | | `Tax2Name` | Tax Name 2 | Text | | | | `Tax2Rate` | Tax Rate 2 | Currency | | | | `Tax2Type` | Tax Type 2 | Text | | | | `Tax3` | Tax 3 | Currency | | | | `Tax3Name` | Tax Name 3 | Text | | | | `Tax3Rate` | Tax Rate 3 | Currency | | | | `Tax3Type` | Tax Type 3 | Text | | | | `Tax4` | Tax 4 | Currency | | | | `Tax4Name` | Tax Name 4 | Text | | | | `Tax4Rate` | Tax Rate 4 | Currency | | | | `Tax4Type` | Tax Type 4 | Text | | | | `Tax5` | Tax 5 | Currency | | | | `Tax5Name` | Tax Name 5 | Text | | | | `Tax5Rate` | Tax Rate 5 | Currency | | | | `Tax5Type` | Tax Type 5 | Text | | | | `Tax6` | Tax 6 | Currency | | | | `Tax6Name` | Tax Name 6 | Text | | | | `Tax6Rate` | Tax Rate 6 | Currency | | | | `Tax6Type` | Tax Type 6 | Text | | | | `TaxAmount` | Tax Amount | Currency | | Total tax on the line — the sum of the six component slots. This is the figure to use for a line's tax; the parent's Total* tax columns are calculated over a stale child-collection name and are unreliable. | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | | | `UnitCost2` | Unit Cost | Currency | | | | `UnitPrice` | Unit Price | Number | | | | `UnitPrice2` | Unit Price 2 | Currency | | | | `UOM` | UOM | Text | | | | `UOM1` | UOM 1 | Text | | | | `UOMQuantity` | UOM Quantity | Number | | | | `UOMQuantity1` | UOM Quantity1 | Number | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `NewInLine` | New | NewInline | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Invoice Line Filter | `InvoiceLineId` | | ## Related entities - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — looks up via `GoodsReceiptId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — looks up via `SchemeBenefitId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [OrderLine](/docs/reference/entities/order-line/) — looks up via `OrderLineId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — looks up via `DeliveryOrderLineId` - [SchemeLine](/docs/reference/entities/scheme-line/) — looks up via `SchemeLineId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — looks up via `PriceListRuleId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — looks up via `GeneralLedgerId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — looks up via `InvoiceLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — looks up via `GoodsReceiptLineId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [ClaimLine](/docs/reference/entities/claim-line/) — looks up via `ClaimLineId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — looks up via `PurchaseOrderLineId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — looks up via `PurchaseOrderId` - [CreditNote](/docs/reference/entities/credit-note/) — looks up via `CreditNoteId` - [BillLine](/docs/reference/entities/bill-line/) — looks up via `BillLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Bill](/docs/reference/entities/bill/) — looks up via `BillId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — looks up via `ServiceOrderLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Credit Note — entity reference URL: https://xmatix.com/docs/reference/entities/credit-note/ Last reviewed: 2026-08-16 A credit document that reduces what a party owes, and the merged home of three different documents discriminated by TransactionType: null/empty is a pure financial AR credit note (Dr Sales / Cr AR, party = AccountId); "SaleReturn" is a customer goods return (the mirror of an Invoice, revenue and AR reversal, lines carry items and post to inventory); "BillReturn" is a purchase return to a supplier (Dr AP / Cr GR-IR plus input-tax reversal, party = SupplierAccountId). CreditNoteHandler gates almost all return behaviour on this discriminator, so the same entity behaves as three documents and a query that ignores TransactionType mixes sales and purchase traffic. Children are CreditNoteLine; it can point at the Invoice, DeliveryOrder, GoodsReceipt or PurchaseOrder it reverses, and at the Claim that generated it. Settlement against open invoices is recorded as PaymentAdjustment rows (legacy) or SettlementAllocation against an OpenTransaction (the current open-item engine). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer the note is issued to, and the party the ledger posts against for the financial CreditNote and SaleReturn purposes. A BillReturn credit note does NOT use this field — its party is SupplierAccountId — so party analysis over credit notes must branch on TransactionType. | | `AdjustedAmount` | Adjusted Amount | Currency | | How much of the note's value has already been consumed settling other documents. It is maintained by the settlement code (the claim-engine credit application and the payment-adjustment service), not by the user, and OpenAmount is kept as Amount minus this value. | | `Amount` | Amount | Calculated (calculated) | | Calculated field: the sum of CreditNoteLine.Amount over the note's lines. It is the note's face value and the base of OpenAmount (OpenAmount = Amount - AdjustedAmount when a settlement is applied), not a user-entered figure. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `ClaimId` | Claim | Lookup → [Claim](/docs/reference/entities/claim/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Currency` | Currency | PickList | | Values: INR, GBP. | | `DeliveryOrderId` | Delivery Order | Lookup → [DeliveryOrder](/docs/reference/entities/delivery-order/) | | The outbound delivery the returned goods came out on, for sale-return notes; return quantities are written back to its lines. Purchase-return notes instead RELEASE a delivery order for the goods going back to the vendor, via the PerformReleaseDelivery / SelectiveDeliveryOrder actions. | | `DeliveryOrderLineId` | Delivery Order Line | Lookup → [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) | | | | `Description` | Description | Text | | | | `DiscountGroupId` | Discount Group | Lookup → [DiscountGroup](/docs/reference/entities/discount-group/) | | | | `DocumentDate` | Document Date | Date | Yes | The note's accounting date — the date every posting purpose for this entity uses to date its journal, so it decides which fiscal period the credit lands in. Defaulted to the current date when a sale-return note is created. | | `DueDate` | Due Date | Date | | | | `ExternalId` | External | Text | | | | `GeneralLedgerId` | General Ledger | Lookup → [GeneralLedger](/docs/reference/entities/general-ledger/) | | Legacy pointer to the decommissioned GeneralLedger entity, retained on the row and guarded as a system field. The current ledger links the other way: Journal.SourceEntityName + Journal.SourceRecordId identify the document that produced the journal. | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | An explicit header (control) GL account for the note. Where a posting purpose opts into it, this beats PostingDefinition and chart-of-accounts resolution, which is how a charge lands in the same subledger as the document it relates to instead of whichever account resolution by type would pick. | | `GLAmount` | GL Amount | Calculated (calculated) | | Calculated as a copy of Amount, and the header-side amount the financial CreditNote posting purpose uses when the note has no lines to post. Note the asymmetry: the CreditNote purpose reads GLAmount on the lines too, while the SaleReturn (Return) and BillReturn purposes read CreditNoteLine.Amount instead. | | `GoodsReceiptId` | Goods Receipt | Lookup → [GoodsReceipt](/docs/reference/entities/goods-receipt/) | | | | `Id` | Id | Guid | Yes | | | `InvoiceId` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | The customer invoice this note credits or returns against. It is the audit link to the original supply — GST credit/debit-note reporting quotes the original invoice — but it does NOT itself settle the invoice: settlement is a separate PaymentAdjustment or SettlementAllocation row. | | `IsGLPosted` | Is GL Posted | Boolean | Yes | A legacy posting marker guarded as a system field (a client attempting to change it is rejected). No first-party code sets it on a credit note under the journal-based ledger, so it stays false even on fully posted notes — do not use it to test whether a note has posted. The reliable test is the existence of a Journal whose SourceEntityName is "CreditNote" and SourceRecordId is this row, or the note's OpenTransaction. | | `IsGLPostingApproved` | Is GL Posting Approved | Boolean | Yes | The flag that actually triggers ledger posting. When it is true as the note is saved, the handler posts the note through DocumentJournalPostingService under the purpose chosen by TransactionType and captures the GST tax transactions. | | `IsInJobQueue` | In Job Queue | Boolean | | | | `IsReturned` | Returned | Boolean | | Set true by the handler when PerformReturn is approved on a purchase-return (BillReturn) note; it marks the return as executed. Not maintained on financial or sale-return notes. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `JobInterfaceQueueId` | Job Queue | Lookup → [InterfaceQueue](/docs/reference/entities/interface-queue/) | | | | `LineSubTotal` | Line Sub Total | Calculated | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `Name` | Name | Text | Yes | | | `Notes` | Notes | LongMultiLineText | | | | `OpenAmount` | Open Amount | Calculated | | The unconsumed balance of the credit note — a STORED column recomputed as Amount minus AdjustedAmount whenever a settlement is applied, not a live formula. Zero means the credit is fully consumed; the credit-application pass skips notes with nothing left. For an authoritative party balance prefer the matching OpenTransaction row, which the ledger maintains. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The trading partner (dealer/distributor) the note belongs to, used for branch validation on sale returns and as the key the credit-application pass uses to find that partner's open invoices. Distinct from AccountId (the customer) and SupplierAccountId (the vendor). | | `PerformGLPosting` | Perform GL Posting | Boolean | Yes | | | `PerformInventoryPosting` | Perform Inventory Posting | Boolean | | Request flag for posting the note's lines to the inventory ledger. The PerformInventoryPosting action is what performs it, and it validates first: if every CreditNoteLine already carries an InventoryLedgerId the invoke fails with "No Credit Note Lines found for Inventory Posting". | | `PerformReturn` | Perform Return | Boolean | | Two distinct meanings by TransactionType. On a SaleReturn note it drives the PerformReturn action, which builds return lines from the invoice lines the user picked. On a BillReturn note, setting it true during a save makes the handler flip IsReturned to true and reset this flag back to false — so it behaves as a one-shot trigger, not a state. | | `PlaceOfSupply` | Place of Supply | PickList | | | | `PriceAsOnDate` | Price As On Date | Date | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `PriceListRuleId` | Price List Rule | Lookup → [PriceListRule](/docs/reference/entities/price-list-rule/) | | | | `PurchaseOrderId` | Purchase Order | Lookup → [PurchaseOrder](/docs/reference/entities/purchase-order/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `ResourceId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `RoundOff` | Round Off | Currency | | | | `SourceOfSupply` | Source of Supply | PickList | | | | `Status` | Status | PickList | | | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | The vendor a purchase-return (TransactionType "BillReturn") credit note is raised on, and the party its Dr Accounts Payable posting hits. Validated to be an account flagged as a supplier on insert and update. Null on financial and sale-return notes. | | `SupplierInvoiceAmount` | Supplier Invoice Amount | Currency | | | | `SupplierInvoiceDate` | Supplier Invoice Date | Date | | | | `SupplierInvoiceNumber` | Supplier Invoice Number | Text | | The vendor's own document number for the purchase being returned, carried on a BillReturn note for reconciliation against the supplier's books and for GST credit-note reporting on the inward side. Free text supplied by the user, not a link. | | `TaxSupplyType` | Tax Supply Type | PickList | | | | `TotalAmount` | Total Amount | Calculated (calculated) | | A calculated total whose stored formula sums a "ReturnLines" collection — the child navigation of the pre-merge Return document. The merged CreditNote type exposes its children as CreditNoteLines only, so do not rely on this column: sum CreditNoteLine directly (GrossAmount for the gross figure) when the number matters. The same caveat applies to the other Total* columns on this entity. | | `TotalDiscountAmount` | Total Discount Amount | Calculated (calculated) | | Calculated total of line net discount, summing the pre-merge "ReturnLines" collection rather than CreditNoteLines — unreliable; sum CreditNoteLine.NetDiscount directly. | | `TotalLineAmount` | Total Line Amount | Calculated (calculated) | | Calculated total of the line amounts, but its stored formula sums the pre-merge "ReturnLines" collection rather than CreditNoteLines — treat the value as unreliable and sum CreditNoteLine.Amount directly. | | `TotalLineBaseAmount` | Total Line Base Amount | Calculated (calculated) | | Calculated total of line base (pre-discount, pre-tax) amounts, summing the pre-merge "ReturnLines" collection rather than CreditNoteLines — unreliable; sum CreditNoteLine.BaseAmount directly. | | `TotalLineGrossAmount` | Total Line Gross Amount | Calculated (calculated) | | Header amount the BillReturn (purchase-return) posting purpose reads when posting the note, calculated over the pre-merge "BillReturnLines" collection — the same stale-navigation caveat as the other Total* columns applies, so verify against CreditNoteLine.GrossAmount. | | `TotalLineTaxAmount` | Total Line Tax Amount | Calculated (calculated) | | Calculated total of line tax, summing the pre-merge "ReturnLines" collection rather than CreditNoteLines — unreliable on merged credit notes; sum CreditNoteLine.TaxAmount directly. | | `TotalSchemeDiscountAmount` | Total Scheme Amount | Calculated (calculated) | | Calculated total of scheme discount on the lines (labelled "Total Scheme Amount"), summing the pre-merge "ReturnLines" collection rather than CreditNoteLines — unreliable; sum CreditNoteLine.NetSchemeDiscount directly. | | `TotalTaxAmount` | Total Tax Posting Amount | Currency | | A stored (non-calculated) decimal labelled "Total Tax Posting Amount". Easy to confuse with TotalTaxAmount2, which is labelled "Total Tax Amount" and IS calculated — the two names and the two labels are crossed, so check which column a screen or query actually means. Neither is the note's true total tax; sum CreditNoteLine.TaxAmount for that. | | `TotalTaxAmount2` | Total Tax Amount | Calculated (calculated) | | Despite its label "Total Tax Amount" this is a calculated sum of a single tax slot only — Tax2 across the lines — and it sums the pre-merge "ReturnLines" collection at that. It is not the note's total tax. Use CreditNoteLine.TaxAmount for the real figure. | | `TransactionType` | Transaction Type | PickList | | The discriminator that decides which of three documents this row is, and therefore how it posts: null or empty = financial AR credit note (CreditNote posting purpose, party AccountId), "SaleReturn" = customer goods return (Return purpose, revenue/AR reversal), "BillReturn" = purchase return to a supplier (BillReturn purpose, party SupplierAccountId). Validation, defaults, inventory posting and the delivery-release actions are all gated on it. Filter on it before aggregating credit notes — otherwise sales and purchase traffic land in the same total. Values: SaleReturn, BillReturn, Claim Settlement. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `EditInLine1` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit, inactive | EditListRow | | `New` | New | New | New | | `PerformReturn` | Perform Return | ServerAction (`PerformReturn`) | On a sale-return credit note, creates CreditNoteLine rows from the invoice lines passed in the action payload (an "InvoiceLines" array). The quantity write-backs to the Invoice, DeliveryOrder and Order lines are NOT done here — inserting the lines runs the line handler, which owns those aggregates and recomputes them as a SUM, so they stay correct when a line is later edited or removed. | | `PostAdjustments` | Post Adjustments | ServerAction (`PostAdjustments`) | Advertised as a supported action on this entity, but the credit-note handler has no dispatch branch for it: invoking it reaches the handler and falls through to a NotSupportedException, and the seeded action row asks for no confirmation, so the user sees a raw error. Do not describe it as posting anything. Credit-note settlement is actually recorded by creating PaymentAdjustment rows (the claim-settlement path nets a note against the partner's open invoices oldest-first) or, on the current open-item engine, SettlementAllocation rows against the note's OpenTransaction. | | `PostGeneralLedger` | Post General Ledger | ServerAction (`PostGeneralLedger`) | Sets IsGLPostingApproved on the note and saves it; the save pipeline is what posts. The handler then posts through DocumentJournalPostingService under the purpose chosen by TransactionType — CreditNote (Dr Sales / Cr AR) for a financial note, Return (revenue and AR reversal) for a sale return, BillReturn (Dr AP / Cr GR-IR plus input-tax reversal, party SupplierAccountId) for a purchase return — creating one balanced journal plus the note's OpenTransaction, and captures GST tax transactions afterwards (outward for sales notes, inward for purchase returns). Posting is append-only: re-posting an already-posted document produces reversal journals rather than editing the ledger. A GST capture failure is swallowed and never blocks the ledger posting. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Customer Account Filter | `AccountId` | | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — looks up via `PurchaseOrderId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — looks up via `DeliveryOrderLineId` - [InterfaceQueue](/docs/reference/entities/interface-queue/) — looks up via `JobInterfaceQueueId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — looks up via `PriceListRuleId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [Claim](/docs/reference/entities/claim/) — looks up via `ClaimId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — looks up via `GoodsReceiptId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — looks up via `DeliveryOrderId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — looks up via `GeneralLedgerId` - [DiscountGroup](/docs/reference/entities/discount-group/) — looks up via `DiscountGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [PaymentAdjustment](/docs/reference/entities/payment-adjustment/) — referenced by via `CreditNoteId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `SourceRecordId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [Payment](/docs/reference/entities/payment/) — referenced by via `CreditNoteId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `CreditNoteId` - [InterestCharge](/docs/reference/entities/interest-charge/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Currency Revaluation Line — entity reference URL: https://xmatix.com/docs/reference/entities/currency-revaluation-line/ Last reviewed: 2026-08-16 One revalued foreign-currency position on a revaluation run, typically a bank balance, a receivable or a payable, identified by its ledger account and, where relevant, the counterparty. It holds the original foreign amount, the base amount already carried on the books, the closing rate applied, the restated base amount, and the difference between the last two. Money amounts round to two decimals while the rate is stored to eight, so the restatement can be reproduced exactly. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BookedBaseAmount` | Booked Base Amount | Currency | | What the position is currently carried at in the base currency, that is the historical figure already sitting in the ledger. It is the baseline the gain or loss is measured against, not a recomputed value. | | `ClosingRate` | Closing Rate | Currency | | The rate resolved for this currency pair on the revaluation date under the run's chosen rate series. It is stored to eight decimal places so the restated amount can be reproduced exactly. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Currency` | Currency | Text | | | | `CurrencyRevaluationId` | Currency Revaluation | Lookup → [CurrencyRevaluation](/docs/reference/entities/currency-revaluation/) | | | | `ForeignAmount` | Foreign Amount | Currency | | The open position stated in its own currency, as it stands before any restatement. | | `GainLoss` | Gain Loss | Currency | | The restated value minus the amount already booked, so positive is a gain and negative a loss. It is unrealized by construction, because the position being measured is still open. | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The ledger account holding the position being restated, typically a foreign-currency bank, receivable or payable account. | | `Id` | Id | Guid | Yes | | | `LineNumber` | Line Number | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyAccountId` | Party Account | Lookup → [Account](/docs/reference/entities/account/) | | The counterparty whose open balance is being restated. It is set for receivable and payable positions and left empty for bank positions, which have no counterparty. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RevaluedBaseAmount` | Revalued Base Amount | Currency | | The foreign amount priced at the closing rate, in other words what the position would be carried at if it were restated as at the revaluation date. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `New` | New | New | New | | `NewInline` | New | NewInline | New | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [CurrencyRevaluation](/docs/reference/entities/currency-revaluation/) — looks up via `CurrencyRevaluationId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Currency Revaluation — entity reference URL: https://xmatix.com/docs/reference/entities/currency-revaluation/ Last reviewed: 2026-08-16 A period-end foreign-exchange revaluation run that restates open foreign-currency positions at the closing rate. Each line computes an unrealized gain or loss as the restated base amount minus the amount originally booked, and the run total is the net unrealized figure to post. Building the run and posting its gain or loss journal are deliberately separate steps, which is why the run carries both a draft or posted status and a journal reference that stays empty until posting happens. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BaseCurrency` | Base Currency | Text | | The reporting currency every position on the run is restated into. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FiscalPeriodId` | Fiscal Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | | | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | The journal that posted this run's net gain or loss. An empty value means the run has been computed but the result has not reached the ledger. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RateType` | Rate Type | Text | | Which published rate series each position is priced from, normally the closing series at period end. Storing it on the run makes the valuation basis auditable rather than something that has to be inferred from the date. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RevaluationDate` | Revaluation Date | DateAndTime | | | | `Status` | Status | Text | | Either Draft or Posted. Runs are built as Draft and the gain or loss journal is a separate step, so a Draft run holds fully computed numbers that are not yet reflected anywhere in the ledger. | | `TotalGainLoss` | Total Gain Loss | Currency | | The net unrealized gain when positive and loss when negative, expressed in the run's base currency and rounded to two decimals. It is the single figure the follow-up journal is expected to post. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `FiscalPeriodId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `FiscalPeriodId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [CurrencyRevaluationLine](/docs/reference/entities/currency-revaluation-line/) — referenced by via `CurrencyRevaluationId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Currency — entity reference URL: https://xmatix.com/docs/reference/entities/currency/ Last reviewed: 2026-08-16 An ISO 4217 currency the tenant transacts in. Name holds the ISO code itself (for example INR or USD) while label, symbol and decimalPlaces drive display and rounding. Exactly one row per company should be flagged isBaseCurrency - the functional/reporting currency - and rows are keyed to their owning company via partnerAccountId. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DecimalPlaces` | Decimal Places | Number | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `IsBaseCurrency` | Is Base Currency | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | Holds the ISO 4217 code itself (for example INR or USD), not a display name - the friendly name lives in the label field. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Symbol` | Symbol | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [AccountingBook](/docs/reference/entities/accounting-book/) — referenced by via `CurrencyId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Cycle Count Line — entity reference URL: https://xmatix.com/docs/reference/entities/cycle-count-line/ Last reviewed: 2026-08-16 One item to count within a cycle count, generated per item lot or per InventoryStock row: OnHandQuantity is the system expectation seeded at generation per the header's CountQuantityType, RecordedQuantity is the physical count, and the calculated variance DiscrepencyQuantity (misspelled in C# and metadata; the JSON and API name is discrepancyQuantity) is RecordedQuantity minus OnHandQuantity. The companion DiscrepencyCostValue multiplies that variance by the line's UnitCost, but generation never populates UnitCost, so the valued variance is zero unless someone types a cost in. RecordedDamagedQuantity and RecordedExpiredQuantity are separate counts that become their own adjustment lines. Lines with a non-zero variance cannot be deleted, and inserting an item already on another started-but-unfinished count for the same partner, branch and storage location is rejected. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ConversionRatio` | Conversion Ratio | Number | | | | `ConversionRatio1` | Conversion Ratio 1 | Number | | | | `CountedByResourceId` | Counted By | Lookup → [Resource](/docs/reference/entities/resource/) | | Intended to name who performed the physical count, but no code path writes it - neither line generation nor the start and finish actions populate it, so it is only ever set by manual entry or an integration. | | `CountedDateTime` | Counted Date Time | DateAndTime | | Intended to timestamp the physical count, but no code path writes it; finishing a count stamps IsApproved on the lines and leaves this untouched, so it is only ever set by manual entry or an integration. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CycleCountId` | Cycle Count | Lookup → [CycleCount](/docs/reference/entities/cycle-count/) | | | | `DiscrepencyCostValue` | Discrepency Cost Value | Calculated (calculated) | | Calculated as the variance quantity times the line's unit cost. Because line generation never populates UnitCost, it evaluates to zero on generated lines unless someone types a cost in, so it should not be read as a valued shrinkage figure by default. | | `DiscrepencyQuantity` | Discrepency Quantity | Calculated (calculated) | | | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `InventoryStockId` | Stock | Lookup → [InventoryStock](/docs/reference/entities/inventory-stock/) | | The stock bucket this line counts. Generation creates one line per item lot for lot-tracked items and one per stock bucket otherwise, and the count's inventory lock is applied to exactly these rows. | | `IsApproved` | Is Approved | Boolean | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | The specific lot being counted on lot-tracked items; locking the count sets the transaction lock on these lots for the duration. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `LineNumber` | LineNumber | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Line Number | Text | Yes | | | `OnHandQuantity` | On Hand Quantity | Number | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordedDamagedQuantity` | Recorded Damaged Quantity | Number | | Damage observed while counting. On adjustment release it becomes its own adjustment line typed Damaged, separate from the net discrepancy line. | | `RecordedExpiredQuantity` | Recorded Expired Quantity | Number | | Expired stock observed while counting; released as a separate adjustment line typed Expired, alongside the net discrepancy line. | | `RecordedQuantity` | Recorded Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `SKUId` | Item SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | Left unset when lines are generated from stock rows or item lots - the generator copies quantities only. It is nevertheless copied onto the adjustment lines that Release For Adjustment creates, so a blank here means the resulting stock adjustment also carries a zero cost. | | `UOM` | UOM | PickList | | Values: Box. | | `UOM1` | UOM1 | PickList | | | | `UOMQuantity` | UOM Quantity | Number | | | | `UOMQuantity1` | UOM Quantity 1 | Number | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `EditInLineEntity` | Edit | EditInline | Edit | | `New` | New | New | New | | `NewInLine` | New | NewInline | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Quantity Recorded Rule Validation | `RecordedQuantity`, Error | Recorded Quantity can't be negative. | Recorded Quantity can't be negative. | | Quantity Rule Validation | Error | Expected Quantity can't be negative. | Expected Quantity can't be negative. | | Unit Price Validation | `UnitCost`, Error, inactive | Unit Cost can't be negative | Unit Cost can't be negative | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Sku For Item | `SKUId` | | ## Related entities - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — looks up via `InventoryStockId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Resource](/docs/reference/entities/resource/) — looks up via `CountedByResourceId` - [CycleCount](/docs/reference/entities/cycle-count/) — looks up via `CycleCountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `CycleCountLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Cycle Count Rule — entity reference URL: https://xmatix.com/docs/reference/entities/cycle-count-rule/ Last reviewed: 2026-08-16 A stored field, operator and value criterion attached to a cycle count and ordered by SequenceNumber. Treat it as a declared-but-unused container rather than an active filter, and do not tell a user that adding rules will change which items are counted. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CycleCountId` | Cycle Count | Lookup → [CycleCount](/docs/reference/entities/cycle-count/) | | | | `FieldName` | Field Name | Text | | | | `FieldValue` | Field Value | Text | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `Operation` | Operation | PickList | | Values: Less Or Equal, Greater Or Equal. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SequenceNumber` | Sequence Number | Number | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [CycleCount](/docs/reference/entities/cycle-count/) — looks up via `CycleCountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Cycle Count — entity reference URL: https://xmatix.com/docs/reference/entities/cycle-count/ Last reviewed: 2026-08-16 A physical stock-count exercise for one branch and partner account, optionally narrowed by Item, ItemGroup, ABC/FSN class or StorageLocation. Lines are auto-generated on insert and regenerated when the filters change, until counting starts: one CycleCountLine per item lot, else per InventoryStock row, capped by MaximumItems (0 falls back to 2000). The count itself posts nothing - it is a data-entry exercise whose only outputs are recorded variances and, optionally, locked stock; stock and value move only through the separate Adjustment that Release For Adjustment creates and someone then posts. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AdjustmentId` | Adjustment | Lookup → [Adjustment](/docs/reference/entities/adjustment/) | | The link between a count and the adjustment it produced is stored the other way round, on Adjustment.CycleCountId, and on the adjustment lines through CycleCountLineId - follow those reverse references instead. | | `AssignedToResourceId` | Assigned To | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | Yes | | | `CountQuantityType` | Count Quantity Type | PickList | Yes | Values: Quantity Available, Quantity In Hand, Actual Quantity. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | | | `DocumentNumber` | DocumentNumber | Number | Yes | | | `DynamicMemberType` | Dynamic Member Type | PickList | | Values: Report Data. | | `ExternalId` | External | Text | | | | `FilterABC` | Filter ABC | PickList | | Restricts generated count lines to items whose ItemInventoryAttribute carries this ABC class; attribute rows scoped to the count's partner/branch or left unscoped both match. Values: A Category, B Category, C Category. | | `FilterFSN` | Filter FSN | PickList | | Restricts line generation to items with this Fast/Slow/Non-moving class on their ItemInventoryAttribute, with the same null-scope wildcard matching as the ABC filter. Values: F category, S category, N category. | | `Id` | Id | Guid | Yes | | | `IsAdjustmentReleased` | Adjustment Released | Boolean | Yes | Set once PerformReleaseAdjustment has generated the Adjustment from the counted discrepancies; the action refuses to run twice. | | `IsCountingFinished` | Counting Finished | Boolean | Yes | Set by PerformFinishCounting, which also approves every count line and releases the inventory transaction lock. Finishing requires counting to have started and blocks a second finish. | | `IsCountingStarted` | Counting Started | Boolean | Yes | Set by PerformStartCounting; from then on the item/filter fields are locked and the action refuses to run again. Starting also applies the transaction lock to counted stock and lots when inventory locking is on. | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `LockInventory` | Lock Inventory | Boolean | | | | `MaximumItems` | Maximum Items | Number | | Caps how many items line generation pulls (2000 when left at zero). Editing it or any filter before counting starts deletes and regenerates the lines; once counting has started these fields are locked. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartCostFrom` | Part Cost From (Future Use) | Currency | | | | `PartCostTo` | Part Cost To (Future Use) | Currency | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | Yes | | | `PartStockFrom` | Part Stock From (Future Use) | Number | | | | `PartStockTo` | Part Stock To (Future Use) | Number | | | | `PerformFinishCounting` | Perform Finish Counting | Boolean | Yes | A trigger flag rather than stored state: running the Finish Counting server action clears it back to false as part of executing. Read IsCountingFinished to know whether counting has been completed. | | `PerformReleaseAdjustment` | Perform Release Adjustment | Boolean | Yes | A trigger flag naming the release server action, but unlike the start and finish flags it is never cleared by the release path. Whether an adjustment was actually produced is recorded by IsAdjustmentReleased, which is set only when at least one adjustment line was created. | | `PerformStartCounting` | Perform Start Counting | Boolean | Yes | A trigger flag rather than stored state: running the Start Counting server action clears it back to false as part of executing, so a saved record always shows false. Read IsCountingStarted to know whether counting has begun. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReportId` | Report (Future Use) | Text | | | | `ResourceId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `RuleSuccessCriteria` | Rule Success Criteria (Future Use) | PickList | | Values: All Rules Are Met. | | `RuleSuccessCustomLogic` | Rule Success Custom Logic (Future Use) | Text | | | | `Status` | Status | PickList | | Values: Draft, Counting in Progress, Finish Counting, Released for Adjustment. | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | Scopes line generation to lots and stock buckets sitting in this location, so a count can target one zone or van rather than the whole branch. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `DeleteInLists` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `EditInLines` | Edit | EditInline | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `New` | New | New | New | | `PerformFinishCounting` | Finish Counting | ServerAction (`PerformFinishCounting`) | It is used for finish counting for the inventory. | | `PerformReleaseAdjustment` | Release For Adjustment | ServerAction (`PerformReleaseAdjustment`) | This is used to release adjustment for the particular cycle count. | | `PerformStartCounting` | Start Counting | ServerAction (`PerformStartCounting`) | It is used to start counting of physical inventory. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Only Part Acc | `PartnerAccountId` | | | Partner acc | `BranchId` | PartnerAccountId = __target.PartnerAccountId | ## Related entities - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Adjustment](/docs/reference/entities/adjustment/) — looks up via `AdjustmentId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [Resource](/docs/reference/entities/resource/) — looks up via `AssignedToResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Adjustment](/docs/reference/entities/adjustment/) — referenced by via `CycleCountId` - [CycleCountLine](/docs/reference/entities/cycle-count-line/) — referenced by via `CycleCountId` - [CycleCountRule](/docs/reference/entities/cycle-count-rule/) — referenced by via `CycleCountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Dealer Onboarding — entity reference URL: https://xmatix.com/docs/reference/entities/dealer-onboarding/ Last reviewed: 2026-08-16 A dealership application record capturing everything an applicant is assessed on in one wide document: applicant identity and residence, firm constitution and PAN/GST, showroom and workshop area and ownership, banking references, financial capability, and the letter of intent dates. It optionally links back to the Opportunity it came from and carries the DealerCode once one is issued; both of those become non-editable after creation. Progress is tracked by several independent approval picklists rather than one lifecycle field - a regional sales approval, a channel head approval, and two legal approvals - each moving between pending, approved and rejected on its own, with LegalHoldReason and OnboardingRejectionReason for the negative outcomes. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AadharNumber` | Aadhar Number | Number | | | | `ACNumber` | A/C Number | Text | | | | `ApplicantContactNumber` | Applicant Contact Number | Text | | | | `ApplicantPermanentAddress` | Applicant Permanent Address | Text | | | | `ApplicantPincode` | Applicant Pincode | Number | | | | `ApplicantResidenceAddress` | Applicant Resence Address | Text | | | | `ApplicantResidenceState` | Applicant Resence State | PickList | | Values: None, Delhi, Andhra Pradesh, Arunachal Pradesh, Assam, Bihar, Chhattisgarh, Goa, Gujarat, Haryana, Himachal Pradesh, Jharkhand, Karnataka, Kerala, Madhya Pradesh, Maharashtra, Manipur, Meghalaya, Mizoram, Nagaland, Odisha, Punjab, Rajasthan, Sikkim, Tamil Nadu, Telangana, Tripura, Uttar Pradesh, Uttarakhand, West Bengal, Andaman and Nicobar Islands, Chandigarh, Dadra and Nagar Haveli and Daman and Diu, Lakshadweep, Puducherry, Ladakh, Charlotte, Ohio. | | `ApplicantResidenceType` | Applicant Resence Type | PickList | | Values: Owned, Rented. | | `ApplicantWorkspaceAddress` | Applicant Workspace Address | Text | | | | `ApprovalByLegalTeam` | Approval By Legal Team | PickList | | The legal team's verdict on the application. Note that a second, separately seeded field (ApprovalStatusByLegal) records what appears to be the same decision with a slightly different option list, so a tenant must decide which one it treats as authoritative. Values: Approval Pending, Approved, Rejected. | | `ApprovalByRSM` | Approval By RSM | PickList | | The regional sales manager's verdict on the application - pending, approved or rejected. One of several independent approval fields; nothing aggregates them into an overall decision and no server action sets them. Values: Approval Pending, Approved, Rejected. | | `ApprovalStatusByLegal` | Approval Status By Legal | PickList | | A second legal-approval picklist alongside ApprovalByLegalTeam, differing only in the wording of its pending option. Nothing keeps the two in step, so read both before concluding what legal decided. Values: Pending Approval, Approved, Rejected. | | `AreaLocalitySector` | Area / Locality / Sector | Text | | | | `BankerAddress` | Banker Address | Text | | | | `BankerName` | Banker Name | Text | | | | `Category` | Category | PickList | | Values: E-Bike. | | `ChannelHeadApproval` | Channel Head Approval | PickList | | The channel head's verdict, recorded independently of the regional sales and legal approvals. No code enforces an order between the approvals or blocks the record while one is pending. Values: Pending Approval, Approved, Rejected. | | `City` | City | Text | | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrentBusinessOfTheFirm` | Current Business Of The Firm | Text | | | | `DateOfBirth` | Date Of Birth | Date | | | | `DateOfEstablishment` | Date Of Establishment | Date | | | | `DealerCode` | Dealer Code | Text | | The dealer code issued for the applicant. It is frozen after the record is created - the save pipeline rejects any change to it - so it must be right first time or the record replaced. | | `DealerLeadStatus` | Dealer Lead Status | PickList | | How far the applicant has progressed as a lead. This is the one picklist on the entity that is validated server-side: a value outside the allowed set is rejected on save with a validation error. It tracks pursuit of the applicant and is independent of the approval fields. Values: Open - Not Contacted, Working - Contacted, Nurturing, Closed - Lost, Closed - Won. | | `DealerLocationLatitude` | Dealer Location Latitude | Number | | | | `DealerLocationLongitude` | Dealer Location Longitude | Number | | | | `DealershipLocation` | Dealership Location | PickList | | Values: Main Market, City Outskirts, Any Other. | | `DealershipLocationAddress` | Dealership Location Address | Text | | | | `District` | District | Text | | | | `EmailId` | Email | Text | | | | `FinancialCapability` | Financial Capability | PickList | | Values: Inventory Funding, Cash Credit Limit, Term Loan, Others. | | `FirmAddress` | Firm Address | Text | | | | `FirmBankerName` | Firm Banker Name | Text | | | | `FirmPANNumber` | Firm PAN Number | Text | | | | `FirmType` | Firm Type | PickList | | Values: Partnership, Private Limited, Proprietorship, Public Limited, HFCs, Others. | | `FlatDoorBuilding` | Flat / Door / Building | Text | | | | `FrontageOfShowroom` | Frontage Of Showroom | PickList | | Values: <20, 20-30, >30. | | `Gender` | Gender | PickList | | Values: Male, Female, Others. | | `GSTNumber` | GST Number | Text | | | | `Id` | Id | Guid | Yes | | | `IsDealer` | Is Dealer | Text | | A text field, not a boolean, despite the name - it is stored as a string and no code interprets it, so whatever convention a tenant adopts for it is theirs alone. | | `LegalHoldReason` | Legal Hold Reason | PickList | | Why legal has parked the application - typically showroom frontage, improper documents, layouts, or missing showroom and workshop photographs. Recording it does not itself block anything; it is a note against the legal approval. Values: Frontage Of The Showroom, Improper Document, Layouts, Showroom & Workshop Photographs. | | `LOIExpiryDate` | LOI Expiry Date | Date | | | | `LOIExpiryDays` | LOI Expiry Days | Number | | Days remaining until the letter of intent expires, recomputed on every insert and update as the expiry date minus today. It is a snapshot taken at save time, not a live countdown - it goes stale as soon as the record stops being edited, and goes negative once the LOI has expired. | | `LOIIssueDate` | LOI Issue Date | Date | | When the letter of intent was issued to the applicant. The save pipeline rejects an expiry date earlier than this, which is the only cross-field rule on the entity besides the lead-status check. | | `MinimumShowroomAreaSqFt` | Minimum Showroom Area (Sq Ft) | PickList | | Values: <600, 600-800, 800-1000, >100. | | `MinimumWorkshopAreaSqFt` | Minimum Workshop Area (Sq Ft) | PickList | | Values: <200, 200-300, 300-400, >400. | | `MobileNumber` | Mobile Number | Text | | | | `MSMEUdyogAadharNo` | MSME Udyog Aadhar No | Text | | | | `Name` | Dealer Onboarding No | Text, unique | Yes | The application's document number, auto-numbered centrally from the tenant's document-name settings rather than typed - it is not the applicant's or the firm's name, which are held in NameOfMainProprietor and NameOfTheFirm. | | `NameInBankAccount` | Name In Bank Account | Text | | | | `NameOfMainProprietor` | Name Of Main Proprietor | Text | | | | `NameOfTheFirm` | Name Of The Firm | Text | | | | `OfficeEmailId` | Office Email | Text | | | | `OnboardingRejectionReason` | Onboarding Rejection Reason | PickList | | Why the application was turned down - documentation, funding, unmet criteria or infrastructure. Purely descriptive: setting it does not change any approval field or close the record. Values: Improper Documentation, Lack Of Funds, Criteria Not Fulfilled, Poor Infrastructure. | | `OpportunityId` | Opportunity | Lookup → [Opportunity](/docs/reference/entities/opportunity/) | | The Opportunity this application originated from, and the field the platform looks an application up by when working back from the pipeline. Like the dealer code it cannot be changed after creation. | | `PANNumber` | PAN Number | Text | | | | `PartnerName` | Partner Name | Text | | | | `PersonalQualificationOfApplicant` | Personal Qualification Of Applicant | PickList | | Values: Below 12th Pass, 12th Pass, Graduate, Post-Graduate, Any Automobile Degree. | | `PinCode` | Pin Code | Number | | | | `PropertyAvailable` | Property Available | PickList | | Values: Lease, Rented, Owned. | | `RelationshipWithMainPromoter` | Relationship With Main Promoter | Text | | | | `Remarks` | Remarks | Text | | | | `ResidenceStatus` | Resence Status | PickList | | Values: Owned, Rented. | | `RoadStreet` | Road / Street | Text | | | | `ShowroomOwnershipStatus` | Showroom Ownership Status | PickList | | Values: Owned, Rented. | | `SignatoryDesignation` | Signatory Designation | Text | | | | `SignatoryName` | Signatory Name | Text | | | | `SiteOwnership` | Site Ownership | PickList | | Values: Owned, Rented. | | `StandaloneFacility` | Standalone Facility | PickList | | Values: Yes, No. | | `State` | State | PickList | | Values: None, Delhi, Andhra Pradesh, Arunachal Pradesh, Assam, Bihar, Chhattisgarh, Goa, Gujarat, Haryana, Himachal Pradesh, Jharkhand, Karnataka, Kerala, Madhya Pradesh, Maharashtra, Manipur, Meghalaya, Mizoram, Nagaland, Odisha, Punjab, Rajasthan, Sikkim, Tamil Nadu, Telangana, Tripura, Uttar Pradesh, Uttarakhand, West Bengal, Andaman and Nicobar Islands, Chandigarh, Dadra and Nagar Haveli and Daman and Diu, Lakshadweep, Puducherry, Ladakh, Charlotte, Ohio. | | `TelephoneNumber` | Telephone Number | Text | | | | `TotalDealershipAmount` | Total Dealership Amount | Decimal | | | | `TotalShowroomAreaSqFt` | Total Showroom Area (Sq Ft) | Number | | | | `TotalWorkshopAreaSqFt` | Total Workshop Area (Sq Ft) | Number | | | | `TurnoverOfCurrentBusiness` | Turnover Of Current Business | PickList | | Values: <25, 25-50, 50-75, >75. | | `Type` | Type | PickList | | Values: Partnership, Proprietorship, LLP, Private Ltd., HUF. | | `TypeOfPropertyDealer` | Type Of Property Dealer | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `WorkshopOwnershipStatus` | Workshop Ownership Status | PickList | | Values: Owned, Rented. | | `WorkshopPinCode` | Workshop Pin Code | Number | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `New` | New | New | New | ## Related entities - [Opportunity](/docs/reference/entities/opportunity/) — looks up via `DealerOnboardingId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `DealerOnboardingId` - [KYCDocument](/docs/reference/entities/kycdocument/) — looks up via `DealerOnboardingId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `DealerOnboardingId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # DebitNoteLine — entity reference URL: https://xmatix.com/docs/reference/entities/debit-note-line/ Last reviewed: 2026-08-16 One charge line of a DebitNote, tying the note to the Bill line (BillLineId) or the supply it adjusts and carrying the amount the ledger posts. On a sale-direction debit note the line is also the tax document: the GST breakdown (taxable value, rate, HSN/SAC and per-component tax slots) lives on the line because the printed note must show it and GSTR-1 needs an HSN summary rather than a header total. Those GST columns exist on the domain type but are not all seeded as metadata fields in the first-party package. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | The line's value, and the column the sale-direction (customer) posting purpose reads for its income leg; it also rolls up into the parent's calculated Amount. | | `BillId` | Bill | Lookup → [Bill](/docs/reference/entities/bill/) | | | | `BillLineId` | Bill Line | Lookup → [BillLine](/docs/reference/entities/bill-line/) | | The supplier bill line this debit-note line adjusts, tying the charge back to the specific billed item on a purchase debit note. | | `BranchId` | Branch | Lookup | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DebitNoteId` | Debit Note | Lookup → [DebitNote](/docs/reference/entities/debit-note/) | Yes | | | `Description` | Description | MultiLineText | | | | `DocumentNumber` | Document Number | Number | Yes | | | `ExternalId` | External | Text | | | | `GeneralLedgerId` | General Ledger | Lookup → [GeneralLedger](/docs/reference/entities/general-ledger/) | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | An explicit GL account for this line's leg, which wins over the account resolved by type — this is how an interest charge lands in an interest-income account rather than in sales. | | `GLAmount` | GL Amount | Calculated (calculated) | | The line amount used by the default purchase-direction posting purpose. Sale-direction debit notes post their line legs from Amount instead, so the two columns are not interchangeable. | | `HsnSacCode` | HSN/SAC Code | Text | | Inherited from the invoice line this share relates to. GSTR-1 Table 12 (HSN summary) needs it. | | `Id` | Id | Guid | Yes | | | `IsGLPosted` | Is GL Posted | Boolean | Yes | A legacy per-line posting marker; the journal ledger does not maintain it. Posting state belongs to the note, evidenced by the Journal that names the note as its source. | | `IsGLPostingApproved` | Is GL Posting Approved | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Calculated | | | | `RecordId` | Record | Lookup | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Tax1` | Tax 1 Amount | Currency | | Component 1 amount. Resolved to a GL account via Tax1Type. | | `Tax1Name` | Tax 1 Name | Text | | Display name of component 1. | | `Tax1Rate` | Tax 1 Rate | Percent | | Rate applied for component 1. | | `Tax1Type` | Tax 1 Type | Text | | CGST / SGST / IGST / Cess. The posting engine resolves the tax GL account by this value. | | `Tax2` | Tax 2 Amount | Currency | | Component 2 amount. Resolved to a GL account via Tax2Type. | | `Tax2Name` | Tax 2 Name | Text | | Display name of component 2. | | `Tax2Rate` | Tax 2 Rate | Percent | | Rate applied for component 2. | | `Tax2Type` | Tax 2 Type | Text | | CGST / SGST / IGST / Cess. The posting engine resolves the tax GL account by this value. | | `Tax3` | Tax 3 Amount | Currency | | Component 3 amount. Resolved to a GL account via Tax3Type. | | `Tax3Name` | Tax 3 Name | Text | | Display name of component 3. | | `Tax3Rate` | Tax 3 Rate | Percent | | Rate applied for component 3. | | `Tax3Type` | Tax 3 Type | Text | | CGST / SGST / IGST / Cess. The posting engine resolves the tax GL account by this value. | | `Tax4` | Tax 4 Amount | Currency | | Component 4 amount. Resolved to a GL account via Tax4Type. | | `Tax4Name` | Tax 4 Name | Text | | Display name of component 4. | | `Tax4Rate` | Tax 4 Rate | Percent | | Rate applied for component 4. | | `Tax4Type` | Tax 4 Type | Text | | CGST / SGST / IGST / Cess. The posting engine resolves the tax GL account by this value. | | `Tax5` | Tax 5 Amount | Currency | | Component 5 amount. Resolved to a GL account via Tax5Type. | | `Tax5Name` | Tax 5 Name | Text | | Display name of component 5. | | `Tax5Rate` | Tax 5 Rate | Percent | | Rate applied for component 5. | | `Tax5Type` | Tax 5 Type | Text | | CGST / SGST / IGST / Cess. The posting engine resolves the tax GL account by this value. | | `Tax6` | Tax 6 Amount | Currency | | Component 6 amount. Resolved to a GL account via Tax6Type. | | `Tax6Name` | Tax 6 Name | Text | | Display name of component 6. | | `Tax6Rate` | Tax 6 Rate | Percent | | Rate applied for component 6. | | `Tax6Type` | Tax 6 Type | Text | | CGST / SGST / IGST / Cess. The posting engine resolves the tax GL account by this value. | | `TaxableValue` | Taxable Value | Currency | | Value the tax on this line is computed on. | | `TaxAmount` | Tax Amount | Currency | | Total tax on this line — the sum of its component slots. | | `TaxRate` | Tax Rate | Percent | | Combined rate across the components on this line, for display. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Selected Name | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `NewInLine` | New | NewInline | New | ## Related entities - [Bill](/docs/reference/entities/bill/) — looks up via `BillId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [GeneralLedger](/docs/reference/entities/general-ledger/) — looks up via `GeneralLedgerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [BillLine](/docs/reference/entities/bill-line/) — looks up via `BillLineId` - [DebitNote](/docs/reference/entities/debit-note/) — looks up via `DebitNoteId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Debit Note — entity reference URL: https://xmatix.com/docs/reference/entities/debit-note/ Last reviewed: 2026-08-16 A debit document with two directions selected by TransactionType. The default (and null, which every pre-discriminator row carries) is a purchase debit note raised on a SUPPLIER against a Bill: Dr Accounts Payable / Cr expense, reducing what we owe. TransactionType "SaleDebitNote" is the mirror, raised on a CUSTOMER against an Invoice: Dr AR / Cr income, increasing what they owe — this is how interest on overdue receivables is charged, and a sale debit note inherits its rate, HSN/SAC, place of supply and party GSTIN from the invoice it charges. Readers must use DebitNoteTransactionType.IsSaleDebitNote rather than comparing the string, or the null-valued purchase notes flip direction. Children are DebitNoteLine; settlement is recorded as PaymentAdjustment or SettlementAllocation rows. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The party the note is raised on, and the party the ledger posts against. Its meaning flips with the note's direction: on the default purchase debit note it is the SUPPLIER whose payable is reduced (and is validated to be a supplier account on insert and update); on a sale-direction note it is the CUSTOMER whose receivable is increased. | | `AdjustedAmount` | Adjusted Amount | Currency | | How much of the note has been consumed settling other documents, maintained by the settlement code rather than by the user; OpenAmount is kept as Amount minus this value. | | `Amount` | Amount | Calculated (calculated) | | Calculated field: the sum of DebitNoteLine.Amount. It is the note's face value and the base of OpenAmount (Amount minus AdjustedAmount), not a user-entered figure. | | `BillId` | Bill | Lookup → [Bill](/docs/reference/entities/bill/) | | The supplier bill this note debits — the source document of a purchase debit note. Its sale-direction counterpart is the customer invoice the note charges, which exists on the domain type but is not seeded as a metadata field here. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Currency` | Currency | PickList | | | | `DocumentDate` | Document Date | Date | Yes | | | `ExternalId` | External | Text, unique | | | | `GeneralLedgerId` | General Ledger | Lookup → [GeneralLedger](/docs/reference/entities/general-ledger/) | | Legacy pointer to the decommissioned GeneralLedger entity, retained and guarded as a system field. The journal ledger links the other way, through Journal.SourceEntityName + SourceRecordId. | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | An explicit header (control) GL account for the note. The sale-direction posting purpose opts into reading it, so an interest or other charge posts into the same subledger account as the invoice it relates to instead of an account resolved by type — which matters when a company has more than one receivable account. | | `GLAmount` | GL Amount | Calculated (calculated) | | Calculated as a copy of Amount; the header-side amount the posting purposes use when the note has no lines to post. Sale-direction notes read DebitNoteLine.Amount for their line legs rather than the line GLAmount. | | `GSTRegistrationId` | GST Registration | Lookup → [GSTRegistration](/docs/reference/entities/gstregistration/) | | Own GST registration the note is raised under. | | `Id` | Record | Guid | Yes | | | `InvoiceId` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | The invoice this note increases the value of. Set on sale debit notes; the GST rate and place of supply are inherited from it. | | `IsGLPosted` | Is GL Posted | Boolean | Yes | A legacy posting marker guarded as a system field. No first-party code sets it on a debit note under the journal-based ledger, so it stays false even on posted notes — test posting by looking for a Journal whose SourceEntityName is "DebitNote" and SourceRecordId is this row, or for the note's OpenTransaction. | | `IsGLPostingApproved` | Is GL Posting Approved | Boolean | Yes | The flag that triggers ledger posting: when it is true as the note is saved, the handler posts it through DocumentJournalPostingService — under the DebitNote purpose (Dr AP / Cr expense) for a purchase note, or the SaleDebitNote purpose (Dr AR / Cr income) for a customer note — and captures outward GST for the latter. The PostGeneralLedger action only sets this flag and saves. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Notes` | Notes | LongMultiLineText | | | | `OpenAmount` | Open Amount | Calculated | | The unconsumed balance of the note — a STORED column recomputed as Amount minus AdjustedAmount when a settlement is applied, not a live formula. For an authoritative party balance prefer the note's OpenTransaction row. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PerformGLPosting` | Perform GL Posting | Boolean | | | | `Reason` | Reason | LongMultiLineText | | Why the note was raised — for interest charges, the accrual window it covers. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `TransactionType` | Transaction Type | Text | | PurchaseDebitNote (reduces a payable) or SaleDebitNote (increases a receivable). NULL means purchase — every note raised before this field existed is a purchase note. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete Selected | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteHeader` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `EditInLine1` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit, inactive | EditListRow | | `New` | New | New | New | | `PostAdjustments` | Post Adjustments | ServerAction (`PostAdjustments`) | Debit-note settlement is recorded as PaymentAdjustment rows or, on the current open-item engine, SettlementAllocation rows against the note's OpenTransaction. | | `PostGeneralLedger` | Post General Ledger | ServerAction (`PostGeneralLedger`) | Sets IsGLPostingApproved on the note and saves it; the save pipeline posts. The purpose follows the note's direction: a purchase debit note posts under DebitNote (Dr Accounts Payable / Cr expense, reducing the payable), while a sale-direction note posts under SaleDebitNote (Dr AR / Cr income, increasing the receivable) and then has its outward GST captured so the tax reaches GSTR-1. Line legs read DebitNoteLine.Amount on the sale-direction purpose; a line naming its own GLAccountId overrides account resolution by type. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Supplier Account Filter | `AccountId` | | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — looks up via `GeneralLedgerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Bill](/docs/reference/entities/bill/) — looks up via `BillId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `SourceRecordId` - [InterestCharge](/docs/reference/entities/interest-charge/) — referenced by via `SourceRecordId` - [Payment](/docs/reference/entities/payment/) — referenced by via `DebitNoteId` - [PaymentAdjustment](/docs/reference/entities/payment-adjustment/) — referenced by via `DebitNoteId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [DebitNoteLine](/docs/reference/entities/debit-note-line/) — referenced by via `DebitNoteId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Delivery Order Line — entity reference URL: https://xmatix.com/docs/reference/entities/delivery-order-line/ Last reviewed: 2026-08-16 One item line of a delivery order, and the row that actually moves stock: when the parent's PerformInventoryPosting runs, four mutually exclusive seeded ledger rules discriminate on InventoryFulfilmentPickingLineId, InventoryFulfilmentAllocationLineId and InvoiceLineId to post an Outward movement and relieve the matching reservation bucket (Picked, Allocation or PendingDeliveries). DeliveredInvoiceQuantity and ReturnedQuantity are genuine roll-ups from InvoiceLine and CreditNoteLine rows keyed on DeliveryOrderLineId, which is what makes PendingInvoiceQuantity and EligibleReturnQuantity trustworthy; ShippedQuantity is not maintained by any code path. Lot and serial identity travel on ItemLotId with ItemLotTypeId, and posting fails outright when the item tracks lots but no lot was chosen. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AllocatedQuantity` | Allocated Quantity | Decimal | | | | `Amount` | Amount | Calculated (calculated) | | The net line value: BaseAmount when discounts are applied post-tax, otherwise BaseAmount less NetSchemeDiscount and NetDiscount. The document's TotalLineAmount is the sum of this field. | | `ApplyPostTaxDiscount` | Apply Post Tax Discount | Boolean | | Switches the whole discount calculation from pre-tax to post-tax: when true every discount percentage is applied to BaseAmount plus tax rather than BaseAmount alone, and Amount stops deducting discounts (they are taken out at GrossAmount instead). It changes the meaning of Amount, NetDiscount and GrossAmount together. | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | A link to a serialised Asset record for the unit being delivered. | | `BaseAmount` | Base Amount | Calculated (calculated) | | Calculated as Quantity multiplied by UnitPrice2 when that is above zero, otherwise by UnitPrice. It is the pre-discount, pre-tax line value that every discount formula is applied to. | | `BillReturnLineId` | Bill Return Line | Lookup → BillReturnLine | | | | `ContractDiscount` | Contract Discount | Percent | | | | `ContractDiscountAmount` | Contract Discount Amount | Currency | | | | `ConversionRatio` | Conversion Ratio | Decimal | | The multiplier from the line's unit of measure to the item's base unit, stamped from the item's unit-of-measure configuration when the quantity is derived. | | `ConversionRatio1` | Conversion Ratio 1 | Decimal | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeliveredInvoiceQuantity` | Delivered Invoice Quantity | Decimal | | A live roll-up: the sum of InvoiceLine.Quantity over the invoice lines keyed to this delivery line, refreshed whenever those invoice lines are added, edited or deleted. PendingInvoiceQuantity is Quantity minus this value, and PerformCreateInvoice gates on it. | | `DeliveredQuantity` | Delivered Quantity | Decimal | | | | `DeliveryOrderDiscount` | Delivery Order Discount | Calculated (calculated) | | | | `DeliveryOrderId` | Delivery Order | Lookup → [DeliveryOrder](/docs/reference/entities/delivery-order/) | | | | `Discount` | Discount | Percent | | | | `Discount2` | Cash Discount | Percent | | | | `DiscountAmount` | Discount Amount | Currency | | | | `DiscountAmount2` | Cash Discount Amount | Currency | | | | `EligibleReturnQuantity` | Eligible Return Quantity | Calculated (calculated) | | Calculated as Quantity minus ReturnedQuantity: how much of this delivered line can still be credited back. It is validated never to go negative, so an over-return is rejected at save time. | | `ExternalId` | External | Text | | | | `GrossAmount` | Gross Amount | Calculated (calculated) | | Amount plus TaxAmount, less scheme and net discounts when the line is flagged post-tax discount. It is the figure the document's TotalLineGrossAmount rolls up, which is what PerformGLPosting books. | | `Id` | Id | Guid | Yes | | | `InventoryFulfilmentAllocationLineId` | Inventory Fulfillment Allocation Line | Lookup → [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) | | Set when the delivery line was generated from a fulfilment allocation line (allocation-delivery path); the picking path sets inventoryFulfilmentPickingLineId instead. Which one is filled tells you how the goods were staged. | | `InventoryFulfilmentPickingLineId` | Inventory Fulfillment Picking Line | Lookup → [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) | | Set when the delivery line was generated from a fulfilment picking line. It is the discriminator for the ledger rule that posts Outward and decrements the Picked bucket, as opposed to the allocation path, which decrements Allocation instead. | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | The posted marker for this line: PerformInventoryPosting only picks up lines where it is empty, and stamps the created ledger row's id here afterwards. It is set by the engine as a system-modified field, so it is not user-editable. | | `InvoicedQuantity` | Invoiced Quantity | Decimal | | A provenance copy taken at creation from the source invoice or order line, capped at that line's quantity. It is the quantity the invoice-sourced Outward ledger rule posts against the PendingDeliveries bucket, and it is not the same thing as DeliveredInvoiceQuantity, which is the live roll-up. | | `InvoiceLineId` | Sale Invoice Line | Lookup → [InvoiceLine](/docs/reference/entities/invoice-line/) | | Set when the line was generated from an invoice line (invoice-first delivery). It selects the ledger rule that decrements the PendingDeliveries bucket using InvoicedQuantity rather than posting a plain Outward movement, so its presence changes what dispatching does to stock. | | `IsGLPostingApproved` | GL Posting Approved | Boolean | | | | `IsILPosted` | IL Posted | Boolean | | A per-line inventory-posted flag that no code writes; InventoryLedgerId is the marker the posting action actually filters and stamps. Do not use this flag to decide whether a line has moved stock. | | `IsILPostingApproved` | IL Posting Approved | Boolean | | A per-line approval gate for inventory posting that the posting path never consults - the line is posted purely on InventoryLedgerId being empty. Setting it grants no authorisation on its own. | | `IsInspectionDone` | Inspection Done | Boolean | | Intended to record that the pre-delivery inspection was completed, but no code path sets it. Actual inspection evidence lives in the checklist lines that Populate Checklist creates, not here. | | `IsInspectionRequired` | Inspection Required | Boolean | | | | `IsInsuranceDone` | Insurance Done | Boolean, unique | | | | `IsRegistrationDone` | Registration Done | Boolean | | | | `IsRegistrationRequired` | Registration Required | Boolean | | | | `ItemAliasId` | Item Alias | Lookup → [ItemAlias](/docs/reference/entities/item-alias/) | | The customer- or supplier-specific alias for the item, resolved on insert by the item alias service. It lets the printed delivery note show the counterparty's own product code while ItemId stays the internal item. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | The specific lot or serialised unit being dispatched; the lot record is where serial and registration numbers live. Inventory posting fails with 'Product Lot was not selected for the transaction' when the item tracks lots and this is empty, and posting also updates the lot's own bucket counters, not just branch stock. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | The lot classification (for example new, demo or refurbished) copied from the source line. It is carried onto the inventory ledger row so stock can be analysed by lot type, but it does not itself select a lot. | | `ItemName` | Item Name | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `NetDiscount` | Net Discount | Calculated (calculated) | | The single blended discount figure for the line: it sums three independent legs (line discount, second discount and contract discount), each of which takes its explicit amount field when one is set and otherwise applies its percentage to BaseAmount, or to BaseAmount plus tax under post-tax discounting. | | `NetSchemeDiscount` | Net Scheme Discount | Calculated (calculated) | | The scheme (promotion) leg of the discount, computed the same way as NetDiscount but from SchemeDiscountAmount or the SchemeDiscount percentage. It is kept separate from NetDiscount so promotional give-away can be reported apart from commercial discount. | | `OrderLineId` | Sale Order Line | Lookup → [OrderLine](/docs/reference/entities/order-line/) | | The sales order line being delivered. It is the key the order-side roll-up uses to decrement the order line's pending delivery quantity when this line is created, edited or deleted, and it is also the anchor for the source-populated field lock on item, lot and SKU. | | `OriginalItemId` | Original Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | PartnerAccount | Text | | | | `PendingInvoiceQuantity` | Pending Invoice Quantity | Calculated (calculated) | | | | `PendingShippedQuantity` | Pending Shipped Quantity | Calculated (calculated) | | Calculated as Quantity minus ShippedQuantity. | | `PickedQuantity` | Picked Quantity | Decimal | | Its counterpart on allocation-sourced lines is AllocatedQuantity; neither is a live measure of picking progress. | | `PolicyNumber` | Policy Number | Text | | | | `PriceAsOnDate` | Price As On Date | Date | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `PriceListRuleId` | Price List Rule | Lookup → [PriceListRule](/docs/reference/entities/price-list-rule/) | | | | `PurchaseOrderLineId` | Purchase Order Line | Lookup → [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) | | | | `Quantity` | Quantity | Decimal | | The delivered amount for this line, and the single quantity that matters: every creation path sets it, the Outward ledger rules read it, and it feeds the roll-ups back onto the order line, allocation line and picking line. Editing it re-posts the line's inventory movement. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RegistrationNumber` | Registration Number | Text | | The registration number of the delivered unit, for vehicle-style goods. No code writes it on the delivery line - the equivalent value that the system actually maintains is on the ItemLot record, which is copied lot to lot on transfers. | | `RequestedQuantity` | Requested Quantity | Number | | A virtual, non-stored field used only as an argument: the selective release-shipment and selective delivery flows pass a per-line requested quantity through it, validated against the line's quantity. It is never persisted and is meaningless when read back from a saved row. | | `ReturnedQuantity` | Returned Quantity | Decimal | | A live roll-up of CreditNoteLine.Quantity over the credit note lines keyed to this delivery line, maintained on credit note line insert, update and delete. EligibleReturnQuantity is Quantity minus this value. | | `SchemeDiscount` | Scheme Discount | Percent | | | | `SchemeDiscountAmount` | Scheme Discount Amount | Currency | | | | `SchemeLineId` | Scheme Line | Lookup → [SchemeLine](/docs/reference/entities/scheme-line/) | | | | `SchemeRewardPoints` | Scheme Reward Points | LargeNumber | | Reward points the scheme engine attached to this line when a points-based benefit applied. The scheme ledger reads it to post the points, so it is engine-written rather than user-entered. | | `ServiceOrderLineId` | Work Orde Line | Lookup → [ServiceOrderLine](/docs/reference/entities/service-order-line/) | | | | `ShippedQuantity` | Shipped Quantity | Decimal | | Intended as the cumulative quantity placed on Shipments, but nothing maintains it: the roll-up that would sum shipment lines by DeliveryOrderLineId is defined and never called, and shipment lines created from a delivery are not stamped with DeliveryOrderLineId in the first place. It therefore stays at zero, which also makes the calculated PendingShippedQuantity always equal Quantity. | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | The bin or storage location the goods leave from, copied from the source invoice, allocation or picking line. It is part of the key that identifies which InventoryStock row the Outward movement relieves, so a different location means a different stock bucket. | | `Tax1` | Tax1 | Currency | | | | `Tax1Name` | Tax Name 1 | Text | | | | `Tax1Rate` | Tax Rate 1 | Currency | | | | `Tax1Type` | Tax Type 1 | Text | | | | `Tax2` | Tax2 | Currency | | | | `Tax2Name` | Tax Name 2 | Text | | | | `Tax2Rate` | Tax Rate 2 | Currency | | | | `Tax2Type` | Tax Type 2 | Text | | | | `Tax3` | Tax3 | Currency | | | | `Tax3Name` | Tax Name 3 | Text | | | | `Tax3Rate` | Tax Rate 3 | Currency | | | | `Tax3Type` | Tax Type 3 | Text | | | | `Tax4` | Tax4 | Currency | | | | `Tax4Name` | Tax Name 4 | Text | | | | `Tax4Rate` | Tax Rate 4 | Currency | | | | `Tax4Type` | Tax Type 4 | Text | | | | `Tax5` | Tax5 | Currency | | | | `Tax5Name` | Tax Name 5 | Text | | | | `Tax5Rate` | Tax Rate 5 | Currency | | | | `Tax5Type` | Tax Type 5 | Text | | | | `Tax6` | Tax6 | Currency | | | | `Tax6Name` | Tax Name 6 | Text | | | | `Tax6Rate` | Tax Rate 6 | Currency | | | | `Tax6Type` | Tax Type 6 | Text | | | | `TaxAmount` | Tax Amount | Currency | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | The cost per unit carried through from the source allocation line when the delivery raises an invoice. Inventory posting reads UnitPrice first and falls back to this value for the ledger row's unit cost. | | `UnitPrice` | Unit Price | Decimal | | The selling price per base unit, defaulted from the applicable price-list rule on insert and refreshed when PriceListRuleId changes. Inventory posting also stamps it onto the ledger row as the movement's unit cost when no UnitCost is present. | | `UnitPrice2` | Unit Price 2 | Currency | | The second price from the applicable price-list rule, set alongside UnitPrice. | | `UOM` | UOM | Text | | | | `UOM1` | UOM1 | Text | | | | `UOMQuantity` | UOM Quantity | Decimal | | The quantity as entered in the line's chosen unit of measure. It is multiplied by ConversionRatio (and the second UOM leg by ConversionRatio1) to derive the base-unit Quantity, so this is what the user types and Quantity is what the system stores and posts. | | `UOMQuantity1` | UOM Quantity 1 | Decimal | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `HeaderEdit` | Edit | Edit | Edit | | `NewInLine` | New | NewInline | New In Line | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Quantity Rule Validation | `Quantity`, Error | Quantity cannot be 0 | Quantity cannot be 0 | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Lot For SKU | `ItemLotId` | | | Lot Type for Item | `ItemLotTypeId` | | | Sku For Item | `SKUId` | | ## Related entities - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — looks up via `InventoryFulfilmentAllocationLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — looks up via `PurchaseOrderLineId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — looks up via `InvoiceLineId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — looks up via `InventoryFulfilmentPickingLineId` - [ItemAlias](/docs/reference/entities/item-alias/) — looks up via `ItemAliasId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [OrderLine](/docs/reference/entities/order-line/) — looks up via `OrderLineId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — looks up via `ServiceOrderLineId` - [Item](/docs/reference/entities/item/) — looks up via `OriginalItemId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [SchemeLine](/docs/reference/entities/scheme-line/) — looks up via `SchemeLineId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — looks up via `PriceListRuleId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — looks up via `DeliveryOrderId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `DeliveryOrderLineId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `DeliveryOrderLineId` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `DeliveryOrderLineId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `DeliveryOrderLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Delivery Order — entity reference URL: https://xmatix.com/docs/reference/entities/delivery-order/ Last reviewed: 2026-08-16 The outbound dispatch document for a customer or dealer account: what is leaving a branch, to which ship-to address, under which transporter and e-way-bill references. It is normally generated rather than keyed - from a sales Order, from an InventoryFulfilment's allocation or picking lines (one delivery per fulfilment), from an Invoice, or from claim approval and rejection (ApprovedPart and RejectedPart discriminate the two documents a single Claim produces). Every header total is a calculated roll-up over DeliveryOrderLines, and no stock moves when the document or its lines are created: the Outward movement is written only when the PerformInventoryPosting action runs. Downstream it raises the Invoice (PerformCreateInvoice), the counterparty's inbound Shipment (PerformReleaseShipment) and the GL accrual (PerformGLPosting), and visit planning turns unplanned deliveries into 'Order Delivery' visits. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The ship-to customer or dealer account receiving the goods. It is source-populated from the originating order, fulfilment, invoice or claim and cannot be edited afterwards, and releasing a shipment requires a Branch whose PartnerAccountId equals this account. | | `AccountName` | Account Name | Text | | | | `ApprovedPart` | Approved Part | Boolean | | True on the delivery order built from the approved lines of a Claim, whose line quantities come from ClaimLine.ApproveQuantity. It is the discriminator that keeps the approved and rejected documents for the same claim apart. | | `ApproximateDistance` | Approximate Distance | Decimal | | | | `BillingAddress` | Billing Address | Text | | | | `BillingCity` | Billing City | PickList | | Values: Pune, Mumbai, Chandigarh. | | `BillingCityPlaceId` | Billing City | Lookup → [Place](/docs/reference/entities/place/) | | Values: Pune, Chandigarh, Mumbai. | | `BillingContactAddressId` | Billing Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `BillingCountry` | Billing Country | PickList | | Values: India. | | `BillingPostalCode` | Billing Postal Code | Text | | | | `BillingRegion` | Billing Region | Text | | | | `BillingState` | Billing State | PickList | | Values: Haryana, Maharashtra, New Delhi, Punjab. | | `BillingStreet` | Billing Street | Text | | | | `BillReturnId` | Bill Return | Lookup → BillReturn | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The dispatching branch, validated to belong to PartnerAccountId and locked after creation. It is also the branch whose InventoryStock buckets the Outward posting relieves and the branch the cost journal is booked at. | | `ClaimId` | Claim | Lookup → [Claim](/docs/reference/entities/claim/) | | Present only on the deliveries generated from a Claim's lines. A claim produces at most two such documents - one with ApprovedPart true and one with RejectedPart true - and the service reuses the existing one for the claim rather than creating a second. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeliveredDateTime` | Delivered Date Time | DateAndTime | | Actual proof of delivery in the running system comes from the generated Visit and its checklist lines rather than from this timestamp. | | `DeliveryCity` | Delivery City | PickList | | | | `DeliveryContactAddressId` | Delivery Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `DeliveryCountry` | Delivery Country | PickList | | Values: India. | | `DeliveryDate` | Delivery Date | Date | | | | `DeliveryDoneByResourceId` | Delivery By | Lookup → [Resource](/docs/reference/entities/resource/) | | The resource (driver or field person) credited with performing the delivery. It is validated against the resource master on both insert and update, but nothing else in the platform reads it - it does not drive visit assignment. | | `DeliveryLocation` | Delivery Location | Text | | A free-text description of where to deliver, not coordinates. Route and distance calculations deliberately ignore it and take the planned position from the ship-to account's stored geolocation instead. | | `DeliveryPostalCode` | Delivery Postal Code | Text | | | | `DeliveryRegion` | Delivery Region | Text | | | | `DeliveryState` | Delivery State | PickList | | The state or province of the ship-to address, held as free text. No code writes it; it is read once, when visit planning copies it onto the generated Visit as VisitState. | | `DeliveryStreet` | Delivery Street | Text | | | | `Discount` | Discount | Currency | | A header discount that cascades: modifying it re-runs discount distribution across all delivery order lines. | | `DiscountGroupId` | Discount Group | Lookup → [DiscountGroup](/docs/reference/entities/discount-group/) | | | | `DocumentDate` | Document Date | Date | | Defaulted to the current date when the delivery is created and non-editable thereafter. It is the date the GL journal from PerformGLPosting carries, so it is the accounting date of the dispatch rather than a planning date. | | `EWayBillDate` | E-Way Bill Date | DateAndTime | | | | `EWayBillNumber` | E-Way Bill Number | Text | | The e-way bill reference for this consignment. | | `ExternalId` | External | Text | | | | `FailedItemTreatment` | Failed Item Treatment | PickList | | | | `GeneralLedgerId` | General Ledger | Lookup → [GeneralLedger](/docs/reference/entities/general-ledger/) | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `GSTIN` | GSTIN | Text | | The customer's GST registration number for this dispatch, auto-filled from the billing contact address and, failing that, from the customer account, and format-validated on both insert and update. | | `Id` | Id | Guid | Yes | | | `InventoryFulfilmentId` | Inventory Fulfillment | Lookup → [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) | | | | `InvoiceId` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | Set when the delivery was generated from an Invoice rather than an Order, in the invoice-first flow. Its lines then carry InvoiceLineId, which selects the ledger rule that decrements the PendingDeliveries bucket using InvoicedQuantity instead of posting a plain Outward movement. | | `IsCancelled` | Cancelled | Boolean | | | | `IsConfirmed` | Confirmed | Boolean | | | | `IsDelivered` | Delivered | Boolean | | Its only consumer is visit planning, which selects delivery orders where it is not true, so in practice every delivery stays eligible for visit generation indefinitely. | | `IsGLPosted` | Is GL Posted | Boolean | | Intended to record that the delivery's journals were posted, but nothing in the platform writes it - PerformGLPosting sets only IsGLPostingApproved. Look for Journal rows sourced from the document instead. | | `IsGLPostingApproved` | Is GL Posting Approved | Boolean | | Stamped true by PerformGLPosting immediately before the document's journals are posted through the document journal posting service. | | `IsILPosted` | IL Posted | Boolean | | A header-level inventory-posted flag that no code writes. Inventory posted state is tracked per line by DeliveryOrderLine.InventoryLedgerId, which is also what the posting action filters on. | | `IsILPostingApproved` | IL Posting Approved | Calculated (calculated) | | An approval gate for inventory posting that is never enforced: the handler collects the approved records on update but discards the result without acting on it, and PerformInventoryPosting does not consult it. Setting it true does not authorise anything on its own. | | `IsInJobQueue` | In Job Queue | Boolean | | | | `IsShipmentReleased` | Shipment Released | Boolean | | To tell whether a delivery has been shipped, look for Shipment rows built from it rather than at this flag. | | `JobInterfaceQueueId` | Job Queue | Lookup → [InterfaceQueue](/docs/reference/entities/interface-queue/) | | | | `JobQueueId` | Job Queue | Lookup | | | | `LRDate` | LR Date | DateAndTime | | | | `LRNumber` | LR Number | Text | | The carrier's lorry receipt or consignment note number. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | The sales Order being delivered. It is locked after creation, and partner account, branch and account are source-populated from it and equally non-editable. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The selling company that owns the document; it is validated against BranchId on insert, locked after creation, and becomes the SupplierAccountId of any Shipment released from this delivery. | | `PerformPopulateChecklist` | Perform Populate Checklist | Boolean | | No code writes or reads the column. | | `PerformReleaseShipment` | Perform Release Shipment | Boolean | | | | `PlaceOfSupply` | Place of Supply | PickList | | The destination state for GST purposes. It is auto-filled from the billing contact address and, failing that, from the customer account, and comparing it with SourceOfSupply is what decides between a within-state and an outside-state supply. Values: Haryana, Maharashtra, Gujarat, Rajasthan. | | `PorterContactNumber` | Porter Contact Number | Text | | | | `PriceAsOnDate` | Price As On Date | Date | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RejectedPart` | Rejected Part | Boolean | | True on the delivery order built from the rejected lines of a Claim, whose line quantities come from ClaimLine.RejectQuantity. It is the mirror of ApprovedPart and only one of the two is ever set on a given document. | | `Remarks` | Remarks | Text | | | | `RequestedDeliveryBranchTimeSlotBookingId` | Requested Delivery Time Slot Booking | Lookup → [BranchTimeSlotBooking](/docs/reference/entities/branch-time-slot-booking/) | | | | `RequestedDeliveryBranchTimeSlotId` | Requested Delivery Time Slot | Lookup → [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) | | | | `RequestedDeliveryDate` | Requested Delivery Date | Date | | | | `RequestedDeliveryDateTime` | Requested Delivery Date Time | DateAndTime | | | | `RequestedDeliveryTime` | Requested Delivery Time | TimeOnly | | | | `RoundOff` | Round Off | Currency | | TotalAmount is computed purely from the line roll-ups. | | `ScheduledDeliveryDate` | Scheduled Delivery Date | Date | | | | `ScheduledDeliveryDateTime` | Scheduled Delivery Date Time | DateAndTime | | The planned delivery slot that visit planning matches against a VisitPlan's start and end dates; it also becomes the generated Visit's planned start time, with the planned end one hour later. No code writes it, so it must be set by the user or an integration for planning to slot the delivery precisely - deliveries with it empty are picked up by any plan window for the same branch and partner. | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | Alternative source document: a delivery raised for a ServiceOrder instead of a sales Order. | | `ShippingAddress` | Shipping Address | Text | | | | `ShippingCity` | Shipping City | PickList | | Values: Pune, Mumbai, Chandigarh. | | `ShippingCityPlaceId` | Shipping City | Lookup → [Place](/docs/reference/entities/place/) | | Values: Pune, Chandigarh, Mumbai. | | `ShippingContactAddressId` | Shipping Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `ShippingCountry` | Shipping Country | PickList | | Values: India. | | `ShippingPostalCode` | Shipping Postal Code | Text | | | | `ShippingRegion` | Shipping Region | Text | | | | `ShippingState` | Shipping State | PickList | | Values: Haryana, Maharashtra, New Delhi, Punjab. | | `ShippingStreet` | Shipping Street | Text | | | | `SourceOfSupply` | Source of Supply | PickList | | The origin state for GST purposes, auto-filled from the dispatching branch. It is only ever compared with PlaceOfSupply to derive TaxSupplyType. Values: Rajasthan, Haryana, Maharashtra, Gujarat. | | `Status` | Status | PickList | | All four seeded values (Draft, Registration, Delivery Checklist, Delivered) are inactive and no code writes this column, so it stays at its 'Draft' default default forever. Do not filter or report deliveries by Status; use the line-level InventoryLedgerId and the quantity roll-ups instead. Values: Insurance Issued. | | `Tax1` | Tax1 | Currency | | | | `Tax1Name` | Tax Name 1 | Text | | | | `Tax1Rate` | Tax Rate 1 | Currency | | | | `Tax1Type` | Tax Type 1 | Text | | | | `TaxSupplyType` | Tax Supply Type | PickList | | The GST supply classification, derived automatically by the India handler from the billing address or customer GST registration type: 'Exempt' for out-of-scope and non-GST supply, 'Export' for overseas and deemed exports, 'SEZ' for special economic zone, otherwise 'Outside State' when PlaceOfSupply differs from SourceOfSupply and 'Within State' when they match. Only the last two exist as seeded pick-list values, so the engine can legitimately store Export, SEZ or Exempt values that a picker will not offer. Values: Within State, Outside State. | | `TotalAmount` | Total Amount | Calculated (calculated) | | Calculated as TotalLineAmount plus line tax, falling back to TotalTaxAmount2 when TotalLineTaxAmount is zero. It ignores the header Discount and RoundOff fields, so it is not necessarily the amount invoiced. | | `TotalDiscountAmount` | Total Discount Amount | Calculated (calculated) | | | | `TotalLineAmount` | Total Line Amount | Calculated (calculated) | | | | `TotalLineBaseAmount` | Total Line Base Amount | Calculated (calculated) | | | | `TotalLineGrossAmount` | Total Line Gross Amount | Calculated (calculated) | | The sum of the lines' GrossAmount (line amount plus tax, less post-tax discounts). This is the figure PerformGLPosting books, as Dr Unbilled Dispatch / Cr Inventory Asset. | | `TotalLineTaxAmount` | Total Line Tax Amount | Calculated (calculated) | | | | `TotalTaxAmount` | Total Tax Posting Amount | Calculated (calculated) | | Calculated as the line tax total plus the header Tax1, and labelled Total Tax Posting Amount. It pairs with TotalTaxAmount2, which is the same line total minus Tax1 - the two are a plus and minus pair, not two independent tax totals. | | `TotalTaxAmount2` | Total Tax Amount | Calculated (calculated) | | | | `TransportDocumentDate` | Transport Document Date | DateAndTime | | | | `TransportDocumentNumber` | Transport Document No. | Text | | | | `TransporterGSTIN` | Transporter GSTIN | Text | | The carrier's own GST registration number, captured for the e-way bill. It is format-validated by the India handler on insert and update, so an incorrectly shaped value is rejected at save time. | | `TransporterName` | Transporter Name | Text | | | | `TransportMode` | Transport Mode | Text | | How the consignment travels, for the e-way bill; the domain model documents the intended values as Air, Road, Railway and Ship, but no pick-list values are seeded for it and no code validates or reads it. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VehicleNumber` | Vehicle Number | Text | | The vehicle registration carrying the consignment, format-validated by the India handler on insert and update. It is captured for the e-way bill and is not linked to any Asset or fleet record. | | `VisitId` | Visit | Lookup → [Visit](/docs/reference/entities/visit/) | | Meant to mark a delivery that has already been turned into a field visit, and visit planning skips deliveries where it is set. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInList` | Edit | Edit | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EWayBill` | E Way Bill | ServerAction | Seeded as a server action but dead: the row carries no ServerActionName, so dispatch falls back to the action name 'EWayBill', which the delivery order handler does not list among its supported actions. The e-way-bill fields on the document (EWayBillNumber, EWayBillDate and the transport details) are manual capture only. | | `New` | New | New | New | | `PerformCreateInvoice` | Create Invoice | ServerAction (`PerformCreateInvoice`) | Creates an Invoice from the delivery order's lines that still have PendingInvoiceQuantity above zero, and refuses with 'No pending invoice quantities found in delivery order lines to create invoice' when none do. A second, stricter gate lives inside the invoice service, which re-queries the underlying order lines and can still refuse when the order side is fully invoiced even though a delivery line looks pending. | | `PerformGLPosting` | Post General Ledger | ServerAction (`PerformGLPosting`) | Force-sets IsGLPostingApproved to true on the document and then posts it through the document journal posting service with the DeliveryOrder purpose: Dr Unbilled Dispatch / Cr Inventory Asset for TotalLineGrossAmount, dated DocumentDate and keyed on AccountId. It has no validation gate of its own, and it does not set IsGLPosted or GeneralLedgerId - neither field is written anywhere in the platform. | | `PerformInventoryPosting` | Post Inventory | ServerAction (`PerformInventoryPosting`) | The action that actually moves stock for a delivery: it collects the lines whose InventoryLedgerId is still empty and runs the inventory posting engine over them. Four mutually exclusive seeded rules pick the movement by provenance - picking-sourced lines post Outward and decrement Picked, allocation-only lines post Outward and decrement Allocation, plain lines post Outward only, and invoice-sourced lines decrement PendingDeliveries using InvoicedQuantity. Each posted row also updates the branch's InventoryStock buckets and the ItemLot counters, and hands the row to the finance cost engine, which rebuilds the perpetual cost layers for that item and branch and books an Outward movement as Dr Cost Of Goods Sold / Cr Inventory at the engine cost. Nothing posts when the lines are first created: all four ledger settings have OnCreate false. | | `PerformPopulateChecklist` | Populate Checklist | ServerAction (`PerformPopulateChecklist`) | Materialises checklist lines for the delivery from the CheckListTemplate whose Type is 'Delivery' (the mapping the checklist service holds for the DeliveryOrder entity), stamping each created line with RelatedEntityType DeliveryOrder and the delivery's id. | | `PerformReleaseShipment` | Release Shipment | ServerAction (`PerformReleaseShipment`) | Creates the counterparty's inbound Shipment from this delivery's lines with quantity above zero, swapping the party roles: the delivery's PartnerAccountId becomes the shipment's SupplierAccountId, the delivery's AccountId becomes the shipment's PartnerAccountId, and the shipment's branch is the Branch whose PartnerAccountId equals that account - so it fails with 'No branch found for account ... to create shipment' when the customer is not a partner account with a branch in the same system. Each shipment line copies the item, SKU, quantity and PurchaseOrderLineId, but not DeliveryOrderLineId, so the delivery line's ShippedQuantity roll-up has nothing to sum. It does not set IsShipmentReleased, which no code path ever writes. | | `PrintDO` | Print DO | Print | A Print-type action rather than a server action, so it renders the delivery note through the platform's print pipeline and changes no data. | | `SelectiveReleaseShipment` | Selective Release Shipment | ServerAction (`SelectiveReleaseShipment`) | Creates a Shipment for chosen lines and quantities instead of the whole delivery order. Args carry DeliveryOrderLines with id and requestedQuantity; each requested quantity is validated against the line quantity, and the action refuses when no selected line has quantity above zero. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | PartnerAccountId = __target.PartnerAccountId | | Customer Account Filter | `AccountId` | | | Executive Filter | `DeliveryDoneByResourceId` | | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [InterfaceQueue](/docs/reference/entities/interface-queue/) — looks up via `JobInterfaceQueueId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [Resource](/docs/reference/entities/resource/) — looks up via `DeliveryDoneByResourceId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `DeliveryContactAddressId` - [DiscountGroup](/docs/reference/entities/discount-group/) — looks up via `DiscountGroupId` - [Visit](/docs/reference/entities/visit/) — looks up via `VisitId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — looks up via `InventoryFulfilmentId` - [Place](/docs/reference/entities/place/) — looks up via `ShippingCityPlaceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Place](/docs/reference/entities/place/) — looks up via `BillingCityPlaceId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `BillingContactAddressId` - [Claim](/docs/reference/entities/claim/) — looks up via `ClaimId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — looks up via `GeneralLedgerId` - [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) — looks up via `RequestedDeliveryBranchTimeSlotId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `ShippingContactAddressId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [BranchTimeSlotBooking](/docs/reference/entities/branch-time-slot-booking/) — looks up via `RequestedDeliveryBranchTimeSlotBookingId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `DeliveryOrderId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [Visit](/docs/reference/entities/visit/) — referenced by via `DeliveryOrderId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ParentRecordId` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — referenced by via `DeliveryOrderId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `DeliveryOrderId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `DeliveryOrderId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `DeliveryOrderId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Depreciation Line — entity reference URL: https://xmatix.com/docs/reference/entities/depreciation-line/ Last reviewed: 2026-08-16 One period of a Depreciation schedule — period number, the opening and closing book values, the charge for the period and the running accumulated total. Note also that the domain class carries a ToDate but the metadata surface does not expose it, so a period can only be identified here by PeriodNumber together with FromDate. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccumulatedDepreciation` | Accumulated Depreciation | Currency | | The running total of depreciation charged from the start of the schedule up to and including this period — a cumulative figure, not the period's own charge, which is DepreciationAmount. | | `ClosingBookValue` | Closing Book Value | Currency | | The carrying value at the end of the period, after the period's DepreciationAmount has been deducted from OpeningBookValue. It becomes the next period's opening value. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Currency` | Currency | PickList | | | | `DepreciationAmount` | Depreciation Amount | Currency | | The charge for this single period only. Do not sum it with AccumulatedDepreciation, which already includes it. | | `DepreciationId` | Depreciation | Lookup → [Depreciation](/docs/reference/entities/depreciation/) | | | | `FromDate` | Date | Date | | The start of the period this line charges, labelled just 'Date'. The matching period end is not exposed in metadata, so treat the next line's FromDate as the boundary. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `OpeningBookValue` | Opening Book Value | Currency | | The asset's carrying value at the start of this period, before the period's charge is applied. Subtracting DepreciationAmount from it gives ClosingBookValue. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PeriodNumber` | Period Number | Number | | The one-based ordinal of this period within its parent schedule. Because the metadata surface exposes FromDate but not the domain class's ToDate, this ordinal plus FromDate is the only way to identify a period here. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `ToDate` | To Date | Date | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteListHeader` | Delete | Delete | DeleteListHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListHeader` | Edit | Edit | EditListHeader | | `EditRow` | Edit | Edit | EditRow | | `NewInLine` | New | NewInline | NewInLine | ## Related entities - [Depreciation](/docs/reference/entities/depreciation/) — looks up via `DepreciationId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Depreciation Policy — entity reference URL: https://xmatix.com/docs/reference/entities/depreciation-policy/ Last reviewed: 2026-08-16 A reusable, category-level template for how a class of assets should be depreciated — method, rate, useful life, frequency and currency — which assets adopt through Asset.DepreciationPolicyId. Per the fixed-assets configuration manual it documents intended treatment only; the schedule that actually executes depreciation is RecurringDepreciation in the finance module, and generating one from a policy is not yet implemented. Its own AssetId is an optional pin to a single asset, which is separate from the set of assets that reference the policy. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AssetCategory` | Asset Category | PickList | | Values: IT, Furniture, Office Equipment, Electronics, Machines. | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | An optional pin to one specific asset, per the fixed-assets configuration manual. It is separate from and should not be confused with the set of assets that adopt this policy through Asset.DepreciationPolicyId. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Currency` | Currency | PickList | | | | `DepreciationRate` | Depreciation Rate | Percent | | The per-period rate for a written-down-value policy, held as a percentage-typed field. It is only meaningful when Method is WDV; a straight-line policy is described by UsefulLife instead. | | `Frequency` | Frequency | PickList | | How often the policy intends depreciation to be charged, seeded with Monthly and Yearly. It records intent only — no scheduler reads this entity. Values: Monthly, Yearly. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `Method` | Method | PickList | | The depreciation basis the policy prescribes, seeded as 'Straight Line' or 'WDV'. Note this field is named Method here while the equivalent on Asset and Depreciation is named DepreciationMethod. Values: Straight Line, WDV. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SubCategory` | Sub Category | PickList | | The asset sub-class the policy applies to, and the one of the two identically labelled sub-category fields that actually carries seeded values (Laptop, Desktop, Server, Printer, Air Conditioner, CNC Machines and similar). Values: Laptop, Desktop, Server, Printer, Scanner, Router, Switch, Office Chair, Table, Workstation, Cabinet, Conference Table, Air Conditioner, Biometric Machine, CNC Machines. | | `Subcategory1` | Sub Category | PickList | | The two cannot be told apart by label, and the fixed-assets manual lists both without distinguishing them — use SubCategory unless a tenant has explicitly populated this one. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UsefulLife` | Useful Life (in years) | Number | | The expected life in years for assets in this category, labelled 'Useful Life (in years)'. The platform ships indicative Companies Act Schedule II lives as reference data that a tenant can override here. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteListHeader` | Delete | Delete | DeleteListHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `Edit` | Edit | EditInline | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditRow` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [Asset](/docs/reference/entities/asset/) — referenced by via `DepreciationPolicyId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Depreciation — entity reference URL: https://xmatix.com/docs/reference/entities/depreciation/ Last reviewed: 2026-08-16 A depreciation schedule header for an Asset, holding the method, the start and end dates, the period count and the residual value, with DepreciationLine as its per-period breakdown. The depreciation that actually computes and posts to the general ledger is RecurringDepreciation in the finance module, driven by RecurringDepreciationService and its scheduled evaluator/processor, and it links to assets by name rather than by a foreign key. Do not answer questions about an asset's real depreciation charge or accumulated depreciation from this table; it will normally be empty. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Currency` | Currency | PickList | | | | `DepreciationMethod` | Depreciation Method | PickList | | The basis for the schedule, seeded as 'Straight Line' or 'WDV'. As on Asset, these display strings differ from the StraightLine and WrittenDownValue tokens used by the finance engine and the manuals. Values: Straight Line, WDV. | | `EndDate` | End Date | Date | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | The schedule's document number — this entity labels the standard Name field as 'Document Number' rather than using a separate column, so the human-facing reference for a depreciation schedule is here. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResidualValue` | Residual Value | Currency | | | | `StartDate` | Start Date | Date | | | | `Status` | Status | PickList | | The schedule's state, seeded with Draft, Active and Completed. Because nothing in the platform drives this entity, the value only ever reflects what a user or an import set. Values: Draft, Active, Completed. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TotalPeriods` | Total Periods | Number | | The number of periods the schedule is meant to span, which should correspond to the count of DepreciationLine children. It is a declared intent, not a computed count of existing lines. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteListHeader` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | EditInLine | | `New` | New | New | New | ## Related entities - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [DepreciationLine](/docs/reference/entities/depreciation-line/) — referenced by via `DepreciationId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Discount Group Rule — entity reference URL: https://xmatix.com/docs/reference/entities/discount-group-rule/ Last reviewed: 2026-08-16 One dated discount percentage inside a DiscountGroup, aimed at an item, an item group or a SKU. Matching is confined to the discount group already on the document header, then per line to a rule whose item, SKU and item group are each either equal to the line's or left blank, inside an effective-date window compared against the header's DocumentDate; item-group membership is read from ItemGroupMember rows in an item group of type Discount. Candidates are ordered by item, then SKU, then DateEffectiveFrom descending, so an item-specific rule beats a group-wide one even when the group-wide one is newer. The winner writes its percentage into the line's ContractDiscount and its own identifier into DiscountGroupRuleId, which downstream documents carry forward when an order becomes an invoice. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ClaimablePercentage` | Claimable Percentage | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DateEffectiveFrom` | Date Effective From | Date | Yes | Compared against the parent document's DocumentDate, and used as the last tie-break behind item and SKU. When several documents are saved in one batch the candidate rules are pre-filtered against the earliest document date in that batch, so a rule that only becomes effective later can be missed for the later-dated documents of the same save. | | `DateEffectiveTill` | Date Effective Till | Date | | End of validity, tested against the document date. Empty leaves the rule open-ended. | | `DiscountGroupId` | Discount Group | Lookup → [DiscountGroup](/docs/reference/entities/discount-group/) | Yes | Matching is confined to the group already stored on the document header, so a rule belonging to any other group is never even considered — an unexpected zero discount is usually a header pointing at the wrong group rather than a missing rule. | | `DiscountPercent` | Discount Percent | Percent | | Copied into the matched line's ContractDiscount. It is a percent-typed field held as a fraction — five percent is stored as 0.05 — and the API scales it by 100 on read and back on write, so services copying it between records never rescale it. | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | Matches when the line's item belongs to that group, using ItemGroupMember rows whose item group is of type Discount; groups of any other type are never seen by discount matching. An empty value matches every line. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | Empty makes the rule apply to every item on the document. Item is the first ordering key, so an item-specific rule is preferred over a blank one even when the blank one starts later. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | Unlike price-list rules, lot type does not narrow a discount rule at all. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | Empty means the rule covers all SKUs of the item. It is the second ranking key after item, so a SKU-specific rule outranks a SKU-blank one. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete Selected | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Delete in page. | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | NewInline | New | | `UIAction` | UI Action | UIAction | UI Action | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Date Effective Till Rule Validation | `DateEffectiveTill`, Error | Date Effective Till can not be Backdated | Date Effective can't be Backdated Validation. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Active Items | `ItemId` | | | SKU For Item | `SKUId` | | ## Related entities - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [DiscountGroup](/docs/reference/entities/discount-group/) — looks up via `DiscountGroupId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `DiscountGroupRuleId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `DiscountGroupRuleId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `DiscountGroupRuleId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Discount Group — entity reference URL: https://xmatix.com/docs/reference/entities/discount-group/ Last reviewed: 2026-08-16 A container for contract-discount percentages that DiscountGroupService stamps onto a document header when the header has none. Candidates must be active and carry a DiscountType of exactly 'Sale Price' or 'Purchase Price', and must fit the document on partner account, branch, partner account group and customer account group, where group membership comes from AccountGroupMember rows in an account group of type Discount. The percentages themselves live in child DiscountGroupRule rows, and the IncentiveEngine can overwrite a document's discount group from a compensation slab. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Confines the group to documents raised in that branch; empty means every branch. Branch is the first ordering key among matching groups, so a branch-specific group is preferred. | | `ClaimablePercentage` | Claimable Percentage | Percent | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CustomerAccountGroupId` | Customer Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | Restricts the group to customers in that account group, resolved from AccountGroupMember rows whose account group is of type Discount. Groups of any other type are invisible here. | | `DiscountType` | Discount Type | PickList | Yes | Must read exactly 'Sale Price' or 'Purchase Price'. The selector coerces anything that is not the sale value to the purchase value before comparing, so a typo or a blank effectively files the group under purchase and it will never be chosen for a sales document. Values: Sale Price, Purchase Price. | | `Id` | Id | Guid | Yes | | | `IsActive` | Active | Boolean | | Only active groups are considered when a document header is given a discount group; deactivating a group stops new documents picking it up but does not disturb groups already stored on existing documents. | | `IsClaimable` | Claimable | Boolean | | The claims engine decides claimability from the scheme's own claimable flag, not from this one, so setting it here does not make a discount recoverable. | | `IsDefault` | Default | Boolean | | Stored but never consulted by the selector — unlike price lists, discount-group selection has no default fallback, so a document that matches no scoped group simply ends up with no discount group and no contract discount. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountGroupId` | Partner Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | Restricts the group to documents whose partner account belongs to that group, again through AccountGroupMember rows in an account group of type Discount. | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Confines the group to documents for that partner account; empty means all partners. It ranks second behind branch when several groups match. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Delete in page. | | `EditInList` | Edit | Edit | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `New` | New | New | New | | `UIAction` | UI Action | UIAction | UI Action | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Partner Account Filter | `PartnerAccountId` | | | Related Branch | `BranchId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `PartnerAccountGroupId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `CustomerAccountGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `DiscountGroupId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `DiscountGroupId` - [Quote](/docs/reference/entities/quote/) — referenced by via `DiscountGroupId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `DiscountGroupId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `DiscountGroupId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `DiscountGroupId` - [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) — referenced by via `DiscountGroupId` - [Bill](/docs/reference/entities/bill/) — referenced by via `DiscountGroupId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `DiscountGroupId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `DiscountGroupId` - [Order](/docs/reference/entities/order/) — referenced by via `DiscountGroupId` - [CompensationSlab](/docs/reference/entities/compensation-slab/) — referenced by via `DiscountGroupId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Document Name Setting — entity reference URL: https://xmatix.com/docs/reference/entities/document-name-setting/ Last reviewed: 2026-08-16 Tenant configuration that switches on automatic document-name generation for one target entity: at save time the naming service composes series, date and sequence into the record field named by destinationFieldName, using dateFormat, autoNumberLength and concatenationCharacter to shape the result and allocating numbers from the DocumentName counter for the resolved series. The series prefix comes from the record field named by sourceSeriesField when configured (a calculated field's formula is evaluated on demand, and a dotted path can read across a relation), otherwise defaultSeries applies - and the fallback is silent, so a misconfigured series field shows up only as a wrongly prefixed document name. Lives in the metadata schema as tenant-authored configuration; only rows with isActive true take effect. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AutoNumberLength` | Auto Number Length | Number | | | | `ConcatenationCharacter` | Concatenation Character | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DateFormat` | Date Format | Text | | | | `DefaultSeries` | Default Series | Text | | The series used whenever the source series field is not configured or fails to resolve. Because the fallback is silent, documents unexpectedly carrying this series usually mean the source series field is misconfigured. | | `DestinationFieldName` | Destination Field Name | Text | | The field on the target entity that receives the generated document name - the composed series, date and sequence value is written here at save time. | | `EntityName` | Entity Name | Text | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SourceDateFieldName` | Source Date Field Name | Text | | | | `SourceSeriesField` | Source Series Field | Text | | Names the record field that supplies the series prefix at naming time. A calculated field is supported - its formula is evaluated on demand because the value is not computed yet when naming runs - and a dotted path can read across a relation. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Clone | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Document Name — entity reference URL: https://xmatix.com/docs/reference/entities/document-name/ Last reviewed: 2026-08-16 The runtime sequence counter behind automatic document numbering: one row per target entity and document series (entityName plus documentSeries) holding lastNumberUsed. The transaction-time naming service reads and increments it to allocate the next number when composing a document name from series, date and sequence; the rules deciding the format live separately in DocumentNameSetting (metadata schema) while this counter stays in the data schema. Treat it as engine state rather than reference data. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DateFormat` | Date Format | Text | | | | `DocumentSeries` | DocumentSeries | Text, unique | | | | `EntityName` | Entity Name | Text | | | | `Id` | Id | Guid | Yes | | | `LastNumberUsed` | Last Number Used | Number | | The high-water mark of the sequence for this entity/series pair; the naming service increments it to allocate the next document number. It is engine state, not a configurable starting value on existing rows. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Document Service Contract Line — entity reference URL: https://xmatix.com/docs/reference/entities/document-service-contract-line/ Last reviewed: 2026-08-16 A service-contract scope line captured against a sales document rather than against an asset or a template — it records which component items are in or out of scope on an Opportunity line, sale order line or sale invoice line. Be careful with its lookups: ComponentItemId, SaleInvoiceLineId, SaleOrderLineId and OpportunityLineId are typed as lookups but have no EntityRelation defined and no foreign key on the domain class, so they cannot be expanded or joined through the relations API and must be resolved by a second query on the raw id. The domain class also carries a second, unsuffixed copy of each of these columns, but only the Id-suffixed ones are exposed in metadata. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ComponentItemId` | Component Item | Lookup | | The component item whose contract scope this line records. It is typed as a lookup but has no EntityRelation and no foreign key on the domain class, so it cannot be expanded through the relations API — resolve the Item with a separate query on the raw id. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IsInScope` | Is In Scope | Boolean | Yes | Whether the component is included in or excluded from contract scope on the referenced sales document line. The same in-or-out semantics as the flag of the same name on ItemServiceContractLine. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OpportunityLineId` | Opportunity Line | Lookup | | The opportunity line this scope line was captured against. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SaleInvoiceLineId` | Sale Invoice Line | Lookup | | The sales invoice line this scope line was captured against. Like the other lookups on this entity it has no relation defined, so it holds a raw id that must be resolved with a second query. | | `SaleOrderLineId` | Sale Order Line | Lookup | | The sales order line this scope line was captured against, held as an unrelated raw id — no EntityRelation exists for it, so it cannot be joined or expanded. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Duplicate Rule — entity reference URL: https://xmatix.com/docs/reference/entities/duplicate-rule/ Last reviewed: 2026-08-16 An admin-authored duplicate-detection rule for one entity (entityName), with the field criteria on child DuplicateRuleCondition rows. The dedup engine reads the active rules for an entity and builds its find-duplicates query from them, so matching is configurable per entity; when an entity has no active rule the engine falls back to built-in heuristics. matchLogic decides whether any condition suffices or all must match, and onMatch is Detect today - candidates are surfaced for review; Alert and Block are reserved values that do not yet prevent saves. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Description` | Description | Text | | | | `EntityName` | Target Entity | Text | | | | `IsActive` | Active | Boolean | | | | `MatchLogic` | Match Logic | Text | | Any (the default, also used when null) flags a candidate when ANY condition matches; All requires EVERY condition to match. | | `OnMatch` | On Match | Text | | Detect (the default) surfaces candidates in the duplicates panel for review. Alert and Block are reserved values - they do not yet warn on or prevent saves, so do not describe a Block rule as enforcing anything. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # E Invoice — entity reference URL: https://xmatix.com/docs/reference/entities/einvoice/ Last reviewed: 2026-08-16 Register table modelled on the IRP/NIC e-invoicing submission: source invoice reference, seller and buyer GSTIN, the IRP request payload, and the IRN, acknowledgement, signed invoice and QR code that come back. Important for grounding: no code path writes rows here. The e-invoicing that actually runs stores everything on the Invoice record's own EINV fields — the EInvoiceGenerator action builds the IRP 1.1 payload into Invoice.EINVPayload and sets EINVStatus, the bound integration flow transmits it, and EInvoiceGspService.RecordResponseAsync writes the IRN, QR, acknowledgement and signed invoice back onto the same Invoice. Treat this entity as a modelled register that is currently unpopulated, not as the source of truth for e-invoice state. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AckDate` | Ack Date | Text | | | | `AckNo` | Ack No | Text | | | | `BranchId` | Branch Id | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BuyerGSTIN` | Buyer GSTIN | Text | | | | `BuyerName` | Buyer Name | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | | | `EInvoiceImage` | EInvoice Image | LongMultiLineText | | | | `GspResponse` | GSP Response | LongMultiLineText | | The raw response body from the GSP or portal, kept verbatim for audit and for diagnosing rejections whose reason is not captured in the structured fields. | | `GSTInvoiceType` | GST Invoice Type | PickList | | The supply classification sent to the portal. | | `GSTRegistrationId` | GST Registration Id | Lookup → [GSTRegistration](/docs/reference/entities/gstregistration/) | | | | `Id` | Id | Guid | Yes | | | `InvoiceId` | Invoice Id | Lookup → [Invoice](/docs/reference/entities/invoice/) | | | | `InvoiceNumber` | Invoice Number | Text | | | | `IRN` | IRN | Text | | The Invoice Reference Number the IRP returns and the marker that an invoice is legally e-invoiced. In the running system it is recorded onto the Invoice record, not here, and the invoice's own generate action refuses to rebuild a payload once that value is present. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account Id | Lookup → [Account](/docs/reference/entities/account/) | | | | `Payload` | Payload | LongMultiLineText | | The IRP request JSON in the version 1.1 schema — transaction details, document details, seller and buyer parties, item list and value totals. The builder that produces it stores the result on the Invoice, and the actual HTTP submission is performed by an integration flow bound to the GSP connector, not by this record. | | `PlaceOfSupply` | Place Of Supply | Text | | | | `QRCode` | QR Code | LongMultiLineText | | The signed QR content returned by the portal, which must be printed on the invoice. It is the portal's signed string rather than an image; the separate image field is for a rendered version. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SellerGSTIN` | Seller GSTIN | Text | | | | `SignedInvoice` | SignedInvoice | LongMultiLineText | | The digitally signed invoice JSON returned by the portal alongside the reference number; it is the artefact that proves the submission, as distinct from the request payload that was sent. Recorded onto the Invoice in the live path. | | `Status` | Status | PickList | | The status that actually moves during e-invoicing lives on the source Invoice's own e-invoice status field. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TotalValue` | Total Value | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GSTRegistration](/docs/reference/entities/gstregistration/) — looks up via `GSTRegistrationId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Employee — entity reference URL: https://xmatix.com/docs/reference/entities/employee/ Last reviewed: 2026-08-16 The HR and payroll configuration record for a person, and a satellite of Resource rather than a replacement for it. Resource stays the canonical person and the universal keying anchor: payroll posting, open items, payslips, expense, leave and attendance all carry ResourceId, and an Employee is never itself a posting key - it resolves to a Resource through Employee.ResourceId, while Resource.EmployeeId is an unrelated plain code string that points at nothing. It carries the HR lifecycle (joining, probation, confirmation, exit, EmploymentStatus of Active/OnNotice/Exited, SettlementStatus of Active/ExitInProcess/Settled) plus payroll configuration, while statutory and bank identity such as PAN, UAN, ESI number, bank account and IFSC live on the Resource; the payroll calculation picks up employees whose PayrollCompanyId or PartnerAccountId matches the run's company, who have a ResourceId, and who are not Exited. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | Yes | | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `ConfirmationDate` | Confirmation Date | Date | | | | `CostCenterId` | Cost Center | Lookup | | Declared as a lookup but with no related entity named, so it does not resolve even though a Cost Center entity exists. No payroll or finance service reads the employee's copy of this field. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DateOfExit` | Date Of Exit | Date | | The last day of employment. Posting a full-and-final settlement fills it from that settlement's Last Working Day only when it is still empty, and never overwrites an existing value. Note the seeded validation on this field is inverted: it raises its error when the joining date is earlier than the exit date, which is the normal case, and lets an exit date before the joining date through unchallenged. | | `DateOfJoining` | Date Of Joining | Date | Yes | | | `DepartmentId` | Department | Lookup | | It cannot resolve, and no service reads it. | | `EmployeeCode` | Employee Code | Text | Yes | The organisation's own staff number for the person, distinct from the record id. It is also distinct from Resource.EmployeeId, which is a separate free-text code held on the Resource; no code path copies one into the other, so the two can disagree. | | `EmploymentStatus` | Employment Status | PickList | | Values: Active, On Notice, Exited. | | `EmploymentType` | Employment Type | PickList | Yes | The declared engagement category. No first-party service reads it - payroll makes no distinction between a full-time employee, a contractor, a consultant and an intern. Its seeded value list has also drifted from the four values the domain documents, carrying an extra Permanent option and a leftover TEST entry. Values: Full Time, Contract, Consultant, Intern, Permanent. | | `EsiApplicable` | Esi Applicable | Boolean | | Declares that Employees' State Insurance applies to this person. Configuration of record only - no first-party service reads it, and ESI is deducted because the assigned salary structure carries an ESI component, not because of this flag. | | `ExpenseAdvanceId` | Expense Advance | Lookup → [ExpenseAdvance](/docs/reference/entities/expense-advance/) | | Expense advances are keyed on the Resource - query ExpenseAdvance by ResourceId instead. | | `ExpenseClaimId` | Expense Claim | Lookup → [ExpenseClaim](/docs/reference/entities/expense-claim/) | | Expense claims are keyed on the Resource - query ExpenseClaim by ResourceId instead. | | `ExpenseVoucherId` | Expense Voucher | Lookup → [ExpenseVoucher](/docs/reference/entities/expense-voucher/) | | Query ExpenseVoucher by its own EmployeeId instead, which is the real link. | | `GradeId` | Grade | Lookup → [Grade](/docs/reference/entities/grade/) | | Points at the Grade master, but nothing reads the employee's copy. The grade that actually drives grade-based expense-policy limits is the one held on the Resource, so evaluate policy and banding from there rather than from this field. | | `Id` | Id | Guid | Yes | | | `KYCDocumentId` | KYC Document | Lookup → [KYCDocument](/docs/reference/entities/kycdocument/) | | A single KYC document pointer, though a person normally has several documents. No first-party service reads or writes it; find a person's documents by querying KYCDocument rather than following this field. | | `Label` | Label | Text | | | | `LwfApplicable` | Lwf Applicable | Boolean | | Declares that Labour Welfare Fund applies to this person. Configuration of record only - no first-party service reads it, so it neither triggers nor suppresses an LWF deduction. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | Yes | | | `PartnerResourceId` | Partner Resource | Lookup → [PartnerResource](/docs/reference/entities/partner-resource/) | | | | `PaymentSalaryDisbursementId` | Payment (Salary Disbursement) | Lookup → [PaymentSalaryDisbursement](/docs/reference/entities/payment-salary-disbursement/) | | Salary disbursement records are keyed on the payroll run rather than on an individual, so there is nothing meaningful for this pointer to hold. | | `PayrollCompanyId` | Payroll Company | Lookup → [Account](/docs/reference/entities/account/) | | | | `PayslipId` | Payslip | Lookup → [Payslip](/docs/reference/entities/payslip/) | | | | `PayType` | Pay Type | PickList | | Declares whether the person is paid monthly, hourly, daily or by piece rate. No first-party payroll code reads it: the calculation always prorates the assigned monthly salary structure by payable days regardless of this value. Values: Monthly, Hourly, Daily, Piece Rate. | | `PfApplicable` | Pf Applicable | Boolean | | | | `PfWageCapOverride` | Pf Wage Cap Overre | Currency | | An employee-specific override of the statutory Provident Fund wage ceiling. Declaration only: no first-party service reads it, so PF is computed from the salary structure's PF component and the statutory rule masters and setting a value here changes nothing. | | `ProbationEndDate` | Probation End Date | Date | | When probation finishes. The seeded validation requires this date to be on or after Confirmation Date, so confirming someone after their probation window has closed is rejected rather than the other way round. | | `PtApplicable` | Pt Applicable | Boolean | | Declares that Professional Tax applies to this person. Configuration of record only - no first-party service reads it, so clearing it does not stop a PT deduction that the salary structure produces. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceAvailabilityId` | Resource Availability | Lookup → [ResourceAvailability](/docs/reference/entities/resource-availability/) | | A single pointer to one attendance record, which cannot represent attendance at all - availability is a per-day series queried by Resource. No first-party code reads the employee's copy of this field. | | `ResourceCompensationId` | Resource Compensation | Lookup → [ResourceCompensation](/docs/reference/entities/resource-compensation/) | | A single pointer to a compensation record that payroll never uses. The salary structure that drives the calculation is found by querying ResourceCompensation by ResourceId and taking the latest active row that names a salary structure, so this field is neither read nor kept current. | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | Yes | The Resource this record configures, and the identity everything else keys on: payroll posting, open items, payslips, expense, leave and attendance all carry ResourceId, so joins from payroll data to a person go through this field rather than through the Employee id. | | `SalaryComponentId` | Salary Component | Lookup → [SalaryComponent](/docs/reference/entities/salary-component/) | | Salary components belong to a salary structure, not to a person - read them by querying SalaryComponent for the structure named on the employee's latest active ResourceCompensation. | | `SalaryPaymentMode` | Salary Payment Mode | PickList | | The declared disbursement channel for salary. Configuration of record only - no first-party service reads it, and neither the payroll calculation nor the payment path branches on it. Values: Bank Transfer, Cash, Cheque. | | `SalaryStructureId` | Salary Structure | Lookup → [SalaryStructure](/docs/reference/entities/salary-structure/) | | | | `SettlementStatus` | Settlement Status | PickList | | Tracks the exit-settlement pipeline separately from Employment Status, with values Active, ExitInProcess and Settled. Only posting a full-and-final settlement moves it, and it jumps straight to Settled - nothing in first-party code ever writes ExitInProcess, so that value appears only when a user or integration sets it. Values: Active, Exit In Process, Settled. | | `TaxRegime` | Tax Regime | PickList | | Values: Old Regime, New Regime. | | `TdsApplicable` | Tds Applicable | Boolean | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this Employee. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this Employee. | | `EditInLine` | Edit | EditInline | Edit | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a Employee. | | `View` | View | View, inactive | View this Employee. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Date of Confirmation | `ConfirmationDate`, Error | Confirmation date cannot be less than Joining Date | Confirmation date cannot be less than Joining Date | | Date Of Exist | `DateOfExit`, Error | Date of exist cannot be less than Date of confirmation | Probation End Date cannot be less than Confirmation Date | | Probation End date | `ProbationEndDate`, Error | Probation End Date cannot be less than Confirmation Date | date | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `BranchId` | | | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [PartnerResource](/docs/reference/entities/partner-resource/) — looks up via `PartnerResourceId` - [PaymentSalaryDisbursement](/docs/reference/entities/payment-salary-disbursement/) — looks up via `PaymentSalaryDisbursementId` - [ResourceAvailability](/docs/reference/entities/resource-availability/) — looks up via `ResourceAvailabilityId` - [Payslip](/docs/reference/entities/payslip/) — looks up via `PayslipId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — looks up via `ExpenseClaimId` - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — looks up via `ExpenseVoucherId` - [SalaryStructure](/docs/reference/entities/salary-structure/) — looks up via `SalaryStructureId` - [SalaryComponent](/docs/reference/entities/salary-component/) — looks up via `SalaryComponentId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Grade](/docs/reference/entities/grade/) — looks up via `GradeId` - [Account](/docs/reference/entities/account/) — looks up via `PayrollCompanyId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — looks up via `ExpenseAdvanceId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ResourceCompensation](/docs/reference/entities/resource-compensation/) — looks up via `ResourceCompensationId` - [KYCDocument](/docs/reference/entities/kycdocument/) — looks up via `KYCDocumentId` - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — referenced by via `EmployeeId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `EmployeeId` - [SalaryComponent](/docs/reference/entities/salary-component/) — referenced by via `EmployeeId` - [ResourceAvailability](/docs/reference/entities/resource-availability/) — referenced by via `EmployeeId` - [PaymentSalaryDisbursement](/docs/reference/entities/payment-salary-disbursement/) — referenced by via `EmployeeId` - [Payslip](/docs/reference/entities/payslip/) — referenced by via `EmployeeId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `EmployeeId` - [SalaryStructure](/docs/reference/entities/salary-structure/) — referenced by via `EmployeeId` - [PartnerResource](/docs/reference/entities/partner-resource/) — referenced by via `EmployeeId` - [KYCDocument](/docs/reference/entities/kycdocument/) — referenced by via `EmployeeId` - [ResourceCompensation](/docs/reference/entities/resource-compensation/) — referenced by via `EmployeeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # ESI Rule — entity reference URL: https://xmatix.com/docs/reference/entities/esirule/ Last reviewed: 2026-08-16 The Employees' State Insurance rule master for a company: the gross-wage eligibility threshold above which ESI does not apply at all, plus the employee and employer contribution rates, effective-dated. As with PFRule, a deterministic ESI calculator exists (nil above the threshold, otherwise gross times the rate) but the payroll calculation engine does not consult this master — ESI on a payslip comes from an ordinary salary-structure component. Use this entity to answer what the company's configured ESI eligibility and rates are, not to explain or reconcile a specific ESI deduction in a run. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EffectiveFrom` | Effective From | Date | | The date the rule is meant to take effect. Nothing selects ESI rules by date, and the payroll run does not read this master at all, so it records the change rather than applying it. | | `EmployeeRate` | Employee Rate | Currency | | The employee's contribution as a percentage of gross wage, applied to the WHOLE gross rather than to a capped slice — ESI has an eligibility threshold, not a wage ceiling. Used by the platform's ESI helper, which the payroll run does not call. | | `EmployerRate` | Employer Rate | Currency | | The employer's contribution as a percentage of the same full gross wage, and likewise nil once gross exceeds the threshold. | | `GLAccountName` | Name | Text, unique | Yes | ESI posting accounts come from the PayrollComponent master's GL mappings and from the ESI payable control account. Do not filter or join on this field. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `WageThreshold` | Wage Threshold | Currency | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this ESIRule. | | `DeleteListHeader` | Delete | Delete | DeleteEntity | | `Edit` | Edit | Edit | Edit this ESIRule. | | `EditInLine` | EDIT | EditInline | EDIT | | `New` | New | New | Create a ESIRule. | | `View` | View | View | View this ESIRule. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # E-Way Bill — entity reference URL: https://xmatix.com/docs/reference/entities/eway-bill/ Last reviewed: 2026-08-16 An e-way bill (Rule 138) for a movement of goods - one register entry per generated bill, linked polymorphically to its source document via SourceEntityName/SourceRecordId (invoice, delivery order, transfer) and to the GSTRegistration, branch and company it was generated under. Created as Draft with its Part A consignment payload built from the source document; when the NIC/GSP generation result arrives the EWB number, generated date, Part B transport payload and raw response are recorded and validity is computed by the NIC rule of one day per 200 km or part thereof (minimum one day). Status runs Draft, Generated, Cancelled, Expired; the service also lists the register per company/GSTIN/date range and surfaces bills expiring within a window for expiry alerts. Portal transport happens through the connector integration, not through this record. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `ChallanType` | Challan Type | Text | | Returnable or Non-Returnable - the delivery-challan classification carried into the Part A payload for challan-based movements (job work, stock transfer) rather than tax-invoice movements. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DistanceKm` | Distance Km | Number | | | | `DocumentDate` | Document Date | Date | | | | `DocumentNumber` | Document Number | Text | | | | `DocumentType` | Document Type | Text | | | | `EwbNumber` | Ewb Number | Text | | | | `GeneratedDate` | Generated Date | Date | | | | `GspResponse` | Gsp Response | Text | | | | `GSTRegistrationId` | GST Registration | Lookup → [GSTRegistration](/docs/reference/entities/gstregistration/) | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartAPayload` | PartA Payload | Text | | The Part A consignment JSON built at creation (supply type, document type/number/date, total invoice value, transport distance, challan type) - the payload half describing WHAT moves; Part B (PartBPayload) carries the transport details and is recorded with the generation result. | | `PartBPayload` | PartB Payload | Text | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SourceEntityName` | Source Entity Name | Text | | Polymorphic source-document pointer (with SourceRecordId): the entity name of the document the bill covers, such as an invoice, delivery order or transfer. | | `SourceRecordId` | Source Record | Guid | | | | `Status` | Status | Text | | Lifecycle: Draft (register entry created with Part A payload), Generated (EWB number recorded, validity computed), Cancelled, Expired. Expiry alerts scan Generated bills whose ValidUpto falls within the warning window. | | `SubSupplyType` | Sub Supply Type | Text | | | | `SupplyType` | Supply Type | Text | | | | `TotalValue` | Total Value | Currency | | | | `TransporterId` | Transporter | Text | | | | `TransporterName` | Transporter Name | Text | | | | `TransportMode` | Transport Mode | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `ValidUpto` | Val Upto | Date | | Validity end computed at generation from the NIC rule: one day per 200 km of transport distance or part thereof, minimum one day, counted from the generation date. | | `VehicleNumber` | Vehicle Number | Text | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GSTRegistration](/docs/reference/entities/gstregistration/) — looks up via `GSTRegistrationId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Exchange Rate — entity reference URL: https://xmatix.com/docs/reference/entities/exchange-rate/ Last reviewed: 2026-08-16 A conversion rate between two currency codes effective from a date: one unit of fromCurrency equals rate units of toCurrency. rateType distinguishes Spot, Average and Closing rates - period-end currency revaluation consumes the Closing rate and P&L translation the Average rate. Rows are keyed to their owning company via partnerAccountId. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `EffectiveDate` | Effective Date | DateAndTime | | | | `FromCurrency` | From Currency | Text | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Rate` | Rate | Currency | | | | `RateType` | Rate Type | Text | | Spot, Average or Closing. Period-end currency revaluation reads the Closing rate and P&L translation the Average rate, so the same currency pair typically needs rows of more than one type. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ToCurrency` | To Currency | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Executive Position — entity reference URL: https://xmatix.com/docs/reference/entities/executive-position/ Last reviewed: 2026-08-16 The dated record of who occupies a Position and over what window; a seat's ownership history is the set of these rows, not a separate audit trail. A handover closes the current row by stamping Effective To and inserts a new one - rows are not edited in place - and validation enforces at most one open row per seat with no overlapping windows, though one person may hold several seats at once to cover vacancies. Saving an assignment change cascades inside the same save: the affected seats' cached route assignee and open future visit plans are re-pointed to the seat's current holder. Handovers dated in the future are deliberately left alone at save time and applied by a nightly reconcile job on the day they take effect. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AssignmentReason` | Assignment Reason | MultiLineText | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | | | | `EffectiveFrom` | Effective From | DateAndTime | | When this holder takes the seat; it defaults to today's date when a new assignment is saved without one. Validation requires Effective To, when set, to be strictly later, and rejects any window that overlaps another assignment on the same seat. | | `EffectiveTo` | Effective To | DateAndTime | | Empty = the current holder of the seat. | | `ExecutiveResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | The person holding the seat, pointing at Resource rather than at Employee or a login user - seats are held by resources, and the route and plan cascade re-points work to this resource id. Saving an assignment without it is rejected. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PositionId` | Position | Lookup → [Position](/docs/reference/entities/position/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInList` | Edit | EditInline | Edit In List Header | | `New` | New | New | New | ## Related entities - [Position](/docs/reference/entities/position/) — looks up via `PositionId` - [Resource](/docs/reference/entities/resource/) — looks up via `ExecutiveResourceId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Advance Settlement — entity reference URL: https://xmatix.com/docs/reference/entities/expense-advance-settlement/ Last reviewed: 2026-08-16 One settlement event on an ExpenseAdvance, written automatically by the advance actions rather than entered by hand: SettleAgainstClaim writes a row with settlementType AgainstClaim (linking the ExpenseClaim), RecoverAdvance writes CashReturn; PayrollRecovery exists in the vocabulary. Each row carries the settled amount, date and the posting journal (journalId), forming the audit trail of how an advance was cleared. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExpenseAdvanceId` | Expense Advance | Lookup → [ExpenseAdvance](/docs/reference/entities/expense-advance/) | | | | `ExpenseClaimId` | Expense Claim | Lookup → [ExpenseClaim](/docs/reference/entities/expense-claim/) | | | | `Id` | Id | Guid | Yes | | | `JournalId` | Journal | Lookup → [Journal](/docs/reference/entities/journal/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SettledAmount` | Settled Amount | Currency | | | | `SettlementDate` | Settlement Date | Date | | | | `SettlementType` | Settlement Type | Text | | How the advance balance was cleared: AgainstClaim (applied to a posted claim's payable), CashReturn (employee returned cash to bank), or PayrollRecovery. Rows are written by the settle/recover actions, not entered by hand. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this ExpenseAdvanceSettlement. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this ExpenseAdvanceSettlement. | | `EditInLine` | Edit | EditInline | Edit | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a ExpenseAdvanceSettlement. | | `NewInLine` | New | NewInline | NewInLine | | `View` | View | View | View this ExpenseAdvanceSettlement. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — looks up via `ExpenseAdvanceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Journal](/docs/reference/entities/journal/) — looks up via `JournalId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — looks up via `ExpenseClaimId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Expense Advance — entity reference URL: https://xmatix.com/docs/reference/entities/expense-advance/ Last reviewed: 2026-08-16 A cash advance paid to an employee (Resource) before travel or work - the mirror image of a claim: the employee owes the company. Paying it (PostAdvance) posts Dr Employee Advance / Cr Bank and raises a recoverable (Receivable-direction) OpenTransaction keyed on the ResourceId. It is then settled against a posted claim (SettleAgainstClaim reduces both the claim's payable and the advance's outstanding balance) or recovered in cash (RecoverAdvance). Status runs Requested, Approved, Paid, PartiallySettled, Settled, Recovered; each settlement or recovery writes an ExpenseAdvanceSettlement row with its journal. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AdvanceDate` | Advance Date | Date | Yes | | | `Amount` | Amount | Currency | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `CostCenterId` | Cost Center | Lookup → [CostCenter](/docs/reference/entities/cost-center/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EmployeeId` | Employee | Lookup → [Employee](/docs/reference/entities/employee/) | | | | `ExpenseClaimId` | Expense Claim | Lookup → [ExpenseClaim](/docs/reference/entities/expense-claim/) | | Optional link to the claim this advance is intended for; used as the default claim by the Settle Against Claim action when no expenseClaimId argument is passed. | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | Yes | The bank/payment GL account used as the default for the Pay Advance and Recover Advance actions when no glAccountId argument is supplied. Not the Employee Advance control account - that is resolved from GLControlType.EmployeeAdvance. | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OpenTransactionId` | Open Transaction | Lookup → [OpenTransaction](/docs/reference/entities/open-transaction/) | | Points at the Receivable-direction Employee-Advance open item raised when the advance was paid - the per-employee subledger row that settlements and recoveries draw down. | | `OutstandingAmount` | Outstanding Amount | Currency | | The recoverable balance still owed by the employee: set to the full amount when the advance is paid, reduced by every settlement against a claim and every cash recovery. Zero flips the status to Settled or Recovered. Derived - do not edit. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `ProjectId` | Project | Lookup → [Project](/docs/reference/entities/project/) | | | | `PurposeText` | Purpose | Text | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | The employee as a Resource - required before the advance can be paid; the Employee-Advance open item is keyed on it, matching the claim-side keying. | | `Status` | Status | Text | | Advance lifecycle: Requested, Approved, Paid (set when the advance posts), PartiallySettled, Settled (fully applied to claims), Recovered (unspent balance returned in cash). Settle and recover both require the advance to be paid first, and a Settled/Recovered advance cannot be settled again. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this ExpenseAdvance. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this ExpenseAdvance. | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a ExpenseAdvance. | | `PostAdvance` | Pay Advance | ServerAction (`PostAdvance`) | Pays the advance to the employee: Dr Employee Advance (the CurrentAssets-typed EmployeeAdvance control account) / Cr the bank account (glAccountId argument or the advance's own glAccountId), raising a recoverable open item keyed on the Resource and stamping status Paid with outstandingAmount set to the full amount. Validation requires a bank account, a positive amount, and refuses an advance already paid (glId set). | | `RecoverAdvance` | Recover Advance | ServerAction (`RecoverAdvance`) | Books the employee returning unspent advance money: Dr Bank (glAccountId argument or the advance's glAccountId) / Cr Employee Advance for the amount argument (default: the whole open balance). Reduces the open item, updates outstandingAmount, sets status Recovered when nothing remains (PartiallySettled otherwise), and writes a CashReturn ExpenseAdvanceSettlement row. Requires a paid advance and a valid amount within the open balance. | | `SettleAgainstClaim` | Settle Against Claim | ServerAction (`SettleAgainstClaim`) | Applies the advance to a posted claim: Dr Employee Payable / Cr Employee Advance for the settlement amount (the amount argument, defaulting to the smaller of the two open balances, always capped at the advance's open balance). Reduces both open items, updates the advance's outstandingAmount/status and the claim's advanceAdjustedAmount/netReimbursableAmount (marking the claim Paid/Settled if fully covered), and writes an AgainstClaim ExpenseAdvanceSettlement row. Requires the advance to be paid, not already fully settled, and a claim id (argument or the advance's expenseClaimId); fails if the amount exceeds the claim's open balance. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Amount Validation | `Amount`, Error | Amount can not be zero or less than zero. | Amount can not be zero or less than zero. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `BranchId` | | | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [Employee](/docs/reference/entities/employee/) — looks up via `EmployeeId` - [Project](/docs/reference/entities/project/) — looks up via `ProjectId` - [CostCenter](/docs/reference/entities/cost-center/) — looks up via `CostCenterId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — looks up via `OpenTransactionId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — looks up via `ExpenseClaimId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [InterestCharge](/docs/reference/entities/interest-charge/) — referenced by via `SourceRecordId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [ExpenseAdvanceSettlement](/docs/reference/entities/expense-advance-settlement/) — referenced by via `ExpenseAdvanceId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `SourceRecordId` - [Employee](/docs/reference/entities/employee/) — referenced by via `ExpenseAdvanceId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Expense Category — entity reference URL: https://xmatix.com/docs/reference/entities/expense-category/ Last reviewed: 2026-08-16 The expense spend taxonomy (Travel, Hotel, Meals, Fuel and similar) referenced by claim lines, card transactions and policy rules. Its policy-looking defaults (dailyLimit, monthlyLimit, receiptRequired, approvalRequired, gstEligibleDefault, isBillableDefault) are declarative master data - no posting or policy-engine code reads them; actual enforcement comes from ExpensePolicyRule thresholds. What IS enforced is deactivation: an inactive category raises a Block-severity violation at policy evaluation and the claim posting refuses to post lines that use one. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApprovalRequired` | Approval Required | Boolean | | | | `Code` | Code | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DailyLimit` | Daily Limit | Currency | | Declarative per-day cap for the category. No posting or policy-engine code reads it - enforceable caps must be configured as ExpensePolicyRule rows (CategoryLimit) with a threshold. | | `DefaultGLAccountId` | DefaultGL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | Yes | The expense GL account this category maps to for account determination. What actually posts is the line's own expenseGLAccountId - this default is where that value comes from when defaulting, not what posting reads. | | `Description` | Description | Text | | | | `GLAccountName` | Name | Text, unique | Yes | | | `GstEligibleDefault` | Gst Eligible Default | Boolean | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `IsBillableDefault` | Is Billable Default | Boolean | | | | `IsReimbursable` | Is Reimbursable | Boolean | | Marks whether spend in this category is meant to be paid back to employees (versus tracked-only spend). Informational master data; the posting path does not filter lines on it. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `MonthlyLimit` | Monthly Limit | Currency | | Declarative per-month cap for the category. Like dailyLimit it is not read by the policy engine or posting; use an ExpensePolicyRule for actual enforcement. | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `ReceiptRequired` | Receipt Required | Boolean | | Declarative default only - the enforced receipt check is the ReceiptMandatoryAbove policy rule, which tests the claim line's receiptFileAssetId against the rule threshold; this flag itself is not read by the engine. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this ExpenseCategory. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this ExpenseCategory. | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a ExpenseCategory. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `DefaultGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ExpensePolicyRule](/docs/reference/entities/expense-policy-rule/) — referenced by via `ExpenseCategoryId` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — referenced by via `ExpenseCategoryId` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — referenced by via `ExpenseCategoryId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Expense Claim Line — entity reference URL: https://xmatix.com/docs/reference/entities/expense-claim-line/ Last reviewed: 2026-08-16 One expense position on an ExpenseClaim: the expense GL account debited (expenseGLAccountId), amount and GST, the ExpenseCategory, merchant/invoice details, payment mode, cost dimensions (project, cost centre, branch) and the receipt file. Posting only picks up lines that have an expense GL account and a non-zero amount+tax; ITC-eligible tax is debited to the Input GST control account instead of the expense head, with the cgst/sgst/igst/cess split captured as tax analytics. Also carries the billable-recharge fields (isBillableToCustomer, customerAccountId, markupPercent, billingStatus, rechargeInvoiceId) and the policy outcome flags (policyViolationFlag, duplicateFlag, disallowedAmount). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | | | `ApprovedAmount` | Approved Amount | Currency | | | | `BillingStatus` | Billing Status | Text | | Recharge pipeline state: NotBillable, PendingBilling (set by Compute Recharge), Billed (set by Link Recharge Invoice together with rechargeInvoiceId). Generating the actual customer invoice document is a separate sales-invoice flow. | | `BlockedCreditReason` | Blocked Credit Reason | Text | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `Cess` | Cess | Currency | | | | `Cgst` | Cgst | Currency | | | | `CostCenterId` | Cost Center | Lookup → [CostCenter](/docs/reference/entities/cost-center/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `CustomerAccountId` | Customer Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Description` | Description | Text | | | | `DisallowedAmount` | Disallowed Amount | Currency | | The portion of the line finance will not reimburse. Policy rules with the AutoDisallow action add each over-limit excess to it automatically during evaluation; it can also be set in finance review. | | `DuplicateFlag` | Duplicate Flag | Boolean | | Set by the DuplicateDetection policy rule when another line with the same merchant, invoice number and amount exists on this claim or on a prior claim by the same employee (matched via the claim's resourceId). | | `ExpenseCategoryId` | Expense Category | Lookup → [ExpenseCategory](/docs/reference/entities/expense-category/) | | | | `ExpenseClaimId` | Expense Claim | Lookup → [ExpenseClaim](/docs/reference/entities/expense-claim/) | | | | `ExpenseDate` | Expense Date | Date | | | | `ExpenseGLAccountId` | Expense GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The expense head debited when the claim posts. Lines without it (or with a zero amount+tax) are skipped by posting entirely, so a claim whose lines all lack it cannot post. | | `GLAccountName` | Name | Text, unique | Yes | | | `HsnSacCode` | Hsn Sac Code | Text | | | | `Id` | Id | Guid | Yes | | | `Igst` | Igst | Currency | | | | `InvoiceDate` | Invoice Date | Date | | | | `InvoiceNumber` | Invoice Number | Text | | | | `IsBillableToCustomer` | Is Billable To Customer | Boolean | | Marks the line as rechargeable to a client. The Compute Recharge action only considers lines with this flag AND a customerAccountId, moving their billingStatus to PendingBilling and totalling them per customer and project. | | `ItcCategory` | Itc Category | Text | | GST input-credit classification of the line: Input, InputService, CapitalGoods or ImportIgst. | | `ItcEligible` | Itc Eligible | Boolean | | When true (and the line has tax), claim posting debits the tax to the Input GST control account rather than the expense head, and captures per-component TaxTransaction analytics for the input-credit trail. Posting fails if no TaxCredit control account is configured. | | `LineNumber` | Line Number | Number | | | | `LineStatus` | Line Status | Text | | Per-line review outcome: Pending, Approved, PartiallyApproved, Rejected. Line-level state for finance review, independent of the header's lifecycle Status. | | `MarkupPercent` | Markup Percent | Currency | | Recharge markup on a billable line: the recharge amount is (amount + tax) * (1 + markupPercent/100), computed by the Compute Recharge action. | | `MerchantName` | Merchant Name | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PaymentMode` | Payment Mode | Text | | How the expense was paid out of pocket: Cash, PersonalCard, CompanyCard, UPI or Bank. Distinguishes employee-payable spend from company-card spend, which is posted from CompanyCardTransaction against the card-payable liability instead. | | `PlaceOfSupply` | Place Of Supply | Text | | | | `PolicyViolationFlag` | Policy Violation Flag | Boolean | | | | `ProjectId` | Project | Lookup → [Project](/docs/reference/entities/project/) | | | | `ReceiptFileAssetId` | Receipt File Asset | Lookup | | The attached receipt/proof file (a FileAsset; the binary is in blob storage). This exact field is what the ReceiptMandatoryAbove policy rule checks - a line over the threshold with this empty raises the violation. Richer OCR metadata lives on ExpenseReceipt rows. | | `RechargeInvoiceId` | Recharge Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Sgst` | Sgst | Currency | | | | `SupplierGstin` | Supplier GSTIN | Text | | | | `TaxAmount` | Tax Amount | Currency | | GST on the line. For ITC-eligible lines it is debited to the Input GST (TaxCredit) control account instead of the expense head; the cgst/sgst/igst/cess component fields should sum to it, and an un-split tax amount is captured as IGST in the tax analytics. | | `TaxInvoiceAvailable` | Tax Invoice Available | Boolean | | | | `TdsApplicable` | Tds Applicable | Boolean | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this ExpenseClaimLine. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this ExpenseClaimLine. | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a ExpenseClaimLine. | | `NewInLine` | New | NewInline | New | | `View` | View | View | View this ExpenseClaimLine. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `ExpenseGLAccountId` - [CostCenter](/docs/reference/entities/cost-center/) — looks up via `CostCenterId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `RechargeInvoiceId` - [ExpenseCategory](/docs/reference/entities/expense-category/) — looks up via `ExpenseCategoryId` - [Account](/docs/reference/entities/account/) — looks up via `CustomerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Project](/docs/reference/entities/project/) — looks up via `ProjectId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — looks up via `ExpenseClaimId` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — referenced by via `ExpenseClaimLineId` - [ExpenseReceipt](/docs/reference/entities/expense-receipt/) — referenced by via `ExpenseClaimLineId` - [ExpensePolicyViolation](/docs/reference/entities/expense-policy-violation/) — referenced by via `ExpenseClaimLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Expense Claim — entity reference URL: https://xmatix.com/docs/reference/entities/expense-claim/ Last reviewed: 2026-08-16 An employee reimbursement claim, anchored on the claimant Resource (resourceId - the same person key HR/payroll use; employeeAccountId is the legacy Account-based key). Expense heads live on child ExpenseClaimLine rows. It carries three independent status fields: Status (the lifecycle: Draft, Submitted, ManagerApproved, FinanceReview, ApprovedForPayment, ApprovedForPayroll, Posted, PartiallyPaid, Paid, Settled, Rejected, ReturnedForCorrection, Cancelled), PostingStatus (NotPosted/Posted/Reversed/Failed) and PaymentStatus (Unpaid/Partial/Paid). Approval routes through the finance-wide ApprovalProcess engine; a decision listener mirrors the outcome onto ApprovalStatus/Status and on final approval automatically posts the claim: Dr expense heads (plus Dr Input GST for ITC-eligible lines) / Cr Employee Payable, raising an Employee-Payable OpenTransaction keyed on the ResourceId. Reimbursement then settles that open item - singly (PostReimbursement), in a batch (ExpenseReimbursementBatch), through payroll (reimbursementMode Payroll), or by adjusting an ExpenseAdvance. Policy checks write ExpensePolicyViolation rows and set hasPolicyViolation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AdvanceAdjustedAmount` | Advance Adjusted Amount | Currency | | Cumulative amount of employee advances applied to this claim. Each advance settlement adds to it; at posting time the employee payable raised is the gross claim minus this amount, and posting fails if the advance already covers the whole claim (settle via the advance instead). | | `ApprovalStatus` | Approval Status | Text | | Thin mirror of the approval-engine outcome (Pending, Approved, Rejected), stamped by the decision listener - the routing itself lives in ApprovalProcess/ApprovalRequest, not on the claim. A recalled request clears it to empty; a reverted approval sets it back to Pending. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `ClaimDate` | Claim Date | Date | | | | `ClaimPeriodFrom` | Claim Period From | Date | | | | `ClaimPeriodTo` | Claim Period To | Date | | | | `CostCenterId` | Cost Center | Lookup → [CostCenter](/docs/reference/entities/cost-center/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrencyCode` | Currency Code | Text | | | | `DepartmentId` | Department | Lookup | | | | `EmployeeAccountId` | Employee Account | Lookup → [Account](/docs/reference/entities/account/) | | Legacy claimant key pointing at a CRM Account in the employee role. The canonical anchor is resourceId; the expense posting and open-item machinery key on the Resource, not this Account. | | `EmployeeId` | Employee | Lookup → [Employee](/docs/reference/entities/employee/) | | | | `EmployeePayableOpenTransactionId` | Employee Payable Open Transaction | Lookup → [OpenTransaction](/docs/reference/entities/open-transaction/) | | Points at the Employee-Payable OpenTransaction (per-employee subledger row) raised when the claim posted. Reimbursement, batch payment, payroll settlement and advance settlement all resolve the open item through this pointer, falling back to a lookup by source entity and record. | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | The posting journal of the claim. A non-empty value means the claim has hit the ledger - posting treats it as already-posted and refuses to post again. | | `HasPolicyViolation` | Has Policy Violation | Boolean | | Set by policy evaluation: true when the run recorded any ExpensePolicyViolation rows for the claim, false when it recorded none. A summary flag only - the detail (rule, severity, excess) lives on the violation rows. | | `Id` | Id | Guid | Yes | | | `IncludedInPayrollRunId` | Included In Payroll Run | Lookup → [PayrollRun](/docs/reference/entities/payroll-run/) | | | | `IsGLPosted` | Is GL Posted | Boolean | | | | `IsGLPostingApproved` | Is GL Posting Approved | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `Narration` | Narration | Text | | | | `NetReimbursableAmount` | Net Reimbursable Amount | Currency | | The amount actually payable to the employee: recomputed at posting as gross (amount+tax over postable lines) minus advanceAdjustedAmount, then reduced further by any later advance settlements. Derived - do not set it by hand. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PaymentGLAccountId` | PaymentGL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The GL account credited for the claim total - the employee-payable control, or cash/bank if paid immediately. Also serves as the default bank account for the Reimburse action when no bankGLAccountId argument is passed. | | `PaymentStatus` | Payment Status | Text | | Settlement state of the employee payable: Unpaid, Partial, Paid. Set to Paid by finance reimbursement, batch reimbursement, payroll settlement, or when advance adjustments fully cover the payable. Distinct from the lifecycle Status, which moves to Settled at the same moments. | | `PayrollComponentId` | Payroll Component | Lookup → [PayrollComponent](/docs/reference/entities/payroll-component/) | | | | `PayrollPeriodId` | Payroll Period | Lookup → [PayrollPeriod](/docs/reference/entities/payroll-period/) | | | | `PolicyId` | Policy | Lookup → [ExpensePolicy](/docs/reference/entities/expense-policy/) | | | | `PostingStatus` | Posting Status | Text | | Ledger state of the claim: NotPosted, Posted, Reversed, Failed. Posted (or a non-empty glId) is the idempotency guard - posting refuses a claim that is already Posted, and the approval listener skips auto-posting when it sees it. | | `ProjectId` | Project | Lookup → [Project](/docs/reference/entities/project/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReimbursementMode` | Reimbursement Mode | PickList | | Where the approved claim gets paid: FinancePayment (settled by a finance/treasury payment) or Payroll (handed to a payroll run as Payroll Payable). Finance reimbursement refuses Payroll-mode claims, and the approval listener chooses ApprovedForPayroll vs ApprovedForPayment from this field. Values: Cash, Bank Transfer. | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | The claimant as a Resource - the canonical employee key shared with HR and payroll. Posting refuses a claim without it, and the Employee-Payable open item is keyed on it (not on an Account), which is also how duplicate detection finds the employee's prior claims. | | `Status` | Status | Text | | The claim lifecycle: Draft, Submitted, ManagerApproved, FinanceReview, ApprovedForPayment, ApprovedForPayroll, Posted, PartiallyPaid, Paid, Settled, Rejected, ReturnedForCorrection, Cancelled. Moved by the approval listener (ApprovedForPayment or ApprovedForPayroll depending on reimbursementMode, Rejected, back to Draft on recall, Submitted on revert), by posting (Posted) and by settlement (Settled). It is one of three independent status fields - do not confuse it with postingStatus or paymentStatus. | | `TaxablePerquisiteFlag` | Taxable Perquisite Flag | Boolean | | Payroll-bridge marker: flags the reimbursement as a taxable perquisite for the payroll module that consumes Payroll-mode claims. The expense posting itself does not read it. | | `TotalAmount` | Total Amount | Currency | | | | `TotalApprovedAmount` | Total Approved Amount | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `ComputeRecharge` | Compute Recharge | ServerAction (`ComputeRecharge`) | Collects the claim's billable lines (isBillableToCustomer with a customerAccountId), moves their billingStatus to PendingBilling, and returns totals grouped by customer and project: raw cost (amount+tax) versus recharge (cost with each line's markupPercent applied) and the line count. No journal and no invoice are created - invoice generation is a separate sales flow. | | `Delete` | Delete | Delete | Delete this ExpenseClaim. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this ExpenseClaim. | | `EditInLine` | Edit | EditInline | Edit | | `EditRecord` | Edit | Edit | Edit | | `EvaluatePolicy` | Evaluate Policy | ServerAction (`EvaluatePolicy`) | Runs the policy engine against the claim: gathers every active rule of active policies matching the tenant, the claimant's grade and the claim date, checks the six enforced rule types (category/grade-hotel limits, receipt-mandatory-above, blocked category, late submission, duplicate detection) plus the automatic inactive-category guard, writes ExpensePolicyViolation rows, sets policyViolationFlag/duplicateFlag on offending lines, adds AutoDisallow excesses to disallowedAmount, and sets the claim's hasPolicyViolation. Returns the violation list with blocked and requires-higher-approval indicators. Evaluation records and flags - run it before submission/approval so disallowances reach the posted amount. | | `LinkRechargeInvoice` | Link Recharge Invoice | ServerAction (`LinkRechargeInvoice`) | Stamps the generated customer invoice onto the claim's billable lines: requires a rechargeInvoiceId argument, sets it on every billable line and marks them Billed. Purely a linkage/status update - the invoice itself must already exist. | | `New` | New | New | Create a ExpenseClaim. | | `PostClaim` | Post | ServerAction (`PostClaim`) | Posts the claim to the ledger. Preconditions: not already posted, a claimant resourceId, at least one line with an expense GL account and non-zero amount, no deactivated expense categories, and an EmployeePayable control account configured. Effects: a journal debiting each expense head (ITC-eligible tax goes to the Input GST control instead), crediting Employee Payable for gross minus advanceAdjustedAmount; an Employee-Payable open item keyed on the Resource; best-effort GST/ITC analytics capture; stamps glId, postingStatus Posted, status Posted, totals and paymentStatus Unpaid. Fails if the advance adjustment covers the whole claim. Note this also runs automatically on final approval via the approval decision listener - manual use is mainly recovery when auto-posting failed. | | `PostReimbursement` | Reimburse | ServerAction (`PostReimbursement`) | Pays a posted claim from the bank: Dr Employee Payable / Cr Bank for the full open payable balance, settling the open item and stamping the claim Paid/Settled. Uses the bankGLAccountId argument, falling back to the claim's paymentGLAccountId. Refuses claims that are unposted, already fully paid, or set to reimbursementMode Payroll (those settle through the payroll run). | | `SettleViaPayroll` | Settle via Payroll | ServerAction (`SettleClaimViaPayroll`) | Hands a posted Payroll-mode claim to payroll: Dr Employee Payable / Cr Payroll Payable, settling the expense open item, tagging includedInPayrollRunId and stamping the claim Paid/Settled - the salary payment then discharges Payroll Payable, and the claim is NOT re-accrued as a payroll earning. Requires a posted claim with an open payable and a PayrollPayable control account. Note the underlying handler registers this operation under the name SettleClaimViaPayroll; the reliable path is automatic - the payroll-run integration pulls every posted, unpaid Payroll-mode claim of the run's employees and performs this settlement per claim. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `BranchId` | | | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [PayrollComponent](/docs/reference/entities/payroll-component/) — looks up via `PayrollComponentId` - [ExpensePolicy](/docs/reference/entities/expense-policy/) — looks up via `PolicyId` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [PayrollRun](/docs/reference/entities/payroll-run/) — looks up via `IncludedInPayrollRunId` - [Employee](/docs/reference/entities/employee/) — looks up via `EmployeeId` - [CostCenter](/docs/reference/entities/cost-center/) — looks up via `CostCenterId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — looks up via `EmployeePayableOpenTransactionId` - [Project](/docs/reference/entities/project/) — looks up via `ProjectId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [PayrollPeriod](/docs/reference/entities/payroll-period/) — looks up via `PayrollPeriodId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `PaymentGLAccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `EmployeeAccountId` - [ExpenseReimbursementBatchLine](/docs/reference/entities/expense-reimbursement-batch-line/) — referenced by via `ExpenseClaimId` - [InterestCharge](/docs/reference/entities/interest-charge/) — referenced by via `SourceRecordId` - [Employee](/docs/reference/entities/employee/) — referenced by via `ExpenseClaimId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `SourceRecordId` - [ExpensePolicyViolation](/docs/reference/entities/expense-policy-violation/) — referenced by via `ExpenseClaimId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `ExpenseClaimId` - [ExpenseAdvanceSettlement](/docs/reference/entities/expense-advance-settlement/) — referenced by via `ExpenseClaimId` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — referenced by via `ExpenseClaimId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Expense Policy Rule — entity reference URL: https://xmatix.com/docs/reference/entities/expense-policy-rule/ Last reviewed: 2026-08-16 One rule inside an ExpensePolicy: a ruleType, an optional ExpenseCategory scope (empty = all categories), a numeric threshold, and the action taken on breach (HardBlock, Warn, RequireHigherApproval, AutoDisallow). The evaluation engine currently enforces six rule types: CategoryLimit and GradeHotelLimit (line amount+tax over the threshold), ReceiptMandatoryAbove (over the threshold with no receipt attached), BlockedCategory (any line in the category), LateSubmissionDays (expense date older than the threshold in days at the claim date) and DuplicateDetection (same merchant + invoice number + amount within the claim or on the employee's prior claims). The vocabulary also defines CityClassLimit, ForeignTravelCap and MileageRate, but the engine has no evaluation for them - rules of those types record no violations and enforce nothing. An InactiveCategory violation is raised automatically for lines using a deactivated category, independent of any configured rule. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Action` | Action | Text | | What a breach does: HardBlock marks the evaluation blocked (Block severity), Warn only records the violation, RequireHigherApproval flags the evaluation as needing an extra approval step, AutoDisallow adds the excess to the line's disallowedAmount. All actions record an ExpensePolicyViolation. | | `CityClass` | City Class | Text | | Intended scoping attribute for city-class caps (metro vs non-metro). | | `Country` | Country | Text | | Intended scoping attribute for country-specific foreign-travel caps. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExpenseCategoryId` | Expense Category | Lookup → [ExpenseCategory](/docs/reference/entities/expense-category/) | Yes | Scopes the rule to lines of one ExpenseCategory; empty means the rule checks every line of the claim. | | `ExpensePolicyId` | Expense Policy | Lookup → [ExpensePolicy](/docs/reference/entities/expense-policy/) | | | | `GLAccountName` | Name | Text, unique | Yes | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RuleType` | Rule Type | Text | | Which check the rule performs. Enforced by the evaluation engine: CategoryLimit, GradeHotelLimit, ReceiptMandatoryAbove, BlockedCategory, LateSubmissionDays, DuplicateDetection. InactiveCategory appears on violations raised automatically for deactivated categories rather than being configured as a rule. | | `Threshold` | Threshold | Currency | | The numeric trigger, interpreted per ruleType: an amount cap for CategoryLimit/GradeHotelLimit (compared to line amount+tax), an amount floor for ReceiptMandatoryAbove, or a day count for LateSubmissionDays. Ignored by BlockedCategory and DuplicateDetection. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this ExpensePolicyRule. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this ExpensePolicyRule. | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a ExpensePolicyRule. | | `NewInLine` | New | NewInline | NewInLine | | `View` | View | View | View this ExpensePolicyRule. | ## Related entities - [ExpenseCategory](/docs/reference/entities/expense-category/) — looks up via `ExpenseCategoryId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [ExpensePolicy](/docs/reference/entities/expense-policy/) — looks up via `ExpensePolicyId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ExpensePolicyViolation](/docs/reference/entities/expense-policy-violation/) — referenced by via `ExpensePolicyRuleId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Policy Violation — entity reference URL: https://xmatix.com/docs/reference/entities/expense-policy-violation/ Last reviewed: 2026-08-16 The audit record written when policy evaluation finds a breach on a claim or a specific claim line: the rule (expensePolicyRuleId), ruleType, severity (Info, Warning, Block), a message, and the excess amount for over-limit breaches. overriddenById/overrideReason record a manual override. Evaluating a claim appends new violation rows and sets the claim's hasPolicyViolation flag. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExcessAmount` | Excess Amount | Currency | | For over-limit breaches, the amount above the threshold (also what AutoDisallow adds to the line's disallowedAmount); for BlockedCategory it is the full line amount. Empty for checks with no monetary excess. | | `ExpenseClaimId` | Expense Claim | Lookup → [ExpenseClaim](/docs/reference/entities/expense-claim/) | | | | `ExpenseClaimLineId` | Expense Claim Line | Lookup → [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) | | | | `ExpensePolicyRuleId` | Expense Policy Rule | Lookup → [ExpensePolicyRule](/docs/reference/entities/expense-policy-rule/) | | | | `Id` | Id | Guid | Yes | | | `Message` | Message | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OverriddenById` | Overriden By | Lookup | | Who approved proceeding despite the violation, with the justification in overrideReason. Recorded manually - the evaluation engine only writes violations, it does not process overrides. | | `OverrideReason` | Override Reason | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RuleType` | Rule Type | Text | | | | `Severity` | Severity | Text | | Info, Warning or Block. Derived from the breached rule's action: HardBlock produces Block, everything else produces Warning; automatic inactive-category violations are Block. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this ExpensePolicyViolation. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this ExpensePolicyViolation. | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a ExpensePolicyViolation. | ## Related entities - [ExpenseClaim](/docs/reference/entities/expense-claim/) — looks up via `ExpenseClaimId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — looks up via `ExpenseClaimLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ExpensePolicyRule](/docs/reference/entities/expense-policy-rule/) — looks up via `ExpensePolicyRuleId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Expense Policy — entity reference URL: https://xmatix.com/docs/reference/entities/expense-policy/ Last reviewed: 2026-08-16 A named set of expense rules (child ExpensePolicyRule rows) evaluated against a claim by the policy engine. A policy applies when it is active, its effectiveFrom/effectiveTo window covers the claim date, and its gradeId is either empty (all grades) or matches the claimant Resource's grade. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `EffectiveFrom` | Effective From | Date | | Start of the policy's validity window, compared against the claim date (not today) during evaluation; a policy outside its effectiveFrom/effectiveTo window contributes no rules. | | `EffectiveTo` | Effective To | Date | | | | `GLAccountName` | Name | Text, unique | Yes | | | `GradeId` | Grade | Lookup → [Grade](/docs/reference/entities/grade/) | Yes | Optional grade scope: when set, the policy's rules only evaluate for claimants whose Resource carries this grade; empty means the policy applies to all employees. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this ExpensePolicy. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this ExpensePolicy. | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a ExpensePolicy. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Grade](/docs/reference/entities/grade/) — looks up via `GradeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `PolicyId` - [ExpensePolicyRule](/docs/reference/entities/expense-policy-rule/) — referenced by via `ExpensePolicyId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Expense Receipt — entity reference URL: https://xmatix.com/docs/reference/entities/expense-receipt/ Last reviewed: 2026-08-16 Receipt metadata for an ExpenseClaimLine - the binary itself is a FileAsset in blob storage. Holds the OCR-extract fields (merchant, date, amount, invoice number, GSTIN) and a duplicate hash of merchant + invoice + amount + date. The OCR connector that fills the extract fields is not built, so ocrStatus stays Pending unless an external process or a person (Manual) populates them. Note the policy engine's receipt-required check looks at ExpenseClaimLine.receiptFileAssetId, not at this entity. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DuplicateHash` | Duplicate Hash | Text | | Hash of merchant + invoice + amount + date intended for receipt-level duplicate detection. Note the policy engine's DuplicateDetection rule compares the claim-line fields directly rather than this hash. | | `ExpenseClaimLineId` | Expense Claim Line | Lookup → [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) | | | | `ExtractedAmount` | Extracted Amount | Currency | | | | `ExtractedDate` | Extracted Date | Date | | | | `ExtractedGSTIN` | Extracted GSTIN | Text | | | | `ExtractedInvoiceNumber` | Extracted Invoice Number | Text | | | | `ExtractedMerchant` | Extracted Merchant | Text | | | | `FileAssetId` | File Asset | Guid | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OcrStatus` | OCR Status | Text | | Extraction pipeline state: Pending, Extracted, Failed, Manual. The OCR connector that would populate the extracted fields is not built, so rows stay Pending unless filled externally or by hand. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this ExpenseReceipt. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this ExpenseReceipt. | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a ExpenseReceipt. | | `View` | View | View | View this ExpenseReceipt. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — looks up via `ExpenseClaimLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Reimbursement Batch Line — entity reference URL: https://xmatix.com/docs/reference/entities/expense-reimbursement-batch-line/ Last reviewed: 2026-08-16 One claim inside an ExpenseReimbursementBatch, linking the ExpenseClaim and its Resource. On batch posting the line's amount is overwritten with the claim's actual open payable balance and paymentStatus is stamped Paid; utrNumber records the bank payment reference. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `ExpenseClaimId` | Expense Claim | Lookup → [ExpenseClaim](/docs/reference/entities/expense-claim/) | | | | `ExpenseReimbursementBatchId` | Expense Reimbursement Batch | Lookup → [ExpenseReimbursementBatch](/docs/reference/entities/expense-reimbursement-batch/) | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PaymentStatus` | Payment Status | Text | | Pending, Paid or Failed for this claim within the batch; stamped Paid by the batch posting when the claim's payable open item was found and settled. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `UtrNumber` | Utr Number | Text | | Bank payment reference (UTR) for the employee's payout in this batch - recorded for traceability against the bank statement. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this ExpenseReimbursementBatchLine. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this ExpenseReimbursementBatchLine. | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a ExpenseReimbursementBatchLine. | | `NewInLine` | New | NewInline | NewInLine | | `View` | View | View | View this ExpenseReimbursementBatchLine. | ## Related entities - [ExpenseClaim](/docs/reference/entities/expense-claim/) — looks up via `ExpenseClaimId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ExpenseReimbursementBatch](/docs/reference/entities/expense-reimbursement-batch/) — looks up via `ExpenseReimbursementBatchId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Reimbursement Batch — entity reference URL: https://xmatix.com/docs/reference/entities/expense-reimbursement-batch/ Last reviewed: 2026-08-16 A batch reimbursement run: pays several posted claims to their employees in one bank transaction. Posting the batch collects each claim's open Employee-Payable item, aggregates the debits per control account and branch, credits the bank GL for the grand total, then settles every open item and stamps each claim Paid/Settled, each batch line Paid, and the batch itself Paid with the recomputed totalAmount and itemCount. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BankGLAccountId` | Bank GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The bank account credited for the batch total. The posting action's bankGLAccountId argument overrides it; with neither set the batch cannot post. | | `BatchDate` | Batch Date | Date | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | | | `Id` | Id | Guid | Yes | | | `ItemCount` | Item Count | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Reference` | Reference | Text | | | | `Status` | Status | Text | | Draft, Approved, Paid. Paid is stamped by the batch posting together with glId; a batch with glId set is treated as already paid and cannot post again. | | `TotalAmount` | Total Amount | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this ExpenseReimbursementBatch. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this ExpenseReimbursementBatch. | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a ExpenseReimbursementBatch. | | `PostReimbursementBatch` | Pay Batch | ServerAction (`PostReimbursementBatch`) | Pays every claim in the batch with one bank transaction: resolves each line's claim and its open Employee-Payable item (skipping unposted claims and settled payables), aggregates debits per control account and branch, credits the bank (bankGLAccountId argument or the batch's bank account) for the grand total, then settles the open items and stamps claims Paid/Settled, lines Paid, and the batch Paid with recomputed totalAmount and itemCount. Line amounts are overwritten with the actual open balances. Refuses a batch already paid or with nothing payable. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `BankGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [ExpenseReimbursementBatchLine](/docs/reference/entities/expense-reimbursement-batch-line/) — referenced by via `ExpenseReimbursementBatchId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Expense Voucher Line — entity reference URL: https://xmatix.com/docs/reference/entities/expense-voucher-line/ Last reviewed: 2026-08-16 One expense head on an ExpenseVoucher: the expense GL account debited and its amount plus tax. Posting skips lines with no expense GL account or a zero amount+tax; the voucher's credit total is the sum of the remaining line debits. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Description` | Description | Text | | | | `ExpenseGLAccountId` | Expense GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | Yes | | | `ExpenseVoucherId` | Expense Voucher | Lookup → [ExpenseVoucher](/docs/reference/entities/expense-voucher/) | | | | `GLAccountName` | Name | Text, unique | Yes | | | `Id` | Id | Guid | Yes | | | `LineNumber` | Line Number | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `TaxAmount` | Tax Amount | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteListRow` | Delete | Delete | DeleteListRow | | `EditEntity` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListRow` | Edit | Edit | Edit | | `NewInLine` | New | NewInline | NewInLine | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Amount Validation | `Amount`, Error | Amount can not be zero or less than zero! | Verify that Expense Voucher Line cannot be saved without Amount Verify that Expense Voucher Line cannot be saved with Amount = 0 | ## Related entities - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — looks up via `ExpenseVoucherId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `ExpenseGLAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Expense Voucher — entity reference URL: https://xmatix.com/docs/reference/entities/expense-voucher/ Last reviewed: 2026-08-16 A direct-expense voucher for petty-cash / non-PO spend, separate from the employee claim flow: posting writes a balanced journal debiting each line's expense GL account and crediting the payment GL account for the total. glPostingType decides the credit leg: Cash/Bank (or empty) means paid at posting with no open item, while Credit is a pay-later voucher that requires a party (supplier) account, tags the credit line with it and raises an Accounts-Payable open item that Record Payment settles. Payment tracking on credit vouchers mirrors Invoice/Bill: payments tagged with the voucher roll into amountPaid, credit-note-style PaymentAdjustments into adjustedAmount, leaving openAmount. Status runs Draft, Posted, Reversed; a Posted or Reversed voucher cannot be posted again. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AdjustedAmount` | Adjusted Amount | Currency | | Total of credit-note-style PaymentAdjustments applied to the voucher; each application is validated against the remaining openAmount and recomputes it. Undoing an adjustment posting subtracts it back. | | `AmountPaid` | Amount Paid | Currency | | Sum of Payment rows tagged with this voucher, maintained automatically by the payment rollup - only meaningful for Credit vouchers. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EmployeeId` | Employee | Lookup → [Employee](/docs/reference/entities/employee/) | | | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | | | `GLPostingType` | GL Posting Type | PickList | | Drives the credit leg at posting: Cash or Bank (or empty, the backward-compatible default) means paid at posting with openAmount 0; Credit is a pay-later voucher - it requires a party (supplier) account, tags the credit journal line with it, and raises an Accounts-Payable open item that Record Payment settles. Values: Cash, Bank, Credit. | | `Id` | Id | Guid | Yes | | | `IsGLPosted` | Is GL Posted | Boolean | | | | `IsGLPostingApproved` | Is GL Posting Approved | Boolean | | | | `JournalId` | Journal | Lookup → [Journal](/docs/reference/entities/journal/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `Narration` | Narration | Text | | | | `OpenAmount` | Open Amount | Currency | | Unpaid balance of a credit voucher: totalAmount minus adjustedAmount, maintained by the payment-adjustment rollup; payments tagged to the voucher roll into amountPaid. Stays 0 for cash/bank vouchers, which are settled at posting. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyAccountId` | Party Account | Lookup → [Account](/docs/reference/entities/account/) | | The payee/supplier Account. Mandatory for Credit (pay-later) vouchers - posting refuses a credit voucher without it, since the payable open item must be tagged to a party. | | `PaymentGLAccountId` | Payment GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Status` | Status | Text | | Draft, Posted or Reversed (journal-status vocabulary). Validation refuses to post a voucher already Posted (correct with a reversal) or Reversed. | | `TotalAmount` | Total Amount | Calculated (calculated) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VoucherDate` | Voucher Date | Date | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListRow` | Edit | Edit | EditListRow | | `GetOpenDocuments` | Get Open Documents | ServerAction (`GetOpenDocuments`) | Read-only helper for the payment-recording UI: lists open documents via the shared payment service so a payment can be allocated. Requires the voucher's tenant partner account to be set; creates nothing and changes nothing. | | `GetPaymentAmountSummary` | Payment | ServerAction (`GetPaymentAmountSummary`) | Read-only helper for the payment-recording UI: returns the voucher's payment amount summary (paid/open figures) via the shared payment service. Creates nothing and changes nothing. | | `New` | New | New | New | | `PerformGLPosting` | Post | ServerAction (`PerformGLPosting`) | Posts the voucher: one journal debiting each line's expense head (amount+tax) and crediting the payment GL account for the total, stamping glId, isGLPosted, totalAmount and status Posted. A Credit (pay-later) voucher must carry a party account - the credit line is tagged with it and an Accounts-Payable open item is raised for Record Payment to settle; cash/bank vouchers are settled at posting. Validation refuses vouchers already Posted or Reversed, and posting requires a payment GL account and at least one postable line. | | `PostAdjustments` | Post Adjustments | ServerAction (`PostAdjustments`) | PostAdjustments | | `PostGeneralLedger` | Post General Ledger | ServerAction (`PostGeneralLedger`) | Alternate name for the voucher posting operation - identical behaviour to PerformGLPosting: same validation (not already Posted/Reversed), same journal (Dr expense heads / Cr payment account) and same credit-voucher payable handling. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Voucher Date Validation | `VoucherDate`, Error | Voucher Date can not be future date ! | Voucher Date can not be future date ! | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Customer Account Filter | `PartyAccountId` | | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [Employee](/docs/reference/entities/employee/) — looks up via `EmployeeId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Journal](/docs/reference/entities/journal/) — looks up via `JournalId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `PaymentGLAccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [ExpenseVoucherLine](/docs/reference/entities/expense-voucher-line/) — referenced by via `ExpenseVoucherId` - [Employee](/docs/reference/entities/employee/) — referenced by via `ExpenseVoucherId` - [Payment](/docs/reference/entities/payment/) — referenced by via `ExpenseVoucherId` - [PaymentAdjustment](/docs/reference/entities/payment-adjustment/) — referenced by via `ExpenseVoucherId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [InterestCharge](/docs/reference/entities/interest-charge/) — referenced by via `SourceRecordId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Field Sales Invoice — entity reference URL: https://xmatix.com/docs/reference/entities/field-sales-invoice/ Last reviewed: 2026-08-16 The join between a FieldSales van run and an Invoice raised during it, plus the cash actually collected against that invoice. CollectedAmount is not typed by the user: the day-end unload step overwrites it with the linked invoice's adjusted amount and sums those figures into the run's CashExpected, which is the number the rep is then held to at reconciliation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup | | | | `CollectedAmount` | Collected Amount | Number | | Cash collected against this invoice on the run. It is overwritten at day end with the invoice's adjusted amount rather than being entered, and the sum of these values becomes the run's CashExpected. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FieldSalesId` | Field Sales | Lookup | | | | `Id` | Id | Guid | Yes | | | `InvoiceAmount` | Invoice Amount | Number | | The invoice's face value carried onto the join row. Nothing writes it during the run - the day-end rollup only touches CollectedAmount - so it is populated by whatever created the join row. | | `InvoiceId` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Field Sales Line — entity reference URL: https://xmatix.com/docs/reference/entities/field-sales-line/ Last reviewed: 2026-08-16 One item line of a van-sales run, carrying the same item through every stage of the journey in separate quantity buckets rather than mutating one figure: Quantity is the dispatcher's planned load, ReceivedQuantity plus the TakeIn damaged/shortage/excess trio is what the rep confirmed onto the van, SoldQuantity is accumulated back from the run's invoice lines at day end, and the CheckIn quantities are what the dispatcher counted back into the depot. Each stage's numbers are copied onto the corresponding Transfer lines, which is what actually moves stock. Lines are commonly edited standalone in a grid rather than through the parent, so the service reloads them explicitly when a Perform flag fires. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Number | | | | `CheckInDamagedQuantity` | Check-In Damaged Quantity | Decimal | | Damage found when stock came back off the van, copied onto the return transfer's damaged bucket. Distinct from the take-in damage, which was found on the way out. | | `CheckInExcessQuantity` | Check-In Excess Quantity | Decimal | | | | `CheckInReceivedQuantity` | Check-In Received Quantity | Decimal | | What the dispatcher counted back into the depot at day end - the quantity the return transfer is built from. A line with nothing checked in produces no return leg at all. | | `CheckInShortageQuantity` | Check-In Shortage Quantity | Decimal | | | | `ConversionRatio` | Conversion Ratio | Number | | | | `ConversionRatio1` | Conversion Ratio 1 | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DamagedQuantity` | Damaged Quantity | Number | | A general damage figure separate from the stage-specific take-in and check-in damage fields; the transfers are built from those stage fields, not from this one, so nothing posted depends on it. | | `ExcessQuantity` | Excess Quantity | Calculated | | | | `ExpectedReceivedQuantity` | Expected Received Quantity | Calculated | | | | `FieldSalesId` | Field Sales | Lookup | Yes | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup | | | | `ItemLotId` | Item Lot | Lookup | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Line Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Quantity` | Quantity | Number | | The dispatcher's planned load quantity - the figure the outward depot-to-van transfer is built from and the one the van capacity check multiplies by item weight and volume. It is not what the rep received; that is ReceivedQuantity. | | `ReceivedQuantity` | Received Quantity | Number | | What the rep confirmed onto the van at take-in, and the quantity the inward take-in transfer is built from. When left empty the take-in falls back to the planned Quantity. The day-end rollup deliberately does not overwrite it, so it stays the rep-confirmed figure. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ShortageQuantity` | Shortage Quantity | Calculated | | | | `SKUId` | Item SKU | Lookup | | | | `SoldQuantity` | Sold Quantity | Number | | Accumulated at day end from the invoice lines raised on the run, matched to this line by item, SKU and lot. | | `TakeInDamagedQuantity` | Take-In Damaged Quantity | Decimal | | Damage the rep found when taking stock onto the van; it is copied straight onto the inward take-in transfer's damaged bucket, which is what actually posts it. Separate from the check-in damage recorded at day end. | | `TakeInExcessQuantity` | Take-In Excess Quantity | Decimal | | | | `TakeInShortageQuantity` | Take-In Shortage Quantity | Decimal | | | | `UIProps` | UI Props | Text | | | | `UOM` | UOM | PickList | | | | `UOM1` | UOM1 | PickList | | | | `UOMQuantity` | UOM Quantity | Number | | | | `UOMQuantity1` | UOM Quantity 1 | Number | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkHeader` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [TransferLine](/docs/reference/entities/transfer-line/) — referenced by via `FieldSalesLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Field Sales — entity reference URL: https://xmatix.com/docs/reference/entities/field-sales/ Last reviewed: 2026-08-16 The van-sales (field sales) run document: one record per van journey, tying the executing rep, the van (StorageLocationId, a mobile StorageLocation) and the depot it draws from (SourceStorageLocationId) to a visit plan and a set of stock lines. It has no server actions - the whole lifecycle is driven by five boolean 'Perform' flags that the save pipeline reacts to: releasing the load creates an outward depot-to-van Transfer and sets status Released; the rep's take-in creates an inward Transfer for the received quantities, sets status TakenIn and stamps TakenInDateTime, and queues an invoice-processor job; releasing the unload creates the inward van-to-depot Transfer for the checked-in quantities and sets status Reconciled with ReconciledDateTime; releasing the visit plan creates a linked Van Sales VisitPlan. Cash settlement is tracked on the header - CashExpected is rolled up from the run's invoice collections, CashReceived and CashDiscrepancyReason are entered at reconciliation. Inventory itself is posted by the generated Transfer documents, not by this record. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountGroupId` | Account Group | Lookup | | Scoping a van run to a set of outlets is done through the linked visit plan and route, not here. | | `BranchId` | Branch | Lookup | | | | `CashDiscrepancyReason` | Cash Discrepancy Reason | Text | | | | `CashExpected` | Cash Expected | Currency | | What the rep should hand in at day end. It is not typed: the day-end rollup overwrites it with the sum of the adjusted amounts of the invoices raised on the run, so it is a computed figure that any manual edit will be discarded on the next rollup. | | `CashReceived` | Cash Received | Currency | | What the dispatcher actually took at reconciliation, entered by hand. The platform records it beside CashExpected but does not compare them or raise anything on a shortfall - explaining a gap is the purpose of CashDiscrepancyReason. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | | | `ExecutiveResourceId` | Executive Resource | ExternalId | | The rep executing the van run; it is what the generated visit plan is assigned to and executed by. Distinct from the record's owner. | | `Id` | Id | Guid | Yes | | | `IsLoadReleased` | Is Load Released | Boolean | Yes | | | `IsPlanReleased` | Is Plan Released | Boolean | Yes | | | `IsUnloadReleased` | Is Unload Released | Boolean | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | The run's document number, auto-numbered from the tenant's document-name settings. It is also the stem of every artefact the run generates - the load, take-in and unload transfers and their lines are all named from it, which is how they can be traced back to the run. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PerformLoad` | Perform Load | Boolean | Yes | The rep's confirmation that stock is physically on the van: on save it creates an inward Transfer for each line's received quantity carrying the take-in damage, shortage and excess figures, sets status to TakenIn, stamps TakenInDateTime, queues the invoice-processor job, and clears itself. Despite the name it is the take-in step, not the dispatcher's release. | | `PerformReleaseLoad` | Perform Release Load | Boolean | Yes | Setting this true is what dispatches the run: on save the platform creates an outward depot-to-van Transfer for the planned line quantities, sets the run's status to Released, marks IsLoadReleased and clears this flag again. If van capacity checking is set to block and the load exceeds the van, the whole save fails and nothing is released; in warn mode it releases anyway and stamps the overload onto the transfer's label. | | `PerformReleaseUnload` | Perform Release Unload | Boolean | Yes | The dispatcher's day-end return: on save it creates an inward van-to-depot Transfer for each line's check-in received quantity with the check-in damage, shortage and excess figures, sets status to Reconciled, stamps ReconciledDateTime, marks IsUnloadReleased and clears itself. | | `PerformReleaseVisitPlan` | Perform Release Visit Plan | Boolean | Yes | Creates the linked visit plan for the run - a fully formed plan named after the run and dated to its document date, typed as a van-sales plan and assigned to the executive resource - then links it, marks IsPlanReleased and clears itself. | | `PerformUnload` | Perform Unload | Boolean | Yes | Triggers the cash and sales rollup at day end: the run's invoice collections are written onto its FieldSalesInvoice rows and totalled into CashExpected, and sold quantities are accumulated from the invoice lines onto the matching FieldSalesLines. Unlike the other four trigger flags this one is never reset to false by the handler, so it stays set after firing and re-fires on any later save of the record. | | `ReconciledDateTime` | Reconciled At | DateAndTime | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup | | The rep on the run is ExecutiveResourceId, which is the field that actually persists and flows into the generated visit plan. | | `SourceStorageLocationId` | Source Storage Location | ExternalId | | The depot the load is drawn from: the source of the outward load transfer and the destination of the unload transfer, the mirror of StorageLocationId which is the van. | | `Status` | Status | PickList | | Where the run has got to. The service writes exactly four values in sequence - Draft, Released, TakenIn and Reconciled - as the trigger flags fire. The seeded picklist offers a different vocabulary (loaded, unloaded, draft) that does not match what the code writes, so filter on the values above rather than on the option list. Values: Loaded, Unloaded, Draft. | | `StorageLocationId` | Storage Location | Lookup | | The van itself, modelled as a mobile StorageLocation - it is the destination of the load transfer and the source of the unload transfer, and its declared weight and volume capacity are what the capacity check measures the planned load against. The depot the stock comes from is SourceStorageLocationId, not this. | | `TakenInDateTime` | Taken In At | DateAndTime | | | | `Type` | Type | PickList | | Values: Van Delivery, Ready Stock Sales, Pre-Bill. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VisitPlanId` | Visit Plan | Lookup | | | | `VisitRouteGroupId` | Visit Route Group | Lookup | | | | `VisitTaskTemplateId` | Visit Task Template | Lookup | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `FieldSalesId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `FieldSalesId` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `FieldSalesId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Finance Case — entity reference URL: https://xmatix.com/docs/reference/entities/finance-case/ Last reviewed: 2026-08-16 A retail finance application raised against a sale: it records what the customer asked for and what the financier granted as parallel requested/approved/disbursed sets of amount, down payment, interest rate, tenure and EMI, and links the sale through OrderId and InvoiceId plus the financier through FinanceProviderId and FinancerSchemeId. It is live and wired into order-to-cash: creating one, changing its DisbursedAmount, or deleting it pushes the financed amount back onto the linked Order and Invoice, and when an invoice is raised for an order the platform re-tags the order's finance cases with the new InvoiceId. OrderId, InvoiceId, BranchId and PartnerAccountId are frozen after creation, and the partner/branch pairing is validated on insert. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `ApprovalRemarks` | Approval Remarks | Text | | | | `ApprovedAmount` | Approved Amount | Currency | | | | `ApprovedById` | Approved By | Lookup | | | | `ApprovedDownPayment` | Approved Down Payment | Currency | | | | `ApprovedInterestRate` | Approved Interest Rate | Decimal | | | | `ApprovedTenureMonths` | Approved Tenure (In Months) | Number | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeclinedById` | Declined By | Lookup | | | | `DeclinedRemarks` | Declined Remarks | Text | | | | `DisbursedAmount` | Disbursed Amount | Currency | | The amount the financier actually paid out, and the only field on the case that drives anything downstream: changing it re-pushes the financed amount onto the linked Order and the linked Invoice. Creating or deleting the case does the same. | | `DisbursementDate` | Disbursement Date | Date | | | | `DisbursementNumber` | Disbursement Number | Text | | | | `EMIOnApprovedAmount` | EMI on Approved Amount | Currency | | | | `EMIOnDisbursedAmount` | EMI on Disbursed Amount | Currency | | | | `EMIOnRequestedAmount` | EMI on Requested Amount | Currency | | | | `ExternalId` | External | Text | | | | `FinanceProviderId` | Finance Provider | Lookup → [Financer](/docs/reference/entities/financer/) | | The Financer funding this case. Where the customer has gone to a lender that is not on the master, OtherFinancer holds the name as free text instead - so a case can be financed with this left empty. | | `FinancerSchemeId` | Financer Scheme | Lookup → [FinancerScheme](/docs/reference/entities/financer-scheme/) | | The financier's product the case is written under. Nothing validates the case's amount or tenure against that scheme's minimum and maximum bounds - the scheme entity is never loaded by any code - so the bounds are advisory. | | `FinanceSchemeId` | Finance Scheme | Lookup | | A second scheme reference distinct from FinancerSchemeId, with no code reading either; where both are populated nothing reconciles them. Prefer FinancerSchemeId, which is the one that maps to the FinancerScheme master. | | `Id` | Id | Guid | Yes | | | `InvoiceId` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | The invoice the financed sale was billed on. It is usually not chosen by hand - when an invoice is raised for the case's order, the platform stamps the new invoice onto the order's finance cases that do not already have one. It is frozen against edits after creation. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | The sales order being financed; it is the key the platform uses to find the case when an invoice is later raised. Frozen against edits after creation, along with the invoice, branch and partner-account links. | | `OtherFinancer` | Other Financer | Text | | Free-text name of a lender that is not on the Financer master, used instead of FinanceProviderId. Because it is unstructured it will not join to anything, so cases recorded this way are invisible to any analysis grouped by financier. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company that owns the case, validated against the chosen branch on insert and frozen thereafter. This is the company dimension, not the applicant - the customer applying for finance is AccountId. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedAmount` | Requested Amount | Currency | | | | `RequestedDownPayment` | Requested Down Payment | Currency | | | | `RequestedInterestRate` | Requested Interest Rate | Decimal | | | | `RequestedTenureMonths` | Requested Tenure (In Months) | Number | | | | `Status` | Status | PickList | | Where the application stands - draft, documentation, approval in process, declined or approved. | | `TenureMonths` | Tenure Months | PickList | | A picklist of standard tenures held separately from the numeric RequestedTenureMonths and ApprovedTenureMonths, which are what the requested and approved terms actually record. Nothing keeps this in step with them. Values: 12, 24, 36, 48, 60, 72, 84. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page | | `EditInList` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Disbursed Amount Validation | `DisbursedAmount`, Error | Disbursed Amount cannot be greater than the Requested Amount | Disbursed Amount Validation | | XM_DownPaymentAmountValidation | `RequestedDownPayment`, Error | Requested Down Payment cannot be Negative | Requested Down Payment cannot be Negative | | EMI Amount Rule Validation | `EMIOnRequestedAmount`, Error | EMI Amount should be less than or Equal to Disbursed Amount | EMI Amount Validation | | XM_RequestedAmountValidation | `RequestedAmount`, Error | Requested Amount cannot be Negative. | Requested Amount cannot be Negative | | Tenure Rule Validation | `AccountId`, Error | Tenure should not be less than 1 | Account Tenure must be greater than 1 month. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | Branch For Partner Account | | Customer Account Filter | `AccountId` | | | Partner Account | `PartnerAccountId` | | ## Related entities - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [FinancerScheme](/docs/reference/entities/financer-scheme/) — looks up via `FinancerSchemeId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [Financer](/docs/reference/entities/financer/) — looks up via `FinanceProviderId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [KYCDocument](/docs/reference/entities/kycdocument/) — referenced by via `FinanceCaseId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Financer Scheme — entity reference URL: https://xmatix.com/docs/reference/entities/financer-scheme/ Last reviewed: 2026-08-16 One named financing product offered by a Financer, bounding the deals that may be written under it: minimum and maximum amount, minimum and maximum tenure in months, and a free-text Features blurb. ApplicablePartnerAccountId and ApplicableToPartnerAccountGroupId are meant to restrict the scheme to a company or to a group of partner accounts, but nothing reads them - no service, handler or engine in the platform loads FinancerScheme at all, so the amount/tenure bounds and the applicability scope are documentation for the user filling in the form rather than constraints the platform enforces on a FinanceCase. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApplicablePartnerAccountId` | Applicable Partner Account | Lookup | | | | `ApplicableToPartnerAccountGroupId` | Applicable To Partner Account Group | Lookup | | Intended to limit the scheme to partner accounts in a given group, but nothing reads it - no service or engine loads FinancerScheme at all - so it records intent without restricting anything. Finance cases can be raised against the scheme regardless of the group. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `ExternalId` | External | Text, unique | | | | `Features` | Features | LongMultiLineText | | | | `FinancerId` | Financer | Lookup | Yes | | | `FinancerSchemeName` | Financer Scheme Name | Text | | | | `Id` | Id | Guid | Yes | | | `MaximumAmount` | Maximum Amount | Currency | | | | `MaximumTenure` | Maximum Tenure (in months) | Number | | | | `MinimumAmount` | Minimum Amount | Currency | | | | `MinimumTenure` | Minimum Tenure (in month) | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `FinancerSchemeId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `FinancerSchemeId` - [FinanceCase](/docs/reference/entities/finance-case/) — referenced by via `FinancerSchemeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Financer — entity reference URL: https://xmatix.com/docs/reference/entities/financer/ Last reviewed: 2026-08-16 The list of finance providers a tenant can raise a FinanceCase with - a bare reference master carrying only a name, with the commercial terms held on its child FinancerScheme rows. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `FinancerId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `FinanceProviderId` - [FinanceCase](/docs/reference/entities/finance-case/) — referenced by via `FinanceProviderId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Financial Projection Line — entity reference URL: https://xmatix.com/docs/reference/entities/financial-projection-line/ Last reviewed: 2026-08-16 One forecast line inside a FinancialProjection. GLAccountId is what makes it count: lines without a GL account are excluded from the projected income statement entirely. The optional customer, item, project and posting dimensions plus the three expected dates give it invoice-level granularity for billing and cash-flow tracking. The consuming services read ProjectedNetAmount and WeightedAmount only — ProjectedAmount and ProjectedTaxAmount are recorded for reference but are not what the statements sum — and the cash-flow forecast additionally requires ExpectedCollectionDate, dropping any line that lacks one. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `CostCenterId` | Cost Center | Lookup → [CostCenter](/docs/reference/entities/cost-center/) | | Cost-centre allocation for the line, mirroring the same dimension on journal lines and period balances so a projection can in principle be compared with cost-centre actuals. Note that the cash-flow forecast filters lines only by branch, business unit and GST registration, and the projected income statement does not scope by cost centre at all, so this is stored for analysis rather than acted on today. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | CreatedDateTime | DateAndTime | Yes | | | `ExpectedCollectionDate` | ExpectedCollectionDate | Date | | When the cash is expected to actually arrive (or leave, for expense projections) — the only line date the cash-flow forecast reads. A line with this left null is excluded from the forecast pipeline altogether, no matter how well populated its amounts are. | | `ExpectedInvoiceDate` | ExpectedInvoiceDate | Date | | When the line is expected to be billed. It captures billing intent for review and reporting; the first-party projected income statement and cash-flow forecast bucket on the collection date instead, so this date alone will not move money in either output. | | `ExpectedRevenueDate` | ExpectedRevenueDate | Date | | When the line is expected to be recognised in the profit and loss. It records the intended revenue period, but the projected income statement aggregates the whole projection rather than phasing by this date, so it does not by itself place the amount in a particular month. | | `FinancialProjectionId` | Financial Projection | Lookup → [FinancialProjection](/docs/reference/entities/financial-projection/) | | | | `FiscalPeriodId` | Fiscal Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | | Optional accounting period for a period-phased plan. It is stored for analysis; the projected income statement does not split its columns by it, so phasing a projection across periods here does not produce a month-by-month projected profit and loss. | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The P&L account the projected amount rolls up to, and effectively mandatory: the projected income statement selects only lines that have one, so a customer-level line left without an account is forecast in cash-flow terms yet contributes nothing to the projected profit and loss. | | `GSTRegistrationId` | GST Registration | Lookup → [GSTRegistration](/docs/reference/entities/gstregistration/) | | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The owning company, duplicated from the header onto the line. Do not confuse it with PartyAccountId: this is the legal entity whose forecast this is, while the counterparty being billed or paid is the party account. | | `PartyAccountId` | Party Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer or supplier this line is expected to be transacted with — the counterparty, distinct from PartnerAccountId which holds the company doing the forecasting. It gives the line invoice-level granularity; leave it null for a purely account-level plan line. | | `ProbabilityPercent` | ProbabilityPercent | Percent | | Confidence in the line expressed as a whole percentage (100 means certain), not a fraction. It is used as the multiplier when WeightedAmount has not been stored, defaulting to 100 when null, and it also surfaces as the statement's Probability % column, which is derived as weighted divided by projected rather than read straight from here. | | `ProjectedAmount` | ProjectedAmount | Currency | | The expected gross or pre-tax value of the line, recorded for reference. Neither the projected income statement nor the cash-flow forecast reads it — both work from ProjectedNetAmount — so a line with only this populated will forecast as zero. | | `ProjectedNetAmount` | ProjectedNetAmount | Currency | | The operative figure. The projected income statement sums it per GL account for the full-value projection column, and the cash-flow forecast multiplies it by the probability when no weighted amount is stored. A line with a zero or null net amount is skipped entirely by the projected profit and loss. | | `ProjectedTaxAmount` | ProjectedTaxAmount | Currency | | Expected tax component of the line, held alongside the gross and net figures. Like ProjectedAmount it is descriptive: the forecasting services never add it to or subtract it from the amounts they report. | | `ProjectId` | Project | Lookup → [Project](/docs/reference/entities/project/) | | | | `RecordTypeId` | RecordTypeId | Guid | | | | `ReferenceId` | ReferenceId | Guid | | Identifier of the originating record within the entity named by ReferenceType. | | `ReferenceType` | ReferenceType | Text | | Free-text name of the entity the projection line was derived from — an opportunity or a contract, for example. It pairs with ReferenceId as a soft, unenforced back-pointer with no foreign key behind it. | | `Remarks` | Remarks | Text | | | | `Status` | Status | Text | | | | `UIProps` | UIProps | Text | | | | `UpdatedDateTime` | UpdatedDateTime | DateAndTime | Yes | | | `WeightedAmount` | WeightedAmount | Currency | | The probability-adjusted value, conceptually net amount multiplied by probability divided by one hundred. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Related entities - [FinancialProjection](/docs/reference/entities/financial-projection/) — looks up via `FinancialProjectionId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Financial Projection — entity reference URL: https://xmatix.com/docs/reference/entities/financial-projection/ Last reviewed: 2026-08-16 An entered, scenario-based forecast header for a company and fiscal year — the manual sibling of Budget, kept parallel to it rather than merged, with its own scenario and version columns. Its lines carry projected amounts per GL account, and optionally per customer, item and dimension with expected invoice, revenue and collection dates. It feeds two things: the projected income statement, which shows projected full-year value, probability percent, year-to-date actuals and variance per P&L account; and the cash-flow forecast pipeline, which buckets probability-weighted line amounts by expected collection date. Actuals are never stored here — every comparison is against the posted ledger. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApprovedById` | Approved By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `ApprovedOn` | ApprovedOn | DateAndTime | | Timestamp captured when the projection was signed off, paired with ApprovedById. It is an audit record only — no service gates the projected income statement or the cash-flow forecast on the projection having been approved. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FiscalYearId` | Fiscal Year | Lookup → [FiscalYear](/docs/reference/entities/fiscal-year/) | | The year the projection plans for. The projected income statement takes it from here in preference to the caller's request, falling back to the request only when it is null, and uses it to decide which posted periods form the year-to-date actual column. | | `Id` | Id | Guid | Yes | | | `IsActive` | IsActive | Boolean | | The one flag the consuming pipelines honour: the cash-flow forecast includes a projection when this is true or null and excludes it otherwise. Deactivating is therefore how a superseded scenario or an older version is taken out of the forecast without deleting its lines. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company being forecast, not a customer — customers belong on the lines' PartyAccountId. The projected income statement prefers this over the requested company, and the cash-flow forecast matches projections to the company being forecast on this column alone. | | `PeriodFrom` | Period From | Date | | Start of the window the forecast covers, recorded on the header for context. It does not drive any bucketing — the cash-flow forecast places money using each line's expected collection date, so a line dated outside this window is still forecast. | | `PeriodTo` | Period To | Date | | End of the header's forecast window, the counterpart to PeriodFrom. Like it, this is descriptive: line-level expected dates, not this range, determine which period or bucket a projected amount lands in. | | `ProjectionType` | ProjectionType | Text | | Classifies the forecast as Revenue, Expense or CashFlow. The cash-flow forecast branches on it: a projection typed Expense sends its weighted line amounts into the payments (outflow) buckets, and every other value — including CashFlow — is treated as a collection (inflow), so the comparison is effectively Expense versus not-Expense. | | `RecordTypeId` | RecordTypeId | Guid | | | | `Remarks` | Remarks | Text | | | | `ScenarioType` | ScenarioType | Text | | The what-if variant this version represents: Base (the default), Optimistic, Pessimistic or Revised. Be careful when several scenarios are active at once — the cash-flow forecast pipeline selects every active projection for the company regardless of scenario, so leaving an optimistic and a pessimistic version both active double-counts the same expected cash. | | `Status` | Status | Text | | Workflow state, defaulting to Draft. It is recorded for review purposes only: neither the projected income statement nor the cash-flow forecast filters on it, so a Draft projection contributes to both exactly as an approved one would. IsActive, not Status, is the switch that keeps a projection out of the forecast. | | `UIProps` | UIProps | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VersionNo` | VersionNo | Number | | Revision counter for successive re-forecasts of the same period, starting at 1. It is stored for provenance and is not read by the projection services — superseding an earlier version means deactivating it, not merely bumping this number. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | EditInLine | | `New` | New | New | New | ## Related entities - [FinancialProjectionLine](/docs/reference/entities/financial-projection-line/) — referenced by via `FinancialProjectionId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Statement Layout Node — entity reference URL: https://xmatix.com/docs/reference/entities/financial-statement-layout-node/ Last reviewed: 2026-08-16 One line of a statement layout tree. A node either rolls up its children through the parent self-reference or, as a leaf, aggregates the balances of the single Schedule III classification it names, with a display order for sibling sequencing and a multiplier for lines that must print inverted. The same caveat as its parent layout applies: the current statement engine groups by the classification stored on each GL account rather than by these nodes, so the tree describes an intended presentation that is not yet consumed. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DisplayOrder` | Display Order | Number | | Sequences siblings sharing the same parent. It is not a global statement ordering, so two nodes under different parents may carry the same value without conflict. | | `FinancialStatementLayoutId` | Financial Statement Layout | Lookup → [FinancialStatementLayout](/docs/reference/entities/financial-statement-layout/) | | | | `Id` | Id | Guid | Yes | | | `IsSubtotal` | Is Subtotal | Boolean | | Marks the node as a computed total over its children rather than a line that aggregates account balances in its own right. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | GL Account Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentNodeId` | Parent Node | Lookup → [FinancialStatementLayoutNode](/docs/reference/entities/financial-statement-layout-node/) | | The self-reference that builds the layout tree. A node without one is a root line of the statement, and children roll up into their parent rather than printing as independent lines. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ScheduleIIIClassification` | ScheduleIII Classification | Text | | The single Companies Act Schedule III line item whose balances this node aggregates, matched against the classification stored on each GL account. Setting it makes the node a leaf; leaving it empty makes the node a container whose value comes entirely from its children. | | `SignMultiplier` | Sign Multiplier | Number | | Either 1 or -1, applied so a line prints in the direction the statement expects. The inverting case exists for deductions shown inside an otherwise positive block, such as accumulated depreciation sitting under property, plant and equipment. It defaults to 1. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [FinancialStatementLayout](/docs/reference/entities/financial-statement-layout/) — looks up via `FinancialStatementLayoutId` - [FinancialStatementLayoutNode](/docs/reference/entities/financial-statement-layout-node/) — looks up via `ParentNodeId` - [FinancialStatementLayoutNode](/docs/reference/entities/financial-statement-layout-node/) — referenced by via `ParentNodeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Statement Layout — entity reference URL: https://xmatix.com/docs/reference/entities/financial-statement-layout/ Last reviewed: 2026-08-16 A tenant-authored presentation tree for one statement type, intended to let a company reorder, rename or regroup statement lines without touching the Schedule III mapping held on the chart of accounts. It owns an ordered set of layout nodes and is scoped to a single company. Important caveat: the shipped statement engine derives its groupings from each GL account's own Schedule III classification and does not read these rows, so a layout stored here does not currently change rendered statement output. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Format` | Format | Text | | Whether the tree is intended to print in the stacked vertical presentation or the side-by-side horizontal one; it defaults to vertical. The single-statement generators accept the same choice as a runtime argument, independently of this stored preference. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `IsDefault` | Is Default | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | GL Account Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StatementTypeName` | Statement Type Name | Text | | Which statement the tree is meant to shape, one of balance sheet, profit and loss, cash flow or trial balance. It selects the intended target rather than triggering any rendering by itself. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [FinancialStatementLayoutNode](/docs/reference/entities/financial-statement-layout-node/) — referenced by via `FinancialStatementLayoutId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Fiscal Period — entity reference URL: https://xmatix.com/docs/reference/entities/fiscal-period/ Last reviewed: 2026-10-10 One month of a company's fiscal year. Its status decides whether anything can still post into the dates it covers: Open accepts postings, Closed refuses them but can be reopened, and Locked refuses them for good. Every journal is placed in the period of its company whose start and end dates cover the journal date, and posting also needs the period's fiscal year to be Open. Periods are normally created by Generate Periods on the fiscal year. Close Period, Reopen Period and Lock Period move the status and carry it to the period's fiscal days; Verify Ledger compares the period's stored GL and party balances with its posted journals, and Rebuild Balances recalculates them. The shipped record page shows only Edit and Delete in its header, so an administrator adds these actions to the layout before users can run them. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EndDate` | End Date | Date | | Last day the period covers. Generate Periods ends each period on the last day of its calendar month, or on the fiscal year's end date if that comes first. | | `FiscalYearId` | Fiscal Year | Lookup → [FiscalYear](/docs/reference/entities/fiscal-year/) | | The fiscal year this period belongs to. Generate Periods on the fiscal year creates and links the periods. | | `GLAccountName` | Name | Text, unique | Yes | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | Display label of the period, set to the same month text as the name by Generate Periods. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | The period's name, for example Apr 2026, set by Generate Periods. It is the label shown in posting error messages. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company (partner Account) whose fiscal calendar this period belongs to - periods are maintained per company, so filter by the right company as well as by date when resolving a period. | | `PeriodNumber` | Period Number | Number | | The period's position in its fiscal year, starting at 1. The highest number is the year's last period, which the year-end Close Year journal posts into. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StartDate` | Start Date | Date | | First day the period covers. A journal lands in the period of its company whose start and end dates include the journal date. | | `Status` | Status | PickList | | Open, Closed or Locked. Only Open accepts postings and only an Open period can be deleted. Close Period moves Open to Closed, Reopen Period moves Closed to Open, and Lock Period moves Open or Closed to Locked, which is final. Change it with these actions rather than by editing, so the period's fiscal days follow. Values: Open. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `ClosePeriod` | Close Period | ServerAction (`ClosePeriod`) | Moves an Open period to Closed, blocking further journal posting into it. Refused with a validation error when the period is not currently Open. Closing is reversible - use ReopenPeriod to undo it. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListRow` | Edit | Edit | EditListRow | | `LockPeriod` | Lock Period | ServerAction (`LockPeriod`) | Finalizes the period: an Open period is closed and locked in one step, a Closed period is locked directly. Locked is terminal - validation blocks any later status change away from it - so lock only once statements for the period are final. | | `New` | New | New | New | | `RebuildLedgerBalances` | Rebuild Balances | ServerAction (`RebuildLedgerBalances`) | Rebuilds this period's balance caches from the posted ledger via the ledger verification service and returns the result - the sanctioned resync after drift. Balances themselves only ever change by posting journals; direct edits to balance rows are rejected. | | `ReopenPeriod` | Reopen Period | ServerAction (`ReopenPeriod`) | Moves a Closed period back to Open so posting can resume. Only Closed periods qualify; a Locked period is refused because locking is terminal. | | `VerifyLedger` | Verify Ledger | ServerAction (`VerifyLedger`) | Runs the ledger verification service for this period and returns its findings, comparing the period's balance caches against the posted ledger. A detection step: use it to spot drift before trusting cached balances or before closing. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [FiscalYear](/docs/reference/entities/fiscal-year/) — looks up via `FiscalYearId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [InventoryOpeningLotState](/docs/reference/entities/inventory-opening-lot-state/) — referenced by via `FiscalPeriodId` - [PeriodClose](/docs/reference/entities/period-close/) — referenced by via `FiscalPeriodId` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — referenced by via `FiscalPeriodId` - [BudgetLine](/docs/reference/entities/budget-line/) — referenced by via `FiscalPeriodId` - [CurrencyRevaluation](/docs/reference/entities/currency-revaluation/) — referenced by via `FiscalPeriodId` - [PartyPeriodBalance](/docs/reference/entities/party-period-balance/) — referenced by via `FiscalPeriodId` - [InventoryNrvAssessment](/docs/reference/entities/inventory-nrv-assessment/) — referenced by via `FiscalPeriodId` - [GLAccountPeriodBalance](/docs/reference/entities/glaccount-period-balance/) — referenced by via `FiscalPeriodId` - [PublishedStatement](/docs/reference/entities/published-statement/) — referenced by via `AsOfPeriodId` - [RevenueRecognitionScheduleLine](/docs/reference/entities/revenue-recognition-schedule-line/) — referenced by via `FiscalPeriodId` - [CurrencyRevaluation](/docs/reference/entities/currency-revaluation/) — referenced by via `FiscalPeriodId` - [BookValuationAdjustment](/docs/reference/entities/book-valuation-adjustment/) — referenced by via `FiscalPeriodId` - [Journal](/docs/reference/entities/journal/) — referenced by via `FiscalPeriodId` - [PayrollPeriod](/docs/reference/entities/payroll-period/) — referenced by via `FiscalPeriodId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Fiscal Year — entity reference URL: https://xmatix.com/docs/reference/entities/fiscal-year/ Last reviewed: 2026-10-09 The accounting calendar of one company: a dated window whose monthly fiscal periods decide which dates a journal can post into. Generate Periods fills it with one Open period per calendar month of the window, and Generate Fiscal Days can add one row per date flagged working or non-working. A posting needs an Open period covering its date inside a fiscal year whose own status is also Open, so the year's status gates every period beneath it. When a posting date has no covering period, an April to March year with Open monthly periods is created automatically for the company. The trial balance, profit and loss, balance sheet, cash flow, ratio and statutory-filing actions are all run from this record, and Close Year posts the year-end closing journal to retained earnings. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EndDate` | End Date | Date | | The last day of the fiscal year, which must be after the start date or the save is refused. The last period ends on this date, and the year-end closing journal is dated on the last period's end date. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | An optional display name for the year. It is not on the create form; when present it is used in messages and in the closing journal's description. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | The year's name, for example FY2026-27. It also names the year-end closing journal, which is called CLOSE- followed by this name. Years created automatically for a posting date are named this way. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company that owns this accounting calendar, and a frequent cause of statements that come back blank. The balance sheet and trial balance select their periods by matching this company rather than by fiscal year, so a calendar stamped with a different company than the one being reported yields an empty statement with no error raised. The profit and loss path selects periods by fiscal year instead and keeps working, and that asymmetry is the diagnostic tell. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StartDate` | Start Date | Date | | The first day of the fiscal year. Generate Periods and Generate Fiscal Days refuse to run until both the start and end date are set, and the first period starts on this date even if it is mid-month. | | `Status` | Status | Text | | The year-level status, defaulting to Open and using the fiscal-period vocabulary of Open, Closed and Locked. It is a plain text field and it gates posting: a journal is refused in any period of a year whose status is anything other than Open, even when the period itself is Open. No action writes it; Close Year posts the closing journal but leaves this status unchanged, so set it yourself to stop or allow postings into the whole year. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `CheckCreditLimit` | CheckCreditLimit | ServerAction (`CheckCreditLimit`) | Despite sitting on the fiscal-year action list, this evaluates one counterparty's credit limit against its open receivables and a proposed new amount, both of which are required arguments, and reports nothing about the year itself. It is hosted here only because the finance reporting actions are all mounted on this record, and the company is the only thing it actually takes from it. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `CloseYear` | Close Year | ServerAction (`CloseYear`) | Posts the year-end closing journal: it reads the year's profit and loss, reverses every income and expense account with a balance, and books the net profit or loss to a retained-earnings account that must be supplied as an argument. The journal is dated on the last period's end date and is posted immediately, so that period and the year must still be Open. It changes no status, closes no period and does not check whether the year was already closed. The record-page button supplies no argument, so run from there it stops with a message asking for the retained-earnings account. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | UIAction | Edit | | `EditInLine1` | Edit | EditInline | EditInLine | | `EditListRow` | Edit | Edit | EditListRow | | `GenerateAdt1Notice` | ADT-1 Auditor Appointment Notice | ServerAction (`GenerateAdt1Notice`) | Form ADT-1 notice of appointment of auditor (s.139, rule 4(2)), box by box for the fiscal year. Company and period details are derived; the auditor block comes from the Statutory Audit Report and the rest from the ADT-1 draft. | | `GenerateAoc4Filing` | AOC-4 Filing | ServerAction (`GenerateAoc4Filing`) | Computes the AOC-4 annual filing pack (Balance Sheet + P&L + Notes to Accounts) for review; file the permanent copy via PublishedStatement. | | `GenerateApAgeing` | Generate Ap Ageing | ServerAction (`GenerateApAgeing`) | GenerateApAgeing | | `GenerateArAgeing` | Generate Ar Ageing | ServerAction (`GenerateArAgeing`) | GenerateArAgeing | | `GenerateAuditSchedules` | Audit Schedules (All) | ServerAction (`GenerateAuditSchedules`) | Runs all four audit schedules together for the fiscal year: Fixed Assets, AR/AP Ageing, Provisions, and the Loan register. | | `GenerateBalanceSheet` | Balance Sheet | ServerAction (`GenerateBalanceSheet`) | Computes the balance sheet cumulatively up to the cut-off period, grouping into Schedule III equity-and-liabilities and asset blocks and folding cumulative profit and loss into reserves. Like the trial balance it resolves its periods by company, so a fiscal calendar owned by the wrong company yields an empty statement rather than an error. | | `GenerateBalanceSheetByAccountGroup` | Balance Sheet by Account Group | ServerAction (`GenerateBalanceSheetByAccountGroup`) | Chart-of-accounts grouped Balance Sheet (section bands + account tree). | | `GenerateBalanceSheetScheduleIII` | Balance Sheet (Schedule III) | ServerAction (`GenerateBalanceSheetScheduleIII`) | Renders the statutory balance-sheet format with fixed Schedule III line items, in the same multi-column shape as its profit-and-loss counterpart: year over year, explicit date windows, or one column per posting-dimension value. This is the presentation a statutory filing pack expects, as distinct from the account-tree balance sheet. | | `GenerateBankBook` | Bank Book | ServerAction (`GenerateBankBook`) | Ledger of the bank control accounts for the year. | | `GenerateBudgetIncomeStatement` | Budget Income Statement | ServerAction (`GenerateBudgetIncomeStatement`) | Budget vs actual income statement built from a budget. | | `GenerateCashBook` | Cash Book | ServerAction (`GenerateCashBook`) | Ledger of the cash control accounts for the year. | | `GenerateCashFlow` | Generate Cash Flow | ServerAction (`GenerateCashFlow`) | Produces the cash flow statement by the indirect method for the reporting window. Like the other single-statement generators it returns either the structured result or print-ready statutory markup depending on a format argument. | | `GenerateCashFlowByAccountGroup` | Cash Flow by Account Group | ServerAction (`GenerateCashFlowByAccountGroup`) | Chart-of-accounts grouped Cash Flow Statement. | | `GenerateCashFlowForecast` | Cash Flow Forecast | ServerAction (`GenerateCashFlowForecast`) | Forward-looking cash flow forecast. | | `GenerateChangesInEquity` | Changes in Equity | ServerAction (`GenerateChangesInEquity`) | Produces the statement of changes in equity as a multi-column grouped result spanning one or more fiscal years, taking the same year-selection arguments as the other grouped statutory statements. | | `GenerateComparativeStatement` | Comparative Statement | ServerAction (`GenerateComparativeStatement`) | Runs either the profit and loss or the balance sheet across several fiscal years side by side. Which of the two is an argument that quietly defaults to profit and loss, the span defaults to two years, and passing an explicit list of fiscal years overrides the year count entirely. | | `GenerateDayBook` | Day Book | ServerAction (`GenerateDayBook`) | Chronological list of every posted journal line in the year. | | `GenerateDpt3Return` | DPT-3 Return of Deposits | ServerAction (`GenerateDpt3Return`) | Form DPT-3 return of deposits (rules 16 & 16A) for this fiscal year, including the rule 2(1)(c) receipts table. | | `GenerateFinancialRatios` | Financial Ratios | ServerAction (`GenerateFinancialRatios`) | Liquidity, solvency, profitability and efficiency ratios. | | `GenerateFixedAssetSchedule` | Fixed Asset Schedule | ServerAction (`GenerateFixedAssetSchedule`) | Audit schedule: fixed-asset movement note (gross block, accumulated depreciation, net block) derived from the ledger for the fiscal year. | | `GenerateFundFlow` | Generate Fund Flow | ServerAction (`GenerateFundFlow`) | Produces the fund flow statement, showing sources and applications of funds across the window. It is a companion to the cash flow statement rather than a substitute, and answers a different question from it. | | `GenerateGeneralLedger` | General Ledger | ServerAction (`GenerateGeneralLedger`) | Generate the General Ledger / account-balance tree (opening, movement, running and closing balances) over the chart of accounts. | | `GenerateInventoryComparative` | Inventory Comparative | ServerAction (`GenerateInventoryComparative`) | Closing stock / value per fiscal period (comparative columns) from the period-balance cache. | | `GenerateInventoryMovement` | Inventory Movement | ServerAction (`GenerateInventoryMovement`) | Per-book inventory movement (roll-forward vs the preceding period) with opening / closing. | | `GenerateInventoryValuation` | Inventory Valuation | ServerAction (`GenerateInventoryValuation`) | Per-book inventory valuation (on-hand cost and NRV carrying value) with the GL control tie-out. | | `GenerateInventoryValuationMatrix` | Inventory Valuation (by dimension) | ServerAction (`GenerateInventoryValuationMatrix`) | Inventory carrying value pivoted into columns by branch / period (Balance Statement comparative). | | `GenerateInventoryValueStatement` | Inventory Value Statement | ServerAction (`GenerateInventoryValueStatement`) | Inventory carrying value + quantity per column (point-in-time or Opening/Change/Closing movement) for the Balance Statement. | | `GenerateLoanSchedule` | Loan Schedule | ServerAction (`GenerateLoanSchedule`) | Audit schedule: employee loan register (opening + disbursed - repaid = closing) per loan, derived from LoanAdvance/LoanAdvanceRecovery. | | `GenerateMgt7AAnnualReturn` | MGT-7A Annual Return | ServerAction (`GenerateMgt7AAnnualReturn`) | Form MGT-7A abridged annual return (s.92(1)) for this fiscal year, section by section. | | `GeneratePartyStatement` | Generate Party Statement | ServerAction (`GeneratePartyStatement`) | GeneratePartyStatement | | `GeneratePeriods` | Generate Periods | ServerAction (`GeneratePeriods`) | Creates one Open fiscal period for each calendar month of the year's date range, labelled by month and numbered from 1, shortening the first or last period when the year starts or ends mid-month. It refuses when the year lacks a valid start and end date, and refuses if any period already exists rather than topping up, so regenerating means deleting the existing Open periods first. Monthly is the only cadence it produces. | | `GenerateProfitAndLoss` | Profit & Loss | ServerAction (`GenerateProfitAndLoss`) | Computes the profit and loss for the reporting window, grouping accounts by their Schedule III classification. Unlike the balance sheet and trial balance it selects its periods by fiscal year rather than by company, so it can still return figures in cases where those two come back empty because of a mis-stamped calendar. | | `GenerateProfitAndLossByAccountGroup` | P&L by Account Group | ServerAction (`GenerateProfitAndLossByAccountGroup`) | Chart-of-accounts grouped Profit & Loss (section bands + account tree). | | `GenerateProfitAndLossScheduleIII` | P&L (Schedule III) | ServerAction (`GenerateProfitAndLossScheduleIII`) | Renders the statutory Statement of Profit and Loss with its fixed roman-numeral line items instead of the account tree, returned as a multi-column result. Columns can chain fiscal years, chain explicit date windows, or break out by a posting dimension with one column per business unit, branch, tax registration or cost centre plus a total. | | `GenerateProjectedIncomeStatement` | Projected Income Statement | ServerAction (`GenerateProjectedIncomeStatement`) | Forward-looking income statement (run-rate or stored projection). | | `GenerateProvisionSchedule` | Provisions Schedule | ServerAction (`GenerateProvisionSchedule`) | Audit schedule: provisions movement note (opening + additions - utilized/reversed = closing) per provision type, derived from Provision-tagged GL accounts. | | `GenerateRelatedPartyDisclosure` | Related Party Disclosure | ServerAction (`GenerateRelatedPartyDisclosure`) | Nature-wise value of transactions with related parties and the balance outstanding, for the audit disclosure note. | | `GenerateResourceProfitability` | Resource-wise Profitability | ServerAction (`GenerateResourceProfitability`) | Revenue and parts cost of the jobs each engineer/technician worked, less their logged time priced at their labour cost rate. Args: fromDate, toDate, resourceId, branchId, status, includeJobs, format. | | `GenerateRiskReport` | Risk Report | ServerAction (`GenerateRiskReport`) | Piotroski, Altman, Beneish, Montier and risk-ratio scoring. | | `GenerateTrialBalance` | Trial Balance | ServerAction (`GenerateTrialBalance`) | Computes the trial balance for the company as at the requested cut-off, listing each account's net debit or credit and suppressing accounts with no movement at all. Empty output against a well-populated ledger usually means the fiscal calendar is stamped with a different company than the one being reported, because period selection on this path filters by company rather than by fiscal year. | | `GenerateTrialBalanceByAccountGroup` | Trial Balance by Account Group | ServerAction (`GenerateTrialBalanceByAccountGroup`) | Produces the trial balance arranged down the chart-of-accounts hierarchy rather than as a flat account list, returning debit, credit and closing columns per node. Prefer it over the flat trial balance when the question concerns account groupings instead of individual account balances. | | `GetBookOverlayStatus` | Book Overlay Status | ServerAction (`GetBookOverlayStatus`) | Reports whether a chosen secondary accounting book's stored valuation overlay is still current given inventory activity since it was last recomputed. The book is a required argument, and the primary book is never reported as stale because it is the general ledger itself. | | `New` | New | New | New | | `RebuildInventoryPeriodBalances` | Rebuild Inventory Period Balances | ServerAction (`RebuildInventoryPeriodBalances`) | Recompute the InventoryPeriodBalance cache from the ledger (prerequisite for the comparative view). | | `RecomputeBookOverlay` | Recompute Book Overlay | ServerAction (`RecomputeBookOverlay`) | Rebuilds the per-book valuation deltas for every period of this fiscal year up to an as-of date that defaults to the year end, doing so across all secondary books rather than only the one being inspected, and reports how many periods it rewrote. Reach for it mid-period when a secondary book's statements are lagging recent inventory movement; period close runs the same recomputation as an advisory step. | | `SaveAdt1Notice` | Save ADT-1 Notice | ServerAction (`SaveAdt1Notice`) | Stores the ADT-1 answers that have no ledger source (CIN, appointment date, auditor particulars, board resolution) on the draft PublishedStatement backing the notice. Merges by default; null clears a box, replace=true discards all. | | `SeedScheduleIIIClassifications` | Seed Classifications | ServerAction (`SeedScheduleIIIClassifications`) | Populates the Schedule III classification on the company's GL accounts by deriving a default from each account's existing account type, so a freshly imported chart of accounts groups into statutory statement lines without manual mapping. By default it only fills accounts that have none; an overwrite argument makes it replace mappings that are already set. | | `ViewForm3CDAudit` | Form 3CD Tax Audit | ServerAction (`ViewForm3CDAudit`) | Clause-wise Form 3CD tax-audit report for this fiscal year. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — referenced by via `FiscalYearId` - [Budget](/docs/reference/entities/budget/) — referenced by via `FiscalYearId` - [PublishedStatement](/docs/reference/entities/published-statement/) — referenced by via `FiscalYearId` - [BudgetCommitment](/docs/reference/entities/budget-commitment/) — referenced by via `FiscalYearId` - [AssetBlock](/docs/reference/entities/asset-block/) — referenced by via `FiscalYearId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — referenced by via `FiscalYearId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Follower — entity reference URL: https://xmatix.com/docs/reference/entities/follower/ Last reviewed: 2026-08-16 A subscription marking a user as watching a record, created by the Follow server action and retired by Unfollow, both of which soft-delete rather than remove rows. Like Collaborator it is polymorphic - Record plus Related Entity Name, no foreign key - and the actions are registered on Case only in first-party metadata. Notify On Change and Muted express an intention to be notified, and following an already-followed record un-mutes it instead of duplicating the row, but no first-party business rule or notification service reads either flag, so following a record currently produces no messages on its own. Record merge re-points followers onto the surviving record. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Muted` | Muted | Boolean | Yes | Following a record that is already followed clears this back to false instead of creating a second row, which is how a mute is undone. Nothing reads the flag, so muting currently suppresses nothing. | | `NotifyOnChange` | Notify On Change | Boolean | Yes | Set true on every row the follow action creates and never changed afterwards. No first-party business rule or notification service reads it, so it records an intention to be notified rather than driving any message. | | `RecordId` | Record | Lookup → [Case](/docs/reference/entities/case/) | Yes | The record being watched, stored as a bare identifier with no foreign key behind it. It is only meaningful together with the related entity name, since identifiers from different entities share this one column. | | `UserId` | User | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `EditInLine` | Edit | EditInline | Edit in page. | ## Related entities - [Case](/docs/reference/entities/case/) — looks up via `CaseId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Form 26AS Line — entity reference URL: https://xmatix.com/docs/reference/entities/form26-asline/ Last reviewed: 2026-08-16 Form 26AS Line is part of the xMatix data model. Field-level notes for this entity are still being written — the table below reflects the live model. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AmountPaid` | Amount Paid | Decimal | | | | `BookingStatus` | Booking Status | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DeductorName` | Deductor Name | Text | | | | `FinancialYear` | Financial Year | Text | | | | `Form26ASStatementId` | Form 26AS Statement | Lookup → [Form26ASStatement](/docs/reference/entities/form26-asstatement/) | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PAN` | PAN | Text | | | | `Quarter` | Quarter | Text | | | | `ReconciliationStatus` | Reconciliation Status | PickList | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SectionCode` | Section | Text | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TAN` | TAN | Text | | | | `TdsAmount` | TDS Amount | Decimal | | | | `TransactionDate` | Transaction Date | DateAndTime | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `ValidationMessage` | Validation Message | Text | | | | `ValidationStatus` | Validation Status | Text | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Bulk Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInline` | Edit Inline | EditInline | Edit Inline | | `EditRecord` | Edit Record | Edit | Edit | | `New` | New | New | New | ## Related entities - [Form26ASStatement](/docs/reference/entities/form26-asstatement/) — looks up via `Form26ASStatementId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Form26ASReconciliationEntry](/docs/reference/entities/form26-asreconciliation-entry/) — referenced by via `Form26ASLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Form 26AS Reconciliation Entry — entity reference URL: https://xmatix.com/docs/reference/entities/form26-asreconciliation-entry/ Last reviewed: 2026-08-16 Form 26AS Reconciliation Entry is part of the xMatix data model. Field-level notes for this entity are still being written — the table below reflects the live model. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Difference` | Difference | Decimal | | | | `FinancialYear` | Financial Year | Text | | | | `Form26ASAmount` | 26AS Amount | Decimal | | | | `Form26ASLineId` | Form 26AS Line | Lookup → [Form26ASLine](/docs/reference/entities/form26-asline/) | | | | `Form26ASStatementId` | Form 26AS Statement | Lookup → [Form26ASStatement](/docs/reference/entities/form26-asstatement/) | | | | `Form26ASTds` | 26AS TDS | Decimal | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `LedgerAmount` | Ledger Amount | Decimal | | | | `LedgerTds` | Ledger TDS | Decimal | | | | `MatchedDate` | Matched Date | DateAndTime | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PAN` | PAN | Text | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `SectionCode` | Section | Text | | | | `SourceEntityName` | Source Entity | Text | | | | `SourceRecordId` | Source Record | Guid | | | | `StatusCode` | Status Code | PickList | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TAN` | TAN | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Bulk Delete | Delete | Bulk Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Form26ASStatement](/docs/reference/entities/form26-asstatement/) — looks up via `Form26ASStatementId` - [Form26ASLine](/docs/reference/entities/form26-asline/) — looks up via `Form26ASLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Form 26AS Statement — entity reference URL: https://xmatix.com/docs/reference/entities/form26-asstatement/ Last reviewed: 2026-08-16 Form 26AS Statement is part of the xMatix data model. Field-level notes for this entity are still being written — the table below reflects the live model. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `ErrorRows` | Error Rows | Number | | | | `ExtraCount` | Extra Count | Number | | | | `FileAssetId` | File Asset | Guid | | | | `FileName` | File Name | Text | | | | `FinancialYear` | Financial Year | Text | | | | `FiscalPeriodId` | Fiscal Period | Lookup → [GSTFiscalPeriod](/docs/reference/entities/gstfiscal-period/) | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `MatchedCount` | Matched Count | Number | | | | `MismatchCount` | Mismatch Count | Number | | | | `MissingCount` | Missing Count | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ReconciledAt` | Reconciled At | DateAndTime | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `Status` | Status | Text | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TotalRows` | Total Rows | Number | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `ValidRows` | Valid Rows | Number | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `New` | New | New | New | ## Related entities - [GSTFiscalPeriod](/docs/reference/entities/gstfiscal-period/) — looks up via `FiscalPeriodId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Form26ASLine](/docs/reference/entities/form26-asline/) — referenced by via `Form26ASStatementId` - [Form26ASReconciliationEntry](/docs/reference/entities/form26-asreconciliation-entry/) — referenced by via `Form26ASStatementId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Form 3CD Clause — entity reference URL: https://xmatix.com/docs/reference/entities/form3-cdclause/ Last reviewed: 2026-08-16 Statutory Form 3CD (tax-audit report) clause catalog: clause number, part, title and description. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ClauseNumber` | Clause Number | Text | | Statutory clause number as printed on the form, e.g. 18, 21a, 34. | | `ComputationKey` | Computation Key | Text | | Reserved for a future per-clause computation service to dispatch on. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Description` | Description | LongMultiLineText | | | | `EditorShape` | Editor Shape | PickList | | Reserved for a future auditor edit-UI to dispatch on. Values: Number Pair, Row Table, Yes/No + Detail, Free Text. | | `EffectiveFrom` | Effective From | DateAndTime | | | | `EffectiveTo` | Effective To | DateAndTime | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartName` | Part | PickList | | Which part of Form 3CD this clause belongs to: A or B. Values: Part A, Part B. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `Title` | Title | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # F&F Line — entity reference URL: https://xmatix.com/docs/reference/entities/full-and-final-settlement-line/ Last reviewed: 2026-08-16 One component of an exit settlement, either an amount owed to the departing employee or an amount recovered from them. The direction is decided purely from Component Type: posting treats a line as a deduction only when that text equals Deduction case-insensitively and treats every other value, blanks and typos included, as a payable. A payable line must carry an expense GL account and a deduction line must carry a payable GL account, or posting the whole settlement fails. Lines with a zero or null amount and soft-deleted lines are skipped entirely. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | Always entered as a positive figure whatever the component type, since direction comes from Component Type and not from the sign. Lines with zero or no amount are skipped entirely when the settlement posts. | | `ComponentType` | Component Type | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `FullAndFinalSettlementId` | Full And Final Settlement | Lookup → [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The expense account debited for a payable line. It is required on payable lines - posting the settlement fails if one is missing - and is unused on deduction lines. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PayableGLAccountId` | PayableGL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The liability or control account credited for a deduction line. It is required on deduction lines - posting fails if one is missing - and is unused on payable lines. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this FullAndFinalSettlementLine. | | `Edit` | Edit | Edit | Edit this FullAndFinalSettlementLine. | | `EditInLine` | Edit | EditInline | Edit | | `New` | New | New | Create a FullAndFinalSettlementLine. | | `NewInLine` | New | NewInline | New | | `View` | View | View | View this FullAndFinalSettlementLine. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — looks up via `FullAndFinalSettlementId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `PayableGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Full & Final Settlement — entity reference URL: https://xmatix.com/docs/reference/entities/full-and-final-settlement/ Last reviewed: 2026-08-16 The exit settlement for a leaving employee: payable components such as salary to the last working day, leave encashment, gratuity and pending reimbursement, net of deductions such as notice recovery, loan recovery and TDS, all held as FullAndFinalSettlementLine children. Posting builds one journal - debit each payable line's expense GL, credit each deduction line's payable GL, credit Payroll Payable for the net - raises a Resource-keyed payable open item for the net, dates everything on the Last Working Day, and then closes the person out by setting the matching Employee to SettlementStatus Settled and EmploymentStatus Exited and filling Date Of Exit if empty. Posting refuses when the settlement is already posted, has no lines, has no Resource, or when recoveries exceed payables so the net would be negative. The Employee it closes is located by matching Employee.ResourceId, so a settlement raised against a Resource with no Employee row still posts but closes nobody. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | Filled with the settlement's posting journal, and used as the already-posted guard: a settlement that already has a value here refuses to post again rather than duplicating the entries. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `LastWorkingDay` | Last Working Day | Date | Yes | Doubles as the accounting date - the settlement journal and the payable open item it raises are both dated on it, falling back to today only when it is empty. It is also the value copied into the employee's Date Of Exit when that is still blank. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `NetSettlement` | Net Settlement | Currency | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | Yes | | | `PayrollPayableOpenTransactionId` | Payroll Payable Open Transaction | Lookup → [OpenTransaction](/docs/reference/entities/open-transaction/) | | The Resource-keyed payable open item raised for the net settlement amount, which the salary payment path later discharges. It stays empty when the net works out to exactly zero, because no open item is raised in that case. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | Yes | The person being settled, keyed on Resource; posting refuses without it. The Employee record that gets closed out at the end is found by matching this against Employee.ResourceId, so a settlement for a Resource with no Employee row still posts but closes nobody. | | `Status` | Status | PickList | | The seeded list also offers Approved and In Progress, which no code path sets or reads. Values: Draft, Posted, Paid, Approved, In Progress. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this FullAndFinalSettlement. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this FullAndFinalSettlement. | | `EditInLine` | Edit | EditInline | Edit | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a FullAndFinalSettlement. | | `PostSettlement` | Post | ServerAction (`PostSettlement`) | Posts the settlement rather than merely approving it: it builds one payroll journal debiting each payable line's expense account, crediting each deduction line's payable account and crediting Payroll Payable for the net, dates it on the Last Working Day, raises a Resource-keyed payable open item for any positive net, sets Status to Posted and stores the net and the journal. It then closes the person out, setting the matching Employee to SettlementStatus Settled and EmploymentStatus Exited and filling Date Of Exit if empty. It refuses when the settlement is already posted, has no Resource, has no lines with a non-zero amount, has a line missing its required GL account, when no Payroll Payable control account is configured, or when deductions exceed payables. | | `View` | View | View | View this FullAndFinalSettlement. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `BranchId` | | | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — looks up via `PayrollPayableOpenTransactionId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [InterestCharge](/docs/reference/entities/interest-charge/) — referenced by via `SourceRecordId` - [FullAndFinalSettlementLine](/docs/reference/entities/full-and-final-settlement-line/) — referenced by via `FullAndFinalSettlementId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # General Ledger — entity reference URL: https://xmatix.com/docs/reference/entities/general-ledger/ Last reviewed: 2026-08-16 A decommissioned legacy ledger table. Its physical table was dropped when the balanced journal ledger replaced it, and the general ledger is now a view over posted journal lines rather than a table of its own — reads and writes against this entity will not work, and first-party reports that referenced it were retired. Any question about ledger entries, account movements or postings should be answered from Journal and JournalLine instead. The metadata row survives only because entity definitions are upsert-only in the seed engine. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Amount` | Amount Signed | Currency | | | | `AmountCrDr` | Amount | Calculated | | | | `BillId` | Bill | Lookup → [Bill](/docs/reference/entities/bill/) | | | | `BillLineId` | BillLine | Lookup → [BillLine](/docs/reference/entities/bill-line/) | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Credit` | Credit (Deprecated) | Currency | | | | `Debit` | Debit (Deprecated) | Currency | | | | `Details` | Details | Text | | | | `EffectiveAmount` | Effective Amount | Calculated | | | | `ExternalId` | External | Text | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `Id` | Id | Guid | Yes | | | `IsAccountBalancePosted` | Is Account Balance Posted | Boolean | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PostingDate` | Posting Date | Date | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Reference` | Reference | Text | | | | `SourceDocumentName` | Source Document Name | Text | Yes | | | `TransactionType` | Transaction Type | PickList | Yes | Values: Invoice, InvoiceLine, PaymentTaken, PaymentTakenRelated, PaymentGiven, PaymentGivenRelated, BillLine, CreditNote, CreditNoteLine, DebitNote, DebitNoteLine, Journal, JournalLine, JournalRelated, Inventory, InventoryRelated, GoodReceipt. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Amount Validation | `Amount`, Error | Amount can't be zero | Amount rule Validation. | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [BillLine](/docs/reference/entities/bill-line/) — looks up via `BillLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Bill](/docs/reference/entities/bill/) — looks up via `BillId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `GeneralLedgerId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `GeneralLedgerId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `GeneralLedgerId` - [DebitNote](/docs/reference/entities/debit-note/) — referenced by via `GeneralLedgerId` - [Payment](/docs/reference/entities/payment/) — referenced by via `GeneralLedgerId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — referenced by via `GeneralLedgerId` - [PurchaseReturn](/docs/reference/entities/purchase-return/) — referenced by via `GeneralLedgerId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `GeneralLedgerId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `GeneralLedgerId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `GeneralLedgerId` - [DebitNoteLine](/docs/reference/entities/debit-note-line/) — referenced by via `GeneralLedgerId` - [Payment](/docs/reference/entities/payment/) — referenced by via `RelatedGeneralLedgerId` - [Bill](/docs/reference/entities/bill/) — referenced by via `GeneralLedgerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GL Period Balance — entity reference URL: https://xmatix.com/docs/reference/entities/glaccount-period-balance/ Last reviewed: 2026-08-16 A rebuildable aggregate of posted journal lines per GL account, fiscal period and dimension tuple — a cache, never the source of truth. Rows are maintained inside the posting unit of work as journals post and reverse, and can be re-derived wholesale from the ledger by the rebuild action on the fiscal period; a verification pass re-aggregates the ledger and reports any drift. To change a balance you post a journal; to repair one you rebuild. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Part of the composite key the balance row is bucketed by, copied from the posted line after its own branch defaulting has run. A blank branch is a distinct bucket, not a wildcard. | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | Part of the composite key, taken from the posted line's resolved business unit. Segment reporting reads these buckets, which is why the line-level resolution order deliberately prefers the branch's unit over the GL account's default. | | `ClosingBalance` | Closing Balance | Currency | | Computed as opening plus period debits minus period credits and rounded to two decimals, so it is signed debit-positive and credit-negative. Because the opening value is never carried forward, in practice this equals the period's net movement rather than a cumulative account balance. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FiscalPeriodId` | Fiscal Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `GSTRegistrationId` | GST Registration | Lookup → [GSTRegistration](/docs/reference/entities/gstregistration/) | | Part of the composite key, carried from the posted line where it is normally derived from the branch. Two registrations on the same account and period therefore hold separate balance rows. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | GL Account Name | Text, unique | Yes | | | `OpeningBalance` | Opening Balance | Currency | | A stored field that neither posting nor the rebuild ever populates: new rows are created with zero and rebuild leaves existing values untouched. Do not read it as a carried-forward prior-period balance — an opening position should be derived from the ledger or taken from the account-ledger and statement actions, which compute their own opening figures. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Stamped from the owning company on the journal header when the row is first created. It is NOT part of the key the posting engine matches rows on — that key is account, period, branch, business unit, registration and the reporting subtype — so this value reflects whichever journal happened to open the row and should not be relied on to scope balances by company; scope through the GL account's company instead. | | `PeriodCredit` | Period Credit | Currency | | The running sum of credit amounts for the same account and dimension tuple within the period. The verification pass re-aggregates the posted ledger and reports any row whose stored debit or credit total differs from the recomputed one. | | `PeriodDebit` | Period Debit | Currency | | The running sum of debit amounts posted to this account and dimension tuple within the fiscal period, incremented as each journal posts and rewritten wholesale by a rebuild. Reversal journals add to this figure on the opposite side rather than subtracting from it, so gross totals stay visible. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Always fails. Removing a derived balance row does not remove the underlying ledger movement, so the platform refuses it outright; the rebuild-ledger-balances action on the fiscal period is the supported way to bring rows back in line with the posted ledger. | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Always fails. Correct a balance by posting or reversing a journal, or resync the whole period with the rebuild-ledger-balances action on the fiscal period. | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | Always fails. These rows are a derived projection of the posted ledger and the platform rejects any create through the data API — the only legitimate writers are journal posting and the rebuild service. To bring a balance into existence, post a journal that touches the account and period. | ## Related entities - [GSTRegistration](/docs/reference/entities/gstregistration/) — looks up via `GSTRegistrationId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `FiscalPeriodId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GL Account — entity reference URL: https://xmatix.com/docs/reference/entities/glaccount/ Last reviewed: 2026-10-10 An account in a company's chart of accounts: the target every journal line debits or credits and the unit every financial statement adds up. Each account belongs to one company through Partner Account. Its Account Type is what posting falls back to when no posting definition matches, its Schedule III Classification decides where its balance appears on the statements, Is Control Account makes a customer or supplier mandatory on every line, and Control Type lets withholding, payroll, expense and clearing postings find it. A chart is usually seeded from a chart template when finance is enabled for a company in Org Settings; ticking GL Posting Enabled on a company also adds a standard starter set marked Is System. See the GL accounts guide at /docs/finance/gl-accounts/ for procedures. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountBalance` | Account Balance | Calculated (calculated) | | A legacy stored figure that nothing maintains — it is written as zero when the standard chart of accounts is seeded and is never updated by posting, reversal or rebuild. It is not a live balance; read balances from the GL period-balance rows or from the account-ledger and balance-statement actions. | | `AccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | An optional grouping of accounts, shown on the create form's main tab and in the Applicability section of the record page. | | `AccountNumber` | Account Code | Text | | Your chart's code for the account, up to 80 characters. Optional, but chart templates and Enable finance use it to recognise accounts the company already has, so keep codes stable once a template has been applied. | | `AccountType` | Account Type | PickList | Yes | The broad classification that drives account determination whenever no posting definition matches: the posting engine looks up an account of the required type for the company, preferring one whose default branch matches the document. Matching ignores spaces and folds several synonyms — tax receivable is treated as tax credit, tax payable and GST payable as other current liability, service and other income as sales, purchases as cost of goods sold, and rent, salary and administrative expense all as expense — so those types cannot be targeted separately by type-based resolution. It is also the fallback for statutory statement classification when no explicit classification is set. Values: Fixed Asset, Accounts Payable, Salaries and Employee Wages, Accounts Receivable, Service Income, Long Term Liability, Rent Expense, Opening Balance Equity, Purchases, Current Assets, Non Current Assets, Other Assets, Tax Credit, Current Liability, Credit Card, Other Liability, Tax Payable, Equity, Income, Inventory, Expense, Retained Earnings, Other Income, Bank, Accumulated Depreciation, Cost Of Goods Sold, Billed Inventory, Unbilled Dispatch, Unbilled Receipt, Sales, Other Current Liability, Other Current Asset, Depreciation Expense, Cash, General and Administrative Expense, Provision. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The account's default branch, not a restriction: transactions and journal lines that reference this account and leave their own branch empty inherit this value. Type-based account determination also prefers an account whose default branch matches the document's branch over one with no branch at all. | | `BusinessUnitId` | Default Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | The account's default business unit, applied to a journal line only as the last resort — after the line, the journal header and the line's branch have all failed to supply one. That ordering is deliberate: the branch is the system of record for which unit a location rolls into, so letting the account default win first would persist branch and unit pairings that exist nowhere in master data. | | `ControlType` | Control Type | PickList | | Names which control the account is, so features can find it: withholding tax, payroll payment and posting, statutory challans, expense claims and advances, company cards and inter-business-unit clearing each look up the company's account of a given control type and stop with a message naming it when none exists. The lookup is an exact match on the stored value, which for multi-word controls has no spaces (AccountsReceivable, AccountsPayable, TdsPayable, TdsReceivable, TcsPayable, PayrollPayable and so on), as written by the chart templates. A multi-word value chosen from this list is stored with spaces and is not recognised by those lookups; single-word values such as Bank and Inventory match either way. Keep exactly one account per control type per company. Values: Payroll Payable, PF Payable, Tax Credit, Accounts Payable, Accounts Receivable, TDS Payable, Gratuity Provision, Tax Payable, TCS Payable, Professional Tax Payable, Bank, ESI Payable, Credit Card Payable, Inventory, TDS Salary Payable, Employee Loan, LWF Payable, Employee Advance, Employee Payable, Interest Expense. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Currency` | Currency | PickList | | | | `Description` | Description | MultiLineText | | A free-text note on what the account is for. Advisory only: nothing in posting, statement or balance resolution reads it. | | `DisclosureNoteGroup` | Disclosure Note Group | Text | | Groups accounts under a common note in the published statements, used by the statutory return builders to identify sets of accounts — reserve accounts for the deposits return, for example — that cannot be told apart by classification alone. | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | Posting hard-fails on any journal line whose account is explicitly inactive, with a message pointing at the posting definition or the line. Accounts with no value set are treated as usable, so deactivation is an opt-in block rather than a default. | | `IsControlAccount` | Is Control Account | Boolean | | Marks the account as a party subledger control: once set, posting refuses any journal line on this account that does not carry a party, and each posted line also maintains a per-party balance row. Employee-facing and tax-authority controls are deliberately left unflagged because their counterparty is not a customer or supplier account. | | `IsSystem` | Is System | Boolean | | Marks the standard starter accounts added when GL Posting Enabled is ticked on a company: cash, bank, receivables, payables, inventory, tax, equity, income, cost of sales and expense accounts, each named after the company and given a four-digit code. Accounts seeded from a chart template by Enable finance are not flagged. It records where the account came from; it does not lock the account against editing. | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | An item group linked to the account, shown in the Applicability section of the record page. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | The account's name as shown in lookups, ledgers and statements. Required. The inactive-account posting error quotes it. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentId` | Parent GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | Points at the parent account, letting the chart form a hierarchy that statement generators roll balances up through. It is a reporting hierarchy only — posting always happens against the specific account named on the line, never against a parent. | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | Yes | The company (legal entity) that owns this account, following the finance convention that the partner account is the company rather than a trading counterparty. Chart-of-accounts lookups, control-account lookups and the account-ledger action are all scoped by it, and an account with no company cannot be resolved by type-based account determination. | | `PostingType` | Posting Type | PickList | | A broad asset/liability/income/expense grouping kept for classification and display. The posting engine does not consult it: account determination works from account type and posting definitions, and statutory statement placement works from the statutory classification, so changing this value does not change where anything posts. Values: Asset, Equity, Expense, Cost of Goods Sold, Income, Liability. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ScheduleIIIClassification` | Schedule III Classification | PickList | | The statutory statement node the account's balance aggregates into. When blank the statement builders fall back to deriving a classification from the account type, so an explicit value here is an override used to place an account that the type-based derivation would put in the wrong section. Values: Finance Costs, Property, Plant and Equipment, Short-term Borrowings, Other Current Liabilities, Long-term Borrowings, Trade Payables, Short-term Loans and Advances, Inventories, Deferred Tax Liabilities (Net), Non-current Investments, Cost of Materials Consumed, Other Non-current Assets, Other Income, Reserves and Surplus, Deferred Tax Assets (Net), Short-term Provisions, Intangible Assets, Long-term Loans and Advances, Share Capital, Other Current Assets, Revenue from Operations, Employee Benefits Expense, Changes in Inventories, Current Investments, Depreciation and Amortisation, Trade Receivables, Long-term Provisions, Other Expenses, Tax Expense, Cash and Cash Equivalents, Other Long-term Liabilities, Purchases of Stock-in-Trade. | | `Subtype` | Sub Type | PickList | | The tax component the account holds. Shown on the form only when Account Type is Tax Payable, Tax Credit or Other Current Liability. When set, a tax amount of that component posts to this account and the component is carried onto the journal line so statements can split the figure; when blank, nothing changes. Values: CGST, SGST, IGST, UTGST, Cess, VAT, TDS, TCS. | | `TaxType` | Tax Type | PickList | | Values: CGST, IGST, UTGST, Cess. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in list page | | `EditEntity` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page | | `EditInList` | Edit | Edit | Edit | | `GetGLAccountBalances` | GL Account Balances (as-on) | ServerAction (`GetGLAccountBalances`) | Company-wide account balances are now served by the GetGLAccountStatement action, which returns signed balances per requested column either point-in-time or as an opening/change/closing movement window; that is what the web and mobile balance-statement widgets call. Invoking this name will not produce balances. | | `GetGLAccountBalancesMatrix` | GL Account Balances (by dimension) | ServerAction (`GetGLAccountBalancesMatrix`) | GL account balances pivoted into columns by branch / business unit / GSTIN / cost centre / period (Balance Statement comparative). | | `GetGLAccountLedger` | GL Account Ledger | ServerAction (`GetGLAccountLedger`) | Returns the transaction ledger for one GL account: the opening balance as at the from-date, the posted journal lines in the window with a running balance, and the closing balance. It is date-driven rather than period-driven, and accepts optional filters for party (to narrow a control account to a single customer or supplier), branch, business unit, GST registration and cost centre. The account must belong to a company, and the amounts come from the posted ledger, not from the balance cache. | | `GetGLAccountStatement` | GL Account Statement | ServerAction (`GetGLAccountStatement`) | Signed GL balances per column (point-in-time or Opening/Change/Closing movement) for the Balance Statement. | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `ParentId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [TdsChallan](/docs/reference/entities/tds-challan/) — referenced by via `PayableGLAccountId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `GLAccountId` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — referenced by via `ExpenseGLAccountId` - [CompanyCard](/docs/reference/entities/company-card/) — referenced by via `BankGLAccountId` - [CurrencyRevaluationLine](/docs/reference/entities/currency-revaluation-line/) — referenced by via `GLAccountId` - [PayrollComponent](/docs/reference/entities/payroll-component/) — referenced by via `PayableGLAccountId` - [PartyPeriodBalance](/docs/reference/entities/party-period-balance/) — referenced by via `ControlGLAccountId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `ControlGLAccountId` - [BudgetCommitment](/docs/reference/entities/budget-commitment/) — referenced by via `GLAccountId` - [TdsChallan](/docs/reference/entities/tds-challan/) — referenced by via `BankGLAccountId` - [ExpenseVoucherLine](/docs/reference/entities/expense-voucher-line/) — referenced by via `ExpenseGLAccountId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `GLAccountId` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — referenced by via `ExpenseGLAccountId` - [RevenueRecognitionSchedule](/docs/reference/entities/revenue-recognition-schedule/) — referenced by via `RevenueGLAccountId` - [Payment](/docs/reference/entities/payment/) — referenced by via `GLAccountId` - [DebitNote](/docs/reference/entities/debit-note/) — referenced by via `GLAccountId` - [Payment](/docs/reference/entities/payment/) — referenced by via `RelatedGLAccountId` - [AccountBalance](/docs/reference/entities/account-balance/) — referenced by via `GLAccountId` - [RecurringDepreciation](/docs/reference/entities/recurring-depreciation/) — referenced by via `DepreciationExpenseGLAccountId` - [FullAndFinalSettlementLine](/docs/reference/entities/full-and-final-settlement-line/) — referenced by via `GLAccountId` - [ExpenseCategory](/docs/reference/entities/expense-category/) — referenced by via `DefaultGLAccountId` - [JournalLine](/docs/reference/entities/journal-line/) — referenced by via `GLAccountId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — referenced by via `GLAccountId` - [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) — referenced by via `PayableGLAccountId` - [GLAccountPeriodBalance](/docs/reference/entities/glaccount-period-balance/) — referenced by via `GLAccountId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — referenced by via `GLAccountId` - [RevenueRecognitionSchedule](/docs/reference/entities/revenue-recognition-schedule/) — referenced by via `DeferredGLAccountId` - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — referenced by via `PaymentGLAccountId` - [CompanyCard](/docs/reference/entities/company-card/) — referenced by via `CreditCardPayableGLAccountId` - [PostingDefinition](/docs/reference/entities/posting-definition/) — referenced by via `GLAccountId` - [AssetDisposal](/docs/reference/entities/asset-disposal/) — referenced by via `ProceedsGLAccountId` - [PayrollRunComponentLine](/docs/reference/entities/payroll-run-component-line/) — referenced by via `GLAccountId` - [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) — referenced by via `BankGLAccountId` - [BudgetLine](/docs/reference/entities/budget-line/) — referenced by via `GLAccountId` - [PayrollRunComponentLine](/docs/reference/entities/payroll-run-component-line/) — referenced by via `PayableGLAccountId` - [Bill](/docs/reference/entities/bill/) — referenced by via `GLAccountId` - [RecurringJournalLine](/docs/reference/entities/recurring-journal-line/) — referenced by via `GLAccountId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `GLAccountId` - [AssetDisposal](/docs/reference/entities/asset-disposal/) — referenced by via `GainLossGLAccountId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `GLAccountId` - [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) — referenced by via `BankGLAccountId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `GLAccountId` - [AssetDisposal](/docs/reference/entities/asset-disposal/) — referenced by via `FixedAssetGLAccountId` - [BankAccount](/docs/reference/entities/bank-account/) — referenced by via `GLAccountId` - [JournalLine](/docs/reference/entities/journal-line/) — referenced by via `GLAccountId2` - [FullAndFinalSettlementLine](/docs/reference/entities/full-and-final-settlement-line/) — referenced by via `PayableGLAccountId` - [PayrollComponent](/docs/reference/entities/payroll-component/) — referenced by via `GLAccountId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `ControlGLAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — referenced by via `ParentId` - [AssetDisposal](/docs/reference/entities/asset-disposal/) — referenced by via `AccumulatedDepreciationGLAccountId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `PaymentGLAccountId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `GLAccountId` - [BankingTransaction](/docs/reference/entities/banking-transaction/) — referenced by via `GLAccountId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `GLAccountId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `GLAccountId` - [RecurringDepreciation](/docs/reference/entities/recurring-depreciation/) — referenced by via `AccumulatedDepreciationGLAccountId` - [ExpenseReimbursementBatch](/docs/reference/entities/expense-reimbursement-batch/) — referenced by via `BankGLAccountId` - [DebitNoteLine](/docs/reference/entities/debit-note-line/) — referenced by via `GLAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Goods Receipt Line — entity reference URL: https://xmatix.com/docs/reference/entities/goods-receipt-line/ Last reviewed: 2026-08-16 One item line of a goods receipt, and the row that converts arriving goods into stock movements and a cost layer. It carries three different quantities that are deliberately not the same number: SupplierQuantity is what the supplier says was sent, ReceivedQuantity is what was actually counted in, and OrderedQuantity is what the source purchase-order line released, with ShortageQuantity and ExcessQuantity derived from the gap between the first two. Nothing posts at line creation; posting happens when PerformReceive sets IsILPostingApproved, at which point the seeded inventory-ledger rules fire, the line is stamped with InventoryLedgerId, and the line's UnitCost becomes the ledger row's unit cost and therefore the cost of the stock layer. Damaged, shortage and excess quantities post to their own separate InventoryStock buckets. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | Set when receiving created a tracked Asset from this line, which happens only for items flagged to track assets and only once the line has a lot. Such lines are also forced to a quantity of one per line, so one receipt line equals one asset. | | `ClaimableQuantity` | Claimable Quantity | Calculated (calculated) | | | | `ComponentNumber` | Component Number | Text | | A second traceability identifier (engine, chassis or equivalent) that, like SerialNumber, the receive action requires on every line still pending inventory posting. It is carried onto the Asset record created for asset-tracked items. | | `ConversionRatio` | Conversion Ratio | Number | | | | `ConversionRatio1` | Conversion Ratio 1 | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DamagedInventoryLedgerId` | Damaged Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | Stamped with the inventory-ledger row raised for this line's damaged quantity, which is a separate posting from the main receipt movement. Its presence is what proves damage was booked rather than merely recorded. | | `DamagedQuantity` | Damaged Quantity | Number | | Quantity found damaged on arrival. It is not merely informational: a seeded ledger rule posts it into the separate Damaged inventory bucket rather than into available stock, and it is also rolled up from the inspection lines' damaged quantity when inspection completes, so it can change after the line was first keyed. | | `DateOfExpiry` | Date Of Expiry | Date | | | | `DateOfMFG` | Date Of MFG | Date | | | | `ExcessQuantity` | Excess Quantity | Calculated (calculated) | | | | `ExternalId` | External | Text, unique | | | | `GoodsReceiptId` | Goods Receipt | Lookup → [GoodsReceipt](/docs/reference/entities/goods-receipt/) | | | | `Id` | Id | Guid | Yes | | | `InspectionAdjustmentInventoryLedgerId` | Inventory Ledger Inspection Adjustment | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | | | `InspectionInventoryLedgerId` | Inventory Ledger Inspection | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | Stamped with the inventory-ledger row that moved this line's quantity into the Inspection bucket when inspection started; the reversal on completion is tracked separately by InspectionAdjustmentInventoryLedgerId. | | `InspectionQuantity` | Inspection Quantity | Number | | The quantity currently held under quality inspection for this line. It is set to the received quantity automatically when the item is flagged as requiring inspection on receipt, and a seeded ledger rule moves that quantity into the Inspection bucket, where it is not available for issue until inspection is completed. | | `InventoryFulfilmentOrderLineId` | Inventory Fulfillment Order Line | Lookup → [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) | | | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | | | `InvoiceQuantity` | Invoice Quantity | Number | | How much of this receipt line has been billed, rolled up from the quantity on the linked bill lines. PendingInvoiceQuantity is received quantity minus this, and it is what the release-bill action checks and what each generated bill line is sized from. | | `IsApproved` | Approved | Boolean | | | | `IsClaimed` | Claimed | Boolean | | | | `IsILPosted` | IL Posted | Boolean | | Records that the inventory-ledger posting for this line has been carried out, as distinct from IsILPostingApproved which is the flag receiving sets to authorise it. The definitive evidence of posting is InventoryLedgerId being populated, which is also what the receive action checks to avoid posting a line twice. | | `IsILPostingApproved` | IL Posting Approved | Boolean | | | | `IsPosted` | Posted | Boolean | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | The stock lot created (or matched) for this line when the receipt is received; until PerformReceive runs it is empty. Editing or deleting a received line drives lot maintenance, and for asset-tracked items the lot is also what the automatically created Asset record is built from. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `MRP` | MRP | Currency | | The maximum retail price printed on the received goods, captured for downstream retail pricing and statutory labelling. It plays no part in receipt valuation, which uses UnitCost. | | `Name` | Document Number | Text | | | | `OrderedQuantity` | Ordered Quantity | Number | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PackageGoodsReceiptLineId` | Package Goods Receipt Line | Lookup → [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) | | Self-reference from a component receipt line to the package (kit) receipt line it belongs to, mirroring the package structure on the purchase order. Component lines post to inventory in their own right, so counting both levels double-counts. | | `PendingInspectionQuantity` | Pending Inspection Quantity | Calculated (calculated) | | | | `PendingInvoiceQuantity` | Pending Invoice Quantity | Calculated (calculated) | | | | `PipelineQuantity` | Pipeline Quantity | Calculated (calculated) | | | | `PurchaseOrderLineId` | Purchase Order Line | Lookup → [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) | | | | `ReceivedQuantity` | Received Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReturnedQuantity` | Returned Quantity | Number | | Quantity returned to the supplier from this receipt line, rolled up from credit-note lines whose parent credit note is a bill return. The stock and value reversal itself is a separate inventory-ledger movement of type 'PurchaseReturn' raised from the credit note, not from this receipt. | | `SerialNumber` | Serial Number | Text | | A traceability identifier that is mandatory at receiving: the receive action refuses to post any line that still lacks it, alongside ComponentNumber. That requirement is specific to receiving; the other goods-receipt actions do not enforce it. | | `ShipmentLineId` | Shipment Line | Lookup → [ShipmentLine](/docs/reference/entities/shipment-line/) | | | | `ShortageQuantity` | Shortage Quantity | Calculated (calculated) | | | | `SKUId` | Item SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StartedInspectionQuantity` | Started Inspection Quantity | Number | | How much of this line has been drawn into inspection lines so far, rolled up from the received quantity on those inspection lines. PendingInspectionQuantity is received quantity minus this, and it is the gate that decides whether starting an inspection has anything to do. | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | The bin or location within the branch the goods are put away to. It is carried onto the split lines when a receipt line is broken up by maximum lot size, and it narrows the stock bucket the ledger posting increments. | | `SupplierQuantity` | Supplier Quantity | Number | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | The receipt cost basis for this line, and the single most important value on it: it is copied forward from the source purchase-order line's unit cost or the source shipment line's unit price at creation, it becomes the unit cost of the inventory-ledger row and therefore of the stock cost layer, and it is what the header TotalAmount (received quantity times unit cost) and the goods-received accrual journal are built from. A receipt keyed by hand with no source document has no cost carried in, so the lot and the journal will value at zero unless it is entered. | | `UOM` | UOM | PickList | | Values: MB, Messages, Pack, Each. | | `UOM1` | UOM1 | PickList | | Values: Pack, Each. | | `UOMQuantity` | UOM Quantity | Number | | | | `UOMQuantity1` | UOM Quantity1 | Number | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditReceiptLine` | Edit | Edit | The edit form used from the receiving view, where the quantities that matter are keyed. Editing the supplier quantity on a saved line re-runs the over-receipt check and re-rolls the parent purchase-order and shipment line counters, and editing quantities on a line already approved for posting drives the inventory posting, so this is not a cosmetic edit. | | `MainNew` | New | New | New | | `New` | Quick Add | NewInline | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | XM_DateOfExpiryValidation | `DateOfExpiry`, Error | Date Of Expiry should be less than Date Of MFG | Expiry date validation | | XM_DateOfMFGValidation | `DateOfMFG`, Error | Date Of MFG should be less than or equal to today's date | Date Of MFG should be less than or equal to today's date | | XM_MRPValidation | `MRP`, Error | MRP can't be negative | MRP can't be negative | | XM_OrderedQuantityValidation | `OrderedQuantity`, Error | Ordered Quantity can't be negative | Ordered Quantity can't be negative | | XM_UnitCostRuleValidation | `UnitCost`, Error, inactive | Unit Cost can't be negative | Unit Cost can't be negative | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — looks up via `PurchaseOrderLineId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `DamagedInventoryLedgerId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — looks up via `PackageGoodsReceiptLineId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — looks up via `GoodsReceiptId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InspectionInventoryLedgerId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InspectionAdjustmentInventoryLedgerId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — looks up via `InventoryFulfilmentOrderLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [ShipmentLine](/docs/reference/entities/shipment-line/) — looks up via `ShipmentLineId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `GoodsReceiptLineId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `PackageGoodsReceiptLineId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `GoodsReceiptLineId` - [InspectionLine](/docs/reference/entities/inspection-line/) — referenced by via `GoodsReceiptLineId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `GoodsReceiptLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Goods Receipt — entity reference URL: https://xmatix.com/docs/reference/entities/goods-receipt/ Last reviewed: 2026-08-16 The inbound receiving document: goods physically arriving at a branch from a supplier, plus the supplier's dispatch and invoice references and transporter details. It is created by PurchaseOrder.PerformReleaseReceipt (PurchaseOrderId set, receipt lines carrying OrderedQuantity) or by a Shipment release (ShipmentId set, receipt lines carrying SupplierQuantity), and can also stand alone with neither. Its actions run the receiving sequence: PerformReceive builds item lots and approves the lines for inventory posting, PerformInspection and PerformInspectionComplete drive quality inspection through InspectionLine rows, PerformReleaseBill creates the supplier Bill, and PerformGLPosting posts the accrual journal (Dr Inventory / Cr unbilled-receipt GR-IR at header TotalAmount) which the Bill later clears. Status has a seeded vocabulary but no code path writes it. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | The receiving date. It is defaulted to the current date when the receipt is created and cannot be edited afterwards - the handler blocks changes to it, along with branch, partner and supplier, once the record exists. | | `ExternalId` | External | Text, unique | | | | `GeneralLedgerId` | General Ledger | Lookup → [GeneralLedger](/docs/reference/entities/general-ledger/) | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `HasLineItems` | Has Line Items | Calculated (calculated) | | | | `Id` | Id | Guid | Yes | | | `InspectionLineId` | Inspection Line | Lookup → [InspectionLine](/docs/reference/entities/inspection-line/) | | Points at a single inspection line, used where a receipt was itself raised out of an inspection (for example a rework or return-to-stock consignment). It is the reverse of the InspectionLines collection, which holds the inspection lines this receipt generated. | | `IsAllocated` | Allocated | Boolean | Yes | Neither this flag nor PerformAllocation is ever read or written. | | `IsBillGenerated` | Bill Generated | Calculated (calculated) | Yes | Intended to record that a supplier bill was released from this receipt, but no code path sets it. PerformReleaseBill creates the Bill with this receipt's id on it, so look for that Bill rather than trusting the flag. | | `IsClaimed` | Claimed | Boolean | Yes | | | `IsGLPosted` | Is GL Posted | Boolean | | Records that this receipt's accrual journal has been posted - the goods-received accrual that debits inventory and credits the unbilled-receipt (GR-IR) account at the header TotalAmount. The supplier Bill later clears that same GR-IR account for every bill line sourced from a receipt line, which is what stops inventory being debited twice. | | `IsGLPostingApproved` | Is GL Posting Approved | Boolean | | Set to true by the general-ledger posting action immediately before the journal is built; it is the approval gate the document posting service reads, not a user-set field. IsGLPosted then records that the journal was written. | | `IsInspected` | Inspected | Calculated (calculated) | Yes | Read the inspection lines to know the inspection state. | | `IsInspectionCompleted` | Inspection Completed | Calculated (calculated) | Yes | Intended to mark inspection closed on the header, but the constant is declared and never assigned; completing inspection only flips InspectionDone on the individual inspection lines. A header with open inspection lines is the real test. | | `IsReceived` | Received | Calculated (calculated) | Yes | A system field that a user may not set on create (the handler rejects it as an attempted change to a system field), but which no code path afterwards sets either. Whether stock actually moved is told by the receipt lines carrying an InventoryLedgerId, not by this flag. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PerformAllocation` | Perform Allocation | Boolean | Yes | A trigger boolean for the disabled receipt-allocation step. Nothing listens to it; allocation of stock to demand happens on the sale order and inventory-fulfilment side instead. | | `PerformInspection` | Perform Inspection | Boolean | Yes | | | `PerformInspectionComplete` | Perform Inspection Complete | Boolean | Yes | | | `PerformPopulateChecklist` | Perform Populate Checklist | Boolean | Yes | | | `PerformReceive` | Perform Receive | Boolean | Yes | | | `PerformReceiveAsync` | Perform Receive Async | Boolean | Yes | Receiving runs synchronously through the PerformReceive server action. | | `PerformReleaseBill` | Perform Release Bill | Boolean | Yes | | | `PurchaseOrderId` | Purchase Order | Lookup → [PurchaseOrder](/docs/reference/entities/purchase-order/) | | | | `ReceivedTime` | Received Time | Date | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `ShipmentId` | Shipment | Lookup → [Shipment](/docs/reference/entities/shipment/) | | | | `Status` | Status | PickList | | Values: Draft, Receive, Start Inspection, Complete Inspection, Bill. | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `SupplierDispatchDate` | Supplier Dispatch Date | Date | | When the supplier dispatched the consignment, as opposed to DocumentDate which is when it was received. The gap between the two is the transit time; neither is used by any calculation in the receiving code. | | `SupplierInvoiceDate` | Supplier Invoice Date | DateAndTime | | Date on the supplier's own invoice for this consignment, distinct from DocumentDate (when the goods were booked in) and from SupplierDispatchDate (when they left the supplier). It is the date carried onto asset records created from this receipt. | | `SupplierInvoiceNumber` | Supplier Invoice Number | Text | | The supplier's own invoice or delivery-note reference for this consignment, copied from the shipment when the receipt was released from one. It is a free-text reference, not validated for uniqueness, and it is carried onto the asset records created for asset-tracked items. | | `TotalAmount` | Total Amount | Calculated (calculated) | | | | `TransporterContactNumber` | Transporter Contact Number | Number | | | | `TransporterName` | Transporter Name | Text | | | | `TransporterReferenceNumber` | Transporter Reference Number | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit In page | | `EditInList` | Edit | EditInline | Edit | | `EditPopUp` | Edit | Edit | Edit | | `New` | New | New | New | | `PerformGLPosting` | Post General Ledger | ServerAction (`PerformGLPosting`) | PerformGLPosting | | `PerformInspection` | Inspection | ServerAction (`PerformInspection`) | PerformInspection | | `PerformInspectionComplete` | Inspection Complete | ServerAction (`PerformInspectionComplete`) | PerformInspectionComplete | | `PerformReceive` | Receive | ServerAction (`PerformReceive`) | Perform Receive | | `PerformReleaseBill` | Release Bill | ServerAction (`PerformReleaseBill`) | Perform Release Bill | | `PostGeneralLedger` | Post General Ledger | ServerAction (`PostGeneralLedger`), inactive | Post goods receipt to General Ledger. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Partner Account Filter | `PartnerAccountId` | | | Only Supplier | `SupplierAccountId` | | ## Related entities - [InspectionLine](/docs/reference/entities/inspection-line/) — looks up via `InspectionLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — looks up via `GeneralLedgerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Shipment](/docs/reference/entities/shipment/) — looks up via `ShipmentId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — looks up via `PurchaseOrderId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `GoodsReceiptId` - [Bill](/docs/reference/entities/bill/) — referenced by via `GoodsReceiptId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `GoodsReceiptId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [InspectionLine](/docs/reference/entities/inspection-line/) — referenced by via `GoodsReceiptId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ParentRecordId` - [Claim](/docs/reference/entities/claim/) — referenced by via `GoodsReceiptId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `GoodsReceiptId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `GoodsReceiptId` - [Asset](/docs/reference/entities/asset/) — referenced by via `GoodsReceiptId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Grade — entity reference URL: https://xmatix.com/docs/reference/entities/grade/ Last reviewed: 2026-08-16 An employee grade/band master referenced by Resource.gradeId. Its main functional role in expenses is policy scoping: an ExpensePolicy with a gradeId only applies to claimants whose Resource carries that grade. rank orders grades by seniority. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Code` | Code | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Rank` | Rank | Number | | Seniority rank of the grade (higher = more senior), for ordering and escalation; the policy engine matches grades by id, not rank. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this Grade. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this Grade. | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a Grade. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Employee](/docs/reference/entities/employee/) — referenced by via `GradeId` - [ExpensePolicy](/docs/reference/entities/expense-policy/) — referenced by via `GradeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GST Fiscal Period — entity reference URL: https://xmatix.com/docs/reference/entities/gstfiscal-period/ Last reviewed: 2026-08-16 One GST return period - a calendar month (month + year) tagged with the Indian financial year it falls in. The scheduled GST-return provisioning job auto-rolls the target period (creating it with an Open status if absent) and then creates one Draft return header per active own GST registration for it: GSTR1, GSTR2B and GSTR3B for normal filers (GSTR3B links via its ReturnPeriodId field) and GSTR6 for ISD registrations. Form 26AS statements also key on it. This is the GST filing calendar; it is separate from the accounting FiscalPeriod used for ledger period close. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FinancialYear` | Financial Year | Text | | Indian financial-year tag in start-end form, e.g. 2025-26: April 2025 through March 2026 all carry the same value. Used to group the twelve monthly periods of a filing year, e.g. for the GSTR-9 annual rollup. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Month` | Month | Number | | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Status` | Status | PickList | | Period state; the provisioning job creates missing periods as Open. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `Type` | Type | Text | | Values: Annual, Month. | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `Year` | Year | Number | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Edit` | Edit | EditInline | Edit | | `New` | New | New | New | ## Related entities - [GSTR3B](/docs/reference/entities/gstr3-b/) — referenced by via `ReturnPeriodId` - [GSTR1](/docs/reference/entities/gstr1/) — referenced by via `GSTFiscalPeriodId` - [Form26ASStatement](/docs/reference/entities/form26-asstatement/) — referenced by via `FiscalPeriodId` - [GSTR2B](/docs/reference/entities/gstr2-b/) — referenced by via `GSTFiscalPeriodId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # B2B Invoice — entity reference URL: https://xmatix.com/docs/reference/entities/gstr1-b2-binvoice/ Last reviewed: 2026-08-16 A single outward B2B invoice in GSTR-1 Table 4, belonging to a GSTR1B2BSupply group (grouped by buyer GSTIN). Its rate-slab IGST/CGST/SGST-UTGST/cess detail is in GSTR1LineItem rows referencing it polymorphically; taxableRate and taxAmount on the row are per-invoice figures bound for the list view. Books rows are merged incrementally by the originating Invoice id, so re-processing updates a row in place instead of duplicating it. Distinct from GSTR2BB2BInvoice, which is the inward (purchase-side) counterpart in the GSTR-2B statement. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTIN` | GSTIN | Text | | | | `GSTR1B2BSupplyId` | B2B Supply | Lookup → [GSTR1B2BSupply](/docs/reference/entities/gstr1-b2-bsupply/) | | | | `Id` | Id | Guid | Yes | | | `InvoiceDate` | Invoice Date | Date | | | | `InvoiceNumber` | Invoice Number | Text | | | | `InvoiceType` | Invoice Type | Text | | GST invoice classification with Regular as the default (covers the SEZ / deemed-export variants of Table 4). Distinct from the document's commercial type - this is the GSTN reporting category. | | `InvoiceValue` | Invoice Value | Currency | | | | `IsCarriedForward` | Carried Forward | Boolean | | | | `IsIgnored` | Ignored | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlaceOfSupply` | Place Of Supply | Text | | | | `RecordTypeId` | Record Type | Guid | | | | `ReverseCharge` | Reverse Charge | Boolean | | Whether the supply is taxed under reverse charge, i.e. the recipient pays the tax. Boolean here on the outward side; the GSTR-2B inward counterpart stores it as a Y/N string. | | `Source` | Source | Text | | | | `SourceRecordId` | Source Record | Guid, hidden | | | | `TaxableRate` | Taxable Rate | Decimal | | Per-invoice tax rate bound onto the row for list views. The authoritative rate-slab breakup (one row per rate with the IGST/CGST/SGST-UTGST/cess split) lives in GSTR1LineItem children, not here. | | `TaxAmount` | Tax Amount | Decimal | | Per-invoice total tax bound onto the row for list views; the rate-slab detail behind it is in GSTR1LineItem rows referencing this invoice polymorphically. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `CarryForward` | Carry Forward | ServerAction | The recon grid's row-level carry-forward decision on a B2B invoice - same shared implementation as the GSTR1 header's CarryForward: the selected document is reported in the next period's filing instead of this one, without moving or copying the row. Portal rows and already-carried rows are rejected. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Edit` | Edit | Edit, inactive | edit | | `Ignore` | Ignore | ServerAction | The recon grid's row-level ignore decision on a B2B invoice - same shared implementation as the GSTR1 header's Ignore: the document is dropped from the filing outright and no later filing picks it up. Portal rows are rejected. | | `New` | New | New, inactive | New | ## Related entities - [GSTR1B2BSupply](/docs/reference/entities/gstr1-b2-bsupply/) — looks up via `GSTR1B2BSupplyId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # B2B Supply — entity reference URL: https://xmatix.com/docs/reference/entities/gstr1-b2-bsupply/ Last reviewed: 2026-08-16 GSTR-1 Table 4 grouping row - supplies to a registered buyer, grouped by the buyer's GSTIN (buyerGstin) under a GSTR1 header. The individual invoices are GSTR1B2BInvoice children, and the per-rate tax breakup lives in GSTR1LineItem rows that point back polymorphically. Carries the Books-vs-Portal source discriminator and the row-level reconciliation decision flags set by the CarryForward and Ignore actions. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BuyerGstin` | Buyer GSTIN | Text | | The registered buyer's GSTIN - the grouping key of this Table 4 section; all GSTR1B2BInvoice children under this row belong to that buyer. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR1Id` | GSTR-1 Header | Lookup → [GSTR1](/docs/reference/entities/gstr1/) | | | | `Id` | Id | Guid | Yes | | | `IsCarriedForward` | Carried Forward | Boolean | | | | `IsIgnored` | Ignored | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlaceOfSupply` | Place Of Supply | Text | | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | EditInline | Edit | | `New` | New | New | New | ## Related entities - [GSTR1](/docs/reference/entities/gstr1/) — looks up via `GSTR1Id` - [GSTR1B2BInvoice](/docs/reference/entities/gstr1-b2-binvoice/) — referenced by via `GSTR1B2BSupplyId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # B2C Large Invoice — entity reference URL: https://xmatix.com/docs/reference/entities/gstr1-b2-clinvoice/ Last reviewed: 2026-08-16 A single B2C-large invoice in GSTR-1 Table 5, belonging to a GSTR1B2CLSupply group. Carries the invoice identity and value plus taxableValue/taxAmount; the rate-slab tax breakup is captured by GSTR1LineItem rows referencing it polymorphically. Books rows merge incrementally by the originating Invoice id. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTIN` | GSTIN | Text | | | | `GSTR1B2CLSupplyId` | B2C Large Supply | Lookup → [GSTR1B2CLSupply](/docs/reference/entities/gstr1-b2-clsupply/) | | | | `Id` | Id | Guid | Yes | | | `InvoiceDate` | Invoice Date | Date | | | | `InvoiceNumber` | Invoice Number | Text | | | | `InvoiceValue` | Invoice Value | Currency | | | | `IsCarriedForward` | Carried Forward | Boolean | | | | `IsIgnored` | Ignored | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlaceOfSupply` | Place of Supply | Text | | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `SourceRecordId` | Source Record | Guid, hidden | | | | `TaxableValue` | Taxable Rate | Decimal | | | | `TaxAmount` | Tax Amount | Decimal | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Edit` | Edit | Edit | edit | ## Related entities - [GSTR1B2CLSupply](/docs/reference/entities/gstr1-b2-clsupply/) — looks up via `GSTR1B2CLSupplyId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # B2C Large Supply — entity reference URL: https://xmatix.com/docs/reference/entities/gstr1-b2-clsupply/ Last reviewed: 2026-08-16 GSTR-1 Table 5 grouping row - B2C large: inter-state supplies to unregistered buyers exceeding the per-invoice threshold, grouped by place of supply under a GSTR1 header. The threshold is period-aware in the materializer (100,000 rupees from August 2024, 250,000 before), so historical periods rebuild on the floor in force then. Individual invoices are GSTR1B2CLInvoice children. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR1Id` | GSTR-1 Header | Lookup → [GSTR1](/docs/reference/entities/gstr1/) | | | | `Id` | Id | Guid | Yes | | | `IsCarriedForward` | Carried Forward | Boolean | | | | `IsIgnored` | Ignored | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlaceOfSupply` | Place Of Supply | Text | | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `New` | New | New | New | ## Related entities - [GSTR1](/docs/reference/entities/gstr1/) — looks up via `GSTR1Id` - [GSTR1B2CLInvoice](/docs/reference/entities/gstr1-b2-clinvoice/) — referenced by via `GSTR1B2CLSupplyId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # B2C Small Supply — entity reference URL: https://xmatix.com/docs/reference/entities/gstr1-b2-cssupply/ Last reviewed: 2026-08-16 GSTR-1 Table 7 row - B2C small: aggregated supplies to unregistered buyers, summarised by supply scope (intra/inter), place of supply and tax rate. Pre-aggregated, so the taxable value and IGST/CGST/SGST-UTGST/cess amounts sit directly on the row with no per-invoice or line-item children. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Currency | | | | `Cess` | Cess | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR1Id` | GSTR-1 Header | Lookup → [GSTR1](/docs/reference/entities/gstr1/) | | | | `Id` | Id | Guid | Yes | | | `IntegratedTax` | Integrated Tax | Currency | | | | `IsCarriedForward` | Carried Forward | Boolean | | | | `IsIgnored` | Ignored | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlaceOfSupply` | Place Of Supply | Text | | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `StateUTTax` | State/UT Tax | Currency | | | | `SupplyType` | Supply Type | Text | | Supply scope of this aggregated B2C-small row: intra-state or inter-state (defaults to intra). Part of the aggregation key together with place of supply and tax rate. | | `TaxableValue` | Taxable Value | Currency | | | | `TaxRate` | Tax Rate | Decimal | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `New` | New | New | New | ## Related entities - [GSTR1](/docs/reference/entities/gstr1/) — looks up via `GSTR1Id` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR1 Credit/Debit Note — entity reference URL: https://xmatix.com/docs/reference/entities/gstr1-credit-debit-note/ Last reviewed: 2026-08-16 GSTR-1 Tables 9 and 10 - a credit or debit note adjusting an earlier outward invoice, under a GSTR1 header. Used for both registered recipients (receiverGstin populated) and unregistered ones (receiverGstin null); noteType distinguishes credit from debit and originalInvoiceNumber/Date reference the adjusted invoice. The per-rate tax breakup lives in GSTR1LineItem rows pointing back polymorphically. Posted sales credit notes flow in via their output TaxTransaction rows and net down the outward liability; purchase-return notes are inward and belong to GSTR-2B instead. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR1Id` | GSTR-1 Header | Lookup → [GSTR1](/docs/reference/entities/gstr1/) | | | | `Id` | Id | Guid | Yes | | | `IsCarriedForward` | Carried Forward | Boolean | | | | `IsIgnored` | Ignored | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NoteDate` | Note Date | Date | | | | `NoteNumber` | Note Number | Text | | | | `NoteType` | Note Type | Text | | Credit or Debit (defaults to Credit). Credit notes net DOWN the outward liability of the period; the note references the adjusted invoice via originalInvoiceNumber/originalInvoiceDate. | | `NoteValue` | Note Value | Currency | | | | `OriginalInvoiceDate` | Original Invoice Date | Date | | | | `OriginalInvoiceNumber` | Original Invoice Number | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlaceOfSupply` | Place Of Supply | Text | | | | `ReceiverGstin` | Receiver GSTIN | Text | | The recipient's GSTIN when the note is against a registered recipient (Table 9); null means an unregistered recipient (Table 10). The same entity stores both. | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `SourceRecordId` | Source Record | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR1](/docs/reference/entities/gstr1/) — looks up via `GSTR1Id` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Document Summary — entity reference URL: https://xmatix.com/docs/reference/entities/gstr1-document-summary/ Last reviewed: 2026-08-16 GSTR-1 Table 13 row - documents issued during the return period: one row per document nature/series with the issued serial range (serialNumberFrom/To), the total issued, the count cancelled, and the resulting net issued. Not auto-derived from TaxTransaction - the Books materializer leaves this table empty. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Cancelled` | Cancelled | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR1Id` | GSTR-1 Header | Lookup → [GSTR1](/docs/reference/entities/gstr1/) | | | | `Id` | Id | Guid | Yes | | | `IsCarriedForward` | Carried Forward | Boolean | | | | `IsIgnored` | Ignored | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NatureOfDocument` | Nature Of Document | Text | | | | `NetIssued` | Net Issued | Number | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `SerialNumberFrom` | Serial Number From | Text | | | | `SerialNumberTo` | Serial Number To | Text | | | | `Source` | Source | Text | | | | `TotalNumber` | Total Number | Number | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR1](/docs/reference/entities/gstr1/) — looks up via `GSTR1Id` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Export Invoice — entity reference URL: https://xmatix.com/docs/reference/entities/gstr1-export-invoice/ Last reviewed: 2026-08-16 A single export invoice in GSTR-1 Table 6, belonging to a GSTR1ExportSupply group. Carries the customs shipping details (port, shippingBillNumber, shippingBillDate) alongside the invoice identity; its rate-slab tax breakup is in GSTR1LineItem rows referencing it polymorphically. Books rows merge incrementally by the originating Invoice id. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR1ExportSupplyId` | Export Supply | Lookup → [GSTR1ExportSupply](/docs/reference/entities/gstr1-export-supply/) | | | | `Id` | Id | Guid | Yes | | | `InvoiceDate` | Invoice Date | Date | | | | `InvoiceNumber` | Invoice Number | Text | | | | `InvoiceValue` | Invoice Value | Currency | | | | `IsCarriedForward` | Carried Forward | Boolean | | | | `IsIgnored` | Ignored | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Port` | Port | Text | | | | `RecordTypeId` | Record Type | Guid | | | | `ShippingBillDate` | Shipping Bill Date | Date | | | | `ShippingBillNumber` | Shipping Bill Number | Text | | | | `Source` | Source | Text | | | | `SourceRecordId` | Source Record | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR1ExportSupply](/docs/reference/entities/gstr1-export-supply/) — looks up via `GSTR1ExportSupplyId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Export Supply — entity reference URL: https://xmatix.com/docs/reference/entities/gstr1-export-supply/ Last reviewed: 2026-08-16 GSTR-1 Table 6 grouping row - export supplies under a GSTR1 header, grouped by payment treatment (exportType: with or without payment of IGST). The individual export invoices are GSTR1ExportInvoice children; the per-rate tax breakup is captured by GSTR1LineItem rows pointing back polymorphically. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `ExportType` | Export Type | Text | | Payment treatment of the export group - with payment of IGST (default) or without. It is the grouping key of Table 6: invoices sit under the group matching their treatment. | | `GSTR1Id` | GSTR-1 Header | Lookup → [GSTR1](/docs/reference/entities/gstr1/) | | | | `Id` | Id | Guid | Yes | | | `IsCarriedForward` | Carried Forward | Boolean | | | | `IsIgnored` | Ignored | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR1](/docs/reference/entities/gstr1/) — looks up via `GSTR1Id` - [GSTR1ExportInvoice](/docs/reference/entities/gstr1-export-invoice/) — referenced by via `GSTR1ExportSupplyId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # HSN Summary — entity reference URL: https://xmatix.com/docs/reference/entities/gstr1-hsnsummary/ Last reviewed: 2026-08-16 GSTR-1 Table 12 row - HSN/SAC-wise summary of outward supplies for the return period: quantity, taxable value and the IGST/CGST/SGST-UTGST/cess breakup per HSN code and rate. Pre-aggregated (tax sits on the row, no line-item children) and re-derived from the document rows on both sides when reconciliation decisions change which documents count. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Currency | | | | `Cess` | Cess | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Description` | Description | Text | | | | `GSTR1Id` | GSTR-1 Header | Lookup → [GSTR1](/docs/reference/entities/gstr1/) | | | | `HsnCode` | HSN/SAC Code | Text | | | | `Id` | Id | Guid | Yes | | | `IntegratedTax` | Integrated Tax | Currency | | | | `IsCarriedForward` | Carried Forward | Boolean | | | | `IsIgnored` | Ignored | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Quantity` | Quantity | Decimal | | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `StateUTTax` | State/UT Tax | Currency | | | | `TaxableValue` | Taxable Value | Currency | | | | `TaxRate` | Tax Rate | Decimal | | | | `UIProps` | UI Props | Text | | | | `UnitOfMeasurement` | Unit Of Measurement | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `New` | New | New | New | ## Related entities - [GSTR1](/docs/reference/entities/gstr1/) — looks up via `GSTR1Id` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GST Line Item — entity reference URL: https://xmatix.com/docs/reference/entities/gstr1-line-item/ Last reviewed: 2026-08-16 Shared rate-slab tax breakup line for GSTR-1 documents: the taxable value at a single GST rate with its IGST/CGST/SGST-UTGST/cess split. Reused across B2B, B2C-large, export and credit/debit-note documents, so the owning row is referenced polymorphically via parentEntityName + parentRecordId (the same pattern as Journal's source reference); the GSTR1 header is also linked directly (gstr1Id) for return-level roll-ups. B2CS and HSN tables do not use it - they are pre-aggregated with tax on their own rows. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Currency | | | | `Cess` | Cess | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR1Id` | GSTR-1 Header | Lookup → [GSTR1](/docs/reference/entities/gstr1/) | | | | `Id` | Id | Guid | Yes | | | `IntegratedTax` | Integrated Tax | Currency | | | | `IsCarriedForward` | Carried Forward | Boolean | | | | `IsIgnored` | Ignored | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentEntityName` | Parent Entity Name | Text | | The entity name of the owning document row - e.g. GSTR1B2BInvoice, GSTR1B2CLInvoice, GSTR1ExportInvoice or GSTR1CreditDebitNote - paired with parentRecordId. The line item is shared across document tables, so ownership is polymorphic rather than a fixed FK. | | `ParentRecordId` | Parent Record Id | Guid | | Id of the owning document row named by parentEntityName. Together they mirror the Journal source-reference pattern; the gstr1Id link exists separately for return-level roll-ups. | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `StateUTTax` | State/UT Tax | Currency | | | | `TaxableValue` | Taxable Value | Currency | | | | `TaxRate` | Tax Rate | Percent | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR1](/docs/reference/entities/gstr1/) — looks up via `GSTR1Id` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Nil Rated Supply — entity reference URL: https://xmatix.com/docs/reference/entities/gstr1-nil-rated/ Last reviewed: 2026-08-16 GSTR-1 Table 8 row - nil-rated, exempt and non-GST outward supplies, summarised by supplyType (inter/intra x B2B/B2C per the GSTN taxonomy) with one value column per bucket (nilSupplies, exemptSupplies, nonGstSupplies) and no tax amounts. This table is not derivable from TaxTransaction, so the Books materializer leaves it empty; rows come from the portal side or manual entry. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `ExemptSupplies` | Exempt Supplies | Currency | | | | `GSTR1Id` | GSTR-1 Header | Lookup → [GSTR1](/docs/reference/entities/gstr1/) | | | | `Id` | Id | Guid | Yes | | | `IsCarriedForward` | Carried Forward | Boolean | | | | `IsIgnored` | Ignored | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NilSupplies` | Nil Supplies | Currency | | | | `NonGstSupplies` | Non-GST Supplies | Currency | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `SupplyType` | Supply Type | Text | | The GSTN Table 8 bucket this summary row covers - the inter/intra x B2B/B2C taxonomy (default inter-state B2B). Each row then splits its value into nil-rated, exempt and non-GST supplies. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `New` | New | New | New | ## Related entities - [GSTR1](/docs/reference/entities/gstr1/) — looks up via `GSTR1Id` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR1 — entity reference URL: https://xmatix.com/docs/reference/entities/gstr1/ Last reviewed: 2026-08-16 Root of a granular GSTR-1 outward-supply return: one filing per filer GSTIN and return period (the period is the linked GSTFiscalPeriod via gstFiscalPeriodId, not a raw MMYYYY string). Draft headers are auto-provisioned per active GSTRegistration each period by the GST-return provisioning service; the table-wise detail (B2B, B2C large/small, credit/debit notes, exports, nil-rated, HSN summary, documents issued) hangs off it as child collections, and every child row carries a Source discriminator separating Books rows (materialized from output TaxTransaction by ProcessGSTR1Data) from Portal rows (pulled from GSTIN) in the same tables. Status runs a filing lifecycle from Draft to Filed - a Filed return is frozen: re-processing is refused and corrections go through an amendment. Incremental processing uses a header watermark (last processed time + source row count) so unchanged periods skip outright. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FilingDate` | Filing Date | Date | | | | `GSTFiscalPeriodId` | GST Fiscal Period | Lookup → [GSTFiscalPeriod](/docs/reference/entities/gstfiscal-period/) | | The return period, modelled as a link to GSTFiscalPeriod rather than a raw MMYYYY string. Processing is refused while it is empty, and the period's month/year scope the TaxTransaction rows the Books side is built from. | | `GSTIN` | GSTIN | Text | | The filer's own 15-character GSTIN. Format-validated on save; processing and filing are refused while it is empty. Materialization selects output TaxTransaction rows whose own-GSTIN matches this value. | | `Id` | Id | Guid | Yes | | | `IsFiled` | Is Filed | Boolean | | | | `Label` | Label | Text | | | | `LastProcessedSourceCount` | Source Rows Processed | Number, hidden | | | | `LastProcessedUtc` | Last Processed | DateAndTime | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ProcessedInvoiceValue` | Processed Invoice Value | Decimal | | Total processed outward-supply invoice value for the period, written by materialization and surfaced on the GST console GSTR-1 card. A roll-up, not an input. | | `RecordTypeId` | Record Type | Guid | | | | `Status` | Status | PickList | | Filing lifecycle, Draft to Filed. Filed is load-bearing: it freezes the period against re-processing (ProcessGSTR1Data is refused), the filing action refuses an already-Filed return, and the GSTR-9 filed-returns rollup selects on it. Corrections to a Filed period go through an amendment, not a re-process. Values: Draft, Processed, Submitted, Filed, Error. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `CarryForward` | Carry Forward | ServerAction (`CarryForward`) | Row-level reconciliation decision on selected document rows of this filing: report them in the NEXT return period's filing instead of this one. Rows are neither moved nor copied - the decision re-points which return counts them, and the HSN summary re-derives on both filings. The next period's filing need not exist yet (one provisioned later picks the documents up), and the action is legal on a Filed filing - the usual case is a document found missing in GSTN after filing. Rejects an empty selection, non-document rows, Portal rows, rows of another filing, already-carried rows, and an already-Filed next period. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `FileToGSTN` | File To GSTN | ServerAction (`FileToGSTN`) | File GSTR1 | | `GetGSTR1` | Get from GSTR1 | ServerAction (`GetGSTR1`) | Read-only: builds the GSTN-style consolidated summary for one filing - one block per return table with document counts, invoice value and the IGST/CGST/SGST-UTGST/cess totals, plus a drill-down target per row and grand totals - in a single response. Optional source argument selects the Books side (default) or the Portal side; reconciliation decisions are applied, so ignored and carried-forward documents are held out of the figures and reported as separate decision counts. | | `GetGSTR1Reconciliation` | Get GSTR1 Reconciliation | ServerAction (`GetGSTR1Reconciliation`) | Get GSTR1 Reconciliation | | `Ignore` | Ignore | ServerAction (`Ignore`) | Row-level reconciliation decision on selected document rows of this filing: drop them from the filing outright - unlike CarryForward, no later filing picks them up. The filing's summary figures exclude ignored rows and report them in a separate decision count. | | `New` | New | New | New | | `ProcessGSTR1Data` | Process GSTR1 | ServerAction (`ProcessGSTR1Data`) | Materializes the Books side of the filing from the period's output TaxTransaction rows for the filer GSTIN. Incremental: an unchanged period skips outright via the header watermark, and a changed one merges by originating document - rows update in place keeping their ids and reconciliation decisions, new documents append, vanished ones soft-remove. Refused on a Filed return (corrections go through an amendment). An optional rebuild argument forces the legacy wipe-and-rebuild repair path, which discards the reconciliation decisions. Portal rows are never touched. | | `PullFromGSTIN` | Pull from GSTIN | ServerAction (`PullFromGSTIN`) | Push to GSTIN | | `Test` | Test | Edit | test | ## Related entities - [GSTFiscalPeriod](/docs/reference/entities/gstfiscal-period/) — looks up via `GSTFiscalPeriodId` - [GSTR1HSNSummary](/docs/reference/entities/gstr1-hsnsummary/) — referenced by via `GSTR1Id` - [GSTR1ExportSupply](/docs/reference/entities/gstr1-export-supply/) — referenced by via `GSTR1Id` - [GSTR1DocumentSummary](/docs/reference/entities/gstr1-document-summary/) — referenced by via `GSTR1Id` - [GSTR1LineItem](/docs/reference/entities/gstr1-line-item/) — referenced by via `GSTR1Id` - [GSTR1CreditDebitNote](/docs/reference/entities/gstr1-credit-debit-note/) — referenced by via `GSTR1Id` - [GSTR1B2BSupply](/docs/reference/entities/gstr1-b2-bsupply/) — referenced by via `GSTR1Id` - [GSTR1B2CSSupply](/docs/reference/entities/gstr1-b2-cssupply/) — referenced by via `GSTR1Id` - [GSTR1NilRated](/docs/reference/entities/gstr1-nil-rated/) — referenced by via `GSTR1Id` - [GSTR1B2CLSupply](/docs/reference/entities/gstr1-b2-clsupply/) — referenced by via `GSTR1Id` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR2B — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-b/ Last reviewed: 2026-10-10 One GSTR-2B statement: the input tax credit statement GSTN drafts every month from what suppliers filed, for one recipient GSTIN and one monthly GST fiscal period. It is not filed and has no filing status, and it cannot be deleted. GST return provisioning creates one per active regular registration per month, with the expected Generation Date set to the 14th of the following month. Each statement holds two sides in the same section tables. The books side is built by Process GSTR2B (or the Process GSTR-2B data scheduled job) from the period's purchase tax lines: bills become B2B invoices and purchase returns become credit/debit notes. The portal side is fetched from GSTN by Pull From GSTIN through the GSP integration and covers every section, including amendments, ISD credits, imports, e-commerce documents and the ITC summary. Each action changes only its own side. The Reconciliations tab pairs the two sides document by document as Matched, Mismatch, Missing in Books or Missing in GSTN. GSTR-3B table 4A reads only the portal side. See the GSTR-2B guide in the Tax Center documentation for the full procedure. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `CutoffDate` | Cutoff Date | Date | | The last date of supplier filings this statement includes. Supplier filings after it appear in a later month's statement, which explains documents that are in your books but missing from GSTN this month. | | `GenerationDate` | Generation Date | Date | | When GSTN generates the statement. Provisioning sets the expected date, the 14th of the following month, and a successful pull replaces it with the date GSTN reports. The GST console shows Awaiting GSTN Data before this date and Not Synced after it until the statement is pulled. | | `GSTFiscalPeriodId` | GST Fiscal Period | Lookup → [GSTFiscalPeriod](/docs/reference/entities/gstfiscal-period/) | | The monthly GST fiscal period the statement covers. Process GSTR2B and Pull From GSTIN both refuse a statement without it. The scheduled processing job and the automatic pull after GSTN authentication work on statements whose period is Open. | | `GSTIN` | GSTIN | Text | | Your own 15-character GSTIN, the recipient of the supplies. A malformed value is refused on save. Decides which purchase tax lines Process GSTR2B reads and which GST Registration session Pull From GSTIN uses; both actions refuse a statement without it. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | Display name of the statement, set by provisioning as GSTR-2B followed by the period, for example GSTR-2B Aug 2026. | | `LastProcessedSourceCount` | Source Rows Processed | Number, hidden | | Hidden. Number of purchase tax lines read by the last Process GSTR2B run; a lower count on the next run, after a document is deleted, forces reprocessing. | | `LastProcessedUtc` | Last Processed | DateAndTime | | Change time of the newest purchase tax line taken in by the last Process GSTR2B run. Together with the hidden source-row count it lets an unchanged period be skipped. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | Reference of the statement. Statements created with New are numbered by the GSTR-2B Headers Name Setting (series GSTR2B); provisioned statements are named after the GSTIN and period. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ProcessedInvoiceValue` | Processed Invoice Value | Decimal | | Total value (taxable value plus tax) of the books side, written by Process GSTR2B. It is not the ITC amount and not the GSTN figure; the GST console card shows the portal side's value instead. | | `RecordTypeId` | Record Type | Guid | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `AddTransactionInBooks` | Add In Books | ServerAction (`AddTransactionInBooks`) | Shown on the Missing in Books tab. Records nothing on a GSTR-2B statement; post the missing bill through the normal purchase process. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Edit | Delete | | `DeleteListHeader` | Delete List Header | Delete | Delete List Header | | `DeleteListRow` | Delete List Row | Delete | Delete List Row | | `Edit` | Edit | Edit | Edit | | `EditListHeader` | Edit List Header | Edit | Edit List Header | | `EditListRow` | Edit List Row | Edit | Edit List Row | | `GetGSTR2B` | Get GSTR2B | ServerAction (`GetGSTR2B`) | Returns the section-by-section summary shown on the Overview tab: document count, taxable value and the four tax heads per section, plus the ITC available and not-available totals when present. Books side by default. Read-only. | | `GetGSTR2BReconciliation` | Get GSTR2B Reconciliation | ServerAction (`GetGSTR2BReconciliation`) | Returns the document-by-document comparison of the books and portal sides shown on the Reconciliations tab, with a Matched, Mismatch, Missing in Books or Missing in GSTN status per document. Read-only; nothing is stored. | | `IgnoreTransaction` | Ignore | ServerAction (`IgnoreTransaction`) | Shown on the Missing in Books and Missing in GSTN tabs. Records nothing on a GSTR-2B statement. | | `New` | New | New | New | | `ProcessGSTR2BData` | Process GSTR2B | ServerAction (`ProcessGSTR2BData`) | Process GSTR2B. Builds the books side from the period's purchase tax lines for the statement's GSTIN that carry a supplier account: bills into B2B, purchase returns into credit/debit notes. Incremental: skips when nothing changed, otherwise updates changed documents, adds new ones and removes vanished ones. Never touches the portal side. Refused without a GSTIN or GST fiscal period. | | `PullFromGSTIN` | Pull From GSTIN | ServerAction (`PullFromGSTIN`) | Pull From GSTIN. Opens the GSTN authentication panel; once the GSTIN has a live session, Proceed requests the statement from GSTN through the GSP integration. The reply is normally imported automatically, replacing every portal section and the ITC summary and setting Pull Status to Imported; a second click imports a reply that is still waiting. A GSTN refusal sets Pull Status to FetchFailed with the reason in Pull Message and keeps the previous portal rows. Needs a GST Registration authenticated within the last 6 hours. | | `VendorFollowup` | Vendor Follow-up | ServerAction (`VendorFollowup`) | Shown on the Missing in GSTN tab. Records nothing on a GSTR-2B statement; follow up with the supplier through your usual process. | ## Related entities - [GSTFiscalPeriod](/docs/reference/entities/gstfiscal-period/) — looks up via `GSTFiscalPeriodId` - [GSTR2BITCSummary](/docs/reference/entities/gstr2-bitcsummary/) — referenced by via `GSTR2BId` - [GSTR2BReconciliationEntry](/docs/reference/entities/gstr2-breconciliation-entry/) — referenced by via `GSTR2BId` - [GSTR2BECOSupplier](/docs/reference/entities/gstr2-becosupplier/) — referenced by via `GSTR2BId` - [GSTR2BB2BSupplier](/docs/reference/entities/gstr2-bb2-bsupplier/) — referenced by via `GSTR2BId` - [GSTR2BCDNRASupplier](/docs/reference/entities/gstr2-bcdnrasupplier/) — referenced by via `GSTR2BId` - [GSTR2BIMPGSEZRecord](/docs/reference/entities/gstr2-bimpgsezrecord/) — referenced by via `GSTR2BId` - [GSTR2BIMPGRecord](/docs/reference/entities/gstr2-bimpgrecord/) — referenced by via `GSTR2BId` - [GSTR2BISDASupplier](/docs/reference/entities/gstr2-bisdasupplier/) — referenced by via `GSTR2BId` - [GSTR2BB2BASupplier](/docs/reference/entities/gstr2-bb2-basupplier/) — referenced by via `GSTR2BId` - [GSTR2BCDNRSupplier](/docs/reference/entities/gstr2-bcdnrsupplier/) — referenced by via `GSTR2BId` - [GSTR2BISDSupplier](/docs/reference/entities/gstr2-bisdsupplier/) — referenced by via `GSTR2BId` - [GSTR2BECOASupplier](/docs/reference/entities/gstr2-becoasupplier/) — referenced by via `GSTR2BId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # B2B Amendment Invoice — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bb2-bainvoice/ Last reviewed: 2026-08-16 An amended inward B2B invoice in GSTR-2B, belonging to a GSTR2BB2BASupplier. Same shape as GSTR2BB2BInvoice plus the amendment references: originalInvoiceNumber/originalInvoiceDate identify the invoice being amended and differencePercent carries the differential percentage. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Currency | | | | `Cess` | Cess | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DifferencePercent` | Difference Percent | Decimal | | The differential percentage GSTN reports on an amendment - how much the amended invoice differs from the original identified by originalInvoiceNumber/originalInvoiceDate. | | `GSTR2BB2BASupplierId` | B2B Amendment Supplier | Lookup → [GSTR2BB2BASupplier](/docs/reference/entities/gstr2-bb2-basupplier/) | | | | `Id` | Id | Guid | Yes | | | `ImsStatus` | IMS Status | Text | | | | `IntegratedTax` | Integrated Tax | Currency | | | | `InvoiceDate` | Invoice Date | Date | | | | `InvoiceNumber` | Invoice Number | Text | | | | `InvoiceType` | Invoice Type | Text | | | | `InvoiceValue` | Invoice Value | Currency | | | | `Irn` | IRN | Text | | | | `ItcAvailability` | ITC Availability | Text | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OriginalInvoiceDate` | Original Invoice Date | Date | | | | `OriginalInvoiceNumber` | Original Invoice Number | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlaceOfSupply` | Place Of Supply | Text | | | | `RecordTypeId` | Record Type | Guid | | | | `ReverseCharge` | Reverse Charge | Text | | | | `SourceType` | Source Type | Text | | | | `StateUTTax` | State/UT Tax | Currency | | | | `TaxableValue` | Taxable Value | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete List Header | Delete | DeleteListHeader | | `DeleteListRow` | Delete List Row | Delete | Delete List Row | | `EditInLine` | Edit In Line | Edit | EditInLine | | `EditListHeader` | Edit List Header | EditInline | Edit List Header | | `EditListRow` | Edit List Row | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [GSTR2BB2BASupplier](/docs/reference/entities/gstr2-bb2-basupplier/) — looks up via `GSTR2BB2BASupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # B2B Amendment Supplier — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bb2-basupplier/ Last reviewed: 2026-08-16 GSTR-2B B2B amendment section grouping row - supplier amendments to previously reported B2B invoices, grouped by supplier GSTIN under a GSTR2B header. Its amended invoices are GSTR2BB2BAInvoice children. Amendment sections are Portal-only: the Books materializer never writes them. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR2BId` | GSTR-2B Header | Lookup → [GSTR2B](/docs/reference/entities/gstr2-b/) | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `SupplierGstin` | Supplier GSTIN | Text | | | | `TradeName` | Trade Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete List Header | Delete | Delete List Header | | `DeleteListRow` | Delete List Row | Delete | DeleteListRow | | `Edit` | Edit | Edit | Edit | | `EditListHeader` | Edit List Header | EditInline | Edit List Header | | `EditListRow` | Edit List Row | Edit | Edit List Row | | `New` | New | New | New | ## Related entities - [GSTR2B](/docs/reference/entities/gstr2-b/) — looks up via `GSTR2BId` - [GSTR2BB2BAInvoice](/docs/reference/entities/gstr2-bb2-bainvoice/) — referenced by via `GSTR2BB2BASupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # B2B Invoice 2B — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bb2-binvoice/ Last reviewed: 2026-08-16 A single inward B2B invoice in the GSTR-2B statement, belonging to a GSTR2BB2BSupplier. Carries its own tax breakup directly on the row (no line-item indirection, unlike GSTR-1), plus the ITC availability flag, the IMS action status, the e-invoice IRN and the GSTN source type. Books rows are merged incrementally by the originating Bill id, so a re-run updates the row in place and preserves the IMS action recorded on it. Named with the 2B prefix to distinguish it from the outward GSTR1B2BInvoice. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Currency | | | | `Cess` | Cess | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR2BB2BSupplierId` | B2B Supplier | Lookup → [GSTR2BB2BSupplier](/docs/reference/entities/gstr2-bb2-bsupplier/) | | | | `Id` | Id | Guid | Yes | | | `ImsStatus` | IMS Status | Text | | The Invoice Management System action recorded on this document. It survives incremental re-processing (rows merge in place by originating document) but is discarded by the wipe-and-rebuild repair path. | | `IntegratedTax` | Integrated Tax | Currency | | | | `InvoiceDate` | Invoice Date | Date | | | | `InvoiceNumber` | Invoice Number | Text | | | | `InvoiceType` | Invoice Type | Text | | | | `InvoiceValue` | Invoice Value | Currency | | | | `Irn` | IRN | Text | | The e-invoice Invoice Reference Number of the supplier's document, when it was e-invoiced. Identity aid when pairing against local Bills. | | `ItcAvailability` | ITC Availability | Text | | Y/N flag: whether input tax credit is available on this document. On Books-materialized rows it is Y when any component of the document is ITC-eligible, else N; on Portal rows it is GSTN's verdict. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlaceOfSupply` | Place Of Supply | Text | | | | `RecordTypeId` | Record Type | Guid | | | | `ReverseCharge` | Reverse Charge | Text | | | | `SourceRecordId` | Source Record | Guid, hidden | | | | `SourceType` | Source Type | Text | | GSTN's source classification for how the document entered the statement, as pulled from the portal. Not to be confused with the supplier row's Books/Portal source discriminator. | | `StateUTTax` | State/UT Tax | Currency | | | | `TaxableValue` | Taxable Value | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete List Header | Delete | Delete List Header | | `DeleteListRow` | Delete List Row | Delete | Delete List Row | | `Edit` | Edit | EditInline | Edit | | `EditListHeader` | Edit List Header | EditInline | Edit List Header | | `EditListRow` | Edit List Row | Edit | Edit List Row | | `New` | New | New | New | ## Related entities - [GSTR2BB2BSupplier](/docs/reference/entities/gstr2-bb2-bsupplier/) — looks up via `GSTR2BB2BSupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # B2B Supplier — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bb2-bsupplier/ Last reviewed: 2026-08-16 GSTR-2B B2B section grouping row - inward supplies from one registered supplier, grouped by the supplier's GSTIN under a GSTR2B header, with the supplier's trade name, the period they reported (supplyPeriod) and when they filed (supplierFilingDate). Its invoices are GSTR2BB2BInvoice children. The supplier row is the Books-vs-Portal unit: leaf invoices carry only the supplier FK and inherit their side from it. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR2BId` | GSTR-2B Header | Lookup → [GSTR2B](/docs/reference/entities/gstr2-b/) | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `SupplierFilingDate` | Supplier Filing Date | Date | | When the supplier filed the GSTR-1 these documents came from, as reported by GSTN. Relative to the statement's cutoffDate this explains which statement month a document landed in. | | `SupplierGstin` | Supplier GSTIN | Text | | | | `SupplyPeriod` | Supply Period | Text | | The return period (MMYYYY) the supplier reported these documents in - which can differ from this statement's period when the supplier filed late (documents land in the statement of the month they were filed by the cutoff). | | `TradeName` | Trade Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete List Header | Delete | Delete List Header | | `DeleteListRow` | Delete List Row | Delete | Delete List Row | | `EditInLine` | Edit In Line | EditInline | Edit In Line | | `EditListHeader` | Edit List Header | EditInline | Edit List Header | | `EditListRow` | Edit List Row | Edit | Edit List Row | | `New` | New | New | New | ## Related entities - [GSTR2B](/docs/reference/entities/gstr2-b/) — looks up via `GSTR2BId` - [GSTR2BB2BInvoice](/docs/reference/entities/gstr2-bb2-binvoice/) — referenced by via `GSTR2BB2BSupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # CDN Amendment Note — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bcdnranote/ Last reviewed: 2026-08-16 An amended inward credit/debit note in GSTR-2B, belonging to a GSTR2BCDNRASupplier. Same shape as GSTR2BCDNRNote plus the amendment references: originalNoteNumber/originalNoteDate identify the note being amended and differencePercent carries the differential percentage. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Currency | | | | `Cess` | Cess | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DifferencePercent` | Difference Percent | Decimal | | | | `GSTR2BCDNRASupplierId` | CDN Amendment Supplier | Lookup → [GSTR2BCDNRASupplier](/docs/reference/entities/gstr2-bcdnrasupplier/) | | | | `Id` | Id | Guid | Yes | | | `ImsStatus` | IMS Status | Text | | | | `IntegratedTax` | Integrated Tax | Currency | | | | `ItcAvailability` | ITC Availability | Text | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NoteDate` | Note Date | Date | | | | `NoteNumber` | Note Number | Text | | | | `NoteType` | Note Type | Text | | | | `OriginalNoteDate` | Original Note Date | Date | | | | `OriginalNoteNumber` | Original Note Number | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `StateUTTax` | State/UT Tax | Currency | | | | `SupplyType` | Supply Type | Text | | | | `TaxableValue` | Taxable Value | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR2BCDNRASupplier](/docs/reference/entities/gstr2-bcdnrasupplier/) — looks up via `GSTR2BCDNRASupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # CDN Amendment Supplier — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bcdnrasupplier/ Last reviewed: 2026-08-16 GSTR-2B credit/debit-note amendment section grouping row - supplier amendments to previously reported notes, grouped by supplier GSTIN under a GSTR2B header. Its amended notes are GSTR2BCDNRANote children. Portal-only; modelled by analogy to GSTR2BCDNRSupplier since the GSTN spec lists this section without a detailed field table. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR2BId` | GSTR-2B Header | Lookup → [GSTR2B](/docs/reference/entities/gstr2-b/) | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `SupplierGstin` | Supplier GSTIN | Text | | | | `TradeName` | Trade Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR2B](/docs/reference/entities/gstr2-b/) — looks up via `GSTR2BId` - [GSTR2BCDNRANote](/docs/reference/entities/gstr2-bcdnranote/) — referenced by via `GSTR2BCDNRASupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # CDNR Note — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bcdnrnote/ Last reviewed: 2026-08-16 A single inward credit or debit note in GSTR-2B, belonging to a GSTR2BCDNRSupplier, with its own tax breakup, ITC availability and IMS action status. Books rows are materialized from posted purchase credit/debit notes and merged incrementally by the originating document id, preserving the IMS action across re-runs. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Currency | | | | `Cess` | Cess | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR2BCDNRSupplierId` | CDN Supplier | Lookup → [GSTR2BCDNRSupplier](/docs/reference/entities/gstr2-bcdnrsupplier/) | | | | `Id` | Id | Guid | Yes | | | `ImsStatus` | IMS Status | Text | | | | `IntegratedTax` | Integrated Tax | Currency | | | | `ItcAvailability` | ITC Availability | Text | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NoteDate` | Note Date | Date | | | | `NoteNumber` | Note Number | Text | | | | `NoteType` | Note Type | Text | | Credit or debit marker (GSTN short code) for this inward note. Credit notes from suppliers reduce the ITC you can claim; the note carries its own tax breakup and IMS action. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `SourceRecordId` | Source Record | Guid, hidden | | | | `StateUTTax` | State/UT Tax | Currency | | | | `SupplyType` | Supply Type | Text | | | | `TaxableValue` | Taxable Value | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete List Header | Delete | Delete List Header | | `DeleteListRow` | Delete List Row | Delete | Delete List Row | | `Edit` | Edit | EditInline | Edit | | `EditListHeader` | Edit List Header | EditInline | Edit List Header | | `EditListRow` | Edit List Row | Edit | Edit List Row | | `New` | New | New | New | ## Related entities - [GSTR2BCDNRSupplier](/docs/reference/entities/gstr2-bcdnrsupplier/) — looks up via `GSTR2BCDNRSupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # CDN Supplier — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bcdnrsupplier/ Last reviewed: 2026-08-16 GSTR-2B credit/debit-note section grouping row - notes from one registered supplier, grouped by the supplier's GSTIN under a GSTR2B header. Its notes are GSTR2BCDNRNote children. One of the two sections (with B2B) that the Books materializer can derive from purchase transactions. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR2BId` | GSTR-2B Header | Lookup → [GSTR2B](/docs/reference/entities/gstr2-b/) | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `SupplierGstin` | Supplier GSTIN | Text | | | | `TradeName` | Trade Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete List Header | Delete | Delete List Header | | `DeleteListRow` | Delete List Row | Delete | Delete List Row | | `Edit` | Edit | EditInline | Edit | | `EditListHeader` | Edit List Header | EditInline | Edit List Header | | `EditListRow` | Edit List Row | Edit | Edit List Row | | `New` | New | New | New | ## Related entities - [GSTR2B](/docs/reference/entities/gstr2-b/) — looks up via `GSTR2BId` - [GSTR2BCDNRNote](/docs/reference/entities/gstr2-bcdnrnote/) — referenced by via `GSTR2BCDNRSupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # E-Commerce Amendment Document — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-becoadocument/ Last reviewed: 2026-08-16 An amended e-commerce supply document in GSTR-2B, belonging to a GSTR2BECOASupplier. Same shape as GSTR2BECODocument plus originalInvoiceNumber/originalInvoiceDate referencing the document being amended and differencePercent for the differential percentage. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Currency | | | | `Cess` | Cess | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DifferencePercent` | Difference Percent | Decimal | | | | `GSTR2BECOASupplierId` | ECO Amendment Supplier | Lookup → [GSTR2BECOASupplier](/docs/reference/entities/gstr2-becoasupplier/) | | | | `Id` | Id | Guid | Yes | | | `ImsStatus` | IMS Status | Text | | | | `IntegratedTax` | Integrated Tax | Currency | | | | `InvoiceDate` | Invoice Date | Date | | | | `InvoiceNumber` | Invoice Number | Text | | | | `InvoiceType` | Invoice Type | Text | | | | `InvoiceValue` | Invoice Value | Currency | | | | `ItcAvailability` | ITC Availability | Text | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OriginalInvoiceDate` | Original Invoice Date | Date | | | | `OriginalInvoiceNumber` | Original Invoice Number | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlaceOfSupply` | Place Of Supply | Text | | | | `RecordTypeId` | Record Type | Guid | | | | `ReverseCharge` | Reverse Charge | Text | | | | `StateUTTax` | State/UT Tax | Currency | | | | `TaxableValue` | Taxable Value | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR2BECOASupplier](/docs/reference/entities/gstr2-becoasupplier/) — looks up via `GSTR2BECOASupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # E-Commerce Amendment Supplier — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-becoasupplier/ Last reviewed: 2026-08-16 GSTR-2B e-commerce amendment section grouping row - amendments to previously reported section 9(5) e-commerce supplies, grouped by the operator's GSTIN under a GSTR2B header. Its amended documents are GSTR2BECOADocument children. Portal-only; modelled by analogy to GSTR2BECOSupplier. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `EcoGstin` | ECO GSTIN | Text | | | | `GSTR2BId` | GSTR-2B Header | Lookup → [GSTR2B](/docs/reference/entities/gstr2-b/) | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `TradeName` | Trade Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR2B](/docs/reference/entities/gstr2-b/) — looks up via `GSTR2BId` - [GSTR2BECOADocument](/docs/reference/entities/gstr2-becoadocument/) — referenced by via `GSTR2BECOASupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # E-Commerce Document — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-becodocument/ Last reviewed: 2026-08-16 A single section 9(5) e-commerce supply document in GSTR-2B, belonging to a GSTR2BECOSupplier. Same field shape as GSTR2BB2BInvoice: invoice identity plus its own tax breakup, ITC availability and IMS action status. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Currency | | | | `Cess` | Cess | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR2BECOSupplierId` | ECO Supplier | Lookup → [GSTR2BECOSupplier](/docs/reference/entities/gstr2-becosupplier/) | | | | `Id` | Id | Guid | Yes | | | `ImsStatus` | IMS Status | Text | | | | `IntegratedTax` | Integrated Tax | Currency | | | | `InvoiceDate` | Invoice Date | Date | | | | `InvoiceNumber` | Invoice Number | Text | | | | `InvoiceType` | Invoice Type | Text | | | | `InvoiceValue` | Invoice Value | Currency | | | | `ItcAvailability` | ITC Availability | Text | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlaceOfSupply` | Place Of Supply | Text | | | | `RecordTypeId` | Record Type | Guid | | | | `ReverseCharge` | Reverse Charge | Text | | | | `StateUTTax` | State/UT Tax | Currency | | | | `TaxableValue` | Taxable Value | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR2BECOSupplier](/docs/reference/entities/gstr2-becosupplier/) — looks up via `GSTR2BECOSupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # E-Commerce Supplier — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-becosupplier/ Last reviewed: 2026-08-16 GSTR-2B e-commerce section grouping row - supplies on which the e-commerce operator pays tax under section 9(5), grouped by the operator's GSTIN (ecoGstin) under a GSTR2B header. Its documents are GSTR2BECODocument children. Portal-only. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `EcoGstin` | ECO GSTIN | Text | | | | `GSTR2BId` | GSTR-2B Header | Lookup → [GSTR2B](/docs/reference/entities/gstr2-b/) | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `TradeName` | Trade Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR2B](/docs/reference/entities/gstr2-b/) — looks up via `GSTR2BId` - [GSTR2BECODocument](/docs/reference/entities/gstr2-becodocument/) — referenced by via `GSTR2BECOSupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Import (Overseas) — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bimpgrecord/ Last reviewed: 2026-08-16 GSTR-2B import-of-goods record - an overseas import auto-populated from ICEGATE against a Bill of Entry (portCode, billOfEntryNumber/Date/Value). Has no supplier GSTIN and hangs directly off the GSTR2B header rather than under a supplier group. Portal-only - not derivable from purchase transactions. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BillOfEntryDate` | Bill Of Entry Date | Date | | | | `BillOfEntryNumber` | Bill Of Entry Number | Text | | | | `BillOfEntryValue` | Bill Of Entry Value | Currency | | | | `Cess` | Cess | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR2BId` | GSTR-2B Header | Lookup → [GSTR2B](/docs/reference/entities/gstr2-b/) | | | | `Id` | Id | Guid | Yes | | | `IntegratedTax` | Integrated Tax | Currency | | | | `IsAmended` | Is Amended | Text | | Y/N string marking an amended Bill-of-Entry record - imports carry an amendment flag on the row instead of having a separate amendment section like the supplier-grouped sections. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PortCode` | Port Code | Text | | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `TaxableValue` | Taxable Value | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete List Header | Delete | Delete List Header | | `DeleteListRow` | Delete List Row | Delete | Delete List Row | | `Edit` | Edit | EditInline | Edit | | `EditListHeader` | Edit List Header | EditInline | Edit List Header | | `EditListRow` | Edit List Row | Edit | Edit List Row | | `New` | New | New | New | ## Related entities - [GSTR2B](/docs/reference/entities/gstr2-b/) — looks up via `GSTR2BId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Import (SEZ) — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bimpgsezrecord/ Last reviewed: 2026-08-16 GSTR-2B import-from-SEZ record - goods received from an SEZ unit against a Bill of Entry. Unlike the overseas GSTR2BIMPGRecord it carries the SEZ supplier's GSTIN, trade name and invoice reference alongside the Bill of Entry details. Hangs directly off the GSTR2B header; Portal-only. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BillOfEntryDate` | Bill Of Entry Date | Date | | | | `BillOfEntryNumber` | Bill Of Entry Number | Text | | | | `BillOfEntryValue` | Bill Of Entry Value | Currency | | | | `Cess` | Cess | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR2BId` | GSTR-2B Header | Lookup → [GSTR2B](/docs/reference/entities/gstr2-b/) | | | | `Id` | Id | Guid | Yes | | | `IntegratedTax` | Integrated Tax | Currency | | | | `InvoiceDate` | Invoice Date | Date | | | | `InvoiceNumber` | Invoice Number | Text | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PortCode` | Port Code | Text | | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `SupplierGstin` | Supplier GSTIN | Text | | | | `TaxableValue` | Taxable Value | Currency | | | | `TradeName` | Trade Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR2B](/docs/reference/entities/gstr2-b/) — looks up via `GSTR2BId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # ISD Amendment Credit — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bisdacredit/ Last reviewed: 2026-08-16 An amended ISD distributed-credit document in GSTR-2B, belonging to a GSTR2BISDASupplier. Same shape as GSTR2BISDCredit plus originalDocumentNumber/originalDocumentDate referencing the document being amended. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Currency | | | | `Cess` | Cess | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | | | `DocumentNumber` | Document Number | Text | | | | `DocumentType` | Document Type | Text | | | | `GSTR2BISDASupplierId` | ISD Amendment Supplier | Lookup → [GSTR2BISDASupplier](/docs/reference/entities/gstr2-bisdasupplier/) | | | | `Id` | Id | Guid | Yes | | | `IntegratedTax` | Integrated Tax | Currency | | | | `ItcAvailability` | ITC Availability | Text | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OriginalDocumentDate` | Original Document Date | Date | | | | `OriginalDocumentNumber` | Original Document Number | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `StateUTTax` | State/UT Tax | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR2BISDASupplier](/docs/reference/entities/gstr2-bisdasupplier/) — looks up via `GSTR2BISDASupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # ISD Amendment Supplier — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bisdasupplier/ Last reviewed: 2026-08-16 GSTR-2B ISD amendment section grouping row - amendments to previously distributed ISD credits, grouped by the ISD's GSTIN under a GSTR2B header. Its amended credits are GSTR2BISDACredit children. Portal-only; modelled by analogy to GSTR2BISDSupplier. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR2BId` | GSTR-2B Header | Lookup → [GSTR2B](/docs/reference/entities/gstr2-b/) | | | | `Id` | Id | Guid | Yes | | | `IsdGstin` | ISD GSTIN | Text | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `TradeName` | Trade Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete List Header | Delete | Delete List Header | | `DeleteListRow` | Delete List Row | Delete | Delete List Row | | `Edit` | Edit | EditInline | Edit | | `EditListHeader` | Edit List Header | EditInline | Edit List Header | | `EditListRow` | Edit List Row | Edit | Edit List Row | | `New` | New | New | New | ## Related entities - [GSTR2B](/docs/reference/entities/gstr2-b/) — looks up via `GSTR2BId` - [GSTR2BISDACredit](/docs/reference/entities/gstr2-bisdacredit/) — referenced by via `GSTR2BISDASupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # ISD Credit — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bisdcredit/ Last reviewed: 2026-08-16 A single ISD distributed-credit document (ISD invoice or credit note, per documentType) in GSTR-2B, belonging to a GSTR2BISDSupplier. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Currency | | | | `Cess` | Cess | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | | | `DocumentNumber` | Document Number | Text | | | | `DocumentType` | Document Type | Text | | | | `GSTR2BISDSupplierId` | ISD Supplier | Lookup → [GSTR2BISDSupplier](/docs/reference/entities/gstr2-bisdsupplier/) | | | | `Id` | Id | Guid | Yes | | | `IntegratedTax` | Integrated Tax | Currency | | | | `ItcAvailability` | ITC Availability | Text | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `StateUTTax` | State/UT Tax | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete List Header | Delete | Delete List Header | | `DeleteListRow` | Delete List Row | Delete | Delete List Row | | `Edit` | Edit | EditInline | Edit | | `EditListHeader` | Edit List Header | EditInline | Edit List Header | | `EditListRow` | Edit List Row | Edit | Edit List Row | | `New` | New | New | New | ## Related entities - [GSTR2BISDSupplier](/docs/reference/entities/gstr2-bisdsupplier/) — looks up via `GSTR2BISDSupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # ISD Supplier — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bisdsupplier/ Last reviewed: 2026-08-16 GSTR-2B ISD section grouping row - input-tax credits distributed by an Input Service Distributor, grouped by the ISD's GSTIN (isdGstin) under a GSTR2B header. Its distributed-credit documents are GSTR2BISDCredit children. Portal-only: ISD credits are not derivable from purchase transactions, so the Books materializer never writes this section. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR2BId` | GSTR-2B Header | Lookup → [GSTR2B](/docs/reference/entities/gstr2-b/) | | | | `Id` | Id | Guid | Yes | | | `IsdGstin` | ISD GSTIN | Text | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `TradeName` | Trade Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete List Header | Delete | Delete List Header | | `DeleteListRow` | Delete List Row | Delete | Delete List Row | | `Edit` | Edit | EditInline | Edit | | `EditListHeader` | Edit List Header | EditInline | Edit List Header | | `EditListRow` | Edit List Row | Edit | Edit List Row | | `New` | New | New | New | ## Related entities - [GSTR2B](/docs/reference/entities/gstr2-b/) — looks up via `GSTR2BId` - [GSTR2BISDCredit](/docs/reference/entities/gstr2-bisdcredit/) — referenced by via `GSTR2BISDSupplierId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # ITC Summary — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-bitcsummary/ Last reviewed: 2026-08-16 GSTR-2B aggregate ITC totals row under a GSTR2B header: the GSTN ITC-available and ITC-not-available blocks flattened into paired tax-head columns (an itcAvailable and an itcNotAvailable column each for IGST, CGST, SGST-UTGST and cess). One of the header-FK records that carries the Books-vs-Portal source discriminator; the GetGSTR2B summary reads it for the GSTN-computed ITC roll-up. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR2BId` | GSTR-2B Header | Lookup → [GSTR2B](/docs/reference/entities/gstr2-b/) | | | | `Id` | Id | Guid | Yes | | | `ItcAvailableCentralTax` | ITC Available CGST | Currency | | | | `ItcAvailableCess` | ITC Available Cess | Currency | | | | `ItcAvailableIntegratedTax` | ITC Available IGST | Currency | | | | `ItcAvailableStateUTTax` | ITC Available SGST/UTGST | Currency | | | | `ItcNotAvailableCentralTax` | ITC Not Available CGST | Currency | | | | `ItcNotAvailableCess` | ITC Not Available Cess | Currency | | | | `ItcNotAvailableIntegratedTax` | ITC Not Available IGST | Currency | | | | `ItcNotAvailableStateUTTax` | ITC Not Available SGST/UTGST | Currency | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `Source` | Source | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR2B](/docs/reference/entities/gstr2-b/) — looks up via `GSTR2BId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR-2B Reconciliation Entry — entity reference URL: https://xmatix.com/docs/reference/entities/gstr2-breconciliation-entry/ Last reviewed: 2026-08-16 Persisted ITC reconciliation workbench row - one GSTR-2B document matched against the local purchase books (a Bill, via localBillId). Holds both sides of the comparison per tax head (the gstr2b-prefixed columns as supplier-reported, the local-prefixed columns as per the matched Bill), the IMS action taken, the match-bucket status (Missing in GSTN / Missing in Books / Partially Matched / Matched / Reconciled) and the ITC difference. This is the stored 2B-versus-Bill workbench; it is separate from the GetGSTR2BReconciliation server action, which is a pure read-side Books-versus-Portal comparison that persists nothing. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Difference` | Difference | Currency | | The ITC difference between the supplier-reported (gstr2bItc) and local-books (localItc) sides of this matched document. | | `Gstr2bCentralTax` | GSTR-2B CGST | Currency | | | | `Gstr2bCess` | GSTR-2B Cess | Currency | | | | `GSTR2BId` | GSTR-2B Header | Lookup → [GSTR2B](/docs/reference/entities/gstr2-b/) | | | | `Gstr2bIntegratedTax` | GSTR-2B IGST | Currency | | | | `Gstr2bItc` | GSTR-2B ITC | Currency | | | | `Gstr2bStateUTTax` | GSTR-2B SGST/UTGST | Currency | | | | `Gstr2bTaxableValue` | GSTR-2B Taxable Value | Currency | | | | `Gstr2bTotalAmount` | GSTR-2B Total Amount | Currency | | | | `Id` | Id | Guid | Yes | | | `ImsAction` | IMS Action | Text | | The IMS action recorded for this matched document in the reconciliation workbench - the decision taken on the supplier-reported document. | | `InvoiceNumber` | Invoice Number | Text | | | | `Label` | Label | Text | | | | `LocalBillId` | Local Bill Id | Guid | | The purchase Bill this GSTR-2B document was matched against - the local-books side of the comparison; the local-prefixed tax columns are that Bill's figures. Null when the document is missing in books. | | `LocalCentralTax` | Local CGST | Currency | | | | `LocalCess` | Local Cess | Currency | | | | `LocalIntegratedTax` | Local IGST | Currency | | | | `LocalItc` | Local ITC | Currency | | | | `LocalStateUTTax` | Local SGST/UTGST | Currency | | | | `LocalTaxableValue` | Local Taxable Value | Currency | | | | `LocalTotalAmount` | Local Total Amount | Currency | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid | | | | `Status` | Status | Text | | Match bucket of this workbench row: Missing in GSTN, Missing in Books, Partially Matched, Matched or Reconciled. Different vocabulary from the read-only GetGSTR2BReconciliation action, whose statuses are Matched/Mismatch/MissingInBooks/MissingInGstin. | | `SupplierGstin` | Supplier GSTIN | Text | | | | `TransactionDate` | Transaction Date | Date | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified On | DateAndTime | Yes | | | `VendorName` | Vendor Name | Text | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR2B](/docs/reference/entities/gstr2-b/) — looks up via `GSTR2BId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR 3B — entity reference URL: https://xmatix.com/docs/reference/entities/gstr3-b/ Last reviewed: 2026-10-09 One GSTR-3B monthly summary return for one GSTIN and one monthly GST fiscal period. Draft returns are created by GST-return provisioning (the Provision GST returns scheduled job or the Provision GST Returns action on a GST Registration), one per active regular registration per month. Process GSTR3B fills the boxes: table 3.1 from the same-period GSTR-1 (a Filed one preferred), table 4A from the latest same-period GSTR-2B statement, 3.1(d) reverse charge and 4B(1) blocked credit from the tax ledger, and 4B(2)/4D(1) from the Rule 37 180-day unpaid-bill tracker. Rows entered by hand (3.1(e), table 3.1.1, 4A(2), Rule 42/43 reversals, 6.1 payment details) are kept on reprocessing. The return is filed either through the GSP integration (Save to GSTN, Check Save Status, Submit File to GSTN) or on the government portal and then recorded with Record Manual Filing. A Filed return is frozen and is what the GSTR-9 annual return reads. See the GSTR-3B guide in the Tax Center documentation for the full procedure. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AckNumber` | Ack Number | Text | | The acknowledgement number GSTN issued for the filing, at most 20 characters. Written back by Submit File to GSTN, or entered in Record Manual Filing, where it is required. | | `ComputedAt` | Computed At | DateAndTime | | When Process GSTR3B last ran for this return. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FiledOn` | Filed On | DateAndTime | | Date the return was filed. Stamped when Submit File to GSTN succeeds, or taken from the Record Manual Filing dialog (defaults to now when left empty). | | `GspReferenceId` | GSP Reference Id | Text | | The reference GSTN issued for the latest Save to GSTN. It is not a receipt: only Check Save Status can tell whether GSTN accepted the save. | | `GSTIN` | GSTIN | Text | | The filer's 15-character GST identification number. It must be well formed; a malformed value is refused whenever the record is saved. Decides which GSTR-1, GSTR-2B, tax-ledger lines and GST Registration session the return uses. | | `GSTMonthId` | GST Month | Lookup → GSTMonth_c | | Legacy month link. Not used by processing or filing; the return period is Return Period. | | `GstnPayload` | GSTN Payload | LongMultiLineText | | Hidden working field holding the request being sent to GSTN while a save, status check or filing is in progress. Cleared once GSTN accepts the save. Not for users. | | `GstnResponse` | GSTN Response | LongMultiLineText | | The last message from GSTN or the gateway for this return: the acceptance line, a refusal, or the per-box error list when GSTN rejects a save. | | `Id` | Id | Guid | Yes | | | `IsFiled` | Is Filed | Boolean | | Set when the return is filed by either route (Submit File to GSTN or Record Manual Filing), together with Status Filed. | | `IsNilReturn` | Is Nil Return | Boolean | | Marker that the month is a nil return. Informational only: no action reads it, and Save to GSTN still refuses a return that has no rows. | | `Label` | Label | Text | | Display name of the return, set by provisioning as GSTR-3B followed by the period, for example GSTR-3B Aug 2026. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ProcessedInvoiceValue` | Processed Invoice Value | Decimal | | Header total field that Process GSTR3B does not fill. A blank value does not mean processing failed; confirm a run by Status, Computed At and the box figures. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReturnPeriodId` | Return Period | Lookup → [GSTFiscalPeriod](/docs/reference/entities/gstfiscal-period/) | | The monthly GST fiscal period this return covers. Process GSTR3B is refused without it, and it decides which month's GSTR-1, GSTR-2B and ledger lines are read. | | `Status` | Status | PickList | | Lifecycle of the return. Provisioning sets Draft, Process GSTR3B sets Computed, an accepted GSTN save sets Saved, and a filing (Submit File to GSTN or Record Manual Filing) sets Filed. Filed is one-way: it blocks reprocessing and re-sending and is what the GSTR-9 rollup selects. The values Pushed to GSTN and GST Payment Made exist in the list but no action sets them. Values: Draft, Pushed to GSTN, GST Payment Made, Filed. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `ComputeGSTR3B` | Process GSTR3B | ServerAction (`ComputeGSTR3B`) | Process GSTR3B. Refreshes the Rule 37 tracker from purchase bills, rebuilds every auto-filled box row (3.1 from the same-period GSTR-1, Filed preferred; 4A from the latest GSTR-2B statement; 3.1(d) and 4B(1) from the tax ledger; 4B(2) and 4D(1) from the Rule 37 tracker; 4D(2) from the statement's not-available ITC), refreshes Payable on the 6.1 rows, and sets Status to Computed. Rows entered by hand are kept. Refused on a Filed return. The Process GSTR-3B data scheduled job runs the same processing. | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit InLine | EditInline | Edit InLine | | `EditInList` | Edit | EditInline | edit | | `FileToGSTN` | File To GSTN | ServerAction (`FileToGSTN`) | Record Manual Filing. Records a GSTR-3B already filed on the government portal: asks for the Ack Number (required, at most 20 characters) and Filed On (defaults to now), then sets Is Filed and Status Filed. Sends nothing to GSTN. Refused on a return already Filed, without a valid GSTIN, or while a GSP filing is in progress. | | `GetGSTR3B` | GetGSTR3B | ServerAction (`GetGSTR3B`) | Returns the table-wise summary shown on the Overview tab: tables 3.1, 3.1.1, 4A, 4B, 4D and 6.1, every statutory line included, with taxable value and the four tax heads. Read-only. | | `MakeChallan` | Make Challan | ServerAction | Has no effect. xMatix does not generate GST payment challans; create and pay them on the government portal. | | `New` | New | New | New | | `PullFromGSTIN` | Pull From GSTIN | ServerAction (`Pull From GSTIN`) | Retired and inactive. GSTR-3B figures are not pulled from GSTN; they are built by Process GSTR3B. | ## Related entities - [GSTFiscalPeriod](/docs/reference/entities/gstfiscal-period/) — looks up via `ReturnPeriodId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GSTR3BSection311](/docs/reference/entities/gstr3-bsection311/) — referenced by via `GSTR3BId` - [GSTR3BItcIneligible](/docs/reference/entities/gstr3-bitc-ineligible/) — referenced by via `GSTR3BId` - [GSTR3BItcAvailable](/docs/reference/entities/gstr3-bitc-available/) — referenced by via `GSTR3BId` - [GSTR3BSection31](/docs/reference/entities/gstr3-bsection31/) — referenced by via `GSTR3BId` - [GSTR3BItcReversed](/docs/reference/entities/gstr3-bitc-reversed/) — referenced by via `GSTR3BId` - [GSTR3BPayment](/docs/reference/entities/gstr3-bpayment/) — referenced by via `GSTR3BId` - [GSTR3BRule37Tracker](/docs/reference/entities/gstr3-brule37-tracker/) — referenced by via `GSTR3BId` - [GSTR3BFilingLog](/docs/reference/entities/gstr3-bfiling-log/) — referenced by via `GSTR3BId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR 3B Filing Log — entity reference URL: https://xmatix.com/docs/reference/entities/gstr3-bfiling-log/ Last reviewed: 2026-08-16 GSTR 3B Filing Log is part of the xMatix data model. Field-level notes for this entity are still being written — the table below reflects the live model. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Action` | Action | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `ErrorCode` | Error Code | Text | | | | `ErrorMessage` | Error Message | Text | | | | `GspEndpoint` | GSP Endpoint | Text | | | | `GSTR3BId` | GSTR-3B | Lookup → [GSTR3B](/docs/reference/entities/gstr3-b/) | | | | `HttpStatus` | HTTP Status | Number | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestPayload` | Request Payload | LongMultiLineText | | | | `ResponsePayload` | Response Payload | LongMultiLineText | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [GSTR3B](/docs/reference/entities/gstr3-b/) — looks up via `GSTR3BId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR 3B Table 4A ITC — entity reference URL: https://xmatix.com/docs/reference/entities/gstr3-bitc-available/ Last reviewed: 2026-08-16 GSTR 3B Table 4A ITC is part of the xMatix data model. Field-level notes for this entity are still being written — the table below reflects the live model. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Decimal | | | | `Cess` | Cess | Decimal | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR3BId` | GSTR-3B | Lookup → [GSTR3B](/docs/reference/entities/gstr3-b/) | | | | `Id` | Id | Guid | Yes | | | `IntegratedTax` | Integrated Tax | Decimal | | | | `IsAutoFilled` | Is Auto Filled | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StateUTTax` | State/UT Tax | Decimal | | | | `SubRow` | Sub Row | Number | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GSTR3B](/docs/reference/entities/gstr3-b/) — looks up via `GSTR3BId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR 3B Table 4D ITC — entity reference URL: https://xmatix.com/docs/reference/entities/gstr3-bitc-ineligible/ Last reviewed: 2026-08-16 GSTR 3B Table 4D ITC is part of the xMatix data model. Field-level notes for this entity are still being written — the table below reflects the live model. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Decimal | | | | `Cess` | Cess | Decimal | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR3BId` | GSTR-3B | Lookup → [GSTR3B](/docs/reference/entities/gstr3-b/) | | | | `Id` | Id | Guid | Yes | | | `IntegratedTax` | Integrated Tax | Decimal | | | | `IsAutoFilled` | Auto Filled | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StateUTTax` | State/UT Tax | Decimal | | | | `SubRow` | Sub Row | Number | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR3B](/docs/reference/entities/gstr3-b/) — looks up via `GSTR3BId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR-3B Table 4B ITC — entity reference URL: https://xmatix.com/docs/reference/entities/gstr3-bitc-reversed/ Last reviewed: 2026-08-16 GSTR-3B Table 4B ITC is part of the xMatix data model. Field-level notes for this entity are still being written — the table below reflects the live model. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Decimal | | | | `Cess` | Cess | Decimal | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR3BId` | GSTR-3B | Lookup → [GSTR3B](/docs/reference/entities/gstr3-b/) | | | | `Id` | Id | Guid | Yes | | | `IntegratedTax` | Integrated Tax | Decimal | | | | `IsAutoFilled` | Auto Filled | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReversalReason` | Reversal Reason | Text | | | | `StateUTTax` | State/UT Tax | Decimal | | | | `SubRow` | Sub Row | Number | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR3B](/docs/reference/entities/gstr3-b/) — looks up via `GSTR3BId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR 3B Payment — entity reference URL: https://xmatix.com/docs/reference/entities/gstr3-bpayment/ Last reviewed: 2026-08-16 GSTR-3B Table 6.1 payment of tax per head (feeds GSTR-9 Table-9 paid). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `GSTR3BId` | GSTR 3B | Lookup → [GSTR3B](/docs/reference/entities/gstr3-b/) | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PaidCash` | Paid Cash | Currency | | | | `PaidItcCess` | Paid ITC Cess | Currency | | | | `PaidItcCGST` | Paid ITC CGST | Currency | | | | `PaidItcIGST` | Paid ITC IGST | Currency | | | | `PaidItcSGST` | Paid ITC SGST | Currency | | | | `Payable` | Payable | Currency | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TaxHead` | Tax Head | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GSTR3B](/docs/reference/entities/gstr3-b/) — looks up via `GSTR3BId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR 3B Rule 37 Tracker — entity reference URL: https://xmatix.com/docs/reference/entities/gstr3-brule37-tracker/ Last reviewed: 2026-08-16 GSTR 3B Rule 37 Tracker is part of the xMatix data model. Field-level notes for this entity are still being written — the table below reflects the live model. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BillId` | Bill | Lookup → [Bill](/docs/reference/entities/bill/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DueBy` | Due By | DateAndTime | | | | `GSTR3BId` | GSTR-3B | Lookup → [GSTR3B](/docs/reference/entities/gstr3-b/) | | | | `Id` | Id | Guid | Yes | | | `InvoiceDate` | Invoice Date | DateAndTime | | | | `ItcCentralTax` | ITC Central Tax | Decimal | | | | `ItcIntegratedTax` | ITC Integrated Tax | Decimal | | | | `ItcStateUTTax` | ITC State/UT Tax | Decimal | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PaidOn` | Paid On | DateAndTime | | | | `ReclaimedInPeriod` | Reclaimed In Period | Text | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReversedInPeriod` | Reversed In Period | Text | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Bill](/docs/reference/entities/bill/) — looks up via `BillId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GSTR3B](/docs/reference/entities/gstr3-b/) — looks up via `GSTR3BId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR 3B Table 3.1 — entity reference URL: https://xmatix.com/docs/reference/entities/gstr3-bsection31/ Last reviewed: 2026-08-16 GSTR 3B Table 3.1 is part of the xMatix data model. Field-level notes for this entity are still being written — the table below reflects the live model. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Decimal | | | | `Cess` | Cess | Decimal | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR3BId` | GSTR-3B | Lookup → [GSTR3B](/docs/reference/entities/gstr3-b/) | | | | `Id` | Id | Guid | Yes | | | `IntegratedTax` | Integrated Tax | Decimal | | | | `IsAutoFilled` | Is Auto Filled | Boolean | | | | `IsLocked` | Is Locked | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RowCode` | Row Code | Text | | | | `StateUTTax` | State/UT Tax | Decimal | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TaxableValue` | Taxable Value | Decimal | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [GSTR3B](/docs/reference/entities/gstr3-b/) — looks up via `GSTR3BId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR 3B Table 3.1.1 — entity reference URL: https://xmatix.com/docs/reference/entities/gstr3-bsection311/ Last reviewed: 2026-08-16 GSTR 3B Table 3.1.1 is part of the xMatix data model. Field-level notes for this entity are still being written — the table below reflects the live model. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CentralTax` | Central Tax | Decimal | | | | `Cess` | Cess | Decimal | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `GSTR3BId` | GSTR-3B | Lookup → [GSTR3B](/docs/reference/entities/gstr3-b/) | | | | `Id` | Id | Guid | Yes | | | `IntegratedTax` | Integrated Tax | Decimal | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RowCode` | Row Code | Text | | | | `StateUTTax` | State/UT Tax | Decimal | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TaxableValue` | Taxable Value | Decimal | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR3B](/docs/reference/entities/gstr3-b/) — looks up via `GSTR3BId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # ISD Distribution — entity reference URL: https://xmatix.com/docs/reference/entities/gstr6-isddistribution/ Last reviewed: 2026-08-16 ISD Distribution is part of the xMatix data model. Field-level notes for this entity are still being written — the table below reflects the live model. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Cess` | Cess | Currency | | | | `CGST` | CGST | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DistributionMethod` | Distribution Method | PickList | | Values: Auto, Ratio, Manual, Pro-rata. | | `DocumentDate` | Document Date | Date | | | | `DocumentNumber` | Document Number | Text | | | | `DocumentSerial` | Document Serial | Text | | | | `DocumentType` | Document Type | PickList | | Values: ISD Invoice, ISD Credit Note. | | `FilingPeriod` | Filing Period | Date | | | | `GSTR6Id` | GSTR 6 | Lookup → [GSTR6](/docs/reference/entities/gstr6/) | | | | `Id` | Id | Guid | Yes | | | `IGST` | IGST | Currency | | | | `ISDBranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `ISDSourceDocumentId` | ISD Source Document | Lookup → ISDSourceDocument_c | | | | `IsEligible` | Is Eligible | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OriginalDistributionId` | Original Distribution | Lookup | | | | `OriginalISDInvoiceDate` | Original ISD Invoice Date | Date | | | | `OriginalISDInvoiceNumber` | Original ISD Invoice Number | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SGST` | SGST | Currency | | | | `Source` | Source | Text | | | | `Status` | Status | PickList | | Values: Draft, Locked, Filed. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TableRef` | Table Ref | Text | | | | `TotalITC` | Total ITC | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `EditInLine` | Edit | EditInline | Edit | | `New` | New | New | New | ## Related entities - [GSTR6](/docs/reference/entities/gstr6/) — looks up via `GSTR6Id` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `ISDBranchId` - [GSTR6ISDSourceDocument](/docs/reference/entities/gstr6-isdsource-document/) — looks up via `ISDSourceDocumentId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [GSTR6ISDRecipientAllocation](/docs/reference/entities/gstr6-isdrecipient-allocation/) — referenced by via `ISDDistributionId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # ISD Document Series — entity reference URL: https://xmatix.com/docs/reference/entities/gstr6-isddocument-series/ Last reviewed: 2026-08-16 GSTR-6 ISD document serial allocator (Rule 54(1)). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FinancialYear` | Financial Year | Text | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `Label` | Label | Text | | | | `LastSerialNumber` | Last Serial Number | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NextSerialNumber` | Next Serial Number | Number | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Prefix` | Prefix | Text | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SeriesType` | Series Type | Text | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # ISD Recipient Allocation — entity reference URL: https://xmatix.com/docs/reference/entities/gstr6-isdrecipient-allocation/ Last reviewed: 2026-08-16 ISD Recipient Allocation is part of the xMatix data model. Field-level notes for this entity are still being written — the table below reflects the live model. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CESS` | CESS | Currency | | | | `CGST` | CGST | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DistributedCess` | Distributed Cess | Currency | | | | `DistributedCGST` | Distributed CGST | Currency | | | | `DistributedIGST` | Distributed IGST | Currency | | | | `DistributedSGST` | Distributed SGST | Currency | | | | `GSTR6Id` | GSTR 6 | Lookup → [GSTR6](/docs/reference/entities/gstr6/) | | | | `Id` | Id | Guid | Yes | | | `IGST` | IGST | Currency | | | | `IsCrossState` | Is Cross State | Boolean | | | | `ISDDistributionId` | ISD Distribution | Lookup → ISDDistribution | | | | `ISDRecipientTurnoverId` | ISD Recipient Turnover | Lookup | | | | `IsEligible` | Is Eligible | Boolean | | | | `IsSezRecipient` | Is SEZ Recipient | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OutputLiabilityFlag` | Output Liability Flag | Boolean | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Ratio` | Ratio | Number | | | | `RecipientGSTIN` | Recipient GSTIN | Text | | | | `RecipientStateCode` | Recipient State Code | Text | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SGST` | SGST | Currency | | | | `Source` | Source | Text | | | | `SourceCess` | Source Cess | Currency | | | | `SourceCGST` | Source CGST | Currency | | | | `SourceIGST` | Source IGST | Currency | | | | `SourceSGST` | Source SGST | Currency | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | delete | | `EditInList` | Edit | EditInline | edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GSTR6ISDRecipientTurnover](/docs/reference/entities/gstr6-isdrecipient-turnover/) — looks up via `ISDRecipientTurnoverId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GSTR6](/docs/reference/entities/gstr6/) — looks up via `GSTR6Id` - [GSTR6ISDDistribution](/docs/reference/entities/gstr6-isddistribution/) — looks up via `ISDDistributionId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # ISD Recipient Turnover — entity reference URL: https://xmatix.com/docs/reference/entities/gstr6-isdrecipient-turnover/ Last reviewed: 2026-08-16 GSTR-6 ISD recipient turnover (Rule 39 pro-rata master). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EffectiveFrom` | Effective From | Date | | | | `EffectiveTo` | Effective To | Date | | | | `FinancialYear` | Financial Year | Text | | | | `Id` | Id | Guid | Yes | | | `IsOperational` | Is Operational | Boolean | | | | `IsRegistered` | Is Registered | Boolean | | | | `IsSez` | Is SEZ | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Quarter` | Quarter | Text | | | | `RecipientGSTIN` | Recipient GSTIN | Text | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StateCode` | State Code | Text | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `Turnover` | Turnover | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GSTR6ISDRecipientAllocation](/docs/reference/entities/gstr6-isdrecipient-allocation/) — referenced by via `ISDRecipientTurnoverId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # ISD Source Document — entity reference URL: https://xmatix.com/docs/reference/entities/gstr6-isdsource-document/ Last reviewed: 2026-08-16 ISD Source Documents ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AttributedRecipientId` | Attributed Recipient | Lookup | | | | `Cess` | Cess | Currency | | | | `CGST` | CGST | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | Date | | `DocumentNumber` | Document Number | Text | | | | `DocumentType` | Document Type | PickList | | Values: Invoice, Credit Note. | | `EligibleCess` | Eligible Cess | Currency | | | | `EligibleCGST` | Eligible CGST | Currency | | | | `EligibleIGST` | Eligible IGST | Currency | | | | `EligibleSGST` | Eligible SGST | Currency | | | | `FilingPeriod` | Filing Period | Date | | | | `GSTR6ADetailId` | GSTR-6A Detail | Lookup | | | | `GSTR6Id` | GSTR 6 | Lookup → [GSTR6](/docs/reference/entities/gstr6/) | | | | `Id` | Id | Guid | Yes | | | `IGST` | IGST | Currency | | | | `IneligibleCess` | Ineligible Cess | Currency | | | | `IneligibleCGST` | Ineligible CGST | Currency | | | | `IneligibleIGST` | Ineligible IGST | Currency | | | | `IneligibleReason` | Ineligible Reason | Text | | | | `IneligibleSGST` | Ineligible SGST | Currency | | | | `InvoiceValue` | Invoice Value | Currency | | | | `IsAmendment` | Is Amendment | Boolean | | | | `IsISDEligible` | Is ISD Eligible | Boolean | | | | `IsReverseCharge` | Is Reverse Charge | Boolean | | | | `MatchStatus` | Match Status | PickList | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OriginalDocumentDate` | Original Document Date | Date | | | | `OriginalDocumentNumber` | Original Document Number | Text | | | | `OriginalFinancialYear` | Original Financial Year | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlaceOfSupply` | Place Of Supply | Text | | | | `PortalAction` | Portal Action | Text | | | | `RcmTransferSourceGstin` | RCM Transfer Source GSTIN | Text | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SGST` | SGST | Currency | | | | `Source` | Source | Text | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `SupplierGSTIN` | Supplier GSTIN | Text | | | | `TaxableValue` | Taxable Value | Currency | | | | `TaxRate` | Tax Rate | Currency | | | | `TotalTax` | Total Tax | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | delete | | `EditInLine` | Edit | EditInline | edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GSTR6](/docs/reference/entities/gstr6/) — looks up via `GSTR6Id` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GSTR6ISDDistribution](/docs/reference/entities/gstr6-isddistribution/) — referenced by via `ISDSourceDocumentId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR 6 — entity reference URL: https://xmatix.com/docs/reference/entities/gstr6/ Last reviewed: 2026-10-09 A GSTR 6 record is the monthly return of an Input Service Distributor (ISD) registration: one record per ISD GSTIN and return month, created as Draft by GST-return provisioning for every GST Registration with Enable ISD switched on. Process GSTR6 reads the month's input tax for the ISD GSTIN from the tax ledger into received documents (form tables 3 and 6), Distribute ISD Credit splits each eligible and ineligible credit pool between the operational recipient registrations under the same PAN by turnover or to a single attributed recipient (Rule 39) with ISD document serials (Rule 54), and Calculate ITC checks the form table 4 equality of ITC received and distributed. Status moves Draft, Processed, Distributed, Computed, Filed. A Computed return is filed either through the GSP integration (Save to GSTN, Check Save Status, Submit to GSTN, Submit File to GSTN) or recorded with Record Manual Filing after filing on the portal; Pull From GSTIN imports the auto-drafted GSTR-6A for reconciliation. A Filed return is frozen. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | ISD Account | Lookup → [Account](/docs/reference/entities/account/) | | Optional account representing the Input Service Distributor. Not used by processing, distribution or filing. | | `ARN` | ARN | Text | | Acknowledgement reference number GSTN issued when the return was filed, at most 120 characters. Written back by Submit File to GSTN, or entered in the Record Manual Filing dialog, where it is required. | | `ComputedAt` | Computed At | Date | | When Calculate ITC last ran. Cleared whenever Process GSTR6 or Distribute ISD Credit rebuilds the return, because the earlier check no longer applies. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FiledAt` | FiledAt | DateAndTime | | When the return was filed. Stamped by Submit File to GSTN, or taken from Filed On in the Record Manual Filing dialog (defaults to now). | | `GSTFiscalPeriodId` | GST Fiscal Period | Lookup | | The monthly GST fiscal period the return covers, set by provisioning. Decides which month's input tax lines Process GSTR6 reads and the return period sent to GSTN. | | `GSTIN` | GSTIN | Text | | The ISD's 15-character GST identification number, set by provisioning. Saving a malformed GSTIN is refused; processing and the GSP actions are refused when it is blank. | | `GSTRegistrationId` | GST Registration | Lookup | | The ISD's GST Registration. Its GSTN session (Request GSTN OTP, Submit OTP) is used by the GSP actions; when blank, the registration is found by GSTIN. | | `Id` | Id | Guid | Yes | | | `IsFiled` | Is Filed | Boolean | | Yes once the return has been filed, through the GSP or recorded with Record Manual Filing. Set together with Status Filed; never cleared. | | `LateFeePaid` | Late Fee Paid | Currency | | Late fee paid for the return (form table 10). | | `LateFeePayable` | Late Fee Payable | Currency | | Late fee for the return (form table 10). Filled from the portal's late-fee section by Pull From GSTIN. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | Record name, set by provisioning from the GSTIN and the month, for example GSTR6-29AAAAA0000A2Z4-082026. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Period` | Period | Date | | A date in the return month. Used to find the month only when no GST fiscal period is linked. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RefundClaimed` | Refund Claimed | Currency | | Refund claimed from the electronic cash ledger (form table 11). Shown in the return summary. | | `Status` | Status | PickList | | Where the return is in its lifecycle, written by the actions: Draft (provisioned), Processed (received documents built), Distributed (credit split between recipients), Computed (ITC received equals ITC distributed within one rupee and every distribution fully allocated), Filed (frozen). Processing or distributing again moves a Computed return back. Only a Computed return can be saved to GSTN or recorded as filed. Values: Draft, Submitted, Filed. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TotalDocuments` | Total Documents | Number | | Number of received documents Process GSTR6 found for the month. | | `TotalITCDistributed` | Total ITC Distributed | Currency | | Total input tax credit passed on to recipient registrations by Distribute ISD Credit. Must equal Total ITC Received within one rupee for Calculate ITC to set Computed. | | `TotalITCReceived` | TotalITCReceived | Currency | | Total tax on the month's received documents, set by Process GSTR6 and Calculate ITC. Must equal Total ITC Distributed within one rupee for the return to reach Computed. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `CalculateITC` | Calculate ITC | ServerAction (`CalculateITC`) | Checks the form table 4 equality: ITC received equals ITC distributed within one rupee and every distribution is fully allocated to recipients. Sets Status Computed when balanced and stamps Computed At. Refused on a Filed return or one frozen at GSTN. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DistributeISDCredit` | Distribute ISD Credit | ServerAction (`DistributeISDCredit`) | Splits each received document's eligible and ineligible credit between the operational recipient registrations under the ISD's PAN, by turnover or to the single attributed recipient (Rule 39), converting CGST and SGST to IGST for cross-state and SEZ recipients and numbering each ISD invoice or credit note (Rule 54). Refused, changing nothing, when a credit pool has no recipient. Sets Status Distributed. | | `EditInLine` | Edit | EditInline, inactive | Edit | | `FileToGSTN` | File To GSTN | ServerAction (`FileToGSTN`) | Record Manual Filing: records a return already filed on the GSTN portal by hand, with its ARN (required) and filing date. Sends nothing to GSTN. Refused unless the return is Computed, when it is already Filed, and while a GSP filing is in progress. | | `GetGSTR6` | Get from GSTR6 | ServerAction (`GetGSTR6`) | Returns the return summary by form table (3, 6, 8 and 9) with integrated, central, state/UT tax and cess, shown on the Reconciliation tab. | | `GetGSTR6Reconciliation` | Reconcile GSTR6 | ServerAction (`GetGSTR6Reconciliation`) | Compares the received documents in your books with those pulled from the auto-drafted GSTR-6A, by supplier GSTIN and document number: Matched, Partial, MissingInBooks or MissingInGstin. | | `New` | New | New | New | | `ProcessGSTR6Data` | Process GSTR6 | ServerAction (`ProcessGSTR6Data`) | Rebuilds the received documents from the month's input tax lines for the ISD GSTIN, splitting each document's tax into eligible and ineligible pools. Leaves portal-pulled rows alone. Sets Status Processed and fills Total Documents and Total ITC Received. Refused on a Filed return or one frozen at GSTN. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [GSTR6ISDDistribution](/docs/reference/entities/gstr6-isddistribution/) — referenced by via `GSTR6Id` - [GSTR6ISDSourceDocument](/docs/reference/entities/gstr6-isdsource-document/) — referenced by via `GSTR6Id` - [GSTR6ISDRecipientAllocation](/docs/reference/entities/gstr6-isdrecipient-allocation/) — referenced by via `GSTR6Id` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR 9 Config — entity reference URL: https://xmatix.com/docs/reference/entities/gstr9-config/ Last reviewed: 2026-08-16 The tenant's copy of the GSTR-9 form catalog - one row per form line and value lane describing HOW that figure is produced: the section/sub-section/line item coordinates, the logic type dispatch key (rollup of filed returns, 2B rollup, books ledger, spillover, formula over other rows, or manual entry) and its logic definition. Materialized per tenant on demand from the shipped catalog definition; a catalog upgrade refreshes stale rows in place but skips rows the tenant deliberately customized. The GSTR-9 compute evaluates this catalog rather than hard-coding the form, because GSTN renotifies the form most years and several years must stay computable at once. Do not confuse with GSTR9CConfig, which belongs to the removed 9C reconciliation feature. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CatalogVersion` | Catalog Version | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExecutionOrder` | Execution Order | Number | | | | `FinancialYear` | Financial Year | Text | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `IsCustomized` | Is Customized | Boolean | | | | `IsSystemLocked` | Is System Locked | Boolean | | | | `Lane` | Lane | Text | | | | `LineItem` | Line Item | Text | | | | `LogicDefinition` | Logic Definition | Text | | The parameter payload for the row's logic type - e.g. which source slices a rollup reads or the formula over other row codes. Edited only when a tenant deliberately customizes a row; customized rows are skipped by catalog upgrades. | | `LogicType` | Logic Type | PickList | | Dispatch key for how the row's value is produced: RollupFiledReturns (the twelve filed GSTR-1 children plus GSTR-3B), Rollup2B (GSTR-2B ITC by document date), BooksLedger (TaxTransaction plus the Rule-37 tracker), Spillover (documents dated in the FY but reported April-October of the next), Formula (derived from other rows in execution order), or Manual (taxpayer entry). Snapshotted onto the summary row at compute time. Values: SQL, Rule, Rollup Filed Returns, Rollup GSTR-2B, Books Ledger, Spillover, Formula, Manual. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Section` | Section | PickList | | Values: 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19. | | `SourceModule` | Source Module | PickList | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `SubSection` | Sub Section | PickList | | Values: 4A, 6B. | | `TableRowCode` | Table Row Code | Text | | | | `TaxType` | Tax Type | PickList | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [GSTR9Summary](/docs/reference/entities/gstr9-summary/) — referenced by via `GSTR9ConfigId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR 9 HSN Summary — entity reference URL: https://xmatix.com/docs/reference/entities/gstr9-hsn-summary/ Last reviewed: 2026-08-16 GSTR-9 HSN-wise summary of outward/inward supplies (Tables 17/18). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CessAmount` | Cess Amount | Currency | | | | `CGSTAmount` | CGST Amount | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Direction` | Direction | Text | | | | `GSTR9ReturnId` | GSTR 9 Return | Lookup → [GSTR9Return](/docs/reference/entities/gstr9-return/) | | | | `HSNCode` | HSN Code | Text | | | | `Id` | Id | Guid | Yes | | | `IGSTAmount` | IGST Amount | Currency | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Quantity` | Quantity | Currency | | | | `Rate` | Rate | Currency | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SGSTAmount` | SGST Amount | Currency | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TaxableValue` | Taxable Value | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UQC` | UQC | Text | | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GSTR9Return](/docs/reference/entities/gstr9-return/) — looks up via `GSTR9ReturnId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR 9 Return — entity reference URL: https://xmatix.com/docs/reference/entities/gstr9-return/ Last reviewed: 2026-10-09 A GSTR 9 Return is the annual GST return for one GSTIN and one financial year. GST-return provisioning creates it as Draft for every active registration that is not an Input Service Distributor, once per GSTIN and year, linked to the year's annual GST fiscal period. Compute GSTR9 builds the statutory rows (GSTR 9 Summary) by rolling up the year's Filed GSTR-1 and GSTR-3B returns and the GSTR-2B portal ITC summary into the Computed lane, your tax ledger into the Books lane of five rows, and Table 17 from the filed GSTR-1 HSN summaries; rows no monthly return carries are created as zeros for you to enter. Entries and overrides need a reason, flow into the dependent sub-totals and survive recompute; 6A, 8A and Table 9 are locked. Status moves Draft, Computed, Validated (pre-file checklist passed, which needs all twelve months filed), Filed. A Validated return is filed through the GSTN integration (Save GSTR-9 to GSTN, File GSTR-9 on GSTN) or recorded with File To GSTN after filing on the portal; a Filed return is frozen. The same record carries the GSTN requests for GSTR-9A and GSTR-9C, which xMatix does not compute; the GSTN fields that support this are described on the Annual returns page. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AATO` | AATO | Currency | | Annual aggregate turnover for the year. The taxpayer's own declaration, which the statutory thresholds depend on; provisioning and Compute GSTR9 never fill it. Included in the Export GSTR9 JSON output. | | `ARN` | ARN | Text | | Acknowledgement number of the GSTR-9 filing, at most 120 characters. Written automatically when File GSTR-9 on GSTN succeeds. The standard File To GSTN dialog does not ask for it. | | `ComputedAt` | Computed At | Date | | When Compute GSTR9 last built the return's rows. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FiledOn` | Filed On | Date | | When the return was filed. Stamped by File To GSTN (the moment it is confirmed) or by a successful File GSTR-9 on GSTN. | | `FinancialYear` | Financial Year | Text | | The financial year the return covers, written like 2025-26. Required when a return is created by hand; xMatix then links or creates the year's annual GST fiscal period and normalises the spelling. Decides which twelve months are rolled up and which year's form definition is used. Cannot be moved to another year once the return is past Draft. | | `GSTIN` | GSTIN | Text | | The GSTIN the annual return is for. Must be a well-formed 15-character GSTIN; only one GSTR-9 is allowed per GSTIN and financial year. Decides which monthly returns and tax ledger lines are read. | | `GSTRegistrationId` | GST Registration | Lookup | | The GST Registration the return is filed under, set by provisioning. Its GSTN session is used by the GSTN actions, and its GSTIN must match the return's. | | `Id` | Id | Guid | Yes | | | `IsFiled` | Is Filed | Boolean | | Yes once the return is filed by either route, set together with Status Filed. A filed return cannot be recomputed, overridden, saved or filed again. | | `LegalName` | Legal Name | Text | | The registered legal name of the taxpayer. Not filled by provisioning. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `Name` | Name | Text | Yes | The record name. Provisioning names it GSTR9--. | | `OTP` | OTP | Number | | No longer stored on the return. The GSTN session used by the GSTN actions comes from the GST Registration's OTP authentication. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `PeriodFrom` | Period From | Date | | Start of the coverage period, filled with 1 April of the financial year. With Period To it sets the document-date range read into the Books lane. | | `PeriodTo` | Period To | Date | | End of the coverage period, filled with 31 March after the financial year starts. | | `PrerequisiteStatus` | Prerequisite Status | Text | | Written by Compute GSTR9: whether every one of the twelve months has a Filed GSTR-1 and GSTR-3B, for example 'Complete: 12/12 GSTR-1 and 12/12 GSTR-3B filed.' or 'Incomplete: 11/12 GSTR-1 and 12/12 GSTR-3B filed.'. The pre-file checklist blocks unless it starts with Complete. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Status` | Status | PickList | | Lifecycle written by the actions: Draft (created), Computed (Compute GSTR9 ran; computing again after validation returns here), Validated (pre-file checklist passed with no blocking findings), Filed (frozen statutory snapshot). Filing by either route needs Validated. Do not set it by hand, whatever values the form's list offers. Values: Draft, Filed, Locked. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `ComputeGSTR9` | Compute GSTR9 | ServerAction (`ComputeGSTR9`) | Roll up the annual GSTR-9 summary from the filed GSTR-1/3B, GSTR-2B and the books ledger. | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | UIAction | Edit | | `ExportGSTR9Json` | Export GSTR9 JSON | ServerAction (`ExportGSTR9Json`) | Emit the GSTN offline-utility JSON payload for the GSTR-9 return. | | `FileToGSTN` | File To GSTN | ServerAction (`FileToGSTN`) | Push to GSTRN | | `GetGSTR9` | Get GSTR9 | ServerAction (`GetGSTR9`) | Get the GSTR-9 table-wise summary (blocks/rows). | | `New` | New | New | New GSTR 9 Return | | `OverrideGSTR9Line` | Override GSTR9 Line | ServerAction (`OverrideGSTR9Line`) | Override a GSTR-9 summary line with a mandatory reason (audit trail). | | `PerformGSTR9Summary` | Get Records | ServerAction (`PerformGSTR9Summary`) | Computes the annual return (legacy name kept as an alias of the compute): wipes and rebuilds the non-overridden GSTR9Summary rows for this header from the tenant's GSTR9Config catalog - rolling up the filed monthly GSTR-1/GSTR-3B returns into the Computed lane and the TaxTransaction books ledger into the Books lane, materializing the variance and rebuilding the HSN tables from the filed GSTR-1 HSN summaries. Overridden rows are preserved and the row version is bumped; a Filed return is refused. Requires the header to exist with a valid GSTIN and financial year. | | `ValidateGSTR9` | Validate GSTR9 | ServerAction (`ValidateGSTR9`) | Run the GSTR-9 pre-file checklist and lock the portal-owned rows. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GSTR9Summary](/docs/reference/entities/gstr9-summary/) — referenced by via `GSTR9ReturnId` - [GSTR9HsnSummary](/docs/reference/entities/gstr9-hsn-summary/) — referenced by via `GSTR9ReturnId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GSTR 9 Summary — entity reference URL: https://xmatix.com/docs/reference/entities/gstr9-summary/ Last reviewed: 2026-08-16 One line of a GSTR-9 annual return (GSTR9ReturnId lookup) - a form table row identified by its section/sub-section/line item and driven by a GSTR9Config catalog row (GSTR9ConfigId). Carries parallel value lanes per tax head (taxable value, IGST, CGST, SGST, cess): the Computed lane rolled up from the filed monthly returns and books by the compute, the Override lane a user adjustment with a mandatory reason, and the Final lane the resolved value carried onto the return. Rebuilt wipe-and-rebuild on every compute except rows marked overridden, which are preserved with their version bumped. Source coordinates (SourceModule, SourceDocumentType, SourceReference) record where a figure came from. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BooksCess` | Books Cess | Currency | | | | `BooksCGST` | Books CGST | Currency | | | | `BooksIGST` | Books IGST | Currency | | | | `BooksSGST` | Books SGST | Currency | | | | `BooksTaxableValue` | Books Taxable Value | Currency | | | | `ComputedCess` | Computed Cess | Currency | | | | `ComputedCGST` | Computed CGST | Currency | | | | `ComputedIGST` | Computed IGST | Currency | | | | `ComputedOn` | Computed On | Date | | | | `ComputedQuantity` | Computed Quantity | Currency | | | | `ComputedSGST` | Computed SGST | Currency | | | | `ComputedTaxableValue` | Computed Taxable Value | Currency | | | | `ComputedTaxAmount` | Computed Tax Amount | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `FinalCess` | Final Cess | Currency | | | | `FinalCGST` | Final CGST | Currency | | | | `FinalIGST` | Final IGST | Currency | | | | `FinalSGST` | Final SGST | Currency | | | | `FinalTaxableValue` | Final Taxable Value | Decimal | | | | `FinalTaxAmount` | Final Tax Amount | Currency | | The resolved tax figure carried onto the return: the override value when the line is overridden, otherwise the computed value. Read the Final lane (not the Computed lane) when quoting what the return reports. | | `GSTR9ConfigId` | GSTR 9 Config | Lookup → [GSTR9Config](/docs/reference/entities/gstr9-config/) | | | | `GSTR9ReturnId` | GSTR 9 Return | Lookup → [GSTR9Return](/docs/reference/entities/gstr9-return/) | | | | `Id` | Id | Guid | Yes | | | `IsLocked` | Is Locked | Boolean | | | | `IsOverridden` | Is Overrden | Boolean | | True once a user adjustment was applied to this line via the override action. Overridden rows survive recompute (the wipe-and-rebuild skips them); only the explicit reset action clears the flag and returns the line to computed values. | | `IsSystemLocked` | Is System Locked | Boolean | | | | `LineItem` | Line Item | Text | | | | `LogicType` | Logic Type | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OverrideCess` | Override Cess | Currency | | | | `OverrideCGST` | Override CGST | Currency | | | | `OverrideIGST` | Override IGST | Currency | | | | `OverrideQuantity` | Override Quantity | Currency | | | | `OverrideReason` | Override Reason | Text | | Mandatory justification captured when a line is overridden - the audit trail for why the filed figure departs from the computed one. | | `OverrideSGST` | Override SGST | Currency | | | | `OverrideTaxableValue` | Override Taxable Value | Currency | | | | `OverrideTaxAmount` | Override Tax Amount | Currency | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Section` | Section | PickList | | Values: 4a, 5a, 6a, 7a, 8a, 9a, 10a, 11a, 12a, 13a, 14a, 15a, 16a, 17a, 18a, 19a. | | `SerialNumber` | Serial Number | Text | | | | `SourceDocumentType` | Source Document Type | PickList | | Values: Invoice, Bill, Journal, NA, 24, 25, 26. | | `SourceModule` | Source Module | PickList | | Values: Sales, Purchase, GL, External, Manual. | | `SourceReference` | Source Reference | Text | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `SubSection` | Sub Section | PickList | | Values: 4A, 6B, Details of Outward supplies made during the financial year on which tax is not payable, Details of ITC availed during the financial year, Details of ITC Reversed and Ineligible ITC for the financial year, Other ITC related information, Details of tax paid as declared in returns filed during the financial year, Supplies / tax declared through Invoices/Debit Note/Amendments (+), Differential tax paid on account of declaration in 10 & 11 above, Particulars of Demands and Refunds, HSN wise summary of outward supplies, HSN wise summary of inward supplies. | | `TableRowCode` | Table Row Code | Text | | | | `TaxType` | Tax Type | PickList | | Values: IGST, CGST, SGST, Cess, NA. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VarianceValue` | Variance Value | Currency | | | | `VersionNo` | Version No | Number | | Compute-run version stamped on the row; bumped when a recompute preserves an overridden row so it is visible that the underlying computed lanes were refreshed since the override was taken. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `EditInLine` | Edit | EditInline | EditInLine | | `New` | New | New | New | ## Related entities - [GSTR9Config](/docs/reference/entities/gstr9-config/) — looks up via `GSTR9ConfigId` - [GSTR9Return](/docs/reference/entities/gstr9-return/) — looks up via `GSTR9ReturnId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # GST Registration — entity reference URL: https://xmatix.com/docs/reference/entities/gstregistration/ Last reviewed: 2026-08-16 A GST registration (GSTIN) held by the company - one PAN can hold multiple GSTINs, one per state. Branches map to exactly one registration, and journal lines plus TaxTransaction rows are stamped with the registration so accounting, returns and reports can be produced GSTIN-wise. The scheduled GST-return provisioning job walks the active registrations each period and creates Draft return headers: GSTR-1/2B/3B for a normal filer, GSTR-6 when EnableISD marks the registration as an Input Service Distributor. E-way bills also reference the registration they were generated under. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EnableISD` | Enable ISD | Boolean | | Marks this GSTIN as an Input Service Distributor registration. The GST-return provisioning job creates a GSTR6 header for ISD registrations instead of the GSTR-1/2B/3B set, and an ISD is excluded from the GSTR-9 annual return. | | `GSTIN` | GSTIN | Text, unique | Yes | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `Label` | Label | Text | | | | `LegalName` | Legal Name | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PAN` | PAN | Text | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company (partner Account) that holds this registration - the owner side, not a customer or vendor. All GSTINs of one company share its PAN. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StateCode` | State Code | Text | | | | `StateName` | State Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditInLineHeader` | Edit | EditInline | EditInLineHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `ProvisionGSTReturns` | Provision GST Returns | ServerAction (`ProvisionGSTReturns`) | Provision GST returns for this GST registration. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `GSTRegistrationId` - [EWayBill](/docs/reference/entities/eway-bill/) — referenced by via `GSTRegistrationId` - [TaxTransaction](/docs/reference/entities/tax-transaction/) — referenced by via `GSTRegistrationId` - [GLAccountPeriodBalance](/docs/reference/entities/glaccount-period-balance/) — referenced by via `GSTRegistrationId` - [PublishedStatement](/docs/reference/entities/published-statement/) — referenced by via `GSTRegistrationId` - [EInvoice](/docs/reference/entities/einvoice/) — referenced by via `GSTRegistrationId` - [JournalLine](/docs/reference/entities/journal-line/) — referenced by via `GSTRegistrationId` - [Branch](/docs/reference/entities/branch/) — referenced by via `GSTRegistrationId` - [ITCLedger](/docs/reference/entities/itcledger/) — referenced by via `GSTRegistrationId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Holiday — entity reference URL: https://xmatix.com/docs/reference/entities/holiday/ Last reviewed: 2026-08-16 A shared non-working-day calendar entry - public holiday, restricted holiday or weekly off - optionally scoped to a Branch and/or to a Business Hours definition. One entity serves two unrelated consumers with different scoping rules: the Service SLA business-hours calculator reads only rows whose Business Hours matches the case's definition, while mobile attendance reads rows that either have no branch or match the person's default branch and ignores Business Hours entirely. Despite the payroll intent recorded in the module plan, payroll proration does not read this calendar at all - payable days are calendar days in the period minus approved unpaid leave, so holidays and weekly offs neither add to nor subtract from pay. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Scoping for the attendance consumer only: mobile attendance treats a row with no branch as company-wide and otherwise matches it against the person's default branch. The Service SLA calculator ignores this field entirely. | | `BusinessHoursId` | Business Hours | Lookup → [BusinessHours](/docs/reference/entities/business-hours/) | | Scoping for the Service SLA consumer only: the business-hours calculator loads exactly the rows whose Business Hours matches the case's definition. A holiday left blank here is therefore invisible to SLA calculations even though mobile attendance still honours it. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Date` | Date | Date | | | | `HolidayType` | Holiday Type | Text | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | Both consumers treat an empty value as active, so only an explicit false takes a date out of the calendar. Clearing it is not the same as deactivating the holiday. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this Holiday. | | `DeleteHeader` | Delete | Delete | Delete | | `DeleteListHeader` | Delete | Delete | DeleteListHeader | | `Edit` | Edit | Edit | Edit this Holiday. | | `Editheader` | Edit | Edit | Edit | | `EditInLine` | Edit | UIAction | Edit | | `EditInLineHeader` | Edit | EditInline | EditInLineHeader | | `New` | New | New | Create a Holiday. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `BranchId` | | | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Incentive Line — entity reference URL: https://xmatix.com/docs/reference/entities/incentive-line/ Last reviewed: 2026-08-16 One rule of an IncentivePlan (incentivePlanId): groups IncentiveTarget rows and decides how they combine via definitionFilterCriteria - Always (No Criteria) auto-qualifies, All Conditions Are Met is an AND, Any Condition Is Met is an OR, and Custom Logic Is Met evaluates the {1} AND {2} OR {3} expression in definitionCustomLogic. Lines are evaluated in sequenceNumber order against plans with Status Approved; when a line qualifies, its CompensationSlab payout bands are applied to the CompensationLine being processed. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DefinitionCustomLogic` | Definition Custom Logic | Text | | | | `DefinitionFilterCriteria` | Definition Filter Criteria | PickList | | How the line's targets combine: Always (No Criteria) auto-qualifies without evaluating targets, All Conditions Are Met requires every target, Any Condition Is Met requires one, Custom Logic Is Met evaluates the {1} AND {2} OR {3} expression in DefinitionCustomLogic over target ordinals. Values: All Conditions Are Met, Any Condition Is Met. | | `Id` | Id | Guid | Yes | | | `IncentivePlanId` | Incentive Plan | Lookup → [IncentivePlan](/docs/reference/entities/incentive-plan/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RewardApplicability` | Reward Applicability | PickList | | Values: All Rewards, Any One With Lowest Value, Any One With Highest Value, Custom Logic. | | `RewardCustomLogic` | Reward Custom Logic | Text | | | | `SequenceNumber` | Sequence | Number | | Evaluation order of the plan's lines; the engine processes lines ascending by this number. | | `Title` | Title | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UseSlabAbsoluteValue` | Use Slab Absolute Value | Boolean | Yes | UI-only toggle in the rewards designer; the incentive engine does not read it and it is not sent when slabs are saved. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — looks up via `IncentivePlanId` - [CompensationSlab](/docs/reference/entities/compensation-slab/) — looks up via `IncentiveLineId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — looks up via `IncentiveLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Incentive Period — entity reference URL: https://xmatix.com/docs/reference/entities/incentive-period/ Last reviewed: 2026-08-16 A date slice of an IncentivePlan, generated automatically on plan insert from the plan's periodType (Yearly one row through to Daily one row per day; weekly rows align to Monday). Per-resource targets (IncentiveResourceTarget), KPI accruals and Compensation payout documents all key off the period. Also supports simulations: a period can be cloned as a what-if via simulationSourcePeriodId with simulationName/simulationType describing the run. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DateFrom` | Date From | Date | | | | `DateTo` | Date To | Date | | | | `Id` | Id | Guid | Yes | | | `IncentivePlanId` | Incentive Plan | Lookup → [IncentivePlan](/docs/reference/entities/incentive-plan/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PeriodName` | Period Name | Text | | | | `ProcessLog` | Process Log | Text | | Free-text log slot for period processing runs; informational only. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SimulationName` | Simulation Name | Text | | | | `SimulationSourcePeriodId` | Incentive Period | Lookup → [IncentivePeriod](/docs/reference/entities/incentive-period/) | | Set on a what-if copy of a period: points at the real period the simulation was cloned from; the source period lists its simulation children. SimulationName and SimulationType describe the run. | | `SimulationType` | Simulation Type | PickList | | Values: Previous Period, Same Period Last Year, Imported KPI Data. | | `Status` | Status | PickList | | Values: Calculated, Draft. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [IncentivePeriod](/docs/reference/entities/incentive-period/) — looks up via `SimulationSourcePeriodId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — looks up via `IncentivePlanId` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `IncentivePeriodId` - [KPIData](/docs/reference/entities/kpidata/) — referenced by via `IncentivePeriodId` - [IncentivePeriod](/docs/reference/entities/incentive-period/) — referenced by via `SimulationSourcePeriodId` - [IncentiveResourceTarget](/docs/reference/entities/incentive-resource-target/) — referenced by via `IncentivePeriodId` - [CompensationSlab](/docs/reference/entities/compensation-slab/) — referenced by via `IncentivePeriodId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `IncentivePeriodId` - [Compensation](/docs/reference/entities/compensation/) — referenced by via `IncentivePeriodId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Incentive Plan — entity reference URL: https://xmatix.com/docs/reference/entities/incentive-plan/ Last reviewed: 2026-08-16 The header of a sales-incentive program: who participates (memberType Resource, Partner, Branch or Customer, optionally narrowed by memberResourceType or memberResourceGroupId), over which window (periodType generates child IncentivePeriod rows on insert - Yearly, Quarterly, Monthly, Weekly, Bi Weekly, Daily), and what is measured and paid (child IncentiveLine rows pairing IncentiveTarget rows with CompensationSlab payout bands). Participants are enrolled as IncentiveResource rows with per-resource targets in IncentiveResourceTarget. The incentive engine only evaluates plans with Status Approved. Scope fields (branch, member type, partner account/group, period type, member resource type) are locked once transactions exist, and a plan cannot name both a partner account and a partner account group. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BusinessHoursId` | Business Hours | Lookup → [BusinessHours](/docs/reference/entities/business-hours/) | | | | `CompensationEligibility` | Compensation Eligibility | PickList | | Values: Any One Max, Any One Min, Formulae. | | `CompensationEligibilityFormula` | Compensation Eligibility Formula | Text | | | | `CopySourceTargets` | Copy Source Targets | Boolean | Yes | Write-and-clear trigger flag: the save handler resets it to false after an update. No first-party code performs a target copy when it is set, so setting it currently has no other effect. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `MemberResourceGroupId` | Resource Group | Lookup → [ResourceGroup](/docs/reference/entities/resource-group/) | | | | `MemberResourceType` | Member Resource Type | PickList | | Optional narrowing of participating resources; only valid when MemberType is Resource - validation rejects it otherwise. Locked once transactions exist. Values: Service Advisor. | | `MemberType` | Member Type | PickList | | Who participates: Resource, Partner, Branch or Customer. Decides which id on the IncentiveResource enrollment (resourceId, partnerAccountId, branchId or contactId) is matched against PerformanceKPI dimension keys. Locked once the plan has enrolled resources or targets. Values: Partner, Dealer, Branch, Resource, Role. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | Mutually exclusive with PartnerAccountId and with BranchId - validation rejects a plan that sets the group together with either of them. | | `PartnerAccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PeriodEndDate` | Period End Date | Date | Yes | | | `PeriodStartDate` | Period Start Date | Date | Yes | | | `PeriodType` | Period Type | PickList | Yes | Yearly, Quarterly, Monthly, Weekly, Bi Weekly or Daily - drives the IncentivePeriod rows generated on insert. Daily, Weekly and Bi Weekly plans may span at most one year. Locked once transactions exist. Values: Weekly, Monthly, Yearly. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SourceIncentivePlanId` | Incentive Plan | Lookup → [IncentivePlan](/docs/reference/entities/incentive-plan/) | | Self-reference linking a plan derived from another plan back to its source; the source lists its derived plans. | | `Status` | Status | PickList | | The incentive engine only evaluates lines of plans with Status Approved; any other status leaves compensation lines unprocessed. Values: Draft, Pending Approval, Approved. | | `SupplierAccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `CreateCompensationSlab` | Create Compensation Slab | ServerAction (`CreateCompensationSlab`) | Seeded as a server action but no server handler implements it - executing it saves the record and performs no other work (the rewards designer creates CompensationSlab rows directly through the data API instead). Only a tenant automation script bound to this action name would give it behavior. | | `CreateIncentiveLine` | Create Incentive Line | ServerAction (`CreateIncentiveLine`) | Seeded as a server action but no server handler implements it - executing it saves the record and performs no other work (the rewards designer creates IncentiveLine rows directly through the data API instead). Only a tenant automation script bound to this action name would give it behavior. | | `CreateIncentiveTarget` | Create Incentive Target | ServerAction (`CreateIncentiveTarget`) | Seeded as a server action but no server handler implements it - executing it saves the record and performs no other work (the rewards designer creates IncentiveTarget rows directly through the data API instead). Only a tenant automation script bound to this action name would give it behavior. | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [KPIDataDetail](/docs/reference/entities/kpidata-detail/) — looks up via `IncentivePlanId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `PartnerAccountGroupId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` - [ResourceGroup](/docs/reference/entities/resource-group/) — looks up via `MemberResourceGroupId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — looks up via `SourceIncentivePlanId` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `IncentivePlanId` - [BusinessHours](/docs/reference/entities/business-hours/) — referenced by via `BusinessHoursId` - [CompensationSlab](/docs/reference/entities/compensation-slab/) — referenced by via `IncentivePlanId` - [Account](/docs/reference/entities/account/) — referenced by via `PartnerAccountId` - [Compensation](/docs/reference/entities/compensation/) — referenced by via `IncentivePlanId` - [Account](/docs/reference/entities/account/) — referenced by via `SupplierAccountId` - [IncentiveLine](/docs/reference/entities/incentive-line/) — referenced by via `IncentivePlanId` - [IncentiveResource](/docs/reference/entities/incentive-resource/) — referenced by via `IncentivePlanId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `IncentivePlanId` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `IncentivePlanId` - [Account](/docs/reference/entities/account/) — referenced by via `AccountId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — referenced by via `SourceIncentivePlanId` - [IncentivePeriod](/docs/reference/entities/incentive-period/) — referenced by via `IncentivePlanId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Incentive Resource Target — entity reference URL: https://xmatix.com/docs/reference/entities/incentive-resource-target/ Last reviewed: 2026-08-16 The per-participant quota for one IncentiveTarget in one IncentivePeriod: value is the number the participant must reach. This row is what the incentive engine actually evaluates - achievement percent is computed as reached value divided by THIS row's value (not the plan-level IncentiveTarget.value), and a participant with no IncentiveResourceTarget row for a target simply does not qualify on it. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IncentivePeriodId` | Incentive Period | Lookup → [IncentivePeriod](/docs/reference/entities/incentive-period/) | | | | `IncentiveResourceId` | Incentive Resource | Lookup → [IncentiveResource](/docs/reference/entities/incentive-resource/) | | | | `IncentiveTargetId` | Incentive Target | Lookup → [IncentiveTarget](/docs/reference/entities/incentive-target/) | Yes | | | `KPIConfigurationId` | KPI Configuration | Lookup → [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `Value` | Value | Number | | The operative quota: achievement percent is computed as reached KPI value divided by this figure, and that percent is what CompensationSlab from/to bands qualify against. A zero value never qualifies. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [IncentiveResource](/docs/reference/entities/incentive-resource/) — looks up via `IncentiveResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [IncentivePeriod](/docs/reference/entities/incentive-period/) — looks up via `IncentivePeriodId` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — looks up via `KPIConfigurationId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `IncentiveTargetId` - [KPIData](/docs/reference/entities/kpidata/) — referenced by via `IncentiveResourceTargetId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Incentive Resource — entity reference URL: https://xmatix.com/docs/reference/entities/incentive-resource/ Last reviewed: 2026-08-16 The enrollment of one participant in an IncentivePlan (incentivePlanId): depending on the plan's memberType this points at a Resource (resourceId), a partner Account (partnerAccountId), a Branch (branchId) or a Contact (contactId). The incentive engine matches KPI rows to the participant through whichever of these ids the plan's member type selects. Per-target quotas for the participant live in child IncentiveResourceTarget rows. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `ContactId` | Contact | Lookup → [Contact](/docs/reference/entities/contact/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IncentivePlanId` | Incentive Plan | Lookup → [IncentivePlan](/docs/reference/entities/incentive-plan/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `ResourceName` | Resource Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Contact](/docs/reference/entities/contact/) — looks up via `ContactId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — looks up via `IncentivePlanId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [IncentiveResourceTarget](/docs/reference/entities/incentive-resource-target/) — referenced by via `IncentiveResourceId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `IncentiveResourceId` - [KPIData](/docs/reference/entities/kpidata/) — referenced by via `IncentiveResourceId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Incentive Target — entity reference URL: https://xmatix.com/docs/reference/entities/incentive-target/ Last reviewed: 2026-08-16 One measurable goal under an IncentiveLine/IncentivePlan: incentiveTargetType picks the metric read from PerformanceKPI accruals - No Of Sale Orders, Sale Order Amount, No Of Invoices, Sale Amount, Sale Order Quantity, Invoice Quantity, Purchase Order Amount, Purchase Order Quantity, No Of Unique Invoices, No Of Unique Items, or Custom KPI (reads the PerformanceKPI field named in customKPIFieldName). Optional itemId, itemGroupId or accountId filters narrow which KPI rows count. The operative quota per participant lives in IncentiveResourceTarget rows, keyed by this target. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrencyIsoCode` | Currency ISO Code | Text | | | | `CustomKPIFieldName` | Custom KPI Field Name | Text | | When IncentiveTargetType is Custom KPI, the PerformanceKPI field name whose values are summed as the reached value; the result is stamped into CompensationLine.customKPIValue. | | `ExternalId` | External | Text | | | | `FinancerId` | Financer | Lookup → [Financer](/docs/reference/entities/financer/) | | | | `FinancerSchemeId` | Financer Scheme | Lookup → [FinancerScheme](/docs/reference/entities/financer-scheme/) | | | | `Id` | Id | Guid | Yes | | | `IncentiveLineId` | Incentive Line | Lookup → [IncentiveLine](/docs/reference/entities/incentive-line/) | | | | `IncentivePlanId` | Incentive Plan | Lookup → [IncentivePlan](/docs/reference/entities/incentive-plan/) | | | | `IncentiveTargetType` | Incentive Target Type | PickList | | The metric read from PerformanceKPI accruals: No Of Sale Orders, Sale Order Amount, No Of Invoices, Sale Amount, Sale Order Quantity, Invoice Quantity, Purchase Order Amount, Purchase Order Quantity, No Of Unique Invoices, No Of Unique Items, or Custom KPI (reads the field named in CustomKPIFieldName). Unknown types contribute zero. Values: No Of Purchase Orders, No Of Sale Orders, No Of Bills, No Of Finance, No Of Insurance, Sale Amount, Bill Amount, Parts Amount, Service Amount, WO Amount, Sale Order Amount, Purchase Order Amount, Finance Amount, Insurance Amount, Billed Hours, Spent Hours, Efficiency, Custom KPI, No Of Unique Invoices, Sale Order Quantity, Sale Invoice Quantity, Purchase Order Quantity, Bill Quantity, Repair Order Quantity, No Of Unique Items. | | `InsuranceSchemeId` | Insurance Scheme | Lookup → [InsuranceScheme](/docs/reference/entities/insurance-scheme/) | | | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | Restricts which PerformanceKPI rows count toward this target: only rows whose item (and SKU, when the membership row pins one) belongs to the group. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `KPIConfigurationId` | KPI Configuration | Lookup → [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Operation` | Operation | PickList | | Values: Equals, Not Equals, Less Than, Greater Than, Greater or Equal, Less or Equal. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SequenceNumber` | Sequence Number | Number | | | | `ServiceContractId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `TargetValueType` | Target Value Type | PickList | | Values: Fixed Value, Value Across Periods, Value Across Resources, Resource Target, Resource Target Percentage, Resource Target Last Period. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `Value` | Value | Currency | | Plan-level default target figure. Note the engine evaluates against the per-participant IncentiveResourceTarget.value, not this field - a participant with no resource-target row does not qualify at all. | | `ValuePercentage` | Value Percentage | Percent | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [InsuranceScheme](/docs/reference/entities/insurance-scheme/) — looks up via `InsuranceSchemeId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — looks up via `IncentivePlanId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Financer](/docs/reference/entities/financer/) — looks up via `FinancerId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [FinancerScheme](/docs/reference/entities/financer-scheme/) — looks up via `FinancerSchemeId` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — looks up via `KPIConfigurationId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` - [IncentiveResourceTarget](/docs/reference/entities/incentive-resource-target/) — looks up via `IncentiveTargetId` - [Item](/docs/reference/entities/item/) — looks up via `ServiceContractId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [CompensationSlab](/docs/reference/entities/compensation-slab/) — looks up via `ReferenceIncentiveTargetId` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `IncentiveTargetId` - [IncentiveLine](/docs/reference/entities/incentive-line/) — referenced by via `IncentiveLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Entity reference — all entities URL: https://xmatix.com/docs/reference/entities/ Last reviewed: 2026-10-10 Every business entity in the xMatix data model, alphabetically. Each page lists the entity's fields — type, requiredness, and what the field does — along with its actions, validations, lookup filters and relationships. | Entity | Fields | Description | |---|---|---| | [Account](/docs/reference/entities/account/) | 96 | An account is the single master record for every organization or person you deal with: customers, suppliers, retail outlets and the partner companies in your network that own transactions. | | [Account Balance](/docs/reference/entities/account-balance/) | 14 | A decommissioned legacy balance table, dropped alongside the old general-ledger table when the balanced journal ledger shipped. | | [Account Group](/docs/reference/entities/account-group/) | 16 | A named set of Accounts used as a targeting dimension by the pricing, discount, tax, scheme, item-component and incentive engines: instead of naming each account, a PriceList, DiscountGroup, TaxGroup, Scheme, SchemeCondition, SchemeAccountBudget, ItemComponent, KPIConfiguration or IncentivePlan row points at a group and the engine resolves the accounts through AccountGroupMember. | | [Account Group Member](/docs/reference/entities/account-group-member/) | 14 | One Account's membership of one AccountGroup - the join every group-aware engine actually reads (pricing, discount, tax, scheme, scheme budget and item-component resolution all query this table rather than any field on Account). | | [Account Group Rule](/docs/reference/entities/account-group-rule/) | 14 | One dynamic-membership condition under an AccountGroup: a field name, an operation and a value, evaluated against the Account entity by the shared group-rule engine when the group's member rebuild runs. | | [Accounting Book](/docs/reference/entities/accounting-book/) | 18 | A parallel valuation perspective for a company — statutory, tax or management — under a named accounting framework. | | [Account Location](/docs/reference/entities/account-location/) | 14 | An aisle, shelf or display at a customer outlet - the unit a merchandising audit is scoped to, classified by locationType and channel. | | [Account Stock](/docs/reference/entities/account-stock/) | 26 | A stock observation recorded at a customer or partner account during a field visit, carrying the visit, visit plan, visit task and visit task activity keys that produced it. | | [Adjustment](/docs/reference/entities/adjustment/) | 26 | An inventory adjustment document header for one branch and partner account; the item-level changes live on AdjustmentLine. | | [Adjustment Line](/docs/reference/entities/adjustment-line/) | 44 | One item-level stock change on an adjustment, for one lot, SKU and storage location. | | [Asset](/docs/reference/entities/asset/) | 92 | A tracked physical unit in the install base — the record the service module hangs warranty, maintenance, servicing history and depreciation off. | | [Asset Block](/docs/reference/entities/asset-block/) | 15 | A pool of assets of one class and one depreciation rate under the Income-tax Act Section 32 block-of-assets scheme — the tax book, kept separate from the Companies Act book that RecurringDepreciation and the fixed-asset schedule maintain. | | [Asset Disposal](/docs/reference/entities/asset-disposal/) | 30 | The retirement of an Asset — sale, scrap or donation — carrying the disposal proceeds and the cost/accumulated-depreciation snapshot used to work out gain or loss. | | [Asset Maintenance](/docs/reference/entities/asset-maintenance/) | 23 | A single planned or executed maintenance job for an Asset — the unit that links an entitlement to the work that consumed it. | | [Asset Service Contract](/docs/reference/entities/asset-service-contract/) | 35 | The per-asset instance of an entitlement whose terms come from an ItemServiceContract template — this is the record that says a specific Asset is actually covered. | | [Asset Service Contract Line](/docs/reference/entities/asset-service-contract-line/) | 14 | One covered component on an AssetServiceContract, with the entitled quantity and how much of it has been consumed. | | [Auto Order](/docs/reference/entities/auto-order/) | 42 | A replenishment-planning header that first proposes what to buy and then generates the purchase order from the accepted proposal. | | [Auto Purchase Order Line](/docs/reference/entities/auto-purchase-order-line/) | 38 | One proposed purchase line inside an AutoOrder, together with the frozen explainability snapshot of how that proposal was reached. | | [Auto Purchase Order Line Relation](/docs/reference/entities/auto-purchase-order-line-relation/) | 22 | An orphan entity: the metadata and domain type exist but nothing else does. | | [Availability Request](/docs/reference/entities/availability-request/) | 11 | A minimal first-party record carrying only a name, a RequestType and a Status, with no relationship to any other business entity. | | [Bank Account](/docs/reference/entities/bank-account/) | 19 | Master record for one account the company holds at a bank; many accounts per company and per operating branch are supported. | | [Banking](/docs/reference/entities/banking-transaction/) | 23 | A legacy standalone bank-feed row (date, deposit or withdrawal, payee, narration, reference) held directly against a GL account, predating the BankAccount / BankStatement / BankStatementLine chain that the current reconciliation engine works from. | | [Bank Reconciliation](/docs/reference/entities/bank-reconciliation/) | 18 | A reconciliation session header for one bank account as at a statement date, holding the closing balance per bank and per book plus the difference between them, and owning the BankReconciliationLine reconciling items. | | [Bank Reconciliation Line](/docs/reference/entities/bank-reconciliation-line/) | 18 | One reconciling item inside a reconciliation session — a bank statement line, a ledger journal line, or a hand-typed adjustment such as an outstanding cheque, a deposit in transit or a bank charge. | | [Bank Statement](/docs/reference/entities/bank-statement/) | 16 | One imported bank statement for a bank account — its as-at date and the bank's opening and closing balances — owning the statement lines that the reconciliation engine matches against posted ledger lines on the bank's GL account. | | [Bank Statement Line](/docs/reference/entities/bank-statement-line/) | 18 | One transaction on an imported bank statement: the bank's value date, its narration and reference, and a deposit or a withdrawal amount. | | [Bank Transfer](/docs/reference/entities/bank-transfer/) | 20 | A movement of funds between two of the company's own bank accounts, posted as a single balanced journal that debits the destination bank's GL account and credits the source's — no party, income or tax leg. | | [Bill](/docs/reference/entities/bill/) | 88 | The vendor-side counterpart of Invoice and the terminus of procure-to-pay. | | [Bill Line](/docs/reference/entities/bill-line/) | 97 | One item on a vendor Bill. | | [Book Valuation Adjustment](/docs/reference/entities/book-valuation-adjustment/) | 17 | A per-book valuation overlay row from the multi-book design: rather than maintaining a parallel ledger, a secondary accounting book's statements are the primary general ledger plus these stored deltas. | | [Branch](/docs/reference/entities/branch/) | 41 | A branch is one operating location of a company, such as a showroom, depot, service centre or office, and the place documents, stock and people are keyed to. | | [Branch Postal Code](/docs/reference/entities/branch-postal-code/) | 14 | Maps one PostalCode to a Branch that serves it, optionally with the owning company (partnerAccountId) and a coverageType classification. | | [Branch Time Slot](/docs/reference/entities/branch-time-slot/) | 28 | A bookable capacity window a Branch offers (startTime to endTime), with per-weekday capacity fields (mondayCapacity through sundayCapacity) and a maximumCapacity ceiling. | | [Branch Time Slot Booking](/docs/reference/entities/branch-time-slot-booking/) | 13 | The per-date consumption record of a BranchTimeSlot: one row per slot per bookingDate carrying that date's capacity and capacityUtilized. | | [Budget](/docs/reference/entities/budget/) | 16 | The planning header for one company (PartnerAccountId) and one fiscal year, optionally narrowed to a business unit and a cost centre; the money itself sits on its BudgetLine children, one per GL account. | | [Budget Commitment](/docs/reference/entities/budget-commitment/) | 20 | An encumbrance row: budget reserved against a GL account by an approved commitment document (purchase order or requisition) before any actual has posted, so the same money cannot be committed twice between approval and invoicing. | | [Budget Line](/docs/reference/entities/budget-line/) | 16 | One budgeted amount for a GL account inside a Budget, optionally pinned to a fiscal period and to business unit, branch, cost-centre and partner dimensions. | | [Business Hour](/docs/reference/entities/business-hours/) | 13 | A working-hours calendar: timeZoneId (a .NET TimeZoneInfo id, null = UTC), workingDaysMask (a bitmask of working weekdays), and the working-day window as minutes from local midnight (dayStartMinutes/dayEndMinutes). | | [Business Unit](/docs/reference/entities/business-unit/) | 15 | An operational division that consolidates one or more Branches for segment accounting and reporting, self-nesting through ParentBusinessUnitId and optionally owned by a partner company through PartnerAccountId. | | [Call](/docs/reference/entities/call/) | 26 | A telephony call log row (Call Register / CTI) - one row per inbound or outbound call. | | [Campaign](/docs/reference/entities/campaign/) | 49 | An outreach/recall campaign in the service module: it defines who is targeted (rule-built CampaignMember rows over Accounts or Assets, per dynamicMemberObject and the child CampaignRule rows) and what is offered (child CampaignItem rows), then its Process* server actions generate the downstream records - Leads, Opportunities (with lines copied from the campaign items), or AssetMaintenance rows - one per member, plus contract/maintenance-schedule reminder leads driven by the reminderDaysOffset fields. | | [Campaign Item](/docs/reference/entities/campaign-item/) | 14 | One item or service the campaign offers (campaignId is the parent; itemId the catalog item, with optional itemServiceContractId and quantity). | | [Campaign Member](/docs/reference/entities/campaign-member/) | 19 | One targeted Account and/or Asset in a Campaign - the row the generation actions fan out from. | | [Campaign Rule](/docs/reference/entities/campaign-rule/) | 15 | One dynamic-membership condition under a Campaign: fieldName + operation + fieldValue evaluated against the member object (Account or Asset) by the shared group-rule engine when ProcessMembers runs. | | [Case](/docs/reference/entities/case/) | 68 | A case is the record of one customer-reported issue or request, tracked from first contact to close. | | [Case Milestone](/docs/reference/entities/case-milestone/) | 12 | A live SLA timer on a Case - one row per milestone the applied SLAPolicy tracks (kind FirstResponse, Resolution, or a custom MilestoneConfig name). | | [Case SLA Event](/docs/reference/entities/case-slaevent/) | 6 | An immutable audit entry for an SLA state change on a Case: eventType is Applied, Warning, Breached, Paused, Resumed, Met or Cancelled, with occurredUtc and an optional detail. | | [Check In Inspection](/docs/reference/entities/check-in-inspection/) | 38 | The record of a customer's vehicle or machine being taken into custody for a job: when it arrived, the meter readings it came in on, and a walk-around of damage findings (Check In Inspection Line rows) with photos attached per section. | | [Check In Inspection Line](/docs/reference/entities/check-in-inspection-line/) | 16 | One recorded finding for a single sub-section of the check-in inspection - for example the front bumper within the exterior section - not one line per item or quantity. | | [Check In Template](/docs/reference/entities/check-in-template/) | 11 | The reusable inspection checklist for one product type: it carries almost no data of its own beyond a name and ApplicableItemId, and its content is entirely in its CheckInTemplateLine children. | | [Check In Template Line](/docs/reference/entities/check-in-template-line/) | 14 | One sub-section of a check-in checklist, defining the area being inspected (SectionName plus SubSection) and the list of pre-set issues an inspector can tick. | | [Checklist Line](/docs/reference/entities/check-list-line/) | 30 | One recorded checklist answer: the runtime row for a ChecklistTemplateLine question (checklistTemplateLineId) with typed value slots (booleanValue, numericValue, decimalValue, currencyValue, dateValue, dateTimeValue, timeValue, textValue, ragValue, email, phone, url). | | [Checklist Template](/docs/reference/entities/checklist-template/) | 24 | A reusable questionnaire header whose questions are child ChecklistTemplateLine rows. | | [Checklist Template Line](/docs/reference/entities/checklist-template-line/) | 25 | One question on a ChecklistTemplate: dataType picks the answer control, picklistValues supplies choices, and parent/dependent links build conditional question trees. | | [Cheque Register](/docs/reference/entities/cheque-register/) | 18 | A cheque book issued against a bank account: a number range from start to end with an optional prefix, plus a live counter holding the next number to be drawn. | | [Cheque Transaction](/docs/reference/entities/cheque-transaction/) | 21 | One cheque and its clearing lifecycle, either drawn by the company or received from a customer. | | [Claim](/docs/reference/entities/claim/) | 42 | Header of a claim raised against a supplier, principal or manufacturer for money or stock owed back to the dealer — warranty and service-contract recovery, damage/shortage on inward goods, and trade-scheme/incentive payouts. | | [Claim Batch](/docs/reference/entities/claim-batch/) | 24 | A working container that groups many Claims through ClaimBatchLine junction rows so they can be populated and reconciled together instead of one at a time. | | [Claim Batch Line](/docs/reference/entities/claim-batch-line/) | 11 | Junction row linking one Claim into one ClaimBatch; it carries no amounts or quantities of its own. | | [Claim Generation Setup](/docs/reference/entities/claim-generation-setup/) | 42 | One row per automated claim scenario for the config-driven claims.generate engine — it names the source entity, the selection conditions, how rows are grouped into claims, which amount is aggregated, and how source fields map onto the resulting Claim and ClaimLine. | | [Claim Generation Rule](/docs/reference/entities/claim-generation-setup-rule/) | 11 | One selection condition of a ClaimGenerationSetup, expressed as field path, operation and value with a sequence number. | | [Claim Line](/docs/reference/entities/claim-line/) | 57 | One claimable item on a Claim, holding the claimed quantity and unit price alongside the approved and rejected splits that everything downstream reads. | | [Claim Reconciliation](/docs/reference/entities/claim-reconciliation/) | 16 | Register head for matching credit actually received from a supplier or principal against the claims that were submitted, holding the credit-note amount, the reconciled amount and the period date. | | [Claim Reconciliation Line](/docs/reference/entities/claim-reconciliation-line/) | 24 | Per-item detail under a ClaimReconciliation, restating the claimed and approved quantities and amounts for one ClaimLine plus a rejection reason and remarks. | | [Claim Settlement Setup](/docs/reference/entities/claim-settlement-setup/) | 15 | Post-approval settlement configuration, one active row per claim type, consumed by the claims.settle job when an approval process returns Approved on a Claim. | | [Collaborator](/docs/reference/entities/collaborator/) | 5 | A named participant on a record, carrying a team role and an intended access level. | | [Company Card](/docs/reference/entities/company-card/) | 18 | A corporate credit card assigned to an employee Resource. | | [Card Reconciliation](/docs/reference/entities/company-card-reconciliation/) | 16 | A corporate-card reconciliation session comparing the card statement's closing balance against the Credit Card Payable book balance for one CompanyCard, recording the difference. | | [Card Transaction](/docs/reference/entities/company-card-transaction/) | 22 | One imported corporate-card statement line: date, merchant, amount, and the expense category / expense GL account the employee tags it with, optionally linked to an ExpenseClaimLine and a receipt file. | | [Compensation](/docs/reference/entities/compensation/) | 16 | The payout header for one participant scope in one IncentivePeriod of an IncentivePlan: groups the CompensationLine detail rows and carries totalIncentiveAmount and a status. | | [Compensation Line](/docs/reference/entities/compensation-line/) | 60 | The incentive calculation worksheet for one participant (incentiveResourceId) under a Compensation header: saving it triggers the incentive engine, which loads the plan's approved IncentiveLine rules, matches PerformanceKPI accruals to the participant by the plan's member type, evaluates each IncentiveTarget against the participant's IncentiveResourceTarget quota, stamps the reached metric onto the matching summary field (noOfSaleOrders, saleAmount, noOfUniqueInvoices, customKPIValue and so on), and applies the qualifying CompensationSlab rewards - writing incentiveAmount, gifts/giftPoints, schemeId or discountGroupId depending on the slab's compensation type. | | [Compensation Slab](/docs/reference/entities/compensation-slab/) | 33 | A payout band under an IncentiveLine (incentiveLineId): qualifies when the participant's achievement percent - floor of 100 times reached value over the IncentiveResourceTarget quota - falls between fromPercentage and toPercentage (a null or zero toPercentage means no upper bound; the first matching band in sequence wins). | | [Complaint](/docs/reference/entities/complaint/) | 12 | A master list of customer-reportable symptoms - the 'what the customer says is wrong' vocabulary - not an individual customer grievance or case. | | [Complaint Fault](/docs/reference/entities/complaint-fault/) | 15 | The diagnosed fault code that a technician assigns against a reported complaint - the 'what was actually wrong' counterpart to the customer-reported Complaint symptom. | | [Consolidation Group](/docs/reference/entities/consolidation-group/) | 14 | A named set of business units reported together, so statutory and management groupings can differ without maintaining separate ledgers. | | [Consolidation Group Member](/docs/reference/entities/consolidation-group-member/) | 12 | The junction row placing one business unit into a consolidation group. | | [Contact](/docs/reference/entities/contact/) | 43 | An individual person, usually attached to an Account via accountId (an account's people are its Contacts collection; the account's primary contact is pointed at by Account.accountContactId). | | [Contact Address](/docs/reference/entities/contact-address/) | 26 | A contact address is one entry in an account's address book: a billing address, a shipping address, or one that serves as both. | | [Contract](/docs/reference/entities/contract/) | 28 | A service/maintenance agreement header for a customer Account, optionally tied to a single Asset. | | [Contract Line](/docs/reference/entities/contract-line/) | 30 | One covered-scope line of a service/maintenance agreement: the catalog Item covered or supplied, quantity and pricing (unit price, cost price, discount), the count of customer assets covered, contracted hours, and the preventive-maintenance visit cadence. | | [Contract Line item](/docs/reference/entities/contract-lineitem/) | 25 | A priced coverage line under an asset service contract, naming the item covered, the covered asset, a date window, quantity and pricing, and an optional year number for multi-year contracts. | | [Conversion Batch](/docs/reference/entities/conversion-batch/) | 51 | A staged document conversion (Order → Invoice, Requisition → Purchase Order, …). | | [Conversion Batch Line](/docs/reference/entities/conversion-batch-line/) | 32 | One source line in a conversion batch, with its outcome and the document it produced. | | [Conversion Definition](/docs/reference/entities/conversion-definition/) | 33 | Declares one document conversion (Order→Invoice, Requisition→Purchase Order, …) for the conversion batch engine. | | [Cost Center](/docs/reference/entities/cost-center/) | 15 | A hierarchical cost-allocation dimension (parentCostCenterId builds the tree, optionally under a Business Unit), stamped on expense claims, claim lines and advances for cost control and segment reporting - complementary to Branch and Business Unit. | | [Credit Limit](/docs/reference/entities/credit-limit/) | 17 | The credit ceiling a company (PartnerAccountId) extends to one customer account (AccountId), and the row that actually blocks trading. | | [Credit Note](/docs/reference/entities/credit-note/) | 65 | A credit document that reduces what a party owes, and the merged home of three different documents discriminated by TransactionType: null/empty is a pure financial AR credit note (Dr Sales / Cr AR, party = AccountId); "SaleReturn" is a customer goods return (the mirror of an Invoice, revenue and AR reversal, lines carry items and post to inventory); "BillReturn" is a purchase return to a supplier (Dr AP / Cr GR-IR plus input-tax reversal, party = SupplierAccountId). | | [Credit Note Line](/docs/reference/entities/credit-note-line/) | 115 | One item or charge line of a CreditNote, and like its parent it carries three flavours driven by the parent's TransactionType: a financial line (GL repost on approval only), a SaleReturn line (item/price/tax setup, inventory posting, and return-quantity write-backs to the source InvoiceLine, DeliveryOrderLine and OrderLine), and a BillReturn line (same setup plus write-backs to Bill, PurchaseOrder and GoodsReceipt lines). | | [Currency](/docs/reference/entities/currency/) | 15 | An ISO 4217 currency the tenant transacts in. | | [Currency Revaluation](/docs/reference/entities/currency-revaluation/) | 17 | A period-end foreign-exchange revaluation run that restates open foreign-currency positions at the closing rate. | | [Currency Revaluation Line](/docs/reference/entities/currency-revaluation-line/) | 20 | One revalued foreign-currency position on a revaluation run, typically a bank balance, a receivable or a payable, identified by its ledger account and, where relevant, the counterparty. | | [Cycle Count](/docs/reference/entities/cycle-count/) | 40 | A physical stock-count exercise for one branch and partner account, optionally narrowed by Item, ItemGroup, ABC/FSN class or StorageLocation. | | [Cycle Count Line](/docs/reference/entities/cycle-count-line/) | 35 | One item to count within a cycle count, generated per item lot or per InventoryStock row: OnHandQuantity is the system expectation seeded at generation per the header's CountQuantityType, RecordedQuantity is the physical count, and the calculated variance DiscrepencyQuantity (misspelled in C# and metadata; the JSON and API name is discrepancyQuantity) is RecordedQuantity minus OnHandQuantity. | | [Cycle Count Rule](/docs/reference/entities/cycle-count-rule/) | 14 | A stored field, operator and value criterion attached to a cycle count and ordered by SequenceNumber. | | [Dealer Onboarding](/docs/reference/entities/dealer-onboarding/) | 81 | A dealership application record capturing everything an applicant is assessed on in one wide document: applicant identity and residence, firm constitution and PAN/GST, showroom and workshop area and ownership, banking references, financial capability, and the letter of intent dates. | | [Debit Note](/docs/reference/entities/debit-note/) | 30 | A debit document with two directions selected by TransactionType. | | [DebitNoteLine](/docs/reference/entities/debit-note-line/) | 52 | One charge line of a DebitNote, tying the note to the Bill line (BillLineId) or the supply it adjusts and carrying the amount the ledger posts. | | [Delivery Order](/docs/reference/entities/delivery-order/) | 111 | The outbound dispatch document for a customer or dealer account: what is leaving a branch, to which ship-to address, under which transporter and e-way-bill references. | | [Delivery Order Line](/docs/reference/entities/delivery-order-line/) | 106 | One item line of a delivery order, and the row that actually moves stock: when the parent's PerformInventoryPosting runs, four mutually exclusive seeded ledger rules discriminate on InventoryFulfilmentPickingLineId, InventoryFulfilmentAllocationLineId and InvoiceLineId to post an Outward movement and relieve the matching reservation bucket (Picked, Allocation or PendingDeliveries). | | [Depreciation](/docs/reference/entities/depreciation/) | 19 | A depreciation schedule header for an Asset, holding the method, the start and end dates, the period count and the residual value, with DepreciationLine as its per-period breakdown. | | [Depreciation Line](/docs/reference/entities/depreciation-line/) | 20 | One period of a Depreciation schedule — period number, the opening and closing book values, the charge for the period and the running accumulated total. | | [Depreciation Policy](/docs/reference/entities/depreciation-policy/) | 20 | A reusable, category-level template for how a class of assets should be depreciated — method, rate, useful life, frequency and currency — which assets adopt through Asset.DepreciationPolicyId. | | [Discount Group](/docs/reference/entities/discount-group/) | 18 | A container for contract-discount percentages that DiscountGroupService stamps onto a document header when the header has none. | | [Discount Group Rule](/docs/reference/entities/discount-group-rule/) | 20 | One dated discount percentage inside a DiscountGroup, aimed at an item, an item group or a SKU. | | [Document Name](/docs/reference/entities/document-name/) | 13 | The runtime sequence counter behind automatic document numbering: one row per target entity and document series (entityName plus documentSeries) holding lastNumberUsed. | | [Document Name Setting](/docs/reference/entities/document-name-setting/) | 19 | Tenant configuration that switches on automatic document-name generation for one target entity: at save time the naming service composes series, date and sequence into the record field named by destinationFieldName, using dateFormat, autoNumberLength and concatenationCharacter to shape the result and allocating numbers from the DocumentName counter for the resolved series. | | [Document Service Contract Line](/docs/reference/entities/document-service-contract-line/) | 15 | A service-contract scope line captured against a sales document rather than against an asset or a template — it records which component items are in or out of scope on an Opportunity line, sale order line or sale invoice line. | | [Duplicate Rule](/docs/reference/entities/duplicate-rule/) | 5 | An admin-authored duplicate-detection rule for one entity (entityName), with the field criteria on child DuplicateRuleCondition rows. | | [E Invoice](/docs/reference/entities/einvoice/) | 32 | Register table modelled on the IRP/NIC e-invoicing submission: source invoice reference, seller and buyer GSTIN, the IRP request payload, and the IRN, acknowledgement, signed invoice and QR code that come back. | | [Employee](/docs/reference/entities/employee/) | 46 | The HR and payroll configuration record for a person, and a satellite of Resource rather than a replacement for it. | | [ESI Rule](/docs/reference/entities/esirule/) | 17 | The Employees' State Insurance rule master for a company: the gross-wage eligibility threshold above which ESI does not apply at all, plus the employee and employer contribution rates, effective-dated. | | [E-Way Bill](/docs/reference/entities/eway-bill/) | 34 | An e-way bill (Rule 138) for a movement of goods - one register entry per generated bill, linked polymorphically to its source document via SourceEntityName/SourceRecordId (invoice, delivery order, transfer) and to the GSTRegistration, branch and company it was generated under. | | [Exchange Rate](/docs/reference/entities/exchange-rate/) | 16 | A conversion rate between two currency codes effective from a date: one unit of fromCurrency equals rate units of toCurrency. | | [Executive Position](/docs/reference/entities/executive-position/) | 14 | The dated record of who occupies a Position and over what window; a seat's ownership history is the set of these rows, not a separate audit trail. | | [Expense Advance](/docs/reference/entities/expense-advance/) | 25 | A cash advance paid to an employee (Resource) before travel or work - the mirror image of a claim: the employee owes the company. | | [Advance Settlement](/docs/reference/entities/expense-advance-settlement/) | 16 | One settlement event on an ExpenseAdvance, written automatically by the advance actions rather than entered by hand: SettleAgainstClaim writes a row with settlementType AgainstClaim (linking the ExpenseClaim), RecoverAdvance writes CashReturn; PayrollRecovery exists in the vocabulary. | | [Expense Category](/docs/reference/entities/expense-category/) | 22 | The expense spend taxonomy (Travel, Hotel, Meals, Fuel and similar) referenced by claim lines, card transactions and policy rules. | | [Expense Claim](/docs/reference/entities/expense-claim/) | 43 | An employee reimbursement claim, anchored on the claimant Resource (resourceId - the same person key HR/payroll use; employeeAccountId is the legacy Account-based key). | | [Expense Claim Line](/docs/reference/entities/expense-claim-line/) | 49 | One expense position on an ExpenseClaim: the expense GL account debited (expenseGLAccountId), amount and GST, the ExpenseCategory, merchant/invoice details, payment mode, cost dimensions (project, cost centre, branch) and the receipt file. | | [Expense Policy](/docs/reference/entities/expense-policy/) | 16 | A named set of expense rules (child ExpensePolicyRule rows) evaluated against a claim by the policy engine. | | [Expense Policy Rule](/docs/reference/entities/expense-policy-rule/) | 19 | One rule inside an ExpensePolicy: a ruleType, an optional ExpenseCategory scope (empty = all categories), a numeric threshold, and the action taken on breach (HardBlock, Warn, RequireHigherApproval, AutoDisallow). | | [Policy Violation](/docs/reference/entities/expense-policy-violation/) | 19 | The audit record written when policy evaluation finds a breach on a claim or a specific claim line: the rule (expensePolicyRuleId), ruleType, severity (Info, Warning, Block), a message, and the excess amount for over-limit breaches. | | [Expense Receipt](/docs/reference/entities/expense-receipt/) | 19 | Receipt metadata for an ExpenseClaimLine - the binary itself is a FileAsset in blob storage. | | [Reimbursement Batch](/docs/reference/entities/expense-reimbursement-batch/) | 17 | A batch reimbursement run: pays several posted claims to their employees in one bank transaction. | | [Reimbursement Batch Line](/docs/reference/entities/expense-reimbursement-batch-line/) | 16 | One claim inside an ExpenseReimbursementBatch, linking the ExpenseClaim and its Resource. | | [Expense Voucher](/docs/reference/entities/expense-voucher/) | 27 | A direct-expense voucher for petty-cash / non-PO spend, separate from the employee claim flow: posting writes a balanced journal debiting each line's expense GL account and crediting the payment GL account for the total. | | [Expense Voucher Line](/docs/reference/entities/expense-voucher-line/) | 17 | One expense head on an ExpenseVoucher: the expense GL account debited and its amount plus tax. | | [Field Sales](/docs/reference/entities/field-sales/) | 35 | The van-sales (field sales) run document: one record per van journey, tying the executing rep, the van (StorageLocationId, a mobile StorageLocation) and the depot it draws from (SourceStorageLocationId) to a visit plan and a set of stock lines. | | [Field Sales Invoice](/docs/reference/entities/field-sales-invoice/) | 14 | The join between a FieldSales van run and an Invoice raised during it, plus the cash actually collected against that invoice. | | [Field Sales Line](/docs/reference/entities/field-sales-line/) | 34 | One item line of a van-sales run, carrying the same item through every stage of the journey in separate quantity buckets rather than mutating one figure: Quantity is the dispatcher's planned load, ReceivedQuantity plus the TakeIn damaged/shortage/excess trio is what the rep confirmed onto the van, SoldQuantity is accumulated back from the run's invoice lines at day end, and the CheckIn quantities are what the dispatcher counted back into the depot. | | [Finance Case](/docs/reference/entities/finance-case/) | 39 | A retail finance application raised against a sale: it records what the customer asked for and what the financier granted as parallel requested/approved/disbursed sets of amount, down payment, interest rate, tenure and EMI, and links the sale through OrderId and InvoiceId plus the financier through FinanceProviderId and FinancerSchemeId. | | [Financer](/docs/reference/entities/financer/) | 8 | The list of finance providers a tenant can raise a FinanceCase with - a bare reference master carrying only a name, with the commercial terms held on its child FinancerScheme rows. | | [Financer Scheme](/docs/reference/entities/financer-scheme/) | 20 | One named financing product offered by a Financer, bounding the deals that may be written under it: minimum and maximum amount, minimum and maximum tenure in months, and a free-text Features blurb. | | [Financial Projection](/docs/reference/entities/financial-projection/) | 24 | An entered, scenario-based forecast header for a company and fiscal year — the manual sibling of Budget, kept parallel to it rather than merged, with its own scenario and version columns. | | [Financial Projection Line](/docs/reference/entities/financial-projection-line/) | 32 | One forecast line inside a FinancialProjection. | | [Statement Layout](/docs/reference/entities/financial-statement-layout/) | 15 | A tenant-authored presentation tree for one statement type, intended to let a company reorder, rename or regroup statement lines without touching the Schedule III mapping held on the chart of accounts. | | [Statement Layout Node](/docs/reference/entities/financial-statement-layout-node/) | 16 | One line of a statement layout tree. | | [Fiscal Period](/docs/reference/entities/fiscal-period/) | 17 | One month of a company's fiscal year. | | [Fiscal Year](/docs/reference/entities/fiscal-year/) | 14 | The accounting calendar of one company: a dated window whose monthly fiscal periods decide which dates a journal can post into. | | [Follower](/docs/reference/entities/follower/) | 4 | A subscription marking a user as watching a record, created by the Follow server action and retired by Unfollow, both of which soft-delete rather than remove rows. | | [Form 26AS Line](/docs/reference/entities/form26-asline/) | 24 | | | [Form 26AS Reconciliation Entry](/docs/reference/entities/form26-asreconciliation-entry/) | 26 | | | [Form 26AS Statement](/docs/reference/entities/form26-asstatement/) | 24 | | | [Form 3CD Clause](/docs/reference/entities/form3-cdclause/) | 18 | Statutory Form 3CD (tax-audit report) clause catalog: clause number, part, title and description. | | [Full & Final Settlement](/docs/reference/entities/full-and-final-settlement/) | 18 | The exit settlement for a leaving employee: payable components such as salary to the last working day, leave encashment, gratuity and pending reimbursement, net of deductions such as notice recovery, loan recovery and TDS, all held as FullAndFinalSettlementLine children. | | [F&F Line](/docs/reference/entities/full-and-final-settlement-line/) | 17 | One component of an exit settlement, either an amount owed to the departing employee or an amount recovered from them. | | [General Ledger](/docs/reference/entities/general-ledger/) | 27 | A decommissioned legacy ledger table. | | [GL Account](/docs/reference/entities/glaccount/) | 30 | An account in a company's chart of accounts: the target every journal line debits or credits and the unit every financial statement adds up. | | [GL Period Balance](/docs/reference/entities/glaccount-period-balance/) | 19 | A rebuildable aggregate of posted journal lines per GL account, fiscal period and dimension tuple — a cache, never the source of truth. | | [Goods Receipt](/docs/reference/entities/goods-receipt/) | 45 | The inbound receiving document: goods physically arriving at a branch from a supplier, plus the supplier's dispatch and invoice references and transporter details. | | [Goods Receipt Line](/docs/reference/entities/goods-receipt-line/) | 57 | One item line of a goods receipt, and the row that converts arriving goods into stock movements and a cost layer. | | [Grade](/docs/reference/entities/grade/) | 14 | An employee grade/band master referenced by Resource.gradeId. | | [GST Fiscal Period](/docs/reference/entities/gstfiscal-period/) | 14 | One GST return period - a calendar month (month + year) tagged with the Indian financial year it falls in. | | [GSTR1](/docs/reference/entities/gstr1/) | 18 | Root of a granular GSTR-1 outward-supply return: one filing per filer GSTIN and return period (the period is the linked GSTFiscalPeriod via gstFiscalPeriodId, not a raw MMYYYY string). | | [B2B Invoice](/docs/reference/entities/gstr1-b2-binvoice/) | 24 | A single outward B2B invoice in GSTR-1 Table 4, belonging to a GSTR1B2BSupply group (grouped by buyer GSTIN). | | [B2B Supply](/docs/reference/entities/gstr1-b2-bsupply/) | 16 | GSTR-1 Table 4 grouping row - supplies to a registered buyer, grouped by the buyer's GSTIN (buyerGstin) under a GSTR1 header. | | [B2C Large Invoice](/docs/reference/entities/gstr1-b2-clinvoice/) | 22 | A single B2C-large invoice in GSTR-1 Table 5, belonging to a GSTR1B2CLSupply group. | | [B2C Large Supply](/docs/reference/entities/gstr1-b2-clsupply/) | 15 | GSTR-1 Table 5 grouping row - B2C large: inter-state supplies to unregistered buyers exceeding the per-invoice threshold, grouped by place of supply under a GSTR1 header. | | [B2C Small Supply](/docs/reference/entities/gstr1-b2-cssupply/) | 22 | GSTR-1 Table 7 row - B2C small: aggregated supplies to unregistered buyers, summarised by supply scope (intra/inter), place of supply and tax rate. | | [GSTR1 Credit/Debit Note](/docs/reference/entities/gstr1-credit-debit-note/) | 23 | GSTR-1 Tables 9 and 10 - a credit or debit note adjusting an earlier outward invoice, under a GSTR1 header. | | [Document Summary](/docs/reference/entities/gstr1-document-summary/) | 20 | GSTR-1 Table 13 row - documents issued during the return period: one row per document nature/series with the issued serial range (serialNumberFrom/To), the total issued, the count cancelled, and the resulting net issued. | | [Export Invoice](/docs/reference/entities/gstr1-export-invoice/) | 21 | A single export invoice in GSTR-1 Table 6, belonging to a GSTR1ExportSupply group. | | [Export Supply](/docs/reference/entities/gstr1-export-supply/) | 15 | GSTR-1 Table 6 grouping row - export supplies under a GSTR1 header, grouped by payment treatment (exportType: with or without payment of IGST). | | [HSN Summary](/docs/reference/entities/gstr1-hsnsummary/) | 24 | GSTR-1 Table 12 row - HSN/SAC-wise summary of outward supplies for the return period: quantity, taxable value and the IGST/CGST/SGST-UTGST/cess breakup per HSN code and rate. | | [GST Line Item](/docs/reference/entities/gstr1-line-item/) | 22 | Shared rate-slab tax breakup line for GSTR-1 documents: the taxable value at a single GST rate with its IGST/CGST/SGST-UTGST/cess split. | | [Nil Rated Supply](/docs/reference/entities/gstr1-nil-rated/) | 18 | GSTR-1 Table 8 row - nil-rated, exempt and non-GST outward supplies, summarised by supplyType (inter/intra x B2B/B2C per the GSTN taxonomy) with one value column per bucket (nilSupplies, exemptSupplies, nonGstSupplies) and no tax amounts. | | [GSTR2B](/docs/reference/entities/gstr2-b/) | 17 | One GSTR-2B statement: the input tax credit statement GSTN drafts every month from what suppliers filed, for one recipient GSTIN and one monthly GST fiscal period. | | [B2B Amendment Invoice](/docs/reference/entities/gstr2-bb2-bainvoice/) | 29 | An amended inward B2B invoice in GSTR-2B, belonging to a GSTR2BB2BASupplier. | | [B2B Amendment Supplier](/docs/reference/entities/gstr2-bb2-basupplier/) | 14 | GSTR-2B B2B amendment section grouping row - supplier amendments to previously reported B2B invoices, grouped by supplier GSTIN under a GSTR2B header. | | [B2B Invoice 2B](/docs/reference/entities/gstr2-bb2-binvoice/) | 27 | A single inward B2B invoice in the GSTR-2B statement, belonging to a GSTR2BB2BSupplier. | | [B2B Supplier](/docs/reference/entities/gstr2-bb2-bsupplier/) | 16 | GSTR-2B B2B section grouping row - inward supplies from one registered supplier, grouped by the supplier's GSTIN under a GSTR2B header, with the supplier's trade name, the period they reported (supplyPeriod) and when they filed (supplierFilingDate). | | [CDN Amendment Note](/docs/reference/entities/gstr2-bcdnranote/) | 25 | An amended inward credit/debit note in GSTR-2B, belonging to a GSTR2BCDNRASupplier. | | [CDN Amendment Supplier](/docs/reference/entities/gstr2-bcdnrasupplier/) | 14 | GSTR-2B credit/debit-note amendment section grouping row - supplier amendments to previously reported notes, grouped by supplier GSTIN under a GSTR2B header. | | [CDNR Note](/docs/reference/entities/gstr2-bcdnrnote/) | 23 | A single inward credit or debit note in GSTR-2B, belonging to a GSTR2BCDNRSupplier, with its own tax breakup, ITC availability and IMS action status. | | [CDN Supplier](/docs/reference/entities/gstr2-bcdnrsupplier/) | 14 | GSTR-2B credit/debit-note section grouping row - notes from one registered supplier, grouped by the supplier's GSTIN under a GSTR2B header. | | [E-Commerce Amendment Document](/docs/reference/entities/gstr2-becoadocument/) | 27 | An amended e-commerce supply document in GSTR-2B, belonging to a GSTR2BECOASupplier. | | [E-Commerce Amendment Supplier](/docs/reference/entities/gstr2-becoasupplier/) | 14 | GSTR-2B e-commerce amendment section grouping row - amendments to previously reported section 9(5) e-commerce supplies, grouped by the operator's GSTIN under a GSTR2B header. | | [E-Commerce Document](/docs/reference/entities/gstr2-becodocument/) | 24 | A single section 9(5) e-commerce supply document in GSTR-2B, belonging to a GSTR2BECOSupplier. | | [E-Commerce Supplier](/docs/reference/entities/gstr2-becosupplier/) | 14 | GSTR-2B e-commerce section grouping row - supplies on which the e-commerce operator pays tax under section 9(5), grouped by the operator's GSTIN (ecoGstin) under a GSTR2B header. | | [Import (Overseas)](/docs/reference/entities/gstr2-bimpgrecord/) | 20 | GSTR-2B import-of-goods record - an overseas import auto-populated from ICEGATE against a Bill of Entry (portCode, billOfEntryNumber/Date/Value). | | [Import (SEZ)](/docs/reference/entities/gstr2-bimpgsezrecord/) | 23 | GSTR-2B import-from-SEZ record - goods received from an SEZ unit against a Bill of Entry. | | [ISD Amendment Credit](/docs/reference/entities/gstr2-bisdacredit/) | 21 | An amended ISD distributed-credit document in GSTR-2B, belonging to a GSTR2BISDASupplier. | | [ISD Amendment Supplier](/docs/reference/entities/gstr2-bisdasupplier/) | 14 | GSTR-2B ISD amendment section grouping row - amendments to previously distributed ISD credits, grouped by the ISD's GSTIN under a GSTR2B header. | | [ISD Credit](/docs/reference/entities/gstr2-bisdcredit/) | 19 | A single ISD distributed-credit document (ISD invoice or credit note, per documentType) in GSTR-2B, belonging to a GSTR2BISDSupplier. | | [ISD Supplier](/docs/reference/entities/gstr2-bisdsupplier/) | 14 | GSTR-2B ISD section grouping row - input-tax credits distributed by an Input Service Distributor, grouped by the ISD's GSTIN (isdGstin) under a GSTR2B header. | | [ITC Summary](/docs/reference/entities/gstr2-bitcsummary/) | 20 | GSTR-2B aggregate ITC totals row under a GSTR2B header: the GSTN ITC-available and ITC-not-available blocks flattened into paired tax-head columns (an itcAvailable and an itcNotAvailable column each for IGST, CGST, SGST-UTGST and cess). | | [GSTR-2B Reconciliation Entry](/docs/reference/entities/gstr2-breconciliation-entry/) | 33 | Persisted ITC reconciliation workbench row - one GSTR-2B document matched against the local purchase books (a Bill, via localBillId). | | [GSTR 3B](/docs/reference/entities/gstr3-b/) | 23 | One GSTR-3B monthly summary return for one GSTIN and one monthly GST fiscal period. | | [GSTR 3B Filing Log](/docs/reference/entities/gstr3-bfiling-log/) | 18 | | | [GSTR 3B Table 4A ITC](/docs/reference/entities/gstr3-bitc-available/) | 17 | | | [GSTR 3B Table 4D ITC](/docs/reference/entities/gstr3-bitc-ineligible/) | 17 | | | [GSTR-3B Table 4B ITC](/docs/reference/entities/gstr3-bitc-reversed/) | 18 | | | [GSTR 3B Payment](/docs/reference/entities/gstr3-bpayment/) | 18 | GSTR-3B Table 6.1 payment of tax per head (feeds GSTR-9 Table-9 paid). | | [GSTR 3B Rule 37 Tracker](/docs/reference/entities/gstr3-brule37-tracker/) | 20 | | | [GSTR 3B Table 3.1](/docs/reference/entities/gstr3-bsection31/) | 19 | | | [GSTR 3B Table 3.1.1](/docs/reference/entities/gstr3-bsection311/) | 17 | | | [GSTR 6](/docs/reference/entities/gstr6/) | 25 | A GSTR 6 record is the monthly return of an Input Service Distributor (ISD) registration: one record per ISD GSTIN and return month, created as Draft by GST-return provisioning for every GST Registration with Enable ISD switched on. | | [ISD Distribution](/docs/reference/entities/gstr6-isddistribution/) | 30 | | | [ISD Document Series](/docs/reference/entities/gstr6-isddocument-series/) | 16 | GSTR-6 ISD document serial allocator (Rule 54(1)). | | [ISD Recipient Allocation](/docs/reference/entities/gstr6-isdrecipient-allocation/) | 32 | | | [ISD Recipient Turnover](/docs/reference/entities/gstr6-isdrecipient-turnover/) | 21 | GSTR-6 ISD recipient turnover (Rule 39 pro-rata master). | | [ISD Source Document](/docs/reference/entities/gstr6-isdsource-document/) | 45 | ISD Source Documents | | [GSTR 9 Config](/docs/reference/entities/gstr9-config/) | 24 | The tenant's copy of the GSTR-9 form catalog - one row per form line and value lane describing HOW that figure is produced: the section/sub-section/line item coordinates, the logic type dispatch key (rollup of filed returns, 2B rollup, books ledger, spillover, formula over other rows, or manual entry) and its logic definition. | | [GSTR 9 HSN Summary](/docs/reference/entities/gstr9-hsn-summary/) | 21 | GSTR-9 HSN-wise summary of outward/inward supplies (Tables 17/18). | | [GSTR 9 Return](/docs/reference/entities/gstr9-return/) | 23 | A GSTR 9 Return is the annual GST return for one GSTIN and one financial year. | | [GSTR 9 Summary](/docs/reference/entities/gstr9-summary/) | 54 | One line of a GSTR-9 annual return (GSTR9ReturnId lookup) - a form table row identified by its section/sub-section/line item and driven by a GSTR9Config catalog row (GSTR9ConfigId). | | [GST Registration](/docs/reference/entities/gstregistration/) | 18 | A GST registration (GSTIN) held by the company - one PAN can hold multiple GSTINs, one per state. | | [Holiday](/docs/reference/entities/holiday/) | 16 | A shared non-working-day calendar entry - public holiday, restricted holiday or weekly off - optionally scoped to a Branch and/or to a Business Hours definition. | | [Incentive Line](/docs/reference/entities/incentive-line/) | 17 | One rule of an IncentivePlan (incentivePlanId): groups IncentiveTarget rows and decides how they combine via definitionFilterCriteria - Always (No Criteria) auto-qualifies, All Conditions Are Met is an AND, Any Condition Is Met is an OR, and Custom Logic Is Met evaluates the {1} AND {2} OR {3} expression in definitionCustomLogic. | | [Incentive Period](/docs/reference/entities/incentive-period/) | 18 | A date slice of an IncentivePlan, generated automatically on plan insert from the plan's periodType (Yearly one row through to Daily one row per day; weekly rows align to Monday). | | [Incentive Plan](/docs/reference/entities/incentive-plan/) | 28 | The header of a sales-incentive program: who participates (memberType Resource, Partner, Branch or Customer, optionally narrowed by memberResourceType or memberResourceGroupId), over which window (periodType generates child IncentivePeriod rows on insert - Yearly, Quarterly, Monthly, Weekly, Bi Weekly, Daily), and what is measured and paid (child IncentiveLine rows pairing IncentiveTarget rows with CompensationSlab payout bands). | | [Incentive Resource](/docs/reference/entities/incentive-resource/) | 15 | The enrollment of one participant in an IncentivePlan (incentivePlanId): depending on the plan's memberType this points at a Resource (resourceId), a partner Account (partnerAccountId), a Branch (branchId) or a Contact (contactId). | | [Incentive Resource Target](/docs/reference/entities/incentive-resource-target/) | 14 | The per-participant quota for one IncentiveTarget in one IncentivePeriod: value is the number the participant must reach. | | [Incentive Target](/docs/reference/entities/incentive-target/) | 31 | One measurable goal under an IncentiveLine/IncentivePlan: incentiveTargetType picks the metric read from PerformanceKPI accruals - No Of Sale Orders, Sale Order Amount, No Of Invoices, Sale Amount, Sale Order Quantity, Invoice Quantity, Purchase Order Amount, Purchase Order Quantity, No Of Unique Invoices, No Of Unique Items, or Custom KPI (reads the PerformanceKPI field named in customKPIFieldName). | | [Individual](/docs/reference/entities/individual/) | 31 | A person-level privacy and consent record: names and salutation plus data-protection flags (dontMarket, dontProcess, dontProfile, dontTrack, forgetThisIndividual, exportIndividualsData, canStorePiiElsewhere, blockGeolocationTracking) and demographic attributes such as birth/death dates, occupation and consumer credit score fields. | | [Inspection Line](/docs/reference/entities/inspection-line/) | 38 | The goods-receipt quality inspection record, unrelated to the CheckIn* check-in inspection family. | | [Insurance Scheme](/docs/reference/entities/insurance-scheme/) | 10 | A thin reference list of insurance schemes, holding only a name and the insurer's own name for the same scheme so external naming can be reconciled with internal naming. | | [Interest Charge](/docs/reference/entities/interest-charge/) | 47 | Interest charged on one overdue open item for one accrual window, with its full derivation. | | [Interest Policy](/docs/reference/entities/interest-policy/) | 33 | Rate and rule master for interest on overdue payments. | | [Interest Run](/docs/reference/entities/interest-run/) | 27 | One interest accrual batch: computes and posts charges for overdue items as at a cut-off date. | | [Job Queue](/docs/reference/entities/interface-queue/) | 9 | A named grouping handle for background interface/job processing - the row itself holds only a label. | | [Inventory Cost Consumption](/docs/reference/entities/inventory-cost-consumption/) | 20 | One draw of an issue against a cost lot, recorded per accounting book and per method because FIFO and LIFO consume different layers for the same physical issue. | | [Inventory Cost Lot](/docs/reference/entities/inventory-cost-lot/) | 25 | A persisted receipt cost layer for one (accounting book, item, branch, method) scope: how much arrived at what unit cost and how much of that layer is still unconsumed. | | [Inventory Fulfilment](/docs/reference/entities/inventory-fulfilment/) | 33 | The fulfilment document (Fulfilment Orders in the Warehouse and Inventory apps) is the warehouse's work order for outbound stock. | | [Allocation Line](/docs/reference/entities/inventory-fulfilment-allocation-line/) | 52 | One reservation against a single concrete stock source: an ItemLot when the item is lot-tracked, otherwise an InventoryStock bucket. | | [Inventory Fulfillment Order Line](/docs/reference/entities/inventory-fulfilment-order-line/) | 35 | The demand side of a fulfilment: one line per source OrderLine or ServiceOrderLine, carrying the quantity that still needs reserving. | | [Inventory Fulfillment Picking Line](/docs/reference/entities/inventory-fulfilment-picking-line/) | 38 | A physical pick raised one-for-one from an allocation line, capped at that line's PendingPickingQuantity; it can only exist with an allocation-line parent, which the handler enforces on insert. | | [Inventory Ledger](/docs/reference/entities/inventory-ledger/) | 36 | The append-only journal of posted inventory movements: one row per source line per matching active InventoryLedgerSetting rule, written only by InventoryLedgerService.DoLedgerPostingAsync. | | [Inventory Ledger Setting](/docs/reference/entities/inventory-ledger-setting/) | 18 | The configuration that makes inventory posting generic: one row per source line entity and ledger type, telling the posting engine (InventoryLedgerService.DoLedgerPostingAsync) how a save of that entity becomes InventoryLedger rows plus stock-counter updates. | | [Inventory NRV Assessment](/docs/reference/entities/inventory-nrv-assessment/) | 28 | A lower-of-cost-and-net-realisable-value assessment for one item or one group of similar items, per accounting book and fiscal period: the carrying cost, the NRV inputs, the impairment movement recorded this run, and the cumulative outstanding write-down that caps any later reversal at original cost. | | [Inventory Opening Lot State](/docs/reference/entities/inventory-opening-lot-state/) | 22 | The open cost lots at the start of a fiscal period, one row per lot, keyed by partner account + accounting book + fiscal period + item + branch + valuation method. | | [Inventory Stock](/docs/reference/entities/inventory-stock/) | 60 | The running stock balance for one stock-keeping slot, keyed by partner account + branch + item + SKU + storage location; rows are created on demand by the ledger posting engine and never entered by hand (the entity has no New/Edit/Delete server actions). | | [Inventory Valuation Policy](/docs/reference/entities/inventory-valuation-policy/) | 23 | The rule that decides which cost-flow method the engine uses for a transaction, per accounting book. | | [Invoice](/docs/reference/entities/invoice/) | 157 | A sales invoice bills a customer for goods or services and turns the sale into a receivable. | | [Invoice Line](/docs/reference/entities/invoice-line/) | 136 | One billed item on an Invoice, and the level at which price, discount and tax are actually resolved. | | [ITC Ledger](/docs/reference/entities/itcledger/) | 27 | Input Tax Credit ledger for Indian GST: one entry per ITC event for a GSTIN and tax period, split into CGST, SGST, IGST and cess. | | [Item](/docs/reference/entities/item/) | 61 | An item is the master record for anything bought, sold, stocked or serviced - a product, part, charge, unit of work, service contract or discounted item - and every document line names one. | | [Item Alias](/docs/reference/entities/item-alias/) | 15 | An alternative identity for an item, optionally narrowed to a SKU and a lot type, that can be selected on a document line instead of the item itself (OrderLine, InvoiceLine, DeliveryOrderLine, PurchaseOrderLine and OpportunityLine all carry an ItemAliasId). | | [Item Alternate](/docs/reference/entities/item-alternate/) | 19 | A directed substitution from one item to another, optionally effective-dated, used both automatically and as a suggestion. | | [Item Cart](/docs/reference/entities/item-cart/) | 15 | A staging basket row that parks an item, SKU, lot type, account and quantity against an Order before it becomes an order line. | | [Item Component](/docs/reference/entities/item-component/) | 29 | One line of a package/bill-of-materials definition: it attaches a component item (and optionally a component SKU) to a parent item, with a quantity, min/max bounds and selection rules. | | [Item Consumption Rate](/docs/reference/entities/item-consumption-rate/) | 15 | One tier of a consumption schedule: a lower and upper consumption bound plus the price that applies inside that band. | | [Item Consumption Schedule](/docs/reference/entities/item-consumption-schedule/) | 19 | A tiered usage price book for an item, holding the ItemConsumptionRate tiers that price metered consumption on subscriptions. | | [Item Feature](/docs/reference/entities/item-feature/) | 19 | A named option group under an item that ItemComponent rows point at, so a configurable product's components can be presented in labelled sets. | | [Item Group](/docs/reference/entities/item-group/) | 15 | A named set of items used to scope pricing, tax, discount, scheme, incentive, cycle-count and mobile-selling rules without listing every item. | | [Item Group Member](/docs/reference/entities/item-group-member/) | 16 | The junction row that places an item (optionally narrowed to a SKU and a lot type) in an item group; it is what every group-scoped engine actually joins against. | | [Item Group Rule](/docs/reference/entities/item-group-rule/) | 16 | One clause of an item group's dynamic-membership predicate: a field name, an operator and a comparison value, applied in sequenceNumber order. | | [Item Inventory Attribute](/docs/reference/entities/item-inventory-attribute/) | 28 | The replenishment and counting policy for an item, optionally narrowed by SKU, lot type, branch and partner account, with a null scope column meaning 'applies to all'. | | [Item Lot](/docs/reference/entities/item-lot/) | 75 | One traceable batch or serial instance of an item at one partner + branch + storage location, with its own costs, dates and per-lot quantity counters that the ledger posting engine moves in step with InventoryStock. | | [Item Lot Type](/docs/reference/entities/item-lot-type/) | 22 | An item-scoped commercial variant or grade of stock - promo, sample or saleable, with optional price and variation codes - carried on nearly every transactional line and copied onto ledger rows and lots as they are created. | | [Item Maintenance Schedule](/docs/reference/entities/item-maintenance-schedule/) | 28 | A service-interval definition for an item, optionally per SKU: when the service falls due (in days, usage hours or a usage reading), the from/to duration and usage window it covers, its position in the sequence of services, and up to five reminder day-offsets. | | [Item Relation](/docs/reference/entities/item-relation/) | 17 | Declares which other items are permitted alongside a given parent item, and is the backend source of truth for that restriction: ItemRelationService.ValidateRelatedItemsAsync checks each document line's item against the related-item set of the document's parent item and rejects one that is not listed. | | [Item Service Contract](/docs/reference/entities/item-service-contract/) | 35 | The template that defines a sellable service entitlement for an Item, SKU or lot type — coverage window, usage limits, grace allowances and the rules that govern how the entitlement behaves when it is claimed. | | [Item Service Contract Line](/docs/reference/entities/item-service-contract-line/) | 13 | A component covered by an ItemServiceContract template, with the entitled quantity — the template-level counterpart of AssetServiceContractLine. | | [Item Unit Of Measure](/docs/reference/entities/item-unit-of-measure/) | 15 | An alternate unit for an item (optionally per SKU), carrying the conversion ratio that relates one of this unit to the item's base unit named in Item.quantityUnitOfMeasure. | | [Journal](/docs/reference/entities/journal/) | 26 | The single posting vehicle of the ledger: every value movement in the platform — document posting, manual entry, opening balance, depreciation, payroll, allocation, reversal and period close — is a journal, and its posted lines ARE the general ledger. | | [Journal Line](/docs/reference/entities/journal-line/) | 23 | One debit or credit leg of a journal, and the row that financial statements, the trial balance and the account ledger are ultimately aggregated from. | | [Knowledge Article](/docs/reference/entities/knowledge-article/) | 10 | A knowledge-base article: titled (Name), categorized help content with a publish lifecycle (status: Draft, Published, Archived) and a visibility of Internal (agent-only) or Public (portal/customer). | | [KPI Configuration](/docs/reference/entities/kpiconfiguration/) | 39 | A KPI definition - the catalog row that names a measurable performance indicator (kpiName, label) and declares where its numbers come from: triggerObjectName/triggerEvent point at the source entity and event, and the *FieldName pointers (accountFieldName, branchFieldName, dateFieldName, itemFieldName, partnerFieldName, resourceFieldName, valueFieldName/valueFieldName2 with valueFunction, rewardFieldName with rewardFunction) map source-entity fields into the KPI dimensions and measures. | | [KPI Data](/docs/reference/entities/kpidata/) | 27 | An aggregated KPI result row - the computed output of a KPIConfiguration for one dimensional slice: kpiConfigurationId identifies the definition, and the slice is keyed by combinations of accountId, partnerAccountId, branchId, resourceId, employeeId, incentivePlanId, incentivePeriodId and incentiveResourceTargetId. | | [KPI Data Detail](/docs/reference/entities/kpidata-detail/) | 18 | One contributing source document under a KPIData aggregate - the drill-down line that shows which document produced how much of the parent total. | | [KPI Rule](/docs/reference/entities/kpirules/) | 15 | A filter condition attached to a KPIConfiguration (kpiConfigurationId): fieldName + operation + fieldValue express one predicate over the KPI's trigger entity, and sequenceNumber orders the conditions. | | [KYC Document](/docs/reference/entities/kycdocument/) | 22 | An identity/verification document captured during onboarding or a financed sale: documentType and documentNumber identify the document, kycType classifies the check, isVerified records the outcome and externalId keeps the provider's reference. | | [Landed Cost](/docs/reference/entities/landed-cost/) | 22 | A voucher gathering the incidental costs of a receipt — freight, customs duty and other charges — so they can be apportioned across the received items and capitalised. | | [Landed Cost Line](/docs/reference/entities/landed-cost-line/) | 19 | One received item on a landed-cost voucher, holding the quantity and base value that drive the apportionment plus the freight, duty and other amounts assigned to it. | | [Lead](/docs/reference/entities/lead/) | 49 | A lead is an enquiry that has not been qualified yet: who the person or business is, how to reach them, where the enquiry came from and what they want. | | [Leave Entitlement](/docs/reference/entities/leave-entitlement/) | 13 | The declared leave allowance for a leave type, granted either to a single Resource or to a whole Resource Group. | | [Leave Request](/docs/reference/entities/leave-request/) | 16 | A person's request for time off across a date range, keyed on Resource and never on Employee. | | [Leave Type](/docs/reference/entities/leave-type/) | 11 | The catalogue of leave categories, and the setting that decides whether an absence costs the employee pay. | | [Loan / Advance](/docs/reference/entities/loan-advance/) | 26 | An employee salary advance, travel advance or loan, disbursed from a bank or cash account and then recovered through payroll in installments, keyed on Resource. | | [Loan Recovery](/docs/reference/entities/loan-advance-recovery/) | 17 | The audit row for one installment taken out of one payroll run against a loan or advance; the payroll calculation writes these, users do not create them. | | [Lower Deduction Certificate](/docs/reference/entities/lower-deduction-certificate/) | 22 | A lower or nil-deduction certificate held by a party - s.395 of the Income-tax Act 2025, Form 128 (erstwhile s.197 / Form 13). | | [LWF Rule](/docs/reference/entities/lwfrule/) | 17 | The state-wise Labour Welfare Fund rule master: a flat employee and employer contribution for a state, with the deduction frequency (Monthly, HalfYearly or Annual), effective-dated. | | [Macro](/docs/reference/entities/macro/) | 7 | A reusable, named set of ordered MacroStep actions an agent runs against a record in one click - set a field, send an email template, pause or resume the SLA, add a note, create a task, or close the record. | | [Macro Step](/docs/reference/entities/macro-step/) | 6 | One ordered action inside a Macro, linked by macroId and executed in stepOrder sequence. | | [Milestone Config](/docs/reference/entities/milestone-config/) | 7 | A custom SLA milestone definition under an SLAPolicy, beyond the built-in FirstResponse and Resolution milestones. | | [Mobile Sync Failure](/docs/reference/entities/mobile-sync-failure/) | 24 | A terminally-failed mobile outbox row, reported by the device once an offline store-and-forward mutation is rejected or conflicts and its retries are exhausted. | | [Monthly TDS Projection](/docs/reference/entities/monthly-tds-projection/) | 27 | The month's salary-TDS projection for one employee: annual income projected forward, verified Chapter VI-A deductions applied, annual tax computed and spread over the months remaining in the financial year. | | [Open Transaction](/docs/reference/entities/open-transaction/) | 26 | One open AR/AP item per posted document — invoice, bill, credit or debit note, advance receipt or payment — created at posting time by DocumentJournalPostingService and reduced by SettlementAllocation rows. | | [Opportunity](/docs/reference/entities/opportunity/) | 115 | An opportunity is a qualified deal being worked: the customer, the items or services under negotiation with their prices, and the record quotes, sales orders and service orders are raised from. | | [Opportunity Line](/docs/reference/entities/opportunity-line/) | 84 | One item or service position under an Opportunity (opportunityId + itemId + quantity). | | [Order](/docs/reference/entities/order/) | 113 | A sales order records what a customer has agreed to buy: the customer account, the selling partner account and branch, the executive, addresses and pricing context, with one order line per item. | | [Order Line](/docs/reference/entities/order-line/) | 122 | One item position of a sales Order (OrderId plus ItemId and Quantity) carrying its own pricing, discount, tax and inventory context. | | [Partner Account Mapping](/docs/reference/entities/partner-account-mapping/) | 22 | A dated rule that allows or blocks items or item groups for one sales executive, optionally narrowed to a selling company, selling company group, branch, customer or customer group. | | [Partner Resource](/docs/reference/entities/partner-resource/) | 20 | A dated posting of a Resource to a selling organisation - a partner account and/or a branch - for a date window, plus an optional reporting manager. | | [Party Period Balance](/docs/reference/entities/party-period-balance/) | 18 | The receivables and payables subledger balance: one row per party inside a control account, per fiscal period and business unit, aggregated from posted control-account journal lines. | | [Payment](/docs/reference/entities/payment/) | 53 | A single money movement in either direction and the only document that settles AR/AP open items: PaymentType 'Payment Taken' is a customer receipt, 'Payment Given' a vendor or employee disbursement. | | [Payment Adjustment](/docs/reference/entities/payment-adjustment/) | 21 | The legacy settlement link: one row nets a payment or credit document against an open document and carries the amount applied. | | [Payment Batch](/docs/reference/entities/payment-batch/) | 17 | A header intended to group money movements for one bank run — an outgoing vendor payment file or an incoming customer deposit slip, distinguished by BatchType — with a count and total rolled up from its lines. | | [Payment Batch Line](/docs/reference/entities/payment-batch-line/) | 16 | One member document inside a PaymentBatch. | | [Payment (Salary Disbursement)](/docs/reference/entities/payment-salary-disbursement/) | 16 | A legacy, thin salary-payout record hanging off a PayrollRun, superseded by PayrollPaymentBatch and its lines. | | [Payroll Adjustment](/docs/reference/entities/payroll-adjustment/) | 19 | A one-off earning or deduction for a single employee in a single payroll period — bonus, penalty, arrears or an ad-hoc reimbursement — held outside the salary structure so it affects exactly one run. | | [Payroll Component](/docs/reference/entities/payroll-component/) | 29 | The reusable pay-component master — every earning, deduction, employer contribution and reimbursement a company can pay, defined once with its type, taxability, calculation method, statutory nature and both GL account mappings. | | [Salary Payment Batch](/docs/reference/entities/payroll-payment-batch/) | 20 | The salary disbursement batch: one bank payment that settles many employees' Payroll-Payable open items in a single posting of Dr Payroll Payable / Cr Bank. | | [Payment Batch Line](/docs/reference/entities/payroll-payment-batch-line/) | 18 | One employee's net-pay row inside a salary payment batch, holding the amount, the bank account and IFSC snapshotted from the Resource at generation time, and a per-line payment status. | | [Payroll Period](/docs/reference/entities/payroll-period/) | 20 | The payroll processing calendar entry (monthly by default, also weekly, biweekly or daily) that every payroll document hangs off: runs, adjustments, statutory challans, TDS projections, loan recovery windows and payslips are all scoped by PayrollPeriodId. | | [Payroll Run](/docs/reference/entities/payroll-run/) | 23 | One execution of payroll for a PayrollPeriod, and the header that drives the whole chain: Project TDS, Calculate, Post, Generate Payslips, Generate Payment. | | [Run Component Line](/docs/reference/entities/payroll-run-component-line/) | 23 | One component's calculated amount for one employee in one payroll run — the finest grain of the payroll calculation and the only place individual earning and deduction figures exist. | | [Payroll Run Detail](/docs/reference/entities/payroll-run-detail/) | 32 | The per-employee summary line of a PayrollRun: one row per Resource processed, carrying rolled-up gross, deductions and net, employer contributions, reimbursements, the day breakdown, and the statutory subtotals TDS, PF and ESI. | | [Statutory Challan](/docs/reference/entities/payroll-statutory-challan/) | 22 | A statutory deposit for a payroll period — the PF, ESI, PT, salary-TDS or LWF payment that clears the company-level liability payroll posting accumulated. | | [Payslip](/docs/reference/entities/payslip/) | 28 | The employee-facing pay document generated from a PayrollRunDetail, carrying header totals plus year-to-date rollups and a masked bank account. | | [Performance KPI](/docs/reference/entities/performance-kpi/) | 49 | A flat performance fact row - the accumulator table that the Scheme and Incentive engines read to know what a partner, account or resource has actually done. | | [Period Close](/docs/reference/entities/period-close/) | 18 | The audit record of one run of the period-close checklist against a fiscal period. | | [Period Close Check](/docs/reference/entities/period-close-check/) | 16 | One evaluated line of a period-close run: a single integrity test with a stable machine code, whether it was blocking, whether it passed, and a detail string naming the offending counts. | | [PF Rule](/docs/reference/entities/pfrule/) | 18 | The Provident Fund rule master for a company: the wage ceiling that caps the PF basis, the employee and employer contribution rates, and the EDLI and administration charge rates, effective-dated. | | [Place](/docs/reference/entities/place/) | 12 | A geographic location master arranged as a self-referencing hierarchy: parentPlaceId points at the containing place, and level/placeType describe what kind of node it is. | | [Planogram](/docs/reference/entities/planogram/) | 8 | A shelf-layout definition that merchandising audits are judged against: layoutJson holds the structured expectation (shelves, positions, product and expected facings) the compliance calculator consumes, and an optional reference photo rides the generic file-asset pipeline. | | [PM Task](/docs/reference/entities/pmtask/) | 24 | A single scheduled preventive-maintenance visit for an Asset, delivered under a ContractLine (not under the Contract header). | | [Position](/docs/reference/entities/position/) | 15 | A field-sales seat, or territory slot, that exists independently of whoever currently occupies it. | | [Postal Code](/docs/reference/entities/postal-code/) | 16 | A postal/PIN code master row with its city (free-text city plus a cityPlaceId lookup to Place), state, region and country. | | [Posting Definition](/docs/reference/entities/posting-definition/) | 24 | The account-determination rule that decides which GL account a document's journal lines hit, and the successor to the legacy accounting rules. | | [Posting Error Log](/docs/reference/entities/posting-error-log/) | 21 | The failed-posting queue: one open entry per source document and posting purpose whose general-ledger posting threw, so the failure is visible and retryable instead of being lost when the posting transaction rolls back. | | [Price List](/docs/reference/entities/price-list/) | 20 | A named collection of item prices whose actual amounts live in child PriceListRule rows. | | [Price List Rule](/docs/reference/entities/price-list-rule/) | 18 | One dated price for one item on one price list, optionally narrowed to a specific SKU and/or item lot type. | | [Price Lot](/docs/reference/entities/price-lot/) | 18 | The cost layer the platform actually uses for receipt costing, valuation and COGS is InventoryCostLot in the Finance module, not this entity. | | [Price Lot Line](/docs/reference/entities/price-lot-line/) | 13 | The allocation child of PriceLot, pairing an invoice line with a price lot and a cost price. | | [Product Catalogue](/docs/reference/entities/product-catalogue/) | 29 | Groups store categories and items available for a store or partner: belongs to a Store (storeId) or a partner Account (partnerAccountId) and is referenced by StoreCategory rows via catalogueId. | | [Product Catalogue Image](/docs/reference/entities/product-catalogue-image/) | 15 | An image asset for a catalogue listing: links a StoreCategoryItem (storeCategoryItemId) and/or the underlying Item, with imageType, imageUrl and orderIndexNumber controlling ordering. | | [Product Configurator Image Detail](/docs/reference/entities/product-configurator-image-detail/) | 13 | Associates a catalogue image with a specific item so a configurator view can show the right picture for a chosen configuration, with an optional currency code and integration id. | | [Appointment](/docs/reference/entities/product-demo/) | 41 | The execution record of a product demo / test drive: process and outcome fields (demoStatus, demoRating, customerVoice, usage readings, cancellation reason) around a demo of an item (itemId) or demo asset (demoAssetId) for an account. | | [Professional Tax Slab](/docs/reference/entities/professional-tax-slab/) | 18 | The state-wise professional-tax slab table: for a monthly gross-wage band, the flat PT amount, with a separate February amount because some states levy a different figure in that month. | | [Project](/docs/reference/entities/project/) | 18 | A project or job used as a cost-and-revenue dimension and as the target for recharging billable expenses to a customer. | | [Prospect Place](/docs/reference/entities/prospect-place/) | 12 | An externally-sourced place (a Places-API lookup or purchased list) that a field rep can onboard as an Account from the visit agenda's nearby-to-onboard feed. | | [Published Statement](/docs/reference/entities/published-statement/) | 23 | An immutable filed snapshot of a computed financial statement, the artifact that survives any later reclassification of the chart of accounts. | | [Purchase Order](/docs/reference/entities/purchase-order/) | 86 | A purchase order is the commitment to a supplier: the items, quantities and prices bought for a branch, and the document every later shipment, goods receipt and bill links back to line by line. | | [Purchase Order Line](/docs/reference/entities/purchase-order-line/) | 98 | One item position on a purchase order: PurchaseOrderId plus ItemId, SKUId and Quantity, carrying the resolved buy price (UnitCost, with UnitCost2 overriding it in the amount formula), the discount ladder, a per-line snapshot of up to six taxes in the Tax1..Tax6 name/rate/type/amount slots, and the counters that drive the chain. | | [Purchase Order Requisition](/docs/reference/entities/purchase-order-requisition/) | 20 | A junction row designed to link a requisition and requisition line to the purchase order line that fulfils it, optionally tagged with the AutoOrder that produced it and carrying RequestedQuantity and OrderedQuantity. | | [Purchase Return](/docs/reference/entities/purchase-return/) | 12 | Its only structural role is as the target of Claim.PurchaseReturnId, so a claim can be tagged against a return. | | [Purchase Return Line](/docs/reference/entities/purchase-return-line/) | 10 | Its only structural role is as the target of ClaimLine.PurchaseReturnLineId. | | [Queue](/docs/reference/entities/queue/) | 5 | A work queue for Omni-Channel routing. | | [Quote](/docs/reference/entities/quote/) | 94 | A quote is the priced offer sent to a customer: the customer, the items or services offered with their prices and taxes, and the record a sales order or service order is created from once the customer agrees. | | [Quote Line](/docs/reference/entities/quote-line/) | 94 | One item or service position on a Quote. | | [Reconciliation Match](/docs/reference/entities/reconciliation-match/) | 16 | A confirmed pairing of one bank statement line with one posted ledger journal line on the bank's GL account; the set of these rows is what drives the reconciliation summary's matched totals and its unmatched residual. | | [Reconciliation Matching Rule](/docs/reference/entities/reconciliation-matching-rule/) | 16 | A configurable gate that narrows which posted ledger lines may be paired with a bank statement line. | | [Recurring Depreciation](/docs/reference/entities/recurring-depreciation/) | 27 | A per-asset (or per-pool) depreciation schedule that posts one period's charge at a time under the Companies Act book: either a fixed straight-line amount or a written-down-value rate applied to the reducing balance, floored at the residual value. | | [Recurring Journal](/docs/reference/entities/recurring-journal/) | 19 | A template that materialises a posted journal on a schedule — rent, accrual, amortisation and standing provision entries. | | [Recurring Journal Line](/docs/reference/entities/recurring-journal-line/) | 17 | One fixed debit or credit leg of a recurring-journal template, cloned into a journal line on every run. | | [Requisition](/docs/reference/entities/requisition/) | 40 | A requisition is an internal request for items raised before a supplier is committed. | | [Requisition Line](/docs/reference/entities/requisition-line/) | 55 | One requested item on a requisition, numbered from document numbering (shipped series RL). | | [Resource](/docs/reference/entities/resource/) | 47 | A resource is the record for one person who does work in xMatix - a sales executive, service advisor, technician, driver, manager or back-office employee - and the record that documents, visits, timesheets, payslips, expense claims, leave and loans point to when they name a person. | | [Resource Assignment Rule](/docs/reference/entities/resource-assignment-rule/) | 15 | One field condition of a PartnerResource's auto-assignment setup (linked by partnerResourceId): fieldName, operation and fieldValue describe a test evaluated against the record being assigned. | | [Resource Availability](/docs/reference/entities/resource-availability/) | 25 | One attendance day for a field Resource: the date, the branch it belongs to plus the branches where check-in and check-out actually happened, the first check-in and last check-out times, accumulated duration and penaltyHours, and a leaveRequestId link when the day is explained by leave. | | [Resource Availability Check In](/docs/reference/entities/resource-availability-check-in/) | 15 | One check-in/check-out pair inside a ResourceAvailability day, numbered by documentNumber. | | [Resource Availability Data](/docs/reference/entities/resource-availability-data/) | 15 | A raw attendance punch event for a Resource: the event time and attendanceTime, its type, the branch, and the parent ResourceAvailability day it rolls up into. | | [Resource Business Hour](/docs/reference/entities/resource-business-hours/) | 13 | A resource's actual working calendar comes from Resource.BusinessHoursId pointing at the BusinessHours master (used, for example, to pick the timezone for attendance auto-checkout, falling back to the default branch's hours), and appointment slot availability is driven by the branch's BusinessHours plus branch holidays. | | [Resource Compensation](/docs/reference/entities/resource-compensation/) | 17 | Despite sitting near the Rewards entities, this is a payroll record: the assignment of a SalaryStructure to a Resource (the employee salary assignment of the payroll plan), with ctc, an effectiveFrom/effectiveTo window, a revisionReason for changes and an isActive flag. | | [Resource Group](/docs/reference/entities/resource-group/) | 18 | A named pool of Resources; membership is the child ResourceGroupMember rows. | | [Resource Group Member](/docs/reference/entities/resource-group-member/) | 12 | A junction row placing one Resource into a ResourceGroup (both lookups required). | | [Resource Leave](/docs/reference/entities/resource-leave/) | 13 | Real leave lives in LeaveRequest and LeaveEntitlement keyed on ResourceId: approved unpaid LeaveRequest days overlapping a payroll period become loss-of-pay days, and appointment slot release checks LeaveRequest to suppress slots for a resource on leave. | | [Resource Presence](/docs/reference/entities/resource-presence/) | 6 | The durable presence and capacity configuration for one Resource in Omni-Channel routing - one row per resource, upserted by the routing service. | | [Resource Skill](/docs/reference/entities/resource-skill/) | 17 | One agent's competency: a child of the Skill master (skillId) held by a Resource (resourceId), with proficiencyLevel and a start/end validity window. | | [Resource Work](/docs/reference/entities/resource-work/) | 10 | One Omni-Channel routing work item: a unit of work pushed to a Resource, polymorphic via workEntityName/workRecordId so any entity - cases, chats, calls, leads - can be routed, not just cases. | | [Revenue Recognition Schedule](/docs/reference/entities/revenue-recognition-schedule/) | 24 | A deferred-revenue plan for one source document: the billed total is parked in a deferred-revenue liability account and released to income across the recognition window. | | [Revenue Recognition Schedule Line](/docs/reference/entities/revenue-recognition-schedule-line/) | 19 | One period's slice of a revenue-recognition schedule: the amount planned for release, the amount actually recognized, and the journal that posted it. | | [Route Sequence](/docs/reference/entities/route-sequence/) | 15 | A versioned, named ordering of a Visit Route's stops - the source of record behind the per-visit sequence snapshots (Visit plannedSequence/optimizedSequence/mostlyFollowedSequence). | | [Route Sequence Entry](/docs/reference/entities/route-sequence-entry/) | 4 | One line of a RouteSequence run: the rank a route stop (visitRouteStopId) takes in that ordering, with an optional confidence score for history-derived runs. | | [Salary Component](/docs/reference/entities/salary-component/) | 28 | One line of a SalaryStructure: which component is paid, how its amount is derived, and in what order. | | [Salary Structure](/docs/reference/entities/salary-structure/) | 15 | A named salary template — an ordered set of SalaryComponent lines that together define how an employee's pay is composed. | | [Salary Tax Slab](/docs/reference/entities/salary-tax-slab/) | 18 | An income-tax slab band for salary TDS: a marginal rate over an income band, scoped by regime, financial year and age band. | | [Scheme](/docs/reference/entities/scheme/) | 42 | A promotional or trade scheme - the header record that makes discounts, free goods and reward points apply automatically to transactional documents. | | [Scheme Account Budget](/docs/reference/entities/scheme-account-budget/) | 16 | A spend cap for a Scheme (schemeId), in currency. | | [Scheme Account Budget Utilisation](/docs/reference/entities/scheme-account-budget-utilization/) | 15 | One draw against a SchemeAccountBudget, keyed per invoice line (invoiceId/invoiceLineId) with the consumed amount and links back to the scheme and the SchemeLedger row it came from. | | [Scheme Benefit](/docs/reference/entities/scheme-benefit/) | 41 | One grant under a Scheme Slab (schemeLineId): rewardType selects the mechanics - Line Level Discount Percentage, Line Level Discount Amount, Discounted Item (a free or discounted item line for discountedItemId), Discounted Item Group (pick from discountedItemGroupId) or Reward Points. | | [Scheme Condition](/docs/reference/entities/scheme-condition/) | 38 | One qualifying test under a Scheme Slab (schemeLineId): conditionType picks what is measured on the document or period (Quantity, Value, Value With Tax, Item Quantity/Value/Value With Tax against itemId, Item Group Quantity/Value/Value With Tax against itemGroupId, or Unique Item Count), conditionOperator compares it (Equal, Does Not Equal, Greater Than, Greater Than Or Equal, Less Than, Less Than Or Equal) with conditionQuantity or conditionValue as the threshold. | | [Scheme Consumption](/docs/reference/entities/scheme-consumption/) | 17 | A summary of scheme benefit consumption per account/partner/branch/item or item group (consumedAmount, consumedQuantity). | | [Scheme Ledger](/docs/reference/entities/scheme-ledger/) | 44 | The applied-scheme record: one row per document line that has a scheme applied, mirrored from the line state by the scheme engine on every save (rows for lines that no longer carry a scheme are deleted). | | [Scheme Slab](/docs/reference/entities/scheme-line/) | 20 | One slab of a Scheme (schemeId): a unit of qualification pairing child SchemeCondition rows (the tests) with child SchemeBenefit rows (the grants). | | [Scheme Period](/docs/reference/entities/scheme-period/) | 13 | A date slice of a Scheme, generated automatically on scheme insert from the scheme's periodType (Yearly one row, Quarterly/Monthly/Weekly/Bi-Weekly/Daily one row per interval across validFrom-validTo). | | [Service Bay](/docs/reference/entities/service-bay/) | 13 | A physical workshop position — a bay, wash bay, van, bin or pallet, typed by ServiceBayType and optionally tied to a Branch. | | [Service Order](/docs/reference/entities/service-order/) | 125 | A service order is the workshop job card: one document per job taken in against a customer and, usually, an asset, with a line for every part and every unit of labour. | | [Service Order Line](/docs/reference/entities/service-order-line/) | 143 | A single billable or workable item on a service order. | | [Service Order Time Sheet](/docs/reference/entities/service-order-time-sheet/) | 24 | A labour-capture sheet attached to a service order, created by the service order's Create Time Sheet action; one sheet is raised per invocation with a child ServiceOrderTimeSheetLine for every selected line whose Item is a Work Item (part lines are excluded). | | [Service Order Time Sheet Line](/docs/reference/entities/service-order-time-sheet-line/) | 21 | One technician-against-one-work-line row on a time sheet. | | [Service Recommendation](/docs/reference/entities/service-recommendation/) | 40 | An upsell or follow-up work suggestion raised against an Asset — most often generated automatically when a check-in inspection checklist line is saved and a matching ServiceRecommendationRule fires, or from a complaint line. | | [Service Recommendation Rule](/docs/reference/entities/service-recommendation-rule/) | 16 | The condition that turns a checklist reading into a Service Recommendation. | | [Service Type](/docs/reference/entities/service-type/) | 9 | A small reference list of work categories used to classify a job. | | [Settlement Allocation](/docs/reference/entities/settlement-allocation/) | 23 | One settlement of one OpenTransaction by one settling document, and the successor of PaymentAdjustment. | | [Shelf Audit Result](/docs/reference/entities/shelf-audit-result/) | 15 | One shelf-vision evaluation run over a merchandising activity's photos - the child result entity of VisitTaskActivity, one row per run so re-analysis history is kept. | | [Shelf Product](/docs/reference/entities/shelf-product/) | 5 | The tenant's reporting identity for one shelf-vision detection label: maps a stable, lowercase gallery label (detectionLabel) to a display name, an optional roll-up cluster (clusterId) and the isOwnBrand flag that drives the share-of-shelf numerator. | | [Shelf Product Cluster](/docs/reference/entities/shelf-product-cluster/) | 3 | A tenant-defined reporting roll-up group for shelf-vision products (for example a beverages family or a competitor cola group). | | [Shipment](/docs/reference/entities/shipment/) | 33 | The in-transit leg of a goods movement, held on the receiving side: goods that have left the sender but have not yet been received, parked in the InventoryStock Pipeline bucket until a GoodsReceipt converts them to inward stock. | | [Shipment Asset Line](/docs/reference/entities/shipment-asset-line/) | 43 | A per-unit identity row hanging off a Shipment, and optionally off one of its lines, for serialised or asset-tracked goods such as vehicles and machines: serial, engine, component, batch and lot numbers, product code, description and family, manufacturing plant and month or year, and the eventual sale-side fields (sale date, sale invoice number, selling branch and selling partner). | | [Shipment Line](/docs/reference/entities/shipment-line/) | 32 | One item line of a Shipment, carrying the in-transit quantity for a single item. | | [Side Conversation](/docs/reference/entities/side-conversation/) | 4 | A private message thread hung off a record - typically a Case - to coordinate with a third party or vendor without the customer seeing it (side conversations are internal-only by design and never customer-visible). | | [Side Conversation Message](/docs/reference/entities/side-conversation-message/) | 8 | One message inside a SideConversation (sideConversationId is the parent). | | [Skill](/docs/reference/entities/skill/) | 3 | An agent's actual competency is a child ResourceSkill row. | | [SKU](/docs/reference/entities/sku/) | 17 | A SKU is one variant of an item, such as a colour or finish, that is sold, bought and stocked separately under its own code. | | [SLA](/docs/reference/entities/sla/) | 15 | A service-level agreement catalog entry pairing a priority/severity classification with target response and resolution times. | | [SLA Policy](/docs/reference/entities/slapolicy/) | 11 | Service-level targets matched to Cases: the SLA engine picks the highest-rank active policy whose matchFormula (a DynamicExpresso predicate over the Case, e.g. | | [Storage Location](/docs/reference/entities/storage-location/) | 35 | A physical or logical stock-holding place inside a branch. | | [Store](/docs/reference/entities/store/) | 13 | A storefront: the catalog universe a partner account sells from, hosting ProductCatalogue and StoreCategory rows (whose StoreCategoryItem children name the sellable items). | | [Store Category](/docs/reference/entities/store-category/) | 14 | Classifies items within a storefront: belongs to a Store (storeId) and optionally to a ProductCatalogue (catalogueId), nests into subcategories via the self-referencing storeCategoryId, and holds its sellable listings as StoreCategoryItem children. | | [Store Category Item](/docs/reference/entities/store-category-item/) | 33 | A sellable listing under a StoreCategory: itemId links the actual inventory Item (and skuId optionally a specific SKU), while the row carries the storefront presentation - marketing name/description, highlights, howTo, ingredients, knowMore, display pricing (mrpOfItem, price), rating/review text and sequenceNumber ordering. | | [Store Dealer](/docs/reference/entities/store-dealer/) | 15 | Links a Store to a dealer: a partner Account (partnerAccountId) and optionally a Branch (branchId), with city/state display fields. | | [Store Item Image](/docs/reference/entities/store-item-image/) | 16 | An image row attached to a StoreCategoryItem - both storeCategoryItemId and parentStoreCategoryItemId are required links, and the underlying Item can be linked too. | | [Subscription](/docs/reference/entities/subscription/) | 40 | A recurring-billing arrangement for an account covering one item (or itemComponent): quantity, pricing (priceList/priceListRule, unitPrice, unitCost, markup fields, taxGroup), billingFrequency and chargeType, and the billing clock (startDate, endDate, lastBillingDate, nextBillingDate, terminatedDate, goodwillDays). | | [Subscription Setting](/docs/reference/entities/subscription-settings/) | 11 | A dormant generic key/value settings table left over from an earlier configuration approach. | | [Subscription Usage](/docs/reference/entities/subscription-usage/) | 16 | One metered-consumption entry under a Subscription: a quantity of an item, optionally a specific itemFeature, consumed by an account or asset. | | [Subscription Usage Summary](/docs/reference/entities/subscription-usage-summary/) | 21 | A billing-window rollup of usage under a Subscription (summaryStartDate to summaryEndDate) tracking billedQuantity against unbilledQuantity, with override fields (overrideQuantity, overrideAmount, overrideSummaryEndDate) to adjust what gets charged. | | [Task](/docs/reference/entities/task/) | 9 | A placeholder whose first-party definition carries only the system fields (id, name, owner, record type, audit stamps) - no business fields, views, layouts or relations ship for it, and the compiled data model contains no table for it. | | [Tax](/docs/reference/entities/tax/) | 16 | One tax component inside a TaxGroup: a rate plus the line slot it posts into. | | [Tax Declaration](/docs/reference/entities/tax-declaration/) | 15 | An employee's yearly investment and deduction declaration, the header over TaxDeclarationLine claims, used to reduce taxable income in the salary-TDS projection. | | [Tax Declaration Line](/docs/reference/entities/tax-declaration-line/) | 16 | One deduction or exemption claim on a TaxDeclaration, identified by its SectionCode and carrying both what the employee declared and what the verifier allowed. | | [Tax Deduction Section](/docs/reference/entities/tax-deduction-section/) | 25 | The master for a Chapter VI-A deduction section (Chapter VIII from FY 2026-27): its own ceiling, its senior-citizen variant, which regimes allow it, and — separately — whether the EMPLOYER may allow it against salary TDS at all. | | [Tax Group](/docs/reference/entities/tax-group/) | 19 | A set of Tax components applied together, referenced from document headers and lines through TaxGroupId. | | [Tax Group Rule](/docs/reference/entities/tax-group-rule/) | 20 | Decides which TaxGroup a document line receives for its item — the Item entity itself carries no tax group, so this is the only mapping. | | [Tax Regime Rule](/docs/reference/entities/tax-regime-rule/) | 25 | The per-regime, per-financial-year scalars of the salary income-tax computation that are not slab bands: standard deduction, the section 87A rebate ceiling and cap and its marginal relief, the surcharge maximum and the special-rate surcharge cap, health and education cess, statutory rounding, and what the regime permits at all (Chapter VI-A deductions, house-property loss set-off and its cap). | | [Tax Surcharge Slab](/docs/reference/entities/tax-surcharge-slab/) | 17 | A surcharge band on income tax, per regime and financial year. | | [Tax Transaction](/docs/reference/entities/tax-transaction/) | 36 | The raw GST ledger: one row per tax component (CGST, SGST, IGST or Cess) of one document line, captured when a tax-bearing document (invoice, bill, credit/debit note) is saved - the line-level analytics the general ledger deliberately does not store, since it posts summarized. | | [TDS Certificate](/docs/reference/entities/tds-certificate/) | 25 | A withholding-certificate register row - Form 131 (non-salary TDS, ex-16A), Form 16 (salary) or Form 27D (TCS) - one per deductee per FILED quarterly return, generated by the certificate action with numbering TAN/kind/FY/quarter/sequence and totals rolled up from the return's rows. | | [TDS Challan](/docs/reference/entities/tds-challan/) | 36 | A vendor-TDS/TCS deposit challan (ITNS 281) - one per company, deduction month, payment code and major head (0020 company deductees / 0021 others; mixed groups are split). | | [TDS Challan Allocation](/docs/reference/entities/tds-challan-allocation/) | 13 | The link row between one withholding event and the deposit challan that carried its tax to the government: TdsTransactionId, TdsChallanId and the amount consumed. | | [TDS Return](/docs/reference/entities/tds-return/) | 29 | One quarterly withholding statement for one company: Form 140 (resident non-salary TDS), Form 143 (TCS) or Form 138 (salary TDS) for a financial-year quarter; Form 144 can be stored but not computed. | | [TDS Return Challan](/docs/reference/entities/tds-return-challan/) | 22 | A challan-detail (CD) row of a quarterly withholding return - the return-side projection of one deposit challan: CIN snapshot (BSR code, tender date, serial), payment code and amounts, plus how much of the deposit this return's deductee rows consume. | | [TDS Return Deductee Line](/docs/reference/entities/tds-return-deductee-line/) | 27 | A deductee-detail (DD) row of a quarterly withholding return - the return-side projection of one TdsTransaction: party PAN and name snapshot, deductee classification, payment code, payment date, amount paid, tax deducted and deposited, rate, remarks code, and the challan (CD) row whose deposit it consumes. | | [TDS Return Salary Detail](/docs/reference/entities/tds-return-salary-detail/) | 33 | The Annexure II row of a Q4 salary return (Form 138, ex-24Q): one employee's full-year salary and tax computation - gross salary, exempt allowances, section-16 deductions, other income, Chapter VI-A claims, the slab/rebate/surcharge/cess waterfall and the deducted-versus-liability position - snapshotted from the payroll ledger and the income-tax calculator at compute time. | | [TDS Section](/docs/reference/entities/tds-section/) | 26 | A withholding-tax section master under the Income-tax Act: TDS sections (contractors, professional fees, purchase of goods, commission and so on) and TCS sections, holding the statutory rate, the PAN-not-available penal rate, the per-transaction and annual exemption thresholds, and when the levy triggers. | | [TDS Transaction](/docs/reference/entities/tds-transaction/) | 35 | One withholding event - TDS deducted from a vendor bill/payment or TCS collected on a customer sale - recorded per source document line, mirroring how TaxTransaction captures GST. | | [Terms](/docs/reference/entities/term/) | 18 | A terms-and-conditions text block for contract documents. | | [Transcript](/docs/reference/entities/transcript/) | 15 | A conversation transcript, generic and channel-agnostic: one row per transcribed conversation on any channel (channel: Voice, Chat, SMS, messaging apps, Email, Web), polymorphically linked to the source conversation record via relatedEntityName/relatedEntityId (e.g. | | [Transfer](/docs/reference/entities/transfer/) | 36 | The header of a stock movement between branches or partner companies, whose Type decides which of three line collections it uses: Outward (dispatch leg, TransferOutwardLines), Inward (receiving leg, TransferInwardLines) or Single Step (TransferLines, one document that books both effects with no transit leg). | | [Transfer Inward Line](/docs/reference/entities/transfer-inward-line/) | 40 | The receiving line of an Inward transfer, normally generated by releasing an outward line rather than entered: TransferOutwardLineId points back at the dispatch line and Quantity equals exactly the batch that was released. | | [Transfer Line](/docs/reference/entities/transfer-line/) | 36 | The item line of a Single Step transfer: one save books both the outward effect against the source and the inward effect against the destination, which is why single-step moves never park quantity in transit. | | [Transfer Outward Line](/docs/reference/entities/transfer-outward-line/) | 41 | The dispatch line of an Outward transfer. | | [User Account](/docs/reference/entities/user-account/) | 9 | A User Account is one person, or one built-in system identity, in the organization: it holds the sign-in username, e-mail, phone, first, last and display names, the audience (Internal for employees, External for portal and partner users), the active flag, the person's language, locale and time zone, and an optional delegated approver. | | [Visit](/docs/reference/entities/visit/) | 59 | One stop a field rep executes: a dated call on an outlet (accountId), normally generated under a VisitPlan from the route's stops (visitRouteStopId links back), from an account group's members, or from pending delivery orders. | | [Visit Plan](/docs/reference/entities/visit-plan/) | 39 | One rep's route execution over a date window (planStartDate..planEndDate): the container the day's Visits are generated into. | | [Visit Route](/docs/reference/entities/visit-route/) | 36 | The beat master: a named, reusable journey whose outlets are child VisitRouteStop rows and whose recurrence drives visit-plan generation (weekday flags plus weekNumbers, or a cron expression that overrides them). | | [Visit Route Group](/docs/reference/entities/visit-route-group/) | 15 | A container grouping related VisitRoutes and their VisitPlans, carrying shared context (branchId, partnerAccountId, visitPurpose, visitTaskTemplateId, resourceId). | | [Visit Route Stop](/docs/reference/entities/visit-route-stop/) | 31 | One outlet's place on a beat (visit route): the customer account visited, its position in the authored order, an optional time window, its coordinates and a check-in tolerance. | | [Visit Task](/docs/reference/entities/visit-task/) | 24 | One task card inside a Visit's execution flow (visitId), materialized from a VisitTaskTemplateEntry when the visit's task template is set - the handler deletes and recreates the visit's tasks when visitTaskTemplateId changes. | | [Visit Task Activity](/docs/reference/entities/visit-task-activity/) | 51 | One data-capture step under a VisitTask (visitTaskId, with visitId denormalized): the runtime instance of a VisitTaskTemplateActivity (visitTaskTemplateActivityId). | | [Visit Task Template](/docs/reference/entities/visit-task-template/) | 17 | The visit execution playbook header: which task cards a visit shows and which mobile options it exposes (showAcceptRejectOption, showVisitStartEndOption, showGetDirectionOption, showRescheduleOption, showProgressPanel - copied onto visits built with the template). | | [Visit Task Template Activity](/docs/reference/entities/visit-task-template-activity/) | 30 | One activity definition under a VisitTaskTemplateEntry (visitTaskTemplateEntryId): the designer-authored spec a runtime VisitTaskActivity is instantiated from. | | [Visit Task Template Entry](/docs/reference/entities/visit-task-template-entry/) | 21 | One task definition inside a VisitTaskTemplate (visitTaskTemplateId): name, taskType, sequence, duration and hidden flag. | ## Related topics - [Entity reference overview](/docs/reference/) - [Administration guide](/docs/administration/) ---- # Individual — entity reference URL: https://xmatix.com/docs/reference/entities/individual/ Last reviewed: 2026-08-16 A person-level privacy and consent record: names and salutation plus data-protection flags (dontMarket, dontProcess, dontProfile, dontTrack, forgetThisIndividual, exportIndividualsData, canStorePiiElsewhere, blockGeolocationTracking) and demographic attributes such as birth/death dates, occupation and consumer credit score fields. The compiled data model does not include a table for it in the current build - only an individualId reference exists elsewhere in the model - so treat it as a declared shape rather than a queryable store of people. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BirthDate` | Birth Date | Date | | | | `BlockGeolocationTracking` | Has Opted Out Geo Tracking | Boolean | | | | `CanStorePiiElsewhere` | OK to Store PII Data Elsewhere | Boolean | | | | `ChildrenCount` | Children Count | Number | | | | `ConsumerCreditScore` | Consumer Credit Score | Number | | | | `ConsumerCreditScoreProviderName` | Consumer Credit Score Prover Name | Text | | | | `ConvictionsCount` | Convictions Count | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeathDate` | Death Date | Date | | | | `DontMarket` | Has Opted Out Solicit | Boolean | | | | `DontProcess` | Has Opted Out Processing | Boolean | | | | `DontProfile` | Has Opted Out Profiling | Boolean | | | | `DontTrack` | Has Opted Out Tracking | Boolean | | | | `ExportIndividualsData` | Send Indivual Data | Boolean | | Send Individual Data | | `FirstName` | First Name | Text | | | | `ForgetThisIndividual` | Should Forget | Boolean | | | | `Id` | Id | Guid | Yes | | | `IndividualsAge` | Indivual's Age | PickList | | Values: 13 or Older, 16 or Older. | | `InfluencerRating` | Influencer Rating | Number | | | | `IsHomeOwner` | Is Home Owner | Boolean | | | | `LastName` | Last Name | Text | | | | `MilitaryService` | Military Service | PickList | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Occupation` | Occupation | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Salutation` | Salutation | PickList | | Values: Ms., Dr., Prof., Mx.. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Inspection Line — entity reference URL: https://xmatix.com/docs/reference/entities/inspection-line/ Last reviewed: 2026-08-16 The goods-receipt quality inspection record, unrelated to the CheckIn* check-in inspection family. GoodsReceipt's PerformInspection action creates one row per receipt line whose Item has RequireInspectionOnReceipt set and whose pending inspection quantity is positive, copying the item, lot, SKU, storage location, unit cost and quantities from the receipt line with the damaged quantity already netted out of ReceivedQuantity and InspectionQuantity. Saving lines posts to the inventory ledger through InventoryLedgerService and pushes started-inspection and damaged quantities back onto the goods-receipt line. GoodsReceipt's PerformInspectionComplete closes every open line by zeroing InspectionQuantity and AdjustmentQuantity and stamping InspectionDone, IsApproved and IsILPostingApproved. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AdjustmentQuantity` | Adjustment Quantity | Decimal | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DamagedQuantity` | Damaged Quantity | Decimal | | | | `ExcessQuantity` | Excess Quantity | Decimal | | | | `GoodsReceiptId` | Goods Receipt | Lookup → [GoodsReceipt](/docs/reference/entities/goods-receipt/) | | | | `GoodsReceiptLineId` | Goods Receipt Line | Lookup → [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) | | | | `Id` | Id | Guid | Yes | | | `InspectionDone` | Inspection Done | Boolean | | | | `InspectionQuantity` | Inspection Quantity | Decimal | | | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | | | `IsApproved` | Is Approved | Boolean | | | | `IsILPosted` | IsILPosted | Boolean | | | | `IsILPostingApproved` | IsILPostingApproved | Boolean | | | | `IsPosted` | Is Posted | Boolean | | | | `IsRepairOrderClosed` | Is Repair Order Closed | Boolean | | | | `IsServiceOrderClosed` | Is Service Order Closed | Boolean | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `LastBillingDate` | Last Billing Date | Date | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text, unique | | number | | `OrderQuantity` | Order Quantity | Decimal | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PerformPopulateChecklist` | Perform Populate Checklist | Boolean | | | | `Quantity` | Quantity | Decimal | | | | `ReceiptId` | Receipt | Lookup | | | | `ReceiptLineId` | Receipt Line | Lookup | | | | `ReceivedQuantity` | Received Quantity | Decimal | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ShortageQuantity` | Shortage Quantity | Decimal | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `SupplierInvoiceQuantity` | Supplier Invoice Quantity | Decimal | | | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Decimal | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `CreateServiceOrder` | Create Service Order | ServerAction (`CreateServiceOrder`) | CreateServiceOrder | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Cost Rule Validation | Error | Cost cannot be 0 or Negative | Prevents zero or negative unit cost on inspection lines | ## Related entities - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — looks up via `GoodsReceiptId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — looks up via `GoodsReceiptLineId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — referenced by via `InspectionLineId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `InspectionLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Insurance Scheme — entity reference URL: https://xmatix.com/docs/reference/entities/insurance-scheme/ Last reviewed: 2026-08-16 A thin reference list of insurance schemes, holding only a name and the insurer's own name for the same scheme so external naming can be reconciled with internal naming. It is used purely as an optional grouping dimension: Insurer, IncentiveTarget and CompensationLine each carry an InsuranceSchemeId, so incentive targets and compensation lines can be measured per scheme. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `InsurerSchemeName` | Insurer's Scheme Name | Text | Yes | The insurer's own name for the scheme, kept alongside the internal Name so external statements and files can be reconciled with the internal record. It is free text and is not used as a matching key by any platform code. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLineEntity` | Edit | EditInline | EditInLine Entity | | `EditInLineHeader` | Edit | EditInline | EditInLineHeader | | `EditRow` | Edit | Edit | EditRow | | `NewHeader` | New | New | NewHeader | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `InsuranceSchemeId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `InsuranceSchemeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Interest Charge — entity reference URL: https://xmatix.com/docs/reference/entities/interest-charge/ Last reviewed: 2026-08-16 Interest charged on one overdue open item for one accrual window, with its full derivation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AnnualRatePercent` | Annual Rate % p.a. | Percent | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `CalculationNote` | Calculation Note | LongMultiLineText | | | | `CappedAmount` | Capped Amount | Currency | | | | `ChargedDays` | Charged Days | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CumulativeInterestAmount` | Cumulative Interest | Currency | | | | `DayCount` | Day Count | PickList | | Values: Actual/365, Actual/360, Actual/366, Actual/Actual, 30E/360. | | `DayCountDenominator` | Day Count Denominator | Number | | | | `DebitNoteId` | Debit Note | Lookup → [DebitNote](/docs/reference/entities/debit-note/) | | | | `Direction` | Direction | PickList | | Values: Receivable, Payable. | | `DocumentNumber` | Document Number | Text | | | | `DueDate` | Due Date | Date | | | | `GSTRegistrationId` | GST Registration | Lookup → [GSTRegistration](/docs/reference/entities/gstregistration/) | | | | `Id` | Id | Guid, hidden | Yes | | | `InterestAmount` | Interest Amount | Currency | | | | `InterestOpenTransactionId` | Interest Open Item | Lookup → [OpenTransaction](/docs/reference/entities/open-transaction/) | | | | `InterestPolicyId` | Interest Policy | Lookup → [InterestPolicy](/docs/reference/entities/interest-policy/) | | | | `InterestRunId` | Interest Run | Lookup → [InterestRun](/docs/reference/entities/interest-run/) | | | | `JournalId` | Journal | Lookup → [Journal](/docs/reference/entities/journal/) | | | | `Label` | Label | Text | | | | `Method` | Method | PickList | | Values: Simple, Compound. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OpenTransactionId` | Open Item | Lookup → [OpenTransaction](/docs/reference/entities/open-transaction/) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Company | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyAccountId` | Party | Lookup → [Account](/docs/reference/entities/account/) | | | | `PeriodFrom` | Period From | Date | | | | `PeriodTo` | Period To | Date | | | | `PrincipalAmount` | Principal Amount | Currency | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReviewReason` | Review Reason | LongMultiLineText | | Why the charge needs a look — names the rate buckets the interest was split across. | | `ReviewRequired` | Review Required | Boolean | | Set when the GST was apportioned across a mixed taxable/exempt invoice. Advisory — it does not block posting, but a person should confirm the split. | | `SourceEntityName` | Source Entity Name | Text | | | | `SourceRecordId` | Source Record | Guid | | | | `Status` | Status | PickList | | Values: Draft, Posted, Waived, Cancelled, Reversed. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TaxAmount` | Tax Amount | Currency | | | | `TaxRatePercent` | Tax Rate % | Percent | | | | `TotalAmount` | Total Amount | Currency | | | | `TotalOverdueDays` | Total Overdue Days | Number | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `WaiveReason` | Waive Reason | LongMultiLineText | | | | `WeightedPrincipalDays` | Weighted Principal-Days | Decimal | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Delete` | Delete | Delete | Delete Interest Charge | | `Edit` | Edit | Edit | Edit Interest Charge | | `EditInLine` | Edit | EditInline | Edit Interest Charge | | `New` | New | New | New Interest Charge | | `WaiveInterestCharge` | Waive Charge | ServerAction (`WaiveInterestCharge`) | Forgives this draft charge. The accrual window stays consumed — the days are forgiven, not deferred to the next run. | ## Related entities - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — looks up via `SourceRecordId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — looks up via `SourceRecordId` - [InterestPolicy](/docs/reference/entities/interest-policy/) — looks up via `InterestPolicyId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — looks up via `SourceRecordId` - [Payment](/docs/reference/entities/payment/) — looks up via `SourceRecordId` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — looks up via `SourceRecordId` - [DebitNote](/docs/reference/entities/debit-note/) — looks up via `SourceRecordId` - [PayrollRun](/docs/reference/entities/payroll-run/) — looks up via `SourceRecordId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `SourceRecordId` - [InterestRun](/docs/reference/entities/interest-run/) — looks up via `InterestRunId` - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — looks up via `SourceRecordId` - [Bill](/docs/reference/entities/bill/) — looks up via `SourceRecordId` - [CreditNote](/docs/reference/entities/credit-note/) — looks up via `SourceRecordId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Interest Policy — entity reference URL: https://xmatix.com/docs/reference/entities/interest-policy/ Last reviewed: 2026-08-16 Rate and rule master for interest on overdue payments. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AppliesToDirection` | Applies To Direction | PickList | | Values: Receivable, Payable. | | `Basis` | Basis | PickList | | Values: Outstanding Balance, Original Amount, Current Open Amount. | | `ChargeOnSettledItems` | Charge On Settled Items | Boolean | | | | `CompoundingFrequency` | Compounding Frequency | PickList | | Values: Monthly, Quarterly, Half Yearly, Yearly. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DayCount` | Day Count | PickList | | Values: Actual/365, Actual/360, Actual/366, Actual/Actual, 30E/360. | | `Description` | Description | LongMultiLineText | | | | `EffectiveFrom` | Effective From | Date | | | | `EffectiveTo` | Effective To | Date | | | | `GraceDays` | Grace Days | Number | | | | `GstRatePercent` | GST Rate % | Percent | | | | `Id` | Id | Guid, hidden | Yes | | | `InterestGLAccountId` | Interest GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `IsActive` | Is Active | Boolean | | | | `IsGstApplicable` | GST Applicable | Boolean | | | | `Label` | Label | Text | | | | `MaximumChargePercentOfPrincipal` | Maximum Charge % of Principal | Percent | | | | `Method` | Method | PickList | | Values: Simple, Compound. | | `MinimumChargeAmount` | Minimum Charge Amount | Currency | | | | `MinimumDaysOverdue` | Minimum Days Overdue | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Company | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyAccountId` | Party | Lookup → [Account](/docs/reference/entities/account/) | | | | `Priority` | Priority | Number | | | | `RatePercent` | Rate % | Percent | | | | `RatePeriod` | Rate Period | PickList | | Values: Per Annum, Per Month, Per Day. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TaxGLAccountId` | Tax GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Delete` | Delete | Delete | Delete Interest Policy | | `Edit` | Edit | Edit | Edit Interest Policy | | `EditInLine` | Edit | EditInline | Edit Interest Policy | | `New` | New | New | New Interest Policy | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Company | `PartnerAccountId` | | | PartyAccount | `PartyAccountId` | | ## Related entities - [InterestCharge](/docs/reference/entities/interest-charge/) — referenced by via `InterestPolicyId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Interest Run — entity reference URL: https://xmatix.com/docs/reference/entities/interest-run/ Last reviewed: 2026-08-16 One interest accrual batch: computes and posts charges for overdue items as at a cut-off date. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AsOfDate` | As Of Date | Date | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `ChargeCount` | Charge Count | Number | | | | `ComputedOn` | Computed On | DateAndTime | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Direction` | Direction | PickList | | Values: Receivable, Payable. | | `Id` | Id | Guid, hidden | Yes | | | `IsPreview` | Is Preview | Boolean | | | | `ItemsEvaluated` | Items Evaluated | Number | | | | `Label` | Label | Text | | | | `Message` | Message | LongMultiLineText | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Company | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyAccountId` | Party | Lookup → [Account](/docs/reference/entities/account/) | | | | `PostedOn` | Posted On | DateAndTime | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Status` | Status | PickList | | Values: Draft, Computed, Posted, Cancelled. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TotalChargeAmount` | Total Charge Amount | Currency | | | | `TotalInterestAmount` | Total Interest Amount | Currency | | | | `TotalPrincipalAmount` | Total Principal Amount | Currency | | | | `TotalTaxAmount` | Total Tax Amount | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `CancelInterestRun` | Cancel Run | ServerAction (`CancelInterestRun`) | Abandons the run. Its draft charges become Cancelled, which releases their accrual windows so a later run can re-charge those days. | | `ComputeInterestRun` | Compute Interest | ServerAction (`ComputeInterestRun`) | Recomputes this run's interest charges for every overdue open item in scope. Existing draft charges are rebuilt; posted charges are left alone. | | `Delete` | Delete | Delete | Delete Interest Run | | `Edit` | Edit | Edit | Edit Interest Run | | `EditInLine` | Edit | EditInline | Edit Interest Run | | `New` | New | New | New Interest Run | | `PostInterestRun` | Post Interest | ServerAction (`PostInterestRun`) | Posts the run's draft charges to the ledger: one balanced journal per charge plus a collectible open item. | ## Related entities - [InterestCharge](/docs/reference/entities/interest-charge/) — referenced by via `InterestRunId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Job Queue — entity reference URL: https://xmatix.com/docs/reference/entities/interface-queue/ Last reviewed: 2026-09-27 A named grouping handle for background interface/job processing - the row itself holds only a label. Documents produced or processed by a job carry an optional jobInterfaceQueueId pointing here (Invoice, CreditNote, DeliveryOrder, Shipment, ServiceOrder), KPI configurations reference it as their job queue, and InterfaceLog rows can tag the queue a callout belonged to. It is not where integration failures live: for 'what interface/integration failures happened' questions, use the background-job and integration-run diagnostics surfaces rather than querying this entity. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — referenced by via `JobQueueId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `JobInterfaceQueueId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `JobInterfaceQueueId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `JobInterfaceQueueId` - [Shipment](/docs/reference/entities/shipment/) — referenced by via `JobInterfaceQueueId` - [Adjustment](/docs/reference/entities/adjustment/) — referenced by via `InterfaceJobQueueId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — referenced by via `JobQueueId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Inventory Cost Consumption — entity reference URL: https://xmatix.com/docs/reference/entities/inventory-cost-consumption/ Last reviewed: 2026-08-16 One draw of an issue against a cost lot, recorded per accounting book and per method because FIFO and LIFO consume different layers for the same physical issue. The sum of CostAmount across the rows sharing a SourceLedgerId is that issue's cost of goods sold, and it is exactly the amount the cost-posting service puts on the resulting COGS or inventory-loss journal. A single issue produces several rows when it spans multiple layers. Like the lots, these rows are rewritten wholesale each time the scope is replayed rather than appended to, so they are a derived audit trail rather than an event log. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountingBookId` | Accounting Book | Lookup → [AccountingBook](/docs/reference/entities/accounting-book/) | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CostAmount` | Cost Amount | Currency | | Quantity times unit cost, rounded to two decimals per draw so that summing the draws ties exactly to the amount posted on the cost journal - the engine deliberately sums rounded draws rather than rounding a total. | | `CostLotId` | Cost Lot | Lookup → [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) | | The cost layer this draw was taken from. Under MovingAverage and WeightedAverage every draw points at the single synthetic pool row rather than at a receipt, so it cannot be used to trace an issue back to a purchase. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IssueDate` | Issue Date | Date | | The document date of the issue movement. It is what slices consumption into fiscal periods when the inventory period balance cache derives a period's outward value. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `Method` | Method | Text | | The cost-flow method that produced this draw. The same physical issue yields different consumption rows under FIFO than under LIFO, which is why the method forms part of the key rather than being derived at read time. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | A generated identifier of the form ICC followed by the row's id and a line index. It carries no business meaning and is regenerated whenever the scope is replayed. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The owning company or legal entity, following the finance convention where partner account means the company rather than a trading counterparty. | | `Quantity` | Quantity | Currency | | The quantity drawn from this one layer, not the total quantity of the issue. Sum the rows sharing a SourceLedgerId to get the issued quantity. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SourceLedgerId` | Source Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | The InventoryLedger issue row this draw belongs to, and the key used to total an issue's cost of goods sold; several rows share it when the issue spans multiple layers. It also acts as the idempotency anchor so re-posting an issue cannot double-consume. | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | The cost per unit of the layer being drawn from, or the prevailing running or period average under the average methods. | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | Delete | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditEntityInLine` | Edit | EditInline | EditEntityInLine | | `EditHeader` | Edit | EditInline | EditHeader | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `SourceLedgerId` - [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) — looks up via `CostLotId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [AccountingBook](/docs/reference/entities/accounting-book/) — looks up via `AccountingBookId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Inventory Cost Lot — entity reference URL: https://xmatix.com/docs/reference/entities/inventory-cost-lot/ Last reviewed: 2026-08-16 A persisted receipt cost layer for one (accounting book, item, branch, method) scope: how much arrived at what unit cost and how much of that layer is still unconsumed. FIFO, LIFO and Specific Identification produce one row per receipt; MovingAverage and WeightedAverage produce a single synthetic pool row whose remaining quantity is the entire on-hand balance. Only the company's primary accounting book persists layers (secondary books are derived by replay plus stored overlay deltas), and the sum of RemainingQuantity times EffectiveUnitCost is what the inventory valuation statement reports as inventory cost. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountingBookId` | Accounting Book | Lookup → [AccountingBook](/docs/reference/entities/accounting-book/) | | The book whose method produced this layer. Only the company's primary book actually has layers persisted; a secondary book's inventory value is derived by replaying the same movements and is stored as statement-line deltas, so querying layers for a secondary book returns nothing. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EffectiveUnitCost` | Effective Unit Cost | Currency | | Intended as unit cost plus capitalised landed cost, and it is the figure the valuation statement prefers over UnitCost. In practice the replay always assigns it the plain UnitCost, so today the two never differ. | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | Declared as a soft reference to the lot or batch master but never assigned when the engine writes layers; lot identity travels in LotKey instead. Do not join on it to find batch-level cost. | | `LandedCostPerUnit` | Landed Cost Per Unit | Currency | | Posting a landed-cost voucher books a general-ledger inventory uplift and stamps the per-line allocation on the voucher, but the documented follow-up to push that allocated charge into the cost layers is still outstanding, so engine cost of goods sold excludes freight and duty. | | `LotKey` | Lot Key | Text | | The lot identity used by Specific Identification, sourced from the movement's ItemLotId; issues must name the same key to draw from this layer. The other methods leave it null. | | `Method` | Method | Text | | The cost-flow method this layer belongs to, written from the method the valuation policy resolved. Layers are keyed by it, so changing an item's policy makes the engine build a parallel set of rows under the new method name rather than converting the existing ones. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | A generated identifier of the form ICL followed by the row's id. It carries no business meaning, is not a document number, and changes every time the scope is replayed. | | `OriginalQuantity` | Original Quantity | Currency | | The quantity the layer was created with, before any consumption. For MovingAverage and WeightedAverage this is the total quantity received across the whole replayed movement stream rather than a single receipt. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The owning company or legal entity, following the finance convention where partner account means the company rather than a trading counterparty. | | `ReceiptDate` | Receipt Date | Date | | The movement date the layer was received on, and the key FIFO and LIFO consume in order of. For the average methods it holds the date of the first receipt in the replayed stream rather than a meaningful receipt date. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RemainingQuantity` | Remaining Quantity | Currency | | The quantity of this layer still unconsumed under the primary book's method, and the figure the inventory valuation statement multiplies by unit cost. For the average methods the single pool row's value here is the entire on-hand balance for the scope, not a per-receipt residue. | | `Sequence` | Sequence | LargeNumber | | Declared for ordering layers within a scope but never assigned when layers are written; it is the sibling opening-lot-state rows carried across a period boundary that actually get a sequence. Order layers by ReceiptDate instead. | | `SourceLedgerId` | Source Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | A deliberately unenforced reference (no foreign key) to the InventoryLedger inward row that created the layer, and the idempotency anchor that lets a replay rebuild identical rows. The average methods leave it null because their single pool row has no single originating receipt. | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | Declared on the layer but never assigned by the engine, which keys a cost scope by book, item, branch and method only. Layers are therefore branch-level, not location-level, regardless of what a policy's CostingLevel says. | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | The receipt cost per unit, taken from the unit cost on the originating InventoryLedger inward row (for a goods receipt that is the purchase order line cost). For the average methods it holds the closing running or period average instead of a receipt price. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | Delete | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | Edit | | `EditIn` | Edit | EditInline | Edit | | `EditInline` | Edit | EditInline | Edit | | `EditRow` | Edit | Edit | Edit | | `NewHeader` | New | New | New | ## Related entities - [AccountingBook](/docs/reference/entities/accounting-book/) — looks up via `AccountingBookId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `SourceLedgerId` - [InventoryCostConsumption](/docs/reference/entities/inventory-cost-consumption/) — referenced by via `CostLotId` - [InventoryOpeningLotState](/docs/reference/entities/inventory-opening-lot-state/) — referenced by via `SourceCostLotId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Allocation Line — entity reference URL: https://xmatix.com/docs/reference/entities/inventory-fulfilment-allocation-line/ Last reviewed: 2026-08-16 One reservation against a single concrete stock source: an ItemLot when the item is lot-tracked, otherwise an InventoryStock bucket. Creating it posts an Allocation ledger row that increments InventoryStock.Allocation, so the reservation is visible to the rest of the platform immediately on save rather than at a later posting step. Polarity carries meaning: positive rows reserve, negative rows are cancellations that link back through ParentFulfillmentAllocationLineId (note the double-l spelling) — original rows are never edited, and the cancellable amount is the calculated EligibleReturnQuantity, not AllocatedQuantity. Most of its many quantity columns are roll-ups written by other documents: picking lines feed the Picking* and PickedQuantity columns, delivery lines feed DeliveryQuantity and PickedDeliveredQuantity, invoice lines feed the three invoiced columns. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AllocatedById` | Allocated By | Lookup | | | | `AllocatedByResourceId` | Allocated By | Lookup → [Resource](/docs/reference/entities/resource/) | | Only picking captures who did the work, through PickedByResourceId on the picking line. | | `AllocatedQuantity` | Allocated Quantity | Calculated (calculated) | | Calculated as Quantity minus ReturnedQuantity, so it is what is still reserved after cancellations; the raw reservation booked to the ledger is Quantity. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeliveredInvoicedQuantity` | Delivered Invoiced Quantity | Decimal | | | | `DeliveryQuantity` | Delivery Quantity | Decimal | | | | `DeliveryReturnQuantity` | Delivery Return Quantity | Decimal | | Declared and stored but written by no code path — the delivery roll-ups maintain DeliveryQuantity and PickedDeliveredQuantity instead. It only ever appears in the never-negative validation list. | | `DocumentDate` | Document Date | Date | | | | `EligibleReturnQuantity` | Eligible Return Quantity | Calculated (calculated) | | | | `ExternalId` | External | Text | | | | `FulfillmentNumber` | Fulfillment Number | Number, unique | | Note also the American double-l spelling, which differs from the 'Fulfilment' used across the rest of the module. | | `Id` | Id | Guid | Yes | | | `InventoryFulfilmentId` | Inventory Fulfilment | Lookup → [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) | | | | `InventoryFulfilmentOrderLineId` | Fulfillment Order Line | Lookup → [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) | | Link back to the demand line this reservation consumes. One demand line commonly has several of these, because allocation keeps taking the next eligible lot or stock row until the pending demand is used up. | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | Stamped by the ledger engine with the immutable Allocation row it wrote. Its presence is what tells the platform the quantity has already been added to the InventoryStock Allocation bucket. | | `InventoryStockId` | Stock | Lookup → [InventoryStock](/docs/reference/entities/inventory-stock/) | | The stock bucket a non-lot reservation is booked against — the seeded Allocation rule increments the Allocation column of exactly this row. | | `InvoiceQuantity` | Invoice Quantity | Decimal | | The directly invoiced portion: invoice-line quantity less its delivered and picked parts, so it counts only what was invoiced without a delivery or a pick in between. | | `IsClosed` | Closed | Boolean | | | | `IsILPosted` | IL Posted | Boolean | | | | `IsILPostingApproved` | IL Posting Approved | Boolean | | Set true on every line the engine creates, cancellation reversals included, so the Allocation ledger rule fires on save. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | The concrete lot the reservation is drawn from for lot-tracked items; when it is empty the reservation is against the InventoryStock bucket instead. It is locked once the line has transacted. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `LastModifiedById` | LastModifiedBy | Guid | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | | | `OrderLineId` | Sale Order Line | Lookup → [OrderLine](/docs/reference/entities/order-line/) | | The sales demand this reservation answers. After allocation runs, a link that is missing or points at a deleted line is automatically repaired to the single matching order line for the same item and SKU (preferring a scheme-generated one); a link that is already valid is left untouched. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentFulfillmentAllocationLineId` | Parent Inventory Fulfillment Allocation Line | Lookup → [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) | | Self-reference used by allocation cancellation: the reversal row created by a cancel points back at the allocation line it undoes, keeping the original row intact. | | `PendingDeliveryQuantity` | Pending Delivery Quantity | Calculated (calculated) | | What allocation-based delivery can still deliver from this line; the AllocationDelivery actions require it above zero. | | `PendingInvoiceQuantity` | Pending Invoice Quantity | Calculated (calculated) | | Calculated as AllocatedQuantity minus all three invoiced buckets (direct, delivered-invoiced, picked-invoiced). | | `PendingPickingQuantity` | Pending Picking Quantity | Calculated (calculated) | | Allocated quantity not yet moved to picking. Gates PerformPicking/SelectivePicking, and an allocation line at zero here must be delivered through the picked-delivery path - allocation delivery refuses it. | | `PickedDeliveredQuantity` | Picked Delivered Quantity | Number | | Roll-up of delivery-order lines that were raised from a picking line. Delivery raised straight off this reservation lands in DeliveryQuantity instead, and both are subtracted in PendingDeliveryQuantity. | | `PickedInvoiceQuantity` | Picked Invoice Quantity | Number | | | | `PickedQuantity` | Picked Quantity | Decimal | | Roll-up of the child picking lines' Quantity, not this line's own reservation; it feeds both EligibleReturnQuantity and PendingPickingQuantity. | | `PickingCancelQuantity` | Picking Cancel Quantity | Number | | Roll-up of the picking lines' CancelQuantity — the shortfall recorded when a pick was confirmed for less than was requested. It is added back into PendingPickingQuantity so the difference can be picked again. | | `PickingRequestedQuantity` | Picking Requested Quantity | Number | | Aggregate of the child picking lines' requested quantities, maintained alongside pickingCancelQuantity by the picking-line rollup. | | `PickingReturnQuantity` | Picking Return Quantity | Number | | Recomputed aggregate: the sum of quantities returned by this allocation's cancelled child picking lines, refreshed whenever picking cancellations post. | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedQuantity` | Requested Quantity | Number | | Carried only in a selective action's payload, never stored demand: it is the amount that call wants to pick or cancel on this line, validated against PendingPickingQuantity or EligibleReturnQuantity depending on the action. | | `ReturnedQuantity` | Returned Quantity | Number | | Maintained as the negated sum of the child cancellation lines' Quantity, so it grows as reversals are booked against this reservation. | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | | | `ServiceOrderLineId` | Service Order Line | Lookup → [ServiceOrderLine](/docs/reference/entities/service-order-line/) | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `SoftCommittedQuantity` | Soft Committed Quantity | Calculated (calculated) | | Calculated: equal to Quantity when the line is tied to an order or service-order line and zero otherwise, so it marks reservations that answer real customer demand rather than speculative ones. | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | Taken from the chosen ItemLot when allocating a lot, but from the demand line's UnitPrice when allocating from an InventoryStock bucket — so for non-lot items it carries a selling price rather than a cost. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete, inactive | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Blocked once the line has a non-zero quantity — reservations are reversed with CancelAllocation on the fulfilment, which writes a negative line, rather than deleted. | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `HeaderEdit` | Edit | EditInline, inactive | HeaderEdit | | `New` | New | New, inactive | | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Quantity Rule Validation | `Quantity`, Error, inactive | Quantity shouldn't be less than zero. | Quantity shouldn't be less than zero. | | Unit Cost Rule Validation | `UnitCost`, Error, inactive | Unit Cost can't be less than zero. | Unit Cost can't be less than zero. | ## Related entities - [Resource](/docs/reference/entities/resource/) — looks up via `AllocatedByResourceId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — looks up via `ParentFulfillmentAllocationLineId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — looks up via `InventoryStockId` - [OrderLine](/docs/reference/entities/order-line/) — looks up via `OrderLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — looks up via `InventoryFulfilmentId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — looks up via `ServiceOrderLineId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — looks up via `InventoryFulfilmentOrderLineId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `InventoryFulfilmentAllocationLineId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `ParentFulfillmentAllocationLineId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `InventoryFulfilmentAllocationLineId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `InventoryFulfilmentAllocationLineId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Inventory Fulfillment Order Line — entity reference URL: https://xmatix.com/docs/reference/entities/inventory-fulfilment-order-line/ Last reviewed: 2026-08-16 The demand side of a fulfilment: one line per source OrderLine or ServiceOrderLine, carrying the quantity that still needs reserving. It is created only by the fulfilment release and consumed by allocation, which loops over eligible lots or stock rows until the line's PendingAllocationQuantity (Quantity minus AllocatedQuantity minus CancelledQuantity) reaches zero, so one demand line can spawn several allocation lines. Two naming traps: its label field is the lower-cased 'label', and the parent navigation is called Fulfilment rather than InventoryFulfilment. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AllocatedQuantity` | Allocated Quantity | Number | | Maintained as the sum of this line's allocation lines' Quantity, so cancellation reversals reduce it; it is the middle term of PendingAllocationQuantity. Changing item, SKU or lot is blocked once it is non-zero. | | `BackOrderQuantity` | Back Order Quantity | Number | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Defaulted from the parent fulfilment rather than entered. The allocation engine reads the parent's value, not this copy, so editing it does not redirect allocation. | | `CancelledQuantity` | Cancelled Quantity | Number | | Subtracted from the posting quantity by the inventory ledger engine, so a partially cancelled line posts its effective quantity rather than its raw one. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EligibleBackOrderQuantity` | Eligible Back Order Quantity | Calculated | | Declared but written by no code path in the platform. Back-order visibility comes from BackOrderQuantity, which is the roll-up of the linked purchase-order lines. | | `Id` | Id | Guid | Yes | | | `InventoryFulfilmentId` | Inventory Fulfillment | Lookup → [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) | | The required parent key. Note the domain navigation for it is named Fulfilment, not InventoryFulfilment, which matters when writing relation paths in views, formulas or queries. | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | Always empty: demand lines have no seeded inventory-ledger rule, so nothing here ever posts to stock. Ledger activity starts at the allocation line. | | `InventoryStockId` | Stock | Lookup → [InventoryStock](/docs/reference/entities/inventory-stock/) | | | | `IsILPosted` | IL Posted | Boolean | Yes | | | `IsILPostingApproved` | IL Posting Approved | Boolean | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | Yes | The item to reserve. Its TrackLots and TrackInventory flags decide the whole allocation strategy: lot-tracked items draw from ItemLot rows, non-lot inventory items from InventoryStock buckets, and an item that tracks neither produces no allocation line at all and no error. | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | When set it pins allocation to that one lot: the engine checks only that lot and does not fall back to others, so if it has no availability the demand is simply left unallocated. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `label` | label | LongMultiLineText | | The display text for the line. Unlike every sibling line entity the field name is lower-cased, which trips up hand-written field paths; no logic depends on its value. | | `LimitExpiryDays` | Limit Expiry Days | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OrderLineId` | Sale Order Line | Lookup → [OrderLine](/docs/reference/entities/order-line/) | | The sales order line this fulfilment line mirrors (serviceOrderLineId is the service-order equivalent); allocation consumes the line's pending allocation quantity. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PendingAllocationQuantity` | Pending Allocation Quantity | Calculated (calculated) | | | | `Quantity` | Quantity | Number | | The demand this line carries, copied at release from the source line's pending fulfilment quantity (or from the per-line requested quantity when the release was selective). It rolls up onto the source line's FulfilmentOrderQuantity and can never be reduced below what has already been allocated, cancelled or back-ordered. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedQuantity` | Requested Quantity | Number | | Not stored demand — a per-line value carried in the selective action payload saying how much of the pending amount to allocate on this run; it is rejected if it exceeds PendingAllocationQuantity. | | `ServiceOrderLineId` | Work Orde Line | Lookup → [ServiceOrderLine](/docs/reference/entities/service-order-line/) | | Populated instead of OrderLineId when the fulfilment was raised from a ServiceOrder; the quantity then rolls up onto ServiceOrderLine.FulfilmentOrderQuantity. | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StockAvailable` | Stock Available | Calculated | | A column that exists in the schema but is populated by nothing — no formula and no code path writes it, so it reads zero. Read availability from the InventoryStock row instead. | | `StockInHand` | Stock In Hand | Calculated | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `UIProps` | UI Props | Text | | | | `UnitPrice` | Unit Price | Currency | | Copied from the source order line. For items that are not lot-tracked this value is written into the allocation line's UnitCost, so a zero price here produces zero-valued reservations. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Blocked once anything has been allocated against the demand line; cancel the reservations first. | | `DeleteInList` | Delete | Delete | Delete in a list page | | `EditEntity` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `Editlist` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `HeaderEdit` | Header Edit | EditInline | Edit | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Quantity Allocated Rule Validation | `AllocatedQuantity`, Error | Allocated Quantity should not be greater than Quantity | Allocated Quantity should not be greater than Quantity | | Quantity Cancelled Validation | `CancelledQuantity`, Error | Quantity Cancelled should not be greater than Quantity. | Quantity Cancelled should not be greater than Quantity. | | Quantity Rule Validation | `Quantity`, Error | Quantity can't be less than zero. | Quantity can't be less than zero. | | XM_RequestedQuantityValidation | Error, inactive | Requested Quantity Cannot be 0 or Less than 0 | Requested Quantity Cannot be 0 or Less than 0 | | Unit Cost Rule Validation | `UnitPrice`, Error | Unit Price can't be less than zero. | Unit Price can't be less than zero. | ## Related entities - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [OrderLine](/docs/reference/entities/order-line/) — looks up via `OrderLineId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — looks up via `InventoryFulfilmentId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — looks up via `ServiceOrderLineId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — looks up via `InventoryStockId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `InventoryFulfilmentOrderLineId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `InventoryFulfilmentOrderLineId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `InventoryFulfilmentOrderLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Inventory Fulfillment Picking Line — entity reference URL: https://xmatix.com/docs/reference/entities/inventory-fulfilment-picking-line/ Last reviewed: 2026-08-16 A physical pick raised one-for-one from an allocation line, capped at that line's PendingPickingQuantity; it can only exist with an allocation-line parent, which the handler enforces on insert. Saving it posts a Picked ledger row that moves the quantity out of the InventoryStock Allocation bucket into Picked — stock is reclassified, not shipped. ConfirmPicking is the step that makes it real: it overwrites Quantity with what was actually picked, records the shortfall in CancelQuantity, sets IsPickingConfirmed, and may re-point the lot, bin or stock bucket from the operator's payload. Confirmation gates both CancelPicking and PickedDelivery, and cancellations are negative rows linked through ParentInventoryFulfilmentPickingLineId. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CancelQuantity` | Cancel Quantity | Number | | Written by ConfirmPicking as the shortfall between what the pick was raised for and what was confirmed. It flows back into the parent reservation's PendingPickingQuantity so the missing amount can be picked again. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeliveryQuantity` | Delivery Quantity | Decimal | | Roll-up of the delivery-order lines raised from this pick; the pending delivery figure is Quantity less this less what was returned. | | `DocumentDate` | Document Date | Date | | Defaults to the UTC construction time of the record rather than being stamped by a handler, so it is a system timestamp, not a warehouse business date. | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `InventoryFulfilmentAllocationLineId` | Fulfillment Allocation Line | Lookup → [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) | | The allocation line this pick draws from; the allocation/picking/delivery quantity state machine reconciles through this link. | | `InventoryFulfilmentId` | Inventory Fulfilment | Lookup → [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) | | | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | Stamped with the Picked ledger row, which decrements the InventoryStock Allocation bucket and increments Picked. Its presence is how the platform knows the reclassification already happened. | | `InventoryStockId` | Stock | Lookup → [InventoryStock](/docs/reference/entities/inventory-stock/) | | | | `IsILPosted` | IL Posted | Boolean | Yes | | | `IsILPostingApproved` | IL Posting Approved | Boolean | Yes | | | `IsPickingConfirmed` | Picking Confirmed | Boolean | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | Inherited from the reservation, but ConfirmPicking may overwrite it from the operator's payload — that is how a picker records that the goods physically came from a different lot. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `LastModifiedById` | LastModifiedBy | Guid | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | | | `OrderLineId` | Sale Order Line | Lookup → [OrderLine](/docs/reference/entities/order-line/) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentInventoryFulfilmentPickingLineId` | Inventory Fulfillment Picking Line | Lookup → [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) | | Cancel-picking creates return lines pointing at the picked line they undo via this self-reference; those children are then aggregated back onto the allocation line's picking-return rollup. | | `PendingDeliveryQuantity` | Pending Delivery Quantity | Calculated (calculated) | | Undelivered picked quantity; the picked-delivery actions require it above zero on the (selected) lines before a delivery order is created. | | `PickedByResourceId` | Picked By | Lookup → [Resource](/docs/reference/entities/resource/) | | Captured only when the ConfirmPicking payload names an operator, so it is blank on picks confirmed in bulk. The JSON property is upper-cased unlike its neighbours, which matters for API payloads. | | `PickedQuantity` | Picked Quantity | Calculated (calculated) | | | | `Quantity` | Quantity | Decimal | | The pick amount that actually posts to stock. It starts equal to the requested amount and is then overwritten by ConfirmPicking with what was really picked, so before confirmation it is an intention rather than a fact. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedQuantity` | Requested Quantity | Decimal | | A genuinely stored column here, unlike the transient namesakes on the sibling line entities: the amount the pick was raised for, taken from the reservation's pending picking quantity. ConfirmPicking compares against it to derive the cancelled shortfall. | | `ReturnedQuantity` | Returned Quantity | Decimal | | Quantity returned from picking on this line; rolls up onto the parent allocation line's pickingReturnQuantity. | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | | | `ServiceOrderLineId` | Service Order Line | Lookup → [ServiceOrderLine](/docs/reference/entities/service-order-line/) | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | Inherited from the reservation and overridable at confirmation, recording the bin the goods were actually taken from rather than the one planned. | | `UIProps` | UI Props | Text | | | | `UnitPrice` | Unit Price | Currency | | Copied from the parent reservation's UnitCost despite the name — for lot allocations that is a lot cost and for stock allocations it is the order line's selling price. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Blocked once the pick has a non-zero quantity; use CancelPicking on the fulfilment, which writes a reversing negative pick and posts the ledger back. | | `DeleteInList` | Delete | Delete | Delete | | `EditEntity` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New, inactive | Deactivated on purpose. Picks are produced only by the fulfilment's picking actions, and the handler rejects any positive-quantity pick that has no allocation-line parent. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Quantity Rule Validation | `Quantity`, Error, inactive | Quantity shouldn't be less than zero | Quantity shouldn't be less than zero | | Unit Price Rule Validation | `UnitPrice`, Error, inactive | Unit Price can't be less than zero | Unit Price can't be less than zero | ## Related entities - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — looks up via `InventoryFulfilmentAllocationLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [Resource](/docs/reference/entities/resource/) — looks up via `PickedByResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [OrderLine](/docs/reference/entities/order-line/) — looks up via `OrderLineId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — looks up via `InventoryFulfilmentId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — looks up via `ParentInventoryFulfilmentPickingLineId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — looks up via `InventoryStockId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — looks up via `ServiceOrderLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `ParentInventoryFulfilmentPickingLineId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `InventoryFulfilmentPickingLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Inventory Fulfilment — entity reference URL: https://xmatix.com/docs/reference/entities/inventory-fulfilment/ Last reviewed: 2026-10-10 The fulfilment document (Fulfilment Orders in the Warehouse and Inventory apps) is the warehouse's work order for outbound stock. It is released from a sales order or a service order, carries one fulfilment order line per item to fulfil, and hosts the warehouse actions in sequence: Allocation reserves specific stock, Picking turns allocation lines into picking lines, Confirm Picking records that the pick happened, and Picked Delivery or Allocation Delivery creates the delivery order. Every action has a selective variant for chosen lines and quantities. The quantities on the header are totals over the line grids, and progress is recorded in the read-only Document State field rather than in Status. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer the goods are going to. Copied from the sales order or service order when the fulfilment is released and locked afterwards: changing it on a released fulfilment is refused. | | `AllocatedQuantity` | Allocated Quantity | Calculated (calculated) | | Total quantity currently reserved on this document: the sum of the allocation lines. Cancelling an allocation writes a negative allocation line, so this total goes down when you cancel and means what is reserved now, not what was ever reserved. | | `AllocatedResourceId` | Allocated By | Lookup → [Resource](/docs/reference/entities/resource/) | | The warehouse person credited with the allocation. Filled in by hand on the New form or by editing; no action sets it. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch whose stock is used. Copied from the source order and locked afterwards. Allocation only looks at lots and stock records at this branch for the partner account, so stock held at another branch is never reserved. The branch must belong to the partner account. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | The document's date. A fulfilment released from a service order takes the service order's document date. It cannot be changed once the fulfilment is saved. | | `ExternalId` | External | Text | | Identifier of this fulfilment in an external system, used by integrations to match records. Not shown on the standard screens. | | `Id` | Id | Guid | Yes | | | `IsAllocated` | Allocated | Boolean | | A flag that no fulfilment action sets. It stays as it was created (normally off) whatever has been allocated, so do not use it to judge progress; read Document State or the Allocated Quantity and pending quantities instead. | | `IsInJobQueue` | In Job Queue | Boolean | | Not used by the fulfilment actions; nothing in the fulfilment process reads or sets it. | | `IsPicked` | Picked | Boolean | | A flag that no fulfilment action sets. Use Document State or Picked Quantity to see whether stock has been picked. | | `JobQueueId` | Job Queue | Lookup → [InterfaceQueue](/docs/reference/entities/interface-queue/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | The fulfilment's document number, assigned automatically when it is created by the Inventory Fulfilment document name setting (series IF by default). | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | The sales order this fulfilment was released from. Empty for a fulfilment released from a service order. It cannot be changed after the fulfilment is created, and the partner account, branch and account are taken from it. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company that owns the stock and runs the branch. Copied from the source order and locked afterwards; allocation only reserves lots and stock records belonging to this partner account. | | `PendingAllocationDelivery` | Pending Allocation Delivery | Calculated (calculated) | | Quantity reserved on allocation lines that has not yet been delivered: what Allocation Delivery would still put on a delivery order. Allocation lines that have already been picked count here too, but they can only be delivered through Picked Delivery. | | `PendingAllocationQuantity` | Pending Allocation Quantity | Calculated (calculated) | | Quantity still waiting to be reserved: for each fulfilment order line, its quantity minus what is allocated and what is cancelled. When stock runs short, allocation reserves what it can and leaves the rest here. | | `PendingDeliveryQuantity` | Pending Delivery Quantity | Calculated (calculated) | | Total quantity on the allocation lines that has not been delivered yet, whether it would go through Allocation Delivery or Picked Delivery. | | `PendingPickedDelivery` | Pending Picked Delivery | Calculated (calculated) | | Quantity on picking lines that has not yet been delivered: what Picked Delivery would put on a delivery order. Cancelled picks are excluded. | | `PendingPickingQuantity` | Pending Picking Quantity | Calculated (calculated) | | Reserved quantity that has no picking line yet: what Picking would still create picking lines for. | | `PerformAllocation` | Perform Allocation | Boolean | | Not used. Allocation is run with the Allocation or Selective Allocation action; ticking this box does nothing. | | `PerformCancelAllocation` | Perform Cancel Allocation | Boolean | | Not used. Use the Cancel Allocation or Selective Cancel Allocation action. | | `PerformCancelPicking` | Perform Cancel Picking | Boolean | | Not used. Use the Cancel Picking or Selective Cancel Picking action. | | `PerformPicking` | Perform Picking | Boolean | | Not used. Use the Picking or Selective Picking action. | | `PickedQuantity` | Picked Quantity | Calculated (calculated) | | Total quantity on the picking lines, net of cancelled picks (a cancelled pick is stored as a negative picking line). | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | The service order this fulfilment was released from, when the parts are being issued for service work. Empty for a fulfilment released from a sales order. | | `Status` | Status | PickList | | A picklist (Draft, Partially Allocated, Allocated) for your own process. The fulfilment actions never write it, so it changes only when a user or one of your business rules sets it. The read-only Document State field records what the actions have done. Values: Draft, Partially Allocated, Allocated. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `AllocationDelivery` | Allocation Delivery | ServerAction (`AllocationDelivery`) | CreateAllocationDelivery | | `BulkDelete` | Delete | Delete | Delete the selected records. | | `CancelAllocation` | Cancel Allocation | ServerAction (`CancelAllocation`) | PerformCancelAllocation | | `CancelPicking` | Cancel Picking | ServerAction (`CancelPicking`) | PerformCancelPicking | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `ConfirmPicking` | Confirm Picking | ServerAction (`ConfirmPicking`) | Confirm Picking | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInList` | Edit | Edit | Edit List Row | | `EditListHeader` | Edit | EditInline, inactive | EditListHeader | | `New` | New | New | New | | `PerformAllocation` | Perform Allocation | ServerAction (`PerformAllocation`) | This action creates allocationLines | | `PerformPicking` | Perform Picking | ServerAction (`PerformPicking`) | Creates picking line from allocation. | | `PickedDelivery` | Picked Delivery | ServerAction (`PickedDelivery`) | Create Delivery Order from picked items. | | `SelectiveAllocation` | Selective Allocation | ServerAction (`SelectiveAllocation`) | Allocates stock for chosen fulfilment order lines only. Args carry InventoryFulfilmentOrderLines with requestedQuantity, validated per line against pendingAllocationQuantity; unlisted lines are untouched, and the action refuses when nothing selected has pending allocation. | | `SelectiveAllocationDelivery` | Selective Allocation Delivery | ServerAction (`SelectiveAllocationDelivery`) | Creates a delivery order from chosen allocation lines with pending delivery quantity. Lines already moved to picking are refused - those must be delivered via SelectivePickedDelivery against their picking lines. | | `SelectiveCancelAllocation` | Selective Cancel Allocation | ServerAction (`SelectiveCancelAllocation`) | Cancels allocated quantity on the chosen allocation lines, handing it back to free stock. The requested quantity per line is validated against eligibleReturnQuantity, and the action refuses when the selected lines have nothing allocated. | | `SelectiveCancelPicking` | Selective Cancel Picking | ServerAction (`SelectiveCancelPicking`) | Cancels picked quantity on chosen picking lines - only lines whose picking is confirmed can be cancelled - and posts reversing inventory-ledger entries for the cancelled quantity. Creates return lines linked to the originals rather than mutating them. | | `SelectivePickedDelivery` | Selective Picked Delivery | ServerAction (`SelectivePickedDelivery`) | Creates a delivery order from chosen picking lines with pending delivery quantity, passing a requested quantity per line; refuses when no selected picking line has anything pending delivery. | | `SelectivePicking` | Selective Picking | ServerAction (`SelectivePicking`) | Creates picking lines for chosen allocation lines. Args carry InventoryFulfilmentAllocationLines with requestedQuantity validated against each line's pendingPickingQuantity; refuses when no selected line has pending picking quantity. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Resource](/docs/reference/entities/resource/) — looks up via `AllocatedResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [InterfaceQueue](/docs/reference/entities/interface-queue/) — looks up via `JobQueueId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ParentRecordId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `InventoryFulfilmentId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `InventoryFulfilmentId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `InventoryFulfilmentId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `InventoryFulfilmentId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `InventoryFulfilmentId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `InventoryFulfilmentId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Inventory Ledger Setting — entity reference URL: https://xmatix.com/docs/reference/entities/inventory-ledger-setting/ Last reviewed: 2026-08-16 The configuration that makes inventory posting generic: one row per source line entity and ledger type, telling the posting engine (InventoryLedgerService.DoLedgerPostingAsync) how a save of that entity becomes InventoryLedger rows plus stock-counter updates. Entity is the source line entity; ParentEntity names the header navigation the engine resolves PartnerAccountId/BranchId from (a setting without one treats the line as its own header). QuantityField picks the line field posted as the movement quantity (a CancelledQuantity field on the source line, when present, is always subtracted first), Condition is a formula gate deciding whether the setting applies to a given row, and IncrementalQuantityField/DecrementalQuantityField are comma-separated counter names added to / subtracted from the matching InventoryStock bucket and ItemLot (names are resolved loosely, matching Quantity/QuantityOn/QuantityIn-prefixed variants). Rows fire in Sequence order - Sequence must be unique within the same Entity + ledger type - and only IsActive rows run. Changing these rows changes what posts to the stock ledger for that entity tenant-wide. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Condition` | Condition | MultiLineText | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DecrementalQuantityField` | Decremental Quantity Field | Text | | | | `Entity` | Entity | Text | | | | `Id` | Id | Guid | Yes | | | `IncrementalQuantityField` | Incremental Quantity Field | Text | | | | `InventoryLedgerType` | Inventory Ledger Type | Text | | | | `IsActive` | Is Active | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentEntity` | Parent Entity | Text | | | | `QuantityField` | Quantity Field | Text | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Sequence` | Sequence | Number | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delte | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | EditInline | Edit | | `EditInLine` | Edit | EditInline | Edit in list Record | | `Editinlist` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Inventory Ledger — entity reference URL: https://xmatix.com/docs/reference/entities/inventory-ledger/ Last reviewed: 2026-08-16 The append-only journal of posted inventory movements: one row per source line per matching active InventoryLedgerSetting rule, written only by InventoryLedgerService.DoLedgerPostingAsync. Rows are immutable - the handler rejects every update and delete with an explicit message, and corrections happen by the engine posting a negated row that points at the original through ReversalOfLedgerId. Posting stamps the new row's id onto the source line's InventoryLedgerId, which is the reliable posted marker across the module, and also moves the matching InventoryStock buckets and ItemLot counters in the same unit of work. Movements are only emitted for items with TrackInventory set, and a lot is mandatory when the item has TrackLots. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch whose stock moved, taken from the source document's header. In the ledger report a branch filter compares against both this and the related branch, and transfer rows only count towards a branch's running totals when this field matches it. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Posting Date | Date | | | | `ExternalId` | External | Text | | | | `HashCode` | HashCode | Guid | | An identifier column that posting never assigns, so it stays null on every generated row. Do not use it to correlate or deduplicate movements - use the source record and parent record references instead. | | `Id` | Id | Guid | Yes | | | `In` | In | Number | | | | `InventoryLedgerType` | Ledger Type | PickList | | Values: Adjustment, Transfer Outward, Transfer Inward, Outward, Fulfilment, Sold, On Loan, Inspection Adjustment, Allocation, Picked, Sale Return, Purchase Return, Pipeline, Soft Commit. | | `IsInventoryStockPosted` | Inventory Stock Posted | Boolean | Yes | Whether this row's quantity was actually applied to an InventoryStock counter; false means the ledger row exists but no stock bucket field was updated (for example no increment field matched the configured names). | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | The item that moved, copied from the source line. Lines whose item does not have inventory tracking enabled are skipped entirely by posting, so no row is ever written for them. | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | The batch this movement consumed or produced, copied from the source line. Posting fails with a validation error when the item has lot tracking enabled and the line carries no lot. On a single-step transfer's inward row the destination lot is swapped in here and the original lot moves to the related lot field. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | The stock grade or variant carried through from the source line. It is recorded on the movement for reporting but is not part of the key used to find or create the matching stock balance. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Ledger Name | Text | | | | `OpeningStock` | Opening Stock | Number | | | | `Out` | Out | Number | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentEntityName` | Parent Entity Name | Text | | | | `ParentRecordId` | Parent Record Id | Lookup → @parentEntityName | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The owning company of the movement, taken from the source document's header rather than the line. On transfers it is resolved per leg, so an outward and an inward row of the same transfer can name different companies. | | `PendingDeliveriesQuantity` | Pending Deliveries Quantity | Number | | Carried for sold-but-undelivered movements: an Outward row can have zero quantity with this field holding the pending amount (the ledger view displays it as the quantity), and a SaleReturn row with it above zero does not count into availability until delivered. | | `Quantity` | Quantity | Number | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RelatedBranchId` | Related Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `RelatedItemLotId` | Related Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | The lot on the other side of a transfer movement. On single-step inward rows the engine swaps itemLotId to the destination lot and parks the source lot here. | | `RelatedPartnerAccountId` | Related Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The counterpart owning company on cross-company transfer rows; company-scoped ledger reads match it as well as partnerAccountId. | | `ReversalOfLedgerId` | Reverse Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | The SKU variant from the source line; together with partner, branch, item and storage location it selects the stock balance this movement is applied to. | | `SourceDocument` | Source Document | Text | | The human-readable name of the source document/line, stamped at posting time so ledger rows read meaningfully without joins. | | `SourceEntityName` | Source Entity Name | Text | | | | `SourceRecordId` | Source Record | Lookup → @sourceEntityName | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | The location whose balance was moved, after transfer resolution rather than as typed on the line - an inward leg is rewritten to the destination location. Movements onto the transit balance are not recorded as ledger rows at all; transit is maintained directly on the stock row. | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `GetInventoryLedgerData` | Get Inventory Ledger Data | ServerAction (`GetInventoryLedgerData`) | Returns a date-windowed stock ledger for one item (optionally one SKU) at one partner account, not a plain list of records: every movement row is returned with a running available and in-hand quantity and a running line-cost value, plus opening and closing totals for the window. BranchId is optional - omitting it consolidates every branch and makes inter-branch transfers net to zero. The running totals apply per-movement-type multipliers, so quantities such as Purchased, Pipeline, Picked and Inspection deliberately contribute nothing to them. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Unit Price Validation | `UnitCost`, Error, inactive | Unit Price should be greater than zero | Unit Price should be greater than zero | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `BranchId` | | | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — looks up via `ParentRecordId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — looks up via `ParentRecordId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `RelatedItemLotId` - [Account](/docs/reference/entities/account/) — looks up via `RelatedPartnerAccountId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Order](/docs/reference/entities/order/) — looks up via `ParentRecordId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — looks up via `ParentRecordId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — looks up via `ParentRecordId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `ParentRecordId` - [Branch](/docs/reference/entities/branch/) — looks up via `RelatedBranchId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Shipment](/docs/reference/entities/shipment/) — looks up via `ParentRecordId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `ReversalOfLedgerId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — looks up via `ParentRecordId` - [TransferLine](/docs/reference/entities/transfer-line/) — looks up via `ParentRecordId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — looks up via `SourceRecordId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ParentRecordId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [Bill](/docs/reference/entities/bill/) — looks up via `ParentRecordId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Adjustment](/docs/reference/entities/adjustment/) — looks up via `ParentRecordId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `InventoryLedgerId` - [TransferLine](/docs/reference/entities/transfer-line/) — referenced by via `InventoryLedgerId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `InventoryLedgerId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `DamagedInventoryLedgerId` - [InventoryCostConsumption](/docs/reference/entities/inventory-cost-consumption/) — referenced by via `SourceLedgerId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `InventoryLedgerId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `InventoryLedgerId` - [InspectionLine](/docs/reference/entities/inspection-line/) — referenced by via `InventoryLedgerId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `InventoryLedgerId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `InspectionInventoryLedgerId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `InspectionAdjustmentInventoryLedgerId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `InventoryLedgerId` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `InventoryLedgerId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `InventoryLedgerId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ReversalOfLedgerId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `InventoryLedgerId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `InventoryLedgerId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `InventoryLedgerId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `InventoryLedgerId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `InventoryLedgerId` - [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) — referenced by via `SourceLedgerId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `InventoryLedgerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Inventory NRV Assessment — entity reference URL: https://xmatix.com/docs/reference/entities/inventory-nrv-assessment/ Last reviewed: 2026-08-16 A lower-of-cost-and-net-realisable-value assessment for one item or one group of similar items, per accounting book and fiscal period: the carrying cost, the NRV inputs, the impairment movement recorded this run, and the cumulative outstanding write-down that caps any later reversal at original cost. History is append-only - each run reads the most recent prior row for the same book, item, group and branch as its starting point. Note that no first-party code path creates these rows: the assessment calculation exists as a service but only tests call it, so in a live tenant the row and its computed amounts have to be entered against the entity. Period close does consume them, posting a write-down or reversal journal for each unposted row and stamping JournalId, and the inventory valuation statement subtracts the latest OutstandingWriteDown from lot cost to reach carrying value. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountingBookId` | Accounting Book | Lookup → [AccountingBook](/docs/reference/entities/accounting-book/) | | | | `AsOfDate` | As Of Date | Date | | The measurement date. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Part of the key used to find the previous assessment, so assessing an item company-wide and then per branch produces independent write-down histories that will not cap each other's reversals. | | `CarryingValue` | Carrying Value | Currency | | Cost less the outstanding write-down after this run - a stored result of the calculation, not a live valuation of stock, and it never exceeds the original cost passed in. | | `CostToComplete` | Cost To Complete | Currency | | Further costs needed to bring the stock to saleable condition; it is subtracted from the estimated selling price when deriving NRV. | | `CostToSell` | Cost To Sell | Currency | | Costs of making the sale, such as commission or freight out; it is subtracted from the estimated selling price alongside cost to complete when deriving NRV. | | `CostValue` | Cost Value | Currency | | The carrying cost before impairment for the assessed scope. It is supplied to the calculation by the caller from the cost engine rather than being looked up from the cost layers here, so a hand-entered row can hold any figure. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EstimatedSellingPrice` | Estimated Selling Price | Currency | | The expected selling price of the assessed stock, the starting point of the NRV calculation - not a price-list lookup and not validated against one. | | `FiscalPeriodId` | Fiscal Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | | The period whose close will post this row. The posting step selects unposted rows by this key, so an assessment left without a fiscal period is never posted no matter what write-down it records. | | `Grouping` | Grouping | Text | | Records whether the lower-of-cost-and-NRV test was applied to a single item or to a group of similar items, which accounting standards require because write-downs may not be netted across the whole inventory. It is a stored label only - no code branches on it. | | `Id` | Id | Guid | Yes | | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | Set instead of the item when the test is applied to a group of similar items. The prior-run lookup matches item and item group together, so switching an item between item-level and group-level assessment starts a fresh impairment history rather than continuing the old one. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `JournalId` | Journal | Lookup → [Journal](/docs/reference/entities/journal/) | | Stamped when period close posts this row's write-down or reversal journal. A row that already has one is skipped on subsequent runs, which is exactly what makes re-running a close safe; an empty value means the impairment has not reached the general ledger. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Nrv` | Nrv | Currency | | Estimated selling price less cost to complete less cost to sell, rounded to two decimals. The impairment the assessment implies is cost less this figure, floored at zero. | | `OutstandingWriteDown` | Outstanding Write Down | Currency | | The cumulative impairment still carried after this run. The next assessment for the same book, item, group and branch reads it as its starting point, and the inventory valuation statement subtracts the latest one from lot cost, so it is the field that carries impairment forward rather than the per-run movements. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Policy` | Policy | Text | | Decides whether a recovery in net realisable value may be released. The calculation permits a reversal only when this equals ReversalAllowed (the IFRS and Ind AS position); NoReversal makes the impairment permanent, as US GAAP requires. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReversalThisRun` | Reversal This Run | Currency | | The incremental recovery this run releases, capped at the cumulative outstanding write-down so carrying value can never rise above original cost, and non-zero only when the policy allows reversal. Period close posts it as the mirror image of a write-down. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `WriteDownThisRun` | Write Down This Run | Currency | | The incremental impairment this run adds, that is the amount by which the newly required write-down exceeds the cumulative outstanding one. Period close posts it as a debit to an expense account and a credit to inventory. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | Delete | | `DeleteRow` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | Edit | | `EditHeader` | Edit | EditInline | Edit | | `EditInline` | Edit | EditInline | Edit | | `NewHeader` | New | New | New | ## Related entities - [Journal](/docs/reference/entities/journal/) — looks up via `JournalId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `FiscalPeriodId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [AccountingBook](/docs/reference/entities/accounting-book/) — looks up via `AccountingBookId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Inventory Opening Lot State — entity reference URL: https://xmatix.com/docs/reference/entities/inventory-opening-lot-state/ Last reviewed: 2026-08-16 The open cost lots at the start of a fiscal period, one row per lot, keyed by partner account + accounting book + fiscal period + item + branch + valuation method. It exists so inventory valuation can be replayed for a single period from an opening snapshot plus that period's movements instead of from inception, with each period's closing lots rolled forward as the next period's opening rows. It is a derived artefact, not a data-entry entity, and is blocked from integration sync for that reason. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountingBookId` | Accounting Book | Lookup → [AccountingBook](/docs/reference/entities/accounting-book/) | | The book this snapshot belongs to. Secondary books do not keep their own perpetual per-method balances, which is exactly why they need these snapshots to bound a replay to one period. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FiscalPeriodId` | Fiscal Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | | The period this snapshot opens, not the period it was computed from - a period's closing lots are written forward against the following period. | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `LotKey` | Lot Key | Text | | The lot identity used only under specific identification valuation; it is left empty for methods such as FIFO or weighted average, where lots are consumed by sequence rather than by name. | | `Method` | Method | Text | | The valuation method this snapshot was produced under, part of the row's identity: the same item and period can hold separate opening lots per method, which is what lets a secondary accounting book be replayed differently from the primary one. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `ReceiptDate` | Receipt Date | Date | | The original receipt date of the lot, preserved across the roll-forward so date-ordered valuation methods keep their ageing after a period boundary. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RemainingQuantity` | Remaining Quantity | Currency | | The quantity still unconsumed in this lot at the period boundary. Replay seeds the period with these as leading receipts, so this is the opening balance the period's issues draw against. | | `Sequence` | Sequence | LargeNumber | | The consumption order of this lot within the snapshot, assigned when a period's closing lots are rolled forward. Replay reconstructs the opening lots by this order first and receipt date second, so it determines which lot is drawn down first. | | `SourceCostLotId` | Source Cost Lot | Lookup → [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) | | A soft reference back to the perpetual cost lot this snapshot row came from, held without a foreign key so pruning cost lots cannot break a period's opening state. | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | The cost per unit carried by this open lot into the new period, and therefore the rate at which its remaining quantity is charged out when consumed. | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `FiscalPeriodId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [AccountingBook](/docs/reference/entities/accounting-book/) — looks up via `AccountingBookId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) — looks up via `SourceCostLotId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Inventory Stock — entity reference URL: https://xmatix.com/docs/reference/entities/inventory-stock/ Last reviewed: 2026-08-16 The running stock balance for one stock-keeping slot, keyed by partner account + branch + item + SKU + storage location; rows are created on demand by the ledger posting engine and never entered by hand (the entity has no New/Edit/Delete server actions). Every movement bucket stores a positive magnitude and direction is expressed by which bucket a rule increments or decrements, so on-hand answers come from the calculated Available / InHand / QuantityProjected fields rather than from summing buckets yourself. Stock only moves when a document posts through DoLedgerPostingAsync, not when a line is created. Two different availability models exist in the platform and they do not agree: this row's calculated Available and InHand both add Purchased, while the ledger report's running totals treat Purchased and Pipeline as neutral - prefer this entity for current balances and the ledger report for movement history. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AdjustedOut` | Negative Adjusted | Number | | Stock written off by adjustment lines that carry a negative quantity and no adjustment type. The engine applies it as a decrement of a negative number, so the bucket accumulates a positive magnitude of the quantity removed, and it is subtracted by the available, in-hand and projected balances alike. | | `Adjustment` | Positive Adjusted | LargeNumber | | Net signed quantity accumulated from adjustment postings against this bucket; in the availability math adjustments count fully into both available and in-hand. | | `Allocation` | Allocation Quantity | LargeNumber | | | | `Assemble` | Assembled In | Number | | Quantity produced by assembly, incremented by adjustment lines whose type is Assemble and added to the available, in-hand and projected balances. It is also incremented by adjustment lines whose type is Disassemble, because the seeded Disassemble rule names this field as its incremental target - a disassembly therefore currently increases assembled quantity. | | `Available` | Available | Calculated (calculated) | | | | `AverageCost` | Average Cost | Currency | | Inventory valuation lives in the Finance cost-lot entities driven by the posting cost hook, not on this row. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch the balance belongs to, part of the stock row key and read from the source document's header rather than the line. Transfer postings resolve it per leg, so an outward and an inward movement of the same transfer touch two different stock rows. | | `ClosingStock` | Closing Stock | Number | | Closing figures come from the ledger action's running totals or from the calculated Available and InHand fields on this row. | | `CostofGoods` | CostofGoods | Currency | | Cost of goods sold is produced by the Finance inventory costing engine from ledger movements, not accumulated here. | | `CostPrice` | Cost Price | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Damaged` | Damaged Quantity | LargeNumber | | Cumulative damaged quantity, fed by damaged quantities on goods receipt lines, transfer lines and credit note returns, and by adjustment lines whose type is Damaged. Subtracted from the available balance; absent from the in-hand formula. | | `DeAllocation` | DeAllocation | Number | | De-allocation is expressed as a negated reversal row that reduces the Allocation bucket instead. | | `Disassemble` | Assembled Out | Number | | In practice it stays at zero. | | `Excess` | Excess Quantity | LargeNumber | | Cumulative over-received or over-counted quantity, fed by excess quantities on goods receipt, transfer and credit note lines and by adjustment lines whose type is Excess. Adds to both the available and in-hand balances. | | `Expired` | Expired Quantity | LargeNumber | | Cumulative expired quantity, written off by adjustment lines whose type is Expired and by expiry-type credit note returns. Subtracted from the available balance; absent from the in-hand formula. | | `External` | Quantity External | Number | | | | `ExternalId` | External | Lookup | | | | `FinancialYear` | Financial Year | Number | | Stock rows are perpetual running balances with no period dimension, so do not use this to scope a balance to a year - use the ledger with a date window instead. | | `Fulfilment` | Fulfilment | LargeNumber | | | | `HashCode` | Hash Code | Number | | A numeric column left at its zero default: unlike the lot equivalent, nothing in the platform assigns or reads it on stock rows. | | `Id` | Id | Guid | Yes | | | `InHand` | In Hand | Calculated (calculated) | | | | `Inspection` | Inspection | LargeNumber | | Quantity held for incoming inspection, incremented from inspection lines raised against a goods receipt. Subtracted from the available balance but absent from the in-hand formula - inspected goods are physically present but not sellable. | | `InspectionAdjustment` | Inspection Adjustment | LargeNumber | | | | `InTransit` | Transit | Number | | | | `InventoryTurnover` | Inventory Turnover | Currency | | | | `Inward` | Unbilled Receipts | LargeNumber | | Received-but-unbilled quantity: goods receipt lines increment it, and it is drained again when the supplier bill posts Purchased against the same receipt line. Counts positively into both the available and in-hand balances. | | `IsTransactionLocked` | Is Transaction Locked | Boolean | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | InventoryStockService.SetInventoryStock searches with a key that does include it, so that lookup can only ever match rows where both sides are unset. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OnHold` | Quantity On Hold | LargeNumber | | Quantity blocked by an adjustment line whose adjustment type is OnHold. Subtracted from the available balance and ignored by the in-hand formula, so putting stock on hold makes it unsellable without pretending it left the building. | | `OnLoan` | Quantity On Loan | LargeNumber | | Quantity lent out via an adjustment line whose adjustment type is OnLoan. Subtracted from the available balance and ignored by the in-hand formula. | | `OpeningStock` | Opening Stock | Number | | Opening figures come from the ledger action, which computes them from movements dated before the window start. | | `Outward` | Unbilled Dispatches | LargeNumber | | Dispatched-but-uninvoiced quantity: delivery order lines increment it and the invoice drains it when it posts Sold against the delivery line. It is subtracted by the available balance but is absent from the in-hand formula, because the goods have left even though the sale is not yet booked. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The owning company for this balance, part of the stock row key. Posting takes it from the source document's header (the rule's parent entity), not from the line, so a line whose header has no partner cannot resolve or create a stock row. | | `PendingDeliveries` | Pending Deliveries | Number | | Counter for sold-but-undelivered stock; its ledger rows carry a matching pendingDeliveriesQuantity, and sale returns tied to a pending delivery stay out of availability until delivered. | | `Picked` | Picked Quantity | LargeNumber | | Quantity sitting on picked fulfilment lines. Neutral in the availability math, because allocation already removed it from available. | | `Pipeline` | Quantity On Pipeline | LargeNumber | | Inbound quantity on shipments not yet received; informational - it contributes to neither available nor in-hand until receipt posts an inward movement. | | `ProfitPrice` | Profit Price | Currency | | | | `Purchased` | Purchased Quantity | LargeNumber | | Quantity on order with suppliers; affects neither available nor in-hand until the goods are received. | | `PurchaseReturn` | Purchase Return Quantity | LargeNumber | | Cumulative quantity returned to suppliers, posted from credit note lines that are not classified as an excess, damage, shortage or expiry return. Subtracts from both the available and in-hand balances. | | `QuantityProjected` | Quantity Projected | Calculated (calculated) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SalePrice` | Sale Price | Currency | | | | `SaleReturn` | Sale Return Quantity | LargeNumber | | Cumulative customer-return quantity; adds to available and in-hand, except returns still tied to a pending delivery, which stay neutral until delivered. | | `Shortage` | Shortage | Number | | Cumulative short-received or short-counted quantity, fed by shortage quantities on goods receipt and transfer lines and by adjustment lines whose type is Shortage. Subtracted from the available balance only. | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `SoftCommit` | SoftCommit | LargeNumber | | Quantity committed by order lines ahead of fulfilment. Deliberately neutral in the availability math - it moves neither available nor in-hand. | | `Sold` | Sold Quantity | LargeNumber | | Accumulated invoiced quantity, incremented when an invoice line posts; the same rules simultaneously drain whichever upstream reservation the sale consumed (Picked, Allocation or Outward). Subtracts from both the available and in-hand balances. | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | Part of the stock row key, so the same item at two bins keeps two balances. A null value is meaningful rather than missing: the transfer transit balance is deliberately held on a row with no location. | | `TransferInward` | Transfer Inward | LargeNumber | | Cumulative quantity transferred into this bucket; counts positively into available and in-hand at the receiving branch. | | `TransferOutward` | Transfer Outward | LargeNumber | | Cumulative quantity transferred out of this bucket; subtracts from available and in-hand at the sending branch. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `Value` | Value | Currency | | Stock value is computed on demand by the ledger action as movement quantity times the ledger row's unit cost, and properly by the Finance costing engine. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `GetInventoryStockData` | Get Inventory Stock Data | ServerAction (`GetInventoryStockData`) | The stock handler implements GetInventoryStockStatement instead (an item-by-column available-quantity statement with opening, closing and change per column), and that action has no metadata row of its own. Invoking this action does not return stock data. | | `GetInventoryStockMatrix` | Inventory Stock (by dimension) | ServerAction (`GetInventoryStockMatrix`) | Stock available pivoted into columns by branch / period (Balance Statement comparative). | | `GetInventoryStockStatement` | Inventory Stock Statement | ServerAction (`GetInventoryStockStatement`) | Available stock per column (point-in-time or Opening/Change/Closing movement) for the Balance Statement. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Available Quantity Validation Rule | Error | Stock Available Quantity cannot be negative!! | Available Quantity cannot be negative!! | | In Hand Quantity Rule | `InHand`, Error | Stock In Hand Quantity can't be negative. | Quantity In Hand can't be negative. | | Validate Negative Quantity | Error | Stock Available Quantity cannot be negative!! | Available Quantity cannot be negative!! | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `BranchId` | | | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [CycleCountLine](/docs/reference/entities/cycle-count-line/) — referenced by via `InventoryStockId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `InventoryStockId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `InventoryStockId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `InventoryStockId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `InventoryStockId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `InventoryStockId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `InventoryStockId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `InventoryStockId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Inventory Valuation Policy — entity reference URL: https://xmatix.com/docs/reference/entities/inventory-valuation-policy/ Last reviewed: 2026-08-16 The rule that decides which cost-flow method the engine uses for a transaction, per accounting book. Resolution is most-specific-scope-wins: candidates are filtered to the book, to active rows and to the effective window, then a non-null scope key (business unit, branch, storage location, item group, item) must equal the transaction's value while a null key is a wildcard, with Priority and then a later EffectiveFrom breaking ties; when nothing matches the engine falls back to MovingAverage. CostingLevel is a separate axis setting the cost-pool boundary and takes no part in the scope match. Two traps: the seeded picklist stores Weighted Average and Moving Average with a space while the engine compares against unspaced constants, and the resolver's own validation (LIFO gating by GAAP framework, method-versus-level coherence, overlapping scopes) has no save-time caller, so contradictory or unusable policies can be saved. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountingBookId` | Accounting Book | Lookup → [AccountingBook](/docs/reference/entities/accounting-book/) | | Resolution is filtered to this book before anything else, so a policy on a different book is never considered. Because only the primary book persists cost layers, policies attached to a secondary book influence only the replay-driven overlay and the reporting paths, never the posted general ledger. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | A scope key matched against the transaction's branch; leaving it empty makes the policy apply across branches. Together with the item it is one of only two location-or-item keys the live posting path actually supplies. | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | A scope key that matches only when the caller supplies a business unit. The live cost-posting path never does, so a policy scoped to a business unit does not participate in posting-time resolution. | | `CostingLevel` | Costing Level | Text | | The boundary of a single cost pool - one FIFO queue or one average pool per this key - and it is a separate axis from the policy's scope, so it does not affect which transactions the policy matches. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EffectiveFrom` | Effective From | Date | | The policy is ignored for transactions dated before this, which is how a method change is applied prospectively rather than restating history. It is also the second tie-breaker at equal specificity and equal priority, where the later date wins. | | `EffectiveTo` | Effective To | Date | | The policy is ignored for transactions dated after this. The only validation on the window is that it must not precede EffectiveFrom, and even that check has no save-time caller, so an inverted or overlapping window will not be rejected. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | Only an explicit false excludes the policy from resolution; an empty value is treated as active. Deactivating is the safe way to retire a rule, since deleting one changes which policy wins for historical replays too. | | `IsDefault` | Is Default | Boolean | | Setting it does not make a scoped policy behave as a default. | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | A scope key that matches only when the caller supplies an item group in the resolution context. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | A scope key rather than a filter on which items the policy covers: leaving it empty makes the policy apply to every item, and setting it makes the policy the most specific match available, outranking an item-group-scoped rule and every location-level rule. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The owning company or legal entity, and also matched as a scope key - a policy left empty here applies to any company within the book. It contributes nothing to the specificity score. | | `Priority` | Priority | Number | | Tie-breaker between policies of equal specificity, where the lower number wins; an empty value is treated as the weakest possible precedence. It cannot promote a broadly scoped policy over a more specific one - specificity is decided first. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | A scope key that matches only when the caller supplies a storage location. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `ValuationMethod` | Valuation Method | PickList | | The cost-flow algorithm the engine runs for transactions this policy wins. FIFO, LIFO, MovingAverage, WeightedAverage (periodic) and SpecificIdentification are implemented; StandardCost is named in the taxonomy but the strategy factory refuses it outright as a later phase. The picklist also omits Specific Identification and Standard Cost. Values: FIFO, LIFO, Weighted Average, Moving Average. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete record | | `DeleteInList` | Delete | Delete | Delete record from the list | | `Edit` | Edit | Edit | Edit record | | `EditInLine` | Edit | EditInline | Edit record inline | | `EditListRow` | Edit | Edit | Edit record from the list | | `New` | New | New | Create a new record | ## Related entities - [AccountingBook](/docs/reference/entities/accounting-book/) — looks up via `AccountingBookId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Invoice Line — entity reference URL: https://xmatix.com/docs/reference/entities/invoice-line/ Last reviewed: 2026-08-16 One billed item on an Invoice, and the level at which price, discount and tax are actually resolved. Its money chain is entirely metadata-calculated: BaseAmount is Quantity times UnitPrice2 when that is non-zero else UnitPrice; NetDiscount and NetSchemeDiscount collapse the percentage/amount discount pairs; Amount is BaseAmount less those discounts; GrossAmount is Amount plus TaxAmount. Tax1 through Tax6 are generic component slots filled from the line's tax group, not fixed tax types. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Calculated (calculated) | | A denormalised copy of the parent invoice's customer, calculated as the invoice's AccountId converted to text. Note it is stored as a string rather than a key, so it is not a usable foreign key or lookup — join through the parent invoice instead. | | `AllocatedQuantity` | Allocated Quantity | Decimal | | | | `Amount` | Amount | Calculated (calculated) | | The net line value before tax, metadata-calculated. When post-tax discounting applies it is simply BaseAmount, because the discount is instead removed later in GrossAmount; otherwise it is BaseAmount less NetDiscount and NetSchemeDiscount. This is the amount rolled into the header TotalLineAmount and the value that becomes the line's ledger leg. | | `ApplyPostTaxDiscount` | Apply Post Tax Discount | Boolean | | Switches where discount is taken. It is copied from the owning company's Account setting when the line's taxes are computed, not chosen per line. When on, discounts are excluded from Amount and instead subtracted in GrossAmount, and the discount rates are applied to BaseAmount plus tax rather than to BaseAmount alone. | | `AssessableAmount` | Assessable Amount | Calculated (calculated) | | | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `Barcode` | Barcode | Text | | | | `BaseAmount` | Base Amount | Calculated (calculated) | | Metadata-calculated as Quantity times UnitPrice2 when that override is non-zero, otherwise Quantity times UnitPrice. It is the gross-of-discount, pre-tax starting point for every discount and tax formula on the line. | | `BenefitIndex` | Benefit Index | Number | | | | `BillingFrequency` | Billing Frequency | Text | | | | `BillingType` | Billing Type | Text | | | | `BranchId` | Branch | Text | | | | `CancelledQuantity` | Cancelled Quantity | Decimal | | | | `ChargeType` | Charge Type | Text | | Values: One Time. | | `ClaimLineId` | Claim Line | Lookup → [ClaimLine](/docs/reference/entities/claim-line/) | | | | `ContractDiscount` | Contract Discount | Percent | | | | `ContractDiscountAmount` | Contract Discount Amount | Currency | | | | `ConversionRatio` | Conversion Ratio | Decimal | | | | `ConversionRatio1` | Conversion Ratio 1 | Decimal | | | | `CostPrice` | Cost Price | Currency | | Dead: no code path anywhere populates it. An earlier invoice-time cost-of-goods-sold block summed this field and therefore always computed zero; it was removed deliberately, and cost of goods sold is now recognised at goods issue from engine cost instead. Do not use this field for margin. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeliveredQuantity` | Delivered Quantity | Decimal | | | | `DeliveryOrderLineId` | Delivery Order Line | Lookup → [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) | | | | `DeliveryQuantity` | Delivery Quantity | Decimal | | A rolling total of the quantity delivered against this line, maintained as the sum of the related DeliveryOrderLine quantities rather than entered by hand. It is the subtrahend behind PendingDeliveryQuantity. It is distinct from DeliveredQuantity, which is derived from inventory fulfilment allocation instead. | | `Discount` | Discount | Percent | | A discount rate expressed as a multiplier, not a percentage out of a hundred: the formulas compute BaseAmount times this value, so 0.10 is ten percent. It is ignored whenever DiscountAmount is positive, since an explicit amount always wins over the rate. | | `Discount2` | Cash Discount | Percent | | | | `DiscountAmount` | Discount Amount | Currency | | It is one of three pairs (with Discount2/DiscountAmount2 and ContractDiscount/ContractDiscountAmount) that add up into NetDiscount. | | `DiscountAmount2` | Cash Discount Amount | Currency | | | | `DiscountGroupRuleId` | Discount Group Rule | Lookup → [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) | | | | `EligibleReturnQuantity` | Eligible Return Quantity | Calculated (calculated) | | Metadata-calculated as Quantity minus ReturnedQuantity — how much of the line can still be taken back on a credit note. Cancellation is accounted for separately in the metadata formulas rather than being netted here in code. | | `ExternalId` | External ID | Text | | | | `FieldSalesId` | Field Sales | Lookup → [FieldSales](/docs/reference/entities/field-sales/) | | | | `FreeQuantity` | FreeQuantity | Decimal | | Not an independently entered figure: it is the line's own Quantity when the line was generated by the promotional-scheme engine, and zero otherwise. It exists so free-goods lines can be reported without inspecting the scheme linkage, and it is both a stored column and a calculated fallback. | | `GeneralLedgerId` | General Ledger | Lookup → [GeneralLedger](/docs/reference/entities/general-ledger/) | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `GLAmount` | GL Amount | Calculated (calculated) | | Metadata-calculated as a copy of Amount, and it is the field posting actually reads for the line's ledger leg. A line whose amount is zero contributes no leg at all, while its tax slots are still posted independently. | | `GLPostingType` | GL Posting Type | Text | | | | `GrossAmount` | Gross Amount | Calculated (calculated) | | Metadata-calculated as Amount plus TaxAmount, less the discounts again when the line is flagged for post-tax discounting (which is where those discounts are actually taken, since Amount left them in). It is the tax-inclusive line value and is what the header TotalAmount and TotalLineGrossAmount both roll up. | | `HsnSacCode` | HSN/SAC Code | Text | | | | `Id` | Id | Guid | Yes | | | `InventoryFulfilmentAllocationLineId` | Inventory Fulfillment Allocation Line | Lookup → [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) | | | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | | | `InvLineName` | InvLineName (For E-invoice) | Text | | A system-generated line document name in the form INVL-ddMMyyyy followed by the last three digits of the sequence, reformatted from the name the document-naming service produced. It is stamped on insert and not maintained afterwards. | | `InvoiceDiscount` | Invoice Discount | Calculated (calculated) | | A read-through of the header invoice's Discount rate, held as a calculated field so line-level reporting can see the header discount that was pushed down. It is informational and is not itself one of the discount pairs that feed NetDiscount. | | `InvoiceId` | Sale Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | | | `IsClaimed` | Claimed | Boolean | | | | `IsGLPosted` | GL Posted | Boolean | | | | `IsGLPostingApproved` | GL Posting Approved | Boolean | | | | `IsILPosted` | IL Posted | Boolean | | | | `IsILPostingApproved` | IL Posting Approved | Boolean | | | | `IsPriceBundled` | Price Bundled | Boolean | | | | `IsSchemeGenerated` | Scheme Generated | Boolean | | | | `ItemAliasId` | Item Alias | Lookup → [ItemAlias](/docs/reference/entities/item-alias/) | | | | `ItemAlternateId` | Alternate Item | Lookup → [ItemAlternate](/docs/reference/entities/item-alternate/) | | | | `ItemComponentId` | Item Component | Lookup → [ItemComponent](/docs/reference/entities/item-component/) | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ItemName` | Item Name | Text | | | | `ItemServiceContractId` | Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | | | `LimitExpiryDays` | Limit Expiry Days | Number | | | | `LineNumber` | Line Number | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `NetDiscount` | Net Discount | Calculated (calculated) | | The collapsed ordinary discount on the line: for each of the three pairs — Discount/DiscountAmount, Discount2/DiscountAmount2 and ContractDiscount/ContractDiscountAmount — an explicit positive amount wins, otherwise the rate is applied to BaseAmount, or to BaseAmount plus tax when post-tax discounting is on. Scheme discount is excluded and handled by NetSchemeDiscount. | | `NetSchemeDiscount` | Net Scheme Discount | Calculated (calculated) | | The promotional-scheme discount, resolved the same way as NetDiscount: SchemeDiscountAmount wins when positive, otherwise the SchemeDiscount rate is applied to BaseAmount, or to BaseAmount plus tax under post-tax discounting. It is kept separate from ordinary discount so scheme cost can be reported on its own. | | `OrderLineId` | Order Line | Lookup → [OrderLine](/docs/reference/entities/order-line/) | | | | `OriginalAssetId` | Original Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `OriginalItemId` | Original Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PackageInvoiceLineId` | Package Invoice Line | Lookup → [InvoiceLine](/docs/reference/entities/invoice-line/) | | | | `PackageOrderLineId` | Package Order Line | Lookup → [OrderLine](/docs/reference/entities/order-line/) | | | | `PartnerAccountId` | Partner Account | Calculated (calculated) | | A denormalised copy of the parent invoice's owning company, calculated as the invoice's PartnerAccountId converted to text. Like AccountId on this entity it is a string, not a key, so it cannot be used as a relation and exists only to make line-level queries filterable by company. | | `PendingDeliveryQuantity` | Pending Delivery Quantity | Calculated (calculated) | | Metadata-calculated as Quantity minus DeliveryQuantity — what is still undelivered on this line. The delivery action only picks up lines where this is above zero, and validation refuses the action when no line has anything pending. | | `PendingShipmentQuantity` | Pending Shipment Quantity | Calculated (calculated) | | | | `PickedQuantity` | Picked Quantity | Decimal | | | | `PriceAsOnDate` | Price As On Date | Date | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `PriceListRuleId` | Price List Rule | Lookup → [PriceListRule](/docs/reference/entities/price-list-rule/) | | | | `Quantity` | Quantity | Decimal | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedQuantity` | Requested Quantity | Decimal | | | | `ReturnedQuantity` | Returned Quantity | Decimal | | | | `RNAExternalId` | RNA External ID | Text | | | | `RNASaleInvoiceExternalId` | RNA Sale Invoice External ID | Text | | | | `SchemeBenefitId` | Scheme Benefit | Lookup → [SchemeBenefit](/docs/reference/entities/scheme-benefit/) | | | | `SchemeDiscount` | Scheme Discount | Percent | | | | `SchemeDiscountAmount` | Scheme Discount Amount | Currency | | | | `SchemeLineId` | Scheme Slab | Lookup → [SchemeLine](/docs/reference/entities/scheme-line/) | | | | `SchemeRewardPoints` | Scheme Reward Points | LargeNumber | | | | `ServiceOrderLineId` | Service Order Line | Lookup → [ServiceOrderLine](/docs/reference/entities/service-order-line/) | | | | `ShipmentQuantity` | Shipment Quantity | Decimal | | | | `SkipScheme` | Skip Scheme | Boolean | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `SoftCommittedQuantity` | Soft Committed Quantity | Calculated (calculated) | | Metadata-calculated: it equals the line quantity when the originating order line or service order line has already reached the inventory ledger, and zero otherwise. It flags stock notionally committed by this line rather than holding an independently maintained reservation. | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `SubscriptionId` | Subscription | Lookup → [Subscription](/docs/reference/entities/subscription/) | | | | `SubscriptionUsageId` | Subscription Usage | Lookup → [SubscriptionUsage](/docs/reference/entities/subscription-usage/) | | | | `SubscriptionUsageSummaryId` | Subscription Usage Summary | Lookup → [SubscriptionUsageSummary](/docs/reference/entities/subscription-usage-summary/) | | | | `Tax1` | Tax 1 | Currency | | The first of six generic tax-component slots, not a fixed tax type. Which component lands here is decided by the posting-field name configured on the Tax master in the line's tax group, so slot 1 might be CGST on one tenant and IGST on another. Every slot is cleared and recomputed whenever the line's taxes are recalculated. | | `Tax1Name` | Tax Name 1 | Text | | | | `Tax1Rate` | Tax Rate 1 | Currency | | | | `Tax1Type` | Tax Type 1 | Text | | A copy of the tax type from the Tax master that filled slot 1, stamped when the line's taxes were computed. Posting uses it to pick the tax account for the leg (an account whose subtype names this component wins over the generic tax account), and a slot with an empty type is skipped entirely at posting time even if its amount is non-zero. | | `Tax2` | Tax 2 | Currency | | | | `Tax2Name` | Tax Name 2 | Text | | | | `Tax2Rate` | Tax Rate 2 | Currency | | | | `Tax2Type` | Tax Type 2 | Text | | | | `Tax3` | Tax 3 | Currency | | | | `Tax3Name` | Tax Name 3 | Text | | | | `Tax3Rate` | Tax Rate 3 | Currency | | | | `Tax3Type` | Tax Type 3 | Text | | | | `Tax4` | Tax 4 | Currency | | | | `Tax4Name` | Tax Name 4 | Text | | | | `Tax4Rate` | Tax Rate 4 | Currency | | | | `Tax4Type` | Tax Type 4 | Text | | | | `Tax5` | Tax 5 | Currency | | | | `Tax5Name` | Tax Name 5 | Text | | | | `Tax5Rate` | Tax Rate 5 | Currency | | | | `Tax5Type` | Tax Type 5 | Text | | | | `Tax6` | Tax 6 | Currency | | | | `Tax6Name` | Tax Name 6 | Text | | | | `Tax6Rate` | Tax Rate 6 | Currency | | | | `Tax6Type` | Tax Type 6 | Text | | | | `TaxAmount` | Tax Amount | Currency | | The total of every tax component that landed in the six tax slots on this line, written by the tax service as the sum of the line's tax-group components. Each component is computed on the discounted line value, not on BaseAmount, so changing a discount changes tax. It is the value the header TotalLineTaxAmount rolls up. | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `TdsSectionId` | TDS Section | Lookup → [TdsSection](/docs/reference/entities/tds-section/) | | Tags the line with a withholding section for tax collected at source. When present, posting the invoice raises a collection entry (debiting the receivable and crediting the collection liability) that grows the customer's balance; unlike the GST analytics capture this is a ledger entry, so a failure here rolls the whole invoice posting back. | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | The cost side of the line, copied from the inventory fulfilment allocation line when the invoice is built from allocated stock, so it reflects the lot or layer cost actually drawn. It does not participate in any price, discount or tax formula and is not what the cost-of-goods-sold journal uses. | | `UnitPrice` | Unit Price | Currency | | | | `UnitPrice2` | Unit Price (Alt) | Currency | | An alternate price copied from the price-list rule's second price, and it takes precedence: BaseAmount uses it whenever it is non-zero and only falls back to UnitPrice otherwise. | | `UOM` | UOM | Text | | | | `UOM1` | UOM1 | Text | | | | `UOMQuantity` | UOM Quantity | Decimal | | | | `UOMQuantity1` | UOM Quantity 1 | Decimal | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Bulk` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditInList` | Edit | Edit | Edit | | `New` | New | New | New | | `NewInLine` | Quick Add | NewInline | New In Line | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Quantity Rule Validation | `Quantity`, Error | Quantity should be in Positive. | Quantity should be in Positive. | | Returned Quantity Validation | `ReturnedQuantity`, Error | Returned Quantity can not be greater than Quantity | Returned Quantity can not be greater than Quantity | | Unit Price Rule Validation | `UnitPrice`, Error | Unit price can not be Negative | Unit price can not be Negative | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Lot For SKU | `ItemLotId` | | | Lot Type for Item | `ItemLotTypeId` | | | SKU For Item | `SKUId` | | ## Related entities - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [Item](/docs/reference/entities/item/) — looks up via `OriginalItemId` - [OrderLine](/docs/reference/entities/order-line/) — looks up via `OrderLineId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [SubscriptionUsageSummary](/docs/reference/entities/subscription-usage-summary/) — looks up via `SubscriptionUsageSummaryId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — looks up via `SchemeBenefitId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [ItemAlias](/docs/reference/entities/item-alias/) — looks up via `ItemAliasId` - [TdsSection](/docs/reference/entities/tds-section/) — looks up via `TdsSectionId` - [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) — looks up via `DiscountGroupRuleId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — looks up via `PackageInvoiceLineId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [FieldSales](/docs/reference/entities/field-sales/) — looks up via `FieldSalesId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [ClaimLine](/docs/reference/entities/claim-line/) — looks up via `ClaimLineId` - [Asset](/docs/reference/entities/asset/) — looks up via `OriginalAssetId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — looks up via `InventoryFulfilmentAllocationLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ItemAlternate](/docs/reference/entities/item-alternate/) — looks up via `ItemAlternateId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — looks up via `GeneralLedgerId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — looks up via `ServiceOrderLineId` - [SchemeLine](/docs/reference/entities/scheme-line/) — looks up via `SchemeLineId` - [ItemComponent](/docs/reference/entities/item-component/) — looks up via `ItemComponentId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — looks up via `DeliveryOrderLineId` - [OrderLine](/docs/reference/entities/order-line/) — looks up via `PackageOrderLineId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — looks up via `PriceListRuleId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [SubscriptionUsage](/docs/reference/entities/subscription-usage/) — looks up via `SubscriptionUsageId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [Subscription](/docs/reference/entities/subscription/) — looks up via `SubscriptionId` - [SchemeAccountBudgetUtilization](/docs/reference/entities/scheme-account-budget-utilization/) — referenced by via `InvoiceLineId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `InvoiceLineId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `InvoiceLineId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `PackageInvoiceLineId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `InvoiceLineId` - [SubscriptionUsageSummary](/docs/reference/entities/subscription-usage-summary/) — referenced by via `InvoiceLineId` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `InvoiceLineId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `InvoiceLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Invoice — entity reference URL: https://xmatix.com/docs/reference/entities/invoice/ Last reviewed: 2026-10-10 A sales invoice bills a customer for goods or services and turns the sale into a receivable. It is usually released from a sales order, and can also be created from a delivery order, by trade-claim settlement or by hand, in the Sales and Finance apps. It receives a document number from document numbering (shipped series INV) and starts as Draft. Header money figures are calculated from its lines. Post General Ledger posts one balanced journal and a receivable item for the customer, and a business rule moves the status to Posted; Post Inventory moves the stock. Payments linked to the invoice reduce its outstanding amount. A posted invoice can be cancelled within a configurable window, which reverses its stock movement, settled payments and journals and sets the status to Cancelled; it cannot be deleted. In India the invoice also carries the e-invoice and e-way bill actions. Step-by-step procedures are on the Invoices page of the Sales documentation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | Yes | The customer being billed — the party side of the receivable, and the account stamped on the AR control leg of the journal and on the resulting open item. Do not confuse it with PartnerAccountId, which is the company that owns the document. It is fixed after creation and is the field the credit-limit breach message points at. | | `AccountName` | Account Name | Text | | | | `AdjustedAmount` | Adjusted Amount | Currency | | Running total of PaymentAdjustment amounts applied to this invoice; the payment-application path adds each adjustment here and immediately recomputes OpenAmount as TotalAmount minus this value. Reversing an adjustment subtracts it back. An adjustment larger than the current OpenAmount is rejected. | | `AmountPaid` | Amount Paid | Currency | | Roll-up of the Amount of every Payment tagged with this invoice, recomputed by the payment save pipeline on insert, on edit of the amount or invoice link, and on delete. It counts payments pointed at the invoice, not money actually allocated in the subledger, so it can exceed what a settlement allocation records. Defaults to zero and is protected against direct user edits. | | `ApproximateDistance` | Approximate Distance | Decimal | | | | `AssetId` | Asset | Lookup | | | | `BillingAddress` | Billing Address | Text | | | | `BillingCity` | Billing City | PickList | | Values: Mumbai, Pune, Chandigarh. | | `BillingCityPlaceId` | Billing City | Lookup → [Place](/docs/reference/entities/place/) | | Values: Mumbai, Pune, Chandigarh. | | `BillingContactAddressId` | Billing Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `BillingCountry` | Billing Country | PickList | | Values: India. | | `BillingPostalCode` | Billing Postal Code | Text | | | | `BillingRegion` | Billing Region | Text | | | | `BillingState` | Billing State | PickList | | Values: Haryana, Maharashtra, New Delhi, Punjab. | | `BillingStreet` | Billing Street | Text | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch of the partner account that issues the invoice. Only active branches of the chosen partner account are accepted, and it is required when the partner account has branches. It cannot be changed once saved. | | `CessValue` | Cess Value | Calculated (calculated) | | Cess Value (E-Invoice) | | `ClaimBatchId` | Claim Batch | Lookup → [ClaimBatch](/docs/reference/entities/claim-batch/) | | | | `ClaimId` | Claim | Lookup → [Claim](/docs/reference/entities/claim/) | | | | `ContactId` | Contact | Lookup → [Contact](/docs/reference/entities/contact/) | | | | `ContactName` | Contact Name | Text | | | | `ContactNumber` | Contact Number | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeliveryOrderId` | Delivery Order | Lookup → [DeliveryOrder](/docs/reference/entities/delivery-order/) | | | | `Discount` | Discount | Percent | | A header discount expressed as a multiplier, not a percentage out of a hundred — the line formulas apply it as base amount times this value, so 0.10 means ten percent. Changing it pushes the value down onto the invoice lines, and each line also exposes it read-only as InvoiceDiscount. | | `DiscountGroupId` | Discount Group | Lookup → [DiscountGroup](/docs/reference/entities/discount-group/) | | The discount group whose contract discount rules apply to the invoice lines. Read-only on the saved invoice. | | `DocumentDate` | Document Date | Date | | Stamped with the server clock at creation and used as the journal date when the invoice posts. It is also the anchor for the cancellation window — the window is measured from this value against the current server time, deliberately rather than from the journal's database-generated timestamp, whose clock and timezone are the database server's. | | `DocumentSeries` | Document Series | Calculated (calculated) | | Metadata-calculated by concatenating the owning company's document-name code with the branch's document-name code, so it identifies which numbering series the document belongs to rather than holding a sequence number. The domain object also falls back to that concatenation when the stored column is empty. | | `DueDate` | Due Date | Date | | The date payment is due. Invoices with an outstanding amount and a due date in the past are counted in the Overdue Receivables summary card. | | `EINVAckDate` | Ack Date (eInvoice) | Text | | | | `EINVAckNo` | Ack No (eInvoice) | Text | | | | `EINVAdditionalCurrencyCode` | Additional Currency Code (eInvoice) | Text | | | | `EINVCancellationDate` | EINV CancellationDate | Date | | | | `EINVCancellationReason` | EINVCancellationReason | Text | | | | `EINVCancellationRemarks` | EINV Cancellation Remarks | Text | | | | `EINVCommerceOperatorGSTIN` | e-Commerce Operator GSTIN (eInvoice) | Text | | | | `EINVExportDutyAmount` | Export Duty Amount (eInvoice) | Currency | | | | `EINVIGSTApplicability` | IGST Applicability (eInvoice) | Boolean | | | | `EINVIRN` | Invoice Reference Number (eInvoice) | Text, unique | | | | `EinvoiceImage` | E-Invoice Image | LongMultiLineText | | | | `EINVPayload` | Payload (eInvoice) | LongMultiLineText | | | | `EINVPortCode` | Port Code (eInvoice) | Text | | | | `EINVQRCode` | QR Code (eInvoice) | LongMultiLineText | | | | `EINVRemarks` | Remarks (eInvoice) | Text | | | | `EINVResponse` | Response (eInvoice) | LongMultiLineText | | | | `EINVReverseCharge` | Reverse Charge (eInvoice) | Boolean | | | | `EINVShippingBillDate` | Shipping Bill Date (eInvoice) | Date | | | | `EINVShippingBillNumber` | Shipping Bill Number (eInvoice) | Text | | | | `EINVSignedInvoice` | Signed Invoice (eInvoice) | LongMultiLineText | | | | `EINVStatus` | Status (eInvoice) | PickList | | Tracks the invoice-registration-portal lifecycle across the vocabulary Pending, Ready For IRN, Generated, Cancelled and Error. Staging the payload sets it to Pending; the bound integration flow advances it, and a dedicated action can set it (typically to Ready For IRN) inside the same save so the flow reacts on that write. It is an edit-protected system field, writable only while those flows run. Values: Pending, Generated, Cancelled, Error, Ready For IRN. | | `EINVSupplierCanOptRefund` | Supplier Can Opt Refund (eInvoice) | Boolean | | | | `EINVSupplyTypeCode` | Supply Type Code (eInvoice) | PickList | | Values: B2B, SEZWP, SEZWOP, EXPWP, EXPWOP, DEXP, O. | | `EINVTaxScheme` | Tax Scheme (eInvoice) | Text | | | | `EWayBillDate` | E-Way Bill Date | DateAndTime | | The date and time the e-way bill was generated, recorded with the e-way bill number. | | `EWayBillNumber` | E-Way Bill Number | Text | | The e-way bill number, recorded when the GST integration returns it after E Way Bill is run, and cleared when the e-way bill is cancelled. | | `ExecutiveResourceId` | Executive Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `ExternalId` | External ID | Text | | | | `FieldSalesId` | Field Sales | Lookup → [FieldSales](/docs/reference/entities/field-sales/) | | | | `FinanceAmount` | Finance Amount | Currency | | Not a receivables figure. It is the total DisbursedAmount of the FinanceCase records attached to this invoice — how much a financier has funded against it — and is refreshed whenever those finance cases change. It is nonetheless the amount used as the proposed exposure in the credit-limit check when an invoice is created, and it is edit-protected as a system field. | | `GeneralLedgerId` | General Ledger | Lookup → [GeneralLedger](/docs/reference/entities/general-ledger/) | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `GLAmount` | GL Amount | Calculated (calculated) | | Metadata-calculated as TotalLineAmount plus TotalLineTaxAmount. It is not, however, what actually gets posted: when the invoice has lines the journal's receivable leg is built from the sum of the line legs plus their tax, and the header amount field is consulted only for header-only postings. Treat it as a display total that should agree with the posting rather than as the posting input. | | `GLPostingType` | GL Posting Type | PickList | | Selects the control account for the header leg at posting time: unset or 'Credit' posts to Accounts Receivable, 'Cash', 'Bank' and 'Credit Card' post to those account types instead, and any other value falls back to Accounts Receivable. The seeded pick list currently offers only 'Credit', so cash-style invoicing requires adding the other values first. Values: Credit. | | `GSTIN` | GSTIN | Text | | The customer's GST identification number. Its format is checked when an Indian invoice is saved. | | `GSTInvoiceType` | GST Invoice Type | Text | | | | `Id` | Id | Guid | Yes | | | `IgnoredSchemeLineId` | Ignored Scheme Line | Text | | | | `InventoryFulfilmentId` | Inventory Fulfilment | Lookup → [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) | | | | `InvName` | Inv Name (For E-Invoice) | Text | | Derived from the generated document name by dropping the leading series prefix, so INV-13072026-000177 becomes 13072026-000177. | | `InvoiceGroup` | Invoice Group | PickList | | | | `InvoiceNumber` | Invoice Number | Text | | Treat any value here as externally supplied (for example an interface or migration) and never as the authoritative document number. | | `InvoiceReferenceNumber` | Invoice Reference Number | Text | | | | `IsGLPosted` | GL Posted | Boolean | | Set by the posting pipeline to record that a journal now exists for this invoice; it is a system field the platform blocks users from editing. Because postings are append-only, a reversal does not clear it — use the invoice's journals and its open item to judge the current ledger state rather than relying on this flag alone. | | `IsGLPostingApproved` | GL Posting Approved | Boolean | | The real posting gate. The posting action turns it on before building the journal, and the posting engine reverses an existing journal instead of writing one whenever this is false or the record is being deleted. It is also the trigger the business rule watches to move Status to Posted, and it is edit-protected except while a system-driven posting is running. | | `IsILPostingApproved` | Is IL Posting Approved | Calculated (calculated) | | True when every line has been posted to the inventory ledger. The Post Inventory button is hidden once it is true. | | `IsInJobQueue` | In Job Queue | Boolean, unique | | | | `IsKPICalculated` | KPI Calculated | Boolean, unique | | It will stay at its stored value forever and should not be used to infer that anything has been computed. | | `ItemServiceContractId` | Item Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | | | `JobInterfaceQueueId` | Job Queue | Lookup → [InterfaceQueue](/docs/reference/entities/interface-queue/) | | | | `LRDate` | LR Date | DateAndTime | | | | `LRNumber` | LR Number | Text | | | | `ModeOfPayment` | Mode Of Payment | PickList | | Values: Card, Electronic Transfer. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | The invoice's document number, generated on creation from the Invoice document numbering setting. The shipped format is INV, the day, month and year, and a six-digit counter, joined by hyphens. A save that fails consumes no number. | | `OpenAmount` | Open Amount | Calculated (calculated) | | Metadata-calculated as TotalAmount minus AdjustedAmount, so it falls only as PaymentAdjustment rows are applied — not when a Payment is merely tagged to the invoice. This is the field the open-documents lookup filters on (greater than zero means still applicable), and it is a document-level figure kept separately from the OpenTransaction open item the ledger actually settles. | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | The sales order this invoice was released from, empty for an invoice created by hand. It cannot be changed once saved, and an invoice created from an order keeps the order's account, partner account and branch. | | `OutstandingAmount` | Outstanding Amount | Calculated (calculated) | | Metadata-calculated as TotalAmount minus AmountPaid — a second, different measure of what is unpaid from OpenAmount, which nets adjustments instead of payments. The two disagree whenever payments and adjustments are not in step. The overdue-receivables insight signal reads this field together with DueDate. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The owning company or dealer entity, not the customer. It scopes account resolution and posting rules, and posting is skipped altogether unless this account has GL posting enabled. It cannot be changed after creation, and when the invoice came from an order it also cannot be edited away from the order's value. | | `PartnerAccountName` | Partner Account Name | Text | | | | `PaymentTerms` | Payment Terms | Text | | The agreed payment terms, as free text. | | `PendingDeliveryQuantity` | Pending Delivery Quantity | Calculated (calculated) | | The total quantity on the lines still waiting for a delivery order. The shipped layout shows Delivery, Post General Ledger, Post Inventory, Apply Scheme and Create Shipment only while this is above zero and the invoice is Draft. | | `PerformGLPosting` | Perform GL Posting | Boolean | | | | `PerformKPICalculation` | Perform KPI Calculation | Boolean, unique | | | | `PlaceOfSupply` | Place of Supply | PickList | | The state the goods or services are supplied to, used to decide the tax supply type. Values: Maharashtra, Gujarat, Rajasthan, Haryana. | | `PorterContactNumber` | Porter Contact Number | Text | | | | `PriceAsOnDate` | Price As On Date | Date | | The date for which prices are read from the price list. | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | The price list line prices are read from. Read-only on the saved invoice. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remark` | Remarks | Text | | Free-text notes on the invoice. | | `RepairOrderServiceOrderId` | Repair Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | The repair order this service invoice bills. When filled, a posted invoice prints with Print Service Invoice instead of Print Invoice. | | `RNAExternalId` | RNA External ID | Text | | | | `RoundOff` | Round Off | Currency | | Declared and defaulted to zero, but no code path computes or applies it: the rounding service that would populate it is only referenced in a comment in the invoice handler. It does not participate in any calculated total and is not posted, so a value here has no effect on the document or the ledger. | | `SalesExecutiveResourceId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | The sales executive responsible for the invoice. Only active resources can be chosen; the shipped New Invoice form requires it. | | `ServiceContractItemId` | Service Contract Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ServiceResourceId` | Service Advisor | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `ServiceTypeId` | Service Type | Lookup → [ServiceType](/docs/reference/entities/service-type/) | | | | `ShippingAddress` | Shipping Address | Text | | | | `ShippingCity` | Shipping City | PickList | | Values: Mumbai, Pune, Chandigarh. | | `ShippingCityPlaceId` | Shipping City | Lookup → [Place](/docs/reference/entities/place/) | | Values: Pune, Mumbai, Chandigarh. | | `ShippingContactAddressId` | Shipping Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `ShippingCountry` | Shipping Country | PickList | | Values: India. | | `ShippingPostalCode` | Shipping Postal Code | Text | | | | `ShippingRegion` | Shipping Region | Text | | | | `ShippingState` | Shipping State | PickList | | Values: Haryana, Maharashtra, New Delhi, Punjab. | | `ShippingStreet` | Shipping Street | Text | | | | `SkipScheme` | Skip Scheme | Boolean, unique | | When on, trade schemes are not applied to this invoice. | | `SourceOfSupply` | Source of Supply | PickList | | The state the goods or services are supplied from, used to decide the tax supply type. Values: Haryana, Rajasthan, Gujarat, Maharashtra. | | `Status` | Status | PickList | | Draft, Posted or Cancelled. It starts as Draft. Shipped business rules set it to Posted when the invoice is approved for ledger posting and to Cancelled when any line has a cancelled quantity, which is what the Cancel action does. A manual change that disagrees with the posting state shows the message Invoice Status Not Editable. Values: Draft, Posted, Cancelled. | | `SubscriptionId` | Subscription | Lookup → [Subscription](/docs/reference/entities/subscription/) | | | | `SupplierBranchId` | Supplier Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch the goods are supplied from. A shipment can only be created from the invoice when this is filled, in organizations that use branches. | | `SupplierPartnerAccountId` | Supplier Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Tax1` | Tax1 | Currency | | | | `Tax1Name` | Tax Name 1 | Text | | | | `Tax1Rate` | Tax Rate 1 | Currency | | | | `Tax1Type` | Tax Type 1 | Text | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `TaxId` | Tax | Lookup → [Tax](/docs/reference/entities/tax/) | | | | `TaxSupplyType` | Tax Supply Type | PickList | | Whether the supply is Within State, Outside State or Exempt. For Indian invoices it is derived from the supply locations when the invoice is saved and decides whether CGST and SGST or IGST apply. Values: Within State, Outside State, Exempt. | | `TCSEligibleAmount` | TCS Eligible Amount | Currency | | The base the header-level tax group is applied to. It does not drive the line-level tax-collected-at-source posting, which keys off the collection section tagged on individual lines. | | `TotalAmount` | Total Amount | Calculated (calculated) | | Metadata-calculated as the sum of InvoiceLine.GrossAmount, so it is tax-inclusive and is the base for both OpenAmount and OutstandingAmount. It shares its formula exactly with TotalLineGrossAmount on this same entity, so the two always hold the same number. | | `TotalAmountInWords` | Total Amount In Words | Text | | Regenerated from the document total after a save, but only for updates — the refresh runs in the post-save step for modified records only, so a freshly created invoice has no words until it is edited once. Do not rely on it being present on a newly inserted record. | | `TotalDiscountAmount` | Total Discount Amount | Calculated (calculated) | | Metadata-calculated as the sum of InvoiceLine.NetDiscount, which already collapses the ordinary, secondary and contract discount pairs on each line. It deliberately excludes scheme discount, which rolls up separately into TotalSchemeDiscountAmount2. | | `TotalInvoiceValue` | Total Invoice Value | Calculated (calculated) | | | | `TotalLineAmount` | Total Line Amount | Calculated (calculated) | | Metadata-calculated as the sum of InvoiceLine.Amount — the net-of-discount, pre-tax value of the lines. Together with TotalLineTaxAmount it forms GLAmount. | | `TotalLineBaseAmount` | Total Line Base Amount | Calculated (calculated) | | | | `TotalLineGrossAmount` | Total Line Gross Amount | Calculated (calculated) | | | | `TotalLineQuantity` | Total Line Quantity | Calculated (calculated) | | | | `TotalLineTaxAmount` | Total Line Tax Amount | Calculated (calculated) | | Metadata-calculated as the sum of InvoiceLine.TaxAmount, which is itself the total of all six tax slots on each line. This is the whole tax on the document, unlike TotalTaxAmount and its siblings which each roll up a single component slot. | | `TotalSchemeDiscountAmount2` | Total Scheme Amount | Calculated (calculated) | | Metadata-calculated as the sum of InvoiceLine.NetSchemeDiscount — the promotional-scheme discount only, kept apart from TotalDiscountAmount. | | `TotalStateCESSValue` | Total State CESS Value | Calculated (calculated) | | | | `TotalTaxAmount` | Total Tax Amount 1 | Calculated (calculated) | | Not the grand total of tax: it is metadata-calculated as the sum of the line-level Tax1 slot only. Which tax component lands in slot 1 depends on the tax group configuration, so this is a per-component subtotal (commonly CGST or IGST). For all tax on the document use TotalLineTaxAmount. | | `TotalTaxAmount2` | Total Tax Amount 2 | Calculated (calculated) | | Metadata-calculated as the sum of the line-level Tax2 slot — the second tax component of the line's tax group, commonly SGST. It is a per-component subtotal, not a running total that includes TotalTaxAmount. | | `TotalTaxAmount3` | Total Tax Amount 3 | Calculated (calculated) | | | | `TransactionType` | Transaction Type | PickList | | Claim Settlement for invoices raised by trade-claim settlement. | | `TransportDocumentDate` | Transport Document Date | DateAndTime | | | | `TransportDocumentNumber` | Transport Document No. | Text | | | | `TransporterGSTIN` | Transporter GSTIN | Text | | | | `TransporterName` | Transporter Name | Text | | | | `TransportMode` | Transport Mode | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VehicleNumber` | Vehicle Number | Text | | | | `VisitId` | Visit | Lookup → [Visit](/docs/reference/entities/visit/) | | | | `VisitPlanId` | Visit Plan | Lookup → [VisitPlan](/docs/reference/entities/visit-plan/) | | | | `VisitRouteId` | Visit Route | Lookup → [VisitRoute](/docs/reference/entities/visit-route/) | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `ApplyPackageConfiguration` | Apply Package Configuration | ServerAction (`ApplyPackageConfiguration`) | Writes the chosen package makeup onto the invoice: for the given LineId and components array it updates the quantity of child invoice lines that already exist for a component and creates new child lines (linked back through the package line reference) for newly selected ones. Both LineId and a non-empty components array are required. | | `ApplyScheme` | Apply Scheme | ServerAction (`ApplyScheme`) | ApplyScheme | | `BulkDelete` | Delete | Delete | Delete the selected records. | | `CancelInvoice` | Cancel | ServerAction (`CancelInvoice`) | Cancel the invoice and reverse its inventory and journal postings. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `CreateShipment` | Create Shipment | ServerAction (`CreateShipment`) | CreateShipment | | `Delete` | Delete | Delete | Delete | | `DeleteRow` | Delete | Delete | Delete List Row | | `Edit` | Edit | Edit | Edit List Row | | `EditDetail` | Edit | EditInline | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `EditInList` | Edit | EditInline | Edit | | `EInvoiceGenerator` | E Invoice Generator | ServerAction (`EInvoiceGenerator`) | Builds the IRP e-invoice payload from the invoice and its lines and stages it on the record, setting the payload field and moving the e-invoice status to Pending; the bound integration flow then transmits it and records the IRN, acknowledgement number and QR code back. The action refuses to run when the invoice already carries an IRN, so it cannot be used to regenerate. | | `EInvoiceGenerator (dup-84993847)` | E Invoice Generator | ServerAction (`EInvoiceGenerator`) | A duplicate of the EInvoiceGenerator row whose name was suffixed to resolve a clash. | | `EWayBill` | E Way Bill | ServerAction (`EWayBill`) | Creates a Draft EWayBill register entry (the Part-A consignment record) for this invoice and returns its id; the bound integration flow generates the actual e-way bill number and records it. Optional arguments are distanceKm, transportMode (defaulting to Road) and vehicleNumber. | | `GetBenefitDetails` | Get Benefit Details | ServerAction (`GetBenefitDetails`) | GetBenefitDetails | | `GetConfigurableItems` | Get Configurable Items | ServerAction (`GetConfigurableItems`) | Read-only. Returns the invoice's lines whose item is flagged as a package, with the item and SKU identification needed by the package-configuration UI. It returns nothing for an invoice with no package lines. | | `GetOpenDocuments` | Get Open Documents | ServerAction (`GetOpenDocuments`) | Read-only lookup that feeds the payment-application screen. Scoped by the invoice's company, branch and customer, it returns open Orders, Invoices and CreditNotes together with unapplied Payments of the opposite direction (open amount above zero). It requires AccountId to be set and writes nothing. | | `GetPackageConfiguration` | Get Package Configuration | ServerAction (`GetPackageConfiguration`) | Read-only. For one package line (LineId is required) it returns the applicable components for the sale channel and customer, each with the quantity already configured on existing child lines and a price resolved against the invoice's price list. Returns nothing when the line's item is not a package. | | `GetPaymentAmountSummary` | Get Payment AmountSummary | ServerAction (`GetPaymentAmountSummary`) | Read-only. Returns the invoice's total, the amount already adjusted, the remaining open amount, and the Payment and PaymentAdjustment rows tagged to this invoice. It reads the invoice's own stored fields rather than the OpenTransaction subledger, so its figures can diverge from an ageing report or party statement. | | `GetQualifiedBenefits` | Get Qualified Benefits | ServerAction (`GetQualifiedBenefits`) | GetQualifiedBenefits | | `GetQualifiedSchemeSlabs` | Get Qualified Scheme Slabs | ServerAction (`GetQualifiedSchemeSlabs`) | GetQualifiedSchemeSlabs | | `GetSchemeRecommendations` | Get Scheme Recommendations | ServerAction (`GetSchemeRecommendations`) | GetSchemeRecommendations | | `New` | New | New | New | | `Payment` | Payment | ServerAction | Recording a receipt against the invoice means creating a Payment record tagged with this invoice. | | `PerformDelivery` | Perform Delivery | ServerAction (`PerformDelivery`) | Creates a DeliveryOrder from this invoice, taking only the lines whose pending delivery quantity is above zero. Validation refuses the call when the invoice has no lines or nothing is left pending on any of them. | | `PerformInventoryPosting` | Post Inventory | ServerAction (`PerformInventoryPosting`) | It touches stock only — the general ledger is untouched, and cost of goods sold is recognised separately by the perpetual costing hook at goods issue. | | `PostAdjustments` | Post Adjustments | ServerAction (`PostAdjustments`), inactive | Applying money to an invoice is done by creating Payment and PaymentAdjustment rows, which is what maintains AdjustedAmount and OpenAmount. | | `PostGeneralLedger` | Post General Ledger | ServerAction (`PostGeneralLedger`) | Sets IsGLPostingApproved and runs document-journal posting: one balanced journal, Dr Accounts Receivable against Cr Sales plus output tax, together with a Receivable open item that becomes the AR subledger row. Re-posting is reverse-then-repost — the earlier journal flips to Reversed and a suffixed replacement is written, nothing is edited in place. It then captures output-GST TaxTransaction rows for the return analytics (best effort, a failure there never blocks the ledger) and posts TCS for any line carrying a collection section (not best effort — a TCS failure rolls the whole posting back). Status moving to Posted is done by a business rule reacting to the approval flag, not by this action. | | `Preview` | Preview | Preview | Preview Entity details | | `PreviewListHeader` | Preview | Preview | PreviewListHeader | | `PrintInvoice` | Print Invoice | Print (`PrintInvoice`) | Print Invoice | | `PrintServiceInvoice` | Print Service Invoice | Print | Service Order Print | | `PrintTest` | Print Test | Print | Test | | `ProductConfigurator` | Product Configurator | ServerAction (`ProductConfigurator`) | The working configuration flow on this entity is GetConfigurableItems, then GetPackageConfiguration, then ApplyPackageConfiguration. | | `Release` | Release | UIAction, inactive | An inactive action of UI type with no server handler behind it. Turning an order into an invoice is driven from the Order side instead, by its PerformReleaseInvoice, PerformReleaseInvoiceAllocatedLines or SelectiveInvoiceOTC actions. | | `SelectiveCreateShipment` | Selective Create Shipment | ServerAction (`SelectiveCreateShipment`) | SelectiveCreateShipment | | `SetEInvoiceStatus` | Set E-Invoice Status | ServerAction (`SetEInvoiceStatus`) | SetEInvoiceStatus | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Contact for Account | `ContactId` | | | Customer Account Filter | `AccountId` | | | Executive Filter | `SalesExecutiveResourceId` | | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `SupplierPartnerAccountId` - [Subscription](/docs/reference/entities/subscription/) — looks up via `SubscriptionId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Visit](/docs/reference/entities/visit/) — looks up via `VisitId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [DiscountGroup](/docs/reference/entities/discount-group/) — looks up via `DiscountGroupId` - [VisitRoute](/docs/reference/entities/visit-route/) — looks up via `VisitRouteId` - [Resource](/docs/reference/entities/resource/) — looks up via `SalesExecutiveResourceId` - [InterfaceQueue](/docs/reference/entities/interface-queue/) — looks up via `JobInterfaceQueueId` - [ClaimBatch](/docs/reference/entities/claim-batch/) — looks up via `ClaimBatchId` - [Tax](/docs/reference/entities/tax/) — looks up via `TaxId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [ServiceType](/docs/reference/entities/service-type/) — looks up via `ServiceTypeId` - [Contact](/docs/reference/entities/contact/) — looks up via `ContactId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — looks up via `GeneralLedgerId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `RepairOrderServiceOrderId` - [Place](/docs/reference/entities/place/) — looks up via `BillingCityPlaceId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — looks up via `InventoryFulfilmentId` - [Branch](/docs/reference/entities/branch/) — looks up via `SupplierBranchId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — looks up via `DeliveryOrderId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [Resource](/docs/reference/entities/resource/) — looks up via `ExecutiveResourceId` - [Item](/docs/reference/entities/item/) — looks up via `ServiceContractItemId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Resource](/docs/reference/entities/resource/) — looks up via `ServiceResourceId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `ShippingContactAddressId` - [VisitPlan](/docs/reference/entities/visit-plan/) — looks up via `VisitPlanId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [Claim](/docs/reference/entities/claim/) — looks up via `ClaimId` - [Place](/docs/reference/entities/place/) — looks up via `ShippingCityPlaceId` - [FieldSales](/docs/reference/entities/field-sales/) — looks up via `FieldSalesId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `BillingContactAddressId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `InvoiceId` - [EInvoice](/docs/reference/entities/einvoice/) — referenced by via `InvoiceId` - [Asset](/docs/reference/entities/asset/) — referenced by via `InvoiceId` - [Payment](/docs/reference/entities/payment/) — referenced by via `InvoiceId` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — referenced by via `RechargeInvoiceId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `InvoiceId` - [SchemeAccountBudgetUtilization](/docs/reference/entities/scheme-account-budget-utilization/) — referenced by via `InvoiceId` - [InterestCharge](/docs/reference/entities/interest-charge/) — referenced by via `SourceRecordId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ParentRecordId` - [SubscriptionUsageSummary](/docs/reference/entities/subscription-usage-summary/) — referenced by via `InvoiceId` - [Visit](/docs/reference/entities/visit/) — referenced by via `InvoiceId` - [PaymentAdjustment](/docs/reference/entities/payment-adjustment/) — referenced by via `InvoiceId` - [Claim](/docs/reference/entities/claim/) — referenced by via `InvoiceId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `InvoiceId` - [FinanceCase](/docs/reference/entities/finance-case/) — referenced by via `InvoiceId` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — referenced by via `InvoiceId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `InvoiceId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `InvoiceId` - [Shipment](/docs/reference/entities/shipment/) — referenced by via `InvoiceId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # ITC Ledger — entity reference URL: https://xmatix.com/docs/reference/entities/itcledger/ Last reviewed: 2026-08-16 Input Tax Credit ledger for Indian GST: one entry per ITC event for a GSTIN and tax period, split into CGST, SGST, IGST and cess. ItcManagementService posts Availed and Blocked entries from the period's input TaxTransaction rows grouped by ITC category — it deletes and re-creates the period's Availed/Blocked entries on each run, so availment is idempotent per period — and adds negative-signed Reversed entries for the Rule 42/43 and Rule 37 reversals. Net ITC available for a period is every entry summed except Blocked ones, which are excluded outright; the same rows, grouped by supplier GSTIN, are what GSTR-2B reconciliation compares against the downloaded statement. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Category` | Category | Text | | Which head the credit falls under — inputs, input services, capital goods, or IGST paid on imports. Availment groups the period's input tax transactions by this category (together with eligibility) and writes one ledger entry per group, so it determines how many rows a period produces. | | `Cess` | Cess | Currency | | | | `CGST` | CGST | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `EntryDate` | Entry Date | Date | | | | `EntryType` | Entry Type | Text | | What kind of ITC event the row records: availed, blocked, reversed or re-availed. It governs the arithmetic — blocked entries are excluded from available credit entirely rather than subtracted, while reversal entries carry negative tax amounts and so reduce it. Availed and blocked entries for a period are deleted and rebuilt whenever availment is re-run; reversal entries are not. | | `GSTRegistrationId` | GST Registration | Lookup → [GSTRegistration](/docs/reference/entities/gstregistration/) | | | | `Id` | Id | Guid | Yes | | | `IGST` | IGST | Currency | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | GL Account Name | Text, unique | Yes | | | `Narration` | Narration | Text | | Human-readable reason written by the posting service — the ITC category for availed entries, a blocked-credit note for Section 17(5) entries, or the computed exempt ratio for a proportional reversal. It is the quickest way to see why a reversal is the size it is. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `ReconciliationStatus` | Reconciliation Status | Text | | Outcome of comparing this credit against the downloaded GSTR-2B: matched, an amount mismatch, present in the books but missing from GSTR-2B, or present in GSTR-2B but missing from the books. The reconciliation routine computes these per supplier GSTIN and returns them; nothing writes the result back onto the ledger rows automatically. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReversalRule` | Reversal Rule | Text | | Which statutory rule forced a reversal, meaningful only on reversed entries: Rule 37 for non-payment to the supplier beyond 180 days, Rules 42 and 43 for the proportional exempt and non-business share of common and capital-goods credit, and Section 17(5) for blocked credit. No picklist is seeded, so it is written as free text by the posting service. | | `SGST` | SGST | Currency | | | | `SourceEntityName` | Source Entity Name | Text | | Names the entity of the bill or document the credit came from, paired with SourceRecordId as a loose polymorphic link rather than a real foreign key. The service that posts availment entries does not populate it, so it is filled only by callers that set it deliberately. | | `SourceRecordId` | Source Record | Guid | | | | `SupplierGstin` | Supplier Gstin | Text | | The supplier's GST registration number, which is the key GSTR-2B reconciliation groups on. Entries without it are bucketed as unknown and will always appear as a mismatch, so it matters more than its optional-looking definition suggests. | | `TaxPeriodMonth` | Tax Period Month | Number | | The month of the return period the credit belongs to, stored as a number alongside the year rather than as a date. It is the grouping key for availment, netting and reconciliation, and is independent of the source document's own date. | | `TaxPeriodYear` | Tax Period Year | Number | | The calendar year of the return period, paired with the month. Note it is the calendar year of the period, not the Indian fiscal year, so an April-to-March fiscal year spans two values here. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GSTRegistration](/docs/reference/entities/gstregistration/) — looks up via `GSTRegistrationId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Alias — entity reference URL: https://xmatix.com/docs/reference/entities/item-alias/ Last reviewed: 2026-08-16 An alternative identity for an item, optionally narrowed to a SKU and a lot type, that can be selected on a document line instead of the item itself (OrderLine, InvoiceLine, DeliveryOrderLine, PurchaseOrderLine and OpportunityLine all carry an ItemAliasId). When a line is saved, ItemAliasService.SetItemAliasData back-fills the line's item, SKU and lot type from the alias wherever the line left them empty, and rejects the line if the item or SKU already on it contradicts the alias. The alias is matched purely by the id chosen on the line - the account and partner-account columns on the alias are not used to filter which aliases a document may pick. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ItemAliasCode` | Item Alias Code | Text | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | The item the alias stands for. On save of a document line the alias fills this in when the line has none, and the line is rejected if it already names a different item. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | PartnerAccount | Lookup → [Account](/docs/reference/entities/account/) | | Intended to scope the alias to a supplier or partner, but no code path filters aliases by it - any alias can be selected on any document, and the customer account column behaves the same way. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | Optionally narrows the alias to one SKU. It is copied onto a document line that has no SKU, and a line naming a different SKU is rejected; the lot type is copied the same way but a conflicting lot type is not rejected. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | UIAction | Edit | | `EditInLine` | Edit | Edit | Delete in page. | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `ItemAliasId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `ItemAliasId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `ItemAliasId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `ItemAliasId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `ItemAliasId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Alternate — entity reference URL: https://xmatix.com/docs/reference/entities/item-alternate/ Last reviewed: 2026-08-16 A directed substitution from one item to another, optionally effective-dated, used both automatically and as a suggestion. ItemAlternateService.SetAlternateItem runs on order, invoice, purchase-order and service-order lines: if the line explicitly names the alternate it swaps the line onto the alternate item and records the original in originalItemId, and independently it force-swaps any line whose item has an alternate of type Superseded that is currently within its effective window. The Sense alternate-item signal provider separately suggests alternates for short-stocked lines, ranking by the quantityAvailable held on the alternate row itself. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AlternateItemId` | Alternate Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `AlternateItemName` | AlternateItemName | LongMultiLineText | | A stored display name for the alternate, preferred over the alternate item's own label when a suggestion is worded; it is not kept in step with the alternate item automatically. | | `AlternateType` | Alternate Type | PickList | | Decides whether the substitution is automatic: only the exact value 'Superseded' makes the save pipeline swap a document line onto the alternate item. The Sense alternate-item nudge additionally singles out the value 'Refurbished', which is not one of the seeded picklist values. Values: Superseded, Optional/Interchangeable. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EffectiveFromDate` | Effective From Date | Date | | Start of the window in which a superseded alternate is auto-applied to document lines; an empty value means the alternate is effective from the outset. | | `EffectiveTillDate` | Effective Till Date | Date | | A second end-of-window column kept for compatibility: automatic substitution falls back to it only when the effective-to date is empty, and the alternate-suggestion nudge ignores it entirely. Prefer the effective-to date. | | `EffectiveToDate` | EffectiveToDate | DateAndTime | | End of the alternate's effective window; empty means open-ended. This is the field the alternate-suggestion nudge filters on. | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `QuantityAvailable` | Available | Decimal (calculated) | | A denormalized availability figure held on the substitution row, used to decide and rank which alternate to suggest for a short-stocked line. No code path writes or refreshes it, so it has to be maintained by import or by hand. | | `QuantityInHand` | In Hand | Decimal (calculated) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit in line | | `EditInList` | Edit | EditInline | Edit in List Header | | `New` | New | New | New | ## Related entities - [Item](/docs/reference/entities/item/) — looks up via `AlternateItemId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `ItemAlternateId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `AlternateItemId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `ItemAlternateId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `ItemAlternateId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `AlternateItemId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Cart — entity reference URL: https://xmatix.com/docs/reference/entities/item-cart/ Last reviewed: 2026-08-16 A staging basket row that parks an item, SKU, lot type, account and quantity against an Order before it becomes an order line. Treat it as reserved scaffolding rather than a source of order demand; actual demand lives on OrderLine. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Quantity` | Quantity | Decimal | Yes | Quantity staged for the item or SKU on this basket row. It is not a source of order demand — no code path in the platform converts it into an OrderLine or into any pending-quantity counter. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Component — entity reference URL: https://xmatix.com/docs/reference/entities/item-component/ Last reviewed: 2026-08-16 One line of a package/bill-of-materials definition: it attaches a component item (and optionally a component SKU) to a parent item, with a quantity, min/max bounds and selection rules. PackageHelper explodes these rows into child document lines when a line is created for a parent item flagged isPackage - on orders, invoices, quotes, opportunities, purchase orders and requisitions - stamping itemComponentId and the package parent-line id on each child. Only components whose featureType is exactly 'Product Configurator' are ever exploded or offered by the configurator, so components carrying the other feature types are configuration-only. Component rows also police their children afterwards: min/max quantity, mandatory-with-zero-quantity, non-editable quantity and deletion of a mandatory component are all rejected. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApplicableFor` | Applicable For | PickList | | Restricts the component to sales, purchase or service documents - an empty value applies everywhere, and each explosion path filters on its own context. All three seeded picklist values are inactive, so nothing is selectable until a tenant activates them. | | `ComponentItemId` | Component Item | Lookup → [Item](/docs/reference/entities/item/) | | The item placed on the generated child line - the component being consumed. The item on the row's own item reference is the package parent, not the component. | | `ComponentSKUId` | Component SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | Text | | | | `FeatureType` | Feature Type | PickList | | Acts as a hard filter rather than a label: only components whose value is exactly 'Product Configurator' are exploded into document lines or returned by the package-configuration action. Components typed as standard or optional package are stored but never auto-added. Values: Standard Package, Optional Package, Product Configurator. | | `Id` | Id | Guid | Yes | | | `IsBundled` | Is Bundled | Boolean | | Copied to the generated child line as its price-bundled flag, meaning the component's value is carried in the package price rather than charged separately on the child line. | | `IsMandatory` | Is Mandatory | Boolean | | Forces the component into every explosion of the package regardless of selection, requires a quantity greater than zero on the child line, and blocks deletion of that child line. | | `IsQuantityEditable` | Is Quantity Editable | Boolean | | When not set, any change to the generated child line's quantity is rejected, so the component ships at its configured quantity. | | `IsSelected` | Is Selected | Boolean | | Marks an optional component as selected by default, which is what gets it included in an automatic explosion; mandatory components are included whether or not this is set. | | `ItemFeatureId` | Product Packages | Lookup → [ItemFeature](/docs/reference/entities/item-feature/) | | Groups the component under an option group of the parent item; the group's name travels with the component in the configuration payload but imposes no selection limits. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `MaxQuantity` | Max Quantity | Number | | Upper bound enforced on the generated child line's quantity, with the minimum-quantity column enforcing the lower bound the same way; on either field a value of zero or below is treated as no bound at all. | | `MinQuantity` | Min Quantity | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Component Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PackageType` | Package Type | PickList | | Decides how the component quantity scales: the exact value 'Multiple Of Package' multiplies the component quantity by the parent line's quantity and keeps it in step when the parent changes, while anything else uses the component quantity as-is. Values: Multiple Of Package, Independent Of Package. | | `PartnerAccountGroupId` | Partner Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Quantity` | Quantity | Number | | The component quantity per package, used as the default on the generated child line - multiplied by the parent line quantity when the package type multiplies, otherwise taken literally. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SKUId` | Item SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | Narrows the component to one SKU of the PARENT item: when the document line names a SKU, only components matching it or carrying no SKU are exploded. The component's own SKU is a separate field. | | `SortOrder` | Sort Order | Number | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Quantity Rule Validation | `Quantity`, Error | Quantity cannot be 0 or negative. | Quantity Rule Validation | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Component SKU | `ComponentSKUId` | | ## Related entities - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `PartnerAccountGroupId` - [Item](/docs/reference/entities/item/) — looks up via `ComponentItemId` - [ItemFeature](/docs/reference/entities/item-feature/) — looks up via `ItemFeatureId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [SKU](/docs/reference/entities/sku/) — looks up via `ComponentSKUId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `ItemComponentId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `ItemComponentId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `ItemComponentId` - [RequisitionLine](/docs/reference/entities/requisition-line/) — referenced by via `ItemComponentId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `ItemComponentId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `ItemComponentId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `ItemComponentId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `ItemComponentId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Consumption Rate — entity reference URL: https://xmatix.com/docs/reference/entities/item-consumption-rate/ Last reviewed: 2026-08-16 One tier of a consumption schedule: a lower and upper consumption bound plus the price that applies inside that band. Subscription usage invoicing walks the tiers in ascending lower-bound order, consuming the usage quantity band by band, charging the tier price once when the tier's pricing method is 'Flat Fee' and price times quantity otherwise, and falling back to the subscription's unit price for any quantity left over past the last tier. The pricing-method field has no seeded picklist, so the exact string 'Flat Fee' has to be typed for flat-fee behaviour. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Description` | Description | Text | | | | `Id` | Id | Guid | Yes | | | `ItemConsumptionScheduleId` | Item Consumption Schedule | Lookup → [ItemConsumptionSchedule](/docs/reference/entities/item-consumption-schedule/) | | | | `LowerBound` | Lower Bound | Number | | Start of the consumption band, and the ascending key the tiers are walked in when usage is priced; the first tier normally starts at zero. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Price` | Price | Decimal | | The tier's charge: added once for the whole tier when the pricing method is flat fee, otherwise multiplied by the quantity that falls inside the band. It is stored to seven decimal places for fine-grained metered rates. | | `PricingMethod` | Pricing Method | PickList | | Only the exact string 'Flat Fee' makes the tier charge its price once for the band; every other value - including empty - charges price times quantity. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `UpperBound` | Upper Bound | Number | | Inclusive end of the consumption band - the band's width is upper minus lower plus one. Leaving it empty makes the tier absorb all remaining usage. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [ItemConsumptionSchedule](/docs/reference/entities/item-consumption-schedule/) — looks up via `ItemConsumptionScheduleId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Consumption Schedule — entity reference URL: https://xmatix.com/docs/reference/entities/item-consumption-schedule/ Last reviewed: 2026-08-16 A tiered usage price book for an item, holding the ItemConsumptionRate tiers that price metered consumption on subscriptions. Subscription usage invoicing looks the schedule up by item only: all schedules for the item are ordered active-first then most-recently-updated, and their tiers are flattened together into one ascending ladder. Its customer account, customer account group, partner account, partner account group, billing term, billing term unit and unit-of-measure columns are stored but take no part in that lookup, and the usage-invoice generator itself is not yet wired to any scheduler. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BillingTerm` | Billing Term | Number | | | | `BillingTermUnit` | Billing Term Unit | PickList | | The unit the billing term is counted in. It has no seeded picklist and, like the billing term itself, is read by no code path - it does not affect usage pricing or when the usage invoice is raised. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `CustomerAccountGroupId` | Customer Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `CustomerAccountId` | Customer Account | Lookup → [Account](/docs/reference/entities/account/) | | Intended to scope the schedule to one customer, but usage pricing looks schedules up by item alone, so a customer-specific schedule is applied to every customer of that item. | | `Description` | Description | Text | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | Used as a ranking key rather than a filter: when an item has several schedules, active ones sort first (then most recently updated), but the tiers of the inactive ones are still flattened into the same ladder. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountGroupId` | Partner Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UnitOfMeasure` | Unit Of Measure | PickList | | Names the unit the consumption bounds are expressed in. It is documentation only - no conversion is applied between it and the usage quantity being priced. | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `CustomerAccountGroupId` - [Account](/docs/reference/entities/account/) — looks up via `CustomerAccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `PartnerAccountGroupId` - [ItemConsumptionRate](/docs/reference/entities/item-consumption-rate/) — referenced by via `ItemConsumptionScheduleId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Feature — entity reference URL: https://xmatix.com/docs/reference/entities/item-feature/ Last reviewed: 2026-08-16 A named option group under an item that ItemComponent rows point at, so a configurable product's components can be presented in labelled sets. It is presentation metadata only: the package-configuration payload carries the feature's name and id alongside each component, and nothing else on the server reads it. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | ExternalId | | | | `FeatureGroup` | Feature Group | Text | | A free-text second level of grouping above the option group; it is stored only and read by no code path. | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `MaxComponentCount` | Max Components | Number | | Intended maximum number of components selectable from this option group; no code path enforces it. | | `MinComponentCount` | Min Components | Number | | Intended minimum number of components a buyer must pick from this option group, but no code path enforces it during configuration or line explosion. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountGroupId` | Partner Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RelatedItemId` | Related Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ShowInCatalog` | Show in Catalog | Boolean | | Intended to control catalogue visibility of the option group, but no server-side code path filters on it. | | `SortOrder` | Sort Order | Number | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInList` | Edit | Edit | Edit in page. | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Maximum Quantity Rule Validation | `MaxComponentCount`, Error | Maximum Quantity cannot be Negative!! | Validates that when a maximum component count is specified, it must be greater than zero. The rule triggers an error if MaxComponentCount has a value but that value is zero or negative. | | Minimum Quantity Rule Validation | `MinComponentCount`, Error | Minimum Quantity cannot be Negative!! | Validates that when a minimumcomponent count is specified, it must be greater than zero. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Item](/docs/reference/entities/item/) — looks up via `RelatedItemId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `PartnerAccountGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [ItemComponent](/docs/reference/entities/item-component/) — referenced by via `ItemFeatureId` - [SubscriptionUsage](/docs/reference/entities/subscription-usage/) — referenced by via `ItemFeatureId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Group Member — entity reference URL: https://xmatix.com/docs/reference/entities/item-group-member/ Last reviewed: 2026-08-16 The junction row that places an item (optionally narrowed to a SKU and a lot type) in an item group; it is what every group-scoped engine actually joins against. Rows created by the ProcessMembers rule run carry the run's batchInstanceId and a uniqueKey of the form groupId_itemId, and the same run soft-deletes members left behind by a previous run of that group. Its handler validates on insert that the item exists, is active, has a SKU when the item requires one, and that the SKU belongs to the item. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BatchInstanceId` | Batch Instance | Text | | Stamps the member with the identifier of the rule run that created it. The next run of the same group stamps a new value and soft-deletes every member carrying an older one, which is how stale members are swept; hand-added members with no value are left alone. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | Set on members produced by a rule run, but honoured only by mobile selling-scope resolution - the scheme engine, discount resolution and incentive targets match members regardless of it, so clearing it does not universally remove an item from a group. | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | Optionally narrows the membership to one lot type; it is carried through to the consumers that resolve group membership per lot type. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | Optionally narrows the membership to one SKU of the item; consumers that care read it alongside the item, and the handler requires it when the item is marked as requiring a SKU. | | `UIProps` | UI Props | Text | | | | `UniqueKey` | Unique Key | Text | | A composite written by the rule run as the group id and item id joined by an underscore, used to recognise the same pairing across runs. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete Selected | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Delete in page. | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | NewInline | New | | `UIAction` | UI Action | UIAction | UI Action | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Sku For Item | `SKUId` | Sku For Item | ## Related entities - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Group Rule — entity reference URL: https://xmatix.com/docs/reference/entities/item-group-rule/ Last reviewed: 2026-08-16 One clause of an item group's dynamic-membership predicate: a field name, an operator and a comparison value, applied in sequenceNumber order. The shared group-member rule engine translates clauses over real scalar Item columns into a parameterized SQL predicate and evaluates the remainder (custom fields, includes/excludes, custom logic) in memory, combining them according to the parent group's rule success criteria. Rules are only ever evaluated by the group's ProcessMembers action; editing a rule does not re-derive membership on its own. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedBy` | Created By | Lookup | Yes | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FieldName` | Field Name | Text | Yes | Names the property of Item the clause tests. A real scalar column is matched case-insensitively and pushed into SQL as a parameterized predicate; a custom-field name is resolved from the record's custom-field bag and evaluated in memory. A name that matches neither makes the clause pass unconditionally. | | `FieldValue` | Field Value | Text | | The comparison value, always stored as text and coerced to the target column's type. Numeric comparisons are scale-insensitive, so '10000.00' matches a stored 10000; in/notIn split it on commas and includes/excludes on semicolons. | | `Id` | Id | Guid | Yes | | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | Yes | | | `LastModifiedBy` | Last Modified By | Lookup | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Rule Name | Text | | | | `Operation` | Operation | PickList | | The comparison the clause applies. The engine recognises equals, notEqual, lessThan, greaterThan, lessOrEqual, greaterOrEqual, like (contains), in and notIn (comma-separated), and includes/excludes (semicolon-separated, evaluated in memory). Anything unrecognised - including an empty value - falls back to equality, and the seeded picklist is both incomplete (no equals, like, in or includes) and entirely inactive. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SequenceNumber` | Sequence Number | Number | Yes | Ascending evaluation order of the clauses, and the numbering that the group's custom-logic expression refers to - clause one is the lowest sequence number. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete Selected | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Delete in page. | | `New` | New | New | New | | `UIAction` | UI Action | UIAction | UI Action | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Group — entity reference URL: https://xmatix.com/docs/reference/entities/item-group/ Last reviewed: 2026-08-16 A named set of items used to scope pricing, tax, discount, scheme, incentive, cycle-count and mobile-selling rules without listing every item. Membership lives in ItemGroupMember rows, which are either maintained by hand or rebuilt from ItemGroupRule clauses by the ProcessMembers server action; itemGroupType labels the group's purpose so each engine can pick out its own groups. In practice only some consumers actually read an item-group scope - the scheme engine, discount resolution, incentive targets, cycle-count population, inventory-valuation policy, branch time-slot booking and mobile selling scope do - while TaxGroupRule, ComplaintFault, VisitPlan, VisitRoute, KPIConfiguration, GLAccount and PartnerAccountMapping store an item group that no resolver ever consults. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `DynamicMemberType` | Dynamic Member Type | PickList | | Chooses how membership is sourced. The exact value 'Report Data' makes the member-processing action skip the group entirely, because report-sourced membership has no engine yet; any other value (including empty) is treated as rule-driven. | | `Id` | Id | Guid | Yes | | | `ItemGroupType` | Item Group Type | PickList | Yes | Labels what the group is for, and engines select their groups by matching this exact string - notably 'Discount' for discount resolution and 'Scheme' for the scheme engine. A group with the wrong or an empty type is simply never picked up. Values: Complaint, Tax, Discount, Scheme. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReportId` | Report | Text | | Intended to name the report that supplies members when membership is report-sourced. | | `RuleSuccessCriteria` | Rule Success Criteria | PickList | | Combines the group's rules: the engine recognises only the exact strings 'Always (No Criteria)' (every item matches), 'All Rules Are Met', 'Any Rule Is Met' and 'Custom Logic Is Met'. | | `RuleSuccessCustomLogic` | Rule Success Custom Logic | Text | | A boolean expression over rule positions, for example '1 and (2 or 3)', where each number is the one-based position of a rule in sequence order. It is evaluated only when the success criteria is set to custom logic. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Delete in page. | | `EditInList` | Edit | Edit | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `New` | New | New | New | | `ProcessMembers` | ProcessMembers | ServerAction (`ProcessMembers`, async) | ProcessMembers | | `UIAction` | UI Action | UIAction | UI Action | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `ItemGroupId` - [ItemGroupMember](/docs/reference/entities/item-group-member/) — referenced by via `ItemGroupId` - [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) — referenced by via `ItemGroupId` - [CycleCount](/docs/reference/entities/cycle-count/) — referenced by via `ItemGroupId` - [ComplaintFault](/docs/reference/entities/complaint-fault/) — referenced by via `ApplicableToItemGroupId` - [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) — referenced by via `ItemGroupId` - [PostingDefinition](/docs/reference/entities/posting-definition/) — referenced by via `ItemGroupId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — referenced by via `DiscountedItemGroupId` - [InventoryNrvAssessment](/docs/reference/entities/inventory-nrv-assessment/) — referenced by via `ItemGroupId` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `ExcludeItemGroupId` - [VisitPlan](/docs/reference/entities/visit-plan/) — referenced by via `ItemGroupId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `ItemGroupId` - [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) — referenced by via `ApplicableToItemGroupId` - [SchemeConsumption](/docs/reference/entities/scheme-consumption/) — referenced by via `ItemGroupId` - [VisitRoute](/docs/reference/entities/visit-route/) — referenced by via `ItemGroupId` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — referenced by via `ItemGroupId` - [GLAccount](/docs/reference/entities/glaccount/) — referenced by via `ItemGroupId` - [TaxGroupRule](/docs/reference/entities/tax-group-rule/) — referenced by via `ItemGroupId` - [ItemGroupRule](/docs/reference/entities/item-group-rule/) — referenced by via `ItemGroupId` - [InventoryValuationPolicy](/docs/reference/entities/inventory-valuation-policy/) — referenced by via `ItemGroupId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — referenced by via `ExcludeDiscountedItemGroupId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Inventory Attribute — entity reference URL: https://xmatix.com/docs/reference/entities/item-inventory-attribute/ Last reviewed: 2026-08-16 The replenishment and counting policy for an item, optionally narrowed by SKU, lot type, branch and partner account, with a null scope column meaning 'applies to all'. Purchase-order line validation enforces its minimum and maximum order quantities and refuses a quantity that is not a multiple of its lot quantity; the auto-purchase-order engine uses minimum stock level and reorder quantity for min/max replenishment and lead time times average consumption plus minimum order quantity as the forecast reorder point, and honours the ABC/FSN category for the order header's exclusion flags; cycle counts filter their item population on the same two categories. Several of its columns - maximum stock level, reorder level, suggested order quantity and the attribute number - are read by no code path. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ABCCategory` | ABC Category | PickList | | The item's ABC class within this row's partner/branch scope; cycle counts filter their item population on it, treating rows with no partner or branch as wildcards. Values: A Category, B Category, C Category. | | `AverageConsumption` | Average Consumption | Number | | Expected consumption per lead-time day, used together with lead time to derive the forecast reorder point. It is an input you maintain - no code path computes it from history. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Scope of the attribute row: set it for a branch-specific policy or leave it empty to apply across branches - consumers treat null as match-any (partnerAccountId scopes the same way). | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | Text, unique | | | | `FSNCategory` | FSN Category | PickList | | Movement class of the item in this row's scope. Two vocabularies are seeded on the same field - 'Fast-Moving'/'Slow-Moving'/'Non-Moving', which is what auto-purchase-order exclusions compare against, and 'F category'/'S category'/'N category', which is what the cycle-count filter offers - so a value chosen from one set is invisible to the consumer that expects the other. Values: Fast-Moving, Slow-Moving, Non-Moving, F category, S category, N category. | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemInventoryAttributeNumber` | Item Inventory Attribute Number | Number | Yes | A sequence number on the policy row that no code path assigns or reads. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `LeadTime` | Lead Time (In Days) | Number | | Supplier lead time in days. Forecasting multiplies it by average consumption and adds the minimum order quantity to obtain the reorder point; when several attribute rows match an item and SKU their lead times are averaged. | | `LotQuantity` | Lot Quantity | Number | | Purchase pack multiple: a purchase-order line whose quantity is not an exact multiple of it is rejected. Zero or empty means no multiple is enforced. | | `MaximumOrderQuantity` | Maximum Order Quantity | Number | | Supplier maximum for a single purchase-order line, rejected above it; the forecasting mode of the auto-purchase-order engine also uses it as the order-up-to level, ordering the difference between it and projected stock. | | `MaximumStockLevel` | Maximum Stock Level | Number | | Stored but read by no code path; the order-up-to level used by forecasting is the maximum order quantity. | | `MinimumOrderQuantity` | Minimum Order Quantity | Number | | Supplier minimum for a single purchase-order line: a line below it is rejected, and the forecast reorder point adds it on top of lead time times average consumption. | | `MinimumStockLevel` | Minimum Stock Level | Number | | The trigger point for min/max replenishment: the auto-purchase-order engine proposes a line whenever available stock falls below it, and uses it as the shortfall base when no reorder quantity is set. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReorderLevel` | Reorder Level | Number | | Stored but read by no code path - the reorder trigger actually used is the minimum stock level, and the forecast reorder point is computed from lead time, average consumption and minimum order quantity. | | `ReorderQuantity` | Reorder Quantity | Number | | Fixed quantity proposed when min/max replenishment triggers; when it is zero the engine falls back to ordering up to the minimum stock level instead. | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `SuggestedOrderQuantity` | Suggested Order Quantity | Number | | Stored but read by no code path; the suggested quantity on a generated auto-purchase-order line is computed by the engine, not taken from here. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete Selected | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit In Line | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `UIAction` | UI Action | UIAction | UI Action | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Maximum Stock Validation | `MaximumStockLevel`, Error | Maximum Stock Level can't be less than Minimum Stock Level. | Ensures maximum stock level is not less than minimum stock level | | Minimum Stock Validation | `MinimumStockLevel`, Error | Minimum Stock Level should be less than Maximum Stock Level | Ensures minimum stock level does not exceed maximum stock level. | | Order Qty Greater Than Zero Validation | Error | Order quantity should be greater than 0. | Prevents negative values for order quantity fields | | Order Quantity Is Mandatory Validation | Error | Please provide value for at least one: Minimum Order Quantity or Maximum Order Quantity | Requires at least one of minimum or maximum order quantity to be specified | | Order Quantity Rule Validation | `MaximumOrderQuantity`, Error | Maximum Order Quantity cannot be less than Minimum Order Quantity | Ensures maximum order quantity is not less than minimum order quantity | | Order Quantity Validation | `MinimumOrderQuantity`, Error | Minimum Order Quantity can't be negative | Prevents zero or negative minimum order quantity | | Reorder Level Validation | `ReorderLevel`, Error | Reorder Level should be greater than Reorder Quantity | Ensures reorder level is strictly greater than reorder quantity. | | Reorder Quantity Rule Validation | `ReorderQuantity`, Error | Reorder Quantity can't be negative | Prevents zero or negative reorder quantity. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Lot Type — entity reference URL: https://xmatix.com/docs/reference/entities/item-lot-type/ Last reviewed: 2026-08-16 An item-scoped commercial variant or grade of stock - promo, sample or saleable, with optional price and variation codes - carried on nearly every transactional line and copied onto ledger rows and lots as they are created. It is a classification of the goods, not a lot-numbering policy or a lot-tracking setting. It has no server actions beyond the standard record CRUD and no seeded pick-list values; note that although InventoryStock and InventoryLedger both carry an ItemLotTypeId, the posting engine keys stock rows without it. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalItemCode` | External Item Code | Text | | The counterpart system's product code for this variant, used when reconciling with an external catalogue rather than by any internal lookup. | | `Id` | Id | Guid | Yes | | | `IsPromo` | Promo | Boolean | | Marks the variant as promotional stock so it can be priced, discounted and reported separately from ordinary saleable stock of the same item. | | `IsSaleable` | Saleable | Boolean | | Marks this grade of stock as ordinary sellable goods, as opposed to promotional or sample stock. It is a classification flag on the variant; the platform does not use it to block lot selection during invoicing or allocation. | | `IsSample` | Sample | Boolean | | Marks the variant as sample stock, distinguishing giveaway or demonstration quantities from saleable stock of the same item. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | The product this variant belongs to. Variants are always item-scoped - the same grade under two items is two separate records - and this link is what carries the variant through onto transactional lines, lots and ledger rows. | | `LotTypeCode` | Code | Text | | Short internal code for the variant, used to identify it in imports and integrations instead of matching on the display name. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `MRP` | MRP | Number | | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PriceCode` | Price Code | Text | | Short code used to line this variant up with pricing rules; price list and discount group rules can target the variant, so this is the compact key those setups quote. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RelatedItemLotId` | Related Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VariationCode` | Variation Code | Text | | Short code distinguishing this variation of the item from its siblings, for use in integrations and imports where the full record name is impractical. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit In Line | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `UIAction` | UI Action | UIAction | UI Action | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `RelatedItemLotId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `ItemLotTypeId` - [ShipmentAssetLine](/docs/reference/entities/shipment-asset-line/) — referenced by via `ItemLotTypeId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — referenced by via `ItemLotTypeId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ItemLotTypeId` - [InspectionLine](/docs/reference/entities/inspection-line/) — referenced by via `ItemLotTypeId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — referenced by via `ItemLotTypeId` - [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) — referenced by via `ItemLotTypeId` - [ItemComponent](/docs/reference/entities/item-component/) — referenced by via `ItemLotTypeId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `ItemLotTypeId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `ItemLotTypeId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `ItemLotTypeId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `ItemLotTypeId` - [ItemGroupMember](/docs/reference/entities/item-group-member/) — referenced by via `ItemLotTypeId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — referenced by via `DiscountedItemLotTypeId` - [ItemLot](/docs/reference/entities/item-lot/) — referenced by via `ItemLotTypeId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `ItemLotTypeId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `ItemLotTypeId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `ItemLotTypeId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `ItemLotTypeId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `ItemLotTypeId` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `ItemLotTypeId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `ItemLotTypeId` - [RequisitionLine](/docs/reference/entities/requisition-line/) — referenced by via `ItemLotTypeId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `ItemLotTypeId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `ItemLotTypeId` - [AutoPurchaseOrderLine](/docs/reference/entities/auto-purchase-order-line/) — referenced by via `ItemLotTypeId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `ItemLotTypeId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — referenced by via `ItemLotTypeId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `ItemLotTypeId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `ItemLotTypeId` - [ItemCart](/docs/reference/entities/item-cart/) — referenced by via `ItemLotTypeId` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `ItemLotTypeId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `ItemLotTypeId` - [TaxGroupRule](/docs/reference/entities/tax-group-rule/) — referenced by via `ItemLotTypeId` - [ItemInventoryAttribute](/docs/reference/entities/item-inventory-attribute/) — referenced by via `ItemLotTypeId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ItemLotTypeId` - [TransferLine](/docs/reference/entities/transfer-line/) — referenced by via `ItemLotTypeId` - [CycleCountLine](/docs/reference/entities/cycle-count-line/) — referenced by via `ItemLotTypeId` - [ItemRelation](/docs/reference/entities/item-relation/) — referenced by via `ItemLotTypeId` - [ItemAlias](/docs/reference/entities/item-alias/) — referenced by via `ItemLotTypeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Lot — entity reference URL: https://xmatix.com/docs/reference/entities/item-lot/ Last reviewed: 2026-08-16 One traceable batch or serial instance of an item at one partner + branch + storage location, with its own costs, dates and per-lot quantity counters that the ledger posting engine moves in step with InventoryStock. A lot is location-scoped rather than globally unique per batch number: goods receipt creates one per receipt line for items with TrackLots, and transfer posting clones a fresh lot at the destination whose RelatedItemLotId points back at the source. Lot selection for invoicing and fulfilment allocation only considers lots with no HoldCode, ordered oldest-created first. IsTransactionLocked blocks further saves while set, and cycle counting sets and clears it when the count has inventory locking enabled. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Adjustment` | Adjustment | Number | | Net signed quantity from untyped adjustment lines against this batch - this, not the adjusted-in counter, is where positive adjustments land. Counts fully into both the lot's available and in-hand balances. | | `BatchNo` | Batch No | Text | | Free-text batch identifier. It is not populated when a lot is created from a goods receipt line - only the transfer and field-sales paths set it, by copying it from the lot being cloned - so receipt-created lots carry it only if a user types one. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `ComponentNumber` | Component Number | Text | | Manufacturer or component reference captured on the goods receipt line and carried onto the lot; transfer cloning copies it to the destination lot so traceability survives a move. | | `Cost` | Cost | Currency | | A separate cost field that goods receipt does not populate - it is only carried across when transfer posting clones a lot. For the receipted cost use the unit cost field. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | | | | `DateOfDispatch` | Date Of Dispatch | Date | | | | `DateOfExpiry` | Date Of Expiry | Date | | Expiry date of the batch. Not populated by goods receipt lot creation - only carried across when a transfer clones a lot - so it must be captured manually or by an integration on the originating lot. | | `DateOfInward` | Date Of Inward | Date | | | | `DateOfMfg` | Date Of Mfg | Date | | Manufacturing date of the batch. Not populated by goods receipt lot creation; it is only copied forward when a transfer clones a lot. | | `DateOfReceipt` | Date Of Receipt | Date | | Set from the goods receipt document's date when the lot is created, so it reflects the receipt, not the line's own timestamp. | | `DateOfRegistration` | Date Of Registration | Date | | | | `DateOfSupplierDispatch` | Date Of Supplier Dispatch | Date | | Copied from the goods receipt header's supplier dispatch date at lot creation and carried onto cloned lots by transfer posting. | | `DateOfSupplierInvoice` | Date Of Supplier Invoice | Date | | Copied from the goods receipt header's supplier invoice date at lot creation and carried onto cloned lots by transfer posting. | | `Disassemble` | Disassemble | Number | | | | `ExternalId` | External | Text | | | | `ExternalName` | External Name | Text | | | | `HashCode` | Hash Code | Number | | An opaque token assigned once at insert from the current millisecond clock plus a random component. It is not a checksum of the record and nothing in the platform matches, deduplicates or orders on it. | | `HoldCode` | Hold Code | Text | | Any non-null value quarantines the lot: invoicing and fulfilment allocation only ever consider lots where this is null, so setting it removes the lot from automatic selection without changing its quantities. The value itself is not interpreted - only its presence. | | `Id` | Id | Guid | Yes | | | `IsClosed` | Is Closed | Boolean | | No code path reads or writes it, so it has no effect on lot selection, posting or valuation today. | | `IsClosedForSale` | Is Closed For Sale | Boolean | | No code path reads or writes it. To stop a lot being sold, set a hold code instead - that is the flag the selection queries actually honour. | | `IsTransactionLocked` | Is Transaction Locked | Boolean | | Set while a cycle count with inventory locking is underway on this lot - start counting locks, finish counting unlocks - to freeze movements during the count. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotCode` | Lot Code | Text | | It is only read back for display in the allocation and manual-picking screens, so it stays blank unless captured manually. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `LandedCost` | Landed Cost | Currency | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `MRP` | MRP | Currency | | Maximum retail price copied from the goods receipt line when the lot is created, and copied again onto the destination lot when a transfer clones it. | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PurchaseDate` | Purchase Date | Date | | | | `QuantityAdjustedIn` | Postitive Adjusted | Number | | Use the adjustment counter for adjusted-in quantity. | | `QuantityAdjustedOut` | Negative Adjusted | Number | | Batch quantity written off by negative untyped adjustment lines, accumulated as a positive magnitude because the engine applies it as a decrement of a negative quantity. | | `QuantityAssembledIn` | Quantity Assembled In (Future Use) | Number | | Batch quantity produced by assembly adjustments; despite the label marking it for future use it is actively written, because the seeded assemble rule's field name resolves to this property. It also absorbs disassembly adjustments, since the seeded disassemble rule points at the same assemble field. | | `QuantityAssembledOut` | Quantity Assembled Out (Future Use) | Number | | | | `QuantityAvailable` | Available | Calculated (calculated) | | | | `QuantityDamaged` | Damaged | Number | | | | `QuantityExcess` | Quantity Excess | Number | | | | `QuantityExpired` | Expired | Number | | | | `QuantityInHand` | In Hand | Calculated (calculated) | | | | `QuantityInPendingDeliveries` | Pending Deliveries | Number | | Batch quantity invoiced but not yet delivered, incremented alongside the sold counter and released again when the delivery posts. | | `QuantityInTransit` | Transit | Number | | The lot-level in-transit balance for two-step transfers: outward release adds the moving quantity on the destination clone, and inward receipt removes it. | | `QuantityOnAllocation` | Allocated | Number | | Quantity of this batch reserved by fulfilment allocation lines; picking drains it as it fills the picked counter. Subtracted from the lot's available balance and ignored by its in-hand balance. | | `QuantityOnFulfillment` | Quantity On Fulfillment (Future Use) | Number | | Reserved quantity is tracked on the allocation and picked counters instead. | | `QuantityOnHold` | Quantity On Hold (Future Use) | Number | | Batch quantity blocked by OnHold adjustment lines; despite the label marking it for future use it is actively maintained by posting, and is subtracted from the lot's available balance. | | `QuantityOnInspection` | Inspection | Number | | Batch quantity held for incoming inspection, posted from inspection lines on a goods receipt. Subtracted from the lot's available balance and ignored by its in-hand balance. | | `QuantityOnInward` | Unbilled Receipts | Number | | Per-lot mirror of the received-but-unbilled stock bucket, moved by the same posting call that moves the stock row. Adds to the lot's calculated available and in-hand balances. | | `QuantityOnLoan` | Quantity On Loan (Future Use) | Number | | Batch quantity lent out by OnLoan adjustment lines; despite the label marking it for future use it is actively maintained by posting, and is subtracted from the lot's available balance. | | `QuantityOnOutward` | Unbilled Dispatches | Number | | Per-lot mirror of the dispatched-but-uninvoiced bucket. Subtracted by the lot's available balance and absent from its in-hand balance. | | `QuantityPicked` | Picked | Number | | Quantity of this batch on picked fulfilment lines, incremented as allocation is drained. Subtracted from the lot's available balance only. | | `QuantityPurchased` | Purchased | Number | | | | `QuantityPurchaseReturned` | Purchase Returned | Number | | | | `QuantitySaleReturned` | Sale Returned | Number | | | | `QuantityShortage` | Shortage | Number | | | | `QuantitySold` | Sold | Number | | | | `QuantityTransferIn` | Transfer In | Number | | | | `QuantityTransferOut` | Quantity Transfer Out | Decimal | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RegistrationNumber` | Registration Number | Text | | Registration identity for registrable goods; not set at goods receipt, only copied forward when transfer posting clones a lot, and read when a receipt produces an asset record. | | `RelatedItemLotId` | Related Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | | | `SaleDate` | Sale Date | Date | | | | `SerialNumber` | Serial Number | Text | | Serial identity of a single-unit lot, taken from the goods receipt line and copied onto the destination lot when a transfer clones it. | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | The bin/location the lot currently sits in. Receiving a transfer inward line rewrites it to the receiving line's location, which is how put-away moves a lot. | | `SupplierInvoiceNumber` | Supplier Invoice Number | Text | | Copied from the goods receipt header at lot creation and carried onto cloned lots by transfer posting, giving each batch its purchase paperwork reference. | | `TotalCost` | Total Cost | Currency | | | | `TransferInward` | Transfer Inward | Decimal | | Cumulative quantity transferred into this batch's location, incremented by the inward leg of a transfer posting. Counts positively into the lot's available and in-hand balances. | | `TransferOut` | TransferOut | Decimal | Yes | | | `TransferOutward` | Transfer Outward | Decimal | | Cumulative quantity transferred out of this batch, incremented by the outward leg of a transfer posting. Subtracted by the lot's available and in-hand balances. | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | Per-unit cost copied from the goods receipt line when the lot is created, and copied again onto ledger rows as the movement's unit cost when this lot posts. | | `UpdatedDateTime` | Modified Date | DateAndTime | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Allow Product Lots Only with One Qty | Error | This Product Lot do not allow quantities in excess of one. | Prevents serialised products from having more than one quantity in a lot | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `RelatedItemLotId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `ItemLotId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `ItemLotId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `ItemLotId` - [Asset](/docs/reference/entities/asset/) — referenced by via `ItemLotId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ItemLotId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `ItemLotId` - [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) — referenced by via `ItemLotId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `ItemLotId` - [InspectionLine](/docs/reference/entities/inspection-line/) — referenced by via `ItemLotId` - [TransferLine](/docs/reference/entities/transfer-line/) — referenced by via `RelatedItemLotId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `RelatedItemLotId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `ItemLotId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `ItemLotId` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `ItemLotId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `RelatedItemLotId` - [ShipmentAssetLine](/docs/reference/entities/shipment-asset-line/) — referenced by via `ItemLotId` - [ItemLot](/docs/reference/entities/item-lot/) — referenced by via `RelatedItemLotId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `RelatedItemLotId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `ItemLotId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `ItemLotId` - [CycleCountLine](/docs/reference/entities/cycle-count-line/) — referenced by via `ItemLotId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `ItemLotId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ItemLotId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `ItemLotId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — referenced by via `RelatedItemLotId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `ItemLotId` - [TransferLine](/docs/reference/entities/transfer-line/) — referenced by via `ItemLotId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `ItemLotId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Maintenance Schedule — entity reference URL: https://xmatix.com/docs/reference/entities/item-maintenance-schedule/ Last reviewed: 2026-08-16 A service-interval definition for an item, optionally per SKU: when the service falls due (in days, usage hours or a usage reading), the from/to duration and usage window it covers, its position in the sequence of services, and up to five reminder day-offsets. Service campaigns pick an active campaign's schedule and stamp it onto the records they generate, and leads carry the schedule that prompted them. Once any transaction exists against the schedule's item, the handler locks dueInDays against edits and blocks deletion of the schedule. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DueInDays` | Due In Days | Number | | How many days after the reference point the service falls due. Once any transaction exists for the schedule's item this field is locked against edits, so change it only on unused schedules. | | `DueInUsageHours` | Due In Usage (Hours) | Number | | Usage-hours alternative to the days-based due point, for equipment metered in running hours. | | `DueOnUsage` | DueOnUsage | Number | | Usage-reading alternative to the days-based due point, for equipment metered by an odometer or counter rather than by hours. | | `ExternalId` | External | Text | | | | `FifthReminderDayOffset` | 5th Reminder Day Offset | Number | | | | `FirstReminderDayOffset` | 1st Reminder Day Offset | Number | | | | `FourthReminderDayOffset` | 4th Reminder Day Offset | Number | | | | `FromDurationDays` | From Duration (Days) | Number | | Start of the age window in days this schedule covers; together with the to-duration value it bounds which units the schedule applies to, so a service programme can be split into successive intervals. | | `FromUsageHours` | From Usage Hours | Number | | | | `FromUsageReading` | From Usage Reading | Number | | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemSKUId` | Item SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NumberOfReminder` | Number Of Reminder | Number | | How many of the five reminder day-offsets on this schedule are in use; each offset is expressed relative to the due point. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SecondReminderDayOffset` | 2nd Reminder Day Offset | Number | | | | `Sequence` | Sequence | Number | | Position of this service in the item's ordered programme of services, so successive intervals can be told apart. | | `ThirdReminderDayOffset` | 3rd Reminder Day Offset | Number | | | | `ToDurationDays` | To Duration (Days) | Number | | | | `ToUsageHours` | To Usage Hours | Number | | | | `ToUsageReading` | To Usage Reading | Number | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete | Delete | Delete | | `DeleteListRow` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListHeader` | Edit | Edit | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | To Usage Reading Validation | `ToUsageReading`, Error | To Usage reading cannot be less than zero. | Ensures To Usage Reading is greater than From Usage Reading. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [SKU](/docs/reference/entities/sku/) — looks up via `ItemSKUId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Campaign](/docs/reference/entities/campaign/) — referenced by via `ItemMaintenanceScheduleId` - [Item](/docs/reference/entities/item/) — referenced by via `ItemMaintenanceScheduleId` - [Lead](/docs/reference/entities/lead/) — referenced by via `ItemMaintenanceScheduleId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Relation — entity reference URL: https://xmatix.com/docs/reference/entities/item-relation/ Last reviewed: 2026-08-16 Declares which other items are permitted alongside a given parent item, and is the backend source of truth for that restriction: ItemRelationService.ValidateRelatedItemsAsync checks each document line's item against the related-item set of the document's parent item and rejects one that is not listed. The restriction is opt-in - a parent item with no related-item rows imposes no constraint at all, and soft-deleted rows are ignored. Its quantity, price and coordinates columns are stored but read by no server-side code path, and the entity has no metadata actions of its own. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Coordinates` | Coordinates | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | Yes | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Price` | Price | Currency | | | | `Quantity` | Quantity | Decimal | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RelatedItemId` | Related Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteListRow` | Delete | Delete | Delete List Row | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLineEntity` | Edit | EditInline | EditInLineEntity | | `EditInLineHeader` | Edit | EditInline, inactive | EditInLineHeader | | `EditListRow` | Edit | Edit, inactive | EditListRow | | `New` | New | New | New | ## Related entities - [Item](/docs/reference/entities/item/) — looks up via `RelatedItemId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Service Contract Line — entity reference URL: https://xmatix.com/docs/reference/entities/item-service-contract-line/ Last reviewed: 2026-08-16 A component covered by an ItemServiceContract template, with the entitled quantity — the template-level counterpart of AssetServiceContractLine. IsInScope marks whether the component is included in or excluded from the contract's coverage. These lines are what a per-asset contract's lines are generated from, subject to the template's RestrictAssetContractLinesGeneration flag. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ComponentItemId` | Component Item | Lookup → [Item](/docs/reference/entities/item/) | | The part or labour item this template line covers or excludes. It is the covered component, not the product the contract is sold against, which is the header's ItemId. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IsInScope` | Is In Scope | Boolean | Yes | Whether this component is covered by the contract or explicitly excluded from it. Lines can therefore record exclusions as well as inclusions, so read the flag rather than assuming every line means coverage. | | `ItemServiceContractId` | Item Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New, inactive | New | | `New2` | New | NewInline | QAP | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Component Item | `ComponentItemId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Item](/docs/reference/entities/item/) — looks up via `ComponentItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Service Contract — entity reference URL: https://xmatix.com/docs/reference/entities/item-service-contract/ Last reviewed: 2026-08-16 The template that defines a sellable service entitlement for an Item, SKU or lot type — coverage window, usage limits, grace allowances and the rules that govern how the entitlement behaves when it is claimed. AssetServiceContract records are the per-asset instances stamped from it, and this template's ActiveServiceContractRequired, IsScopeRestricted and SingleUseContract flags are what AssetServiceContractService enforces when a Service Order or Opportunity cites the contract. ContractPostingTreatment decides whether utilisation produces claims or invoices. Set coverage here once per product rather than per asset. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ActiveServiceContractRequired` | Active Service Contract Required | Boolean | | It also switches on the date, hours and usage validity checks against the matched contract. | | `BillingAccountId` | BillingAccount | Lookup → [Account](/docs/reference/entities/account/) | | | | `BillToPartnerAccount` | Bill To Partner Account | Boolean | Yes | Directs billing for work under this contract to the partner account rather than to the end customer — the usual arrangement for manufacturer-funded warranty. The specific account is BillingAccountId. | | `ContractPostingTreatment` | Contract Posting Treatment | PickList | | How utilisation of this entitlement is turned into commercial documents, seeded with Generate Claims, Generate Invoices and Auto Generate Claims. This is the authoritative copy of the setting — the same-named field on AssetServiceContract is a calculated field with no formula. Values: Generate Claims, Generate Invoices, Auto Generate Claims. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DateEffectiveFrom` | Date Effective From | Date | | The date from which this template may be sold or applied — a property of the template's own validity, not of any entitlement granted under it. Per-asset coverage dates live on AssetServiceContract. | | `DateEffectiveTill` | Date Effective Till | Date | | The date after which this template may no longer be applied. It does not curtail entitlements already granted; those expire on their own ValidTillDate. | | `ExternalId` | External | Text, unique | | | | `FromDays` | From Days | Decimal | | The lower bound, in days since the asset's reference date, of the window in which this template applies. Paired with ToDays it lets several templates cover successive age bands of the same product. | | `GraceUsageDays` | Grace Usage (Days) | Decimal | | | | `GraceUsageHours` | Grace Usage (Hours) | Decimal | | | | `GraceUsageReading` | Grace Usage (Reading) | Decimal | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | Yes | | | `IsScopeRestricted` | Is Scope Restricted | Boolean | Yes | Marks a contract that only covers the components explicitly listed on its lines. Like ActiveServiceContractRequired it forces a matching active AssetServiceContract to exist, failing with a message naming the restricted scope when none is found. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | Restricts the template to assets originating from a particular lot type, allowing coverage to differ between, for example, imported and locally produced stock of the same item. | | `MaximumUsageHours` | Maximum Usage (Hours) | Number | | | | `MaximumUsageReading` | Maximum Usage (Reading) | Decimal | | The upper usage bound of the band this template covers, paired with MinimumUsageReading. Distinct from the per-asset ValidTillUsageReading, which is where a granted entitlement actually expires. | | `MinimumUsageHours` | Minimum Usage (Hours) | Decimal | | | | `MinimumUsageReading` | Minimum Usage (Reading) | Decimal | | The lower usage bound of the band this template covers. Together with MaximumUsageReading it selects a template by how much the asset has been used, rather than by how old it is. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PopulateContractLines` | Populate Contract Lines (Future Use) | Boolean | Yes | Labelled 'Populate Contract Lines (Future Use)' in the shipped metadata — the flag is reserved and does not currently drive any behaviour. Do not rely on setting it to produce contract lines. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RestrictAssetContractLinesGeneration` | Restrict Asset Contract Lines Generation | Boolean | Yes | Suppresses automatic creation of AssetServiceContractLine records from this template's lines when a per-asset contract is instantiated. Use it where coverage lines are meant to be chosen deliberately rather than copied wholesale. | | `ServiceType` | Service Type | PickList | | Whether work under this contract is warranty or chargeable, seeded with Warranty Repairs and Paid Repairs. Contract lookup can filter candidate templates by service type, so this drives which entitlement a service order can draw on. Values: Warranty Repairs, Paid Repairs, Maintanence, AMC. | | `SingleUseContract` | Single Use Contract | Boolean | Yes | Marks an entitlement that may be claimed once only. Enforcement pairs this with the per-asset contract's IsUtilized flag: a second attempt fails with 'This is a Single Use contract and has already been utilised'. | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `ToDays` | To Days | Decimal | | The upper bound in days of the age window this template covers, forming a band with FromDays. This is about which template applies to an asset of a given age, not about how long a granted entitlement lasts — that is DateEffectiveTill and the per-asset ValidTill fields. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `WeightageInvoiceChargeItemId` | ItWeightage Invoice Charge Itemem | Lookup → [Item](/docs/reference/entities/item/) | | The Item used to raise the weightage-based charge when this contract is invoiced. Its shipped label is the garbled 'ItWeightage Invoice Charge Itemem', so identify it by field name rather than by label. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit in page. | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | From Days Rule Validation | `FromDays`, Error | Days cannot be zero | Prevents From Days from being zero or less | | Grace Day Rule Validation | `GraceUsageDays`, Error | Grace Days cannot be Negative | Prevents negative or zero grace usage days | | Grace Hour Rule Validation | `GraceUsageHours`, Error | Grace Hours cannot be Negative | Prevents negative or zero grace usage hours | | Grace Usage Rule Validation | `GraceUsageReading`, Error | Grace Usage Cannot be Negative | Prevents negative or zero grace usage reading | | Maximum Hour Rule Validation | `MaximumUsageHours`, Error | Maximum Hours should be greater than Minimum hours | Ensures maximum usage hours is not less than minimum usage hours | | Maximum Usage Rule Validation | `MaximumUsageReading`, Error | Maximum Usage should be greater than Minimum Usage. | Ensures maximum usage reading is not less than minimum usage reading | | Minimum Hours Rule Validation | `MinimumUsageHours`, Error | Usage Hours cannot be less than 0 | Prevents zero or negative minimum usage hours | | Minimum Usage Rule Validation | `MinimumUsageReading`, Error | Minimum Usage cannot be zero or negative | Prevents zero or negative minimum usage reading | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Account](/docs/reference/entities/account/) — looks up via `BillingAccountId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Item](/docs/reference/entities/item/) — looks up via `WeightageInvoiceChargeItemId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ItemServiceContractId2` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — referenced by via `ItemServiceContractId` - [Claim](/docs/reference/entities/claim/) — referenced by via `ItemServiceContractId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `ItemServiceContractId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `ItemServiceContractId` - [Campaign](/docs/reference/entities/campaign/) — referenced by via `ItemServiceContractId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `ItemServiceContractId` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — referenced by via `ItemServiceContractId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `ItemServiceContractId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `ItemServiceContractId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `ItemServiceContractId3` - [Lead](/docs/reference/entities/lead/) — referenced by via `ItemServiceContractId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `QuoteForItemServiceContractId` - [Quote](/docs/reference/entities/quote/) — referenced by via `ItemServiceContractId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `ItemServiceContractId` - [CampaignItem](/docs/reference/entities/campaign-item/) — referenced by via `ItemServiceContractId` - [ItemServiceContractLine](/docs/reference/entities/item-service-contract-line/) — referenced by via `ItemServiceContractId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `ItemServiceContractId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ItemServiceContractId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `ItemServiceContract2` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ItemServiceContractId3` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `ItemServiceContractId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item Unit Of Measure — entity reference URL: https://xmatix.com/docs/reference/entities/item-unit-of-measure/ Last reviewed: 2026-08-16 An alternate unit for an item (optionally per SKU), carrying the conversion ratio that relates one of this unit to the item's base unit named in Item.quantityUnitOfMeasure. Document lines record which unit was entered (uom / uom1) plus the quantity in that unit (uomQuantity / uomQuantity1), and ItemService.SetQuantityFromUOMAsync multiplies by the ratio to derive the line's base-unit quantity - or divides in reverse to split a base quantity across the two unit legs, largest ratio first. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ConversionRatio` | Conversion Ratio | Decimal | | How many base units one of this unit contains; the line's base-unit quantity is the quantity entered in this unit multiplied by it. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `QuantityUnitOfMeasure` | Unit Of Measure | PickList | | The unit code a document line references in its uom field; the quantity conversion matches on this value case-insensitively and trimmed, and rejects a line naming a unit that has no row for the item. It is required. Values: Each, Box, Pack, Barrel, Litres, MB, Minutes, Messages, KWH. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `UIProps` | UI Props | Text | | | | `UOMCode` | UOM Code | Text | | A second, shorter code for the unit that no code path reads - document lines are matched against the unit-of-measure value, not this one. | | `UOMDecimalPrecision` | UOM Decimal Precision | Number | | Decimal places the quantity expressed in THIS unit is rounded to on a document line; when empty it falls back to two places. The base-unit quantity is rounded separately using the item's own precision. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit In Page | | `New` | New | New | New | ## Related entities - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Item — entity reference URL: https://xmatix.com/docs/reference/entities/item/ Last reviewed: 2026-10-10 An item is the master record for anything bought, sold, stocked or serviced - a product, part, charge, unit of work, service contract or discounted item - and every document line names one. Its list is on the Warehouse app's navigation bar and under Settings in the Sales, Inventory, Procurement and Service apps. Name, Code and Item Type are required and Code is unique; there is no automatic numbering. A new item is inactive until Active is switched on, and every document line rejects an inactive item. The item stores no selling price, cost or tax rate: prices, discounts and taxes are dated rules that name it. Its behaviour is driven by flags - Track Inventory, Track Lots, Track Asset, Inspection On Receipt, SKU Required, Package - and by related records on its tabs: SKUs, units of measure, package components, lot types, alternates and per-branch inventory attributes. Step-by-step procedures are on the Items page of the Inventory documentation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ABCCategory` | ABC Category | PickList | | A value-class label on the item itself. Descriptive only: cycle counting and automatic ordering read the ABC category on the item's per-branch inventory attributes instead. Values: A Category, C Category. | | `AllowService` | Allow Service | Boolean | | Marks an item that can be serviced. Hidden on the create form for Work Item, Charge Item and Service Contract types. | | `BillingFrequency` | Billing Frequency | PickList | | How often the item is billed, defaulted onto a document line when the line leaves it blank. All three seeded picklist values are inactive, so the field renders with no selectable options out of the box. | | `BillingType` | Billing Type | PickList | | Defaulted onto document lines that leave it blank, alongside billing frequency, charge type and invoice group; it has no seeded picklist, so the values in use are whatever the tenant types. | | `ChargeType` | ChargeType | PickList | | Nature of the charge, defaulted onto a document line when blank. Its single seeded picklist value is inactive, so nothing is selectable until a tenant adds values. | | `ClaimToAccountId` | Claim To Account | Lookup | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | Free-text description of the item. | | `ExternalId` | External | ExternalId | | | | `FailedItemId` | Failed Item | Lookup | | | | `FailedItemTreatment` | Failed Item Treatment | PickList | | Values: Scrap, Send to Supplier. | | `FSNCategory` | FSN Category | PickList | | A fast, slow or non-moving label on the item itself. Descriptive only: cycle counting and automatic ordering read the FSN category on the item's per-branch inventory attributes instead. Values: F category, S category, N category. | | `GTIN` | GTIN | Text | | The item's trade (barcode) number. Barcode scanning matches it first, before the item code. | | `HsnSacCode` | HSN/SAC Code | Text | | India GST goods (HSN) or services (SAC) classification code, up to eight characters. It is stamped onto document lines that have none - and re-stamped when the line's item changes - so it flows into the captured tax transactions and the HSN summaries of the GST returns. | | `Id` | Id | Guid | Yes | | | `InventoryValuationMethod` | Inventory Valuation | PickList | | Labelled Inventory Valuation. A descriptive costing label; stock is actually costed with the method chosen in the valuation policies. Values: FIFO, LIFO, Actual Cost, List Cost, Weighted Average. | | `InvoiceGroup` | Invoice Group | PickList | | Copied down onto a document line from the item when the line does not already carry one, so lines can be grouped into separate invoices by the nature of the charge; it is a defaulting value, not a rule the engine evaluates. Values: Insurance, Spare, Vehicle, Subscription. | | `IsActive` | Active | Boolean | | Whether the item may be used. Off by default, so a new or imported item must be switched on before use. Every document line rejects an inactive item with 'Item is Inactive.', and an item group refuses to add one. | | `IsCodeEditable` | Code Editable | Boolean | | Stored setting not on the shipped form and not read by any process. | | `IsDiscontinued` | Discontinued | Boolean | | Marks an item that is no longer bought. Purchase order, requisition and automatic purchase order lines reject it with 'Discontinued Item Cannot be added', and barcode scanning on order screens refuses it. Sales and stock movements of the item are not blocked. | | `IsNameEditable` | Name Editable | Boolean | | Stored setting not on the shipped form and not read by any process. | | `IsOrderAllowed` | Order Allowed | Boolean | | Not on the shipped form. When explicitly switched off, barcode scanning on order screens refuses the item. | | `IsPackage` | Package | Boolean | | Marks the item as a package whose contents are its item components. When a package line is saved on an order, invoice, quote, opportunity, purchase order or requisition, a child line is added for each mandatory or selected component. | | `IsRegistrationRequired` | Registration Required | Boolean | | Marks an item that needs registration. Shown on the create form for Product and Discounted Item types only. | | `IsSaleable` | Saleable | Boolean | | Not on the shipped form. When explicitly switched off, barcode scanning on order screens refuses the item. | | `IsSKURequired` | SKU Required | Boolean | | When on, every document line for the item must name one of the item's own SKUs; lines without one are rejected with 'SKU is required for this item.' | | `ItemCode` | Code | Text, unique | Yes | Labelled Code. The item's unique code, required and typed by hand - there is no automatic numbering. Barcode scanning matches it after GTIN. A cloned item gets an empty code to fill in. | | `ItemFamily` | Item Family | PickList | | Free-text grouping used as a reporting dimension - the financial statement service groups product profitability by it, labelling items without one as '(no family)'. It is not a lookup and takes no part in pricing or scoping. Values: Family A, Family B, Family C, Family D, Family E. | | `ItemMaintenanceScheduleId` | Item Maintenance Schedule | Lookup → [ItemMaintenanceSchedule](/docs/reference/entities/item-maintenance-schedule/) | | | | `ItemSegment` | Item Segment | PickList | | A descriptive grouping of the item for views and reports. Values: Segment A, Segment B, Segment C, Segment D, Segment E. | | `ItemSubType` | Item Sub Type | PickList | | A finer descriptive grouping of the item. Values: Accessories, Bikes, Clothing, Components. | | `ItemType` | Item Type | PickList | Yes | What kind of item this is: Product, Part, Charge Item, Work Item, Service Contract or Discounted Item. Required. Work Item and Service Contract hide the stock flags on the form. Saving a Discounted Item switches Track Inventory off. Values: Product, Part, Charge Item, Work Item, Service Contract. | | `Make` | Make | PickList | | Values: Honda, Honda, TVS, TVS, Bajaj, Bajaj, Yamaha, Yamaha, Suzuki, Suzuki, Royal Enfield, Royal Enfield. | | `ManufacturerOEM` | Manufacturer (OEM) | Text | | The manufacturer's name. Not on the shipped form. | | `MarkupRate` | MarkupRate | Decimal | | Labelled Markup Rate (%) on the record page. The only price-like value stored on the item; selling prices come from dated price list rules. | | `MaximumLotQuantity` | Maximum Lot Quantity | Number | | The largest quantity one goods receipt or shipment line may carry; larger lines are split when added. 0 means no cap. A SKU's value above zero takes precedence. | | `Model` | Model | PickList | | Values: Activa 110, Activa 125, Activa 125, Shine 125, Shine 125, Dio 125, Dio 125, Jupiter 125, Jupiter 125, Ntorq 125, Ntorq 125, Raider 125, Raider 125, Apache RTR 160 4V, Apache RTR 160 4V, Pulsar NS200, Pulsar NS200, Pulsar N250, Pulsar N250, Chetak 3501, Chetak 3501, FZ-S FI V4, FZ-S FI V4, R15 V4, R15 V4, Access 125, Access 125, Burgman Street EX, Burgman Street EX, Classic 350, Classic 350, Meteor 350, Meteor 350. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | The item's name as people read it. Required, not unique. Copied into the description of new order, invoice, opportunity, purchase order and bill lines. | | `OnlySoldInPackage` | Only Sold In Package | Boolean | | Marks a component that may only be invoiced as part of a package. Checked on invoice lines only, which reject it outside a package with 'Item can only be sold as part of a package.' | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | The user who owns the item record; drives record sharing like any other owned record. | | `PercentageOfTotal` | Percentage Of Total | Percent | | | | `PercentageOfTotalCategory` | Percentage Of Total Category | PickList | | | | `PricingMethod` | Pricing Method | PickList | | Copied onto a subscription created from an invoice line for this item; nothing on the item itself branches on it, so it is descriptive metadata carried forward rather than a pricing switch. Values: Markup On Cost, Bundled Price, Percent Of Total. | | `ProductMaintenanceScheduleId` | Product Maintenance Schedule | Lookup | | | | `QuantityUnitOfMeasure` | Primary Unit Of Measure | PickList | | Labelled Primary Unit Of Measure. The base unit stock balances and line quantities are expressed in. Only Each is seeded. Alternate units and their conversion ratios are the item's units of measure. Values: Each. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequireInspectionOnDelivery` | Inspection On Delivery | Boolean | | Labelled Inspection On Delivery. Stored but not read by any process, so it has no effect today. | | `RequireInspectionOnReceipt` | Inspection On Receipt | Boolean | | Labelled Inspection On Receipt. Received quantity waits for inspection instead of becoming available, and the goods receipt cannot complete while any line has uninspected quantity. | | `RequireServiceOrderOnReceipt` | Repair Order On Receipt | Boolean | | Labelled Repair Order On Receipt. An inspection of the item raises a repair (service) order, and the inspection line cannot complete until that order is closed. | | `RFID` | RF | Text | | Labelled RF. An RFID tag value of up to 18 characters. | | `SequenceNumber` | Sequence Number | Number | | | | `ServiceDurationInMinutes` | Service Duration(Minutes) | Decimal | | Standard labour time for a service item. Quote and service order lines convert it to hours, and service bay allocation uses it. Zero leaves the line duration at zero. | | `SubscriptionDurationInMonths` | Subscription Duration(Months) | Number | | Term of a subscription sold on an invoice line: the subscription ends on the invoice date plus this many months, minus one day. | | `TrackAsset` | Track Asset | Boolean | | When on, each unit becomes a serialized asset after receipt or sale, and goods receipts and shipments ask for a serial number. Saving it without Track Lots fails with 'Tracking assets requires tracking lots.' | | `TrackInventory` | Track Inventory | Boolean | | When on, the item keeps stock balances and its lines post stock movements. Leave it off for services and charges: their lines post no stock, and an inventory adjustment refuses them. Forced off for a Discounted Item. | | `TrackLots` | Track Lots | Boolean | | When on, the item's stock is held per lot and every stock-moving line must name a lot. It is also required for Track Asset. | | `UIProps` | UI Props | Text | | | | `UOMDecimalPrecision` | Primary UOM Decimal Precision | Number | | Decimal places a line quantity in the primary unit is rounded to. Defaults to 0, which keeps quantities whole, but never fewer decimals than the item's finest conversion ratio needs. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Copies the item, including its owned related records, into a new item named after the original with (Copy) appended. Code is left empty because it must be unique; enter a new one and save. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Delete in page. | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `productConfigurator` | Product Configurator | ServerAction | Not placed on the shipped record page and has no effect from the item. Configure a package from the document that uses it. | | `ShowStock` | Show Stock | ServerAction (`ShowStock`) | Not placed on the shipped record page and does not read stock. Read the item's balances on its Inventory tab. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ItemMaintenanceSchedule](/docs/reference/entities/item-maintenance-schedule/) — looks up via `ItemMaintenanceScheduleId` - [Account](/docs/reference/entities/account/) — looks up via `ClaimToAccountId` - [Item](/docs/reference/entities/item/) — looks up via `FailedItemId` - [CampaignItem](/docs/reference/entities/campaign-item/) — referenced by via `ItemId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `OriginalItemId` - [CycleCount](/docs/reference/entities/cycle-count/) — referenced by via `ItemId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `OriginalItemId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `ItemId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `ItemId` - [ShipmentAssetLine](/docs/reference/entities/shipment-asset-line/) — referenced by via `ItemId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `ItemId` - [ItemComponent](/docs/reference/entities/item-component/) — referenced by via `ComponentItemId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `ItemId` - [PostingDefinition](/docs/reference/entities/posting-definition/) — referenced by via `ItemId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `ItemId` - [SchemeConsumption](/docs/reference/entities/scheme-consumption/) — referenced by via `ItemId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — referenced by via `ItemId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `OriginalItemId` - [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) — referenced by via `ItemId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `OriginalItemId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `ServiceContractItemId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `ItemId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `ItemId` - [ItemFeature](/docs/reference/entities/item-feature/) — referenced by via `RelatedItemId` - [StoreItemImage](/docs/reference/entities/store-item-image/) — referenced by via `ItemId` - [TransferLine](/docs/reference/entities/transfer-line/) — referenced by via `ItemId` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — referenced by via `ItemId` - [ItemRelation](/docs/reference/entities/item-relation/) — referenced by via `RelatedItemId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — referenced by via `ItemId` - [ClaimReconciliationLine](/docs/reference/entities/claim-reconciliation-line/) — referenced by via `ItemId` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `ItemId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — referenced by via `DiscountedItemId` - [ProductCatalogueImage](/docs/reference/entities/product-catalogue-image/) — referenced by via `ItemId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `ItemId` - [ContractLine](/docs/reference/entities/contract-line/) — referenced by via `ItemId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `ItemId` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — referenced by via `ItemId` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `ItemId` - [TaxGroupRule](/docs/reference/entities/tax-group-rule/) — referenced by via `ItemId` - [InventoryNrvAssessment](/docs/reference/entities/inventory-nrv-assessment/) — referenced by via `ItemId` - [CampaignMember](/docs/reference/entities/campaign-member/) — referenced by via `ItemId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ItemId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — referenced by via `ItemId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `ServiceContractId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `ItemId` - [ItemAlternate](/docs/reference/entities/item-alternate/) — referenced by via `AlternateItemId` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `ItemId` - [ItemAlias](/docs/reference/entities/item-alias/) — referenced by via `ItemId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `ServiceContractItemId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `PackageServiceId` - [TaxGroupRule](/docs/reference/entities/tax-group-rule/) — referenced by via `ServiceContractItemId` - [ItemRelation](/docs/reference/entities/item-relation/) — referenced by via `ItemId` - [ItemLot](/docs/reference/entities/item-lot/) — referenced by via `ItemId` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — referenced by via `ItemId` - [AssetServiceContractLine](/docs/reference/entities/asset-service-contract-line/) — referenced by via `ComponentItemId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ItemId` - [Lead](/docs/reference/entities/lead/) — referenced by via `ServiceContractItemId` - [ItemCart](/docs/reference/entities/item-cart/) — referenced by via `ItemId` - [ItemConsumptionSchedule](/docs/reference/entities/item-consumption-schedule/) — referenced by via `ItemId` - [Lead](/docs/reference/entities/lead/) — referenced by via `InterestedItemId` - [TaxTransaction](/docs/reference/entities/tax-transaction/) — referenced by via `ItemId` - [AutoPurchaseOrderLine](/docs/reference/entities/auto-purchase-order-line/) — referenced by via `ItemId` - [LandedCostLine](/docs/reference/entities/landed-cost-line/) — referenced by via `ItemId` - [ItemGroupMember](/docs/reference/entities/item-group-member/) — referenced by via `ItemId` - [Asset](/docs/reference/entities/asset/) — referenced by via `ItemId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `ItemId` - [Item](/docs/reference/entities/item/) — referenced by via `FailedItemId` - [StoreCategoryItem](/docs/reference/entities/store-category-item/) — referenced by via `ItemId` - [ItemServiceContractLine](/docs/reference/entities/item-service-contract-line/) — referenced by via `ComponentItemId` - [ItemComponent](/docs/reference/entities/item-component/) — referenced by via `ItemId` - [CheckInTemplate](/docs/reference/entities/check-in-template/) — referenced by via `ApplicableItemId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `ServiceContractItemId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `ServiceContractItemId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `ItemId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `ItemId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `PackageServiceId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `ItemId` - [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) — referenced by via `ApplicableToItemId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `ServiceContractId` - [ItemInventoryAttribute](/docs/reference/entities/item-inventory-attribute/) — referenced by via `ItemId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `OriginalItemId` - [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) — referenced by via `ItemId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `ItemId` - [ItemAlternate](/docs/reference/entities/item-alternate/) — referenced by via `ItemId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ServiceContractItemId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `AlternateItemId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `ItemId` - [ContractLineitem](/docs/reference/entities/contract-lineitem/) — referenced by via `ItemId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — referenced by via `WeightageInvoiceChargeItemId` - [ItemFeature](/docs/reference/entities/item-feature/) — referenced by via `ItemId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `ItemId` - [SubscriptionUsage](/docs/reference/entities/subscription-usage/) — referenced by via `ItemId` - [InventoryValuationPolicy](/docs/reference/entities/inventory-valuation-policy/) — referenced by via `ItemId` - [ComplaintFault](/docs/reference/entities/complaint-fault/) — referenced by via `ApplicableToItemId` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `ItemId` - [ItemUnitOfMeasure](/docs/reference/entities/item-unit-of-measure/) — referenced by via `ItemId` - [ContactAddress](/docs/reference/entities/contact-address/) — referenced by via `ItemId` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — referenced by via `ServiceContractItemId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `ItemId` - [ServiceOrderTimeSheetLine](/docs/reference/entities/service-order-time-sheet-line/) — referenced by via `ItemId` - [SKU](/docs/reference/entities/sku/) — referenced by via `ItemId` - [InspectionLine](/docs/reference/entities/inspection-line/) — referenced by via `ItemId` - [RequisitionLine](/docs/reference/entities/requisition-line/) — referenced by via `ItemId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `ItemId` - [BudgetLine](/docs/reference/entities/budget-line/) — referenced by via `ItemId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — referenced by via `ItemId` - [InventoryCostConsumption](/docs/reference/entities/inventory-cost-consumption/) — referenced by via `ItemId` - [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) — referenced by via `ItemId` - [InventoryOpeningLotState](/docs/reference/entities/inventory-opening-lot-state/) — referenced by via `ItemId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `OriginalItemId` - [CycleCountLine](/docs/reference/entities/cycle-count-line/) — referenced by via `ItemId` - [ProductConfiguratorImageDetail](/docs/reference/entities/product-configurator-image-detail/) — referenced by via `ItemId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `ItemId` - [ItemMaintenanceSchedule](/docs/reference/entities/item-maintenance-schedule/) — referenced by via `ItemId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Journal Line — entity reference URL: https://xmatix.com/docs/reference/entities/journal-line/ Last reviewed: 2026-08-16 One debit or credit leg of a journal, and the row that financial statements, the trial balance and the account ledger are ultimately aggregated from. Each line carries exactly one of Debit or Credit as a positive amount — the side, never a sign, expresses direction — plus the GL account and the reporting dimensions (branch, business unit, GST registration) that the balance cache is keyed on. A line posting to a control account must name the party account, which is what makes the receivables and payables subledgers reconcile to their control account. Once the parent journal reaches Posted or Reversed the line is frozen; the platform rejects any edit or delete outside the posting service. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Resolved during posting through a fixed chain: the line's own value, then the journal header, then the GL account's default branch. Once settled it is a key component of the balance-cache row, and business unit and GST registration are then derived from it. | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | Resolved during posting from the line, then the journal header, then the branch's business unit, and only last of all from the GL account's default — the branch must win over the account default or the line can persist a branch/unit pair that exists nowhere in master data. It keys both the GL and the party balance rows and drives the inter-business-unit clearing lines. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Credit` | Credit | Currency | | A positive amount on the credit side, mutually exclusive with debit — exactly one of the two must be non-zero and neither may be negative. In the balance cache the credit side decreases the closing balance, so a signed balance is debit-positive and credit-negative. | | `Debit` | Debit | Currency | | A positive amount on the debit side; direction is expressed by which of the two amount fields is used, never by a negative number. Posting rejects a line that is negative, that has both sides filled, or that has neither. In the balance cache the debit side increases the closing balance. | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | Yes | The ledger account this leg posts to, mandatory on every line. Posting refuses the entry if the account is inactive, and this account alone — not the contra reference — determines the balance-cache row and the subledger requirement. | | `GLAccountId2` | GL Account 2 | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | A secondary contra-account reference carried on the line for context. | | `GSTRegistrationId` | GST Registration | Lookup → [GSTRegistration](/docs/reference/entities/gstregistration/) | | The registration dimension for the line, normally derived during posting from the line's branch rather than entered directly. It forms part of the key of the GL period-balance row, so two lines on the same account with different registrations open separate balance buckets. | | `Id` | Id | Guid | Yes | | | `JournalDate` | Journal Date | Date | | A stored calculated copy of the parent journal's date, populated by the calculation engine on save so line-level queries and reports can filter and sort by accounting date without joining the header. Treat the header value as authoritative. | | `JournalId` | Journal | Lookup → [Journal](/docs/reference/entities/journal/) | | | | `Label` | Label | Text | | | | `LineNumber` | Line Number | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text, unique | Yes | | | `Narration` | Narration | Text | | | | `OpenTransactionId` | Open Transaction | Lookup → [OpenTransaction](/docs/reference/entities/open-transaction/) | | Links a control-account line to the open item (the receivable or payable) it created or settled, populated for lines born from documents and allocations. It is what lets the ledger line be traced to an ageing bucket, and reversal restores the open item alongside the journal. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartyAccountId` | Party Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer or supplier this line belongs to, and the dimension that makes the receivables/payables subledger work — posting refuses any line hitting a control account without it. It is the counterparty, distinct from the journal's partner account, which is the owning company. Employee-facing control accounts are the exception: they are configured as non-control so the per-employee detail lives on the open-item subledger instead. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Only works while the parent journal is unposted. Deleting a line from a posted journal is refused, because removing one leg would leave the ledger unbalanced against its own balance cache. | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Only works while the parent journal is unposted. Lines of a Posted or Reversed journal are immutable, so the save is rejected and the correction has to be made by reversing the journal. | | `EditInLine` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `NewInLine` | New | NewInline | NewInLine | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [Journal](/docs/reference/entities/journal/) — looks up via `JournalId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [GSTRegistration](/docs/reference/entities/gstregistration/) — looks up via `GSTRegistrationId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId2` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — looks up via `OpenTransactionId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [ReconciliationMatch](/docs/reference/entities/reconciliation-match/) — referenced by via `JournalLineId` - [BankReconciliationLine](/docs/reference/entities/bank-reconciliation-line/) — referenced by via `JournalLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Journal — entity reference URL: https://xmatix.com/docs/reference/entities/journal/ Last reviewed: 2026-08-16 The single posting vehicle of the ledger: every value movement in the platform — document posting, manual entry, opening balance, depreciation, payroll, allocation, reversal and period close — is a journal, and its posted lines ARE the general ledger. Posting runs through one pipeline that validates the entry is balanced, resolves an Open fiscal period from the journal date, stamps the totals and the Posted status, and updates the GL and party balance caches in the same unit of work. Posted and Reversed journals are immutable and cannot be edited or deleted; corrections are made by posting a reversal that points back through ReversalOfJournalId. Journals raised by a source document also carry SourceEntityName, SourceRecordId and PostingPurpose so the document's accounting can be found and reversed independently. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | Yes | Header-level branch that seeds each line's branch when the line leaves it empty; the line's own branch, once resolved, is what the balance cache is keyed on. Branch is also the hub from which business unit and GST registration are derived during posting. | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | Header-level business unit used as the first fallback for lines that do not carry their own. When the resolved lines end up spanning more than one business unit, posting adds due-to/due-from clearing lines so each unit balances independently — but only if the company has an inter-business-unit control account configured. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FiscalPeriodId` | Fiscal Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | Yes | Resolved by the posting engine from the journal date, not chosen by the user — posting looks up the Open period covering that date for the company and fails if there is none. Every balance-cache row the journal maintains is keyed on this period. | | `Id` | Id | Guid | Yes | | | `JournalDate` | Document Date | Date | | The accounting date of the entry, defaulting to today when a journal is created. It determines which fiscal period posting resolves and it is mirrored down onto every line, so it — not the created timestamp — is what date-driven ledger reports filter on. | | `JournalTypeName` | Journal Type Name | Text | | Classifies where the entry came from — DocumentPosting, Manual, OpeningBalance, Reversal, Closing, Depreciation, Payroll or Allocation — and defaults to Manual when not supplied. A journal of type Reversal cannot itself be reversed. Note that recurring-journal runs are materialised as Manual, not as a distinct type; they are identified by their source document instead. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `Narration` | Narration | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | Yes | The company (legal entity) the journal belongs to, following the finance convention that a partner account is the owning company — it is not the customer or supplier. Fiscal-period resolution, inter-business-unit clearing-account lookup and the balance rows the journal writes are all scoped by it; the customer or supplier lives on the line's party account instead. | | `PostedById` | Posted By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `PostedDateTime` | Posted Date Time | Date | | Set by the posting engine to the moment of posting in UTC. It is the posting timestamp, not the accounting date — use the journal date for anything period- or statement-related. | | `PostingPurpose` | Posting Purpose | Text | | Distinguishes the several journals a single source document can produce — an invoice raises a main journal plus separate ones for cost of goods sold and for tax collected at source, for example — so each can be found and reversed independently. Values come from the document posting purposes (Invoice, InvoiceCOGS, InvoiceTcs, Bill, BilledInventory, CreditNote, DebitNote, SaleDebitNote, PaymentTaken, PaymentGiven, GoodsReceipt, DeliveryOrder, Return, BillReturn, ChequeClearing, InterestCharge) and it is meaningful only on document postings. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReversalOfJournalId` | Reversal Of Journal | Lookup → [Journal](/docs/reference/entities/journal/) | | Present only on reversal journals, pointing back at the journal being corrected; the original is simultaneously flipped to Reversed. This is the audit trail for every correction, since nothing in the ledger is ever edited or deleted. | | `SourceEntityName` | Source Entity Name | Text | | Names the entity of the document that produced this journal, held as plain text with deliberately no foreign key so that any entity can post. Together with the source record id and the posting purpose it is the lookup key used to find an existing posted journal for a document and reverse it on edit, un-approval or delete. | | `SourceRecordId` | Source Record | Lookup → @sourceEntityName | | | | `Status` | Status | Text | | Takes one of Draft, PendingApproval, Posted or Reversed. Only Draft and PendingApproval can be posted; Posted and Reversed make the whole journal and its lines immutable and undeletable outside the posting service, and Reversed means a swapped-sides reversal journal has already been posted against it. | | `TotalCredit` | Total Credit | Calculated (calculated) | | Stamped by the posting engine as the sum of the line credits, rounded to two decimals, and always equal to the debit total — an entry whose sides differ is rejected before it can post. Note that inter-business-unit clearing lines added during posting are included, though they net to zero. | | `TotalDebit` | Total Debit | Calculated (calculated) | | Stamped by the posting engine as the sum of the line debits, rounded to two decimals, and is always exactly equal to the credit total because posting refuses an unbalanced entry. It is a posting artefact rather than something to fill in by hand. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Only works while the journal is Draft or PendingApproval. A Posted or Reversed journal cannot be deleted — the ledger is append-only — and the attempt is rejected with a prompt to reverse it instead. | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Only meaningful while the journal is Draft or PendingApproval. Once the status is Posted or Reversed the record is immutable outside the posting service, and a status change is refused with a prompt to use the reversal action. | | `EditInLine` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `PostJournal` | Post | ServerAction (`PostJournal`) | Validates and commits the journal to the ledger in one atomic unit of work: it requires at least two lines, exactly one of Debit or Credit per line with no negative amounts, equal debit and credit totals, a GL account on every line, no inactive accounts, and a party on every control-account line. It then defaults each line's dimensions, adds inter-business-unit clearing lines when the entry spans more than one business unit and a clearing account is configured, resolves an Open fiscal period from the journal date, stamps the totals, Posted status, timestamp and posting user, and updates the GL and party balance caches. Only Draft or PendingApproval journals are accepted, and after this the journal is immutable. | | `ReverseJournal` | Reverse | ServerAction (`ReverseJournal`) | Creates a brand-new journal with every debit and credit swapped, posts it immediately, and marks the original Reversed — it does not delete or edit anything. The reversal is dated today unless a reversal date is passed, so it lands in an Open period even when the original period has been closed, and it copies the original's source document, posting purpose and dimensions. Only a Posted journal can be reversed, and a reversal journal cannot itself be reversed. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Fiscal Period | `FiscalPeriodId`, Error | Fiscal Period cannot be null! | Fiscal Period cannot be null! | | Journal Date Validation | `JournalDate`, Error | Document Date cannot be future date. | Document Date cannot be future date. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Fiscal Period Active | `FiscalPeriodId` | | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [Invoice](/docs/reference/entities/invoice/) — looks up via `SourceRecordId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — looks up via `SourceRecordId` - [CompanyCard](/docs/reference/entities/company-card/) — looks up via `SourceRecordId` - [AssetDisposal](/docs/reference/entities/asset-disposal/) — looks up via `SourceRecordId` - [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) — looks up via `SourceRecordId` - [BankTransfer](/docs/reference/entities/bank-transfer/) — looks up via `SourceRecordId` - [RecurringDepreciation](/docs/reference/entities/recurring-depreciation/) — looks up via `SourceRecordId` - [Payment](/docs/reference/entities/payment/) — looks up via `SourceRecordId` - [RecurringJournal](/docs/reference/entities/recurring-journal/) — looks up via `SourceRecordId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `PostedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — looks up via `SourceRecordId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — looks up via `SourceRecordId` - [ExpenseReimbursementBatch](/docs/reference/entities/expense-reimbursement-batch/) — looks up via `SourceRecordId` - [PayrollRun](/docs/reference/entities/payroll-run/) — looks up via `SourceRecordId` - [LandedCost](/docs/reference/entities/landed-cost/) — looks up via `SourceRecordId` - [Bill](/docs/reference/entities/bill/) — looks up via `SourceRecordId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [InterestCharge](/docs/reference/entities/interest-charge/) — looks up via `SourceRecordId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — looks up via `SourceRecordId` - [CreditNote](/docs/reference/entities/credit-note/) — looks up via `SourceRecordId` - [ChequeTransaction](/docs/reference/entities/cheque-transaction/) — looks up via `SourceRecordId` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — looks up via `SourceRecordId` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — looks up via `SourceRecordId` - [RevenueRecognitionSchedule](/docs/reference/entities/revenue-recognition-schedule/) — looks up via `SourceRecordId` - [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) — looks up via `SourceRecordId` - [CurrencyRevaluation](/docs/reference/entities/currency-revaluation/) — looks up via `SourceRecordId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — looks up via `SourceRecordId` - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — looks up via `SourceRecordId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [ExpenseAdvanceSettlement](/docs/reference/entities/expense-advance-settlement/) — looks up via `SourceRecordId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `SourceRecordId` - [Journal](/docs/reference/entities/journal/) — looks up via `ReversalOfJournalId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `FiscalPeriodId` - [DebitNote](/docs/reference/entities/debit-note/) — looks up via `SourceRecordId` - [TdsChallan](/docs/reference/entities/tds-challan/) — looks up via `SourceRecordId` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — referenced by via `GLId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `GLId` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — referenced by via `GLId` - [ExpenseReimbursementBatch](/docs/reference/entities/expense-reimbursement-batch/) — referenced by via `GLId` - [CurrencyRevaluation](/docs/reference/entities/currency-revaluation/) — referenced by via `GLId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `GLId` - [AssetDisposal](/docs/reference/entities/asset-disposal/) — referenced by via `GLId` - [JournalLine](/docs/reference/entities/journal-line/) — referenced by via `JournalId` - [InventoryNrvAssessment](/docs/reference/entities/inventory-nrv-assessment/) — referenced by via `JournalId` - [SettlementAllocation](/docs/reference/entities/settlement-allocation/) — referenced by via `JournalId` - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — referenced by via `JournalId` - [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) — referenced by via `GLId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `JournalId` - [PayrollRun](/docs/reference/entities/payroll-run/) — referenced by via `GLId` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — referenced by via `GLId` - [LandedCost](/docs/reference/entities/landed-cost/) — referenced by via `GLId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `GLId` - [ExpenseAdvanceSettlement](/docs/reference/entities/expense-advance-settlement/) — referenced by via `JournalId` - [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) — referenced by via `GLId` - [BankTransfer](/docs/reference/entities/bank-transfer/) — referenced by via `GLId` - [RevenueRecognitionScheduleLine](/docs/reference/entities/revenue-recognition-schedule-line/) — referenced by via `JournalId` - [Journal](/docs/reference/entities/journal/) — referenced by via `ReversalOfJournalId` - [TdsChallan](/docs/reference/entities/tds-challan/) — referenced by via `GLId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Knowledge Article — entity reference URL: https://xmatix.com/docs/reference/entities/knowledge-article/ Last reviewed: 2026-08-16 A knowledge-base article: titled (Name), categorized help content with a publish lifecycle (status: Draft, Published, Archived) and a visibility of Internal (agent-only) or Public (portal/customer). Agents browse and attach articles to cases and can email one to the case contact via the EmailArticle action; keyword-based suggestion uses the keywords field. Usage counters (viewCount, helpfulCount, notHelpfulCount, deflectionCount) feed deflection metrics - deflectionCount is the number of cases marked as resolved by the article. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Body` | Body | Text | | | | `Category` | Category | PickList | | Values: General, Troubleshooting, HowTo, Policy, FAQ. | | `DeflectionCount` | Deflections | Number | | Number of cases an agent or customer marked as resolved by this article. Drives the deflection report (top deflecting articles); maintained by the deflection tracking flow, not hand-edited. | | `HelpfulCount` | Helpful | Number | | | | `Keywords` | Keywords | Text | | | | `NotHelpfulCount` | Not Helpful | Number | | | | `Status` | Status | PickList | | Values: Draft, Published, Archived. | | `Summary` | Summary | Text | | | | `ViewCount` | Views | Number | | | | `Visibility` | Visibility | PickList | | Values: Internal, Public. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # KPI Configuration — entity reference URL: https://xmatix.com/docs/reference/entities/kpiconfiguration/ Last reviewed: 2026-08-16 A KPI definition - the catalog row that names a measurable performance indicator (kpiName, label) and declares where its numbers come from: triggerObjectName/triggerEvent point at the source entity and event, and the *FieldName pointers (accountFieldName, branchFieldName, dateFieldName, itemFieldName, partnerFieldName, resourceFieldName, valueFieldName/valueFieldName2 with valueFunction, rewardFieldName with rewardFunction) map source-entity fields into the KPI dimensions and measures. Child KPIRules rows add filter conditions on the source records. Definitions can be grouped hierarchically: kPIConfigurationId points at a parent configuration and isGroup marks group nodes. Scoping lookups restrict applicability (accountGroupId, partnerAccountGroupId, itemGroupId). This is the KPI that Rewards configuration points at: IncentiveTarget, IncentiveResourceTarget, CompensationLine and CompensationSlab rows all carry a kpiConfigurationId identifying which KPI their target or slab measures. Aggregated results land in KPIData rows (kpiConfigurationId links back); lastExecutedSystemModstamp records the high-water mark of the last calculation pass. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountFieldName` | Account Field Name | Text | | | | `AccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `BranchFieldName` | Branch Field Name | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DateFieldName` | Date Field Name | Text | Yes | | | `FirstNRecords` | Include First N Records | Number | | | | `Id` | Id | Guid | Yes | | | `IncludeChildResources` | Include Child Resources | Boolean | Yes | | | `IncludeLastNRecords` | Include Last N Records | Number | | | | `IsActive` | Is Active | Boolean | Yes | | | `IsGroup` | Is Group | Boolean | Yes | | | `ItemFieldName` | Item Field Name | Text | | | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | | | `JobQueueId` | Job Queue | Lookup → [InterfaceQueue](/docs/reference/entities/interface-queue/) | | | | `KPIConfigurationId` | KPI Configuration | Lookup → [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) | | Self-referencing parent lookup: points at a parent KPIConfiguration, building a group hierarchy of KPI definitions (isGroup marks the group nodes). Not to be confused with the field of the same name on KPIData/KPIRules, where it links a result or rule to its definition. | | `KPIName` | KPI Name | Text | | | | `LastExecutedSystemModstamp` | Last Executed System Modstamp | DateAndTime | | | | `MemberType` | Member Type | PickList | Yes | Values: Branch, Resource, Customer. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `PartnerFieldName` | Partner Account Field Name | Text | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceFieldName` | Resource Field Name | Text | | | | `ResultRewardFieldName` | Formula Reward Field Name | Text | | | | `ResultValueFieldName` | Formula Value Field Name | Text | | | | `RewardFieldName` | Reward Field Name | Text | | | | `RewardFunction` | Reward Function | PickList | | Values: Sum. | | `RuleSuccessCriteria` | Rule Success Criteria | PickList | | Values: Always (No Criteria). | | `RuleSuccessCustomLogic` | Rule Success Custom Logic | Text | | | | `TriggerEvent` | Trigger Event | PickList | | Values: Scheduled, AFTER_INSERT, AFTER_UPDATE, AFTER_DELETE. | | `TriggerObjectName` | Trigger Object Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `ValueFieldName` | Value Field Name | Text | | | | `ValueFieldName2` | Value Field Name | Text | | | | `ValueFunction` | Value Function | PickList | | Values: Count, Average, Formula. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [InterfaceQueue](/docs/reference/entities/interface-queue/) — looks up via `JobQueueId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `PartnerAccountGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — looks up via `KPIConfigurationId` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `KPIConfigurationId` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — referenced by via `KPIConfigurationId` - [KPIRules](/docs/reference/entities/kpirules/) — referenced by via `KPIConfigurationId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `KPIConfigurationId` - [IncentiveResourceTarget](/docs/reference/entities/incentive-resource-target/) — referenced by via `KPIConfigurationId` - [KPIData](/docs/reference/entities/kpidata/) — referenced by via `KPIConfigurationId` - [CompensationSlab](/docs/reference/entities/compensation-slab/) — referenced by via `KPIConfigurationId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # KPI Data Detail — entity reference URL: https://xmatix.com/docs/reference/entities/kpidata-detail/ Last reviewed: 2026-08-16 One contributing source document under a KPIData aggregate - the drill-down line that shows which document produced how much of the parent total. kPIDataId links to the aggregate row; billNo identifies the source document and kpiValue/rewardValue carry that document's contribution to the KPI and reward totals. Use it to explain or audit a KPIData figure document by document. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BillNo` | Bill No | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DetailName` | Detail Name | Text | | | | `Id` | Id | Guid | Yes | | | `IncentivePlanId` | Incentive Plan | Lookup → [IncentivePlan](/docs/reference/entities/incentive-plan/) | | | | `KPIDataId` | KPI Data | Lookup → [KPIData](/docs/reference/entities/kpidata/) | | | | `KPIValue` | KPI Value | Number | | | | `KPIValue2` | KPI Value | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RewardValue` | Reward Value | Number | | | | `SaleDoc` | Sale Doc | Text | | | | `SourceRecordId` | Source Record | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [KPIData](/docs/reference/entities/kpidata/) — looks up via `KPIDataId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — referenced by via `IncentivePlanId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # KPI Data — entity reference URL: https://xmatix.com/docs/reference/entities/kpidata/ Last reviewed: 2026-08-16 An aggregated KPI result row - the computed output of a KPIConfiguration for one dimensional slice: kpiConfigurationId identifies the definition, and the slice is keyed by combinations of accountId, partnerAccountId, branchId, resourceId, employeeId, incentivePlanId, incentivePeriodId and incentiveResourceTargetId. Measures are kpiValue/kpiValueCount/kpiValueSum (the metric as flag, count and sum) and rewardValue/rewardValueSum (the reward side), with documentDate and currencyISOCode context. Child KPIDataDetail rows itemize the individual source documents that contributed to the totals. Read these rows for computed KPI results per resource or account within an incentive period; the raw per-document accumulator facts live in PerformanceKPI instead. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | | | `EmployeeID` | Employee | Calculated | | | | `Id` | Id | Guid | Yes | | | `IncentivePeriodId` | Incentive Period | Lookup → [IncentivePeriod](/docs/reference/entities/incentive-period/) | | | | `IncentivePlanId` | Incentive Plan | Lookup | | | | `IncentiveResourceId` | Incentive Resource | Lookup → [IncentiveResource](/docs/reference/entities/incentive-resource/) | | | | `IncentiveResourceTargetId` | Incentive Resource Target | Lookup → [IncentiveResourceTarget](/docs/reference/entities/incentive-resource-target/) | | | | `KPIConfigurationId` | KPI Configuration | Lookup → [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) | | | | `KPIValue` | Custom KPI Value | Number | | | | `KPIValueCount` | KPI Value Count | Calculated | | | | `KPIValueSum` | KPI Value Sum | Calculated (calculated) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `RewardValue` | Custom Reward Value | Number | | | | `RewardValueSum` | Reward Value Sum | Calculated (calculated) | | | | `RNAKpiValue` | RNAKpiValue | Calculated (calculated) | | | | `TargetValue` | Target Value | Decimal | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `Edit1` | Edit | EditInline | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [IncentivePeriod](/docs/reference/entities/incentive-period/) — looks up via `IncentivePeriodId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — looks up via `KPIConfigurationId` - [IncentiveResourceTarget](/docs/reference/entities/incentive-resource-target/) — looks up via `IncentiveResourceTargetId` - [IncentiveResource](/docs/reference/entities/incentive-resource/) — looks up via `IncentiveResourceId` - [KPIDataDetail](/docs/reference/entities/kpidata-detail/) — referenced by via `KPIDataId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # KPI Rule — entity reference URL: https://xmatix.com/docs/reference/entities/kpirules/ Last reviewed: 2026-08-16 A filter condition attached to a KPIConfiguration (kpiConfigurationId): fieldName + operation + fieldValue express one predicate over the KPI's trigger entity, and sequenceNumber orders the conditions. Only source records satisfying these rules count toward the KPI. A configuration without rules counts every record of its trigger entity. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FieldName` | Field Name | Text | | | | `FieldValue` | Field Value | Text | | | | `Id` | Id | Guid | Yes | | | `KPIConfigurationId` | KPI Configuration | Lookup → [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) | | | | `KPIName` | KPI Name | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Operation` | Operation | PickList | | Values: Not Equal, Greater Than, In. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SequenceNumber` | Sequence Number | Number | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — looks up via `KPIConfigurationId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # KYC Document — entity reference URL: https://xmatix.com/docs/reference/entities/kycdocument/ Last reviewed: 2026-08-16 An identity/verification document captured during onboarding or a financed sale: documentType and documentNumber identify the document, kycType classifies the check, isVerified records the outcome and externalId keeps the provider's reference. It attaches to whichever process required it - a FinanceCase, an Order or OrderLine, an Opportunity, a DealerOnboarding application or a Resource - is scoped by branch, and Employee records point at their KYC document. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DealerOnboardingId` | Dealer Onboarding | Lookup → [DealerOnboarding](/docs/reference/entities/dealer-onboarding/) | | | | `DocumentNumber` | Document Number | Text | | | | `DocumentType` | Document Type | PickList | | Values: Aadhaar Card, Pan Card, Driving License, Voter ID, Passport, Salary Slip, Cancelled Cheque. | | `EmployeeId` | Employee | Lookup → [Employee](/docs/reference/entities/employee/) | | | | `ExternalId` | External | Text | | | | `FinanceCaseId` | Finance Case | Lookup → [FinanceCase](/docs/reference/entities/finance-case/) | | | | `Id` | Id | Guid | Yes | | | `IsVerified` | Is Verified | Boolean | Yes | | | `KYCType` | KYC Type | PickList | | Values: Identity Proof, Address Proof, Income Proof. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OrderId` | Sale Order | Lookup → [Order](/docs/reference/entities/order/) | | | | `OrderLineId` | Sale Order Line | Lookup → [OrderLine](/docs/reference/entities/order-line/) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `SaleOrderKYC` | Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [OrderLine](/docs/reference/entities/order-line/) — looks up via `OrderLineId` - [FinanceCase](/docs/reference/entities/finance-case/) — looks up via `FinanceCaseId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Employee](/docs/reference/entities/employee/) — looks up via `EmployeeId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [DealerOnboarding](/docs/reference/entities/dealer-onboarding/) — referenced by via `DealerOnboardingId` - [Employee](/docs/reference/entities/employee/) — referenced by via `KYCDocumentId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Landed Cost Line — entity reference URL: https://xmatix.com/docs/reference/entities/landed-cost-line/ Last reviewed: 2026-08-16 One received item on a landed-cost voucher, holding the quantity and base value that drive the apportionment plus the freight, duty and other amounts assigned to it. Every allocated amount and the final unit cost are recomputed and overwritten by the posting service, so values typed by hand do not survive a post. Each of the three charges is split independently on the chosen basis, rounded to two decimals, with the rounding remainder given to the last line in a sequence the posting service orders by ascending line value; when the whole basis is zero the charge is spread evenly instead. The final unit cost is the line value plus its allocated total divided by the quantity, to four decimals, and zero when the quantity is zero. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AllocatedDuty` | Allocated Duty | Currency | | This line's share of the voucher's duty, split independently of freight on the same basis and likewise recomputed and overwritten when the voucher posts. | | `AllocatedFreight` | Allocated Freight | Currency | | This line's share of the voucher's freight, computed and overwritten at posting time — a value entered by hand is discarded. The last line in ascending line-value order absorbs the rounding remainder so the shares always sum to the charge. | | `AllocatedOther` | Allocated Other | Currency | | This line's share of the voucher's other charges, again apportioned as its own pool and overwritten at posting time. | | `AllocatedTotal` | Allocated Total | Currency | | The rounded sum of the three allocated charges for this line; the voucher's total allocated is the sum of these across its lines and becomes the journal amount. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FinalUnitCost` | Final Unit Cost | Currency | | The line value plus its allocated total, divided by the quantity, to four decimals. It is stamped for reference only — no service reads it back into the cost lots or value layers, so inventory valuation and COGS remain unaffected by the landed cost. | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | Identifies the received item the charges are being apportioned to. Nothing matches it back to a goods-receipt line, so the correspondence between a landed-cost line and the receipt it covers is by convention only. | | `LandedCostId` | Landed Cost | Lookup → [LandedCost](/docs/reference/entities/landed-cost/) | | The parent voucher. Only lines that are not soft-deleted take part in the apportionment, and a voucher with no surviving lines is refused at posting. | | `LineValue` | Line Value | Currency | | The base value of the received item: the apportionment basis under the default by-value method, and the starting point for the final unit cost. Posting rewrites it rounded to two decimals. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | A per-line partner reference held independently of the voucher header's partner; the capitalisation journal takes its partner from the header, not from here. | | `Quantity` | Quantity | Decimal | | The apportionment basis when the voucher allocates by quantity, and the divisor for the final unit cost. A zero quantity yields a final unit cost of zero rather than an error. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `EditInLine` | Edit | EditInline | Edit | | `New` | New | New | New | | `NewInline` | New | NewInline | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [LandedCost](/docs/reference/entities/landed-cost/) — looks up via `LandedCostId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Landed Cost — entity reference URL: https://xmatix.com/docs/reference/entities/landed-cost/ Last reviewed: 2026-08-16 A voucher gathering the incidental costs of a receipt — freight, customs duty and other charges — so they can be apportioned across the received items and capitalised. LandedCostPostingService splits the three charges over the child lines (by line value, or by quantity when AllocationMethod reads exactly ByQuantity), stamps the per-line split and final unit cost, posts one journal debiting the inventory account and crediting a landed-cost clearing account for the allocated total, records the journal in GLId and flips the status to Posted. Two limits matter for anyone reasoning about costs: the capitalisation reaches the general ledger only — it does not update InventoryCostLot or the inventory value layers, so engine COGS still ignores landed cost — and no controller, handler, job or metadata action invokes the posting service, so in the shipped product the voucher can be authored but never posted from the application. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AllocationMethod` | Allocation Method | Text | | Only the exact value ByQuantity selects the quantity basis; every other value, empty included, falls through to apportioning by line value. The comparison ignores case but not spelling. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Copied to the capitalisation journal header and to both of its lines, so it determines which branch the inventory uplift and the clearing credit land in. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Document Date | DateAndTime | | Supplies the posting date of the capitalisation journal when the caller does not override it; if it is empty the current UTC date is used instead. | | `DocumentNumber` | Document Number | Text | | | | `DutyAmount` | Duty Amount | Currency | | Customs or excise duty to capitalise, split across the lines on the chosen basis independently of the freight and other charges. | | `FreightAmount` | Freight Amount | Currency | | One of the three charges to capitalise. Each charge is apportioned separately across the lines rather than pooled with the others, so each carries its own rounding remainder on the last line. | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | Points at the capitalisation journal created when the voucher posts. A non-empty value blocks a second posting just as firmly as a Posted status does. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OtherAmount` | Other Amount | Currency | | Any remaining incidental cost — clearing, insurance, handling — capitalised as a third independent pool split on the same basis as the other two. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Carried onto the capitalisation journal as its partner. An empty value does not stop posting — the journal is simply raised against an empty partner. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SourceEntityName` | Source Entity Name | Text | | A plain string naming the entity the costs originate from, such as a goods receipt or a bill. It is not a lookup and nothing in the platform validates it or follows it back to a record. | | `SourceRecordId` | Source Record | Guid | | The identifier of the originating document, stored without a foreign key. No service resolves it, so the link back to the receipt or bill is documentation rather than an enforced relationship. | | `Status` | Status | Text | | Starts as Draft and is set to Posted by the capitalisation service, which refuses to run again once it reads Posted. The intermediate 'Allocated' state the column contemplates is written by no code, so it only ever appears if something sets it by hand. | | `TotalAllocated` | Total Allocated | Currency | | Written by the posting service as the rounded sum of the per-line allocations, and used as the amount of the capitalisation journal. Posting is refused outright when it works out at zero or less. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `New` | New | New | New | | `View` | View | View | View | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [LandedCostLine](/docs/reference/entities/landed-cost-line/) — referenced by via `LandedCostId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Lead — entity reference URL: https://xmatix.com/docs/reference/entities/lead/ Last reviewed: 2026-10-10 A lead is an enquiry that has not been qualified yet: who the person or business is, how to reach them, where the enquiry came from and what they want. It has three record types (Sales, Service, Partner) and appears in the CRM, Service and Partner Onboarding apps. Leads are created by hand, by campaign runs (members, contract schedules, maintenance schedules) or from a support case, and are numbered from document numbering (shipped series L). Status starts as New; shipped business rules set Contacted when a call or email activity is logged and Converted when the lead is saved with an opportunity, and Converted and Lost are final. On every save the postal code can route the lead to a branch and partner account, and a matching account fills the customer details. A sales or service lead converts through a dialog that creates or links an account, contact and opportunity; a partner lead converts in one step. A lead converts once, raises at most one service order, and can release any number of sales orders. Step-by-step procedures are on the Leads page of the CRM documentation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The existing customer account. Limited to active customer accounts. Choosing one fills the blank names, phone, email, city, state, postal code and contact from the account. Conversion uses it or replaces it with the account created or picked in the convert dialog. | | `AccountName` | Account Name | Calculated (calculated) | | Calculated: the Business Name, or else the first and last name. A new account created by conversion is named from it. | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | The customer's asset the lead concerns. Required on the service form and limited to the account's assets. When no account is chosen, the asset's owner becomes the lead's account. Copied to the opportunity and service order. | | `AssetMaintenanceId` | Asset Maintenance | Lookup → [AssetMaintenance](/docs/reference/entities/asset-maintenance/) | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch handling the lead. Required when the partner account has branches and limited to them. Set from the branch postal code mapping when the postal code matches. | | `CaseId` | Case | Lookup → [Case](/docs/reference/entities/case/) | | The support case the lead was created from by the case's Lead action. | | `City` | City | PickList | | The enquirer's city. Overwritten from the postal code list when the postal code matches. Copied to a new account's billing and shipping address on conversion. Values: Mumbai, Pune, Kolkata, Delhi. | | `ContactId` | Contact | Lookup → [Contact](/docs/reference/entities/contact/) | | The person at the account. Limited to the account's contacts; filled with the account's most recently created contact when empty. Conversion sets it to the contact it creates or links. | | `ContactName` | Contact Name | Text | | Retired. The contact's name comes from the lead's First Name and Last Name on conversion. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DateTimeOpened` | Date Time Opened | DateAndTime | | | | `DocumentDate` | Document Date | Date | | The lead's business date. Defaults to today on the first save. | | `DocumentSeriesField` | Document Series Field | Calculated (calculated) | | series | | `Email` | Email | Text | | The enquirer's email address. Must contain @. Becomes the contact's email on conversion and the email on a partner opportunity. | | `EventTaskCount` | Event Task Count | Boolean | | Retired. Activity roll-ups on the lead now set only Is Emailed Or Call; this count is no longer maintained. | | `FirstName` | First Name | Text | | The enquirer's given name. Filled from the selected account or, when empty, from the selected contact. At least one of First Name, Last Name or Business Name is required unless an account or contact is selected. Becomes the contact's first name on conversion. | | `Id` | Id | Guid | Yes | | | `InterestedItemId` | Interested Item | Lookup → [Item](/docs/reference/entities/item/) | | The product or service the enquirer wants. Conversion and the Order and Service Order actions add one line for it, quantity 1. | | `IsEmailedOrCalled` | Is Emailed Or Call | Boolean | | Set automatically when a Call or Email activity exists for the lead, and recalculated when activities change. The shipped Contacted status rule reads it. | | `ItemMaintenanceScheduleId` | Item Maintenance Schedule | Lookup → [ItemMaintenanceSchedule](/docs/reference/entities/item-maintenance-schedule/) | | The maintenance schedule that raised the lead, set by a campaign's Maintenance Schedule action. | | `ItemServiceContractId` | Item Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | The service contract behind the lead, set by a campaign's Contract Schedule action. Copied to the opportunity and service order. | | `LastName` | Last Name | Text | | The enquirer's family name. Filled from the selected account or, when empty, from the selected contact. Becomes the contact's last name on conversion. | | `LeadDueDate` | Lead Due Date | Date | | The date the underlying contract or maintenance work falls due. Set on leads raised by a campaign's Contract Schedule and Maintenance Schedule actions. | | `LeadRating` | Lead Rating | PickList | | How promising the lead is: Hot, Warm or Cold. Descriptive only; it does not affect conversion, assignment or scoring. Values: Hot, Warm, Cold. | | `LeadSource` | Lead Source | PickList | | Where the lead came from. Required on the create forms. Shipped values: Dealer, Campaign, Visit based, Web, Phone, Email, AMC, Scheduled Maintenance, Employee Referal, Social Media. Values: Dealer, Campaign, Visit based, Web, AMC, Scheduled Maintenance, Employee Referal, Social Media. | | `LeadType` | Lead Type | PickList | | Retired. Campaign runs record their origin in Lead Source and in the campaign, contract and maintenance schedule links instead. Values: Recall, Maintenance Schedule, Manual, Contract Schedule. | | `LostReason` | Lost Reason | PickList | | Why the lead was lost, asked by the Lead Lost action: Customer Unresponsive, Timeline Constraints, Service Unavailability, Requirement Withdrawn, Budget Constraint, Competitor Selection, Duplicate, Service Not Aligned with Requirements. Mark Lost leaves it empty; merging sets Duplicate on the merged-away lead. Values: Others. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | The lead's document number, generated on the first save from the Lead Name Setting. The shipped format is L, the day, month and year, and a six-digit counter, joined by hyphens. | | `OpportunityId` | Opportunity | Lookup → [Opportunity](/docs/reference/entities/opportunity/) | | The opportunity created or linked by conversion. Once set, the lead cannot be converted again. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Your selling company handling the lead. Required on every save and must be an active partner account. Set from the branch postal code mapping when the postal code matches. Copied to the opportunity, order and service order. | | `PhoneNumber` | Phone Number | Text | | The enquirer's number. When the lead has no account, a phone number matching an existing account's phone links the lead to that account and fills its blank details. Must be a 10-digit Indian mobile number starting 6 to 9 when the country code is +91 or blank. Becomes the contact's mobile number on conversion. | | `PostalCode` | Postal Code | Text | | The enquirer's postal code. On every save it is matched to the postal code list, replaced with its standard spelling, and fills City, State and Country; if a branch postal code covers it, Branch and Partner Account are set from the mapping (the oldest mapping wins). An assignment rule covering Partner Account or Branch switches this routing off. A lead with a postal code does not need a partner account and branch for conversion and release. | | `PotentialRevenue` | Potential Revenue | Currency | | An estimate of what the lead is worth, for reporting. Not copied to records created from the lead. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | Free-text notes, ideally the customer's own words. Also filled by the Lead Lost dialog. Becomes the customer's voice on a service order raised from the lead. | | `ReminderOffsetNumber` | Reminder Offset Number | Number | | Which of the campaign's three reminder offsets (1, 2 or 3) raised the lead. Set by schedule-driven campaign runs. | | `ResourceId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | The executive handling the lead. Limited to active resources. On a new lead, a matching partner-resource assignment sets it, replacing any value entered, unless an assignment rule decides it. Becomes the executive on a released order and the service advisor on a service order. | | `CampaignBatchInstanceId` | Campaign Batch Instance | Text | | | | `CampaignId` | Campaign | Lookup → [Campaign](/docs/reference/entities/campaign/) | | The campaign that produced the lead. Limited to active, current campaigns of the lead's partner account or of no partner account. Set by campaign runs. | | `CampaignMemberId` | Campaign Member | Lookup → [CampaignMember](/docs/reference/entities/campaign-member/) | | The campaign member the lead was raised for, set by a campaign's Leads action. | | `ServiceContractItemId` | ServiceContractItem | Lookup → [Item](/docs/reference/entities/item/) | | The item the service contract was quoted against. Copied to the opportunity and service order with the contract. | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | The variant of the interested item, limited to that item's SKUs. Copied to the line created on the opportunity, sales order or service order. | | `State` | State | PickList | | The enquirer's state. Overwritten from the postal code list when the postal code matches. Copied to a new account's address on conversion. Values: Maharashtra. | | `Status` | Status | PickList | | The lead's stage: New, Contacted, Nurturing, Lost or Converted. Defaults to New. Shipped rules set Contacted when a call or email activity is logged and Converted when the lead is saved with an opportunity; once Converted or Lost it can no longer change. Lead Lost and Mark Lost set Lost; Advance Status moves New to Contacted to Nurturing. Values: New, Contacted, Nurturing, Lost, Converted. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `ConvertLead` | Lead | ServerAction (`ConvertLead`) | Full lead conversion in one step: when the lead has no account it creates a new customer Account named from the lead's AccountName plus a Contact for it; when an existing account is linked but has no primary contact it creates that contact; then it always creates an Opportunity carrying the lead's account/partner/branch/asset/contract links and stamps Lead.OpportunityId. Refused when OpportunityId is already set (already converted). Record types are mapped from the lead's record type to the Opportunity equivalent. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `EditInLine2` | Edit | EditInline | Edit | | `EditRow` | Edit | EditInline | Edit | | `LeadLost` | Lead Lost | ServerAction (`LeadLost`) | Lead Lost | | `New` | New | New | New | | `NewSales` | New | New | New | | `PerformLeadToOpportunity` | Perform Lead To Opportunity | ServerAction (`PerformLeadToOpportunity`) | Dialog-driven convert: arguments choose per record whether to create or reuse - CreateNewAccount/CreateNewContact/CreateNewOpportunity flags, explicit AccountId/ContactId/OpportunityId picks, AccountFields/ContactFields/OpportunityFields value arrays typed in the dialog, and an optional ConvertedStatus for the lead. ContactFields are applied for both new and existing accounts, and the created/selected account always wins over the lead's old account on the resulting Opportunity. Same preconditions as ConvertLead (no existing OpportunityId; partner/branch resolved). | | `PerformReleaseOpportunity` | Opportunity | ServerAction (`PerformReleaseOpportunity`) | Creates an Opportunity from the lead (OpportunityService.CreateOpportunityFromLead). Preconditions: the lead must not already have an OpportunityId, and PartnerAccountId + BranchId are mandatory unless the lead carries a PostalCode (which auto-resolves them). | | `PerformReleaseOrder` | Order | ServerAction (`PerformReleaseOrder`) | Creates a sales Order directly from the lead (OrderService.CreateOrderFromLead), skipping the opportunity/quote stages. PartnerAccountId and BranchId are mandatory unless PostalCode is set. | | `RunMacro` | Run Macro | ServerAction (`RunMacro`) | Runs a Macro's steps against this lead through the generic macro engine (IMacroRunner) - the same entity-agnostic RunMacro handler used on cases; no lead-specific behavior. | | `testLeadConvert` | Opportunity | ServerAction | convert Lead | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | AccountNamerequired | `AccountName`, Error | Account Name is mandatory. | Account Name is mandatory. | | Email Validation Rule | `Email`, Error | Enter Valid Email. | Enter Valid Email. | | Mobile Validation Rule | `PhoneNumber`, Error | Enter Valid No. | Enter Valid No. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | Branch For Partner Account - Service | | Branch For Partner Account | `BranchId` | | | Customer Account Filter | `AccountId` | | | Customer Account Filter | `AccountId` | Customer Account | | Executive Filter | `ResourceId` | Executive Filter | | Executive Filter | `ResourceId` | | | Partner Account Filter | `PartnerAccountId` | PartnerAccountFilter | | Partner Account Filter Service | `PartnerAccountId` | Partner Account | ## Related entities - [Campaign](/docs/reference/entities/campaign/) — looks up via `CampaignId` - [Contact](/docs/reference/entities/contact/) — looks up via `ContactId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — looks up via `AssetMaintenanceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Case](/docs/reference/entities/case/) — looks up via `CaseId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Item](/docs/reference/entities/item/) — looks up via `ServiceContractItemId` - [Item](/docs/reference/entities/item/) — looks up via `InterestedItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Opportunity](/docs/reference/entities/opportunity/) — looks up via `OpportunityId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [ItemMaintenanceSchedule](/docs/reference/entities/item-maintenance-schedule/) — looks up via `ItemMaintenanceScheduleId` - [CampaignMember](/docs/reference/entities/campaign-member/) — looks up via `CampaignMemberId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Campaign](/docs/reference/entities/campaign/) — referenced by via `LeadId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `LeadId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Leave Entitlement — entity reference URL: https://xmatix.com/docs/reference/entities/leave-entitlement/ Last reviewed: 2026-08-16 The declared leave allowance for a leave type, granted either to a single Resource or to a whole Resource Group. It is reference data only: no first-party service reads this entity. Nothing accrues into it, nothing decrements it when a Leave Request is approved, and no remaining-balance figure is derived from it anywhere in the platform, so approving leave far beyond the declared allowance is neither blocked nor detected. Read Fixed Count as a stated policy number, never as a live balance. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FixedCount` | Fixed Count | Number | | The declared number of days allowed for the leave type. Nothing reads it: it is not a balance, it is not reduced when leave is approved, and it is not checked when a request is raised. | | `Id` | Id | Guid | Yes | | | `LeaveTypeId` | Leave Type | Lookup → [LeaveType](/docs/reference/entities/leave-type/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceGroupId` | Resource Group | Lookup → [ResourceGroup](/docs/reference/entities/resource-group/) | | Lets an allowance be declared for a whole group of people instead of one person, as an alternative to the Resource pointer on the same row. Nothing enforces that exactly one of the two is set, and since no code reads entitlements at all, neither form has any runtime effect. | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [ResourceGroup](/docs/reference/entities/resource-group/) — looks up via `ResourceGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [LeaveType](/docs/reference/entities/leave-type/) — looks up via `LeaveTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Case](/docs/reference/entities/case/) — referenced by via `EntitlementId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Leave Request — entity reference URL: https://xmatix.com/docs/reference/entities/leave-request/ Last reviewed: 2026-08-16 A person's request for time off across a date range, keyed on Resource and never on Employee. Once it reads Approved the row has real effects: the payroll attendance calculation counts overlapping days of an unpaid leave type as Loss of Pay and shrinks payable days, mobile attendance reports the person as on leave for the day, and scheduling drops them from bookable-resource capacity. It never touches Leave Entitlement in any way. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Days` | Days | Calculated | | Not a day count despite the name - it is a boolean half-day flag, and the payroll attendance calculation halves the request's calendar span when it is true. It is also declared in metadata as a calculated field yet carries no formula, so nothing derives it; it is a plain stored bit. | | `FromDate` | From Date | Date | | | | `Id` | Id | Guid | Yes | | | `LeaveTypeId` | Leave Type | Lookup | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Reason` | Reason | MultiLineText | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | Leave is keyed on the Resource, not on Employee, so a leave request exists for people who have no payroll Employee record at all. Payroll reaches this row from the Resource side after resolving the employee it is paying. | | `Status` | Status | PickList | | Payroll and mobile attendance accept Approved or approved; scheduling accepts only the exact-case Approved. Any other wording leaves the request without effect anywhere in the platform. Values: Pending, Approved, Rejected, Cancelled. | | `ToDate` | To Date | Date | | The last day of the absence, and inclusive: payroll counts the span as this date minus From Date plus one day, clipped to the payroll period being calculated. A single-day request therefore has From Date and To Date equal. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Leave Type — entity reference URL: https://xmatix.com/docs/reference/entities/leave-type/ Last reviewed: 2026-08-16 The catalogue of leave categories, and the setting that decides whether an absence costs the employee pay. The payroll attendance calculation inspects both Type and Entitlement Type and treats leave of that type as unpaid when either value contains any of the markers unpaid, lwp, lop, lossofpay or leavewithoutpay, matched case-insensitively with spaces stripped. Nothing else in the platform branches on leave type. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EntitlementType` | Entitlement Type | PickList | | Seeded as Fixed, Grant or Based on entitlement. No entitlement or accrual engine exists, so none of these values produces any balance behaviour; the field's only functional effect is that payroll also scans it for unpaid markers, and none of the seeded values contains one. Values: Fixed, Grant, Based on entitlement. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Leave Type Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Type` | Type | PickList | | Seeded with Paid and Unpaid. Payroll does not compare it exactly - it scans the text for unpaid markers, so Unpaid triggers Loss of Pay and Paid does not, and any custom wording only counts as unpaid if it contains one of those markers. Values: Paid, Unpaid. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [LeaveEntitlement](/docs/reference/entities/leave-entitlement/) — referenced by via `LeaveTypeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Loan Recovery — entity reference URL: https://xmatix.com/docs/reference/entities/loan-advance-recovery/ Last reviewed: 2026-08-16 The audit row for one installment taken out of one payroll run against a loan or advance; the payroll calculation writes these, users do not create them. Each row records the amount recovered and the loan balance immediately after that recovery, so reading the rows in payroll-run order reconstructs the repayment history without recomputing anything. Recalculating a payroll run adds each row's amount back onto the loan balance and its open item before soft-deleting the row, so a deleted recovery means the money was returned to the loan rather than lost. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `LoanAdvanceId` | Loan Advance | Lookup → [LoanAdvance](/docs/reference/entities/loan-advance/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OutstandingAfter` | Outstanding After | Currency | | The loan balance immediately after this installment was taken, written once at calculation time. It is a point-in-time snapshot rather than a live figure, so reading the rows in run order reconstructs the repayment history without recomputing anything. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PayrollPeriodId` | Payroll Period | Lookup → [PayrollPeriod](/docs/reference/entities/payroll-period/) | | | | `PayrollRunId` | Payroll Run | Lookup → [PayrollRun](/docs/reference/entities/payroll-run/) | | The run that took this installment. Recalculating that run adds this amount back onto the loan and its open item before soft-deleting the row, so recovery rows exist strictly per surviving run. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this LoanAdvanceRecovery. | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `Edit` | Edit | Edit | Edit this LoanAdvanceRecovery. | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | EditInLine | | `New` | New | NewInline | Create a LoanAdvanceRecovery. | | `View` | View | View | View this LoanAdvanceRecovery. | ## Related entities - [PayrollPeriod](/docs/reference/entities/payroll-period/) — looks up via `PayrollPeriodId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [LoanAdvance](/docs/reference/entities/loan-advance/) — looks up via `LoanAdvanceId` - [PayrollRun](/docs/reference/entities/payroll-run/) — looks up via `PayrollRunId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Loan / Advance — entity reference URL: https://xmatix.com/docs/reference/entities/loan-advance/ Last reviewed: 2026-08-16 An employee salary advance, travel advance or loan, disbursed from a bank or cash account and then recovered through payroll in installments, keyed on Resource. Disbursing it debits the Employee Loan or Employee Advance control and credits the bank account, raises a Resource-keyed receivable open item, copies the principal into Outstanding Amount, stamps the disbursement date and moves Status from Requested to Active. Every subsequent payroll calculation then recovers the smaller of Installment Amount and Outstanding Amount from any Active loan where both are positive, writing a deduction line against the control account, a LoanAdvanceRecovery audit row, a reduced outstanding balance and a reduced open item, and flipping Status to Closed at zero. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AdvanceType` | Advance Type | PickList | | Decides which control account the disbursement hits, through a single exact comparison: only the literal Loan selects the Employee Loan control and every other value falls through to Employee Advance. The seeded list works against that, offering Personal Loan, Home Loan, Vehicle Loan and Education Loan which all post to the advance control, plus duplicate SalaryAdvance and Salary Advance entries. Values: Salary Advance, Travel Advance, Loan, Salary Advance, Personal Loan, Vehicle Loan, Education Loan, Home Loan. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `ControlGLAccountId` | Control GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The Employee Loan or Employee Advance control account that disbursement debits and every payroll recovery credits. Leaving it empty is normal: disbursement resolves it from the partner account's control accounts by advance type and writes the resolved account back, refusing to post if none is configured. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DisbursementDate` | Disbursement Date | Date | | Stamped by the disbursement action with the journal date it used; empty means the money has not gone out. It is not the date recovery begins - recovery starts with the next payroll run once the loan is Active. | | `EndPayrollPeriodId` | End Payroll Period | Lookup → [PayrollPeriod](/docs/reference/entities/payroll-period/) | | Intended to bound the recovery schedule, but the payroll calculation does not read it. Recovery continues in every run while the loan is Active with a positive balance and installment, and stops only when the balance reaches zero. | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The default bank or cash account credited when the disbursement action is run without an explicit account argument. It is not the loan's control account, which is held separately in Control GL Account. | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | The disbursement journal, and the already-disbursed guard: a loan that already has a value here refuses to disburse again rather than paying the money out twice. | | `Id` | Id | Guid | Yes | | | `InstallmentAmount` | Installment Amount | Currency | | | | `InterestRate` | Interest Rate | Currency | | Stored but never used - no first-party code computes interest on an employee loan. Recovery simply takes the flat installment amount until the principal is repaid, so a rate entered here changes nothing about what is deducted. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OpenTransactionId` | Open Transaction | Lookup → [OpenTransaction](/docs/reference/entities/open-transaction/) | | The Resource-keyed receivable open item created at disbursement, which carries the recoverable balance for ageing and reconciliation. Payroll recovery reduces its open amount in step with the loan and marks it Settled once nothing is left. | | `OutstandingAmount` | Outstanding Amount | Currency | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PrincipalAmount` | Principal Amount | Currency | | The amount disbursed, and the value copied into Outstanding Amount when the advance is posted. It must be greater than zero or disbursement is refused, and editing it after disbursement does not adjust the outstanding balance or the open item. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `StartPayrollPeriodId` | Start Payroll Period | Lookup → [PayrollPeriod](/docs/reference/entities/payroll-period/) | | Intended to mark the period recovery should begin in, but the payroll calculation does not read it. Recovery starts in the very next run after Status becomes Active, regardless of the period recorded here. | | `Status` | Status | PickList | | Values: Active, Closed. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this LoanAdvance. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this LoanAdvance. | | `EditInLine` | Edit | EditInline | Edit | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a LoanAdvance. | | `PostLoanAdvance` | Disburse | ServerAction (`PostLoanAdvance`) | Actually pays the money out and starts the recovery: it posts a payroll journal debiting the Employee Loan or Employee Advance control and crediting the bank or cash account given in the arguments (falling back to the loan's GL Account), raises a Resource-keyed receivable open item for the principal, sets Outstanding Amount to the principal, stamps the disbursement date and moves Status to Active so the next payroll run begins deducting installments. It refuses when the loan is already disbursed, has no Resource, has a principal of zero or less, or when no Employee Loan or Employee Advance control account is configured for the partner account. | | `View` | View | View | View this LoanAdvance. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `BranchId` | | | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `ControlGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [PayrollPeriod](/docs/reference/entities/payroll-period/) — looks up via `EndPayrollPeriodId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [PayrollPeriod](/docs/reference/entities/payroll-period/) — looks up via `StartPayrollPeriodId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [OpenTransaction](/docs/reference/entities/open-transaction/) — looks up via `OpenTransactionId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [InterestCharge](/docs/reference/entities/interest-charge/) — referenced by via `SourceRecordId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `SourceRecordId` - [LoanAdvanceRecovery](/docs/reference/entities/loan-advance-recovery/) — referenced by via `LoanAdvanceId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Lower Deduction Certificate — entity reference URL: https://xmatix.com/docs/reference/entities/lower-deduction-certificate/ Last reviewed: 2026-08-16 A lower or nil-deduction certificate held by a party - s.395 of the Income-tax Act 2025, Form 128 (erstwhile s.197 / Form 13). While valid and within its certified amount cap, the certificate's rate overrides the section rate for that party's deductions, and the deduction is reported with remarks code A (lower) or B (nil) citing the certificate number. Matched by section-code family so one certificate spans the dual-rate rows that share a code; consumption against the cap is tracked as deductions post. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CertificateNumber` | Certificate Number | Text | | | | `ConsumedAmount` | Consumed Amount | Currency | | Taxable base already deducted under this certificate, maintained as postings apply it - compared against ThresholdAmount to decide whether the certificate still covers the next deduction (Status moves to Exhausted when spent). | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IssuingForm` | Issuing Form | PickList | | Values: 128, 13. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NilDeduction` | Nil Deduction | Boolean | | True when the certificate authorizes NO deduction at all - reported with remarks code B; a lower (non-zero) certified rate reports code A. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account Id | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyAccountId` | Party Account Id | Lookup → [Account](/docs/reference/entities/account/) | | | | `RateOverride` | Rate Override | Currency | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SectionCode` | Section Code | Text | | | | `Status` | Status | PickList | | Values: Active, Exhausted, Expired, Cancelled. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TdsSectionId` | Tds Section Id | Lookup → [TdsSection](/docs/reference/entities/tds-section/) | | | | `ThresholdAmount` | Threshold Amount | Currency | | The certified amount cap: the certificate applies only up to this aggregate taxable base; beyond it deductions revert to the section rate. Empty means uncapped. | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `ValidFrom` | Valid From | Date | | | | `ValidTo` | Valid To | Date | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `DeleteListRow` | Delete | Delete | Delete | | `EditHeader` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [TdsSection](/docs/reference/entities/tds-section/) — looks up via `TdsSectionId` - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — referenced by via `LdcCertificateId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # LWF Rule — entity reference URL: https://xmatix.com/docs/reference/entities/lwfrule/ Last reviewed: 2026-08-16 The state-wise Labour Welfare Fund rule master: a flat employee and employer contribution for a state, with the deduction frequency (Monthly, HalfYearly or Annual), effective-dated. LWF is a fixed amount rather than a rate, and like PFRule and ESIRule this master is not consulted by the payroll calculation engine — an LWF deduction on a payslip is an ordinary salary-structure component. Scoped by StateCode and PartnerAccountId, and the platform's LWF helper simply returns the configured amount without applying the frequency. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EffectiveFrom` | Effective From | Date | | The date the state's revised contribution applies from. Not used for selection anywhere — the LWF helper is handed a rule by its caller rather than resolving one by date. | | `EmployeeAmount` | Employee Amount | Currency | | A flat contribution in currency, not a rate and not wage-linked — the platform's LWF helper returns this figure as-is. It is not consulted by the payroll run. | | `EmployerAmount` | Employer Amount | Currency | | The employer's flat contribution for the state, returned as-is by the LWF helper. In most states it is a multiple of the employee amount, but nothing here derives one from the other. | | `Frequency` | Frequency | Text | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StateCode` | State Code | Text | | The state whose Labour Welfare Fund rule this is. Labour welfare is a state subject, so a multi-state employer needs one row per state; nothing in the payroll calculation reads this master, so the code is not currently matched against an employee's work state anywhere. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this LWFRule. | | `DeleteBulk` | Delete | Delete | DeleteBulk | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `Edit` | Edit | Edit | Edit this LWFRule. | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit | | `New` | New | New | Create a LWFRule. | | `View` | View | View, inactive | View this LWFRule. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Macro Step — entity reference URL: https://xmatix.com/docs/reference/entities/macro-step/ Last reviewed: 2026-08-16 One ordered action inside a Macro, linked by macroId and executed in stepOrder sequence. stepType selects the action - SetField, SendTemplate, PauseSla, ResumeSla, AddNote, CreateTask or CloseCase - and the parameter fields are reused per type: SetField reads targetField and value, SendTemplate reads templateId, AddNote and CreateTask read value as the note text or task subject. The value text supports placeholder substitution from the target record's fields. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `MacroId` | Macro | Lookup → [Macro](/docs/reference/entities/macro/) | Yes | | | `StepOrder` | Step Order | Number | | Execution order within the macro - steps run strictly ascending by this number. | | `StepType` | Step Type | PickList | | Selects the action: SetField, SendTemplate, PauseSla, ResumeSla, AddNote, CreateTask or CloseCase. The parameter fields are interpreted per type - SetField uses targetField plus value, SendTemplate uses templateId, AddNote and CreateTask use value. Values: SetField, SendTemplate, PauseSla, ResumeSla, AddNote, CreateTask, CloseCase. | | `TargetField` | Target Field | Text | | For SetField/ChangeStatus: the metadata field to set (ChangeStatus falls back to Status when empty). For CallServerAction it is repurposed as the server-action name to invoke. Unused by other step types. | | `TemplateId` | Email Template | Guid | | The EmailTemplate rendered by a SendTemplate step (rendered against the target record; a failed render falls back to a stub draft rather than aborting the macro). Unused by other step types. | | `Value` | Value | Text | | Meaning depends on stepType: the value to assign for SetField, the note text for AddNote, the task subject for CreateTask. Supports placeholder substitution from the target record's fields. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditRow` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [Macro](/docs/reference/entities/macro/) — looks up via `MacroId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Macro — entity reference URL: https://xmatix.com/docs/reference/entities/macro/ Last reviewed: 2026-08-16 A reusable, named set of ordered MacroStep actions an agent runs against a record in one click - set a field, send an email template, pause or resume the SLA, add a note, create a task, or close the record. Declared for one target entity via entityName (defaults to Case, but the runner is entity-agnostic and any entity with a registered RunMacro action can use it); layoutId optionally restricts the launcher to one layout. runMode decides whether reversible field edits are staged into the open form for review (Review, the default) or persisted immediately (Save); irreversible steps such as notes, emails and tasks always run at execution time. Steps that need a field the entity lacks are skipped rather than failing the run, and every executed step is recorded as a polymorphic Activity on the record's timeline. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Category` | Category | PickList | | Optional grouping for the macro picker: Triage, Response, Closure or Escalation. Values: Triage, Response, Closure, Escalation. | | `Description` | Description | Text | | | | `EntityName` | Target Entity | Text | | The one entity this macro targets (e.g. Case). The runner refuses to run a macro against any other entity; when empty the macro is not entity-scoped. | | `IsActive` | Active | Boolean | | An inactive macro is refused at run time (the RunMacro action fails validation), so deactivating retires a macro without deleting its steps. | | `LayoutId` | Layout | Lookup | | When set, the macro's launcher appears only on that entity layout; when null it appears on all of the target entity's layouts. | | `Name` | Name | Text | | | | `RunMode` | Run mode | Text | | Review (the default, also used when null) stages the reversible field edits into the open form for the agent to check and save, running only the irreversible steps (notes, emails, tasks) immediately; Save applies and persists everything at once. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Related entities - [MacroStep](/docs/reference/entities/macro-step/) — referenced by via `MacroId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Milestone Config — entity reference URL: https://xmatix.com/docs/reference/entities/milestone-config/ Last reviewed: 2026-08-16 A custom SLA milestone definition under an SLAPolicy, beyond the built-in FirstResponse and Resolution milestones. targetMinutes is the deadline offset in working minutes from case open; completionFormula is a DynamicExpresso predicate over the Case that, when true, marks the milestone Met. Each active config produces a CaseMilestone timer when its policy is applied to a case. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CompletionFormula` | Completion Formula | Text | | DynamicExpresso predicate over the Case that, when it evaluates true, marks this custom milestone Met on the corresponding CaseMilestone timer. | | `IsActive` | Active | Boolean | Yes | | | `Name` | Name | Text | | | | `Order` | Order | Number | | | | `SLAPolicyId` | SLA Policy | Lookup → [SLAPolicy](/docs/reference/entities/slapolicy/) | Yes | | | `TargetMinutes` | Target (min) | Number | | | | `WarningPercent` | Warning % | Number | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditHeader` | Edit | EditInline | EditHeader | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditRow` | Edit | Edit | EditRow | | `NewHeader` | New | New | NewHeader | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Mobile Sync Failure — entity reference URL: https://xmatix.com/docs/reference/entities/mobile-sync-failure/ Last reviewed: 2026-08-16 A terminally-failed mobile outbox row, reported by the device once an offline store-and-forward mutation is rejected or conflicts and its retries are exhausted. The report itself rides the same outbox as a normal create against this entity, so it is durable and offline-safe. Rows are a diagnostic/triage surface for operations - resolutionStatus tracks that workflow (defaults Open) - and every column is nullable because the fields are populated from the failing row's own metadata. Devices only ever write here. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AppVersion` | App Version | Text, inactive | | | | `AttemptCount` | Attempt Count | Number, inactive | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeviceId` | Device | Text, inactive | | | | `ErrorMessage` | Error Message | LongMultiLineText, inactive | | | | `FailureReason` | Failure Reason | PickList, inactive | | Why the device gave up on the row: Rejected (terminal client error or retries exhausted) or Conflict (409/412 against a newer server version). | | `Id` | Id | Guid | Yes | | | `LastAttemptUtc` | Last Attempt (UTC) | DateAndTime, inactive | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OccurredUtc` | Occurred (UTC) | DateAndTime, inactive | | | | `Operation` | Operation | PickList, inactive | | The outbox operation that failed: Create, Update, Delete, Action or UploadFile. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Payload` | Payload | LongMultiLineText, inactive | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResolutionNotes` | Resolution Notes | LongMultiLineText, inactive | | | | `ResolutionStatus` | Resolution Status | PickList, inactive | | | | `ResolvedUtc` | Resolved (UTC) | DateAndTime, inactive | | | | `SourceEntityName` | Source Entity | Text, inactive | | | | `SourceRecordId` | Source Record Id | Text, inactive | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `UserName` | User | Text, inactive | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Monthly TDS Projection — entity reference URL: https://xmatix.com/docs/reference/entities/monthly-tds-projection/ Last reviewed: 2026-08-16 The month's salary-TDS projection for one employee: annual income projected forward, verified Chapter VI-A deductions applied, annual tax computed and spread over the months remaining in the financial year. It is the ONLY source of the salary TDS the payroll calculation deducts — the engine reads MonthlyTds for the employee and period and uses it verbatim for the TDS component, and nothing else writes this row in production, which is why Calculate always runs the projection first. Both tax regimes are computed on the same income facts and both are persisted alongside the recommendation and the annual saving, but the deduction always follows the elected Employee.TaxRegime. Note what the projection does NOT yet include: it builds its income facts from projected annual gross and Chapter VI-A claims only, so section 10 exemptions such as HRA, the 16(iii) professional-tax deduction, perquisites, house-property loss and relief under section 89 are all treated as nil. Grain: one row per Resource per PayrollPeriod, replaced on each re-projection. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AnnualSaving` | Annual Saving | Currency | | | | `AppliedRegime` | Applied Regime | PickList | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FinancialYear` | Financial Year | Text | | The Indian financial year the projection is computed for, derived from the payroll period's end date with the year starting on 1 April and formatted as 2026-27. It is the key used to find the regime rule set, slab bands, surcharge bands and the employee's declaration. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `MonthlyTds` | Monthly Tds | Currency | | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PayrollPeriodId` | Payroll Period | Lookup → [PayrollPeriod](/docs/reference/entities/payroll-period/) | | The period this projection is for. Re-projecting soft-deletes any earlier row for the same employee and period rather than updating it, so history is preserved but only one live projection exists per employee per period. | | `ProjectedAnnualGross` | Projected Annual Gross | Currency | | The estimate of the employee's full-year salary that the tax is computed on: year-to-date gross from already-calculated runs in this financial year, plus the average of those months projected over the months that remain. | | `ProjectedAnnualTax` | Projected Annual Tax | Currency | | The full-year tax liability under the applied regime after slab tax, rebate, marginal relief, surcharge and cess, rounded to the statutory unit. It is the annual figure, not what is deducted this month — the monthly figure additionally nets off tax already withheld and divides by the months remaining. | | `RecommendedRegime` | Recommended Regime | PickList | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RegimeMismatch` | On Dearer Regime | Boolean | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | The employee, keyed on Resource rather than Employee — the payroll calculation looks the projection up by Resource and payroll period, which together form the row's effective grain. | | `RevisedAfterProof` | Revised After Proof | Boolean | | Intended to mark a projection recomputed after proof verification. Every code path that writes a projection sets it to false and nothing ever sets it true, so it cannot currently be used to identify post-verification revisions. | | `TaxableIncome` | Taxable Income | Currency | | | | `TaxableIncomeIfNew` | Taxable Income If New | Currency | | | | `TaxableIncomeIfOld` | Taxable Income If Old | Currency | | | | `TaxIfNewRegime` | Tax If New Regime | Currency | | | | `TaxIfOldRegime` | Tax If Old Regime | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this MonthlyTdsProjection. | | `DeleteBulk` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `Edit` | Edit | Edit | Edit this MonthlyTdsProjection. | | `EditEntity` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `New` | New | New | Create a MonthlyTdsProjection. | | `View` | View | View | View this MonthlyTdsProjection. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [PayrollPeriod](/docs/reference/entities/payroll-period/) — looks up via `PayrollPeriodId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Open Transaction — entity reference URL: https://xmatix.com/docs/reference/entities/open-transaction/ Last reviewed: 2026-08-16 One open AR/AP item per posted document — invoice, bill, credit or debit note, advance receipt or payment — created at posting time by DocumentJournalPostingService and reduced by SettlementAllocation rows. Direction (Receivable or Payable) and ControlGLAccountId place it in the right subledger; the source document is referenced polymorphically through SourceEntityName + SourceRecordId so a new document type needs no schema change. This is the table ageing, statements, balance confirmations, reminders, Rule 37 ITC reversal and the subledger-to-GL verification job all ride on: to answer "what does this party still owe", query OpenTransaction rather than summing document OpenAmount columns. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `ControlGLAccountId` | Control GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The control (reconciliation) GL account this open item rolls up to — receivables, payables or a tax account. Ageing reports scope themselves by joining this account and filtering on its account type, which is how an AP ageing separates supplier payables from tax payables. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Direction` | Direction | Text | | Receivable or Payable — which subledger the open item belongs to. It is set from the posting purpose, and credit documents flip the sign rather than the direction: a customer credit note is a Receivable item with a negative sign, a purchase return a Payable one. | | `DocumentDate` | Document Date | Date | | | | `DocumentNumber` | Document Number | Text | | | | `DueDate` | Due Date | Date | | When the item falls due; the axis ageing buckets are built on. DocumentDate is when it was raised, and the two differ by the party's payment terms. | | `GSTRegistrationId` | GST Registration | Lookup → [GSTRegistration](/docs/reference/entities/gstregistration/) | | | | `Id` | Id | Guid | Yes | | | `JournalId` | Journal | Lookup → [Journal](/docs/reference/entities/journal/) | | The journal whose posting created this open item, the link that lets the subledger be reconciled to the general ledger. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OpenAmount` | Open Amount | Currency | | What is still outstanding on this item. Maintained by SettlementAllocation rows — each allocation reduces it, and reversing an allocation adds the amount back and returns the status to Open. This is the authoritative outstanding figure for ageing and statements, in preference to the OpenAmount columns on the documents themselves. | | `OriginalAmount` | Original Amount | Currency | | The item's value when it was created at posting time. It never changes, so OriginalAmount minus OpenAmount is how much has been settled. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyAccountId` | Party Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer or supplier the item is owed to or by — the key for party ageing and statements. Distinct from PartnerAccountId, which carries the trading partner for partner-scoped reporting. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SourceEntityName` | Source Entity Name | Text | | Name of the entity that produced this open item ("Invoice", "Bill", "CreditNote", "DebitNote", "Payment", …). Paired with SourceRecordId it is a polymorphic reference, deliberately used instead of typed FKs so a new document type needs no schema change — which also means it must be filtered as a string, not joined. | | `SourceRecordId` | Source Record | Lookup → @sourceEntityName | | Id of the source document row, to be read together with SourceEntityName. Reversal of a posted document finds its open items by this pair and sets their status to Reversed. | | `Status` | Status | Text | | Open, PartiallySettled, Settled or Reversed. Reversed is set when the source document's posting is reversed, and reversing an allocation moves a Settled item back to Open — so exclude Reversed items rather than assuming Settled is terminal. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [GSTRegistration](/docs/reference/entities/gstregistration/) — looks up via `GSTRegistrationId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — looks up via `SourceRecordId` - [CreditNote](/docs/reference/entities/credit-note/) — looks up via `SourceRecordId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — looks up via `SourceRecordId` - [DebitNote](/docs/reference/entities/debit-note/) — looks up via `SourceRecordId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — looks up via `SourceRecordId` - [Journal](/docs/reference/entities/journal/) — looks up via `JournalId` - [Bill](/docs/reference/entities/bill/) — looks up via `SourceRecordId` - [PayrollRun](/docs/reference/entities/payroll-run/) — looks up via `SourceRecordId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — looks up via `SourceRecordId` - [Payment](/docs/reference/entities/payment/) — looks up via `SourceRecordId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `ControlGLAccountId` - [InterestCharge](/docs/reference/entities/interest-charge/) — looks up via `SourceRecordId` - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — looks up via `SourceRecordId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `SourceRecordId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — referenced by via `PayrollPayableOpenTransactionId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `OpenTransactionId` - [SettlementAllocation](/docs/reference/entities/settlement-allocation/) — referenced by via `OpenTransactionId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `EmployeePayableOpenTransactionId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `OpenTransactionId` - [JournalLine](/docs/reference/entities/journal-line/) — referenced by via `OpenTransactionId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Opportunity Line — entity reference URL: https://xmatix.com/docs/reference/entities/opportunity-line/ Last reviewed: 2026-08-16 One item or service position under an Opportunity (opportunityId + itemId + quantity). Carries resolved pricing the same way order lines do (priceListId/priceListRuleId, discountGroupRuleId, unitPrice/unitPrice2, per-line tax1..tax6 name/rate/amount slots plus taxGroupId) and package-configurator structure: isPackageService marks a configurable package line, isPackageComponent marks a component row, and packageOpportunityLineId points a component at its parent package line. When quote/order/service-order generation runs on the header, these lines are copied into QuoteLine / OrderLine / ServiceOrderLine rows that link back via their opportunityLineId. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AlternateItemId` | Alternate Item | Lookup → [ItemAlternate](/docs/reference/entities/item-alternate/) | | | | `Amount` | Amount | Calculated (calculated) | | | | `ApplyPostTaxDiscount` | Apply Post Tax Discount | Boolean | Yes | | | `AssetMaintenanceId` | Asset Maintenance | Lookup → [AssetMaintenance](/docs/reference/entities/asset-maintenance/) | | | | `AssetServiceContractId` | Asset Service Contract | Lookup → [AssetServiceContract](/docs/reference/entities/asset-service-contract/) | | | | `AssetServiceContractLineId` | Asset Service Contract Line | Lookup → [AssetServiceContractLine](/docs/reference/entities/asset-service-contract-line/) | | | | `BaseAmount` | BaseAmount | Calculated (calculated) | | | | `ContractDiscountAmount` | Contract Discount Amount | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DiscountAmount` | Discount Amount | Currency | | | | `DiscountAmount2` | Cash Discount Amount | Currency | | | | `DiscountGroupRuleId` | Discount Group Rule | Lookup → [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) | | | | `DurationInHours` | Duration In Hours | Decimal | | | | `ExternalId` | External | Text | | | | `GrossAmount` | Gross Amount | Calculated (calculated) | | | | `Id` | Id | Guid | Yes | | | `IsCancelled` | Cancelled | Boolean | Yes | | | `IsConfirmed` | Confirmed | Boolean | Yes | | | `IsPackageComponent` | Package Component | Boolean | Yes | | | `IsPackageService` | Package Service | Boolean | Yes | | | `IsPriceBundled` | Price Bundled | Boolean | Yes | | | `IsCampaignMandatory` | Campaign Mandatory | Boolean | Yes | | | `ItemAliasId` | Item Alias | Lookup → [ItemAlias](/docs/reference/entities/item-alias/) | | | | `ItemComponentId` | Item Component | Lookup → [ItemComponent](/docs/reference/entities/item-component/) | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | Yes | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ItemName` | Item Name | Text | | | | `ItemServiceContract2` | Service Contract Split 2 | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | | | `ItemServiceContractId` | Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | | | `ItemServiceContractId3` | Service Contract Split 3 | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NetDiscount` | Net Discount | Calculated (calculated) | | | | `OpportunityDiscount` | Opportunity Discount | Calculated | | | | `OpportunityId` | Opportunity | Lookup → [Opportunity](/docs/reference/entities/opportunity/) | | | | `OriginalItemId` | Original Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PackageClassification` | Package Classification | PickList | | Values: Packaged Item, Custom BOM Item. | | `PackageOpportunityLineId` | Package Opportunity Line | Lookup → [OpportunityLine](/docs/reference/entities/opportunity-line/) | | | | `PostingType` | Posting Type | PickList | | | | `PriceAsOnDate` | Price As On Date | Date | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `PriceListRuleId` | Price List Rule | Lookup → [PriceListRule](/docs/reference/entities/price-list-rule/) | | | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SchemeBenefitId` | Scheme Benefit | Lookup → [SchemeBenefit](/docs/reference/entities/scheme-benefit/) | | | | `CampaignId` | Campaign | Lookup → [Campaign](/docs/reference/entities/campaign/) | | | | `CampaignItemId` | Campaign Item | Lookup → [CampaignItem](/docs/reference/entities/campaign-item/) | | | | `ServiceContractItemId` | Service Contract Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ServiceContractWeightage` | Service Contract Weightage | Calculated (calculated) | | | | `ServiceRecommendationId` | Service Recommendation | Lookup → [ServiceRecommendation](/docs/reference/entities/service-recommendation/) | | | | `ServiceRequestDiscount` | Service Request Discount | Calculated (calculated) | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `Tax1` | Tax1 | Currency | | | | `Tax1Name` | TaxName1 | Text | | | | `Tax1Rate` | TaxRate1 | Currency | | | | `Tax1Type` | TaxType1 | Text | | | | `Tax2` | Tax2 | Currency | | | | `Tax2Name` | TaxName2 | Text | | | | `Tax2Rate` | TaxRate2 | Currency | | | | `Tax2Type` | TaxType2 | Text | | | | `Tax3` | Tax3 | Currency | | | | `Tax3Name` | TaxName3 | Text | | | | `Tax3Rate` | TaxRate3 | Currency | | | | `Tax3Type` | TaxType3 | Text | | | | `Tax4` | Tax4 | Currency | | | | `Tax4Name` | TaxName4 | Text | | | | `Tax4Rate` | TaxRate4 | Currency | | | | `Tax4Type` | TaxType4 | Text | | | | `Tax5` | Tax5 | Currency | | | | `Tax5Name` | TaxName5 | Text | | | | `Tax5Rate` | TaxRate5 | Currency | | | | `Tax5Type` | TaxType5 | MultiLineText | | | | `Tax6` | Tax6 | Currency | | | | `Tax6Name` | TaxName6 | Text | | | | `Tax6Rate` | TaxRate6 | Currency | | | | `Tax6Type` | TaxType6 | Text | | | | `TaxAmount` | Tax Amount | Currency | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `UIProps` | UI Props | Text | | | | `UnitPrice` | Unit Price | Number | | | | `UnitPrice2` | Unit Price | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListRow` | Delete | Delete | DeleteListRow | | `Edit` | Edit | Edit | Edit | | `Edit1` | Edit | Edit | EditHeader | | `Edit2` | Edit | EditInline | Edit | | `New` | New | NewInline | New Opportunity Line | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Quantity Rule Validation | `Quantity`, Error | Quantity should not be less than 0 | Quantity should not be less than 0 | | Unit Price Rule Validation | `UnitPrice`, Error | Unit Price can not be less than 0 | Unit Price can not be less than 0 | ## Related entities - [Item](/docs/reference/entities/item/) — looks up via `OriginalItemId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — looks up via `SchemeBenefitId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Opportunity](/docs/reference/entities/opportunity/) — looks up via `OpportunityId` - [AssetServiceContractLine](/docs/reference/entities/asset-service-contract-line/) — looks up via `AssetServiceContractLineId` - [ItemAlternate](/docs/reference/entities/item-alternate/) — looks up via `AlternateItemId` - [ServiceRecommendation](/docs/reference/entities/service-recommendation/) — looks up via `ServiceRecommendationId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) — looks up via `DiscountGroupRuleId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — looks up via `AssetMaintenanceId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId3` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — looks up via `PackageOpportunityLineId` - [ItemAlias](/docs/reference/entities/item-alias/) — looks up via `ItemAliasId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [Item](/docs/reference/entities/item/) — looks up via `ServiceContractItemId` - [ItemComponent](/docs/reference/entities/item-component/) — looks up via `ItemComponentId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [PriceListRule](/docs/reference/entities/price-list-rule/) — looks up via `PriceListRuleId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [CampaignItem](/docs/reference/entities/campaign-item/) — looks up via `CampaignItemId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContract2` - [Campaign](/docs/reference/entities/campaign/) — looks up via `CampaignId` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — looks up via `AssetServiceContractId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `OpportunityLineId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `OpportunityLineId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `PackageOpportunityLineId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `OpportunityLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Opportunity — entity reference URL: https://xmatix.com/docs/reference/entities/opportunity/ Last reviewed: 2026-10-10 An opportunity is a qualified deal being worked: the customer, the items or services under negotiation with their prices, and the record quotes, sales orders and service orders are raised from. It has three record types (Sales, Service, Partner) and appears in the CRM, Service and Partner Onboarding apps. It is created directly, by converting a lead or a case, or by a campaign run, and is numbered from document numbering (shipped series OP). Status starts as Prospecting; shipped business rules move it to Appointment/Quote when a quote, demo or appointment exists and to Closed Won when an order, service order or partner application is linked. Partner Account and Branch are locked after the first save. The Quote action copies every line into a new quote each time it runs; the Order and Service Order actions release each line's pending quantity and can run again until nothing is pending. Step-by-step procedures are on the Opportunities page of the CRM documentation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer the deal is with. Only active customer accounts can be picked. When left empty it is filled from the selected asset's owner, from the originating lead, or from the account whose phone matches the opportunity's phone number. Choosing an account fills the names, phone, email, contact and both addresses from it. | | `AccountName` | Account Name | Text | | The customer's filing name, stored as text. It defaults to the business name, or to first and last name when there is no business name, and is copied to the orders raised from the deal. | | `AdjustedAdvanceAmount` | Adjusted Advance Amount | Currency | | | | `AdvanceAmount` | Advance Amount | Currency | | | | `Amount` | Amount | Calculated (calculated) | | | | `AppointmentDate` | Appointment Date | DateAndTime | | | | `AppointmentTimeSlotId` | Appointment Time Slot | Lookup → [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) | | | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | The customer's asset for a service opportunity, required on the service form and limited to the account's assets. When the account is empty it is filled from the asset's owner, and open campaign items on the asset are added as lines. | | `AssetServiceContractId` | Asset Service Contract | Lookup → [AssetServiceContract](/docs/reference/entities/asset-service-contract/) | | The asset's service contract; only contracts valid today can be picked. | | `BillingAddress` | Billing Address | Text | | | | `BillingAddressId` | Billing Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `BillingCity` | Billing City | PickList | | Values: Mumbai, Pune, Chandigarh. | | `BillingCityPlaceId` | Billing City Place | Lookup → [Place](/docs/reference/entities/place/) | | Values: Pune, Mumbai, Chandigarh. | | `BillingContactAddressId` | Billing Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `BillingCountry` | Billing Country | PickList | | Values: India. | | `BillingPostalCode` | Billing Postal Code | Text | | Entering a postal code fills the billing city, state, region and country from the postal-code master. | | `BillingRegion` | Billing Region | Text | | | | `BillingState` | Billing State | PickList | | Values: Haryana, Maharashtra, New Delhi, Punjab. | | `BillingStreet` | Billing Street | Text | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The selling branch. It must belong to the partner account and be active, and it cannot be changed after the opportunity is saved. | | `CancellationReason` | Cancellation Reason | PickList | | | | `CaseId` | Case | Lookup → [Case](/docs/reference/entities/case/) | | The case the opportunity was converted from. | | `ContactId` | Contact | Lookup → [Contact](/docs/reference/entities/contact/) | | The contact person, limited to the account's contacts. It defaults to the account's most recently created contact or the lead's contact. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CustomerVoice` | Customer Voice | Text | | | | `DealerOnboardingId` | Dealer Onboarding | Lookup → [DealerOnboarding](/docs/reference/entities/dealer-onboarding/) | | | | `Discount` | Discount | Number | | A header discount percentage. Changing it on a saved opportunity applies it to every line. Not shown on the shipped layouts. | | `DiscountGroupId` | Discount Group | Lookup → [DiscountGroup](/docs/reference/entities/discount-group/) | | The discount group for the deal, set automatically on save. Not shown on the shipped layouts. | | `DocumentDate` | Document Date | Date | | The business date of the deal. Lead conversion and campaign runs set it to the current date. It is used as the price date for lines when no price-as-on date is set. | | `DropOffAddressId` | Drop Off Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `ExternalId` | External | Text | | | | `FailureDate` | Failure Date | Date | | | | `Id` | Id | Guid | Yes | | | `IsAppointmentGenerated` | Is Appointment Generated | Boolean | | Calculated: true once the opportunity has at least one product demo or appointment. | | `IsCancelled` | Cancelled | Boolean | Yes | | | `IsConfirmed` | Confirmed | Boolean | Yes | | | `IsDropOffRequired` | Drop Off Required | Boolean | Yes | | | `IsFieldService` | Field Service | Boolean | Yes | | | `IsKPICalculated` | KPI Calculated | Boolean | Yes | Set once the opportunity has been posted to performance KPIs. | | `IsLinePopulated` | Line Populated | Boolean | Yes | | | `IsPickUpRequired` | Pick Up Required | Boolean | Yes | | | `IsQuoteGenerated` | Quote Generated | Boolean | Yes | Set when the Quote action raises a quote. It records that a quote exists but does not stop another one being raised. | | `IsRepairOrderGenerated` | Repair Order Generated | Boolean | Yes | | | `IsSaleOrderGenerated` | Sale Order Generated | Boolean | Yes | Stamped by PerformGenerateOrder together with OrderId when the sales Order is created from this opportunity; generation is skipped when OrderId is already set. | | `ItemServiceContractId` | Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | Labelled Service Contract. Choosing it adds the pending lines of the asset's service contract, and the contract's usage band limits the usage readings. | | `JobType` | Job Type | PickList | | | | `LeadId` | Lead | Lookup → [Lead](/docs/reference/entities/lead/) | | The lead the opportunity was converted from. | | `LinesSubtotal` | Total Line Amount | Calculated (calculated) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | The opportunity's document number, generated on save from the Opportunity Name Setting. The shipped format is OP, the day, month and year, and a six-digit counter, joined by hyphens. | | `OpenAmount` | Open Amount | Calculated (calculated) | | Calculated: equal to Total Amount. | | `OpportunityTimeSlotBookingId` | Opportunity Time Slot Booking | Lookup → [BranchTimeSlotBooking](/docs/reference/entities/branch-time-slot-booking/) | | | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | The first sales order raised from the opportunity. Further orders can be raised while lines have pending quantity; all of them link back to the opportunity. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PackageServiceId` | Package Service | Lookup → [Item](/docs/reference/entities/item/) | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The selling company that owns the deal. Only active partner accounts can be picked. It is validated together with Branch on create and cannot be changed after the opportunity is saved; it is copied to every quote and order raised from it. | | `PerformCancel` | Perform Cancel | Boolean | Yes | | | `PerformConfirm` | Perform Confirm | Boolean | Yes | | | `PerformGenerateQuote` | Perform Generate Quote | Boolean | | | | `PerformGenerateRepairOrder` | Perform Generate Repair Order | Boolean | Yes | | | `PerformGenerateSaleOrder` | Perform Generate Sale Order | Boolean | Yes | | | `PerformKPICalculation` | Perform KPI Calculation | Boolean | Yes | | | `PerformPopulateLines` | Perform Populate Lines | Boolean | Yes | | | `PickUpAddressId` | Pick Up Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `PickUpAssignedToId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `PopulateAssetMaintenance` | Populate Asset Maintenance | Boolean | | | | `PriceAsOnDate` | Price As On Date | Date | | The date prices are taken from. Changing it on a saved opportunity reprices every line from the price list. Not shown on the shipped layouts. | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | The sale price list for the deal, set automatically on save. Not shown on the shipped layouts. | | `QuoteForServiceContractId` | Quote For Service Contract | Lookup → [Quote](/docs/reference/entities/quote/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `RepairOrderId` | Repair Order | Lookup | | | | `RoundOff` | Round Off | Currency | | | | `SaleOrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | | | `ServiceAddress` | Service Address | Text | | | | `ServiceAdvisorId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | Labelled Executive: the resource handling the deal. It must be active and authorized for the partner account and branch. It becomes the executive on a generated sales order and the service advisor on a quote or service order. | | `CampaignBatchInstanceId` | Campaign Batch Instance | Text | | | | `CampaignId` | Campaign | Lookup → [Campaign](/docs/reference/entities/campaign/) | | The campaign whose run created the opportunity; a campaign run raises one opportunity per campaign member with one line per campaign item. | | `CampaignMemberId` | Campaign Member | Lookup → [CampaignMember](/docs/reference/entities/campaign-member/) | | | | `ServiceContractItemId` | Service Contract Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | The first service order raised from the opportunity. Further service orders can be raised while lines have pending quantity. | | `ServiceType` | Service Type | PickList | | Kind of service requested. Shipped values: Accidental Repairs, PDI, Paid Repairs, Warranty Repair. Values: Paid Repairs. | | `ServiceVanId` | Service Van | Lookup | | | | `ShippingAddress` | Shipping Address | Text | | | | `ShippingAddressId` | Shipping Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `ShippingCity` | Shipping City | PickList | | Values: Pune, Mumbai, Chandigarh. | | `ShippingCityPlaceId` | Shipping City | Lookup → [Place](/docs/reference/entities/place/) | | Values: Pune, Mumbai, Chandigarh. | | `ShippingContactAddressId` | Shipping Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `ShippingCountry` | Shipping Country | PickList | | Values: India. | | `ShippingPostalCode` | Shipping Postal Code | Text | | | | `ShippingRegion` | Shipping Region | Text | | | | `ShippingState` | Shipping State | PickList | | Values: Haryana, Maharashtra, Punjab, New Delhi, Delhi. | | `ShippingStreet` | Shipping Street | Text | | | | `Status` | Status | PickList | | The deal's stage. Shipped values: Prospecting (the default), Appointment/Quote and Closed Won; a tenant may add more. Shipped business rules set Appointment/Quote when a quote, product demo or appointment exists and Closed Won when a sales order, service order or partner application is linked. A partner application can only be raised at Closed Won. Values: Prospecting, Appointment/Quote, Closed Won. | | `Tax1` | Tax1 | Currency | | | | `Tax1Name` | TaxName1 | Text | | | | `Tax1Rate` | TaxRate1 | Currency | | | | `Tax1Type` | TaxType1 | Text | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `TaxId` | Tax | Lookup → [Tax](/docs/reference/entities/tax/) | | | | `TaxSupplyType` | Tax Supply Type | PickList | | Worked out on every save from the customer's address and the branch. Values: Within State. | | `TCSEligibleAmount` | TCS Eligible Amount | Currency | | | | `TotalAmount` | Total Amount | Calculated (calculated) | | Calculated: total line amount plus total tax. | | `TotalDiscountAmount` | Total Discount Amount | Calculated (calculated) | | | | `TotalLineBaseAmount` | Total Line Base Amount | Calculated (calculated) | | Calculated: quantity times unit price over the lines, before discounts, excluding discounted-item lines. | | `TotalLineGrossAmount` | Total Line Gross Amount | Calculated (calculated) | | | | `TotalLineTaxAmount` | Total Line Tax Amount | Calculated (calculated) | | | | `TotalQuantity` | Total Quantity | Calculated (calculated) | | | | `TotalTaxAmount` | Total Tax Amount | Calculated (calculated) | | | | `TotalTaxPostingAmount` | Total Tax Posting Amount | Calculated (calculated) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UsageReading` | Usage Reading | Decimal | | The asset's reading at intake. It cannot be lower than the asset's last recorded reading and must sit within the usage band of the service contract on the opportunity. | | `UsageReadingHours` | Usage Reading Hours | Decimal | | The asset's hours reading at intake, with the same checks as Usage Reading. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `ApplyPackageConfiguration` | Apply Package Configuration | ServerAction (`ApplyPackageConfiguration`) | Writes a package line's component selection: requires LineId and a components array of {ItemComponentId, Quantity, IsSelected}; the service applies the selection to the package's component lines under that opportunity line. | | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Deletedoc` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `DeleteList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditRow` | Edit | EditInline | Edit | | `GetConfigurableItems` | Get Configurable Items | ServerAction (`GetConfigurableItems`) | Read-only package-configurator query: returns the opportunity's lines that are configurable packages (ItemComponentService.GetConfigurableItemsForOpportunityAsync). No state change. | | `GetPackageConfiguration` | Get Package Configuration | ServerAction (`GetPackageConfiguration`) | Read-only: returns the component configuration of one package line - requires a LineId argument; component pricing is resolved for the opportunity's partner account. No state change. | | `New` | New | New | New | | `PerformGenerateOrder` | Order | ServerAction (`PerformGenerateOrder`) | Creates a sales Order from the opportunity (skipped when OrderId is already set) and stamps OrderId + IsSaleOrderGenerated. Order lines are not copied here - the order pipeline creates them from the opportunity's lines via the new order's OpportunityId during the order save. | | `PerformGenerateQuote` | Quote | ServerAction (`PerformGenerateQuote`) | Creates a Quote from the opportunity: copies account/partner/branch/asset/service fields onto a new Quote (Quote.OpportunityId links back) and copies every OpportunityLine into a QuoteLine. Sets IsQuoteGenerated and refuses to run when it is already true. | | `PerformGenerateServiceOrder` | Service Order | ServerAction (`PerformGenerateServiceOrder`) | Creates a ServiceOrder from the opportunity (ServiceOrderService.CreateServiceOrderFromOpportunity), carrying the service-intake fields; the repair-order flow's generated flag is tracked on the opportunity (IsRepairOrderGenerated). | | `ProductConfigurator` | Product Configurator | ServerAction (`ProductConfigurator`) | ProductConfigurator | | `ProductDemo` | Book Appointment | ServerAction (`ProductDemo`) | ProductDemo | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Usage Reading blank | Error | Usage Reading Cannot be blank | Usage Reading Cannot be blank | | Usage Reading Validation Rule | `UsageReading`, Error | Usage Reading Cannot be Negative | Usage Reading Cannot be Negative | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | ASC for Asset filter | `AssetId` (inactive) | | | Asset Service Contract Filter | `AssetServiceContractId` | Asset | | Branch for PA | `BranchId` | Branch | | Branch For Partner Account | `BranchId` | | | Customer Account Filter | `AccountId` | | | Customer Account Filter | `AccountId` | Sales Opp | | Executive Filter | `ServiceAdvisorId` | | | PA Filter | `PartnerAccountId` | PA | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `ShippingAddressId` - [Resource](/docs/reference/entities/resource/) — looks up via `ServiceAdvisorId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `BillingContactAddressId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [BranchTimeSlotBooking](/docs/reference/entities/branch-time-slot-booking/) — looks up via `OpportunityTimeSlotBookingId` - [DealerOnboarding](/docs/reference/entities/dealer-onboarding/) — looks up via `DealerOnboardingId` - [Contact](/docs/reference/entities/contact/) — looks up via `ContactId` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — looks up via `AssetServiceContractId` - [Campaign](/docs/reference/entities/campaign/) — looks up via `CampaignId` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) — looks up via `AppointmentTimeSlotId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `BillingAddressId` - [Tax](/docs/reference/entities/tax/) — looks up via `TaxId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `PickUpAddressId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Place](/docs/reference/entities/place/) — looks up via `BillingCityPlaceId` - [Lead](/docs/reference/entities/lead/) — looks up via `LeadId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [Item](/docs/reference/entities/item/) — looks up via `ServiceContractItemId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `DropOffAddressId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [DiscountGroup](/docs/reference/entities/discount-group/) — looks up via `DiscountGroupId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Case](/docs/reference/entities/case/) — looks up via `CaseId` - [Item](/docs/reference/entities/item/) — looks up via `PackageServiceId` - [Resource](/docs/reference/entities/resource/) — looks up via `PickUpAssignedToId` - [Order](/docs/reference/entities/order/) — looks up via `SaleOrderId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `ShippingContactAddressId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [CampaignMember](/docs/reference/entities/campaign-member/) — looks up via `CampaignMemberId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Place](/docs/reference/entities/place/) — looks up via `ShippingCityPlaceId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [DealerOnboarding](/docs/reference/entities/dealer-onboarding/) — referenced by via `DealerOnboardingId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `OpportunityId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `OpportunityId` - [CheckInInspection](/docs/reference/entities/check-in-inspection/) — referenced by via `OpportunityId` - [Quote](/docs/reference/entities/quote/) — referenced by via `OpportunityId` - [Lead](/docs/reference/entities/lead/) — referenced by via `OpportunityId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `OpportunityId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `OpportunityId` - [Order](/docs/reference/entities/order/) — referenced by via `OpportunityId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Order Line — entity reference URL: https://xmatix.com/docs/reference/entities/order-line/ Last reviewed: 2026-08-16 One item position of a sales Order (OrderId plus ItemId and Quantity) carrying its own pricing, discount, tax and inventory context. Each processing stage keeps a cumulative counter that the platform rolls up from the child documents — FulfilmentOrderQuantity from inventory-fulfilment order lines, FulfilmentAllocatedQuantity from allocation lines, PickedQuantity and the three picking counters from picking lines, InvoiceQuantity (split into AllocatedInvoicedQuantity and OTCInvoicedQuantity) from invoice lines, DeliveryQuantity from delivery lines, ReturnedQuantity from credit-note lines — and every Pending* field is calculated as Quantity minus the relevant counter minus CancelledQuantity. The money fields are calculated too, not stored input: BaseAmount, then NetDiscount and NetSchemeDiscount, then Amount and GrossAmount. RequestedQuantity is virtual and exists only as the per-line argument of the order's Selective* actions. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AllocatedInvoicedQuantity` | Allocated Invoiced Quantity | Number | | The part of InvoiceQuantity that came from invoice lines carrying an InventoryFulfilmentAllocationLineId — quantity invoiced out of allocated stock. Its counterpart OTCInvoicedQuantity is the sum where that link is absent. | | `Amount` | Amount | Calculated (calculated) | | Calculated as BaseAmount less NetSchemeDiscount and NetDiscount — unless ApplyPostTaxDiscount is set, in which case the discounts are held back for GrossAmount and Amount is simply BaseAmount. Rolls up into Order.LineSubTotal. | | `ApplyPostTaxDiscount` | Apply Post Tax Discount | Boolean | | Switches the discount base for the whole line. When false, discounts come off BaseAmount before tax; when true they are computed on BaseAmount plus TaxAmount and subtracted after tax, which changes NetDiscount, NetSchemeDiscount, Amount and GrossAmount together. | | `BaseAmount` | Base Amount | Calculated (calculated) | | Calculated as (Quantity - CancelledQuantity) times the effective unit price, where UnitPrice2 takes precedence over UnitPrice whenever it is greater than zero. Every other money field on the line derives from it. | | `BenefitIndex` | Benefit Index | Number | | Positional selector for the applied benefit when a scheme line offers several; it is passed to ApplyScheme as benefitIndex and cleared again by ResetScheme. | | `BillingFrequency` | Billing Frequency | Text | | | | `BillingType` | Billing Type | PickList | | Values: Advance, Arrears. | | `BranchId` | Branch | Text | | | | `CancelledQuantity` | Cancelled Quantity | Number | | Cumulative cancelled quantity, increased by CancelOrder and SelectiveCancelOrder by the line's pending fulfilment quantity (or by the requested amount). It is subtracted in BaseAmount and in every Pending* formula, so cancelling both stops further processing and reduces the line's value. | | `ChargeType` | Charge Type | PickList | | Values: One Time, Recurring, Usage. | | `ContractDiscount` | Contract Discount | Percent | | | | `ContractDiscountAmount` | Contract Discount Amount | Currency | | Explicit value of the third discount pair; it overrides the ContractDiscount percentage inside NetDiscount and is one of the fields copied across when order lines are generated from a quote or an opportunity. | | `ConversionRatio` | Conversion Ratio | Number | | | | `ConversionRatio1` | Conversion Ratio 1 | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeliveryQuantity` | Delivery Quantity | Number | | Cumulative delivered quantity, rolled up from delivery-order lines. It reduces PendingDeliveryQuantity and is also subtracted inside PendingPickingQuantity, so despatching picked stock closes the picking loop. | | `Discount` | Discount | Percent | | Regular discount percentage. On insert a non-zero header Order.Discount overwrites it, and on save it is forced to zero whenever DiscountAmount is supplied — the explicit amount always wins. | | `Discount2` | Discount2 | Decimal | Yes | | | `DiscountAmount` | Discount Amount | Currency | | Explicit regular discount value. Supplying it zeroes the Discount percentage on save and takes precedence over it inside NetDiscount. | | `DiscountAmount2` | Cash Discount Amount | Currency | | Explicit value of the second, independent discount pair, labelled 'Cash Discount Amount'. Supplying it zeroes the Discount2 percentage on save and takes precedence over it inside NetDiscount, where it is added on top of the regular and contract discounts. | | `DiscountGroupRuleId` | Discount Group Rule | Lookup → [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) | | | | `ExcludeInAutoOrder` | Exclude In Auto Order | Boolean | | | | `ExternalId` | External | Text, unique | | | | `FulfilmentAllocatedQuantity` | Fulfilment Allocated Quantity | Number | | Cumulative quantity reserved against specific stock lots, rolled up from InventoryFulfilmentAllocationLine.Quantity. It is the base of PendingFulfilmentAllocationQuantity, of PendingPickingQuantity and of the allocation-backed invoicing path. | | `FulfilmentOrderQuantity` | Fulfilment Order Quantity | Number | | Cumulative quantity placed on inventory fulfilments, rolled up automatically from InventoryFulfilmentOrderLine.Quantity — the handler treats it as a system field, so it is never entered by hand. PendingFulfilmentOrderQuantity is Quantity minus this minus CancelledQuantity. | | `GrossAmount` | Gross Amount | Calculated (calculated) | | Calculated line total: Amount plus TaxAmount, minus the scheme and regular discounts when ApplyPostTaxDiscount is set (they were already removed inside Amount otherwise). Rolls up into Order.TotalOrderAmount and Order.TotalLineGrossAmount. | | `Id` | Id | Guid | Yes | | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | Set once the line has been posted to the inventory ledger. PerformInventoryPosting selects exactly the lines where it is still empty, so it doubles as the already-posted marker and the action fails validation when no such line remains. | | `InventoryStockId` | Stock | Lookup → [InventoryStock](/docs/reference/entities/inventory-stock/) | | The InventoryStock bucket resolved for this line's item, SKU, lot type and storage location. It is resolved on insert and re-resolved whenever any of those four fields change, and it is what StockAvailable and StockInHand read through. | | `InvoiceGroup` | Invoice Group | PickList | | Values: Product, Part, Insurance. | | `InvoiceQuantity` | Invoice Quantity | Decimal | | Cumulative invoiced quantity, rolled up from InvoiceLine.Quantity and split in the same pass into AllocatedInvoicedQuantity and OTCInvoicedQuantity depending on whether the invoice line carries an allocation line. PendingInvoiceQuantity is Quantity minus CancelledQuantity minus this. | | `IsILPosted` | IL Posted | Boolean | | | | `IsILPostingApproved` | IL Posting Approved | Boolean | | | | `IsPriceBundled` | Price Bundled | Boolean | | Marks the line as priced inside a bundle. Validation rejects saving such a line with a UnitPrice above zero, on the update path as well as on insert. | | `IsSchemeGenerated` | Scheme Generated | Boolean | | True on lines the promotion engine created as a scheme benefit rather than lines a user entered. The engine excludes such lines when it aggregates the document to test scheme qualification, so generated benefit lines cannot themselves earn further benefits. | | `ItemAliasId` | Item Alias | Lookup → [ItemAlias](/docs/reference/entities/item-alias/) | | | | `ItemAlternateId` | Item Alternate | Lookup → [ItemAlternate](/docs/reference/entities/item-alternate/) | | | | `ItemComponentId` | Item Component | Lookup → [ItemComponent](/docs/reference/entities/item-component/) | | The package component definition this exploded line came from. It is the identifier supplied to ApplyPackageConfiguration when choosing and sizing the components of a configurable package line. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | Yes | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | A specific stock lot named on the line. When fulfilment is released, this value is copied onto the inventory fulfilment order line that is created, alongside the line's item, SKU and storage location. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ItemName` | Item Name | Text | | | | `ItemServiceContractId` | Item Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | | | `LimitExpiryDays` | Limit Expiry Days | LargeNumber | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `NetDiscount` | Net Discount | Calculated (calculated) | | Calculated total of the three discount pairs — regular (Discount / DiscountAmount), cash (Discount2 / DiscountAmount2) and contract (ContractDiscount / ContractDiscountAmount). Within each pair an explicit amount overrides the percentage, and a percentage is taken on BaseAmount, or on BaseAmount plus TaxAmount when ApplyPostTaxDiscount is set. | | `NetSchemeDiscount` | Net Scheme Discount | Calculated (calculated) | | Calculated promotion discount for the line: SchemeDiscountAmount when supplied, otherwise SchemeDiscount applied as a percentage of BaseAmount (or of BaseAmount plus TaxAmount when ApplyPostTaxDiscount is set). Held separately from NetDiscount so promotion value can be reported on its own. | | `OpportunityLineId` | Opportunity Line | Lookup → [OpportunityLine](/docs/reference/entities/opportunity-line/) | | | | `OrderDiscount` | Order Discount | Calculated (calculated) | | Calculated mirror of the parent Order.Discount, refreshed whenever the header discount changes. On insert a non-zero value is copied into the line's own Discount, and it is that copy — not this field — which feeds NetDiscount. | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | | | `OriginalItemId` | Original Item | Lookup | | | | `OTCInvoicedQuantity` | OTC Invoiced Quantity | Number | | Over-the-counter invoiced quantity: the part of InvoiceQuantity from invoice lines with no allocation line behind them. Credit notes raised against this line add back into it alongside InvoiceQuantity. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PackageOrderLineId` | Order Line | Lookup → [OrderLine](/docs/reference/entities/order-line/) | | Self-reference to the parent package line: component lines exploded from a package item point back at the line that owns them. Editing the parent's quantity recalculates the children, deleting the parent cascades to them, and changing Item or SKU on either a package line or a component is rejected. | | `PartnerAccountId` | Partner Account | Calculated | | | | `PendingAllocatedInvoicedQuantity` | Pending Allocated Invoiced Quantity | Calculated (calculated) | | Calculated: for an inventory-tracked item it is FulfilmentAllocatedQuantity minus AllocatedInvoicedQuantity — reserved but not yet billed; for an item that does not track inventory it falls back to PendingInvoiceQuantity. | | `PendingDeliveryQuantity` | Pending Delivery Quantity | Calculated (calculated) | | | | `PendingFulfilmentAllocationQuantity` | Pending Fulfilment Allocation Quantity | Calculated (calculated) | | | | `PendingFulfilmentOrderQuantity` | Pending Fulfilment Order Quantity | Calculated (calculated) | | | | `PendingInvoiceQuantity` | Pending Invoice Quantity | Calculated (calculated) | | | | `PendingPickingQuantity` | Pending Picking Quantity | Calculated (calculated) | | | | `PickedQuantity` | Picked Quantity | Number | | Cumulative quantity picked, rolled up from InventoryFulfilmentPickingLine.Quantity together with the three other picking counters. Note that PendingPickingQuantity is built from PickingRequestedQuantity rather than from this field. | | `PickingCancelQuantity` | Picking Cancel Quantity | Number | | | | `PickingRequestedQuantity` | Picking Requested Quantity | Number | | Cumulative quantity requested on picking lines, rolled up from InventoryFulfilmentPickingLine.RequestedQuantity. PendingPickingQuantity subtracts it (and DeliveryQuantity) from FulfilmentAllocatedQuantity and adds back PickingCancelQuantity and PickingReturnQuantity, so requesting a pick immediately removes that quantity from the pickable pool and cancelling or returning it puts it back. | | `PickingReturnQuantity` | Picking Return Quantity | Number | | | | `PriceAsOnDate` | Price As On Date | Date | | Per-line pricing date, which takes precedence over the order's PriceAsOnDate when the engine picks the effective PriceListRule. Changing it, PriceListId or PriceListRuleId re-resolves the line's prices on save. | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `PriceListRuleId` | Price List Rule | Lookup → [PriceListRule](/docs/reference/entities/price-list-rule/) | | | | `PurchaseOrderLineId` | Purchase Order Line | Lookup → [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) | | Links the line to the purchase order line it was generated from in the dealer flow. Inserting such a line, or changing its quantity, rolls that quantity up into the purchase order line's OrderQuantity. | | `Quantity` | Quantity | Number | Yes | The ordered quantity and the base for every stage counter — each Pending* field is Quantity minus what has already passed that stage minus CancelledQuantity. Reducing it below what has already been processed is rejected by the order service's quantity validation on update. | | `QuoteLineId` | Quote Line | Lookup → [QuoteLine](/docs/reference/entities/quote-line/) | | Back-reference to the quote line this order line was copied from when the order was inserted with a QuoteId; the equivalent for the opportunity path is OpportunityLineId. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedQuantity` | Requested Quantity | Decimal | | | | `ReturnedQuantity` | Returned Quantity | Number | | Cumulative quantity returned through credit notes, rolled up from CreditNoteLine.Quantity against this line. It does not appear in any Pending* formula, so a return does not by itself reopen the line for fulfilment or invoicing. | | `RNAExternalId` | RNA External | Text | | | | `RNAOrderExternalId` | RNA Order External | Text | | | | `SchemeBenefitId` | Scheme Benefit | Lookup → [SchemeBenefit](/docs/reference/entities/scheme-benefit/) | | | | `SchemeDiscount` | Scheme Discount | Percent | | | | `SchemeDiscountAmount` | Scheme Discount Amount | Currency | | | | `SchemeLineId` | Scheme Line | Lookup → [SchemeLine](/docs/reference/entities/scheme-line/) | | The scheme line that was applied to this order line. It is the identifier the ApplyScheme action requires in its arguments, and that action rejects an id which does not reference an existing scheme line. | | `SchemeRewardPoints` | Scheme Reward Points | LargeNumber | | Reward points earned on this line from an applied scheme benefit. They are stamped onto the document's non-generated lines and are what the scheme ledger reads as its RewardPoints when the benefit is recorded. | | `SkipScheme` | Skip Scheme | Boolean | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StockAvailable` | Stock Available | Calculated (calculated) | | Calculated pass-through of the linked InventoryStock.Available, or zero when InventoryStockId is empty. It is free-to-promise quantity at the line's item, SKU, lot type and storage location, refreshed whenever any of those change. | | `StockInHand` | Stock In Hand | Calculated (calculated) | | Calculated pass-through of the linked InventoryStock.InHand — the physical quantity held, which still includes stock reserved for other demand. Compare it with StockAvailable before promising a quantity. | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | Storage location the line draws from. It participates in resolving InventoryStockId, and it is carried onto the inventory fulfilment order line created when fulfilment is released. | | `Tax1` | Tax 1 | Currency | | | | `Tax1Name` | Tax Name 1 | Text | | | | `Tax1Rate` | Tax Rate 1 | Currency | | | | `Tax1Type` | Tax Type 1 | Text | | | | `Tax2` | Tax 2 | Currency | | | | `Tax2Name` | Tax Name 2 | Text | | | | `Tax2Rate` | Tax Rate 2 | Currency | | | | `Tax2Type` | Tax Type 2 | Text | | | | `Tax3` | Tax 3 | Currency | | | | `Tax3Name` | Tax Name 3 | Text | | | | `Tax3Rate` | Tax Rate 3 | Currency | | | | `Tax3Type` | Tax Type 3 | Text | | | | `Tax4` | Tax 4 | Currency | | | | `Tax4Name` | Tax Name 4 | Text | | | | `Tax4Rate` | Tax Rate 4 | Currency | | | | `Tax4Type` | Tax Type 4 | Text | | | | `Tax5` | Tax 5 | Currency | | | | `Tax5Name` | Tax Name 5 | Text | | | | `Tax5Rate` | Tax Rate 5 | Currency | | | | `Tax5Type` | Tax Type 5 | Text | | | | `Tax6` | Tax 6 | Currency | | | | `Tax6Name` | Tax Name 6 | Text | | | | `Tax6Rate` | Tax Rate 6 | Currency | | | | `Tax6Type` | Tax Type 6 | Text | | | | `TaxAmount` | Tax Amount | Currency | | Total of the line's six tax slots; the handler treats it as a system field rather than user input. It feeds GrossAmount and rolls up into Order.TotalLineTaxAmount. | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `UIProps` | UI Props | Text | | | | `UnitPrice` | Unit Price | Currency | Yes | | | `UnitPrice2` | Unit Price 2 | Currency | | | | `UOM` | UOM | PickList | | Values: Pack, Each, Box, Barrel, Litres, MB, Minutes, Messages, kWh. | | `UOM1` | UOM 1 | PickList | | Values: Pack, Each, Box, Barrel, Litres, MB, Minutes, Messages, kWh. | | `UOMQuantity` | UOM Quantity | Decimal | | | | `UOMQuantity1` | UOM Quantity 1 | Decimal | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BarcodeQuickAdd` | Barcode Scanner | UIAction | Scan barcodes to add order lines | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditHeader` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `Import` | Import | UIAction | List-header action that opens the ImportSO layout to bring order lines in from a file rather than entering them one by one. It is a client-side layout action with no server action behind it; the imported rows go through the normal order-line save path. | | `NewInLine` | Quick Add | NewInline | Labelled 'Quick Add': adds an order line inline in the grid rather than through the full line form. The line handler still applies all its defaults on save — item alias, unit conversion, prices, taxes, discounts, stock resolution, package explosion and scheme processing — exactly as for a full-form insert. | | `ProductCatalogue` | Product Catalogue | UIAction | List-header button that opens the product catalogue layout for adding lines to the order. It names no server action, so pressing it runs nothing on the server. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Quantity Cancelled Rule Validation | `CancelledQuantity`, Error | Quantity cancelled cannot be greater than Quantity. | Quantity cancelled cannot be greater than Quantity. | | Quantity Rule Validation | `Quantity`, Error | Quantity should not be less than 0 | Quantity should not be less than 0 | | Track Asset Quantity Validation | `Quantity`, Error, inactive | Quantity cannot be greater than 1 for asset-tracked items. | When Track Asset is enabled on the Item, quantity cannot exceed 1. | | Unit Price Rule Validation | `UnitPrice`, Error | Unit Price can not be less than 0 | Unit Price can not be less than 0 | | Validate On Incorrect Item Alias | `ItemAliasId`, Error | Item Alias is not valid. | Item Alias is not valid. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Lot for Partner and Branch | `ItemLotId` | | | Lot Type for Item | `ItemLotTypeId` | | | Sku For Item | `SKUId` | | ## Related entities - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ItemComponent](/docs/reference/entities/item-component/) — looks up via `ItemComponentId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — looks up via `PriceListRuleId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — looks up via `OpportunityLineId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — looks up via `PurchaseOrderLineId` - [OrderLine](/docs/reference/entities/order-line/) — looks up via `PackageOrderLineId` - [ItemAlternate](/docs/reference/entities/item-alternate/) — looks up via `ItemAlternateId` - [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) — looks up via `DiscountGroupRuleId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [QuoteLine](/docs/reference/entities/quote-line/) — looks up via `QuoteLineId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — looks up via `InventoryStockId` - [ItemAlias](/docs/reference/entities/item-alias/) — looks up via `ItemAliasId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — looks up via `SchemeBenefitId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [Item](/docs/reference/entities/item/) — looks up via `OriginalItemId` - [SchemeLine](/docs/reference/entities/scheme-line/) — looks up via `SchemeLineId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `OrderLineId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `OrderLineId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `OrderLineId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `OrderLineId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `OrderLineId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `OrderLineId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `PackageOrderLineId` - [KYCDocument](/docs/reference/entities/kycdocument/) — referenced by via `OrderLineId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `OrderLineId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `PackageOrderLineId` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `OrderLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Order — entity reference URL: https://xmatix.com/docs/reference/entities/order/ Last reviewed: 2026-10-10 A sales order records what a customer has agreed to buy: the customer account, the selling partner account and branch, the executive, addresses and pricing context, with one order line per item. It appears in the Sales app (and Commerce) and on the mobile app, where field representatives take orders on visits with Take Order. It is created directly, from a quote (once per quote), from an opportunity (repeatable for pending quantity), on a visit, or as a dealer order from another organization's purchase order. It is numbered from document numbering (shipped series SO, separator -, date DDMMYYYY, six digits). Account, Branch and Document Date are locked once saved. Fulfilment, allocation, picking, delivery and invoicing are separate actions, each drawing only on a per-line pending quantity. Status starts at Draft and is moved by shipped business rules on save; Document State records the last action that succeeded. Cancel Order cancels the unreleased remainder. Step-by-step procedures are on the Creating and managing sales orders page of the Sales documentation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | Yes | The customer. Only active customer accounts can be picked. Locked once saved. Together with the partner account it identifies the credit limit checked when the order is first saved. | | `AccountName` | Account Name | Text | | | | `AccountPhone` | Phone | Text | | | | `AdjustedAdvanceAmount` | Adjusted Advance Amount | Currency | | How much of the advance has since been used. | | `AdvanceAmount` | Advance Amount | Currency | | Advance or deposit taken against the order. Open Amount is Total Amount less this. | | `AllocatedQuantity` | Allocated Quantity | Calculated (calculated) | | Order-level roll-up of OrderLine.FulfilmentAllocatedQuantity: how much of the order has been reserved against specific stock lots by the allocation actions. | | `AmountPaid` | Amount Paid | Currency | | Cash recorded as received against the order. It appears in two calculated fields: OutstandingAmount subtracts it (together with FinanceAmount) from the line subtotal plus tax, and TotalCreditAmount is AmountPaid minus FinanceAmount. | | `BillingAddress` | Billing Address | Text | | | | `BillingCity` | Billing City | PickList | | Values: Pune, Chandigarh, Mumbai. | | `BillingCityPlaceId` | Billing City | Lookup → [Place](/docs/reference/entities/place/) | | | | `BillingContactAddressId` | Billing Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `BillingCountry` | Billing Country | PickList | | Values: India. | | `BillingPostalCode` | Billing Postal Code | Text | | | | `BillingRegion` | Billing Region | Text | | | | `BillingState` | Billing State | PickList | | Values: Haryana, Maharashtra, New Delhi, Punjab. | | `BillingStreet` | Billing Street | Text | | Billing | | `BookingAmount` | Booking Amount | Currency | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The location the order is sold from. Must be active and belong to the partner account, and is required when the partner account has branches. Locked once saved. | | `ContactId` | Contact | Lookup → [Contact](/docs/reference/entities/contact/) | | The customer contact. Limited to the account's contacts and filled from the account's default contact when left empty. | | `ContactName` | Contact Name | Text | | | | `ContactNumber` | Contact Number | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Discount` | Discount | Number | | A header discount percentage. Changing it copies the value to every line as Order Discount. Not on the shipped forms. | | `DiscountGroupId` | Discount Group | Lookup → [DiscountGroup](/docs/reference/entities/discount-group/) | | The discount group line discounts come from. A matching group for the partner account, branch and account groups is set on save. | | `DocumentDate` | Document Date | Date | | The order's business date, stamped with the current date and time on save. A future date is set back to now. Locked once saved. | | `ExecutiveId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | Labelled Executive: the sales person responsible for the order. Required on the shipped web form and must be an active resource allowed to sell for the order's partner account and branch. | | `ExternalId` | External | Text, unique | | | | `FinanceAmount` | Finance Amount | Currency | | The financed portion of the order. It is the amount the credit-limit check weighs when the order is created (FinanceAmount, falling back to TotalOrderAmount), and it is subtracted in both OutstandingAmount and TotalCreditAmount, so a non-zero value reduces what the order counts as still owed in cash. | | `FulfilmentOrderQuantity` | Fulfilment Order Quantity | Calculated (calculated) | | Order-level roll-up of OrderLine.FulfilmentOrderQuantity: quantity already placed on an inventory fulfilment. PendingFulfilmentQuantity is the remainder still to be released. | | `FulfilmentReleased` | Fulfilment Released | Boolean | | Metadata-only field with no counterpart in the platform: neither the Order domain type nor the schema created by the platform migration has a column of this name. | | `GSTIN` | GSTIN | Text | | | | `Id` | Id | Guid | Yes | | | `IsDealerOrderCreated` | Dealer Sale Order Created | Boolean | | Set when the order was created as a dealer order from another organization's purchase order. | | `IsDeliveryReleased` | Delivery Released | Boolean | | Legacy flag; not maintained by the release actions. Read Pending Delivery Quantity or Document State instead. | | `IsILPosted` | IL Posted | Boolean | | | | `IsInJobQueue` | In Job Queue | Boolean | | A boolean column on the order that no code in the platform reads or writes; it does not indicate whether an asynchronous action for this order is queued or running. | | `IsInvoiceReleased` | Invoice Released | Boolean | | Legacy flag; not maintained by the release actions. Read Pending Invoice Quantity or Document State instead. | | `IsKPICalculated` | KPI Calculated | Boolean | | | | `JobQueueId` | Job Queue | Lookup | | Metadata-only field with no counterpart in the platform: the Order domain type and the schema created by the platform migration have no JobQueueId column. Asynchronous processing of an order is tracked by the platform's own job ledger, not by a field on the order. | | `LineSubTotal` | Total Line Amount | Calculated (calculated) | | Labelled Total Line Amount: the sum of line amounts after discounts, before tax. | | `Mobile` | Mobile | Text | | | | `ModeOfPayment` | Mode Of Payment | PickList | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | The order's document number, generated on save from the Order Document Name Setting. The shipped format is SO, a hyphen, the document date as DDMMYYYY, a hyphen and a six-digit counter that restarts each day. | | `OpenAdvanceAmount` | Open Advance Amount | Calculated (calculated) | | Calculated as AdvanceAmount minus AdjustedAdvanceAmount: advance money held on the order that has not yet been applied to anything. | | `OpenAmount` | Open Amount | Calculated (calculated) | | | | `OpportunityId` | Opportunity | Lookup → [Opportunity](/docs/reference/entities/opportunity/) | | The opportunity the order was raised from. Each run of the opportunity's Order action creates a new order for the quantity still pending on its lines. | | `OTCInvoicedQuantity` | OTC Invoiced Quantity | Calculated (calculated) | | Order-level roll-up of OrderLine.OTCInvoicedQuantity: quantity invoiced over the counter, meaning through invoice lines with no allocation line behind them, as opposed to allocation-backed invoicing. | | `OutstandingAmount` | Outstanding Amount | Calculated (calculated) | | Calculated: Total Line Amount plus tax, less Amount Paid and Finance Amount. The Payment button in the Amount Summary shows while it is above zero. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Your selling company. Required on save and must be active; only active partner accounts can be picked. It scopes stock, credit and numbering for the order. | | `PendingDeliveryQuantity` | Pending Delivery Quantity | Calculated (calculated) | | Quantity still to be delivered over all lines. | | `PendingFulfilmentAllocationQuantity` | Pending Fulfilment Allocation Quantity | Calculated (calculated) | | Quantity of stock-tracked items still to be allocated. The allocation buttons show while it is above zero. | | `PendingFulfilmentQuantity` | Pending Fulfilment Quantity | Calculated (calculated) | | Pending Fulfillment Quantity | | `PendingInvoiceQuantity` | Pending Invoice Quantity | Calculated (calculated) | | Quantity still to be invoiced over all lines. The invoice buttons show while it is above zero. | | `PerformCreateDealerOrder` | Perform Create Dealer Sale Order | Boolean | | | | `PerformInventoryPosting` | Perform Inventory Posting | Boolean | | | | `PerformKPICalculation` | Perform KPI Calculation | Boolean | | | | `PerformReleaseDelivery` | Perform Release Delivery | Boolean | | | | `PerformReleaseFulfilment` | Perform Release Fulfilment | Boolean | | A stored boolean, not a trigger. The same is true of the other Perform* booleans on this entity. | | `PerformReleaseInvoice` | Perform Release Invoice | Boolean | | A stored boolean, not a trigger. Invoicing is started by invoking the server action of the same name; no code in the platform reads this field. | | `PerformReleaseInvoiceAllocatedLines` | Perform Release Invoice Allocated Lines | Boolean | | | | `PerformReprice` | Perform Reprice | Boolean | | | | `PickedQuantity` | Picked Quantity | Calculated (calculated) | | Order-level roll-up of OrderLine.PickedQuantity: quantity confirmed picked in the warehouse, one stage beyond allocation. | | `PlaceOfSupply` | Place of Supply | PickList | | Values: Maharashtra, Gujarat, Rajasthan, Haryana. | | `PriceAsOnDate` | Price As On Date | Date | | The date prices are taken from. Changing it re-prices every line from the price list in force on that date. | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | The price list the lines are priced from. When left empty, a sale price list matching the partner account, branch and the customer's account groups is chosen on save. | | `PromisedDate` | Promised Date | Date | | | | `PurchaseOrderId` | Purchase Order | Lookup → [PurchaseOrder](/docs/reference/entities/purchase-order/) | | The purchase order of another organization on the platform that this order was created from as a dealer order. | | `QuoteId` | Quote | Lookup → [Quote](/docs/reference/entities/quote/) | | The quote the order was created from. The quote's lines are copied in with their prices, discounts, tax group, SKU and lot type. A quote can create only one order. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remark` | Remark | Text | | | | `RequiredDate` | Tentative Buying Date | Date | | Labelled Tentative Buying Date: the customer's expected purchase date. Not on the shipped forms. | | `RnaExternalId` | RnaExternal | LongMultiLineText | | | | `RoundOff` | Round Off | Currency | | | | `SampleTest` | SampleTest | Boolean | | | | `ShippingAddress` | Shipping Address | Text | | | | `ShippingCity` | Shipping City | PickList | | Values: Pune, Mumbai, Chandigarh. | | `ShippingCityPlaceId` | Shipping City | Lookup → [Place](/docs/reference/entities/place/) | | | | `ShippingContactAddressId` | Shipping Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `ShippingCountry` | Shipping Country | PickList | | Values: India. | | `ShippingPostalCode` | Shipping Postal Code | Text | | | | `ShippingRegion` | Shipping Region | Text | | | | `ShippingState` | Shipping State | PickList | | Values: Haryana, Maharashtra, New Delhi, Punjab. | | `ShippingStreet` | Shipping Street | Text | | | | `SkipScheme` | Skip Scheme | Boolean | | Turns off automatic trade-scheme evaluation for the whole order. Changing it re-runs scheme evaluation. | | `SourceOfSupply` | Source of Supply | PickList | | Values: Maharashtra, Gujarat, Rajasthan, Haryana. | | `Status` | Status | PickList | | The order's stage, Draft by default. Shipped business rules set Fulfilment, Invoicing, Delivery or Closed on save when nothing is left to allocate, invoice or deliver (Closed when nothing is left to deliver or invoice). A manual change to a stage the quantities do not support is refused. Actions such as Cancel Order do not set Status. Values: Draft, Pending Approval, Approved, Fulfilment, Invoicing, Delivery, Closed, Rejected. | | `SupplierAccountId` | Supplier Account | Lookup | | Supplying party on the order, used to scope dealer and distributor documents. Note that the metadata field carries no lookup relation even though the domain model links it to Account, so it will not behave as a lookup in generic tooling. | | `Tax1` | Tax 1 | Currency | | Header-level tax slot (with Tax1Name, Tax1Rate and Tax1Type alongside it), stamped by the tax-group service on insert and whenever TaxGroupId, TaxId or TCSEligibleAmount changes. It is excluded from TotalTaxAmount2, which is TotalLineTaxAmount minus this value. | | `Tax1Name` | TaxName1 | Text | | | | `Tax1Rate` | TaxRate1 | Currency | | | | `Tax1Type` | TaxType1 | Text | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `TaxId` | Tax | Lookup → [Tax](/docs/reference/entities/tax/) | | | | `TaxSupplyType` | Tax Supply Type | PickList | | Within State or Outside State. Used to pick each line's tax group from the tax rules. Values: Within State, Outside State. | | `TCSEligibleAmount` | TCS Eligible Amount | Decimal | | Base amount the header-level tax is computed on. Changing it re-runs the header tax stamping, exactly as changing TaxGroupId or TaxId does. | | `TotalCreditAmount` | Total Credit Amount | Calculated (calculated) | | Calculated as AmountPaid minus FinanceAmount, i.e. the part of what was received that was not financed. It is not a credit limit and not a credit-note total. | | `TotalDiscountAmount` | Total Discount Amount | Calculated (calculated) | | The sum of line discounts, excluding scheme discounts. | | `TotalLineBaseAmount` | Total Line Base Amount | Calculated (calculated) | | Quantity times unit price over all lines, before discounts, excluding discounted-item lines. | | `TotalLineGrossAmount` | Total Line Gross Amount | Calculated (calculated) | | Calculated sum of OrderLine.GrossAmount. TotalOrderAmount is defined by the identical expression, so the two fields always carry the same number. | | `TotalLineTaxAmount` | Total Line Tax Amount | Calculated (calculated) | | Calculated sum of OrderLine.TaxAmount across all six per-line tax slots. TotalTaxPostingAmount uses the same expression, and TotalTaxAmount2 is this figure less the header-level Tax1. | | `TotalOrderAmount` | Total Amount | Calculated (calculated) | | Labelled Total Amount: the order total including line tax. | | `TotalSchemeDiscountAmount` | Total Scheme Amount | Calculated (calculated) | | Labelled Total Scheme Amount: the sum of scheme discounts on the lines. | | `TotalTaxAmount2` | Total Tax Amount | Calculated (calculated) | | Labelled simply 'Total Tax Amount' but calculated as TotalLineTaxAmount minus Tax1 — line taxes excluding the header-level tax component. This is the tax term used inside OutstandingAmount. | | `TotalTaxPostingAmount` | Total Tax Posting Amount | Calculated (calculated) | | | | `TransactionType` | Transaction Type | PickList | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VisitId` | Visit | Lookup → [Visit](/docs/reference/entities/visit/) | | The field visit the order was taken on. The visit is linked back to its first order. | | `VisitPlanId` | Visit Plan | Lookup → [VisitPlan](/docs/reference/entities/visit-plan/) | | | | `VisitRouteId` | Visit Route | Lookup → [VisitRoute](/docs/reference/entities/visit-route/) | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `AllocationDelivery` | Allocation Delivery | ServerAction (`AllocationDelivery`) | Create allocation Delivery | | `ApplyPackageConfiguration` | Apply Package Configuration | ServerAction (`ApplyPackageConfiguration`) | Writes a package configuration onto one order line: it requires LineId plus a non-empty components array of ItemComponentId, Quantity and IsSelected entries, and rejects the call if either is missing. Entries without an item component id are dropped, and the surviving selections are applied to that line's exploded component lines. | | `ApplyScheme` | Apply Scheme | ServerAction (`ApplyScheme`) | Apply Scheme | | `AutoAllocation` | Auto Allocation | ServerAction (`PerformAllocation`) | PerformAllocation | | `BarcodeScanner` | BarcodeScanner | UIAction | BarcodeScanner | | `BulkDelete` | Delete | Delete | Delete the selected records. | | `BulkOrderProcessing` | Bulk Order | ServerAction (`BulkOrderProcessing`) | Bulk Order Processing | | `CancelAllocation` | Cancel Allocation | ServerAction (`CancelAllocation`) | CancelAllocation | | `CancelOrder` | Cancel | ServerAction (`CancelOrder`) | Cancel all pending quantities. | | `CancelPicking` | Cancel Picking | ServerAction (`CancelPicking`), inactive | CancelPicking | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Delete in page. | | `EditInList` | Edit | EditInline | Edit In List Header | | `EditListRow` | Edit | Edit | EditListRow | | `GetAvailableLots` | Get Available Lots | ServerAction (`GetAvailableLots`) | GetAvailableLots | | `GetBenefitDetails` | Get Benefit Details | ServerAction (`GetBenefitDetails`) | Read-only: looks up one scheme benefit by the required benefitId argument and returns its name, discount amount, discount percent and discounted-item quantity. It changes neither the order nor the benefit. | | `GetConfigurableItems` | Get Configurable Items | ServerAction (`GetConfigurableItems`) | Read-only: returns the configurable package items among this order's lines so the client can present a configuration dialogue. Nothing is created or changed. | | `GetOpenDocuments` | Get Open Documents | ServerAction (`GetOpenDocuments`) | GetOpenDocuments | | `GetPackageConfiguration` | Get Package Configuration | ServerAction (`GetPackageConfiguration`) | Read-only: returns the component options and current selections for one order line, whose id must be supplied as LineId — the call is rejected without it. Options are resolved for the order's PartnerAccountId, so the same package can offer different components to different partners. | | `GetPaymentAmountSummary` | Get Payment AmountSummary | ServerAction (`GetPaymentAmountSummary`) | GetPaymentAmountSummary | | `GetQualifiedBenefits` | Get Qualified Benefits | ServerAction (`GetQualifiedBenefits`) | Read-only: returns the benefits available for a given set of item groups, which must be supplied as a non-empty itemGroupIds array or the call is rejected. It is used to populate a choose-your-benefit picker before ApplyScheme is called. | | `GetQualifiedSchemeSlabs` | Get Qualified Scheme Slabs | ServerAction (`GetQualifiedSchemeSlabs`) | Read-only: returns the scheme lines (slabs) the document currently qualifies for, evaluated against its own lines. It applies nothing — ApplyScheme is what commits a chosen slab. | | `GetSchemeRecommendations` | Get Scheme Recommendations | ServerAction (`GetSchemeRecommendations`) | GetSchemeRecommendations | | `ListPreview` | Preview | Preview | Preview the list. | | `ManualAllocation` | Manual Allocation | ServerAction (`ManualAllocation`) | ManualAllocation | | `New` | New | New | New | | `Payment` | Payment | ServerAction | Despite being typed as a server action it carries no server action name; it opens the Payment layout against the order so the receipt is recorded in that form. Reading the order's payment position is done with GetPaymentAmountSummary instead. | | `PerformAllocation` | Manual Allocation | UIAction (`PerformAllocation`) | Creates Allocation lines | | `PerformInventoryPosting` | Post Inventory | ServerAction (`PerformInventoryPosting`) | Perform Inventory Posting | | `PerformPicking` | Picking | ServerAction (`PerformPicking`), inactive | Creates Picking Lines | | `PerformReleaseDelivery` | Delivery | ServerAction (`PerformReleaseDelivery`) | Release Delivery | | `PerformReleaseFulfilment` | Fulfilment | ServerAction (`PerformReleaseFulfilment`) | This action will be used to create inventory fulfilment to reserve the item stock | | `PerformReleaseFulfilmentAndAllocate` | Fulfilment and Auto Allocate | ServerAction (`PerformReleaseFulfilmentAndAllocate`) | Release Fulfilment and Auto Allocate | | `PerformReleaseInvoice` | Invoice ( OTC ) | ServerAction (`PerformReleaseInvoice`) | Release Invoice | | `PerformReleaseInvoiceAllocatedLines` | Invoice | ServerAction (`PerformReleaseInvoiceAllocatedLines`) | Release Invoice AllocatedLines | | `PerformReprice` | Reprice | ServerAction (`PerformReprice`) | Perform Reprice | | `PickedDelivery` | Picked Delivery | ServerAction (`PickedDelivery`), inactive | Create Picking delivery | | `Preview` | Preview | Preview | Preview for the document | | `ProductCatalogue` | Product Catalogue | ServerAction | Opens the Product Catalogue layout for adding items to the order. It carries no server action name, so nothing is executed on the server when the button is pressed. | | `ProductConfigurator` | Product Configurator | UIAction (`ProductConfigurator`) | A client-side action that opens the Product Configurator layout. | | `ResetScheme` | Reset Scheme | ServerAction (`ResetScheme`) | Reset Scheme | | `RowPrint` | Print | Print, inactive | Print in row. | | `SelectiveAllocation` | Selective Allocation | ServerAction (`SelectiveAllocation`), inactive | SelectiveAllocation | | `SelectiveAllocationDelivery` | Selective Allocation Delivery | ServerAction (`SelectiveAllocationDelivery`) | Creates a DeliveryOrder from specific allocation lines, supplied as an InventoryFulfilmentAllocationLines argument. It is refused when the chosen lines have no pending delivery quantity, and also when picking lines already exist for them — in that case Picked Delivery is the correct action. | | `SelectiveCancelAllocation` | Selective Cancel Allocation | ServerAction (`SelectiveCancelAllocation`) | Cancels specific allocation lines, supplied as an InventoryFulfilmentAllocationLines argument, releasing the stock those lines had reserved. Only lines with an allocated quantity above zero are eligible, and each requested quantity is validated against the line's eligible return quantity. | | `SelectiveCancelPicking` | Selective Cancel Picking | ServerAction (`SelectiveCancelPicking`), inactive | Cancels specific picking lines, supplied as an InventoryFulfilmentPickingLines argument. It reverses the pick only — the underlying allocation stays in place — and only lines with a picked quantity above zero are eligible. | | `SelectiveDelivery` | Selective Delivery | ServerAction (`SelectiveDelivery`) | Selective Delivery | | `SelectiveFulfilment` | Selective Fulfilment | ServerAction (`SelectiveFulfilment`) | Selective Fulfilment | | `SelectiveFulfilmentandAutoAllocate` | Selective Fulfilment and Auto Allocate | ServerAction (`SelectiveFulfilmentAndAllocate`) | Runs fulfilment release and immediate allocation for caller-picked lines only: an OrderLines argument of Id and RequestedQuantity pairs, where a requested quantity of 0 falls back to the line's PendingFulfilmentOrderQuantity. Note that the action's stored name differs from the server action it invokes, which is SelectiveFulfilmentAndAllocate. | | `SelectiveInvoiceOTC` | Selective Invoice OTC | ServerAction (`SelectiveInvoiceOTC`) | Selective Invoice OTC | | `SelectivePickedDelivery` | Selective Picked Delivery | ServerAction (`SelectivePickedDelivery`), inactive | Creates a DeliveryOrder from specific picking lines, supplied as an InventoryFulfilmentPickingLines argument, each capped by its RequestedQuantity. An empty list, or ids that match no picking line, is rejected rather than treated as all. | | `SelectivePicking` | Selective Picking | ServerAction (`SelectivePicking`), inactive | SelectivePicking | | `SelectiveReleaseInvoiceAllocatedLine` | Selective Invoice | ServerAction (`PerformReleaseInvoiceAllocatedLines`) | Selective Release For Invoice | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Booking Amount Validation | Error | The 'Total Amount' received against this order is not enough to cover the 'Booking Amount' | This rule verifies that the Booking Amount defined for the order has been received before the order can be confirmed. | | DMS Credit Check Validation | Error | The 'Outstanding Amount' against this order is above the defined 'Credit Limit' of the Account. | This rule validates that the total outstanding amount for the order is less than the allowed credit limit. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Contact for Account | `ContactId` | ContactforAccount | | Customer Account Filter | `AccountId` | | | Discount Group Active | `DiscountGroupId` | | | Executive Filter | `ExecutiveId` | | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [Quote](/docs/reference/entities/quote/) — looks up via `QuoteId` - [Contact](/docs/reference/entities/contact/) — looks up via `ContactId` - [VisitRoute](/docs/reference/entities/visit-route/) — looks up via `VisitRouteId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `ShippingContactAddressId` - [VisitPlan](/docs/reference/entities/visit-plan/) — looks up via `VisitPlanId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Visit](/docs/reference/entities/visit/) — looks up via `VisitId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Place](/docs/reference/entities/place/) — looks up via `BillingCityPlaceId` - [Place](/docs/reference/entities/place/) — looks up via `ShippingCityPlaceId` - [Tax](/docs/reference/entities/tax/) — looks up via `TaxId` - [Resource](/docs/reference/entities/resource/) — looks up via `ExecutiveId` - [DiscountGroup](/docs/reference/entities/discount-group/) — looks up via `DiscountGroupId` - [Opportunity](/docs/reference/entities/opportunity/) — looks up via `OpportunityId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — looks up via `PurchaseOrderId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `BillingContactAddressId` - [PaymentAdjustment](/docs/reference/entities/payment-adjustment/) — referenced by via `OrderId` - [FinanceCase](/docs/reference/entities/finance-case/) — referenced by via `OrderId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `OrderId` - [KYCDocument](/docs/reference/entities/kycdocument/) — referenced by via `OrderId` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `OrderId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `OrderId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `OrderId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `OrderId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `OrderId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ParentRecordId` - [Payment](/docs/reference/entities/payment/) — referenced by via `OrderId` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — referenced by via `OrderId` - [ItemCart](/docs/reference/entities/item-cart/) — referenced by via `OrderId` - [Quote](/docs/reference/entities/quote/) — referenced by via `OrderId` - [Visit](/docs/reference/entities/visit/) — referenced by via `OrderId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `SaleOrderId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `OrderId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `OrderId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — referenced by via `OrderId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `OrderId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Partner Account Mapping — entity reference URL: https://xmatix.com/docs/reference/entities/partner-account-mapping/ Last reviewed: 2026-10-10 A dated rule that allows or blocks items or item groups for one sales executive, optionally narrowed to a selling company, selling company group, branch, customer or customer group. Take Order reads these rules, together with the selling company's store, to decide which products the executive may sell: only rows naming the executive's resource, in date today, whose every filled condition matches the order context are used. A blank condition matches anything. Among matching rows that name an item or item group, a block always wins over an allow, and one allow row switches the executive to an allow list for that context; Is Allowed left blank means not stated and neither allows nor blocks. A row naming no item and no item group does not change the catalogue. The scope is resolved on the server, so the executive needs no read access to the rows. Rows are not moved or copied when a partner's business is transferred. Hidden when the organization does not run multiple companies. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | A group of customers; the rule matches when the customer is an active member of the group. Separate from Partner Account Group, which groups selling companies. | | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer the order is for; blank matches any customer. The lookup lists only active customer accounts. A filled value cannot match when Take Order is opened without a customer. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The selling branch the rule applies to; blank matches any branch. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FromDate` | From Date | Date | | First day the rule applies, inclusive. Required on the standard forms; a row with no From Date applies from the beginning. | | `Id` | Id | Guid | Yes | | | `IsAllowed` | Is Allowed | Boolean, inactive | | Yes allows the matched items, No blocks them and a block always wins. Blank means not stated: the row neither allows nor blocks. Inactive in the standard data model and not on the standard forms. | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | A group of items the rule allows or blocks; it covers the group's active member items. Required when editing in the standard record layout. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | One item the rule allows or blocks. A row with no Item and no Item Group does not change the catalogue. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | The record's document number, generated on save from the PAM series. It does not describe what the row maps. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountGroupId` | Partner Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | A group of selling companies; the rule matches when the selling company is an active member of the group. Separate from Account Group, which groups customers. | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The selling company the rule applies to; blank matches any company. The lookup lists only active partner accounts. Not the customer, which is Account. | | `PartnerAccountMappingId` | Partner Account Mapping | Lookup → [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) | | A link to another partner account mapping. Not used by any built-in process. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedQuantity` | Requested Qty | Number | | A calculated number field with no business meaning. Not used by any built-in process. | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/), inactive | | The sales executive the rule governs. Take Order's selling scope reads only rows naming the executive's own active resource. Inactive in the standard data model and not on the standard forms. | | `ToDate` | To Date | Date | | Last day the rule applies, inclusive. Blank means the rule never expires. Set it to end a rule while keeping it as history. | | `UIProps` | UI Props | Text | | Stores display settings for the record. Not shown to users. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | List Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit In Page | | `EditListHeader` | Edit | EditInline | Edit in list header. | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `NewInline` | New | NewInline | Inline New | | `RowServerAction` | Row Action | ServerAction | Sample | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Customer Account Filter | `AccountId` | CustomerAccountFilter | | Partner Account Filter | `PartnerAccountId` | PartnerAccountFilter | ## Related entities - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) — looks up via `PartnerAccountMappingId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `PartnerAccountGroupId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) — referenced by via `PartnerAccountMappingId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Partner Resource — entity reference URL: https://xmatix.com/docs/reference/entities/partner-resource/ Last reviewed: 2026-08-16 A dated posting of a Resource to a selling organisation - a partner account and/or a branch - for a date window, plus an optional reporting manager. It is what authorises a resource to raise documents for a given partner account or branch, and it is what the platform reads to derive a new document's partner account and branch when the resource has no default pair set: candidates in the document's date window are ordered by AssignmentSequenceNumber (then id) and the first one wins. In the authorisation check a null partner account or null branch on the row acts as a wildcard matching anything, and a row with both legs null within the window is treated as a blanket default that skips the check entirely. It also anchors ResourceAssignmentRule rows used to auto-pick a resource for a document, and Employee rows point at it. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AssignmentSequenceNumber` | Assignment Sequence Number | Number | | The tie-breaker when a resource has several in-window postings: candidates are sorted ascending on this number (rows without one sort last) and the first is used to stamp the document's partner account and branch. It is a priority order, not a count or a line number. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch half of the posting, with the same wildcard semantics as the partner account - null matches any branch rather than restricting to none. When the resource has no default pair, this is one of the two values copied onto a new document. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EmployeeId` | Employee | Lookup → [Employee](/docs/reference/entities/employee/) | | Reach the Employee from its own ResourceId (or from its PartnerResource link) instead of using this field. | | `FromDate` | From Date | Date | | Opens the posting's validity window, compared against the document's own document date (falling back to now) rather than against today. Empty means open-ended in the past, so a blank from-date does not disable the row. | | `Id` | Id | Guid | Yes | | | `ManagerResourceId` | Manager | Lookup → [Resource](/docs/reference/entities/resource/) | | The manager for this specific posting, which can differ from the person's own manager on the Resource record - it lets someone report to a different manager while working for a particular partner account or branch. Nothing keeps the two in sync. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The selling organisation this posting authorises the resource for. A null value here is a wildcard rather than 'none': the authorisation check treats a row with no partner account as matching any partner account, and a row with both partner account and branch null inside the date window acts as a blanket permission that bypasses the check entirely. | | `PartnerResourceCode` | Code | Text | | The partner organisation's own code for this person, kept so external files and integrations can be matched back to the posting. It is free text with no uniqueness enforcement and is not used by any platform lookup. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `RuleSuccessCriteria` | Rule Success Criteria | Text | | Chooses how the attached ResourceAssignmentRule rows combine when auto-picking a resource for a document - all rules must pass, any one may pass, or assign unconditionally. There is a live value mismatch: the engine compares against the spaced forms 'All Rules Are Met', 'Any Rule Is Met' and 'Always (No Criteria)', while the shipped picklist stores the concatenated forms without spaces, and those picklist entries are inactive. | | `RuleSuccessCustomLogic` | Rule Success Custom Logic | Text | | A slot for a custom boolean expression combining the assignment rules, mirroring the same field on account and item groups. | | `ToDate` | To Date | Date | | Closes the posting's validity window, also evaluated against the document date rather than today - which is why back-dating a document can legitimately pick up a posting that has since expired. Empty means open-ended. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | Branch For Partner Account | | Partner Account | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Resource](/docs/reference/entities/resource/) — looks up via `ManagerResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Employee](/docs/reference/entities/employee/) — looks up via `EmployeeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Employee](/docs/reference/entities/employee/) — referenced by via `PartnerResourceId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Party Period Balance — entity reference URL: https://xmatix.com/docs/reference/entities/party-period-balance/ Last reviewed: 2026-08-16 The receivables and payables subledger balance: one row per party inside a control account, per fiscal period and business unit, aggregated from posted control-account journal lines. It exists so a customer or supplier position can be read without scanning the ledger, and the verification job asserts that the sum of party balances under a control account equals that account's GL period balance. Like the GL period balance it is a derived cache — direct create, edit and delete are refused, and the only legitimate writers are journal posting and the rebuild service. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | The only dimension besides the control account, party and period that splits these rows — branch, GST registration and cost centre do NOT, unlike the GL period balance. A party's position is therefore held per business unit. | | `ClosingBalance` | Closing Balance | Currency | | Opening plus period debits minus period credits, rounded to two decimals and signed debit-positive. Since opening is always zero in practice, on a receivables control a positive figure is the period's net amount invoiced less received, not the total outstanding. | | `ControlGLAccountId` | ControlGL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The control account the subledger row hangs under, such as receivables or payables. Only lines posting to an account flagged as a control account create these rows, and the verification job asserts that the party rows under one control account and period sum to that account's GL period balance. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FiscalPeriodId` | Fiscal Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | | | | `GLAccountName` | Name | Text, unique | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `OpeningBalance` | Opening Balance | Currency | | It is not a carried-forward prior-period position, so party ageing and statements should be derived from the ledger or the open-item subledger. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The owning company, stamped from the journal header when the row is first created. It is NOT part of the key posting matches on — that key is control account, party, business unit and fiscal period — so a row opened by one company's journal keeps that stamp regardless of later activity; do not use this field to scope or filter party balances by company. | | `PartyAccountId` | Party Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer or supplier whose position this row holds, taken from the posted journal line's party. This is the counterparty, not the company that owns the ledger. | | `PeriodCredit` | Period Credit | Currency | | Sum of credit amounts for the same party, control account, business unit and period. A mismatch against the re-aggregated ledger is reported by the verification pass as party balance drift. | | `PeriodDebit` | Period Debit | Currency | | Sum of debit amounts posted to this control account for this party, business unit and period. Rebuild rewrites it from the posted ledger and zeroes any stored row the ledger no longer supports. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Always fails. The platform rejects direct deletion of derived subledger balances; use the rebuild-ledger-balances action on the fiscal period to resync them with the posted ledger. | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | Always fails. The row is a projection of the ledger, and hand-editing it would break the invariant that party balances under a control account sum to that account's GL period balance. Post or reverse a journal, or rebuild the period. | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | Always fails. Subledger balances are derived from posted control-account journal lines and may only be written by the posting and rebuild services; post a journal against the control account with a party to create the row. | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `ControlGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `FiscalPeriodId` - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Payment Adjustment — entity reference URL: https://xmatix.com/docs/reference/entities/payment-adjustment/ Last reviewed: 2026-08-16 The legacy settlement link: one row nets a payment or credit document against an open document and carries the amount applied. It is explicitly the predecessor of the OpenTransaction + SettlementAllocation open-item engine (see docs/finance/finance-accounting-module-plan.md D6/D8) and is retained only because live code still writes it — new settlement work belongs on SettlementAllocation, which posts a journal so the GL and the open items cannot disagree. PaymentAdjustment does NOT post to the ledger. Its behaviour is also narrower than its column list suggests: PaymentAdjustmentHandler applies a saved row to Invoice, Order and ExpenseVoucher only, and its validation counts just OrderId, InvoiceId and PaymentId, so rows keyed solely on BillId, PurchaseOrderId, CreditNoteId or DebitNoteId are rejected as an invalid combination even though the columns exist. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AdjustmentAmount` | Adjustment Amount | Currency | | The amount applied by this settlement link. On the invoice path it is validated not to exceed the invoice's current OpenAmount and is then ADDED to the invoice's AdjustedAmount, so the adjustment reduces what remains open. | | `BillId` | Bill | Lookup → [Bill](/docs/reference/entities/bill/) | | The supplier bill being settled. As with the note columns, the save-time application covers Invoice, Order and ExpenseVoucher only and the validation rule does not count this column, so a bill-keyed row records the intent without moving the bill's balance. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CreditNoteId` | Credit Note | Lookup → [CreditNote](/docs/reference/entities/credit-note/) | | The credit note supplying the credit being applied. Written by the claim-settlement path, which nets a credit note against the partner's open invoices oldest-first and records one row per invoice. Note that the generic save-time application does not act on this column, and the two-document validation rule does not count it — reading a credit note's consumption is safer from the note's own AdjustedAmount/OpenAmount. | | `DebitNoteId` | Debit Note | Lookup → [DebitNote](/docs/reference/entities/debit-note/) | | The debit note involved in the settlement. The column exists, but the handler's save-time application covers only Invoice, Order and ExpenseVoucher, and the validation rule does not count this column — so a debit-note-keyed row does not move any balance by itself. | | `DocumentDate` | Document Date | Date | | | | `ExpenseVoucherId` | Expense Voucher | Lookup → [ExpenseVoucher](/docs/reference/entities/expense-voucher/) | | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `InvoiceId` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | The customer invoice being settled. This is the best-supported path: on save, the handler loads the invoice and adds the adjustment to its AdjustedAmount, refusing an amount larger than the invoice's open balance. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | The sales order being settled — an advance or on-account application against an order rather than an invoice. Applied on save by the order service, and counted by the two-document validation rule. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The party the settlement belongs to (labelled simply "Account"). Copied from the source document when the claim engine writes the row; it scopes the adjustment for partner-level reporting. | | `PaymentId` | Payment | Lookup → [Payment](/docs/reference/entities/payment/) | | The payment or receipt doing the settling. Validation counts documents across OrderId, InvoiceId and PaymentId and requires exactly two of them, and rejects an Order-only or Invoice-only row — so in practice a row pairs the payment with an order or an invoice, or pairs an order with an invoice. | | `PurchaseOrderId` | Purchase Order | Lookup → [PurchaseOrder](/docs/reference/entities/purchase-order/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `New` | New | New | New | ## Related entities - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Payment](/docs/reference/entities/payment/) — looks up via `PaymentId` - [CreditNote](/docs/reference/entities/credit-note/) — looks up via `CreditNoteId` - [Bill](/docs/reference/entities/bill/) — looks up via `BillId` - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — looks up via `ExpenseVoucherId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — looks up via `PurchaseOrderId` - [DebitNote](/docs/reference/entities/debit-note/) — looks up via `DebitNoteId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Payment Batch Line — entity reference URL: https://xmatix.com/docs/reference/entities/payment-batch-line/ Last reviewed: 2026-08-16 One member document inside a PaymentBatch. Amount is the line's contribution to the batch and is the only value the roll-up helper sums. Like its parent, nothing in the current code base creates these rows outside tests. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | This line's contribution to the batch, and the only field the batch roll-up sums (skipping soft-deleted lines). It is not validated against the amount of the document the line points at, so the two can disagree. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `LineNumber` | Line Number | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyAccountId` | Party Account | Lookup → [Account](/docs/reference/entities/account/) | | The counterparty on this line — the vendor being paid or the customer whose receipt is being deposited. It duplicates what the referenced source document already holds and is not kept in step with it, so treat it as a snapshot taken when the line was entered. | | `PaymentBatchId` | Payment Batch | Lookup → [PaymentBatch](/docs/reference/entities/payment-batch/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SourceEntityName` | Source Entity Name | Text | | Names the entity of the document this line stands for, forming a polymorphic pointer together with SourceRecordId. | | `SourceRecordId` | Source Record | Guid | | The identifier of the referenced document, meaningful only in combination with SourceEntityName. It is deliberately not a foreign key, so nothing prevents it pointing at a deleted or non-existent record and no cascade or integrity check applies; resolve it by querying the named entity. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `NewInLine` | New | NewInline | NewInLine | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [PaymentBatch](/docs/reference/entities/payment-batch/) — looks up via `PaymentBatchId` - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Payment Batch — entity reference URL: https://xmatix.com/docs/reference/entities/payment-batch/ Last reviewed: 2026-08-16 A header intended to group money movements for one bank run — an outgoing vendor payment file or an incoming customer deposit slip, distinguished by BatchType — with a count and total rolled up from its lines. In the current code base it is a metadata-only structure: no entity handler, server action or job creates a batch, rolls it up or advances its state. The roll-up helper PaymentBatchService.RecomputeTotalsAsync exists but is invoked from nothing except an integration test, and the NEFT/RTGS and cheque-register exports select Payment rows by company and date range without consulting batches at all. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BankAccountId` | Bank Account | Lookup → [BankAccount](/docs/reference/entities/bank-account/) | | The company bank account the run is drawn on or deposited into. It is a plain reference — no posting, file export or reconciliation path reads it today, so it records intent rather than driving the money side of anything. | | `BatchDate` | Batch Date | DateAndTime | | | | `BatchType` | Batch Type | Text | | Distinguishes an outgoing vendor payment run from an incoming customer deposit slip, with 'Payment' as the default. It has no seeded pick list, and no code branches on it today — the roll-up helper merely echoes it back — so it is descriptive metadata rather than a behavioural switch. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ItemCount` | Item Count | Number | | Meant to be the number of non-deleted lines in the batch, set alongside the total by the same roll-up routine. Since nothing invokes that routine outside tests, it is not maintained automatically and should be verified against the actual lines before being trusted. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Reference` | Reference | Text | | | | `Status` | Status | Text | | Any movement here is manual data entry and implies nothing about whether a bank file was produced or the member payments were posted. | | `TotalAmount` | Total Amount | Currency | | Meant to be the sum of the non-deleted line amounts, rounded to two decimals. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteListHeader` | Delete | Delete | DeleteListHeader | | `DeleteListRow` | Delete | Delete | DeleteListRow | | `EditEntity` | Edit | Edit | Edit | | `EditInLine` | EditInLine | EditInline | EditInLine | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [BankAccount](/docs/reference/entities/bank-account/) — looks up via `BankAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [PaymentBatchLine](/docs/reference/entities/payment-batch-line/) — referenced by via `PaymentBatchId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Payment (Salary Disbursement) — entity reference URL: https://xmatix.com/docs/reference/entities/payment-salary-disbursement/ Last reviewed: 2026-08-16 A legacy, thin salary-payout record hanging off a PayrollRun, superseded by PayrollPaymentBatch and its lines. No first-party service, handler or job reads or writes it: nothing creates it, nothing settles an open item from it, and it produces no ledger entry, so rows only ever exist if a tenant or an import puts them there. The shipped disbursement path is Generate Payment on the run, which builds a PayrollPaymentBatch, and then Pay on that batch, which posts Dr Payroll Payable / Cr Bank. Treat any data here as historical and never use it to answer whether salary was actually paid. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EmployeeId` | Employee | Lookup → [Employee](/docs/reference/entities/employee/) | | The salary payout path keys on Resource, through the payment batch lines, not on Employee. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PaymentDate` | Payment Date | Date | | The date this legacy payout record claims money moved. | | `PaymentMode` | Payment Mode | PickList | | How the payout was supposedly made, offering Bank, Cash or Cheque. Purely descriptive data entry on a superseded entity: no payment file, journal or settlement behaviour keys off it. Values: Bank, Cash, Cheque. | | `PaymentStatus` | Payment Status | PickList | | A free-text state for this legacy payout record, with no picklist and no engine constants behind it. Nothing advances or validates it, so it carries whatever a user or import wrote. | | `PayrollRunId` | Payroll Run | Lookup → PayrollRun_c | | The payroll run this legacy payout record claims to relate to. It is the only relationship the record has, and nothing in the platform creates, reconciles or posts from it — the run's real disbursement link is its payment batch. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TotalAmountPaid` | Total Amount Pa | Currency | | The amount this legacy record claims was disbursed. It is not derived from payroll details, not reconciled against Payroll-Payable open items and not posted, so it should never be used as a paid-salary total — sum the payment batch or the ledger instead. | | `TransactionID` | Transaction | Text | | A free-text bank or transfer reference on this superseded record. Nothing writes or validates it; the shipped equivalent is the payment reference on the salary batch and the per-line bank reference on its lines. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [PayrollRun](/docs/reference/entities/payroll-run/) — looks up via `PayrollRunId` - [Employee](/docs/reference/entities/employee/) — looks up via `EmployeeId` - [Employee](/docs/reference/entities/employee/) — referenced by via `PaymentSalaryDisbursementId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Payment — entity reference URL: https://xmatix.com/docs/reference/entities/payment/ Last reviewed: 2026-08-16 A single money movement in either direction and the only document that settles AR/AP open items: PaymentType 'Payment Taken' is a customer receipt, 'Payment Given' a vendor or employee disbursement. It posts as soon as it is inserted, provided the owning partner Account has GL posting enabled, and again whenever IsGLPostingApproved is turned on: a balanced journal pairing the money account (chosen from ModeOfPayment) against the receivable or payable control, then either a SettlementAllocation that reduces the target open item or, when no target document is identified, a negative 'on account' OpenTransaction standing for an unapplied advance. Cheque-mode payments additionally draw or record a ChequeTransaction so the clearing and bounce lifecycle can run. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The counterparty — the customer paying in or the vendor or employee being paid. It is the party stamped on the control leg of the journal and on any on-account open item, and it is what the open-documents lookup and the bank-file export use to resolve the beneficiary. Distinct from PartnerAccountId, which is the company making or receiving the payment. | | `AdjustedAmount` | Adjusted Amount | Currency | | | | `Amount` | Amount | Currency | | The money moved by this document, always recorded as a positive figure — direction comes from PaymentType, never from the sign. Non-positive values are rejected on both insert and edit. Over-allocation is intentionally allowed, because advances legitimately exceed the current outstanding. It is the amount posted and the amount allocated when no explicit split is supplied. | | `BankName` | Bank Name | Text | | | | `BillId` | Bill | Lookup → [Bill](/docs/reference/entities/bill/) | | The settlement target for an outgoing payment, consulted only after ExpenseVoucherId — a payment tagged to a voucher settles the voucher and ignores this field. When it resolves, posting writes a SettlementAllocation against the bill's payable open item; when nothing resolves the payment becomes a negative on-account open item. Note it does not update the bill's AmountPaid, which no code maintains. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CardExpiry` | Card Expiry | Date | | | | `CardNumber` | Card Number | Number | | | | `CardType` | Card Type | PickList | | Values: 3. | | `ChequeDate` | Cheque Date | Date | | | | `ChequeNumber` | Cheque Number | Number | | | | `ClaimId` | Claim | Lookup → [Claim](/docs/reference/entities/claim/) | | | | `ClaimReconciliationId` | Claim Reconciliation | Lookup → [ClaimReconciliation](/docs/reference/entities/claim-reconciliation/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CreditNoteId` | Credit Note | Lookup → [CreditNote](/docs/reference/entities/credit-note/) | | | | `DebitNoteId` | Debit Note | Lookup → [DebitNote](/docs/reference/entities/debit-note/) | | | | `ElectronicMode` | Electronic Mode | PickList | | Values: 2. | | `ExpenseVoucherId` | Expense Voucher | Lookup → [ExpenseVoucher](/docs/reference/entities/expense-voucher/) | | | | `ExternalId` | External | Text, unique | | | | `GeneralLedgerId` | General Ledger | Lookup → [GeneralLedger](/docs/reference/entities/general-ledger/) | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `GLAmount` | GL Amount | Calculated | | A secondary posting amount used only as a fallback: settlement takes the absolute value of Amount and consults this field only when Amount is zero. It is not a calculated field on this entity and is not maintained in step with Amount, so treat Amount as authoritative. | | `Id` | Id | Guid | Yes | | | `InvoiceId` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | The settlement target for an incoming receipt. When set, posting finds the invoice's open item and writes a SettlementAllocation that reduces it, marking it settled or partially settled; when it is empty and no explicit allocation was supplied, the receipt instead becomes a negative on-account open item representing an unapplied advance. It also causes the invoice's AmountPaid roll-up to be recomputed. | | `IsGLPosted` | GL Posted | Boolean | | Records that a journal exists for this payment. Because the ledger is append-only, reversing a payment (for example on a bounced cheque or when the settled invoice is cancelled) writes a reversing journal rather than clearing this flag, so it does not by itself tell you whether the payment is currently live in the ledger. | | `IsGLPostingApproved` | GL Posting Approved | Boolean | | The posting gate on updates: when it turns true the save pipeline builds the journal, the settlement or on-account open item, and the cheque and withholding side effects. It is not required on insert — a newly created payment posts immediately provided the owning company has GL posting enabled — and the posting code sets it itself for any payment it is about to post. | | `IsRelatedGLPosted` | Related GL Posted | Boolean | | Balanced single-journal posting made it redundant; ignore it when judging posting state. | | `LastModifiedById` | LastModifiedBy | Guid | | | | `ModeOfPayment` | Mode Of Payment | PickList | | Chooses the money-side account at posting: 'Cash' or empty posts to Cash, 'Cheque' parks the amount in a cheques-in-hand suspense account until it clears (falling back to Bank when no such account is configured), 'Electronic Transfer' posts to Bank, and 'Card' posts to Credit Card for outgoing or Bank for incoming money. Note the seeded pick list offers a 'Bank' option that the mapping does not recognise and which therefore falls through to Cash, while 'Card' is recognised but is not in the list. Values: Cash, Cheque, Bank, Electronic Transfer. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `Name (dup-9bd92512)` | Document Number | Text | | | | `OpenAmount` | Open Amount | Calculated (calculated) | | | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PaymentDate` | Document Date | Date | | | | `PaymentMode` | PaymentMode | Text | | A second, separate mode field with no pick list of its own, and the one the non-posting paths key on: the cheque hook creates a cheque transaction only when this field reads 'Cheque', and the NEFT/RTGS and cheque-register exports read it (falling back to NEFT). Account selection at posting time, by contrast, uses ModeOfPayment — so the two fields must be kept in step or a cheque will post to the wrong account or never be registered. | | `PaymentType` | Payment Type | PickList | | The direction of the money and the single most important field on the record: 'Payment Taken' is a customer receipt, posting the money account against Accounts Receivable, and 'Payment Given' is a disbursement, posting against Accounts Payable. Comparisons strip spaces, so the stored pick-list values with a space and the space-free forms both match. It also decides which side the withholding hook runs on. Values: Payment Given, Payment Taken. | | `PayrollRunId` | Payroll Run | Lookup → [PayrollRun](/docs/reference/entities/payroll-run/) | | | | `PurchaseOrderId` | Purchase Order | Lookup → [PurchaseOrder](/docs/reference/entities/purchase-order/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RelatedGeneralLedgerId` | Related General Ledger | Lookup → [GeneralLedger](/docs/reference/entities/general-ledger/) | | | | `RelatedGLAccountId` | Related GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `RelatedGLAmount` | Related GL Amount | Calculated | | A leftover from the superseded two-sided posting model, when a payment wrote independent debit and credit rows. No code path writes it, nor the related account and journal fields beside it. Today a payment posts one balanced journal, so this field stays empty and must not be read as the counter-leg amount. | | `Remarks` | Remarks | LongMultiLineText | | | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | | | `Status` | Status | PickList | | A seeded two-value pick list, Draft and Paid, that no code path assigns or reads. Posting state is carried by IsGLPostingApproved and IsGLPosted, and application state by OpenAmount and AdjustedAmount; do not infer anything from this field. Values: Draft, Posted. | | `TransactionDate` | Transaction Date | Date | | | | `TransactionReference` | Transaction Reference | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Delete in page. | | `EditInList` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `PostGeneralLedger` | Post General Ledger | ServerAction (`PostGeneralLedger`) | Despite the name, the action body only turns IsGLPostingApproved on and saves. The journal, the settlement allocation or on-account open item, and the cheque, TDS and TCS side effects are all produced afterwards by the payment's save pipeline, which posts whenever that flag becomes true. Payments created through the ordinary insert path already post without this action, so it is mainly a way to post one that was entered while GL posting was withheld. | | `UIAction` | UI Action | UIAction | A placeholder entry of UI type; the payment handler supports only PostGeneralLedger, so nothing on the server claims this name and invoking it performs no server-side work. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `BranchId` | | | Customer Account Filter | `AccountId` | | | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [PayrollRun](/docs/reference/entities/payroll-run/) — looks up via `PayrollRunId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `RelatedGLAccountId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ExpenseVoucher](/docs/reference/entities/expense-voucher/) — looks up via `ExpenseVoucherId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Claim](/docs/reference/entities/claim/) — looks up via `ClaimId` - [Bill](/docs/reference/entities/bill/) — looks up via `BillId` - [DebitNote](/docs/reference/entities/debit-note/) — looks up via `DebitNoteId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — looks up via `GeneralLedgerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [CreditNote](/docs/reference/entities/credit-note/) — looks up via `CreditNoteId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — looks up via `PurchaseOrderId` - [ClaimReconciliation](/docs/reference/entities/claim-reconciliation/) — looks up via `ClaimReconciliationId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GeneralLedger](/docs/reference/entities/general-ledger/) — looks up via `RelatedGeneralLedgerId` - [PaymentAdjustment](/docs/reference/entities/payment-adjustment/) — referenced by via `PaymentId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [InterestCharge](/docs/reference/entities/interest-charge/) — referenced by via `SourceRecordId` - [Visit](/docs/reference/entities/visit/) — referenced by via `PaymentId` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — referenced by via `PaymentId` - [SettlementAllocation](/docs/reference/entities/settlement-allocation/) — referenced by via `PaymentId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Payroll Adjustment — entity reference URL: https://xmatix.com/docs/reference/entities/payroll-adjustment/ Last reviewed: 2026-08-16 A one-off earning or deduction for a single employee in a single payroll period — bonus, penalty, arrears or an ad-hoc reimbursement — held outside the salary structure so it affects exactly one run. It is not recurring: the calculation loads the adjustments matching the run's period and the employee's ResourceId and appends each as an extra PayrollRunComponentLine at SortOrder 1000, never prorated. Only approved adjustments are picked up, with the gating quirk that a null ApprovalStatus counts as approved, so a blank status is included rather than skipped. When PayrollComponentId is set the master's type, taxability and GL mapping drive the resulting line; otherwise AdjustmentType decides, defaulting to an earning. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AdjustmentType` | Adjustment Type | PickList | | Values: Earning, Deduction, Addition. | | `Amount` | Amount | Currency | | | | `ApprovalStatus` | Approval Status | PickList | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IsArrear` | Is Arrear | Boolean | | Marks the amount as relating to an earlier period rather than the current one. It is recorded for reporting and audit only: the calculation treats an arrear exactly like any other one-off, adding it in full to the current run with no proration and no back-period recomputation. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PayrollComponentId` | Payroll Component | Lookup → [PayrollComponent](/docs/reference/entities/payroll-component/) | | | | `PayrollPeriodId` | Payroll Period | Lookup → [PayrollPeriod](/docs/reference/entities/payroll-period/) | | The single pay cycle this one-off applies to, and the reason an adjustment is never recurring: the calculation only loads adjustments whose period equals the run's period, so an adjustment reaches exactly one cycle. A run with no period picks up no adjustments at all. | | `Reason` | Reason | Text | | The free-text justification for the one-off, carried for audit and approval review. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | The person the one-off applies to, as a Resource rather than an Employee. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this PayrollAdjustment. | | `DeleteHeader` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this PayrollAdjustment. | | `Editheader` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `New` | New | New | Create a PayrollAdjustment. | | `View` | View | View, inactive | View this PayrollAdjustment. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [PayrollComponent](/docs/reference/entities/payroll-component/) — looks up via `PayrollComponentId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [PayrollPeriod](/docs/reference/entities/payroll-period/) — looks up via `PayrollPeriodId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Payroll Component — entity reference URL: https://xmatix.com/docs/reference/entities/payroll-component/ Last reviewed: 2026-08-16 The reusable pay-component master — every earning, deduction, employer contribution and reimbursement a company can pay, defined once with its type, taxability, calculation method, statutory nature and both GL account mappings. Salary-structure lines (SalaryComponent) reference a row here, and at calculation time the master's ComponentType, StatutoryType, Taxability, IsProratable, SortOrder and GL accounts WIN over the equivalent legacy fields on the structure line; the line's own values are only a fallback when it has no master. Because the GL mapping lives here, posting needs no hardcoded account map — and conversely a component missing the mapping its type requires fails the entire post. ComponentType is Earning, Deduction, EmployerContribution or Reimbursement; CalculationType is Fixed, Percentage, Formula, Slab or Manual; StatutoryType, where the component is statutory, is PF, ESI, PT, TDS, LWF or Gratuity. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BasedOnComponentCodes` | Based On Component Codes | Text | | A comma-separated list of the component codes this component's formula depends on. | | `CalculationType` | Calculation Type | PickList | Yes | Values: Fixed, Percentage, Formula, Slab, Manual. | | `ComponentCode` | Component Code | Text, unique | Yes | The short stable identifier for the component, used to reference it from other components' formula dependencies. | | `ComponentType` | Component Type | PickList | Yes | Values: Earning, Deduction, Employer Contribution, Reimbursement. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DisplayOnPayslip` | Display On Payslip | Boolean | | Intended to control whether the component is shown on the payslip, defaulting to on. No first-party code reads it — payslip breakdowns are projected from every component line of the employee's detail regardless of this flag. | | `FormulaExpression` | Formula Expression | Text | | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | Yes | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | Whether the master is available for use in salary structures, defaulting to on. Deactivating it does not stop calculation: the engine resolves masters by identifier and applies them regardless, so an inactive component still referenced by a structure line continues to be paid. | | `IsArrearEligible` | Is Arrear Eligible | Boolean | | Declares that the component may be paid as arrears for an earlier period. It is descriptive only: arrears are entered as PayrollAdjustment records, and nothing in the calculation checks this flag before accepting one. | | `IsPartOfCTC` | Is Part Of CTC | Boolean | | Declares that the component counts toward cost to company. It is a classification flag for structure design and reporting — the calculation does not consult it, and percentage-of-CTC components read the compensation record's CTC figure directly rather than summing flagged components. | | `IsPartOfGross` | Is Part Of Gross | Boolean | | | | `IsPartOfNetPay` | Is Part Of Net Pay | Boolean | | Declares that the component should affect take-home pay. The engine ignores it: what actually decides the effect on net is ComponentType, where earnings and reimbursements add and deductions subtract, while employer contributions never touch net. | | `IsProratable` | Is Proratable | Boolean | | | | `IsStatutory` | Is Statutory | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PayableGLAccountId` | Payable GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SortOrder` | Sort Order | Number | | The component's position in payslip and breakdown ordering, copied onto every calculated line in preference to the salary structure's own sequence. Keep it below 1000, because adjustment lines are stamped 1000 and loan recovery lines 2000, and those two bands are how downstream logic recognises non-structure lines. | | `StatutoryType` | Statutory Type | PickList | | Values: PF, ESI, PT, TDS, LWF, Gratuity. | | `Taxability` | Taxability | PickList | | Values: Taxable, Non Taxable, Partially Taxable. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | BulkDelete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this PayrollComponent. | | `DeleteHeader` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this PayrollComponent. | | `EditHEader` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `New` | New | New | Create a PayrollComponent. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `PayableGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `PayrollComponentId` - [PayrollRunComponentLine](/docs/reference/entities/payroll-run-component-line/) — referenced by via `PayrollComponentId` - [PayrollAdjustment](/docs/reference/entities/payroll-adjustment/) — referenced by via `PayrollComponentId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Payment Batch Line — entity reference URL: https://xmatix.com/docs/reference/entities/payroll-payment-batch-line/ Last reviewed: 2026-08-16 One employee's net-pay row inside a salary payment batch, holding the amount, the bank account and IFSC snapshotted from the Resource at generation time, and a per-line payment status. Lines are informational for the bank file and the audit trail: paying the batch settles the employee's Payroll-Payable open item and posts from that open amount, so a line whose open item is missing or already settled contributes nothing and simply stays Pending. Keyed on ResourceId rather than Employee. UtrNumber exists for the bank reference but no first-party code populates it. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EmployeeBankAccount` | Employee Bank Account | Text | | The employee's account number captured from their Resource record at generation time, unmasked here because this row feeds a bank instruction. It does not refresh if the employee's banking details change afterwards. | | `Id` | Id | Guid | Yes | | | `Ifsc` | Ifsc | Text | | The Indian bank branch routing code snapshotted from the employee's Resource record alongside the account number. Like the account, it is frozen at generation time and is not re-read when the batch is paid. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `NetPayAmount` | Net Pay Amount | Currency | | The employee's net pay as copied from the run detail when the batch was generated. It is a snapshot for the bank file and review: the amount actually paid and settled comes from that employee's Payroll-Payable open item, so editing this value changes nothing about the posting. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PaymentStatus` | Payment Status | PickList | | Per-employee payment state, starting Pending and flipped to Paid only for lines whose Payroll-Payable open item was found and settled when the batch was paid. A line still Pending on a paid batch means that employee had no outstanding net-pay item, so nothing was paid to them — no failure is recorded anywhere else. | | `PayrollPaymentBatchId` | Payroll Payment Batch | Lookup → [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) | | The batch this row belongs to. Lines are created together with the batch from the run's details and are not intended to be added by hand — a manually inserted line settles nothing, because payment works from the open items rather than from these rows. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | The person being paid, as a Resource. It is the key used to find the Payroll-Payable open item to settle, so a line with no resource is skipped entirely at payment time. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UtrNumber` | Utr Number | Text | | The bank's unique transaction reference for this employee's credit. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this PayrollPaymentBatchLine. | | `Edit` | Edit | Edit | Edit this PayrollPaymentBatchLine. | | `New` | New | New | Create a PayrollPaymentBatchLine. | | `View` | View | View | View this PayrollPaymentBatchLine. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) — looks up via `PayrollPaymentBatchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Salary Payment Batch — entity reference URL: https://xmatix.com/docs/reference/entities/payroll-payment-batch/ Last reviewed: 2026-08-16 The salary disbursement batch: one bank payment that settles many employees' Payroll-Payable open items in a single posting of Dr Payroll Payable / Cr Bank. It is generated from a run that is already POSTED (one line per employee with positive net pay, bank details read from each Resource) and starts in Draft with no accounting effect; paying it is the step that moves money and writes the journal, stamps GLId, sets Status to Paid, and sets the run to Paid with its PaymentBatchId. The amounts actually paid come from the run's Resource-keyed Payroll-Payable open items, not from the batch line values, so editing a line does not change what is settled. Status is Draft, Approved, FileGenerated or Paid, but only Draft and Paid are ever written — nothing generates a bank payment file. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BankGLAccountId` | Bank GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The bank account the salary is paid from, credited when the batch is paid. It can be left to the system at generation time, in which case it resolves to the company's configured default bank account or its single bank control account, and generation fails outright when the company has several banks and no default rather than guessing. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | The bank payment Journal this batch posted. It doubles as the already-paid guard — any value here makes a second pay attempt fail — so treat a batch with a journal as final regardless of what Status says. | | `Id` | Id | Guid | Yes | | | `ItemCount` | Item Count | Number | | The number of employees in the batch. At generation it counts the lines built from the run's positive net pay; at payment it is rewritten to the number of open items actually settled, so a drop between the two means some employees had no outstanding net-pay item left. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PaymentDate` | Payment Date | Date | | The value date of the bank payment, defaulting to the generation date, and the date the settlement journal is stamped with. It is independent of the payroll period's pay date, which dates the accrual instead. | | `PaymentFileFormat` | Payment File Format | Text | | Intended to select the bank's payment file layout. | | `PaymentReference` | Payment Reference | Text | | A free-text bank reference for the batch as a whole. No first-party code populates it — it is manual data entry kept for reconciliation notes. | | `PayrollRunId` | Payroll Run | Lookup → [PayrollRun](/docs/reference/entities/payroll-run/) | | The posted run whose net pay this batch disburses; it is also how the batch finds the employees' Payroll-Payable open items to settle. The reverse link on the run is only stamped once the batch is actually paid, so this side exists first. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Status` | Status | PickList | | The batch's state, from Draft, Approved, FileGenerated and Paid. Values: Draft, Approved, File Generated, Paid. | | `TotalNetPay` | Total Net Pay | Currency | | The batch amount. At generation it is the sum of the run's positive per-employee net pay; when the batch is paid it is overwritten with the total actually settled from the Payroll-Payable open items, which is the figure the bank credit line carries. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this PayrollPaymentBatch. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this PayrollPaymentBatch. | | `EditInLine` | Edit | EditInline | Edit | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a PayrollPaymentBatch. | | `PayBatch` | Pay | ServerAction (`PayPaymentBatch`) | Posts the actual bank payment: it finds each line's employee Payroll-Payable open item for the run, aggregates the debits by control account and branch, credits the bank account on the batch, and writes one payroll journal for the whole batch. It then zeroes and settles those open items, marks the settled lines Paid, stamps the batch with its journal and Paid status and rewrites its total and item count, and moves the parent run to Paid with this batch recorded on it. It refuses a batch that already has a journal, one with no bank account, and one where nothing is left open to settle; because it works from the open items, editing line amounts beforehand does not change what is paid. | | `View` | View | View | View this PayrollPaymentBatch. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [PayrollRun](/docs/reference/entities/payroll-run/) — looks up via `PayrollRunId` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `BankGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [PayrollPaymentBatchLine](/docs/reference/entities/payroll-payment-batch-line/) — referenced by via `PayrollPaymentBatchId` - [PayrollRun](/docs/reference/entities/payroll-run/) — referenced by via `PaymentBatchId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Payroll Period — entity reference URL: https://xmatix.com/docs/reference/entities/payroll-period/ Last reviewed: 2026-08-16 The payroll processing calendar entry (monthly by default, also weekly, biweekly or daily) that every payroll document hangs off: runs, adjustments, statutory challans, TDS projections, loan recovery windows and payslips are all scoped by PayrollPeriodId. It is deliberately not the accounting FiscalPeriod — it links to one through FiscalPeriodId, and posting resolves the open FiscalPeriod separately, so the payroll cadence can differ from the ledger calendar. StartDate and EndDate define the calendar-day window the calculation uses for proration and attendance, and PayDate is what the payroll accrual journal is dated with (falling back to EndDate). Status runs Open, Processing, Approved, Paid, Closed, Locked; grain is one row per pay cycle per company, optionally per branch. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | Yes | An optional branch scoping for companies that run payroll separately per location. Nothing in the calculation filters employees by it — it is a dimension for organising and reporting on periods. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EndDate` | End Date | Date | | The last calendar day of the pay cycle. Besides closing the proration window it is the fallback date for the payroll accrual journal when no pay date is set, and a period ending in February switches professional-tax slab computation to its February treatment. | | `FiscalPeriodId` | Fiscal Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | Yes | | | `Id` | Id | Guid | Yes | | | `InputCutoffDate` | Input Cutoff Date | Date | | The intended deadline for payroll inputs for this cycle. It is advisory only — no first-party code reads it, and adjustments or declarations entered after it are still picked up by a later calculation. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | Yes | The company the cycle belongs to. Periods are per company, and the payslip year-to-date rollup only sums over periods of the same company as the run, so a period on the wrong company quietly drops out of those totals. | | `PayDate` | Pay Date | Date | | The intended salary payment date, and the date the payroll accrual journal is stamped with when the run is posted (falling back to the period end). It does not drive the actual bank payment date, which comes from the payment batch. | | `PayrollFrequency` | Payroll Frequency | PickList | | The intended cadence of the cycle: Monthly, Weekly, Biweekly or Daily, defaulting to Monthly. It is descriptive — the calculation derives everything from the actual start and end dates, so this value does not itself change proration or how often runs happen. Values: Monthly, Weekly, Biweekly, Daily. | | `PeriodName` | Period Name | Text | | The human name of the cycle, such as the month and year operators refer to it by. It is free text with no parsing behind it; join on the period record itself rather than matching this string. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StartDate` | Start Date | Date | | The first calendar day of the pay cycle. | | `Status` | Status | PickList | | Values: Open, Processing, Approved, Paid, Closed, Locked. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this PayrollPeriod. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this PayrollPeriod. | | `EditInLine` | Edit | EditInline | Edit | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a PayrollPeriod. | | `View` | View | View | View this PayrollPeriod. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `BranchId` | | | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `FiscalPeriodId` - [LoanAdvanceRecovery](/docs/reference/entities/loan-advance-recovery/) — referenced by via `PayrollPeriodId` - [MonthlyTdsProjection](/docs/reference/entities/monthly-tds-projection/) — referenced by via `PayrollPeriodId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `EndPayrollPeriodId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `StartPayrollPeriodId` - [Payslip](/docs/reference/entities/payslip/) — referenced by via `PayrollPeriodId` - [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) — referenced by via `PayrollPeriodId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `PayrollPeriodId` - [PayrollAdjustment](/docs/reference/entities/payroll-adjustment/) — referenced by via `PayrollPeriodId` - [PayrollRun](/docs/reference/entities/payroll-run/) — referenced by via `PayrollPeriodId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Run Component Line — entity reference URL: https://xmatix.com/docs/reference/entities/payroll-run-component-line/ Last reviewed: 2026-08-16 One component's calculated amount for one employee in one payroll run — the finest grain of the payroll calculation and the only place individual earning and deduction figures exist. PayrollRunDetail rolls these up, the payslip's earning/deduction lines are projected from them at render time rather than duplicated, and posting drives every journal line from them. Each row carries its own ComponentType, taxability, statutory flag, proration flag and both GL account mappings, copied down from the PayrollComponent master at calculation time so posting stays reproducible even if the master later changes. Rows come from three sources distinguished by SortOrder: salary-structure lines (the master's SortOrder or the structure sequence), approved PayrollAdjustment one-offs (1000), and loan or advance installment recovery (2000, with no PayrollComponentId and only a payable account). Prefer this entity over PayrollRunDetail for any question about a specific allowance, deduction or contribution. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | | | `ComponentType` | Component Type | PickList | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The expense or earning account this line debits when the run is posted, copied from the component master at calculation time. It is mandatory for earnings, reimbursements and employer contributions — a single such line without it aborts the whole post, naming that line. | | `Id` | Id | Guid | Yes | | | `IsProrated` | Is Prorated | Boolean | | | | `IsStatutory` | Is Statutory | Boolean | | | | `IsTaxable` | Is Taxable | Boolean | | | | `Label` | Label | Text | | A human-readable caption for the line that the calculation engine never fills in — engine-created rows carry only a generated Name. Do not rely on it to identify which component a line represents; resolve PayrollComponentId to the master instead, and note that recovery lines have no master at all. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PayableGLAccountId` | PayableGL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The liability or control account this line credits at posting: the statutory or deduction payable for a deduction, the contribution payable for an employer contribution, and the loan or advance control account for a recovery line. Deductions and employer contributions cannot post without it. | | `PayrollComponentId` | Payroll Component | Lookup → [PayrollComponent](/docs/reference/entities/payroll-component/) | | | | `PayrollRunDetailId` | Payroll Run Detail | Lookup → [PayrollRunDetail](/docs/reference/entities/payroll-run-detail/) | | The per-employee summary this line rolls into. It is assigned before the detail row itself is built, so every line of one employee in one run shares it and it is the correct grouping key for reconstructing a payslip breakdown. | | `PayrollRunId` | Payroll Run | Lookup → [PayrollRun](/docs/reference/entities/payroll-run/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | The person this component amount belongs to, denormalised onto the line so per-employee component queries need no join through the detail. It is a Resource reference, the same key payroll uses everywhere, not an Employee reference. | | `SortOrder` | Sort Order | Number | | Payslip display order, but also the tell for where the line came from: values copied from the component master or the structure sequence are ordinary salary-structure lines, 1000 marks a line created from an approved PayrollAdjustment, and 2000 marks a loan or advance installment recovery. Filtering on those two values is the reliable way to separate one-off and recovery lines from the standing structure. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this PayrollRunComponentLine. | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteListHeader` | Delete | Delete | DeleteListHeader | | `Edit` | Edit | Edit | Edit this PayrollRunComponentLine. | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | EditInLine | | `New` | New | New | Create a PayrollRunComponentLine. | | `NewInline` | New | NewInline | New | | `View` | View | View | View this PayrollRunComponentLine. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [PayrollComponent](/docs/reference/entities/payroll-component/) — looks up via `PayrollComponentId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `PayableGLAccountId` - [PayrollRun](/docs/reference/entities/payroll-run/) — looks up via `PayrollRunId` - [PayrollRunDetail](/docs/reference/entities/payroll-run-detail/) — looks up via `PayrollRunDetailId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Payroll Run Detail — entity reference URL: https://xmatix.com/docs/reference/entities/payroll-run-detail/ Last reviewed: 2026-08-16 The per-employee summary line of a PayrollRun: one row per Resource processed, carrying rolled-up gross, deductions and net, employer contributions, reimbursements, the day breakdown, and the statutory subtotals TDS, PF and ESI. It is a rollup, not the calculation source — the authoritative per-component amounts live in PayrollRunComponentLine, and a Payslip is generated from this row. Keyed on ResourceId, never on Employee; posting stamps PayrollPayableOpenTransactionId with the Resource-keyed Payroll-Payable open item raised for this employee's net pay, and that open item (not this row) is what the salary payment batch actually settles. Two generations of columns coexist here: the payroll engine writes PayableDays, TotalPayableDays, LossOfPayDays and LossOfPayAmount, while PaidDays, LWPDays, Component1, Component2 and OvertimeAmount are legacy and are written by no first-party code path. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Component1` | Component 1 | Currency | | A legacy generic amount slot from the pre-component payroll model, explicitly deprecated when per-component lines were introduced. No first-party service writes or reads it; the real breakdown is in PayrollRunComponentLine. | | `Component2` | Component 2 | Currency | | The second legacy generic amount slot from the pre-component payroll model. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EmployerContribTotal` | Employer Contrib Total | Currency | | | | `ESI` | ESI | Currency | | The employee-side employee state insurance withheld this period, summed only from deduction components flagged with the ESI statutory nature. The employer's ESI contribution is excluded and is carried as an employer-contribution component instead. | | `GrossEarnings` | Gross Earnings | Currency | | | | `Id` | Id | Guid | Yes | | | `LossOfPayAmount` | Loss Of Pay Amount | Currency | | | | `LossOfPayDays` | Loss Of Pay Days | Currency | | | | `LWPDays` | LWP Days | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NetPay` | Net Pay | Currency | | | | `OvertimeAmount` | Overtime Amount | Currency | | Intended to hold the period's overtime pay, but the calculation engine never writes it — overtime is not an implemented input. It is nevertheless read by profitability reporting, which adds it to gross and reimbursements when costing a resource, so it will simply contribute zero unless a tenant populates it by hand. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PaidDays` | Pa Days | Number | | | | `PartnerAccountId` | Partner Account | Lookup | | | | `PayableDays` | Payable Days | Currency | | | | `PayrollPayableOpenTransactionId` | Payroll Payable Open Transaction | Lookup | | The Resource-keyed Payroll-Payable open item raised for this employee's net pay when the run was posted. That open item, not this row's NetPay, is the amount the salary payment batch settles, so the two can diverge if the open item was partly settled elsewhere. | | `PayrollPeriodId` | Payroll Period | Lookup | | The pay cycle this line belongs to, copied from the parent run at calculation time. It is the field the year-to-date payslip rollup and the period's TDS challan filter on, so a detail whose period is empty is invisible to both even though it belongs to the run. | | `PayrollPostingStatus` | Payroll Posting Status | PickList | | Whether this employee's line reached the ledger — it flips to Posted only for employees whose net pay was positive and therefore raised an open item. An employee with zero or negative net stays NotPosted even on a fully posted run, and the period's TDS challan totals only over details marked Posted. Values: Not Posted, Posted, Reversed, Failed. | | `PayrollRunId` | Payroll Run | Lookup → [PayrollRun](/docs/reference/entities/payroll-run/) | | | | `PF` | PF | Currency | | The employee-side provident fund withheld this period. It sums only deduction components whose statutory nature is PF, so the employer's matching contribution is not included here — that sits in EmployerContribTotal and on its own component lines. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReimbursementAmount` | Reimbursement Amount | Currency | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | The person this line pays, held as a Resource — the platform's person master — not as an Employee. Every payroll join, the payslip, the Payroll-Payable open item and the payment batch line all key on this same value, so filter payroll by ResourceId and reach the Employee record from there when employment attributes are needed. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TDS` | TDS | Currency | | | | `TotalDeductions` | Total Deductions | Currency | | Everything subtracted from gross to reach net: statutory withholding, structure deductions, approved deduction adjustments, and any loan or advance installment recovered in this run. Employer contributions are not part of it — they are a cost to the company, not a withholding from the employee. | | `TotalPayableDays` | Total Payable Days | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | edit | | `EditRow` | Edit | Edit | Edit | | `LatestPayslip` | Latest Payslip | ServerAction | Opens a payslip layout view over this employee's run line. It is registered as a server action but carries no server action name, so nothing is computed, generated or saved by invoking it — it neither creates a Payslip record nor publishes an existing one. | | `NewInLine` | New | NewInline | New | ## Related entities - [PayrollRun](/docs/reference/entities/payroll-run/) — looks up via `PayrollRunId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [Payslip](/docs/reference/entities/payslip/) — referenced by via `PayrollRunDetailId` - [PayrollRunComponentLine](/docs/reference/entities/payroll-run-component-line/) — referenced by via `PayrollRunDetailId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Payroll Run — entity reference URL: https://xmatix.com/docs/reference/entities/payroll-run/ Last reviewed: 2026-08-16 One execution of payroll for a PayrollPeriod, and the header that drives the whole chain: Project TDS, Calculate, Post, Generate Payslips, Generate Payment. It owns per-employee PayrollRunDetail summaries, per-component PayrollRunComponentLine rows (the calculation truth), the Payslips generated from those details, and the LoanAdvanceRecovery rows for installments recovered in this run. Three status fields move independently: Status is the business lifecycle (Draft, InputsLoaded, Calculated, Review, Approved, Posted, PaymentGenerated, Paid, Closed, Reversed), ApprovalStatus mirrors the approval engine, and PayrollPostingStatus plus GLId record whether the accrual journal exists — never infer posting from Status alone. Recalculating REPLACES the previous pass rather than appending, and is refused outright once the run is posted or its payslips are published. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApprovalStatus` | Approval Status | PickList | | A mirror of the approval engine's outcome on this run — Approved, Rejected, Pending, or cleared to null on recall — written by the approval bridge, not by the payroll engine. It matters because a final Approved decision also posts the run's accrual to the ledger automatically, unless the run is already posted, so this field moving to Approved usually means a journal was created. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch dimension copied onto the payroll journal, its lines and every Payroll-Payable open item raised by posting. It is not used to filter which employees are included — the calculation selects on company, not branch. | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | A dimension carried through to the Payroll-Payable open items raised at posting. It does not appear on the journal lines and does not affect which employees are calculated. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | The payroll accrual Journal this run posted. It is a posting gate as much as a link: a run with any value here is treated as posted and will refuse both a second post and a recalculation, even if PayrollPostingStatus says otherwise. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company whose payroll this run is, and the selector for the whole calculation: employees are picked up when their payroll company or their own company matches it, and the bank, Payroll-Payable control account and fiscal-year window for year-to-date figures are all resolved under it. A run left without a company cannot derive a bank account and fails when a payment batch is generated. | | `PaymentBatchId` | Payment Batch | Lookup → [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) | | The salary batch that actually disbursed this run's net pay. It is stamped only when the batch is paid, not when it is generated, so a run can have a Draft PayrollPaymentBatch pointing back at it while this is still empty. | | `PayrollPeriodId` | Payroll Period | Lookup → [PayrollPeriod](/docs/reference/entities/payroll-period/) | | The pay cycle this run belongs to, and the key input to nearly every step: it supplies the start and end dates used for proration and loss of pay, the pay date the accrual journal is dated with, the period whose approved adjustments are pulled in, and the period whose TDS projections the calculation reads. A run without it still calculates, but with no proration, no adjustments and no TDS, and it cannot prepare a statutory challan. | | `PayrollPostingStatus` | Payroll Posting Status | PickList | | Values: Not Posted, Posted, Reversed, Failed. | | `Period` | Period | PickList | Yes | Values: January, February, March, April, May, June, July, August, September, October, November, December. | | `ProcessedResources` | Processed Resources | Number | | How many employees actually produced a PayrollRunDetail in the last calculation pass. Stamped by the calculation and not kept live, so it goes stale if details are deleted by hand afterwards. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SkippedResources` | Skipped Resources | Number | | | | `Status` | Status | PickList | Yes | The run's business lifecycle stage, from the vocabulary Draft, InputsLoaded, Calculated, Review, Approved, Posted, PaymentGenerated, Paid, Closed and Reversed. Note also that the seeded approval process stamps its own values, Pending Approval on submission and Processed on final approval, which is why those two appear in the picklist even though no engine constant matches them. Values: Draft, PendingApproval, Inputs Loaded, Calculated, Processed, Review, Approved, Posted, Payment Generated, Paid, Closed, Reversed. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TotalNetPay` | Total Net Pay | Calculated (calculated) | | The sum of every processed employee's net pay, stamped by the calculation at the end of a pass rather than maintained as rows change. It reflects the last calculation only — it is not adjusted by posting, by the payment batch, or by editing a component line afterwards. | | `TotalResources` | Total Resources | Number | | How many active, non-exited employees of the run's payroll company were considered in the last calculation pass — the denominator, not the number paid. Compare it with ProcessedResources and SkippedResources to see whether the run covered everyone. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `CalculateRun` | Calculate | ServerAction (`CalculatePayrollRun`) | Calculate the payroll run. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `EditRecord` | Edit | Edit | Edit | | `Form16` | Form 16 | ServerAction | Form16 | | `GeneratePaymentBatch` | Generate Payment | ServerAction (`GeneratePaymentBatch`) | Generate the salary payment batch. | | `GeneratePayslips` | Generate Payslips | ServerAction (`GeneratePayslips`) | Generate payslips for the run. | | `New` | New | New | New | | `PostPayroll` | Post Payroll | UIAction | Post Payroll | | `PostRun` | Post | ServerAction (`PostPayrollRun`) | Post the payroll accrual to the ledger. | | `PrepareSalaryTdsChallan` | Prepare TDS Challan | ServerAction (`PrepareSalaryTdsChallan`) | Drafts the period's salary-TDS deposit challan by totalling the tax on every POSTED payroll detail of the same company and period — not just this run — and creating a pending challan for that amount. Re-running is safe: an existing pending challan for the period is refreshed to the new total, while one already deposited is left untouched and instead reports the difference for a separate deposit. It fails when the run has no payroll period or when no posted TDS exists yet, so post the payroll first. | | `Print` | Print | ServerAction | Payroll slip print | | `ProjectTds` | Project TDS | ServerAction (`ProjectTds`) | Project salary TDS for every employee in this run. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `BranchId` | BranchFilter | | PartnerAccountFilter | `PartnerAccountId` | PartnerAccountFilter | ## Related entities - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) — looks up via `PaymentBatchId` - [PayrollPeriod](/docs/reference/entities/payroll-period/) — looks up via `PayrollPeriodId` - [Payslip](/docs/reference/entities/payslip/) — referenced by via `PayrollRunId` - [PaymentSalaryDisbursement](/docs/reference/entities/payment-salary-disbursement/) — referenced by via `PayrollRunId` - [Payment](/docs/reference/entities/payment/) — referenced by via `PayrollRunId` - [PayrollRunDetail](/docs/reference/entities/payroll-run-detail/) — referenced by via `PayrollRunId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `IncludedInPayrollRunId` - [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) — referenced by via `PayrollRunId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [LoanAdvanceRecovery](/docs/reference/entities/loan-advance-recovery/) — referenced by via `PayrollRunId` - [InterestCharge](/docs/reference/entities/interest-charge/) — referenced by via `SourceRecordId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `SourceRecordId` - [PayrollRunComponentLine](/docs/reference/entities/payroll-run-component-line/) — referenced by via `PayrollRunId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Statutory Challan — entity reference URL: https://xmatix.com/docs/reference/entities/payroll-statutory-challan/ Last reviewed: 2026-08-16 A statutory deposit for a payroll period — the PF, ESI, PT, salary-TDS or LWF payment that clears the company-level liability payroll posting accumulated. It is company-level and period-level, not per employee; for per-employee withholding use PayrollRunComponentLine or PayrollRunDetail. The salary-TDS challan can be drafted from a payroll run, which sums TDS across every POSTED run detail of the period (a period may carry several runs) and is idempotent per company and period: it refreshes a Pending draft's amount, and reports rather than alters an already-deposited challan. Posting writes a two-line journal, Dr the statutory payable control / Cr Bank, then sets Status to Paid and stamps PaidDate and GLId. The quarterly salary TDS return picks up only challans of type TDS whose Status is exactly Paid, and cites their BSR code, challan serial and paid date as the CIN. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | The sum being deposited, and the exact figure posted to the journal — the Dr to the payable control and the Cr to bank both use it. When drafted from a payroll run it is the total TDS over every POSTED run detail of the period; edited afterwards it is taken at face value, since posting does not re-check it against what payroll actually withheld. Posting refuses a zero or negative amount. | | `BankGLAccountId` | BankGL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The bank account credited by the deposit. | | `BsrCode` | BSR Code | Text | | The receiving bank branch's seven-digit BSR code — the first part of the CIN that identifies the deposit to the tax department. The quarterly salary TDS return copies it onto its challan annexure, and its checklist counts any challan missing the BSR code, challan serial or tender date as incomplete. | | `ChallanNumber` | Challan Number | Text | | The bank or portal reference for the deposit. For salary TDS it is the legacy fallback for the challan serial: the quarterly return uses ChallanSerial when present and otherwise takes the first ten characters of this value. | | `ChallanSerial` | Challan Serial | Text | | The bank's challan serial number, the third part of the CIN alongside the BSR code and the deposit date. When blank the return falls back to a truncated ChallanNumber, which will not match the tax department's records unless that field happens to hold the serial. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | The journal produced when the challan was posted. It doubles as the posted flag: a challan carrying a journal is refused a second post, and the salary-TDS draft routine treats it as already deposited and will not refresh its amount. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PaidDate` | Pa Date | Date | | The deposit date, which drives the journal date when the challan is posted — if blank at posting time, today's date is used and stamped back onto the record. It also becomes the tender date on the quarterly return's challan annexure, so an incorrect date here misstates whether the deposit was late. | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PayableGLAccountId` | PayableGL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The statutory payable control account to debit. Optional: when blank, posting resolves the control from StatutoryType, and only fails if no control account is configured for that type on the company. Setting it explicitly overrides that resolution. | | `PayrollPeriodId` | Payroll Period | Lookup → [PayrollPeriod](/docs/reference/entities/payroll-period/) | | The payroll period whose liability this deposit clears, and the key that makes the salary-TDS challan idempotent — one challan per company and period, even where the period carries several runs such as off-cycle or correction runs. The return generator also groups deducted-detail rows to a challan through this period. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Status` | Status | PickList | | The deposit's lifecycle. In practice only two values are produced by code: a drafted or newly created challan is Pending, and posting sets it to Paid. The quarterly salary TDS return picks up only challans whose status is exactly Paid, so a challan sitting on any other value is invisible to return filing. Values: Draft, Paid, Reconciled. | | `StatutoryType` | Statutory Type | PickList | | PF, ESI, PT, TDS or LWF. More than a label: when PayableGLAccountId is not set, posting resolves the control account from this value (PF to PfPayable, ESI to EsiPayable, PT to ProfessionalTaxPayable, TDS to TdsSalaryPayable, LWF to LwfPayable), falling back to the general Payroll Payable control for anything else — including Gratuity, which the picklist offers but posting has no dedicated control for. It is also the filter the salary TDS return uses to find deposit challans. Values: PF, ESI, PT, TDS, LWF, Gratuity. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this PayrollStatutoryChallan. | | `DeleteEntity` | Delete | Delete | Delete | | `DeleteHeader` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this PayrollStatutoryChallan. | | `EditEntity` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `New` | New | New | Create a PayrollStatutoryChallan. | | `PostChallan` | Post Challan | ServerAction (`PostChallan`) | Invoking it saves the record and returns without writing a journal or changing Status. The posting logic itself exists in the platform and is exercised by tests, but the only routes that reach it today are the payroll run's own prepare/post actions. Do not tell a user that pressing this posts the challan. | | `View` | View | View | View this PayrollStatutoryChallan. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `PayableGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `BankGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [PayrollPeriod](/docs/reference/entities/payroll-period/) — looks up via `PayrollPeriodId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [TdsReturnChallan](/docs/reference/entities/tds-return-challan/) — referenced by via `PayrollStatutoryChallanId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Payslip — entity reference URL: https://xmatix.com/docs/reference/entities/payslip/ Last reviewed: 2026-08-16 The employee-facing pay document generated from a PayrollRunDetail, carrying header totals plus year-to-date rollups and a masked bank account. The earning and deduction lines are NOT stored here — they are projected from PayrollRunComponentLine, so a payslip alone cannot answer component-level questions. PublishStatus gates visibility (employees are meant to see only Published slips), and a run whose slips are Published can no longer be recalculated; generation is idempotent, skipping any detail that already has a slip. YtdGross and YtdTax are summed only over the PayrollPeriods inside the fiscal year containing the run's period, falling back to an April–March year, so they are year-to-date and not lifetime-to-date. Keyed on ResourceId; the rendered PDF would be referenced by FileAssetId, but no first-party code renders or attaches one. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EmployeeId` | Employee | Lookup → [Employee](/docs/reference/entities/employee/) | | | | `FileAssetId` | File Asset | Guid | | Reserved for the rendered payslip PDF stored as a file asset. | | `GeneratedUtc` | Generated Utc | Date | | When the slip was created by the generation step, in UTC. It is not the pay date and not a publication timestamp — publication is tracked only by PublishStatus, which carries no date of its own. | | `GrossEarnings` | Gross Earnings | Currency | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `LopDays` | Lop Days | Decimal | | | | `MaskedBankAccount` | Masked Bank Account | Text | | The employee's bank account reduced to the literal prefix XXXX plus its last four digits, snapshotted from the Resource when the slip was generated. It is a display artefact only — it is never used to pay anyone, and it does not follow later changes to the employee's bank details. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text, unique | Yes | | | `NetPay` | Net Pay | Currency | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PayableDays` | Payable Days | Decimal | | The days the employee was actually paid for in the period, copied from the run detail. It is calendar days in the period minus approved unpaid leave, not attended days — weekly offs and holidays are not deducted. | | `PayrollPeriodId` | Payroll Period | Lookup → [PayrollPeriod](/docs/reference/entities/payroll-period/) | | The pay cycle the slip covers, taken from the source detail and falling back to the run's period. Use it rather than the generation timestamp when grouping slips by month. | | `PayrollRunDetailId` | Payroll Run Detail | Lookup → [PayrollRunDetail](/docs/reference/entities/payroll-run-detail/) | | The per-employee run summary this slip was generated from, and the idempotency key for generation: a detail that already has a slip is skipped when payslips are generated again. It is also the route to the component lines the printed breakdown is projected from. | | `PayrollRunId` | Payroll Run | Lookup → [PayrollRun](/docs/reference/entities/payroll-run/) | | | | `PublishStatus` | Publish Status | PickList | | Values: Draft, Published. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `TotalDeductions` | Total Deductions | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `YtdGross` | Ytd Gross | Currency | | | | `YtdTax` | Ytd Tax | Currency | | Salary tax withheld so far in the fiscal year containing this run's period, summed across that year's payroll details for the same employee and company. It is bounded to the fiscal year (falling back to an April–March year when the company has no fiscal calendar), so it resets each year and is not a lifetime figure. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this Payslip. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this Payslip. | | `EditInLine` | Edit | EditInline | Edit | | `EditRecord` | Edit | Edit | Edit | | `Form16` | Form 16 | UIAction | Form 16 | | `New` | New | New | Create a Payslip. | | `PrintPayslip` | Print Payslip | Print | Print the payslip as a PDF document. | | `TaxDeclaration` | Tax Declaration | Print | Tax Declaration | | `View` | View | View | View this Payslip. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `BranchId` | BranchFilter | | PartnerAccountFilter | `PartnerAccountId` | PartnerAccountFilter | ## Related entities - [PayrollRun](/docs/reference/entities/payroll-run/) — looks up via `PayrollRunId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Employee](/docs/reference/entities/employee/) — looks up via `EmployeeId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [PayrollRunDetail](/docs/reference/entities/payroll-run-detail/) — looks up via `PayrollRunDetailId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [PayrollPeriod](/docs/reference/entities/payroll-period/) — looks up via `PayrollPeriodId` - [Employee](/docs/reference/entities/employee/) — referenced by via `PayslipId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Performance KPI — entity reference URL: https://xmatix.com/docs/reference/entities/performance-kpi/ Last reviewed: 2026-08-16 A flat performance fact row - the accumulator table that the Scheme and Incentive engines read to know what a partner, account or resource has actually done. Each row carries dimensional keys (accountId, partnerAccountId, supplierAccountId, branchId, resourceId, itemId, sKUId, plus schemeId/schemePeriodId for scheme-period accruals and incentivePlanId/incentivePeriodId/incentiveTargetId for incentive tracking) and a wide palette of per-document-type counters and totals: numberOfInvoices/Orders/Quotes/Bills/Leads/Opportunities/RepairOrders/ServiceRequests/PurchaseOrders and matching totalSaleInvoiceAmount/totalSaleOrderAmount/totalQuoteAmount/totalBillAmount/totalPurchaseOrderAmount/totalRepairOrderAmount quantity-and-amount pairs, plus generic totalAmount/totalQuantity and targetValue. Rows are posted by document services as business documents progress (for example OpportunityService posts one row per opportunity KPI recalculation with numberOfOpportunities=1 and the opportunity total). postingType separates consumer streams: the same event is posted once as SCHEME and once as INCENTIVE. SchemeEngine reads the SCHEME-side rows as its per-period summary, matching on schemeId/schemePeriodId and widening account scope to the account's parent, children and siblings; IncentiveEngine loads rows by incentivePlanId+incentivePeriodId to evaluate targets, including a Custom KPI target type that reads any named PerformanceKPI property by reflection. The Rewards reports (actuals vs targets by period, plan or account) are all built on this table. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IncentivePeriodId` | Incentive Period | Lookup → [IncentivePeriod](/docs/reference/entities/incentive-period/) | | | | `IncentivePlanId` | Incentive Plan | Lookup → [IncentivePlan](/docs/reference/entities/incentive-plan/) | | | | `IncentiveTargetId` | Incentive Target | Lookup → [IncentiveTarget](/docs/reference/entities/incentive-target/) | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | KPI Name | Text | Yes | | | `NumberOfBills` | Number Of Bills | Number | | | | `NumberOfInvoices` | Number Of Invoices | Number | | | | `NumberOfLeads` | Number Of Leads | Number | | | | `NumberOfOpportunities` | Number Of Opportunities | Number | | | | `NumberOfOrders` | Number Of Orders | Number | | | | `NumberOfPurchaseOrders` | Number Of Purchase Orders | Number | | | | `NumberOfQuotes` | Number Of Quotes | Number | | | | `NumberOfRepairOrders` | Number Of Repair Orders | Number | | | | `NumberOfServiceRequests` | Number Of Service Requests | Number | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PostingType` | Posting Type | PickList | | Discriminates which consumer stream the fact row belongs to: the posting services write the same business event twice, once with SCHEME (read by the scheme engine's period summary) and once with INCENTIVE (read by the incentive engine). Filter on it to avoid double counting when totalling rows. Values: KPI, Scheme Ledger. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `SchemeId` | Scheme | Lookup → [Scheme](/docs/reference/entities/scheme/) | | | | `SchemePeriodId` | Scheme Period | Lookup → [SchemePeriod](/docs/reference/entities/scheme-period/) | | Ties a scheme-side accrual row to a specific SchemePeriod. The scheme engine matches a document's date to the scheme's period windows and only counts rows whose SchemePeriodId falls in the matching window (rows without a period are counted for schemes that define no matching periods). | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `TargetValue` | Target Value | Calculated | | The target figure the accumulated actuals are measured against for this slice; the Rewards reports pair it with TotalAmount to show actual versus target per incentive period. | | `TotalAmount` | Total Amount | Currency | | | | `TotalBillAmount` | Total Bill Amount | Currency | | | | `TotalBillQuantity` | Total Bill Quantity | Number | | | | `TotalPurchaseOrderAmount` | Total Purchase Order Amount | Currency | | | | `TotalPurchaseOrderQuantity` | Total Purchase Order Quantity | Number | | | | `TotalQuantity` | Total Quantity | Number | | | | `TotalQuoteAmount` | Total Quote Amount | Currency | | | | `TotalQuoteQuantity` | Total Quote Quantity | Number | | | | `TotalRepairOrderAmount` | Total Repair Order Amount | Currency | | | | `TotalRepairOrderQuantity` | Total Repair Order Quantity | Number | | | | `TotalSaleInvoiceAmount` | Total Sale Invoice Amount | Currency | | | | `TotalSaleInvoiceQuantity` | Total Sale Invoice Quantity | Number | | | | `TotalSaleOrderAmount` | Total Sale Order Amount | Currency | | | | `TotalSaleOrderQuantity` | Total Sale Order Quantity | Number | | | | `TotalServiceRequestAmount` | Total Service Request Amount | Currency | | | | `TotalServiceRequestQuantity` | Total Service Request Quantity | Number | | | | `TotalTaxAmount` | Total Tax Amount | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [IncentivePeriod](/docs/reference/entities/incentive-period/) — looks up via `IncentivePeriodId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — looks up via `IncentivePlanId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [Scheme](/docs/reference/entities/scheme/) — looks up via `SchemeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [SchemePeriod](/docs/reference/entities/scheme-period/) — looks up via `SchemePeriodId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — looks up via `IncentiveTargetId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Period Close Check — entity reference URL: https://xmatix.com/docs/reference/entities/period-close-check/ Last reviewed: 2026-08-16 One evaluated line of a period-close run: a single integrity test with a stable machine code, whether it was blocking, whether it passed, and a detail string naming the offending counts. Four of the ten tests are mandatory and gate the close: every posted journal balances, no draft or pending journals are dated in the period, receivable and payable open items tie to their allocations, and no unresolved posting failures remain queued. The other six are advisory and record a warning without stopping the close. Rows are written by the close service at evaluation time, not entered by hand. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CheckCode` | Check Code | Text | | The stable machine identifier of the test, drawn from a fixed set of upper-case codes such as LEDGER_BALANCED, NO_DRAFT_JOURNALS, OPEN_ITEMS_TIE and NO_FAILED_POSTINGS. Match on this rather than on the display text, which is prose written at evaluation time and may change. | | `CheckName` | Check Name | Text | | The readable sentence describing what the test asserts, copied onto the row by the close service when the run was recorded. It is a snapshot for the audit trail, not a link to a configurable checklist definition. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Detail` | Detail | Text | | Populated only when the item failed, carrying the offending counts or amounts such as how many journals were unbalanced or how far a control account drifted from its subledger. It is left empty on a pass. | | `Id` | Id | Guid | Yes | | | `IsMandatory` | Is Mandatory | Boolean | | Whether this item blocks the close. Only four codes are blocking: journals balance, no draft or pending journals dated in the period, receivable and payable open items tie to allocations, and no unresolved posting failures. Everything else is advisory. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Passed` | Passed | Boolean | | The outcome at the moment the run was recorded. Advisory items are often false on a successfully closed period, so a false value alone does not indicate a problem; read it together with whether the item was blocking. | | `PeriodCloseId` | Period Close | Lookup → [PeriodClose](/docs/reference/entities/period-close/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Edit` | Edit | Edit | Edit | | `New` | New | NewInline | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [PeriodClose](/docs/reference/entities/period-close/) — looks up via `PeriodCloseId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Period Close — entity reference URL: https://xmatix.com/docs/reference/entities/period-close/ Last reviewed: 2026-08-16 The audit record of one run of the period-close checklist against a fiscal period. It stores how many checks ran, how many passed and how many blocking ones failed, plus the close status the period was moved to as a result. Its check children preserve every individual outcome, so a forced close stays visible long after the period moved. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AllMandatoryPassed` | All Mandatory Passed | Boolean | | Set only when no blocking item failed. A forced close is deliberately recorded with this false, which is how an override remains auditable after the period has already moved on. | | `CloseDate` | Close Date | DateAndTime | | The effective date stamped on the run, stored without a time component and defaulting to the day the close was executed rather than to the period's own end date. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FiscalPeriodId` | Fiscal Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | | | | `Id` | Id | Guid | Yes | | | `MandatoryFailures` | Mandatory Failures | Number | | How many blocking items failed. Any value above zero refuses the close unless the caller explicitly overrides, so a stored run carrying a positive count is by definition a forced close. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Notes` | Notes | Text | | Free text supplied by whoever ran the close. It is the usual place a justification for a forced close is captured, since the override path carries no separate reason field of its own. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PassedChecks` | Passed Checks | Number | | How many evaluated items passed, counting advisory items alongside blocking ones. It can legitimately fall short of the total on a perfectly valid close, because advisory failures never stop one. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Status` | Status | Text | | The close state applied to the period by this run, one of SoftClosed, Closed or Locked, rather than the state of the run record itself. SoftClosed marks a soft month-end, Closed and Locked are final, and a locked period can never be reopened. | | `TotalChecks` | Total Checks | Number | | How many checklist items this run actually evaluated, blocking and advisory together. It is a count of what ran, not the size of a configurable checklist definition. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | EDIT | EditInline | EDIT | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `FiscalPeriodId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [PeriodCloseCheck](/docs/reference/entities/period-close-check/) — referenced by via `PeriodCloseId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # PF Rule — entity reference URL: https://xmatix.com/docs/reference/entities/pfrule/ Last reviewed: 2026-08-16 The Provident Fund rule master for a company: the wage ceiling that caps the PF basis, the employee and employer contribution rates, and the EDLI and administration charge rates, effective-dated. Important for grounding: the platform has a deterministic PF calculator (basis capped at the ceiling, times the rate) but the payroll calculation engine does NOT consult this master — only professional-tax slabs and the monthly TDS projection are wired into it. In a live run PF appears because the salary structure carries a PF component computed as an ordinary Fixed or Percentage line, so a figure that disagrees with this rule is not by itself a bug. Treat PFRule as configuration of record and statutory reference, not as the driver of the PF amount on a payslip. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AdminChargeRate` | Admin Charge Rate | Currency | | Configuration for the employer's PF administration charge. As with EdliRate, no code path reads it; it is recorded for reference and does not produce a cost line anywhere in payroll. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EdliRate` | Edli Rate | Currency | | Configuration for the employer's EDLI insurance charge. | | `EffectiveFrom` | Effective From | Date | | The date the rule is meant to take effect. Rule selection is not date-driven in any live path — the payroll run never loads PFRule at all — so this is documentation of the rate change rather than a switch that applies it. | | `EmployeeRate` | Employee Rate | Currency | | The employee's contribution as a percentage of the capped PF wage. Used by the platform's PF helper, which the payroll run does not call, so this rate does not by itself determine the PF deduction on a payslip. | | `EmployerRate` | Employer Rate | Currency | | The employer's contribution as a percentage of the capped PF wage. The helper applies it to the same ceiling-capped basis as the employee rate and does not split it between the pension and provident portions. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | Yes | The legal entity whose PF configuration this is. | | `PFWageCeiling` | PF Wage Ceiling | Currency | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this PFRule. | | `DeleteHeader` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this PFRule. | | `Editheader` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `New` | New | New | Create a PFRule. | | `View` | View | View | View this PFRule. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Place — entity reference URL: https://xmatix.com/docs/reference/entities/place/ Last reviewed: 2026-08-16 A geographic location master arranged as a self-referencing hierarchy: parentPlaceId points at the containing place, and level/placeType describe what kind of node it is. Its main role is as the city lookup on party and document addresses - Account, Order, Invoice, Quote, Opportunity, Bill, PurchaseOrder, DeliveryOrder and ServiceOrder all reference Places through their billing-city and shipping-city lookup pairs, and PostalCode rows link to their city via cityPlaceId. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `Level` | Level | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentPlaceId` | Parent Place | Lookup → [Place](/docs/reference/entities/place/) | | | | `PlaceType` | Place Type | PickList | | Values: City, District, State, Country, Locality, Territory, Region. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Place](/docs/reference/entities/place/) — looks up via `ParentPlaceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Bill](/docs/reference/entities/bill/) — referenced by via `BillingCityId` - [Account](/docs/reference/entities/account/) — referenced by via `ShippingCityPlaceId` - [Bill](/docs/reference/entities/bill/) — referenced by via `ShippingCityId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `BillingCityPlaceId` - [ContactAddress](/docs/reference/entities/contact-address/) — referenced by via `CityPlaceId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `ShippingCityPlaceId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `BillingCityPlaceId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `BillingCityPlaceId` - [Place](/docs/reference/entities/place/) — referenced by via `ParentPlaceId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `BillingCityPlaceId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `ShippingCityPlaceId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `BillingCityPlaceId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `ShippingCityPlaceId` - [Order](/docs/reference/entities/order/) — referenced by via `BillingCityPlaceId` - [Account](/docs/reference/entities/account/) — referenced by via `BillingCityPlaceId` - [Order](/docs/reference/entities/order/) — referenced by via `ShippingCityPlaceId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `ShippingCityPlaceId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `ShippingCityPlaceId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Planogram — entity reference URL: https://xmatix.com/docs/reference/entities/planogram/ Last reviewed: 2026-08-16 A shelf-layout definition that merchandising audits are judged against: layoutJson holds the structured expectation (shelves, positions, product and expected facings) the compliance calculator consumes, and an optional reference photo rides the generic file-asset pipeline. Scope is one outlet (accountId), a class of outlets (accountType, matched against Account.Type), or tenant-wide when both are empty; the applicable planogram for an audit is resolved by effective window with narrowest scope winning, and only Active rows are considered. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `AccountType` | Account Type | MultiLineText | | Outlet-class scope matched verbatim against Account.Type (for example a store-format value). Narrower than tenant-wide, wider than the single-outlet accountId scope; narrowest applicable scope wins at resolution. | | `Description` | Description | MultiLineText | | | | `EffectiveFrom` | Effective From | DateAndTime | | | | `EffectiveTo` | Effective To | DateAndTime | | | | `Label` | Label | MultiLineText | | | | `LayoutJson` | Layout Json | MultiLineText | | The structured shelf expectation the compliance calculator consumes: shelves, positions, product/brand and expected facings. This JSON is the judgment source; the optional reference photo is only illustrative. | | `Status` | Status | PickList | | Values: Draft, Active, Retired. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | Delete Header | | `EditEntityDetail` | Edit | Edit | EditEntityDetail | | `EditInLineEntity` | Edit | EditInline | EditInLineEntity | | `EditInLineHeader` | Edit | EditInline | Edit In Line Header | | `NewHeader` | New | New | NewHeader | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [ShelfAuditResult](/docs/reference/entities/shelf-audit-result/) — referenced by via `PlanogramId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # PM Task — entity reference URL: https://xmatix.com/docs/reference/entities/pmtask/ Last reviewed: 2026-08-16 A single scheduled preventive-maintenance visit for an Asset, delivered under a ContractLine (not under the Contract header). Records the check to perform (TaskType), the contractual due date and the planned visit window, the assigned Technician (a Resource), the partner Account performing the work, and a denormalized snapshot of the asset's billing address (street, city, state, zip) held directly on the task. Rows are created by data entry or import: no first-party scheduler generates PMTask records from ContractLine's visit frequency. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountPMCapacity` | Account PM Capacity | Text | | | | `AssetBillingCity` | Asset Billing City | Text | | | | `AssetBillingState` | Asset Billing State | Text | | | | `AssetBillingStreet` | Asset Billing Street | Text | | Street of the serviced asset's billing address, part of a denormalized address snapshot (street, city, state, zip) held directly on the task rather than joined from the Asset. | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `ContractLineId` | Contract Line | Lookup → [ContractLine](/docs/reference/entities/contract-line/) | | The ContractLine this visit is delivered under. PM tasks attach to contract lines, not to the Contract header. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DueDate` | Due Date | Date | | When the visit falls due under the contract, as opposed to ScheduledDueDate/ScheduledDueEndDate, which hold the window the visit is actually planned for. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Lookup to the Account performing the visit as a service partner. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ScheduledDueDate` | Scheduled Due Date | Date | | Start of the planned visit window; pairs with ScheduledDueEndDate. The contractual deadline is DueDate. | | `ScheduledDueEndDate` | Scheduled Due End Date | Date | | End of the planned visit window that begins at ScheduledDueDate. | | `SRNumber` | SR Number | Text | | External reference number for the visit (labelled SR Number), stored as free text — not a foreign key to any service document. | | `Status` | Status | PickList | | Progress state of the visit. Picklist-typed but with no first-party values seeded — each tenant defines its own status vocabulary, so do not assume any particular set of states. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TaskType` | Task Type | PickList | | The maintenance check this visit performs. Seeded vocabulary: B Check, C Check, D Check, B and C Check, Coolant Topup, OOS, Preventive Maintenance, Performance Qualification, Operational Checks. Values: B Check, C Check, D Check, B and C Check, Coolant Topup, OOS, Preventive Maintenance, Performance Qualification, Operational Checks. | | `TechnicianId` | Technician | Lookup → [Resource](/docs/reference/entities/resource/) | | The Resource (technician) assigned to carry out the visit. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `ZipCode` | Zip Code | Number | | Postal code of the task's asset address snapshot, stored as an integer — leading zeros are lost and alphanumeric postal codes cannot be stored. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `New` | New | New | New | ## Related entities - [ContractLine](/docs/reference/entities/contract-line/) — looks up via `ContractLineId` - [Resource](/docs/reference/entities/resource/) — looks up via `TechnicianId` - [Asset](/docs/reference/entities/asset/) — looks up via `Asset` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Position — entity reference URL: https://xmatix.com/docs/reference/entities/position/ Last reviewed: 2026-08-16 A field-sales seat, or territory slot, that exists independently of whoever currently occupies it. Visit routes can be assigned to the seat rather than to a person, and the plans generated for it go to whoever holds it - the ExecutivePosition row whose Effective To is still empty. The seat carries its own operating coordinates, so route planning departs from the seat's own base and a handover therefore never moves the territory or its customers; depot resolution falls back from the seat's geography to its branch geography, then the holder's default-branch geography, then the account centroid. Parent Position stores a seat hierarchy that no first-party code acts on yet. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | An administrative grouping for the seat, not its depot. Route planning starts from the seat's own coordinates and only falls back to this branch's geography, then the holder's default-branch geography, then the account centroid, when those coordinates are missing. | | `Code` | Code | MultiLineText | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | | | | `Description` | Description | Text | | | | `GeoLocation` | Operating Location | GeoLocation | | The seat's operating base: routes planned for this seat start and end here. | | `Id` | Id | Guid | Yes | | | `IsActive` | Active | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentPositionId` | Parent Position | Lookup → [Position](/docs/reference/entities/position/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInList` | Edit | EditInline | Edit In List Header | | `New` | New | New | New | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Position](/docs/reference/entities/position/) — looks up via `ParentPositionId` - [VisitRoute](/docs/reference/entities/visit-route/) — referenced by via `PositionId` - [ExecutivePosition](/docs/reference/entities/executive-position/) — referenced by via `PositionId` - [Position](/docs/reference/entities/position/) — referenced by via `ParentPositionId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Postal Code — entity reference URL: https://xmatix.com/docs/reference/entities/postal-code/ Last reviewed: 2026-08-16 A postal/PIN code master row with its city (free-text city plus a cityPlaceId lookup to Place), state, region and country. Both Name and Code carry the code text and different services match different ones: lead branch-assignment resolves the lead's postal code against Code, while the nearby-branch search matches with a LIKE against Name - keep the two consistent. Child BranchPostalCode rows map each code to the branches that serve it, which is what postal-code driven assignment and branch search traverse. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `City` | City | PickList | | Values: Pune, Mumbai, Chandigarh. | | `CityPlaceId` | CityPlace | Guid | | | | `Code` | Code | Text | | Holds the postal code text and is the field lead branch-assignment matches against when resolving a lead's postal code. Name also carries the code (the nearby-branch search matches Name instead), so the two must stay consistent. | | `Country` | Country | Text | | Values: India. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `LastModifiedById` | LastModifiedBy | Guid | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | Carries the postal code text, duplicated with Code: the nearby-branch search LIKE-matches this field while lead branch-assignment matches Code. Filter on either, but keep both populated identically. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Region` | Region | Text | | | | `State` | State | PickList | | Values: Maharashtra, Punjab. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [BranchPostalCode](/docs/reference/entities/branch-postal-code/) — referenced by via `PostalCodeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Posting Definition — entity reference URL: https://xmatix.com/docs/reference/entities/posting-definition/ Last reviewed: 2026-08-16 The account-determination rule that decides which GL account a document's journal lines hit, and the successor to the legacy accounting rules. Each rule names the document entity and the posting role within it, points at a GL account, and can be narrowed by company, branch, item or party; when several rules match, the most specific wins and Priority only breaks ties among equally specific rules. It is consulted first during document posting, ahead of the tax-subtype resolution and the plain chart-of-accounts lookup by account type. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | Intended to scope a rule to a group of parties. The current account-determination logic does not read it, so a rule scoped solely by account group behaves as an unscoped rule and can win over rules the author expected to be more specific. | | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | Scopes the rule to one customer party and is the weakest specificity signal. It is matched against the document's party, so a rule naming a different party is excluded from consideration for that document. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Scopes the rule to one branch and is the second-strongest specificity signal. Blank means the rule applies to any branch; a non-matching branch disqualifies the rule completely. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EntityName` | Entity Name | Text | Yes | The document entity the rule applies to, held as plain text — Invoice, Bill, Payment, CreditNote and so on — and matched case-insensitively against the posting document. A rule whose entity name is blank is never considered. | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | Yes | The account the rule resolves to. | | `Granularity` | Granularity | Text | | Intended to choose between one summarised journal line per resolved account and a journal line per document line. The current document-posting engine does not read this field — it always summarises, grouping line and tax amounts by resolved account, dimensions and party — so setting it has no effect on how a document posts. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | Rules are loaded for matching only when this is explicitly true — a rule left unset is treated as inactive and never participates in account determination. This makes it an opt-in switch rather than a soft delete. | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | Intended to scope a rule to a group of items rather than a single item. The current account-determination logic does not read it — matching considers company, branch, item and party only — so a rule scoped solely by item group behaves as an unscoped rule. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | Scopes the rule to one item, ranking below company and branch but above party in specificity. A rule naming a different item than the line being posted is excluded, not just demoted. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | Yes | Scopes the rule to one company and is the strongest specificity signal in matching. Leaving it blank makes the rule apply to every company; setting it to a different company than the document's excludes the rule outright rather than merely ranking it lower. | | `PostingRole` | Posting Role | Text | | Which leg of the document the rule resolves — the header or control side, the line side, the tax side, cost of goods sold, inventory, rounding or discount. A rule with no role set is treated as a header rule, and a rule only competes against others for the same role. | | `Priority` | Priority | Number | | Only breaks ties between rules of equal specificity, with the lower number winning; rules with no priority sort last. Specificity always dominates, so a priority value cannot make a general rule beat a narrower one. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | The supplier-side counterpart of the customer party scope, matched against the same party value on the posting document and carrying the same specificity weight. Setting either party field to a non-matching account disqualifies the rule. | | `TaxType` | Tax Type | Text | | Narrows a tax-role rule to one tax component and is matched strictly: a rule with a tax type only ever matches a leg carrying that same tax type, and a rule with a blank tax type only ever matches a leg with no tax type at all. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | Branch For Partner Account | | Customer Account | `AccountId` | | | PartnerAccount | `PartnerAccountId` | | | SupplierAccount | `SupplierAccountId` | | ## Related entities - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Posting Error Log — entity reference URL: https://xmatix.com/docs/reference/entities/posting-error-log/ Last reviewed: 2026-08-16 The failed-posting queue: one open entry per source document and posting purpose whose general-ledger posting threw, so the failure is visible and retryable instead of being lost when the posting transaction rolls back. Repeated failures for the same document and purpose reuse the open entry, bumping the attempt count and refreshing the message rather than creating duplicates; a successful re-post marks the entry Resolved and an operator can Abandon one that is superseded. The period-close workbench counts entries still Pending for the company as a close check, so an unresolved queue blocks or flags a period close. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AttemptCount` | Attempt Count | Number | | How many times posting has been attempted and failed for this document and purpose, starting at one and incremented each time the same open entry is re-recorded. Retry drivers can use it as a cap so a hopeless document stops being retried. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DocumentNumber` | Document Number | Text | | | | `ErrorMessage` | Error Message | Text | | The failure text from the posting attempt, truncated to fit, and overwritten on each repeat attempt so it always shows the most recent reason rather than the original one. Typical causes are an unresolvable account, an inactive account, a missing control account, a missing party on a control line, or no Open fiscal period for the document date. | | `FirstFailedUtc` | First Failed Utc | DateAndTime | | When the entry was first opened, in UTC, and left untouched by later attempts — it is how long a document has been failing. The pending queue is ordered oldest-first by this value. | | `Id` | Id | Guid | Yes | | | `LastAttemptUtc` | Last Attempt Utc | DateAndTime | | Refreshed in UTC on every repeat failure and also when the entry is resolved or abandoned, so it is the time of the last activity on the entry rather than strictly of the last posting attempt. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company whose ledger the failed posting belonged to. Both the pending-queue listing and the period-close check filter on it, so an entry recorded without a company is invisible to both. | | `Purpose` | Purpose | Text | | The document posting purpose the failure happened on — the same vocabulary the journal carries, so a document that posts several journals can have separate failures for each. Together with the source entity and record it forms the identity of the open queue entry. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResolutionNote` | Resolution Note | Text | | Free text recorded when the entry leaves the Pending state, defaulting to a standard note when a retry posts successfully and holding the operator's reason when the entry is abandoned. | | `SourceEntityName` | Source Entity Name | Text | | The entity of the document whose posting failed, held as plain text with no foreign key because any entity can post. It is part of the identity used to find and reuse the open entry rather than duplicating it. | | `SourceRecordId` | Source Record | Guid | | | | `Status` | Status | Text | | One of Pending, Resolved or Abandoned. Pending is the live queue: a repeat failure for the same document and purpose reuses the Pending entry instead of adding a row, a successful re-post flips it to Resolved, and Abandoned is the manual give-up for an entry that has been superseded. Only Pending entries count towards the period-close check. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditRow` | Edit | Edit | EditRow | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Price List Rule — entity reference URL: https://xmatix.com/docs/reference/entities/price-list-rule/ Last reviewed: 2026-08-16 One dated price for one item on one price list, optionally narrowed to a specific SKU and/or item lot type. PriceListRuleService matches on the exact item, the resolved price list, a SKU and lot type that are either equal to the line's or left blank, and an effective-date window around the pricing date (the line's PriceAsOnDate, else the document's, else the document date, else today); candidates are ordered by DateEffectiveFrom descending then by SKU and lot type, so the newest rule wins and a rule naming the exact SKU or lot type outranks a blank one carrying the same start date. The matched amounts land on the line as UnitPrice/UnitPrice2 for sales-side lines and UnitCost/UnitCost2 for bill, adjustment, purchase-order and bill-return lines. The price is a default rather than an override: bundle-priced lines are skipped entirely, and on a freshly inserted line a non-zero amount the user already typed is preserved. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DateEffectiveFrom` | Date Effective From | Date | Yes | Start of the rule's validity and the strongest tie-break: among the rules valid on the pricing date the one with the latest start wins. The pricing date is the line's PriceAsOnDate, else the document's, else the document date, else today. | | `DateEffectiveTill` | Date Effective Till | Date | | End of validity. Leaving it empty makes the rule open-ended rather than expired, which is the usual reason an old rule keeps pricing lines. | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | Yes | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | Optional narrowing to one item lot type; empty matches all of them. Like SKU it acts as a tie-break, so a lot-type-specific rule outranks a blank rule with the same start date. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Price` | Price | Currency | | The unit amount copied onto the matched document line: UnitPrice on sales-side lines and UnitCost on bill, adjustment, purchase-order, bill-return, requisition and auto-purchase-order lines. It behaves as a default — bundle-priced lines are skipped, and on a newly inserted line a non-zero amount already entered is left untouched. | | `Price2` | Price2 | Currency | | A secondary unit amount copied alongside the primary one into UnitPrice2 or UnitCost2. | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | Yes | Required. The rule is only considered once a list has been settled for the line — the line's own price list, else the parent document's, else any list flagged as the default. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | Leaving it empty makes the rule apply to every SKU of the item. When a SKU-specific rule and a blank one share the same start date, the SKU-specific one is preferred. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit In Page | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | NewInline | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Date Rule Validation | `DateEffectiveTill`, Error | Date Effective Till can not be Older than Date Effective From | Ensures effective-till date is not earlier than effective-from date | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Sku For Item | `SKUId` | Sku For Item | ## Related entities - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `PriceListRuleId` - [AutoPurchaseOrderLine](/docs/reference/entities/auto-purchase-order-line/) — referenced by via `PriceListRuleId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `PriceListRuleId` - [RequisitionLine](/docs/reference/entities/requisition-line/) — referenced by via `PriceListRuleId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `PriceListRuleId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `PriceListRuleId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `PriceListRuleId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `PriceListRuleId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `PriceListRuleId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `PriceListRuleId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `PriceListRuleId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `PriceListRuleId` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `PriceListRuleId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Price List — entity reference URL: https://xmatix.com/docs/reference/entities/price-list/ Last reviewed: 2026-08-16 A named collection of item prices whose actual amounts live in child PriceListRule rows. Two separate resolutions use it: PriceListService fills in a document header's price list when it is empty, keeping only active lists of the requested type whose partner account, branch, partner account group and (sale side only) customer account group fit the document, ordering them by SequenceNumber, then branch, partner account, partner account group, customer account group, IsDefault and finally oldest created, and taking the first match. PriceListRuleService then prices each line from the line's own price list, else the parent document's, else any list flagged as the default. Account-group membership is read from AccountGroupMember rows whose account group is of type Price. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Confines the list to documents raised in that branch; leaving it empty makes the list eligible for every branch, and a branch-specific list outranks an unscoped one during selection. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CustomerAccountGroupId` | Customer Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | Restricts the list to customers belonging to that account group, with membership resolved from active AccountGroupMember rows whose account group is of type Price. It is only evaluated when defaulting a sale-side price list; purchase-side selection ignores it entirely. | | `CustomerAccountId` | CustomerAccount | Guid | | Scope by customer account group instead. | | `ExternalId` | External | Guid | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Active | Boolean | | Only active lists are eligible for automatic price-list defaulting on a document header. It is not re-checked when a line is priced, so an inactive list already stored on a header or line still supplies its rules. | | `IsDefault` | Default | Boolean | | Marks the fallback list a line is priced from when neither the line nor its parent document names one. In default-list selection it is only a late tie-break, ranking below sequence number, branch, partner account, partner account group and customer account group. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountGroupId` | Partner Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | Restricts the list to documents whose partner account belongs to that group, again through active AccountGroupMember rows in an account group of type Price. Unlike the customer group, it is evaluated on both the sale and purchase sides. | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Confines the list to documents for that partner account; empty means the list is open to all partners, and a partner-specific list is preferred over an unscoped one. | | `PartnerGroupId` | PartnerGroup | Guid | | Populating this one changes nothing. | | `PriceListType` | Price List Type | PickList | Yes | Filters which lists are eligible when a document header's price list is defaulted: the caller's type is normalised to 'Sale Price' or 'Purchase Price' first, so a list typed 'Cost Price' — although the pick list offers it — is never auto-selected onto a document. It plays no part in choosing a price once a list is already attached. Values: Cost Price, Sale Price, Purchase Price. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SequenceNumber` | Sequence Number | Number | | The primary ranking key when several lists match a document: higher values are considered first and the first match is taken. It has no bearing on which price is chosen inside a list. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Runs the platform's generic record clone rather than opening a form: it copies every persisted column and custom field of the price list onto a new record, then deep-copies the child rows the delete cascade owns, so the copy comes with its price rules. Identity, audit, soft-delete and job columns are not copied, unique fields other than the name are blanked, and the new record is named after the source with a copy suffix unless document numbering overwrites it. The copies go through the normal save pipeline, so defaults, validation and audit all apply. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit In Pages | | `EditInList` | Edit | Edit | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `New` | New | New | NEW | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `PartnerAccountGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `CustomerAccountGroupId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `PriceListId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `PriceListId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `PriceListId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — referenced by via `PriceListId` - [Adjustment](/docs/reference/entities/adjustment/) — referenced by via `PriceListId` - [Requisition](/docs/reference/entities/requisition/) — referenced by via `PriceListId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `PriceListId` - [AutoOrder](/docs/reference/entities/auto-order/) — referenced by via `PriceListId` - [AutoPurchaseOrderLine](/docs/reference/entities/auto-purchase-order-line/) — referenced by via `PriceListId` - [Bill](/docs/reference/entities/bill/) — referenced by via `PriceListId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `PriceListId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `PriceListId` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `PriceListId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `PriceListId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `PriceListId` - [Order](/docs/reference/entities/order/) — referenced by via `PriceListId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `PriceListId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `PriceListId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `PriceListId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `PriceListId` - [RequisitionLine](/docs/reference/entities/requisition-line/) — referenced by via `PriceListId` - [Quote](/docs/reference/entities/quote/) — referenced by via `PriceListId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `PriceListId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `PriceListId` - [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) — referenced by via `PriceListId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `PriceListId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `PriceListId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Price Lot Line — entity reference URL: https://xmatix.com/docs/reference/entities/price-lot-line/ Last reviewed: 2026-08-16 The allocation child of PriceLot, pairing an invoice line with a price lot and a cost price. FIFO and weighted-average consumption in the shipped product runs off InventoryCostLot and the inventory value layers instead. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CostPrice` | Cost Price | Currency | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `InvoiceLineId` | Invoice Line | Lookup → [InvoiceLine](/docs/reference/entities/invoice-line/) | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `Label` | Label | Text | | | | `Name` | Name | Text | | | | `PriceLotId` | Price Lot | Lookup → [PriceLot](/docs/reference/entities/price-lot/) | Yes | | | `Quantity` | Quantity | Decimal | Yes | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Price Lot — entity reference URL: https://xmatix.com/docs/reference/entities/price-lot/ Last reviewed: 2026-08-16 The cost layer the platform actually uses for receipt costing, valuation and COGS is InventoryCostLot in the Finance module, not this entity. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | | | `ExternalId` | External | ExternalId | | | | `GoodsReceiptLineId` | Goods Receipt Line | Lookup → [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) | | | | `Id` | Id | Guid | Yes | | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | | | `IsClosed` | Is Closed | Boolean | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `Label` | Label | Text | | | | `Name` | Name | Text | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Quantity` | Quantity | Decimal | Yes | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `SoldQuantity` | Sold Quantity | Decimal | Yes | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `UnitPrice` | Unit Price | Currency | Yes | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Product Catalogue Image — entity reference URL: https://xmatix.com/docs/reference/entities/product-catalogue-image/ Last reviewed: 2026-08-16 An image asset for a catalogue listing: links a StoreCategoryItem (storeCategoryItemId) and/or the underlying Item, with imageType, imageUrl and orderIndexNumber controlling ordering. Also the anchor that ProductConfiguratorImageDetail rows attach to for configurator imagery. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrencyIsoCode` | Currency ISO Code | Text | | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid, hidden | Yes | | | `ImageType` | Image Type | Text | | | | `ImageUrl` | Image URL | Text | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `Name` | Name | Text | Yes | | | `OrderIndexNumber` | Order Index Number | LargeNumber | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `StoreCategoryItemId` | Store Category Item | Lookup → [StoreCategoryItem](/docs/reference/entities/store-category-item/) | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [StoreCategoryItem](/docs/reference/entities/store-category-item/) — looks up via `StoreCategoryItemId` - [ProductConfiguratorImageDetail](/docs/reference/entities/product-configurator-image-detail/) — referenced by via `ProductCatalogueImageId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Product Catalogue — entity reference URL: https://xmatix.com/docs/reference/entities/product-catalogue/ Last reviewed: 2026-08-16 Groups store categories and items available for a store or partner: belongs to a Store (storeId) or a partner Account (partnerAccountId) and is referenced by StoreCategory rows via catalogueId. Beyond grouping, it is the storefront's filter configuration: price and discount range filters (minPrice/maxPrice/priceSpan with priceFilterApplicable, discountMin/MaxPercentage/discountSpan with discountFilterApplicable) and attribute filter toggles (fuel, transmission, productCC, productColor, makeFilter, productFilter, showProductFeature). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrencyIsoCode` | Currency ISO Code | Text | | | | `DiscountFilterApplicable` | Discount Filter Applicable | Boolean | | | | `DiscountMaxPercentage` | Discount Max Percentage | Decimal | | | | `DiscountMinPercentage` | Discount Min Percentage | Decimal | | | | `DiscountSpan` | Discount Span | Decimal | | | | `ExternalId` | External | Text | | | | `Fuel` | Fuel | Boolean | | | | `Id` | Id | Guid, hidden | Yes | | | `Label` | Label | Text | | | | `MakeFilter` | Make Filter | Boolean | | | | `MaxPrice` | Max Price | Decimal | | | | `MinPrice` | Min Price | Decimal | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PriceFilterApplicable` | Price Filter Applicable | Boolean | | | | `PriceSpan` | Price Span | Decimal | | | | `ProductCC` | Product CC | Boolean | | | | `ProductColor` | Product Color | Boolean | | | | `ProductFilter` | Product Filter | Boolean | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ShowProductFeature` | Show Product Feature | Boolean | | | | `StoreId` | Store | Lookup → [Store](/docs/reference/entities/store/) | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `Transmission` | Transmission | Boolean | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Partner Account Filter | `PartnerAccountId` | Partner Account Filter | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Store](/docs/reference/entities/store/) — looks up via `StoreId` - [StoreCategory](/docs/reference/entities/store-category/) — referenced by via `CatalogueId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Product Configurator Image Detail — entity reference URL: https://xmatix.com/docs/reference/entities/product-configurator-image-detail/ Last reviewed: 2026-08-16 Associates a catalogue image with a specific item so a configurator view can show the right picture for a chosen configuration, with an optional currency code and integration id. It is reference data only: no server-side service, handler or engine reads these rows, and the entity exposes only new/edit/delete actions. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrencyIsoCode` | Currency ISO Code | Text | | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid, hidden | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `ProductCatalogImageId` | Product Catalog Image | Lookup → [ProductCatalogueImage](/docs/reference/entities/product-catalogue-image/) | | The catalogue image this row attaches to the item; this is the reference backed by a real column on the domain type. | | `ProductCatalogueImageId` | Product Catalogue Image | Lookup → [ProductCatalogueImage](/docs/reference/entities/product-catalogue-image/) | | A duplicate of the catalogue-image reference that exists in metadata only - the domain type has no such property and no code path reads it. Use the product catalog image reference instead. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `EditInList` | Edit | EditInline | Edit | | `New` | New | New | New | ## Related entities - [ProductCatalogueImage](/docs/reference/entities/product-catalogue-image/) — looks up via `ProductCatalogueImageId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Appointment — entity reference URL: https://xmatix.com/docs/reference/entities/product-demo/ Last reviewed: 2026-08-16 The execution record of a product demo / test drive: process and outcome fields (demoStatus, demoRating, customerVoice, usage readings, cancellation reason) around a demo of an item (itemId) or demo asset (demoAssetId) for an account. Despite its display label, this is NOT the global scheduling record - scheduling lives on the separate Appointment entity, which this row points at via appointmentId. Creating or rescheduling a demo reserves branch time slots (branchTimeSlotId / branchTimeSlotBookingId are reserved and released by the handler as slot, date, confirmation or cancellation change) and auto-assigns the owning resource. Links onward to the opportunity, order, service order and delivery order it produced or served, and field visits can reference it via Visit.productDemoId. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BranchTimeSlotBookingId` | Demo Slot | Lookup → [BranchTimeSlotBooking](/docs/reference/entities/branch-time-slot-booking/) | | The booking row created when the demo reserved its branch time slot - system-maintained by the reserve/release cascade, not user-edited. | | `BranchTimeSlotId` | Demo Slot | Lookup → [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) | | Legacy branch time-slot capacity claim: the handler reserves the slot on insert and releases/re-reserves when the slot, date, confirmation or cancellation fields change, and releases it on delete. | | `CancellationReason` | Cancellation Reason | PickList | | Values: Not Interested, Postponed, Lapsed. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CustomerVoice` | Customer Voice | LongMultiLineText | | | | `DeliveryOrderId` | Delivery Order | Lookup → [DeliveryOrder](/docs/reference/entities/delivery-order/) | | | | `DemoAddress` | Demo Address | LongMultiLineText | | | | `DemoAssetId` | Demo Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `DemoAssetNumber` | Demo Asset Number | LongMultiLineText | | | | `DemoDate` | Demo Date | Date | | | | `DemoDateTime` | Demo Date Time | Date | | | | `DemoRating` | Demo Rating | PickList | | Values: 1, 4, 5. | | `DemoStatus` | Demo Status | PickList | | | | `DemoTime` | Demo Time | DateAndTime | | | | `Id` | Id | Guid | Yes | | | `IsCancelled` | Cancelled | Boolean | | | | `IsConfirmed` | Confirmed | Boolean | | | | `IsDemoOnsite` | Demo Onsite | Boolean | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `KYCDocumentNumber` | KYC Document Number | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OpportunityId` | Opportunity | Lookup → [Opportunity](/docs/reference/entities/opportunity/) | | | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `ServiceJobType` | Service Job Type | PickList | | | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | | | `ServiceRequestId` | ServiceRequest | Guid | | | | `ServiceType` | Service Type | PickList | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UsageReadingEnd` | Usage Reading End | Number | | | | `UsageReadingStart` | Usage Reading Start | Number | | | | `UserId` | Sale Executive | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | Edit | | `EditInLineEntity` | Edit | EditInline | EditInLineEntity | | `EditInLineHeader` | Edit | EditInline | EditInLineHeader | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Demo Time Not In Slot | `DemoTime`, Error | The Demo time specified is not within Demo Slot Time range | The Demo time specified is not within Demo Slot Time range | | Usage Reading Rule | `UsageReadingEnd`, Error | Usage Reading Ends should be Greater than Usage Reading Start | Usage Reading Ends should be Greater than Usage Reading Start | ## Related entities - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — looks up via `DeliveryOrderId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [BranchTimeSlotBooking](/docs/reference/entities/branch-time-slot-booking/) — looks up via `BranchTimeSlotBookingId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `UserId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Opportunity](/docs/reference/entities/opportunity/) — looks up via `OpportunityId` - [Asset](/docs/reference/entities/asset/) — looks up via `DemoAssetId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) — looks up via `BranchTimeSlotId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [Visit](/docs/reference/entities/visit/) — referenced by via `ProductDemoId` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — referenced by via `ProductDemoId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Professional Tax Slab — entity reference URL: https://xmatix.com/docs/reference/entities/professional-tax-slab/ Last reviewed: 2026-08-16 The state-wise professional-tax slab table: for a monthly gross-wage band, the flat PT amount, with a separate February amount because some states levy a different figure in that month. Unlike the other statutory masters this one IS wired into the payroll calculation: a salary-structure line whose statutory nature is PT and whose CalculationType is Slab has its amount resolved from these slabs instead of from the line's own value. Three consequences worth knowing. The slab is matched against the gross accumulated up to that point in the component sequence, not the final gross, so the PT line's Sequence changes the answer. The February amount is chosen from the payroll period's END date month. And the run loads the company's slabs without a state filter, so in a tenant that has seeded slabs for several states the bands are pooled and the highest matching FromAmount wins regardless of the employee's state. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EffectiveFrom` | Effective From | Date | | The date the state's revised schedule applies from. The slab lookup filters on company, active flag and optionally state — not on this date — so an old and a new schedule left active at the same time compete on wage band alone. | | `FebruaryPT` | February PT | Currency | | | | `FromAmount` | From Amount | Currency | | The bottom of the monthly gross-wage band, inclusive. When several bands match, the one with the highest FromAmount wins, so overlapping rows resolve to the most specific band rather than erroring. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `MonthlyPT` | Monthly PT | Currency | | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StateCode` | State Code | Text | | The state whose professional-tax schedule this band belongs to. The slab lookup can filter by state, but the payroll calculation calls it WITHOUT a state, so every active slab for the company is pooled and matched on the wage band alone. In a tenant with slabs for more than one state this makes the PT amount depend on which state's band happens to have the highest matching lower bound, not on the employee's state. Rows with a null state code always match. | | `ToAmount` | To Amount | Currency | | The top of the monthly gross-wage band, inclusive; null means open-ended. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this ProfessionalTaxSlab. | | `DeleteBulk` | Delete | Delete | DeleteBulk | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `Edit` | Edit | Edit | Edit this ProfessionalTaxSlab. | | `EditEntity` | Edit | Edit | EditEntity | | `New` | New | New | Create a ProfessionalTaxSlab. | | `View` | View | View | View this ProfessionalTaxSlab. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Project — entity reference URL: https://xmatix.com/docs/reference/entities/project/ Last reviewed: 2026-08-16 A project or job used as a cost-and-revenue dimension and as the target for recharging billable expenses to a customer. It is live and consumed: expense advances, expense claims and expense claim lines carry a ProjectId, expense reporting groups spend by the line's project falling back to the claim's project, and the expense posting service groups recharge summaries by customer account and project. Its customer, partner, branch and business-unit links are all optional, so a project can be an internal cost bucket with no customer at all. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | Ties the project to a business unit so project spend rolls up into the same organisational dimension used elsewhere in finance. Optional, and independent of the branch link on the same record. | | `Code` | Code | Text | | The short human reference for the project used in expense entry and reporting, separate from the record's Name. It is free text with no enforced uniqueness or format. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CustomerAccountId` | Customer Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer this project's costs can be recharged to; expense posting groups its billable recharge summaries by customer account and project together. It is optional, so an internal cost-only project simply leaves it empty. | | `Description` | Description | Text | | | | `EndDate` | End Date | Date | | | | `GLAccountName` | Name | Text, unique | Yes | The project's real display name is the platform Name column, which this metadata set does not expose as a field. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The owning selling organisation for the project, distinct from CustomerAccountId which is who the work is recharged to. Both point at accounts, and a project may legitimately have one without the other. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StartDate` | Start Date | Date | | | | `Status` | Status | Text | | A free-text lifecycle marker with the intended vocabulary Open, OnHold and Closed, defaulted to Open when the record is constructed. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this Project. | | `DeleteRecord` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit this Project. | | `EditInLine` | Edit | EditInline | Edit | | `EditRecord` | Edit | Edit | Edit | | `New` | New | New | Create a Project. | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `CustomerAccountId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `ProjectId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `ProjectId` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — referenced by via `ProjectId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Prospect Place — entity reference URL: https://xmatix.com/docs/reference/entities/prospect-place/ Last reviewed: 2026-08-16 An externally-sourced place (a Places-API lookup or purchased list) that a field rep can onboard as an Account from the visit agenda's nearby-to-onboard feed. Rows are keyed on (source, sourcePlaceId) and upserted by the DiscoverNearbyOutlets action or bulk ingestion at plan creation, stamped with the plan/route they were discovered for. Consumed once onboarded: status flips New to Onboarded and the created Account and proposed VisitRouteStop are linked back via onboardedAccountId / onboardedVisitRouteStopId. Only status New rows appear in the nearby feed. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Address` | Address | MultiLineText | | | | `Category` | Category | MultiLineText | | | | `Location` | Location | GeoLocation | | Place coordinates (geography point, SRID 4326). | | `OnboardedAccountId` | Onboarded Account | Lookup → [Account](/docs/reference/entities/account/) | | The Account created when this place was onboarded - the consumption link that takes the row out of the feed. | | `OnboardedVisitRouteStopId` | Onboarded Route Stop | Lookup → [VisitRouteStop](/docs/reference/entities/visit-route-stop/) | | The route stop proposed for the onboarded account (born Proposed, pending admin approval) - the second half of the onboarding trail. | | `Phone` | Phone | MultiLineText | | | | `Rating` | Rating | Number | | | | `Source` | Source | MultiLineText | | | | `SourcePlaceId` | Source Place Id | MultiLineText | | | | `Status` | Status | PickList | | New rows await onboarding and are the only ones surfaced in the nearby-to-onboard feed; onboarding flips the row to Onboarded and links the created account and proposed route stop. Refreshing place facts on a later discovery never resets the status. Values: New, Onboarded, Dismissed. | | `VisitPlanId` | Visit Plan | Lookup → [VisitPlan](/docs/reference/entities/visit-plan/) | | | | `VisitRouteId` | Visit Route | Lookup → [VisitRoute](/docs/reference/entities/visit-route/) | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRow` | Edit | Edit | EditRow | | `NewHeader` | New | New | New | ## Related entities - [VisitRouteStop](/docs/reference/entities/visit-route-stop/) — looks up via `OnboardedVisitRouteStopId` - [VisitRoute](/docs/reference/entities/visit-route/) — looks up via `VisitRouteId` - [Account](/docs/reference/entities/account/) — looks up via `OnboardedAccountId` - [VisitPlan](/docs/reference/entities/visit-plan/) — looks up via `VisitPlanId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Published Statement — entity reference URL: https://xmatix.com/docs/reference/entities/published-statement/ Last reviewed: 2026-08-16 An immutable filed snapshot of a computed financial statement, the artifact that survives any later reclassification of the chart of accounts. Publishing recomputes the statement from the ledger once, freezes the result as JSON with a content hash, and stamps the publish time; after that the row cannot be edited or deleted, only superseded. It records the exact dimension scope it was generated for, so a later re-run is comparable rather than merely similar. Some statutory packs depend on it: an AOC-4 filing and a DPT-3 return both require this year's balance sheet to already be published. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AsOfPeriodId` | As Of Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | | The cut-off period the snapshot was computed to. Publishing resolves it to a period number before computing, and leaving it empty publishes the whole fiscal year rather than failing. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | One axis of the dimension scope the snapshot was computed under. Empty means the statement was simply not narrowed to a branch, not that the company has none. | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | Narrows the snapshot to exactly one business unit. It contrasts with the consolidation group on the same record, which expands to many units instead of pinning one. | | `ConsolidationGroupId` | Consolation Group | Lookup → [ConsolidationGroup](/docs/reference/entities/consolidation-group/) | | When set, the statement was computed across the group's member business units rather than for a single unit. This is what distinguishes a consolidated filing from a single-unit one at the same company and year. | | `ContentHash` | Content Hash | Text | | A SHA-256 hex digest of the frozen statement JSON, computed at publish time, so later tampering with the stored snapshot can be detected without re-running the ledger. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FiscalYearId` | Fiscal Year | Lookup → [FiscalYear](/docs/reference/entities/fiscal-year/) | | The accounting year the snapshot covers. It is required to publish, alongside the company, and both are validated before any computation is attempted. | | `GSTRegistrationId` | GST Registration | Lookup → [GSTRegistration](/docs/reference/entities/gstregistration/) | | Scopes the snapshot to a single tax registration, for companies that report per registration rather than only at company level. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PublishedById` | Published By | Guid | | | | `PublishedDateTime` | Published Date Time | Date | | Stamped in UTC by the publish action at the moment the statement was frozen. It is never typed in, so a draft always has it empty. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StatementJson` | Statement Json | Text | | The frozen computed statement, serialized once at publish time and never recalculated on read, which is what lets the record survive a later reclassification of the chart of accounts. The auditor-appointment notice type is the exception: while still a draft this same field holds the filer's typed answers rather than a computed result, and publishing replaces them with the computed notice that echoes those answers back. | | `StatementTypeName` | Statement Type Name | Text | | Which statement was frozen, restricted to the types the publisher can actually compute: balance sheet, profit and loss, trial balance, risk report, the AOC-4 filing pack, the DPT-3 return and the ADT-1 auditor-appointment notice. Anything else is refused deliberately, because an unrecognized value once fell through and filed a trial balance under the wrong name as an undeletable artifact. | | `Status` | Status | Text | | One of Draft, Published or Superseded. Publishing is a one-way door enforced on save: a published row may only move to Superseded, cannot otherwise be edited, and cannot be deleted at all. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `PublishStatement` | Publish | ServerAction (`PublishStatement`) | Recomputes the statement named on the record once, freezes the result as JSON with a SHA-256 hash, marks the row published and stamps the publish time, after which the row is immutable and cannot be deleted. Company and fiscal year must both be set or it refuses, and an unsupported statement type is rejected outright rather than quietly filed as a trial balance. Some types carry their own precondition: the AOC-4 pack and the DPT-3 return both require this year's balance sheet to already be published. | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ConsolidationGroup](/docs/reference/entities/consolidation-group/) — looks up via `ConsolidationGroupId` - [GSTRegistration](/docs/reference/entities/gstregistration/) — looks up via `GSTRegistrationId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `AsOfPeriodId` - [FiscalYear](/docs/reference/entities/fiscal-year/) — looks up via `FiscalYearId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Purchase Order Line — entity reference URL: https://xmatix.com/docs/reference/entities/purchase-order-line/ Last reviewed: 2026-08-16 One item position on a purchase order: PurchaseOrderId plus ItemId, SKUId and Quantity, carrying the resolved buy price (UnitCost, with UnitCost2 overriding it in the amount formula), the discount ladder, a per-line snapshot of up to six taxes in the Tax1..Tax6 name/rate/type/amount slots, and the counters that drive the chain. Three independent pending counters track three different downstream stages against the same ordered quantity: PendingQuantity is what is still to be received, PendingInvoiceQuantity what is still to be billed, PendingOrderQuantity what is still to be pushed out as a dealer sale order. A line can be sourced from a requisition line (RequisitionLineId) or from an auto-order proposal line (AutoPurchaseOrderLineId), and quantity edits are blocked below whatever has already been received or returned. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Calculated (calculated) | | | | `ApplyPostTaxDiscount` | Apply Post Tax Discount | Boolean | Yes | | | `AutoPurchaseOrderLineId` | Auto Purchase Order Line | Lookup → [AutoPurchaseOrderLine](/docs/reference/entities/auto-purchase-order-line/) | | Links the line back to the AutoPurchaseOrderLine proposal it was generated from. It is also the key the planner reads back through: the proposal line's PurchaseOrderQuantity is rolled up from the quantity of the purchase-order lines pointing at it, which is what makes a partly accepted suggestion show a remaining pending quantity. | | `BaseAmount` | Base Amount | Calculated (calculated) | | | | `BenefitIndex` | Benefit Index | Number | | | | `BranchId` | Branch | Calculated (calculated) | | A denormalised text copy of the parent order's branch identifier, calculated as the parent's BranchId converted to a string so the line can be filtered and grouped without a join. It is text, not a branch lookup, so it cannot be navigated. | | `CancelledQuantity` | Cancelled Quantity | Decimal | | Quantity struck off the line without being received or billed. It is subtracted in both the pending-receipt and pending-invoice formulas and is also deducted from the ordered quantity that the over-receipt guard compares against, so cancelling reduces how much may still be received. | | `ContractDiscount` | Contract Discount | Percent | | | | `ContractDiscountAmount` | Contract Discount Amount | Currency | | | | `ConversionRatio` | Conversion Ratio | Number | | | | `ConversionRatio1` | Conversion Ratio 1 | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Discount` | Discount | Percent | | | | `Discount2` | Cash Discount | Percent | | | | `DiscountAmount` | Discount Amount | Currency | | | | `DiscountAmount2` | Cash Discount Amount | Currency | | | | `ExcludeInAutoOrder` | Exclude In Auto Order | Boolean | Yes | Opts this line out of the replenishment pipeline: the procurement pipeline queries that feed the Forecasting engine skip lines carrying it, so an excluded line's outstanding quantity is not counted as inbound supply when projecting stock. The same opt-out exists on requisition and sale-order lines. | | `ExternalId` | External | Text, unique | | | | `GrossAmount` | Gross Amount | Calculated (calculated) | | | | `Id` | Id | Guid | Yes | | | `InventoryFulfilmentOrderLineId` | Inventory Fulfillment Order Line | Lookup → [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) | | | | `InventoryStockId` | Stock | Lookup → [InventoryStock](/docs/reference/entities/inventory-stock/) | | An optional pointer to the specific stock bucket row (item, SKU, branch and storage location) this line is meant to replenish. Nothing in the procurement code writes or reads it; the actual stock effect of the order comes from the goods-receipt lines' ledger postings. | | `InvoiceQuantity` | Invoice Quantity | Number | | How much of this line has been billed, rolled up from the quantity on the linked bill lines. It drives PendingInvoiceQuantity (quantity minus billed minus cancelled), which is the gate the release-invoice actions check. | | `IsSchemeGenerated` | Is Scheme Generated | Boolean | Yes | Marks a line the promotional scheme engine created as a benefit (typically a free or discounted give-away item) rather than one a buyer keyed. Resetting the document's schemes removes these lines, so do not treat them as buyer intent. | | `ItemAliasId` | Item Alias | Lookup → [ItemAlias](/docs/reference/entities/item-alias/) | | | | `ItemAlternateId` | Item Alternate | Lookup → [ItemAlternate](/docs/reference/entities/item-alternate/) | | | | `ItemComponentId` | Item Component | Lookup → [ItemComponent](/docs/reference/entities/item-component/) | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ItemName` | ItemName | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `NetDiscount` | Net Discount | Calculated (calculated) | | | | `NetSchemeDiscount` | Net Scheme Discount | Calculated (calculated) | | | | `OrderQuantity` | Order Quantity | Number | | How much of this line has been pushed out as a dealer sale order, rolled up from the sale order lines that point back at it. It drives PendingOrderQuantity and is unrelated to receiving or billing; do not read it as the ordered quantity, which is Quantity. | | `OriginalItemId` | Original Item | Lookup → [Item](/docs/reference/entities/item/) | | The item originally requested, kept when the line was later substituted (through an alternate or alias item) so the substitution stays visible. ItemId is what is actually being bought and what everything downstream receives and bills. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PackagePurchaseOrderLineId` | Purchase Order Line | Lookup → [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) | | Self-reference from a component line to the package (kit) line it was expanded under, written by the apply-package-configuration action. Component lines are ordinary purchase lines and are received and billed in their own right, so summing a package line and its components double-counts. | | `PartnerAccountId` | Partner Account | Calculated | | Declared on the line as text rather than as a lookup to Account, unlike the header field of the same name, so it holds a stringified identifier at best and has no referential integrity. Resolve the counterparty from the parent order's PartnerAccountId instead. | | `PendingInvoiceQuantity` | Pending Invoice Quantity | Calculated (calculated) | | | | `PendingOrderQuantity` | Pending Order Quantity | Calculated (calculated) | | | | `PendingQuantity` | Pending Quantity | Calculated (calculated) | | | | `PriceAsOnDate` | Price As On Date | Date | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `PriceListRuleId` | Price List Rule | Lookup → [PriceListRule](/docs/reference/entities/price-list-rule/) | | | | `PurchaseOrderId` | Purchase Order | Lookup → [PurchaseOrder](/docs/reference/entities/purchase-order/) | | | | `PurchaseOrderLineNumber` | PurchaseOrderLineNumber | Number | | | | `PurchaseRequisitionId` | Purchase Requisition | Lookup → [Requisition](/docs/reference/entities/requisition/) | | | | `Quantity` | Quantity | Number | Yes | | | `ReceiptQuantity` | Receipt Quantity | Number | | How much of this line has been drawn into goods receipts, and the counter that closes the line down: PendingQuantity is quantity minus this minus cancelled quantity. It is rolled up from the linked goods-receipt lines' OrderedQuantity - the quantity released to the receipt - not from what was physically counted in, so a receipt that was released but not yet received still reduces the pending quantity. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedQuantity` | Requested Quantity | Number | | | | `RequisitionLineId` | Requisition Line | Lookup → [RequisitionLine](/docs/reference/entities/requisition-line/) | | | | `ReturnedQuantity` | Returned Quantity | Number | | Quantity returned to the supplier against this line, rolled up from credit-note lines whose parent credit note is a bill return. Together with ReceiptQuantity it forms the transacted quantity that the line's ordered quantity may not be reduced below. | | `SchemeBenefitId` | Scheme Benefit | Lookup → SchemeBenfit | | | | `SchemeDiscount` | Scheme Discount | Percent | | | | `SchemeDiscount1` | Scheme Discount | Percent | | | | `SchemeDiscountAmount` | Scheme Discount Amount | Currency | | | | `SchemeLineId` | Scheme Line | Lookup → [SchemeLine](/docs/reference/entities/scheme-line/) | | | | `SchemeRewardPoints` | Scheme Reward Points | Number | | | | `ServiceOrderLineId` | Service Order Line | Lookup → [ServiceOrderLine](/docs/reference/entities/service-order-line/) | | | | `SkipScheme` | Skip Scheme | Boolean | Yes | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `Tax1` | Tax 1 | Currency | | | | `Tax1Name` | Tax Name 1 | Text | | | | `Tax1Rate` | Tax Rate 1 | Currency | | | | `Tax1Type` | Tax Type 1 | Text | | | | `Tax2` | Tax 2 | Currency | | | | `Tax2Name` | Tax Name 2 | Text | | | | `Tax2Rate` | Tax Rate 2 | Currency | | | | `Tax2Type` | Tax Type 2 | Text | | | | `Tax3` | Tax 3 | Currency | | | | `Tax3Name` | Tax Name 3 | Text | | | | `Tax3Rate` | Tax Rate 3 | Currency | | | | `Tax3Type` | Tax Type 3 | Text | | | | `Tax4` | Tax 4 | Currency | | | | `Tax4Name` | Tax Name 4 | Text | | | | `Tax4Rate` | Tax Rate 4 | Currency | | | | `Tax4Type` | Tax Type 4 | Text | | | | `Tax5` | Tax 5 | Currency | | | | `Tax5Name` | Tax Name 5 | Text | | | | `Tax5Rate` | Tax Rate 5 | Currency | | | | `Tax5Type` | Tax Type 5 | Text | | | | `Tax6` | Tax 6 | Currency | | | | `Tax6Name` | Tax Name 6 | Text | | | | `Tax6Rate` | Tax Rate 6 | Currency | | | | `Tax6Type` | Tax Type 6 | Text | | | | `TaxAmount` | Tax Amount | Currency | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | | | `UnitCost2` | Unit Cost 2 | Currency | | | | `UOM` | UOM | PickList | | | | `UOM1` | UOM 1 | PickList | | Values: Each, kWh. | | `UOMQuantity` | UOM Quantity | Number | | | | `UOMQuantity1` | UOM Quantity1 | Number | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit | | `HeaderEdit` | HeaderEdit | EditInline | Edit | | `Import` | Import | UIAction | A layout-driven bulk load of order lines from a file rather than a server action; the lines it produces go through the ordinary line save pipeline, so minimum, maximum and lot-multiple order-quantity rules and price resolution all still apply to each imported row. | | `MainNew` | New | New | New | | `New` | Quick Add | NewInline | New | | `ProductCatalogue` | Product Catalogue | UIAction | ProductCatalogue | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Item Required Validation | `ItemId`, Error | Item is Required. | Item is Required. | | Tax Group Validation | Error, inactive | Tax Group Type must be "Line Level". | Ensures tax group type is 'Line Level' for purchase order lines | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Active Item | `ItemId` | | | Sku For Item | `SKUId` | | ## Related entities - [ItemAlternate](/docs/reference/entities/item-alternate/) — looks up via `ItemAlternateId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Item](/docs/reference/entities/item/) — looks up via `OriginalItemId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [ItemComponent](/docs/reference/entities/item-component/) — looks up via `ItemComponentId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — looks up via `ServiceOrderLineId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — looks up via `PackagePurchaseOrderLineId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — looks up via `InventoryStockId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — looks up via `InventoryFulfilmentOrderLineId` - [RequisitionLine](/docs/reference/entities/requisition-line/) — looks up via `RequisitionLineId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — looks up via `SchemeBenefitId` - [ItemAlias](/docs/reference/entities/item-alias/) — looks up via `ItemAliasId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — looks up via `PurchaseOrderId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [AutoPurchaseOrderLine](/docs/reference/entities/auto-purchase-order-line/) — looks up via `AutoPurchaseOrderLineId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — looks up via `PriceListRuleId` - [SchemeLine](/docs/reference/entities/scheme-line/) — looks up via `SchemeLineId` - [Requisition](/docs/reference/entities/requisition/) — looks up via `PurchaseRequisitionId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `PurchaseOrderLineId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `PurchaseOrderLineId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `PurchaseOrderLineId` - [PurchaseOrderRequisition](/docs/reference/entities/purchase-order-requisition/) — referenced by via `PurchaseOrderLineId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `PackagePurchaseOrderLineId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `PurchaseOrderLineId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `PurchaseOrderLineId` - [Requisition](/docs/reference/entities/requisition/) — referenced by via `PurchaseOrderLineId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `PurchaseOrderLineId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `PurchaseOrderLineId` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `PurchaseOrderLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Purchase Order Requisition — entity reference URL: https://xmatix.com/docs/reference/entities/purchase-order-requisition/ Last reviewed: 2026-08-16 A junction row designed to link a requisition and requisition line to the purchase order line that fulfils it, optionally tagged with the AutoOrder that produced it and carrying RequestedQuantity and OrderedQuantity. The requisition-to-purchase-order trace that is actually maintained is the direct PurchaseOrderLine.RequisitionLineId and PurchaseOrderLine.PurchaseRequisitionId pair, so do not rely on this entity to answer which purchase order covered a requisition. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AutoOrderId` | Auto Order | Lookup → [AutoOrder](/docs/reference/entities/auto-order/) | | | | `AutoPurchaseOrder` | Auto Purchase Order | Lookup | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `OrderedQuantity` | Ordered Quantity | Number | | Intended to record how much was actually ordered against the linked requisition line. It is a stored integer on an entity that no code writes; the quantity genuinely tracked for that purpose is RequisitionLine.PurchaseOrderQuantity. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PurchaseOrderId` | Purchase Order | Lookup → [PurchaseOrder](/docs/reference/entities/purchase-order/) | | | | `PurchaseOrderLineId` | Purchase Order Line | Lookup → [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) | | | | `PurchaseRequisitionId` | Purchase Requisition | Lookup → [Requisition](/docs/reference/entities/requisition/) | | | | `PurchaseRequisitionLineId` | Purchase Requisition Line | Lookup → [RequisitionLine](/docs/reference/entities/requisition-line/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedQuantity` | Requested Quantity | Number | | Intended to record how much of the requisition line the linked purchase order line was asked to cover. It is a stored integer on an entity that no code writes, so the platform never populates it. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Bulk Delete | Delete | Bulk Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — looks up via `PurchaseOrderId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [RequisitionLine](/docs/reference/entities/requisition-line/) — looks up via `PurchaseRequisitionLineId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — looks up via `PurchaseOrderLineId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Requisition](/docs/reference/entities/requisition/) — looks up via `PurchaseRequisitionId` - [AutoOrder](/docs/reference/entities/auto-order/) — looks up via `AutoOrderId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Purchase Order — entity reference URL: https://xmatix.com/docs/reference/entities/purchase-order/ Last reviewed: 2026-10-10 A purchase order is the commitment to a supplier: the items, quantities and prices bought for a branch, and the document every later shipment, goods receipt and bill links back to line by line. It appears in the Procurement app. It is created directly, released from a requisition, filled from requisitions with Add Requisition, or generated from an auto order. It is numbered from document numbering (shipped series PO, separator -, date DDMMYYYY, six digits). Partner Account, Branch and Document Date are locked once saved with a value. Receiving, billing and dealer-order release are tracked independently by per-line counters; Release Receipt, Release Shipment, Release Invoice and Dealer Order each draw only on the matching pending quantity, and every one has a selective variant. Status starts at Draft; Release Shipment sets it to Shipment and two shipped business rules set Goods Receipt and Bill when the order is saved. There is no cancel action: undelivered quantity is entered as Cancelled Quantity on the line. Step-by-step procedures are on the Purchase orders page of the Procurement documentation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountName` | Account Name | Text | | A denormalised copy of the counterparty account name kept on the document for display and export. It is a snapshot, so it can drift from the current name on the linked Account; resolve through PartnerAccountId when accuracy matters. | | `AdjustedAdvanceAmount` | Adjusted Advance Amount | Currency | | | | `AdvanceAmount` | Advance Amount | Currency | | An advance paid to the supplier against this order, intended to net against the order value alongside AdjustedAdvanceAmount and OpenAdvanceAmount. | | `BillingCity` | Billing City | PickList | | Values: Mumbai, Pune, Chandigarh, Delhi. | | `BillingCityPlaceId` | Billing City | Lookup → [Place](/docs/reference/entities/place/) | | Values: Pune, Chandigarh, Mumbai. | | `BillingContactAddressId` | Billing Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `BillingCountry` | Billing Country | PickList | | Values: India. | | `BillingPostalCode` | Billing Postal Code | Text | | | | `BillingRegion` | Billing Region | Text | | | | `BillingState` | Billing State | PickList | | Values: Maharashtra, Punjab, New Delhi, Haryana. | | `BillingStreet` | Billing Street | Text | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The receiving branch. Must be active and belong to the partner account; required when the partner account has branches. Locked once saved with a value. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DiscountGroupId` | Discount Group | Lookup → [DiscountGroup](/docs/reference/entities/discount-group/) | | The discount group line discounts come from. A purchase-type discount group is chosen automatically on creation. | | `DocumentDate` | Document Date | Date | | The order's business date. Set to today when left empty, and used to pick the fiscal day the order belongs to. Locked once saved. | | `DocumentNumber` | Document Number | Number | | | | `ExecutiveResourceId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | Labelled Executive: the internal person accountable for the order. | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `InventoryFulfilmentId` | Fulfilment | Lookup → [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) | | | | `IsInvoiceReleased` | Invoice Released | Calculated (calculated) | Yes | Legacy flag; not maintained by the release actions. Read the line counters instead. | | `IsKPICalculated` | KPI Calculated | Boolean | Yes | | | `IsOrderReceived` | Order Received | Boolean | Yes | Legacy flag with no effect. | | `IsOrderReleased` | Order Released | Boolean | Yes | Legacy flag with no effect. | | `IsReceiptReleased` | Receipt Released | Calculated (calculated) | Yes | Legacy flag; not maintained by the release actions. Read the line counters instead. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | The purchase order's document number, generated on save from the Purchase Order Name Setting. The shipped format is PO, a hyphen, the document date as DDMMYYYY, a hyphen and a six-digit counter. | | `OpenAdvanceAmount` | Open Advance Amount | Currency | | | | `OpenAmount` | Open Amount | Currency | | Intended as the order value still outstanding after advances (the domain type still carries the commented-out total-minus-advance expression). | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Your organization placing the order. Only active partner accounts can be picked. Locked once saved with a value. | | `PendingOrderQuantity` | Pending Order Quantity | Calculated (calculated) | | | | `PerformKPICalculation` | Perform KPI Calculation | Boolean | Yes | | | `PerformReceive` | Perform Receive | Boolean | Yes | A trigger boolean with no listener on this entity: receiving is performed on the goods receipt, through GoodsReceipt.PerformReceive, not from the purchase order. Nothing reads or clears it here. | | `PerformReleaseInvoice` | Perform Release Invoice | Boolean | Yes | A legacy trigger boolean superseded by the PerformReleaseInvoice server action. | | `PerformReleaseOrder` | Perform Release Order | Boolean | Yes | A trigger boolean with no listener. Releasing a dealer sale order from this purchase order is done by the create-dealer-order server actions, which require SupplierBranchId and read PendingOrderQuantity; this flag plays no part in that. | | `PerformReleaseReceipt` | Perform Release Receipt | Boolean | Yes | A legacy trigger boolean from the era when saving a flag ran a process. | | `PlaceOfSupply` | Place of Supply | PickList | | For tax: defaulted from the supplier's place of supply for businesses in India. Values: Haryana, Rajasthan, Gujarat, Maharashtra. | | `PriceAsOnDate` | Price As On Date | Date | | The date prices are taken from. Changing it reprices every line from the price list in force on that date. | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | The purchase price list lines are priced from. A purchase-type price list is chosen automatically on creation. | | `PurchaseAutoOrderId` | Auto Purchase Order | Lookup → [AutoOrder](/docs/reference/entities/auto-order/) | | Labelled Auto Purchase Order: the auto-order worksheet the order was generated from. Filled automatically. | | `PurchaseOrderShipmentId` | Purchase Order Shipment | Lookup → [Shipment](/docs/reference/entities/shipment/) | | | | `PurchaseOrderType` | Purchase Order Type | PickList | | A classification of the order: Part, Product, Local PO, VOR PO, Subcontracted PO or Blanket PO. The shipped list views filter on it; otherwise it is used for reporting. Values: Part PO, Product PO, Local PO, VOR PO. | | `PurchaseRequisitionId` | Requisition | Lookup → [Requisition](/docs/reference/entities/requisition/) | | The requisition the order was released from. Filled automatically. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `RepairOrderId` | RepairOrder | Guid | | | | `RoundOff` | Round Off | Currency | | A rounding adjustment on the order total. It is not part of any header roll-up formula - TotalAmount is line amount plus tax only - and no code path computes it, so it neither derives from nor feeds the totals. | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | The service order the purchase was raised for, when it came from one. | | `ShippingAddress` | Shipping Address | Text | | | | `ShippingCity` | Shipping City | PickList | | Values: Pune, Chandigarh, Mumbai, Delhi. | | `ShippingCityPlaceId` | Shipping City | Lookup → [Place](/docs/reference/entities/place/) | | Values: Mumbai, Pune, Chandigarh. | | `ShippingContactAddressId` | Shipping Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `ShippingCountry` | Shipping Country | PickList | | Values: India. | | `ShippingPostalCode` | Shipping Postal Code | Text | | | | `ShippingRegion` | Shipping Region | Text | | | | `ShippingState` | Shipping State | PickList | | Values: Maharashtra, Punjab, New Delhi, Haryana. | | `ShippingStreet` | Shipping Street | Text | | | | `SkipScheme` | Skip Scheme | Boolean | Yes | Turns off supplier-scheme evaluation for the whole order. Not on the shipped layouts. | | `SourceOfSupply` | Source of Supply | PickList | | For tax: defaulted from the branch's source of supply for businesses in India. Values: Maharashtra, Gujarat, Rajasthan, Haryana. | | `Status` | Status | PickList | | The order's stage: Draft (the default), New, Shipment, Goods Receipt or Bill. Release Shipment sets Shipment; shipped business rules set Goods Receipt when no line has pending quantity and Bill when something is billed and nothing is left to bill, when the order is saved. It can also be moved by hand with the stepper. The shipped release buttons show only while it is Draft. Values: Draft, Shipment, Goods Receipt, Bill. | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | The vendor. Only active supplier accounts can be picked. Filled from the branch's default supplier when left empty. Add Requisition only accepts requisitions for the same supplier account. | | `SupplierBranchId` | Supplier Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The supplier's branch. Required by the Dealer Order actions, which create a sale order at this branch when the supplier is another organization on the platform. Not on the shipped create form. | | `Tax1` | Tax1 | Currency | | | | `Tax1Name` | Tax Name 1 | Text | | | | `Tax1Rate` | Tax Rate 1 | Currency | | | | `Tax1Type` | Tax Type 1 | Text | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | Header-level taxes. Must be a Document Level tax group. | | `TaxId` | Tax | Lookup → [Tax](/docs/reference/entities/tax/) | | | | `TaxSupplyType` | Tax Supply Type | PickList | | The tax lane: Within State, Outside State, Exempt, Exports or SEZ. For businesses in India it is recalculated on every save from the supplier's registration type and whether the place and source of supply differ. Values: Within State, Outside State, Exempt, Exports, SEZ. | | `TCSEligibleAmount` | TCS Eligible Amount | Currency | | The base amount that tax-collected-at-source is charged on, maintained by the shared tax-group service when header taxes are resolved rather than by the purchase-order handler itself. It is the input to the header Tax1 slot, not a total in its own right. | | `TotalAmount` | Total Amount | Calculated (calculated) | | The order total shown in the Amount Summary: base amount less scheme and other discounts plus tax. | | `TotalDiscountAmount` | Total Discount Amount | Calculated (calculated) | | The total of line discounts. | | `TotalLineAmount` | Total Line Amount | Calculated (calculated) | | Sum of the line net amounts (each line's amount after its discounts). It is the base of the header TotalAmount formula, which adds TotalTaxAmount on top; it excludes tax, freight and rounding. | | `TotalLineBaseAmount` | Total Line Base Amount | Calculated (calculated) | | Quantity times unit cost over all lines, before discounts. | | `TotalLineGrossAmount` | Total Line Gross Amount | Calculated (calculated) | | Sum of the line gross amounts, meaning net plus line tax and with post-tax discounts already taken off. This is the figure the billed-inventory accrual journal reads, so it is the tax-inclusive view of the order rather than the payable base. | | `TotalLineTaxAmount` | Total Line Tax Amount | Calculated (calculated) | | | | `TotalPendingInvoiceQuantity` | Total Pending Invoice Quantity | Calculated (calculated) | | The sum of the lines' pending invoice quantity: ordered less billed less cancelled. The shipped release buttons need it to be greater than zero. | | `TotalPendingQuantity` | Total Pending Quantity | Calculated (calculated) | | The sum of the lines' pending quantity: ordered less staged on goods receipts less cancelled. | | `TotalSchemeDiscountAmount` | Total Scheme Discount Amount | Calculated (calculated) | | The total discount from applied supplier schemes. | | `TotalTaxAmount` | Total Tax Amount | Calculated (calculated) | | The total tax over all lines. | | `TotalTaxPostingAmount` | Total Tax Posting Amount | Calculated (calculated) | | | | `TransactionType` | Transaction Type | PickList | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `ApplyPackageConfiguration` | Apply Package Configuration | ServerAction (`ApplyPackageConfiguration`) | ApplyPackageConfiguration | | `ApplyScheme` | Apply Scheme | ServerAction (`ApplyScheme`) | Handled by the shared scheme engine rather than by the purchase-order handler: it applies one named scheme line to the document, optionally with a chosen benefit and a set of selected items, adding benefit lines and scheme discount to the order. | | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInList` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `GetConfigurableItems` | Get Configurable Items | ServerAction (`GetConfigurableItems`) | GetConfigurableItems | | `GetFrequentlyOrderedItems` | Get Frequently Ordered Items | ServerAction (`GetFrequentlyOrderedItems`) | Get all Items ordered within particular duration. | | `GetOpenDocuments` | Get Open Documents | ServerAction (`GetOpenDocuments`) | GetOpenDocuments | | `GetPackageConfiguration` | Get Package Configuration | ServerAction (`GetPackageConfiguration`) | GetPackageConfiguration | | `GetPaymentAmountSummary` | Get Payment AmountSummary | ServerAction (`GetPaymentAmountSummary`) | GetPaymentAmountSummary | | `GetQualifiedBenefits` | Get Qualified Benefits | ServerAction (`GetQualifiedBenefits`) | Read-only. Returns the benefits available to this document for a given set of item groups supplied in the arguments, so a buyer can choose which benefit to take before applying a scheme. It changes nothing on the order. | | `GetQualifiedSchemeSlabs` | Get Qualified Scheme Slabs | ServerAction (`GetQualifiedSchemeSlabs`) | Read-only. Returns the scheme slabs the document currently qualifies for, evaluated by the shared scheme engine against the order as it stands. Applying one is a separate step. | | `GetSchemeRecommendations` | Get Scheme Recommendations | ServerAction (`GetSchemeRecommendations`) | Read-only. Returns the schemes the document could qualify for; with no item named in the arguments it evaluates the whole document server-side, and with one named it previews that single item's line, optionally reflecting a typed quantity, unit price and the pending basket totals so every card shows the same distance to the next threshold. It applies nothing. | | `New` | New | New | New | | `PerformCreateDealerOrder` | Create Dealer Order | ServerAction (`PerformCreateDealerOrder`) | PerformCreateDealerOrder | | `PerformReleaseInvoice` | Release Invoice | ServerAction (`PerformReleaseInvoice`) | This action will create purchase invoice record for the current purchase order. | | `PerformReleaseReceipt` | Release Receipt | ServerAction (`PerformReleaseReceipt`) | This action will create good receipt record for the current purchase order. | | `PostAdjustments` | Post Adjustments | ServerAction (`PostAdjustments`) | PostAdjustments | | `ProductCatalogue` | Product Catalogue | ServerAction | Despite being typed as a server action it names no server action - it is driven entirely by its attached layout, which opens the catalogue picker for adding lines to the order. | | `ResetScheme` | Reset Scheme | ServerAction (`ResetScheme`) | Strips every applied scheme from the document through the shared scheme engine, removing the benefit lines it generated and clearing scheme discount, so the order can be re-evaluated from scratch. It is the undo for ApplyScheme and does affect stored line data. | | `SelectiveAddRequisition` | Add Requisition | ServerAction (`SelectiveAddRequisition`) | Pull every open line of the selected requisitions into this purchase order | | `SelectiveAddRequisitionLine` | Selective Requisition Lines | ServerAction (`SelectiveAddRequisitionLine`) | Pull the selected requisition lines into this purchase order at the requested quantity | | `SelectiveCreateDealerOrder` | Selective Create Dealer Order | ServerAction (`SelectiveCreateDealerOrder`) | SelectiveCreateDealerOrder | | `SelectiveReleaseInvoice` | Selective Release Invoice | ServerAction (`SelectiveReleaseInvoice`) | It is use to release selective lines. | | `SelectiveReleaseReceipt` | Selective Release Receipt | ServerAction (`SelectiveReleaseReceipt`) | It is use to release selective lines. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Tax Group Validation | Error | Tax Group Type must be "Document Level". | Ensures tax group type is 'Document Level' for purchase orders | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Only Partner Account | `PartnerAccountId` | | | Only Supplier | `SupplierAccountId` | | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `SupplierBranchId` - [Shipment](/docs/reference/entities/shipment/) — looks up via `PurchaseOrderShipmentId` - [Place](/docs/reference/entities/place/) — looks up via `BillingCityPlaceId` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [DiscountGroup](/docs/reference/entities/discount-group/) — looks up via `DiscountGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Tax](/docs/reference/entities/tax/) — looks up via `TaxId` - [Place](/docs/reference/entities/place/) — looks up via `ShippingCityPlaceId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — looks up via `InventoryFulfilmentId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [Resource](/docs/reference/entities/resource/) — looks up via `ExecutiveResourceId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `ShippingContactAddressId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `BillingContactAddressId` - [AutoOrder](/docs/reference/entities/auto-order/) — looks up via `PurchaseAutoOrderId` - [Requisition](/docs/reference/entities/requisition/) — looks up via `PurchaseRequisitionId` - [Shipment](/docs/reference/entities/shipment/) — referenced by via `PurchaseOrderId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `PurchaseOrderId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `PurchaseOrderId` - [PurchaseOrderRequisition](/docs/reference/entities/purchase-order-requisition/) — referenced by via `PurchaseOrderId` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `PurchaseOrderId` - [Requisition](/docs/reference/entities/requisition/) — referenced by via `PurchaseOrderId` - [Bill](/docs/reference/entities/bill/) — referenced by via `PurchaseOrderId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `PurchaseOrderId` - [Payment](/docs/reference/entities/payment/) — referenced by via `PurchaseOrderId` - [PaymentAdjustment](/docs/reference/entities/payment-adjustment/) — referenced by via `PurchaseOrderId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — referenced by via `PurchaseOrderId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `PurchaseOrderId` - [Order](/docs/reference/entities/order/) — referenced by via `PurchaseOrderId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Purchase Return Line — entity reference URL: https://xmatix.com/docs/reference/entities/purchase-return-line/ Last reviewed: 2026-08-16 Its only structural role is as the target of ClaimLine.PurchaseReturnLineId. The line-level detail of a real supplier return lives on CreditNoteLine (TransactionType 'BillReturn' on the parent credit note), which is what rolls returned quantity back onto GoodsReceiptLine and PurchaseOrderLine. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | The only business field the line declares, with no quantity, cost or parent-return link beside it, and no code path that writes it. Returned item detail is recorded on credit-note lines instead. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `PurchaseReturnLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Purchase Return — entity reference URL: https://xmatix.com/docs/reference/entities/purchase-return/ Last reviewed: 2026-08-16 Its only structural role is as the target of Claim.PurchaseReturnId, so a claim can be tagged against a return. Actual returns to a supplier are transacted through CreditNote with TransactionType 'BillReturn', which is what reverses the payable and writes back ReturnedQuantity onto the purchase-order and goods-receipt lines; the stock and valuation reversal is a separate InventoryLedger movement of type 'PurchaseReturn'. Do not point a user at this entity to record a return. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Document Date | Date | | A real supplier return carries its date on the credit note that transacts it. | | `DueDate` | Due Date | Date | | Supplier settlement dates live on the Bill and its payments. | | `GeneralLedgerId` | General Ledger | Lookup → [GeneralLedger](/docs/reference/entities/general-ledger/) | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Document Date Rule Validation | `DocumentDate`, Error | The document date should not go beyond today's date | Prevents backdated document date on new records | | Due Date Rule Validation | `DueDate`, Error | Due date should be a future date | Ensures due date is in the future | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — looks up via `GeneralLedgerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Claim](/docs/reference/entities/claim/) — referenced by via `PurchaseReturnId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Queue — entity reference URL: https://xmatix.com/docs/reference/entities/queue/ Last reviewed: 2026-08-16 A work queue for Omni-Channel routing. routingModel (Direct, RoundRobin, LoadBalance, Skill) decides how the routing service picks an agent; channelTypes is a CSV of channels the queue serves (Email/Chat/Voice/SMS/messaging apps/Web). The agent pool is NOT a member list on the queue: resourceGroupId points at a ResourceGroup whose active members (active Resource with Available presence and a linked User) are the routing candidates. Cases route here via the RouteCase action; calls carry their queueId on the Call row. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ChannelTypes` | Channel Types | Text | | | | `Description` | Description | Text | | | | `IsActive` | Active | Boolean | Yes | | | `ResourceGroupId` | Resource Group | Lookup → [ResourceGroup](/docs/reference/entities/resource-group/) | | The queue's agent pool: a ResourceGroup whose active members (active Resource with Available presence and a linked User) are the routing candidates. | | `RoutingModel` | Routing Model | PickList | | How the Omni-Channel routing service picks an agent from this queue: Direct, RoundRobin, LoadBalance or Skill. Values: Direct, RoundRobin, LoadBalance, Skill. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Quote Line — entity reference URL: https://xmatix.com/docs/reference/entities/quote-line/ Last reviewed: 2026-08-16 One item or service position on a Quote. Usually generated by copying OpportunityLine rows (opportunityLineId links back) or ServiceOrderLine rows in the estimate flow, carrying over item, quantity, unit price, tax group and discount fields. Has its own isApproved/isDeclined pair, set line-by-line when the header's PerformApproval or PerformDecline action runs - so per-line approval state mirrors the quote decision. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AlternateItemId` | Alternate Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `Amount` | Amount | Calculated (calculated) | | | | `ApplyPostTaxDiscount` | Apply Post Tax Discount | Boolean | Yes | | | `AssetServiceContractLineId` | Asset Service Contract Line | Lookup → [AssetServiceContractLine](/docs/reference/entities/asset-service-contract-line/) | | | | `BaseAmount` | Base Amount | Calculated (calculated) | | | | `CashDiscountAmount2` | Cash Discount Amount | Currency | | | | `ContractDiscount` | Contract Discount | Percent | | | | `ContractDiscountAmount` | Contract Discount Amount | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Discount` | Discount | Currency | | Discount Percent | | `Discount2` | Discount2 | Decimal | | | | `DiscountAmount` | Discount Amount | Currency | | | | `DiscountAmount2` | Cash Discount Amount | Currency | | | | `DurationInHours` | Duration In Hours | Decimal | | | | `ExternalId` | External | Text | | | | `GrossAmount` | Gross Amount | Calculated (calculated) | | | | `HealthCheckRecommendationId` | Health Check Recommendation | Lookup | | | | `Id` | Id | Guid | Yes | | | `IncludeinPackage` | Include in Package | Boolean | Yes | | | `IsApproved` | Approved | Boolean | Yes | | | `IsDeclined` | Declined | Boolean | Yes | | | `IsPackageService` | Package Service | Boolean | Yes | | | `IsPriceBundled` | Price Bundled | Boolean | Yes | | | `ItemComponentId` | Item Component | Lookup → [ItemComponent](/docs/reference/entities/item-component/) | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | Yes | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ItemName` | Item Name | Text | | | | `ItemServiceContractId` | Item Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NetDiscount` | Net Discount | Calculated (calculated) | | | | `NetSchemeDiscount` | Net Scheme Discount | Calculated (calculated) | | | | `OpportunityLineId` | Opportunity Line | Lookup → [OpportunityLine](/docs/reference/entities/opportunity-line/) | | | | `OriginalItemId` | Original Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PackageClassification` | Package Classification | PickList | | Values: Optional Item, Mandatory Item, Standard BOM Item. | | `PackageQuoteLineId` | Package Quote Line | Lookup | | | | `PostingType` | Posting Type | PickList | | Values: Post To Expenses, Auto Generate Claims. | | `PriceAsOnDate` | Price As On Date | Date | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `PriceListRuleId` | Price List Rule | Lookup → [PriceListRule](/docs/reference/entities/price-list-rule/) | | | | `Quantity` | Quantity | Number | | | | `QuoteDiscount` | Quote Discount | Calculated (calculated) | | | | `QuoteId` | Quote | Lookup → [Quote](/docs/reference/entities/quote/) | Yes | | | `RecommendationType` | Recommendation Type | PickList | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SchemeBenefitId` | Scheme Benefit | Lookup → [SchemeBenefit](/docs/reference/entities/scheme-benefit/) | | | | `SchemeDiscount` | SchemeDiscount | Decimal | | | | `SchemeDiscountAmount` | Scheme Discount Amount | Currency | | | | `SchemeLineId` | Scheme Slab | Lookup → [SchemeLine](/docs/reference/entities/scheme-line/) | | | | `SchemeRewardPoints` | SchemeRewardPoints | Decimal | | | | `ServiceContractId` | Service Contract | Lookup | | | | `ServiceContractSplit2` | Service Contract Split 2 | Lookup | | | | `ServiceContractSplit3` | Service Contract Split 3 | Lookup | | | | `ServiceContractWeightage` | Service Contract Weightage | Calculated (calculated) | | | | `ServiceContractWeightage2` | ServiceContractWeightage2 | Decimal | | | | `ServiceContractWeightage3` | ServiceContractWeightage3 | Decimal | | | | `ServiceOrderLineId` | Service Order Line | Lookup → [ServiceOrderLine](/docs/reference/entities/service-order-line/) | | | | `ServiceRecommendationId` | Service Recommendation | Lookup → [ServiceRecommendation](/docs/reference/entities/service-recommendation/) | | | | `ServiceRequestLineId` | ServiceRequestLine | Guid | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `Tax1` | Tax1 | Currency | | | | `Tax1Name` | TaxName1 | Text | | | | `Tax1Rate` | TaxRate1 | Currency | | | | `Tax1Type` | TaxType1 | Text | | | | `Tax2` | Tax2 | Currency | | | | `Tax2Name` | TaxName2 | Text | | | | `Tax2Rate` | TaxRate2 | Currency | | | | `Tax2Type` | TaxType2 | Text | | | | `Tax3` | Tax3 | Currency | | | | `Tax3Name` | TaxName3 | Text | | | | `Tax3Rate` | TaxRate3 | Currency | | | | `Tax3Type` | TaxType3 | Text | | | | `Tax4` | Tax4 | Currency | | | | `Tax4Name` | TaxName4 | Text | | | | `Tax4Rate` | TaxRate4 | Currency | | | | `Tax4Type` | TaxType4 | Text | | | | `Tax5` | Tax5 | Currency | | | | `Tax5Name` | TaxName5 | Text | | | | `Tax5Rate` | TaxRate5 | Currency | | | | `Tax5Type` | TaxType5 | Text | | | | `Tax6` | Tax6 | Currency | | | | `Tax6Name` | TaxName6 | Text | | | | `Tax6Rate` | TaxRate6 | Currency | | | | `Tax6Type` | TaxType6 | Text | | | | `TaxAmount` | Tax Amount | Currency | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `UIProps` | UI Props | Text | | | | `UnitPrice` | Unit Price | Currency | | | | `UnitPrice2` | Unit Price 2 | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UsageReading` | Usage Reading (Hours) | Number | | | | `UsageReadingHours` | UsageReadingHours | Decimal | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `New` | New | New | New | | `New2` | New | NewInline | QAP | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ItemComponent](/docs/reference/entities/item-component/) — looks up via `ItemComponentId` - [Item](/docs/reference/entities/item/) — looks up via `OriginalItemId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — looks up via `PriceListRuleId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — looks up via `ServiceOrderLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Quote](/docs/reference/entities/quote/) — looks up via `QuoteId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — looks up via `SchemeBenefitId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [Item](/docs/reference/entities/item/) — looks up via `AlternateItemId` - [AssetServiceContractLine](/docs/reference/entities/asset-service-contract-line/) — looks up via `AssetServiceContractLineId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ServiceRecommendation](/docs/reference/entities/service-recommendation/) — looks up via `ServiceRecommendationId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — looks up via `OpportunityLineId` - [SchemeLine](/docs/reference/entities/scheme-line/) — looks up via `SchemeLineId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `QuoteLineId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `QuoteLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Quote — entity reference URL: https://xmatix.com/docs/reference/entities/quote/ Last reviewed: 2026-10-10 A quote is the priced offer sent to a customer: the customer, the items or services offered with their prices and taxes, and the record a sales order or service order is created from once the customer agrees. It has two record types (Sales, Service) and appears in the CRM app. It is created directly, or by the Quote button on an opportunity, which copies every opportunity line and can run any number of times. It is numbered from document numbering (shipped series QT, no separator). Account, Partner Account, Branch, Opportunity and Asset are locked once saved with a value. Approve and Decline set the approved and declined flags on the quote and every line but never change Status, which starts at Draft and is changed by hand. The Order action creates one sales order per quote and refuses a second run; the Service Order action creates one service order, and a re-run adds only the lines added since to that same order. Both skip a declined quote without a message. Step-by-step procedures are on the Quotes page of the CRM documentation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer the quote is for. Only active customer accounts can be picked. When left empty it is filled from the selected asset's owner. Choosing an account fills the names, email, phone and billing and shipping addresses that are still blank. Locked once saved with a value. | | `AccountName` | Account Name | Text | | The customer's filing name. Defaults to the business name, otherwise first and last name. | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | The customer's asset the work is quoted for, on service quotes. Limited to the account's assets. Locked once saved with a value; copied to the service order. | | `BillingAddress` | Billing Address | Text | | | | `BillingCity` | Billing City | PickList | | Values: Mumbai, Pune, Chandigarh. | | `BillingCityPlaceId` | Billing City Place | Lookup | | | | `BillingContactAddressId` | Contact Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `BillingCountry` | Billing Country | PickList | | Values: India. | | `BillingPostalCode` | Billing Postal Code | Text | | | | `BillingRegion` | Billing Region | Text | | | | `BillingState` | Billing State | PickList | | Values: Haryana, Maharashtra, New Delhi, Punjab. | | `BillingStreet` | Billing Street | Text | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The selling branch. Must be active and belong to the partner account; required when the partner account has branches. Locked once saved with a value. | | `Complaint` | Complaint | Lookup | | | | `ComplaintId` | Complaint | Lookup → [Complaint](/docs/reference/entities/complaint/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Discount` | Discount | Percent | | A header discount percentage. It is copied into each line's discount when the line is added; changing it later does not change lines already on the quote. Not shown on the shipped layouts. | | `DiscountGroupId` | Discount Group | Lookup → [DiscountGroup](/docs/reference/entities/discount-group/) | | The discount group whose discounts apply to the lines. Chosen automatically on creation; not shown on the shipped layouts. | | `DocumentDate` | Document Date | Date | | The quote's business date. Set to the creation day when the quote is raised from an opportunity; there is no default on a quote created directly. | | `DocumentNumber` | Document Number | Number | Yes | | | `EstimateDate` | Estimate Date | Date | | The date the estimate was prepared. Set to the creation day when the quote is raised from an opportunity. | | `EstimateRejectionReason` | Estimate Rejection Reason | PickList | | Why the customer turned the quote down. Only None is shipped; organizations add their own reasons. Shown with Rejection Remarks under Rejections. | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `IsApproved` | Approved | Boolean | Yes | Set on the quote and every line by the Approve action, which also clears Declined. Separate from Status. | | `IsDeclined` | Declined | Boolean | Yes | Set on the quote and every line by the Decline action, which also clears Approved. A declined quote is skipped by the Order and Service Order actions without a message, and declined lines are not copied to a service order. | | `IsDropOffRequired` | Drop Off Required | Boolean | Yes | | | `IsEstimateLinesGenerated` | Estimate Lines Generated | Boolean | Yes | | | `IsFieldService` | Field Service | Boolean | Yes | | | `IsOrderGenerated` | Order Generated | Boolean | Yes | Marks that a sales order has been created from the quote. While set, the Order action is refused with "Order has already been generated for this quote." | | `IsPickUpRequired` | Pick Up Required | Boolean | Yes | | | `IsServiceOrderGenerated` | Service Order Generated | Boolean | Yes | Marks that a service order has been created from the quote. | | `IsServiceOrderUpdated` | Service Order Updated | Boolean | Yes | | | `ItemServiceContractId` | Item Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | The service contract the work falls under. Choosing one adds the contract's lines to the quote. Copied to the service order. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | The quote's document number, generated on save from the Quote Document Name Setting. The shipped format is QT, the day, month and year, and a six-digit counter, with no separator. | | `OpportunityId` | Opportunity | Lookup → [Opportunity](/docs/reference/entities/opportunity/) | | The opportunity the quote came from. Choosing an opportunity on a saved quote whose opportunity was empty adds that opportunity's lines. Locked once saved with a value. | | `OpportunityRepairOrderId` | Opportunity Repair Order | Lookup | | | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | The sales order created from the quote by the Order action. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PackageServiceId` | Package Service | Lookup | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Your selling company. Only active partner accounts can be picked. Locked once saved with a value. | | `PerformApproval` | Perform Approval | Boolean | | | | `PerformDecline` | Perform Decline | Boolean | | | | `PerformEstimateLinesGeneration` | Perform Estimate Lines Generation | Boolean | Yes | Legacy flag with no effect. | | `PerformOrderGeneration` | Perform Order Generation | Boolean | Yes | | | `PerformServiceOrderGeneration` | Perform Service Order Generation | Boolean | Yes | | | `PerformUpdateRepairOrder` | Perform Update Repair Order | Boolean | Yes | Legacy flag with no effect. | | `PriceAsOnDate` | Price As On Date | Date | | The date prices are taken from. Changing it reprices every line from the price list in force on that date. Not shown on the shipped layouts. | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | The sale price list line prices come from. Chosen automatically on creation for the customer, partner account and branch; not shown on the shipped layouts. | | `Quantity` | Quantity | Decimal | | | | `Quantity2` | Quantity2 | Decimal | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RejectionRemarks` | Rejection Remarks | Text | | Free-text explanation of why the quote was lost. The Quotes Lost Sale By Reason report groups lost quotes by it. | | `Remarks` | Remarks | Text | | | | `RoundOff` | Round Off | Currency | | | | `ServiceAdvisorId` | Service Advisor | Lookup → [Resource](/docs/reference/entities/resource/) | | Labelled Executive: the person handling the quote. Shown in the record header; activities on the record are assigned to them. Copied to the service order. | | `ServiceContractItem` | Service Contract Item | Lookup | | | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | The service order created from the quote by the Service Order action. While it is set, running the action again adds only the quote lines not yet on that service order. | | `ServiceRequestId` | ServiceRequest | Guid | | | | `ServiceRequestRepairOrderId` | ServiceRequestRepairOrder | Guid | | | | `ServiceType` | Service Type | PickList | | The kind of work quoted on a service quote: Paid Repair, PDI, Warranty Repair or Accidental Repair. Copied to the service order. Values: Paid Repair. | | `ShippingAddressId` | Shipping Address | Lookup | | | | `ShippingCity` | Shipping City | PickList | | Values: Pune, Mumbai, Chandigarh. | | `ShippingCityPlaceId` | Shipping City Place | Lookup | | | | `ShippingContactAddressId` | Contact Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `ShippingCountry` | Shipping Country | PickList | | Values: India. | | `ShippingPostalCode` | Shipping Postal Code | Text | | | | `ShippingRegion` | Shipping Region | Text | | | | `ShippingState` | Shipping State | PickList | | Values: Haryana, New Delhi, Maharashtra, Punjab. | | `ShippingStreet` | Shipping Street | Text | | | | `Status` | Status | PickList | | Where the quote stands: Draft (the default), Pending Approval, Approved or Declined. Nothing in the shipped configuration changes it; it is set by hand or by business rules an administrator adds. The Approve and Decline actions do not change it. Values: Draft, Pending Approval, Approved, Declined. | | `Tax1` | Tax 1 | Currency | | | | `Tax1Name` | Tax Name 1 | Text | | | | `Tax1Rate` | Tax Rate 1 | Currency | | | | `Tax1Type` | Tax Type 1 | Text | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `TaxId` | Tax | Lookup → [Tax](/docs/reference/entities/tax/) | | | | `TaxSupplyType` | Tax Supply Type | PickList | | Within State, Outside State, Exempt or Exports. For businesses in India it is recalculated on every save from the place of supply, the source of supply and the customer's registration. Values: Within State, Outside State, Exempt, Exports. | | `TCSEligibleAmount` | TCS Eligible Amount | Currency | | | | `TotalAmount` | Total Amount | Calculated (calculated) | | The quote total: total line amount plus total line tax. | | `TotalDiscountAmount` | Total Discount Amount | Calculated (calculated) | | The total of line discounts. | | `TotalLineAmount` | Total Line Amount | Calculated (calculated) | | | | `TotalLineBaseAmount` | Total Line Base Amount | Calculated (calculated) | | Quantity times unit price over all lines, before discounts. | | `TotalLineGrossAmount` | Total Line Gross Amount | Calculated (calculated) | | The total of line amounts including tax. | | `TotalLineTaxAmount` | Total Line Tax Amount | Calculated (calculated) | | The total tax over all lines. | | `TotalSchemeDiscountAmount` | Total Scheme Discount Amount | Calculated (calculated) | | | | `TotalTaxAmount` | TotalTaxAmount | Decimal | | | | `TotalTaxPostingAmount` | Total Tax Posting Amount | Calculated (calculated) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UsageReading` | Usage Reading | Decimal | | The asset's usage reading for the estimate. Copied to the service order. | | `UsageReadingHours` | Usage Reading Hours | Decimal | | The asset's hour-meter reading for the estimate. Copied to the service order. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `ApplyPackageConfiguration` | Apply Package Configuration | ServerAction (`ApplyPackageConfiguration`) | Writes a package quote line's component selection: requires LineId and a components array of {ItemComponentId, Quantity, IsSelected}. | | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditList` | Edit | EditInline | Edit | | `GetConfigurableItems` | Get Configurable Items | ServerAction (`GetConfigurableItems`) | Read-only package-configurator query: returns the quote's configurable package lines (ItemComponentService.GetConfigurableItemsForQuoteAsync). No state change. | | `GetPackageConfiguration` | Get Package Configuration | ServerAction (`GetPackageConfiguration`) | Read-only: returns the component configuration of one package quote line - requires a LineId argument; pricing resolved for the quote's partner account. No state change. | | `New` | New | New | New | | `PerformApproval` | Approve | ServerAction (`PerformApproval`) | Approves the quote: sets IsApproved true and IsDeclined false on the quote and on every QuoteLine. No other documents are created by this action. | | `PerformDecline` | Decline | ServerAction (`PerformDecline`) | Declines the quote: sets IsDeclined true and IsApproved false on the quote and on every QuoteLine. Declined quotes are skipped by service-order generation. | | `PerformOrderGeneration` | Order | ServerAction (`PerformOrderGeneration`) | Creates a sales Order from the quote, copying account/branch/partner and the opportunity link, then stamps Quote.OrderId and IsOrderGenerated. Skipped when OrderId is already set; validation refuses when IsOrderGenerated is already true. | | `PerformServiceOrderGeneration` | Service Order | ServerAction (`PerformServiceOrderGeneration`) | Creates a ServiceOrder from the quote and stamps IsServiceOrderGenerated. Refused when a service order was already generated or the quote has no lines; declined quotes are skipped. | | `PrintQuote` | Print Quote | Print | Printing of quote | | `PrintQuote` | Print Quote | Print | Quote Print | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Usage Reading Cannot be blank | Error, inactive | Usage Reading cannot be blank | Usage Reading cannot be blank | | Usage Reading Validation Rule | Error, inactive | Usage Reading Cannot be Negative | Usage Reading Cannot be Negative | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Customer Account Filter | `AccountId` | | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [Tax](/docs/reference/entities/tax/) — looks up via `TaxId` - [Complaint](/docs/reference/entities/complaint/) — looks up via `ComplaintId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [DiscountGroup](/docs/reference/entities/discount-group/) — looks up via `DiscountGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ServiceAdvisorId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [Opportunity](/docs/reference/entities/opportunity/) — looks up via `OpportunityId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `BillingContactAddressId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `ShippingContactAddressId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `QuoteId` - [Order](/docs/reference/entities/order/) — referenced by via `QuoteId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `QuoteId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `ServiceEstimateQuoteId` - [ServiceRecommendation](/docs/reference/entities/service-recommendation/) — referenced by via `QuoteId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Reconciliation Match — entity reference URL: https://xmatix.com/docs/reference/entities/reconciliation-match/ Last reviewed: 2026-08-16 A confirmed pairing of one bank statement line with one posted ledger journal line on the bank's GL account; the set of these rows is what drives the reconciliation summary's matched totals and its unmatched residual. Each row is written by the confirm step — either by a user or automatically by a matching rule — and is stamped with the statement line's signed amount, the confirmation timestamp and whether it was automatic. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | Copied from the bank statement line as deposit minus withdrawal at the moment of confirmation. It is never refreshed, so editing the statement line afterwards leaves this figure stale. | | `BankAccountId` | Bank Account | Lookup → [BankAccount](/docs/reference/entities/bank-account/) | | Resolved at confirmation time from the statement line's parent statement rather than supplied by the caller, and it is the key the reconciliation summary uses to gather an account's matches. A match written from a statement line with no parent statement is stored without it and drops out of every summary. | | `BankStatementLineId` | Bank Statement Line | Lookup → [BankStatementLine](/docs/reference/entities/bank-statement-line/) | | The bank side of the pair. Confirming the match also flips that line's reconciliation status to Matched, and the reconciliation summary counts a statement line as matched purely by the existence of a row here. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IsAutoMatched` | Is Auto Matched | Boolean | | True when a matching rule confirmed the pair by itself, false when a user confirmed it. It records provenance only — nothing treats an auto-match as provisional or requires it to be reviewed. | | `JournalLineId` | Journal Line | Lookup → [JournalLine](/docs/reference/entities/journal-line/) | | The ledger side of the pair — a line on a posted journal hitting the bank's GL account. Any journal line already named on a match for that bank account is excluded from future candidate pools, so a ledger line can only be matched once. | | `MatchedDate` | Matched Date | Date | | It is not the transaction date of either side of the match. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | GL Account Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [BankAccount](/docs/reference/entities/bank-account/) — looks up via `BankAccountId` - [JournalLine](/docs/reference/entities/journal-line/) — looks up via `JournalLineId` - [BankStatementLine](/docs/reference/entities/bank-statement-line/) — looks up via `BankStatementLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Reconciliation Matching Rule — entity reference URL: https://xmatix.com/docs/reference/entities/reconciliation-matching-rule/ Last reviewed: 2026-08-16 A configurable gate that narrows which posted ledger lines may be paired with a bank statement line. Rules run as a cascade in sequence order — the first filters the candidate ledger lines, the next filters that rule's survivors, and so on — so a candidate must satisfy every rule, and a rule that eliminates all remaining candidates fails the statement line outright. Rules scoped to one bank account take precedence over rules left global, and when no active rule applies the engine falls back to a built-in policy that requires amount within 100, date within 5 days, reference overlap and matching direction, with auto-match off. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AmountTolerance` | Amount Tolerance | Decimal | | Maximum absolute difference between the statement line's signed amount and the ledger line's debit-minus-credit, applied only when the Amount criterion is selected. Zero means an exact match; left empty it falls back to a permissive built-in default of 100, which is rarely what an author intends. | | `AutoMatch` | Auto Match | Boolean | | When on, this rule confirms the match itself as soon as its survivors have an unambiguous winner — a single survivor, or a top candidate that strictly outscores the runner-up — writing the reconciliation match, flipping the statement line to Matched and short-circuiting the rest of the cascade without asking anyone. Ranking is by date proximity plus a bonus for reference overlap, so an exact tie is left for manual confirmation. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DateTolerance` | Date Tolerance | Number | | Maximum whole days between the statement line's transaction date and the journal's date, applied only when the Date criterion is selected. Left empty it falls back to the built-in default of five days. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `MatchingCriteria` | Matching Criteria | PickList | | A comma-separated subset of Amount, Date, Reference, TransactionType and DocumentNumber. Every selected criterion is a hard gate a candidate ledger line must pass, not a weighting: TransactionType requires the statement line's signed amount and the ledger line's debit-minus-credit to share the same sign, and DocumentNumber compares the statement reference against the journal's voucher name. At least one criterion is mandatory at save time, and a rule that somehow ends up with none is skipped by the engine. Values: Amount, Date, Reference, TransactionType. | | `MatchingType` | Matching Type | PickList | | It is nonetheless mandatory at save time, and only OneToOne and OneToMany are seeded in the picklist even though the underlying vocabulary also defines ManyToOne and ManyToMany. Values: OneToOne, OneToMany. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Sequence` | Sequence | Number | | Position in the cascade, lowest running first: rule one filters the candidate ledger lines and each later rule filters the previous rule's survivors, so the ordering decides which candidates ever reach the later gates. Rules with no sequence sort last. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | DeleteRow | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInline` | Edit | EditInline | Edit | | `EditRow` | Edit | Edit | Edit | | `NewInLine` | New | NewInline | NewInLine | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Recurring Depreciation — entity reference URL: https://xmatix.com/docs/reference/entities/recurring-depreciation/ Last reviewed: 2026-08-16 A per-asset (or per-pool) depreciation schedule that posts one period's charge at a time under the Companies Act book: either a fixed straight-line amount or a written-down-value rate applied to the reducing balance, floored at the residual value. Each run posts a balanced Depreciation journal (Dr depreciation expense / Cr accumulated depreciation), reduces CurrentWdv, adds to AccumulatedDepreciation, stamps LastRunDate and advances NextRunDate by the configured frequency. That NextRunDate advance — not a timestamp check — is what makes the schedule safe to run repeatedly: a period is never depreciated twice. A background evaluator picks up Active schedules whose NextRunDate has arrived, and the same service backs the manual PostRecurringDepreciation action. The schedule flips itself to Completed when the carrying value reaches residual or the advanced next date passes EndDate. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccumulatedDepreciation` | Accumulated Depreciation | Currency | | Running total of everything this schedule has charged, incremented by each posting so it mirrors the credit side of the journals. | | `AccumulatedDepreciationGLAccountId` | Accumulated Depreciation GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The contra-asset account credited by every run, forming the other leg of the two-line Depreciation journal. Like the expense account it must be set before the schedule can post at all. | | `AssetName` | Asset Name | Text | | Descriptive name of the asset or pool being depreciated. It is not merely cosmetic: it is embedded in the generated journal's unique name and label alongside the run date, so it is how a posted depreciation journal is traced back to the asset it belongs to. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `Cost` | Cost | Currency | | Acquisition cost of the asset. It is the starting point for the carrying value rather than an input to each run: CurrentWdv should be seeded from it at setup, and the run only falls back to reading this column when the carrying value has not been populated. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrentWdv` | Current WDV | Currency | | The live carrying (written-down) value, seeded from Cost at setup and reduced by every posting. It is the base the written-down-value rate is applied to, so it drives the size of each reducing-balance charge; once it reaches the residual value the schedule marks itself Completed and further runs post nothing. | | `DepreciationExpenseGLAccountId` | Depreciation Expense GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The profit-and-loss account debited by every run. It is mandatory in practice: the engine refuses to run the schedule and raises a validation failure if either this or the accumulated-depreciation account is missing. | | `EndDate` | End Date | DateAndTime | | Optional hard stop for the schedule. It is applied twice: the scheduler skips a schedule whose next run would fall beyond it, and after a posting the engine marks the schedule Completed if the newly advanced next date has passed it. Leave it null to let the schedule run until the carrying value reaches residual. | | `Frequency` | Frequency | PickList | | How far NextRunDate is pushed forward after each posting — Monthly, Quarterly, HalfYearly or Yearly — which makes it the cadence of the whole schedule rather than a display setting. Only the Monthly option is currently seeded as a selectable value in the first-party metadata, so the other three have to be set through data or configuration. Values: Monthly, Yearly. | | `Id` | Id | Guid | Yes | | | `LastRunDate` | Last Run Date | DateAndTime | | Stamped with the effective date of the most recent successful posting. It is written for audit and reconciliation against the generated journals; the scheduler's due test looks at NextRunDate, not at this column. | | `Method` | Method | Text | | Selects the arithmetic for each run: StraightLine charges the fixed PeriodAmount, while WrittenDownValue (the default) charges the current carrying value multiplied by RatePerPeriod. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `NextRunDate` | Next Run Date | DateAndTime | | The control column of the whole mechanism. The scheduler picks up Active schedules whose value here has arrived, the run uses it as the journal's posting date when no explicit date is passed, and after posting it is advanced by the frequency — which is precisely what prevents a period being depreciated twice, however often the job runs. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PeriodAmount` | Period Amount | Currency | | The fixed charge per run for a straight-line schedule. The engine clips it on the final period so the closing carrying value lands exactly on the residual rather than overshooting, and it is ignored when the method is written-down-value. | | `RatePerPeriod` | Rate Per Period | Percent | | The written-down-value rate as a fraction between zero and one, and applied per run rather than per annum — a schedule running monthly needs the monthly rate here, not the annual one. It is ignored entirely when the method is straight-line. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResualValue` | Residual Value | Currency | | Intended as the salvage floor below which the asset is not depreciated. | | `StartDate` | Start Date | DateAndTime | | | | `Status` | Status | Text | | Lifecycle state with the vocabulary Active, Paused and Completed. The engine sets Completed itself once the asset is fully depreciated or the end date is passed, so Paused is the only value an operator sets to suspend a schedule. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | Entity | | `EditInLine` | EditInLine | EditInline | EditInLine | | `New` | New | New | New | | `PostRecurringDepreciation` | Post Recurring Depreciation | ServerAction (`PostRecurringDepreciation`) | Runs one period of the schedule immediately, using an optional runDate argument and otherwise the schedule's own next run date. It computes the period's charge, posts a balanced two-line Depreciation journal (debit depreciation expense, credit accumulated depreciation), reduces the carrying value, increases accumulated depreciation, stamps the last run date and advances the next run date by the frequency, returning whether it posted along with the journal id. It shares the same service the background scheduler uses, so manual and scheduled runs cannot double-post the same period; it refuses to run a schedule that is not Active or that lacks either GL account, and it returns without posting when the asset is already down to its residual value, marking the schedule Completed. | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `DepreciationExpenseGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `AccumulatedDepreciationGLAccountId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Recurring Journal Line — entity reference URL: https://xmatix.com/docs/reference/entities/recurring-journal-line/ Last reviewed: 2026-08-16 One fixed debit or credit leg of a recurring-journal template, cloned into a journal line on every run. Lines with no GL account or with both amounts zero are skipped, and a template needs at least two usable lines or the run fails. The clone carries the account, the amount, the party account and the narration; branch comes from the template header rather than the line. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Credit` | Credit | Currency | | The fixed credit amount cloned onto the generated journal line each run, mutually exclusive with debit as it is on any ledger line. The template must yield at least two usable lines with matching debit and credit totals or the run fails when the generated journal is posted. | | `Debit` | Debit | Currency | | The fixed debit amount cloned onto the generated journal line each run — the amount does not vary by period. A zero on both sides makes the line ineligible and it is dropped from the run entirely. | | `GLAccountId` | GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The ledger account the generated line will post to. | | `Id` | Id | Guid | Yes | | | `LineNumber` | Line Number | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Narration` | Narration | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company recorded against the template line. It is not copied onto the generated journal line — journal lines carry no company of their own, and the generated journal takes its company from the template header instead. | | `PartyAccountId` | Party Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer or supplier copied onto the generated journal line. It is required whenever the line's account is a control account, because posting the generated journal applies the same subledger rule as any other entry. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RecurringJournalId` | Recurring Journal | Lookup → [RecurringJournal](/docs/reference/entities/recurring-journal/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [RecurringJournal](/docs/reference/entities/recurring-journal/) — looks up via `RecurringJournalId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `GLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Recurring Journal — entity reference URL: https://xmatix.com/docs/reference/entities/recurring-journal/ Last reviewed: 2026-08-16 A template that materialises a posted journal on a schedule — rent, accrual, amortisation and standing provision entries. A scheduled evaluator finds active templates whose next run date has arrived and emits one job per template; the processor clones the template lines into a new balanced journal dated for the run, posts it through the normal posting pipeline, and advances the next run date by the frequency. The generated journal is stamped with this template as its source document, and the template flips to Completed once the advanced date passes its end date. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Stamped onto the generated journal header and onto every generated line, since template lines carry no branch of their own. Anything the branch cannot supply is then filled during posting from the GL account's defaults. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `EndDate` | End Date | DateAndTime | | The last date a run may be scheduled for: the scheduler skips a template whose next run date has passed it, and the run that advances beyond it marks the template Completed. Leaving it empty means the template runs indefinitely. | | `Frequency` | Frequency | Text | | Monthly, Quarterly, HalfYearly or Yearly, and it is what the next run date is advanced by after each run — monthly adds one month, quarterly three, half-yearly six, yearly one year. Anything unrecognised, including a blank value, is treated as monthly rather than rejected. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | A second enable switch alongside the status. The service-level due lookup treats an unset value as enabled and skips templates explicitly turned off, so a template needs both an Active status and a non-false value here to run reliably. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Narration` | Narration | Text | | | | `NextRunDate` | Next Run Date | DateAndTime | | The single field that decides whether a template runs: the scheduler picks up active templates whose next run date is on or before today, and the run advances it by the frequency. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StartDate` | Start Date | DateAndTime | | Records when the schedule is meant to begin, but the scheduler does not read it — due-template selection is driven purely by the next run date. Set the next run date to the first intended run or the template will not fire when expected. | | `Status` | Status | Text | | Active, Paused or Completed. Only Active templates are picked up by the scheduler, Paused suspends runs without losing the schedule, and Completed is set automatically once advancing the next run date takes it past the end date. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [RecurringJournalLine](/docs/reference/entities/recurring-journal-line/) — referenced by via `RecurringJournalId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Requisition Line — entity reference URL: https://xmatix.com/docs/reference/entities/requisition-line/ Last reviewed: 2026-10-10 One requested item on a requisition, numbered from document numbering (shipped series RL). The two fulfilment routes are counted separately: Purchase Order Quantity is rolled up from the purchase order lines released from this line, and Stock Transfer Quantity from the transfer lines released from it. Pending Quantity is Quantity minus both, and every release draws on it. Unit Cost comes from the requisition's purchase price list unless typed, the tax group from the tax group rules, and Amount is quantity times unit cost plus tax. Quantity cannot be lowered below the purchase order quantity, and a line with purchase order quantity cannot be deleted. Adding a package item adds its purchase components as child lines. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Calculated (calculated) | | The line value: quantity times unit cost plus the line's tax amount. Rolls up into the requisition's Total Amount. | | `ApplyPostTaxDiscount` | Apply Post Tax Discount | Boolean | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExcludeInAutoOrder` | Exclude In Auto Order | Boolean | Yes | Leaves the line out of the auto-order calculations that count open requisitions. It has no effect on the release actions. | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `ItemComponentId` | Item Component | Lookup → [ItemComponent](/docs/reference/entities/item-component/) | | The package component this line represents. Filled automatically and carried to the purchase order line on release. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | The requested item. Required. Active items only; discontinued and discounted items are refused. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PackageRequisitionLineId` | Requisition Line | Lookup → [RequisitionLine](/docs/reference/entities/requisition-line/) | | The package line this component line belongs to. Filled automatically when a package item is added. | | `PendingQuantity` | Pending Quantity | Calculated (calculated) | | Quantity minus Purchase Order Quantity minus Stock Transfer Quantity: what a release can still take. | | `PriceAsOnDate` | Price As On Date | Date | | The date the line's price is taken from; the requisition's price date or document date when empty. Changing it reprices the line. | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | The price list used for this line; the requisition's price list when empty. | | `PriceListRuleId` | Price List Rule | Lookup → [PriceListRule](/docs/reference/entities/price-list-rule/) | | | | `PurchaseOrderQuantity` | Purchase Order Quantity | Number | | The quantity on purchase order lines released from this line. Maintained by the system from those lines, so it changes when they change. | | `PurchaseRequisitionLineNumber` | PurchaseRequisitionLineNumber | Number | | Sequence number of the line within its requisition. | | `Quantity` | Quantity | Number | Yes | How much is requested. Must be greater than zero, and cannot be lowered below the quantity already on purchase orders. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedQuantity` | Requested Quantity | Number | | The quantity entered for this line in a selective release dialog. Must be greater than zero and no more than Pending Quantity. Not stored as a record of the original request. | | `RequisitionId` | Requisition | Lookup → [Requisition](/docs/reference/entities/requisition/) | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | The item variant. Required when the item requires a SKU; limited to the item's SKUs. | | `StockTransferQuantity` | Stock Transfer Quantity | Number | | The quantity on transfer lines released from this line. Maintained by the system from those lines. | | `Tax1` | Tax 1 | Currency | | | | `Tax1Name` | Tax Name 1 | Text | | | | `Tax1Rate` | Tax Rate 1 | Currency | | | | `Tax1Type` | Tax Type 1 | Text | | | | `Tax2` | Tax 2 | Currency | | | | `Tax2Name` | Tax Name 2 | Text | | | | `Tax2Rate` | Tax Rate 2 | Currency | | | | `Tax2Type` | Tax Type 2 | Text | | | | `Tax3` | Tax 3 | Currency | | | | `Tax3Name` | Tax Name 3 | Text | | | | `Tax3Rate` | Tax Rate 3 | Currency | | | | `Tax3Type` | Tax Type 3 | Text | | | | `Tax4` | Tax 4 | Currency | | | | `Tax4Name` | Tax Name 4 | Text | | | | `Tax4Rate` | Tax Rate 4 | Currency | | | | `Tax4Type` | Tax Type 4 | Text | | | | `Tax5` | Tax 5 | Currency | | | | `Tax5Name` | Tax Name 5 | Text | | | | `Tax5Rate` | Tax Rate 5 | Currency | | | | `Tax5Type` | Tax Type 5 | Text | | | | `Tax6` | Tax 6 | Currency | | | | `Tax6Name` | Tax Name 6 | Text | | | | `Tax6Rate` | Tax Rate 6 | Currency | | | | `Tax6Type` | Tax Type 6 | Text | | | | `TaxAmount` | Tax Amount | Currency | | The line's tax, recalculated when the item, SKU, quantity, amount or tax group changes. | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | The line's taxes, chosen from the tax group rules when the line is added. | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | The expected price per unit. Taken from the price list unless typed. Copied to the purchase order or transfer line on release. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit In Line | | `HeaderEdit` | Header Edit | EditInline | edit | | `Import` | Import | UIAction | Import | | `New` | Quick Add | NewInline | New | | `ProductCatalogue` | Product Catalogue | UIAction | Product Catalogue | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Quantity Rule Validation | `Quantity`, Error | Quantity should be greater than 0 | Prevents zero or negative quantity on requisition lines | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Sku For Item | `SKUId` | SkuForItem | ## Related entities - [ItemComponent](/docs/reference/entities/item-component/) — looks up via `ItemComponentId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — looks up via `PriceListRuleId` - [Requisition](/docs/reference/entities/requisition/) — looks up via `RequisitionId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [RequisitionLine](/docs/reference/entities/requisition-line/) — looks up via `PackageRequisitionLineId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [PurchaseOrderRequisition](/docs/reference/entities/purchase-order-requisition/) — referenced by via `PurchaseRequisitionLineId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `RequisitionLineId` - [RequisitionLine](/docs/reference/entities/requisition-line/) — referenced by via `PackageRequisitionLineId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `RequisitionLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Requisition — entity reference URL: https://xmatix.com/docs/reference/entities/requisition/ Last reviewed: 2026-10-10 A requisition is an internal request for items raised before a supplier is committed. It appears in the Procurement app, on the web and in the mobile app, and is numbered from document numbering (shipped series R, separator -, date DDMMYYYY, six digits). It is fulfilled in two ways that both draw on each line's pending quantity: Release Order and Selective Release Order create a purchase order for the requisition's supplier, partner account and branch, while Release Transfer and Selective Release Transfer create an outward stock transfer from From Branch to Branch. A purchase order can also pull its lines in with Add Requisition. Partner Account, Branch and Supplier Account are locked once saved. Status starts at Draft; a shipped business rule sets it to Confirmed when the requisition is saved with lines and no pending quantity. The shipped release buttons show only while Status is Draft and Total Pending Quantity is greater than zero. Step-by-step procedures are on the Requisitions page of the Procurement documentation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The requesting branch, which receives the goods. Must be active and belong to the partner account; required when the partner account has branches. A released transfer moves stock to this branch. Locked once saved. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | | | | `Description` | Description | Text | | Free text describing the request. | | `Division` | Division | PickList | | | | `DocumentDate` | Document Date | Date | | The request's business date. Set to today when left empty. | | `DocumentNumber` | DocumentNumber | Number | | | | `ExternalId` | External | ExternalId | | | | `FromBranchId` | From Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The supplying branch for the transfer route: Release Transfer and Selective Release Transfer create an outward transfer from this branch to Branch. Limited to the partner account's branches. Leave empty for a purchase. | | `Id` | Id | Guid | Yes | | | `IsOrderReleased` | Order Released | Boolean | | Set when a purchase order is released from the requisition. It does not mean everything is released; read Total Pending Quantity or the line counters for that. | | `LastModifiedBy` | Last Modified By | Lookup | Yes | Not maintained; the record's last modifier is in Modified By. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text, unique | | The requisition's document number, generated on save from the Requisition Name Setting. The shipped format is R, a hyphen, the document date as DDMMYYYY, a hyphen and a six-digit counter. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Your organization raising the request. Only active partner accounts can be picked. Copied to purchase orders and transfers released from it. Locked once saved. | | `PerformReleaseOrder` | Perform Release Order | Boolean | Yes | Internal flag cleared by the release. Releasing happens through the Release Order action, not by setting this field. | | `PriceAsOnDate` | Price As On Date | Date | | The date prices are taken from for new lines. Document Date is used when it is empty. | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | The purchase price list new lines are priced from. A purchase-type price list that applies to the partner account and branch is chosen automatically on creation. Changing it later does not reprice existing lines. | | `PurchaseOrderId` | Purchase Order | Lookup → [PurchaseOrder](/docs/reference/entities/purchase-order/) | | Optional header reference to a purchase order. The release actions do not fill it; each released purchase order points back at the requisition and each of its lines at the requisition line instead. | | `PurchaseOrderLineId` | Purchase Order Line | Lookup → [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) | | Optional reference to a purchase order line. Not filled by the release actions. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | Free text. | | `RequestedById` | Requested By | Lookup | | Optional reference to who asked for the items. | | `RequiredDate` | Required Date | Date | | When the items are needed. Cannot be earlier than today. | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | The person the request is raised for. Must be authorized for the requisition's partner account and branch. | | `Status` | Status | PickList | | Where the request stands: Draft (the default), Confirmed or Approved. A shipped business rule sets Confirmed when the requisition is saved with lines and no pending quantity left. Nothing in the shipped product sets Approved. Read-only on the shipped record page. The shipped release buttons show only while it is Draft. Values: Draft, Confirmed. | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | The vendor to buy from. Only active supplier accounts can be picked. Filled from the branch's default supplier when left empty. Copied to every purchase order released from the requisition. Locked once saved. | | `Tax1` | Tax 1 | Currency | | | | `Tax1Name` | Tax Name 1 | Text | | | | `Tax1Rate` | Tax Rate 1 | Currency | | | | `Tax1Type` | Tax Type 1 | Text | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | Header-level taxes, applied when the requisition is created. | | `TaxId` | Tax | Lookup → [Tax](/docs/reference/entities/tax/) | | | | `TaxSupplyType` | Tax Supply Type | PickList | | The tax lane. For businesses in India it is set from the supplier's tax registration and whether the place and source of supply differ. Values: Within State, Outside State, Exempt, Exports, SEZ. | | `TotalAmount` | Total Amount | Calculated (calculated) | | The estimated value of the request: the sum of the line amounts, where each line amount is quantity times unit cost plus the line's tax. | | `TotalLineTaxAmount` | Total Line Tax Amount | Calculated (calculated) | | The total tax over all lines. | | `TotalQuantityPending` | Total Quantity Pending | Calculated (calculated) | | Labelled Total Pending Quantity on the record page: the sum of the lines' pending quantity, which is what the release actions can still take. The shipped release buttons need it to be greater than zero. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `ApplyPackageConfiguration` | ApplyPackageConfiguration | ServerAction (`ApplyPackageConfiguration`) | ApplyPackageConfiguration | | `BulkDelete` | Delete | Delete | Delete in Selected | | `Clone` | Clone | ServerAction (`Clone`) | Creates a copy of the requisition, including its line items, after a confirmation. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | EDIT | | `EditInLine` | Edit | EditInline | Edit in line | | `EditInList` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | edit list row | | `GetConfigurableItems` | GetConfigurableItems | ServerAction (`GetConfigurableItems`) | GetConfigurableItems | | `GetPackageConfiguration` | GetPackageConfiguration | ServerAction (`GetPackageConfiguration`) | GetPackageConfiguration | | `New` | New | New | New | | `PerformReleaseOrder` | Release Order | ServerAction | Creates one purchase order for every line that still has pending quantity, at its full pending quantity, linked to the requisition and to each requisition line. | | `PerformReleaseTransfer` | Release Transfer | ServerAction (`PerformReleaseTransfer`) | Creates an outward stock transfer from From Branch to Branch for every line that still has pending quantity. | | `ProductConfigurator` | Product Configurator | UIAction | Opens the package configurator to choose optional components and their quantities for a package line. Shown while Status is Draft. | | `SelectiveReleaseOrder` | Selective Release Order | ServerAction (`SelectiveReleaseOrder`) | Creates a purchase order for the lines the user ticks, each at the requested quantity entered for it, which must be greater than zero and no more than the line's pending quantity. | | `SelectiveReleaseTransfer` | Selective Release Transfer | ServerAction (`SelectiveReleaseTransfer`) | Creates an outward stock transfer for the lines the user ticks, each at the requested quantity entered for it, which must be greater than zero and no more than the line's pending quantity. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Required Date Rule Validation | `RequiredDate`, Error | Required By Date Should not be Backdated | Prevents backdated required-by date | | XM_ValidateOnInactiveBranch | `BranchId`, Error | please tag active Branch! | please tag active Branch! | | XM_ValidateOnInactivePartnerAccount | `PartnerAccountId`, Error | Please tag active Partner Account! | Please tag active Partner Account! | | XM_ValidateOnInactiveSupplierAccount | Error | please tag active supplier account! | please tag active supplier account! | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Only Partner Account | `PartnerAccountId` | | | Only Supplier | `SupplierAccountId` | | | Supplier Account From Branch | `FromBranchId` (inactive) | Supplier Account From Branch | ## Related entities - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — looks up via `PurchaseOrderId` - [Tax](/docs/reference/entities/tax/) — looks up via `TaxId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — looks up via `PurchaseOrderLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Branch](/docs/reference/entities/branch/) — looks up via `FromBranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `RequisitionId` - [RequisitionLine](/docs/reference/entities/requisition-line/) — referenced by via `RequisitionId` - [PurchaseOrderRequisition](/docs/reference/entities/purchase-order-requisition/) — referenced by via `PurchaseRequisitionId` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `PurchaseRequisitionId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `PurchaseRequisitionId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `PurchaseRequisitionId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Resource Assignment Rule — entity reference URL: https://xmatix.com/docs/reference/entities/resource-assignment-rule/ Last reviewed: 2026-08-16 One field condition of a PartnerResource's auto-assignment setup (linked by partnerResourceId): fieldName, operation and fieldValue describe a test evaluated against the record being assigned. During assignment the resource service walks the applicable PartnerResources for the record's company/branch in their configured order and applies each one's rules under its success criteria - all rules met, any rule met, or always - stamping the first winner's resource onto the record. Supported operations are equals and notEqual for text, plus numeric and date comparisons (greater/less and their or-equal variants) when the field is numeric or a date. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AssignmentType` | Assignment Type | PickList | | Values: Appointment. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FieldName` | Field Name | Text | | | | `FieldValue` | Field Value | Text | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Operation` | Operation | PickList | | The comparison applied between the record's field and fieldValue: equals or notEqual for text, plus greater/less comparisons (including or-equal variants) when the field is numeric or a date. Unknown operations evaluate to false rather than erroring. Values: Equal. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerResourceId` | Partner Resource | Lookup → [PartnerResource](/docs/reference/entities/partner-resource/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SequenceNumber` | Sequence Number | Number | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Resource Availability Check In — entity reference URL: https://xmatix.com/docs/reference/entities/resource-availability-check-in/ Last reviewed: 2026-08-16 One check-in/check-out pair inside a ResourceAvailability day, numbered by documentNumber. checkInSource and checkOutSource record how each punch was captured, so a day with multiple work sessions keeps each session as its own row under the parent day. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CheckIn` | Check-In | DateAndTime | | | | `CheckInSource` | Check In Source | PickList | | Values: Mobile. | | `CheckOut` | Check-Out | DateAndTime | | | | `CheckOutSource` | Check-Out Source | PickList | | Values: Desktop, Biometric. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentNumber` | Document Number | Number | Yes | | | `Id` | Record | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceAvailabilityId` | Resource Availability | Lookup → [ResourceAvailability](/docs/reference/entities/resource-availability/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `New` | New | UIAction | New | ## Related entities - [ResourceAvailability](/docs/reference/entities/resource-availability/) — looks up via `ResourceAvailabilityId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Resource Availability Data — entity reference URL: https://xmatix.com/docs/reference/entities/resource-availability-data/ Last reviewed: 2026-08-16 A raw attendance punch event for a Resource: the event time and attendanceTime, its type, the branch, and the parent ResourceAvailability day it rolls up into. Location pings captured in the field reference these punch rows (a ping links back to its check-in punch), tying GPS trail data to attendance. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AttendanceTime` | Attendance Time | DateAndTime | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Resource Availability Data Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceAvailabilityId` | Resource Availability | Lookup → [ResourceAvailability](/docs/reference/entities/resource-availability/) | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `Time` | Time | DateAndTime | | | | `Type` | Type | PickList | | Values: Check-In, Check-Out, Auto-Check-Out. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `New` | New | New | New | ## Related entities - [ResourceAvailability](/docs/reference/entities/resource-availability/) — looks up via `ResourceAvailabilityId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Resource Availability — entity reference URL: https://xmatix.com/docs/reference/entities/resource-availability/ Last reviewed: 2026-08-16 One attendance day for a field Resource: the date, the branch it belongs to plus the branches where check-in and check-out actually happened, the first check-in and last check-out times, accumulated duration and penaltyHours, and a leaveRequestId link when the day is explained by leave. Child ResourceAvailabilityCheckIn rows hold the individual check-in/check-out pairs of the day and ResourceAvailabilityData rows the raw punch events; Employee records can reference an availability row. Scoped to a company via partnerAccountId. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AttendanceHours` | Attendance Hours | Calculated | | total hours worked | | `AvailabilityType` | Availability Type | PickList | | Values: Present, Leave, Weekend, Holiday, Absent, Half Day. | | `BranchId` | Branch | Lookup | | | | `CheckIn` | Check-In | DateAndTime | | | | `CheckInBranchId` | Check-In Branch | Lookup | | | | `CheckOut` | Check-Out | DateAndTime | | | | `CheckOutBranchId` | Check-Out Branch | Lookup | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Date` | Date | Date | | | | `Duration` | Duration | Calculated (calculated) | | | | `EmployeeId` | Employee | Lookup → [Employee](/docs/reference/entities/employee/) | | | | `FirstCheckInTime` | First Check-In Time | Calculated (calculated) | | | | `Id` | Id | Guid | Yes | | | `LastCheckOutTime` | Last Check-Out Time | Calculated (calculated) | | | | `LeaveRequestId` | Leave Request | Lookup | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PenaltyHours` | Penalty Hours | Decimal | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `New` | New | New | New | ## Related entities - [Employee](/docs/reference/entities/employee/) — looks up via `EmployeeId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Employee](/docs/reference/entities/employee/) — referenced by via `ResourceAvailabilityId` - [ResourceAvailabilityData](/docs/reference/entities/resource-availability-data/) — referenced by via `ResourceAvailabilityId` - [ResourceAvailabilityCheckIn](/docs/reference/entities/resource-availability-check-in/) — referenced by via `ResourceAvailabilityId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Resource Business Hour — entity reference URL: https://xmatix.com/docs/reference/entities/resource-business-hours/ Last reviewed: 2026-08-16 A resource's actual working calendar comes from Resource.BusinessHoursId pointing at the BusinessHours master (used, for example, to pick the timezone for attendance auto-checkout, falling back to the default branch's hours), and appointment slot availability is driven by the branch's BusinessHours plus branch holidays. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BusinessHoursId` | Business Hours | Lookup | | It cannot be read, written or filtered; a resource's working hours come from Resource.BusinessHoursId instead. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FromDate` | From Date | Date | | Nothing in the platform reads this entity in any case. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `ToDate` | To Date | Date | | Treat any schedule question as belonging to BusinessHours and branch holidays instead. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Resource Compensation — entity reference URL: https://xmatix.com/docs/reference/entities/resource-compensation/ Last reviewed: 2026-08-16 Despite sitting near the Rewards entities, this is a payroll record: the assignment of a SalaryStructure to a Resource (the employee salary assignment of the payroll plan), with ctc, an effectiveFrom/effectiveTo window, a revisionReason for changes and an isActive flag. Employees link back to it. It is not read by the incentive or scheme engines. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CTC` | CTC | Currency | | Total cost-to-company of the salary assignment; a payroll figure, unrelated to incentive payouts. | | `EffectiveFrom` | Effective From | Date | | | | `EffectiveTo` | Effective To | Date | | | | `EmployeeId` | Employee | Lookup → [Employee](/docs/reference/entities/employee/) | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `RevisionReason` | Revision Reason | Text | | | | `SalaryStructureId` | Salary Structure | Lookup → [SalaryStructure](/docs/reference/entities/salary-structure/) | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete | Delete | DeleteListHeader | | `DeleteListRow` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [SalaryStructure](/docs/reference/entities/salary-structure/) — looks up via `SalaryStructureId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [Employee](/docs/reference/entities/employee/) — looks up via `EmployeeId` - [Employee](/docs/reference/entities/employee/) — referenced by via `ResourceCompensationId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Resource Group Member — entity reference URL: https://xmatix.com/docs/reference/entities/resource-group-member/ Last reviewed: 2026-08-16 A junction row placing one Resource into a ResourceGroup (both lookups required). batchInstanceId tags rows created together by a bulk operation. Group membership is what group-scoped features resolve through; the row itself carries no other semantics. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BatchInstanceId` | Batch Instance | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceGroupId` | Resource Group | Lookup → [ResourceGroup](/docs/reference/entities/resource-group/) | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | Yes | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Deleted The Selected Records | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | edit | | `EditInList` | Edit | EditInline | edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | NewInline | New | ## Related entities - [ResourceGroup](/docs/reference/entities/resource-group/) — looks up via `ResourceGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Resource Group — entity reference URL: https://xmatix.com/docs/reference/entities/resource-group/ Last reviewed: 2026-08-16 A named pool of Resources; membership is the child ResourceGroupMember rows. In Omni-Channel/telephony it is the agent-pool construct: a Queue points at a ResourceGroup via resourceGroupId and the router draws candidates from the group's members (active resources with a linked user and Available presence). Also referenced outside routing - by LeaveEntitlement, IncentivePlan, ChecklistTemplate and VisitRoute - so a group can equally represent a leave-policy population or a field-sales team. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedBy` | Created By | Lookup | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `DynamicMemberType` | Dynamic Member Type | PickList | | Values: ReportData, FieldFilter. | | `Id` | Id | Guid | Yes | | | `LastModifiedBy` | Last Modified By | Lookup | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReportId` | Report | Text | | | | `ResourceGroupName` | Resource Group Name | Text | | | | `ResourceGroupType` | Resource Group Type | PickList | | Values: Scheme, Incentive. | | `RuleSuccessCriteria` | Rule Success Criteria | PickList | | Values: Sample. | | `RuleSuccessCustomLogic` | Rule Success Custom Logic | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Delete in page. | | `EditInLine` | Edit | EditInline | Edit | | `EditInList` | Edit | EditInline | edit in list Row | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `UIAction` | UI Action | UIAction | UI Action | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [LeaveEntitlement](/docs/reference/entities/leave-entitlement/) — referenced by via `ResourceGroupId` - [ResourceGroupMember](/docs/reference/entities/resource-group-member/) — referenced by via `ResourceGroupId` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — referenced by via `MemberResourceGroupId` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — referenced by via `ResourceGroupId` - [Resource](/docs/reference/entities/resource/) — referenced by via `IncentiveResourceGroupId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Resource Leave — entity reference URL: https://xmatix.com/docs/reference/entities/resource-leave/ Last reviewed: 2026-08-16 Real leave lives in LeaveRequest and LeaveEntitlement keyed on ResourceId: approved unpaid LeaveRequest days overlapping a payroll period become loss-of-pay days, and appointment slot release checks LeaveRequest to suppress slots for a resource on leave. Any question about someone's leave balance, approvals or availability should be answered from LeaveEntitlement and LeaveRequest, never from this entity. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Balance` | Balance | Number | | Leave balances must be derived from LeaveEntitlement against approved LeaveRequest days. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `LeaveTypeId` | Leave Type | Lookup | | Real leave typing lives on LeaveRequest and LeaveEntitlement, which are keyed on ResourceId. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `TotalAvailable` | Total Available | Number | | Never present it as an entitlement figure - use LeaveEntitlement for what was granted and LeaveRequest for what was consumed. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Resource Presence — entity reference URL: https://xmatix.com/docs/reference/entities/resource-presence/ Last reviewed: 2026-08-16 The durable presence and capacity configuration for one Resource in Omni-Channel routing - one row per resource, upserted by the routing service. Holds the availability status with an optional reason, total capacity in work units (maxWorkItems) and optional per-channel caps as JSON. Live load is not stored here: it is computed from the resource's open ResourceWork items. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `LastChangedOn` | Last Changed On | DateAndTime | | | | `MaxPerChannelJson` | Max Per Channel | Text | | Optional per-channel capacity caps stored as a JSON object, layered on top of the overall maxWorkItems total. | | `MaxWorkItems` | Max Work Items | Number | Yes | Total capacity in work units (default 5). The router only assigns new work when the agent's current load (sum of open ResourceWork capacityWeight) plus the new item's weight fits within this cap. | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/), unique | Yes | The Resource this presence row belongs to - one row per resource, enforced by upsert in the routing service (setting presence updates the existing row rather than adding another). The underlying user is the resource's UserId. | | `Status` | Status | PickList | | Presence vocabulary: Available, Busy, Away, Offline, with statusReason carrying the optional why. This is the agent-declared state; actual load is computed from open ResourceWork items. Values: Available, Busy, Away, Offline. | | `StatusReason` | Status Reason | Text | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `EditInLine` | Edit | EditInline | Edit in page. | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Resource Skill — entity reference URL: https://xmatix.com/docs/reference/entities/resource-skill/ Last reviewed: 2026-08-16 One agent's competency: a child of the Skill master (skillId) held by a Resource (resourceId), with proficiencyLevel and a start/end validity window. Skill-based Omni-Channel routing matches a required skill by this row's Name (which mirrors the parent Skill's name) at proficiencyLevel >= 1; skillId is the structural link to the catalogue. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `EndDate` | End Date | Date | | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Active | Boolean | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ProficiencyLevel` | Proficiency Level | Number | | Numeric competency level; skill-based routing treats the resource as qualified when this is 1 or higher for the matching skill name. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | Yes | | | `SkillId` | Skill | Lookup → [Skill](/docs/reference/entities/skill/) | | Structural link to the parent Skill master. Note the routing gotcha: skill-based routing currently matches by this row's Name (mirroring the skill's name) at ProficiencyLevel >= 1, not by SkillId. | | `StartDate` | Start Date | Date | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | UIAction | EditEntity | | `EditInLine` | Edit | Edit | Edit in page. | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Resource Work — entity reference URL: https://xmatix.com/docs/reference/entities/resource-work/ Last reviewed: 2026-08-16 One Omni-Channel routing work item: a unit of work pushed to a Resource, polymorphic via workEntityName/workRecordId so any entity - cases, chats, calls, leads - can be routed, not just cases. Carries the queue it came from (queueId), the channel, the capacity it consumes (capacityWeight) and the routing timeline (pushedOn, acceptedOn, closedOn). A resource's live load is computed from the open rows here against the capacity configured on ResourcePresence; the assigned user is reached through the resource's userId. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AcceptedOn` | Accepted On | DateAndTime | | | | `CapacityWeight` | Capacity Weight | Number | Yes | How many capacity units this work item consumes against the resource's maxWorkItems (default 1) - heavier work can be modeled by a larger weight rather than a separate cap. | | `Channel` | Channel | PickList | | The channel the work arrived on: Email, Chat, Voice, SMS, messaging apps or Web. Carried through decline re-routes and transfers. Values: Email, Chat, Voice, SMS, messaging apps, Web. | | `ClosedOn` | Closed On | DateAndTime | | | | `PushedOn` | Pushed On | DateAndTime | | When the item was pushed (defaulted on insert). Also the RoundRobin tiebreaker: that model picks the eligible agent with the oldest last-pushed time, so this field drives rotation fairness. | | `QueueId` | Queue | Lookup → [Queue](/docs/reference/entities/queue/) | | The Queue the work was routed through; null when it was assigned directly to a resource. Pending items are counted per queue for the supervisor backlog view. | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `Status` | Status | PickList | | Routing lifecycle vocabulary: Pending, Assigned, Accepted, Declined, Closed, Transferred. Open (non-terminal) rows are what count against the resource's capacity. Values: Pending, Assigned, Accepted, Declined, Closed, Transferred. | | `WorkEntityName` | Work Entity | Text | | The entity name of the routed record (Case, Call, ...) - pairs with workRecordId as a polymorphic reference. Case work gets special treatment on accept: the case's AssignedToId/OwnerId are stamped from the accepting resource's user. | | `WorkRecordId` | Work Record | Lookup | Yes | The id of the routed record; interpret it against workEntityName. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `EditInLine` | Edit | EditInline | Edit in page. | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Resource — entity reference URL: https://xmatix.com/docs/reference/entities/resource/ Last reviewed: 2026-10-10 A resource is the record for one person who does work in xMatix - a sales executive, service advisor, technician, driver, manager or back-office employee - and the record that documents, visits, timesheets, payslips, expense claims, leave and loans point to when they name a person. A user account decides how someone signs in; the resource decides who they are in the business. The two are linked through the resource's User field, and the active resource whose User is the signed-in account is treated as that user's own resource: it fills empty person fields on new records and gives new documents their company and branch. The Payroll Employee record and Resource Compensation records point to the resource, and payroll reads bank details and PAN from it. Resources appear in the Platform, Payroll and Rewards apps. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AadhaarNumber` | Aadhaar Number | Text | | The person's Aadhaar number. | | `BankAccountNumber` | Bank Account Number | Text | | The bank account salary and reimbursements are paid to. Salary payment batches read it from the resource when they are generated. | | `BusinessHoursId` | Business Hours | Lookup → [BusinessHours](/docs/reference/entities/business-hours/) | | The person's own working hours. Where consulted, for example to find the person's time zone for attendance, they take precedence over the default branch's hours. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DefaultBranchId` | Default Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch this person normally works from. Only branches of the Default Partner Account are offered, and it must be set together with Default Partner Account - saving one without the other is refused. | | `DefaultPartnerAccountId` | Default Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The company this person normally works for. Only partner accounts are offered. It must be set together with Default Branch - saving one without the other is refused. When both are set, a new document this person creates with no company and no branch gets this pair. Otherwise the person's first current Partner Resource assignment is used, and failing that whichever default is set. | | `Department` | Department | PickList | | The person's department. Shipped values are IT, HR, Sales and Finance; the list can be extended. Values: IT, HR, Sales, Finance. | | `Designation` | Designation | PickList | | The person's job title. Shipped values are Software Engineer, HR Executive, Sales Executive and Sales Executive Financial Analyst; the list can be extended. Values: Software Engineer, HR Executive, Sales Executive, Sales Executive Financial Analyst. | | `EffectiveFromDate` | Effective From Date | Date | | The start of the person's validity window for automatic assignment rules: before this date the person is skipped as not effective yet. Nothing else reads it, and it is not on the shipped form. | | `EffectiveTillDate` | Effective Till Date | Date | | The end of the person's validity window for automatic assignment rules: after this date the person is skipped as no longer effective. It must be later than Effective From Date. It does not switch the resource off - clear Active for that. | | `EmployeeId` | Code | Text, unique | Yes | The person's staff or employee number, labelled Code and shown as Resource Id in the lists. Required and unique. It is a plain code: the payroll Employee record links to the resource itself, not to this code. | | `EmploymentType` | Employment Type | PickList | | Permanent or Contractual. Payroll uses the employment type on the Employee record instead. Values: Permanent, Contractual. | | `ExternalId` | External | Text, unique | | An identifier for this person in another system, used by integrations. Unique when set. | | `Id` | Id | Guid | Yes | | | `IFSCCode` | IFSC Code | Text | | The bank branch code of the person's bank account, read with the account number when salary payments are generated. | | `IncentiveResourceGroupId` | IncentiveResourceGroup | Lookup → [ResourceGroup](/docs/reference/entities/resource-group/) | | Places the person in a resource group for incentive purposes. | | `IsActive` | Active | Boolean | | Whether the resource is in use. New resources start inactive. Only an active resource acts as its user's own resource, can check in on the mobile app or is picked by automatic assignment, and documents naming an inactive resource that has partner-resource assignments are refused. Switch it off when someone leaves; their history is kept. | | `IsEligibleForPT` | Is Eligible for PT | Boolean | | Marks the person as liable for professional tax so payroll configuration can distinguish them. | | `IsRelatedParty` | Related Party | Boolean | | Marks the person as a related party of the organization, such as a director, key manager or their relative. Related parties are included as persons in the related-party disclosure and statutory annual reports. Switch it on before choosing a Related Party Type. | | `JoiningDate` | Joining Date | Date | | The date the person joined. Recorded for HR purposes; calculations do not read it. | | `Label` | Resource Label | Text | | A secondary display text, separate from Name. Usually left empty. | | `LabourCostRatePerHour` | Labour Cost Rate Per Hour | Decimal | | What one hour of this person's time costs, used to cost their working hours in profitability analysis. | | `ManagerResourceId` | Manager | Lookup → [Resource](/docs/reference/entities/resource/) | | The person's direct manager, as another resource. Requests that go to the manager, such as outlet transfer requests, use it, and on the mobile app a manager's team roster lists the active resources that name them here. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | The person's name as it appears in pickers and on documents. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PANNumber` | PAN Number | Text | | The person's PAN, used for tax deducted from salary, TDS returns and PAN verification. | | `PanVerificationSource` | PAN Verification Source | Text | | Where the PAN verification result came from; the bulk verification import records its own source value. | | `PanVerificationStatus` | PAN Verification | PickList | | The result of verifying this person's PAN with the tax department: Verified, Invalid or Name Mismatch; empty means never verified. Filled when a bulk PAN verification result file is imported on a TDS return. Values: Verified, Invalid, Name Mismatch. | | `PanVerifiedOn` | PAN Verified On | DateAndTime | | When the PAN verification result was recorded. | | `ParentResourceId` | Parent Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | A parent in a resource structure, kept separate from the reporting line held in Manager. | | `PFAccount` | PF Account | Text | | The person's provident fund account number. | | `Phone` | Phone | Text | | The person's contact phone number. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RelatedPartyEffectiveFrom` | Related Party From | Date | | The date the related-party relationship began. | | `RelatedPartyEffectiveTo` | Related Party To | Date | | The date the related-party relationship ended. It cannot be before Related Party From. | | `RelatedPartyRelationship` | Relationship | Text | | A short description of the related-party relationship. | | `RelatedPartyType` | Related Party Type | PickList | | The nature of the related-party relationship. Required when Related Party is on, and refused when it is off. Values: Director, Key Management Personnel, Relative of Director / KMP, Holding Company, Subsidiary Company, Fellow Subsidiary (Sister Concern), Associate / Joint Venture, Entity Controlled by Director / KMP, Promoter, Other. | | `ResourceType` | ResourceType | LongMultiLineText | | A free-text classification beside Resource Type, with no fixed list of values. Organizations use it in their own filters and rules to select a group of people. | | `SalaryStructureId` | Salary Structure | Lookup → [SalaryStructure](/docs/reference/entities/salary-structure/) | | A salary structure kept for reference. Payroll does not use it: pay is calculated from the salary structure on the person's latest active Resource Compensation record. | | `SkipManagerResourceId` | Skip Manager | Lookup → [Resource](/docs/reference/entities/resource/) | | The manager one level above the direct manager, for skip-level approvals and escalation. | | `Type` | Resource Type | PickList | Yes | The person's role: Service Advisor, Manager, Salesperson or Labour. Required. The All Managers and All Service Advisors list views filter on it; the shipped All Salespersons view filters on the value Sales Persons, which the shipped value Salesperson does not match. Values: Service Advisor, Manager, Salesperson, Labour. | | `UAN` | UAN | Text | | The person's provident fund universal account number. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UserId` | User | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | The sign-in account of this person. The active resource whose User is the signed-in account is that user's own resource: it is stamped into empty person fields on new records and supplies their company and branch. Leave it empty for people who never sign in, and link each user to one resource only - with two, either may be picked. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Creates a copy of the resource as a new record, through the normal save, so validations such as the default company and branch rule apply. The shipped record page header does not show it. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditInList` | Edit | EditInline | Edit in List Header | | `EditListRow` | Edit | Edit | Edit | | `EditPopup` | Edit | Edit | Edit | | `LatestForm16` | Latest Form 16 | ServerAction | Opens the Latest Form 16 form. It does not generate a certificate; the person's TDS certificates are separate records. | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Effective Till Date Rule Validation | `EffectiveTillDate`, Error | Effective Till Date cannot be before Effective From Date | Prevents Till Date from Older. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | BranchFilter | `DefaultBranchId` | | | PartnerAccountFilter | `DefaultPartnerAccountId` | | ## Related entities - [Resource](/docs/reference/entities/resource/) — looks up via `SkipManagerResourceId` - [SalaryStructure](/docs/reference/entities/salary-structure/) — looks up via `SalaryStructureId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ManagerResourceId` - [Resource](/docs/reference/entities/resource/) — looks up via `ParentResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `UserId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Branch](/docs/reference/entities/branch/) — looks up via `DefaultBranchId` - [Account](/docs/reference/entities/account/) — looks up via `DefaultPartnerAccountId` - [ResourceGroup](/docs/reference/entities/resource-group/) — looks up via `IncentiveResourceGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [BusinessHours](/docs/reference/entities/business-hours/) — looks up via `BusinessHoursId` - [Resource](/docs/reference/entities/resource/) — referenced by via `SkipManagerResourceId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `ServiceAdvisorId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `AllocatedByResourceId` - [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) — referenced by via `ResourceId` - [CompanyCard](/docs/reference/entities/company-card/) — referenced by via `AssignedResourceId` - [VisitPlan](/docs/reference/entities/visit-plan/) — referenced by via `ExecutedByResourceId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `PickedByResourceId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `DeliveryDoneByResourceId` - [ExpenseReimbursementBatchLine](/docs/reference/entities/expense-reimbursement-batch-line/) — referenced by via `ResourceId` - [PayrollPaymentBatchLine](/docs/reference/entities/payroll-payment-batch-line/) — referenced by via `ResourceId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `SalesExecutiveResourceId` - [ResourceAvailability](/docs/reference/entities/resource-availability/) — referenced by via `ResourceId` - [Resource](/docs/reference/entities/resource/) — referenced by via `ManagerResourceId` - [PartnerResource](/docs/reference/entities/partner-resource/) — referenced by via `ManagerResourceId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `TechnicianId` - [ServiceOrderTimeSheetLine](/docs/reference/entities/service-order-time-sheet-line/) — referenced by via `ResourceId` - [Resource](/docs/reference/entities/resource/) — referenced by via `ParentResourceId` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `ResourceId` - [AutoOrder](/docs/reference/entities/auto-order/) — referenced by via `ResourceId` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `ReceivedResourceId` - [ResourceLeave](/docs/reference/entities/resource-leave/) — referenced by via `ResourceId` - [PMTask](/docs/reference/entities/pmtask/) — referenced by via `TechnicianId` - [Quote](/docs/reference/entities/quote/) — referenced by via `ServiceAdvisorId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `ResourceId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — referenced by via `AllocatedResourceId` - [Requisition](/docs/reference/entities/requisition/) — referenced by via `ResourceId` - [LoanAdvanceRecovery](/docs/reference/entities/loan-advance-recovery/) — referenced by via `ResourceId` - [Case](/docs/reference/entities/case/) — referenced by via `ResourceId` - [PayrollRunDetail](/docs/reference/entities/payroll-run-detail/) — referenced by via `ResourceId` - [Payslip](/docs/reference/entities/payslip/) — referenced by via `ResourceId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `TechnicianId` - [CycleCountLine](/docs/reference/entities/cycle-count-line/) — referenced by via `CountedByResourceId` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `TransferredByResourceId` - [ExecutivePosition](/docs/reference/entities/executive-position/) — referenced by via `ExecutiveResourceId` - [VisitRoute](/docs/reference/entities/visit-route/) — referenced by via `ResourceId` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — referenced by via `ResourceId` - [VisitPlan](/docs/reference/entities/visit-plan/) — referenced by via `AssignedToResourceId` - [LeaveEntitlement](/docs/reference/entities/leave-entitlement/) — referenced by via `ResourceId` - [Adjustment](/docs/reference/entities/adjustment/) — referenced by via `ResourceId` - [Employee](/docs/reference/entities/employee/) — referenced by via `ResourceId` - [Shipment](/docs/reference/entities/shipment/) — referenced by via `ResourceId` - [PayrollAdjustment](/docs/reference/entities/payroll-adjustment/) — referenced by via `ResourceId` - [CycleCount](/docs/reference/entities/cycle-count/) — referenced by via `AssignedToResourceId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — referenced by via `ResourceId` - [CheckInInspection](/docs/reference/entities/check-in-inspection/) — referenced by via `ServiceAdvisorId` - [MonthlyTdsProjection](/docs/reference/entities/monthly-tds-projection/) — referenced by via `ResourceId` - [PayrollRunComponentLine](/docs/reference/entities/payroll-run-component-line/) — referenced by via `ResourceId` - [ResourceGroupMember](/docs/reference/entities/resource-group-member/) — referenced by via `ResourceId` - [IncentiveResource](/docs/reference/entities/incentive-resource/) — referenced by via `ResourceId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `ExecutiveResourceId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `ExecutiveResourceId` - [PartnerResource](/docs/reference/entities/partner-resource/) — referenced by via `ResourceId` - [ResourceAvailabilityData](/docs/reference/entities/resource-availability-data/) — referenced by via `ResourceId` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — referenced by via `ResourceId` - [Lead](/docs/reference/entities/lead/) — referenced by via `ResourceId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `ServiceResourceId` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `ResourceId` - [VisitRouteGroup](/docs/reference/entities/visit-route-group/) — referenced by via `ResourceId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `ServiceAdvisorId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `PickUpAssignedToId` - [LeaveRequest](/docs/reference/entities/leave-request/) — referenced by via `ResourceId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `ResourceId` - [KPIData](/docs/reference/entities/kpidata/) — referenced by via `ResourceId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ResourceId` - [KYCDocument](/docs/reference/entities/kycdocument/) — referenced by via `ResourceId` - [CycleCount](/docs/reference/entities/cycle-count/) — referenced by via `ResourceId` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `ExecutiveResourceId` - [ServiceOrderTimeSheet](/docs/reference/entities/service-order-time-sheet/) — referenced by via `ResourceId` - [ResourceBusinessHours](/docs/reference/entities/resource-business-hours/) — referenced by via `ResourceId` - [Bill](/docs/reference/entities/bill/) — referenced by via `ResourceId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `ResourceId` - [Order](/docs/reference/entities/order/) — referenced by via `ExecutiveId` - [TaxDeclaration](/docs/reference/entities/tax-declaration/) — referenced by via `ResourceId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `ResourceId` - [RouteSequence](/docs/reference/entities/route-sequence/) — referenced by via `ResourceId` - [ResourceCompensation](/docs/reference/entities/resource-compensation/) — referenced by via `ResourceId` - [TdsCertificate](/docs/reference/entities/tds-certificate/) — referenced by via `ResourceId` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `ResourceId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Revenue Recognition Schedule Line — entity reference URL: https://xmatix.com/docs/reference/entities/revenue-recognition-schedule-line/ Last reviewed: 2026-08-16 One period's slice of a revenue-recognition schedule: the amount planned for release, the amount actually recognized, and the journal that posted it. The background sweep picks up lines whose date has arrived while the parent schedule is still active, and posting is safe to retry because a line that already carries a journal or has left the pending state is skipped. The schedule's recognized-to-date total is summed from these lines, which is what keeps the deferred balance tied to the ledger. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FiscalPeriodId` | Fiscal Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | | | | `Id` | Id | Guid | Yes | | | `JournalId` | Journal | Lookup → [Journal](/docs/reference/entities/journal/) | | The recognition journal that posted this line. It doubles as a re-delivery guard: a line already carrying a journal is skipped when the background job runs again, which is what makes the sweep safe to retry. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PeriodDate` | Period Date | DateAndTime | | The date the release falls due. The background sweep compares this against the current date, so it, rather than any linked fiscal period, is what actually triggers recognition. | | `PeriodNumber` | Period Number | Number | | The line's position in the release sequence, starting at one. It orders the schedule internally and is not a fiscal period number, so it should not be matched against the accounting calendar. | | `RecognizedAmount` | Recognized Amount | Currency | | The amount actually released once the line posted. Only lines that reached the recognized state contribute to the parent schedule's recognized total. | | `RecognizedDate` | Recognized Date | DateAndTime | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ScheduledAmount` | Scheduled Amount | Currency | | The amount planned for release in this period. On a straight-line plan every line is equal except the final one, which carries the rounding remainder so the schedule totals exactly. | | `ScheduleId` | Schedule | Lookup → [RevenueRecognitionSchedule](/docs/reference/entities/revenue-recognition-schedule/) | | | | `Status` | Status | Text | | Either Pending or Recognized. An unset value is treated as Pending by the background sweep, so a line with no status is still picked up rather than being stranded unposted. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `FiscalPeriodId` - [RevenueRecognitionSchedule](/docs/reference/entities/revenue-recognition-schedule/) — looks up via `ScheduleId` - [Journal](/docs/reference/entities/journal/) — looks up via `JournalId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Revenue Recognition Schedule — entity reference URL: https://xmatix.com/docs/reference/entities/revenue-recognition-schedule/ Last reviewed: 2026-08-16 A deferred-revenue plan for one source document: the billed total is parked in a deferred-revenue liability account and released to income across the recognition window. The schedule owns one line per period, and a straight-line plan divides the total evenly while pushing the rounding remainder onto the final period so the lines always sum back to the exact total. A background scheduler sweeps active schedules for lines that have come due and posts each release, so recognition advances without anyone opening the record. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeferredGLAccountId` | Deferred GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The liability account holding the not-yet-earned balance. Each recognition release debits it, drawing the deferred balance down toward zero. | | `DocumentNumber` | Document Number | Text | | | | `EndDate` | End Date | DateAndTime | | | | `Id` | Id | Guid | Yes | | | `Method` | Method | Text | | Either StraightLine or Milestone. Only the straight-line plan is generated by the platform, dividing the total evenly and placing the rounding remainder on the last period, so a milestone schedule's lines must be supplied from elsewhere rather than expected automatically. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NumberOfPeriods` | Number Of Periods | Number | | How many periods the release is spread over, which must be at least one. It drives how many lines a straight-line plan creates, stepping one month at a time from the start date. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyAccountId` | Party Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecognizedAmount` | Recognized Amount | Currency | | The amount released to income so far. Treat the stored value as a rollup that can lag: the authoritative figure is summed from the lines that actually posted, and it is that sum which ties back to the ledger. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RevenueGLAccountId` | Revenue GL Account | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | The income account each recognition release credits as revenue is earned, forming the other leg against the deferred liability. | | `SourceEntityName` | Source Entity Name | Text | | The name of the entity the schedule was raised from, such as an invoice or a contract line, paired with the record identifier alongside it. It is a loose polymorphic link stored as text rather than a foreign key, so nothing at the database level guarantees the referenced record still exists. | | `SourceRecordId` | Source Record | Guid | | The identifier of the originating record inside the entity named on the same row. Because the pair is polymorphic, always resolve it through that entity name instead of assuming a single target table. | | `StartDate` | Start Date | DateAndTime | | | | `Status` | Status | Text | | One of Active, Completed or Cancelled. The background sweep only picks up lines whose schedule is Active or has no status set at all, so moving a schedule off Active is what halts further automatic recognition. | | `TotalAmount` | Total Amount | Currency | | The full billed amount to be released across the window. It is the target the generated lines must sum back to exactly, which is precisely why rounding is absorbed by the final period rather than spread. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRow` | EditRow | Edit | EditRow | | `New` | New | New | New | ## Related entities - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `RevenueGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `DeferredGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` - [RevenueRecognitionScheduleLine](/docs/reference/entities/revenue-recognition-schedule-line/) — referenced by via `ScheduleId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Route Sequence Entry — entity reference URL: https://xmatix.com/docs/reference/entities/route-sequence-entry/ Last reviewed: 2026-08-16 One line of a RouteSequence run: the rank a route stop (visitRouteStopId) takes in that ordering, with an optional confidence score for history-derived runs. Ranks are 1-based within the run. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Rank` | Rank | Number | | 1-based position of the stop in this run's ordering. | | `RouteSequenceId` | Route Sequence | Lookup → [RouteSequence](/docs/reference/entities/route-sequence/) | | | | `Score` | Score | Number | | Optional confidence/support metric for the rank - 0 to 1 for history-derived runs, indicating how consistently past visits support this position. | | `VisitRouteStopId` | Route Stop | Lookup → [VisitRouteStop](/docs/reference/entities/visit-route-stop/) | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditHeader` | Edit | Edit | EditHeader | | `EditRow` | Edit | Edit | EditRow | | `NewHeader` | New | New | NewHeader | ## Related entities - [RouteSequence](/docs/reference/entities/route-sequence/) — looks up via `RouteSequenceId` - [VisitRouteStop](/docs/reference/entities/visit-route-stop/) — looks up via `VisitRouteStopId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Route Sequence — entity reference URL: https://xmatix.com/docs/reference/entities/route-sequence/ Last reviewed: 2026-08-16 A versioned, named ordering of a Visit Route's stops - the source of record behind the per-visit sequence snapshots (Visit plannedSequence/optimizedSequence/mostlyFollowedSequence). Every optimization run or history refresh appends a new header plus RouteSequenceEntry lines and flips isCurrent within its (route, type, resource) family, so runs stay comparable and auditable. resourceId scopes a salesperson-specific variant (their personally followed order on the beat); null means route-generic. The planner copies the current sequences onto a plan's visits at creation, and a background maintenance job keeps them fresh as visit history accrues. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Algorithm` | Algorithm | MultiLineText | | Producer of the run - for example NearestNeighbour for the free geo pass, a routing-provider name for paid road-network runs, History for mostly-followed refreshes, Manual for hand-built orders. | | `ComputedDateTime` | Computed On | Date | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `EstDurationMins` | Est. Duration (min) | Number | | | | `Id` | Id | Guid | Yes | | | `IsCurrent` | Is Current | Boolean | | Marks the active run within its (route, type, resource) family. Runs are append-only: a new run or the Activate action flips this flag rather than editing old rows, so the full history stays auditable. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Salesperson | Lookup → [Resource](/docs/reference/entities/resource/) | | Scopes a salesperson-specific run (their personal mostly-followed order on the beat); null = route-generic. When the planner stamps visits, a current run matching the plan's assignee wins over the route-generic one. | | `SequenceType` | Sequence Type | PickList | | Which ordering family the run belongs to: Planned, Optimized, MostlyFollowed or Custom. The planner copies the current Optimized and MostlyFollowed runs onto a plan's visits at creation. Values: Planned, Optimized, Mostly Followed, Custom. | | `StopsResequenced` | Stops Resequenced | Number | | How many stops this ordering moves off their authored (planned) position - a quick signal of how different the run is from the beat as drawn. | | `TotalDistanceKm` | Total Distance (km) | Number | | | | `VisitRouteId` | Visit Route | Lookup → [VisitRoute](/docs/reference/entities/visit-route/) | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `ActivateRouteSequence` | Activate | ServerAction (`ActivateRouteSequence`) | Makes this run the current one within its (route, type, resource) family by flipping isCurrent flags only - runs are append-only and no ordering data changes. Future plans of the route are cut with this ordering; existing plans keep theirs unless ApplySequenceToPlan is used. | | `ActivateRouteSequenceRow` | Activate | ServerAction (`ActivateRouteSequence`) | List-row variant of the activate flow: same behavior as ActivateRouteSequence (flips isCurrent within the run's family; append-only history is preserved), exposed on each row of the sequence list. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Related entities - [VisitRoute](/docs/reference/entities/visit-route/) — looks up via `VisitRouteId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [RouteSequenceEntry](/docs/reference/entities/route-sequence-entry/) — referenced by via `RouteSequenceId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Salary Component — entity reference URL: https://xmatix.com/docs/reference/entities/salary-component/ Last reviewed: 2026-08-16 One line of a SalaryStructure: which component is paid, how its amount is derived, and in what order. Evaluation order is Sequence, and that order is semantically load-bearing — dependent Percentage components resolve their basis only from components already computed earlier in the sequence, and slab-based professional tax is matched against the gross accumulated so far, so re-ordering lines changes the numbers. This entity spans two generations of modelling: PayrollComponentId points at the reusable PayrollComponent master whose ComponentType, StatutoryType, Taxability, IsProratable, SortOrder and GL accounts take precedence, while the older self-describing fields (ComponentType, StatutoryFlag, Taxable, Prorata) apply only when no master is linked. CalculationType, Value, PercentageOf and IsPercentageofCTC drive the amount; MinAmount and MaxAmount clamp it after computation and before proration. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CalculationType` | Calculation Type | PickList | | How this line's amount is derived. Fixed uses Value directly. Percentage uses Value as a percentage of CTC (when IsPercentageofCTC) or of another component named by PercentageOf. Slab is meaningful only for professional tax, where it makes the engine resolve the amount from the state slab table instead of the line. The seeded picklist offers Fixed, Percentage and Formula only — so the unimplemented option is offered while Slab, the one that changes behaviour, has to be entered outside the list. Values: Fixed, Formula, Percentage, Slab, Manual. | | `ComponentName` | Component Name | Text | | The line's own name, and more than a label: it is the key other lines reference through PercentageOf, matched case-insensitively. When blank the line's Label, and failing that its id, is used as the key instead. | | `ComponentType` | Component Type | PickList | | Which bucket the amount lands in: Earning and Reimbursement add to gross, Deduction reduces net, EmployerContribution accumulates separately and does not affect net pay. Used only when no PayrollComponent master is linked — the master's ComponentType wins. The seeded picklist offers only Earning and Deduction, so EmployerContribution and Reimbursement, both of which the calculation handles, cannot be chosen from the standard list. Values: Earning, Deduction, EmployerContribution, Reimbursement. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EffectiveFrom` | Effective From | Date | | Intended start of this line's validity, but the payroll calculation does not filter lines by date — it takes every active line of the structure regardless of effective dating. Treat it as documentation of intent rather than as a control that keeps a line out of a run. | | `EffectiveTo` | Effective To | Date | | Intended end of this line's validity. As with EffectiveFrom, the payroll calculation ignores it: an expired line still contributes to the payslip until it is set inactive or deleted. | | `EmployeeId` | Employee | Lookup → [Employee](/docs/reference/entities/employee/) | | | | `Formula` | Formula | Text | | Free-text expression for a formula-driven component. A populated Formula never changes a calculated amount. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | The only gate the payroll run applies when loading a structure's lines besides deletion: a line set inactive is excluded from the calculation. | | `IsPercentageofCTC` | Is Percentage of CTC | Boolean | | | | `MaxAmount` | Max Amount | Currency | | | | `MinAmount` | Min Amount | Currency | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PayrollComponentId` | Payroll Component | Lookup → [PayrollComponent](/docs/reference/entities/payroll-component/) | | | | `PercentageOf` | Percentage Of | PickList | | For a Percentage line not based on CTC, the NAME of the component supplying the basis, matched case-insensitively against components already computed earlier in the structure's Sequence. Two silent failure modes: a name that matches nothing yields zero rather than an error, and a component appearing later in the sequence is not yet available so it also yields zero. The basis used is the full un-prorated amount. The seeded picklist offers Basic, CTC and Taxable Income, but only values that are literally the name of another component in the same structure resolve — percentage-of-CTC is driven by the separate IsPercentageofCTC flag, not by choosing CTC here. Values: Basic, CTC, Taxable Income. | | `Prorata` | Pro-rata | Boolean | | Legacy per-line proration flag, used only when no PayrollComponent master is linked (the master's IsProratable wins). When set and the period has loss-of-pay days, the amount is scaled by payable days over total calendar days; the shortfall on Earning and Reimbursement lines accumulates as the payslip's loss-of-pay amount. Proration happens AFTER the min/max clamp, and dependent percentage lines still use the full un-prorated basis. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SalaryStructureId` | Salary Structure | Lookup → [SalaryStructure](/docs/reference/entities/salary-structure/) | | The structure this line belongs to. The payroll run loads lines by this key filtered only on not-deleted and IsActive, ordered by Sequence — so a line belongs to exactly one structure and is picked up by every employee assigned that structure. | | `Sequence` | Sequence | Number | | | | `StatutoryFlag` | Statutory Flag | PickList | | Legacy per-line statutory nature, used only when no PayrollComponent master is linked — the master's StatutoryType wins otherwise. Two behaviours depend on it exactly: PT combined with CalculationType Slab makes the engine resolve professional tax from the state slab table, and TDS makes the line take its amount from the month's TDS projection. The seeded picklist offers None, PF, ESI and TDS, which omits PT and LWF and offers None; PT is the value that actually changes the calculation, and any non-blank value here — None included — marks the resulting line as statutory. Values: None, PF, ESI, TDS, PT, LWF, Gratuity. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `Taxable` | Taxable | Boolean | | Legacy per-line taxability, copied onto the calculated component line only when no PayrollComponent master is linked; with a master, taxability is derived from its Taxability value being Taxable. It records the flag on the payslip line and does not itself feed the TDS projection, which works from projected gross rather than from per-component taxability. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `Value` | Value | Number | | The line's numeric input, read differently depending on CalculationType: an absolute amount for Fixed (and for the unevaluated Formula and Manual), or a percentage figure for Percentage. It is not the computed amount — the result after basis, floor, ceiling and proration lands on the run's component line, not here. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | EditInline | Edit | | `EditInRow` | Edit | Edit | Edit | | `New` | New | New | New | | `NewInline` | New | NewInline | New | ## Related entities - [Employee](/docs/reference/entities/employee/) — looks up via `EmployeeId` - [SalaryStructure](/docs/reference/entities/salary-structure/) — looks up via `SalaryStructureId` - [Employee](/docs/reference/entities/employee/) — referenced by via `SalaryComponentId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Salary Structure — entity reference URL: https://xmatix.com/docs/reference/entities/salary-structure/ Last reviewed: 2026-08-16 A named salary template — an ordered set of SalaryComponent lines that together define how an employee's pay is composed. It is assigned to a person through ResourceCompensation (which also carries the CTC that percentage-of-CTC components are computed against), and the payroll calculation resolves the structure from the employee's most recent active ResourceCompensation, NOT from Resource.SalaryStructureId. An employee with no active ResourceCompensation pointing at a structure, or whose structure has no active lines, is counted as skipped by the run rather than failing it. Unlike the statutory rule masters this entity has no PartnerAccountId column, so a structure is tenant-wide rather than scoped to a legal entity. EffectiveFrom and IsActive describe the template's own validity, and neither is applied as a filter when the run loads the structure's lines. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | Structures are not scoped to a business unit — or to a legal entity at all. Do not filter or join on this field. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EffectiveFrom` | Effective From | Date | Yes | Intended start of the template's validity. The run resolves the structure through the employee's most recent active ResourceCompensation and does not compare this date to the payroll period, so it does not by itself prevent an unstarted structure from being used. | | `EmployeeId` | Employee | Lookup → [Employee](/docs/reference/entities/employee/) | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | Marks the template as usable. Note the payroll run filters on the ResourceCompensation being active, not on this flag, so deactivating a structure does not on its own stop employees whose compensation still points at it from being calculated. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PayFrequency` | Pay Frequency | PickList | Yes | Intended pay cadence of the template. Nothing in the payroll calculation reads it: the period and its day count come from PayrollPeriod's start and end dates, so setting this does not change how amounts are computed or prorated. The seeded picklist offers Monthly only. Values: Monthly, Weekly, Biweekly, Daily. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `StructureName` | Structure Name | Text, unique | Yes | The human-facing name of the template, separate from the record's system Name. Nothing in the calculation keys off it — component lines reference their structure by id — so it is descriptive only. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Deleteentity` | Delete | Delete | Delete | | `DeleteHeader` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Related entities - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [Employee](/docs/reference/entities/employee/) — looks up via `EmployeeId` - [Resource](/docs/reference/entities/resource/) — referenced by via `SalaryStructureId` - [Employee](/docs/reference/entities/employee/) — referenced by via `SalaryStructureId` - [SalaryComponent](/docs/reference/entities/salary-component/) — referenced by via `SalaryStructureId` - [ResourceCompensation](/docs/reference/entities/resource-compensation/) — referenced by via `SalaryStructureId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Salary Tax Slab — entity reference URL: https://xmatix.com/docs/reference/entities/salary-tax-slab/ Last reviewed: 2026-08-16 An income-tax slab band for salary TDS: a marginal rate over an income band, scoped by regime, financial year and age band. It is consumed by the salary-TDS projection, not by the payroll calculation directly, and the tax is progressive — each band's rate applies only to the slice of income falling inside it. AgeBand differentiates only the Old regime (General under 60, Senior 60-79, SuperSenior 80+); the New regime has a single band set seeded as General, and null is treated as General. Rows with a null PartnerAccountId apply to every legal entity, so a tenant can ship one shared rate pack and override per company only where it genuinely differs. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AgeBand` | Age Band | PickList | | Old-regime slab category: General (under 60) / Senior (60-79) / SuperSenior (80+). Blank is read as General. Values: General (under 60), Senior citizen (60-79), Super senior citizen (80+). | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FinancialYear` | Financial Year | Text | | Indian financial year label in the form 2026-27, derived by the projection from the payroll period's end date with the year starting on 1 April. A null value makes the row apply to every year, which is rarely intended for rate bands. | | `FromIncome` | From Income | Currency | | The bottom of the band. Tax is progressive: only the slice of taxable income above this figure and below ToIncome is charged at this row's Rate, so the exemption limit is expressed as a first band with a zero rate rather than as a separate setting. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | Excludes the band from the rate pack when false. Because the pack is assembled from whatever rows match, deactivating a middle band does not shift the others — it leaves an untaxed gap in the schedule. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The legal entity this band belongs to. Null means the row applies to every company in the tenant, which is how a shared statutory rate pack is shipped once and overridden only where a company genuinely differs. | | `Rate` | Rate | Currency | | The marginal percentage charged on the portion of taxable income inside this band, entered as a percentage figure (5 means 5%). It is not an effective rate on total income. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Regime` | Regime | PickList | | Old or New, matching the platform's regime constants exactly. The projection resolves a separate slab set per regime and computes both, so a mis-typed value quietly removes bands from one regime's rate pack rather than raising an error. A null value makes the row apply to whichever regime is being computed. Values: Old Regime, New Regime. | | `ToIncome` | To Income | Currency | | The top of the band; leave it null for the open-ended highest band. Gaps or overlaps between rows are not validated — income falling in a gap is simply untaxed and an overlap is charged twice. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this SalaryTaxSlab. | | `DeleteBulk` | Delete | Delete | DeleteBulk | | `Edit` | Edit | Edit | Edit this SalaryTaxSlab. | | `EditInLine` | Edit | EditInline | Edit | | `New` | New | New | Create a SalaryTaxSlab. | | `View` | View | View | View this SalaryTaxSlab. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Scheme Account Budget Utilisation — entity reference URL: https://xmatix.com/docs/reference/entities/scheme-account-budget-utilization/ Last reviewed: 2026-08-16 One draw against a SchemeAccountBudget, keyed per invoice line (invoiceId/invoiceLineId) with the consumed amount and links back to the scheme and the SchemeLedger row it came from. Written by the budget service when invoice-related ledger rows are inserted or their discount figures change. Only invoices create utilization rows - the invoice is the consumption of record, which avoids double-counting the same sale at order and invoice stage. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `InvoiceId` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | | | `InvoiceLineId` | Invoice Line | Lookup → [InvoiceLine](/docs/reference/entities/invoice-line/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SchemeAccountBudgetId` | Scheme Account Budget | Lookup → [SchemeAccountBudget](/docs/reference/entities/scheme-account-budget/) | | | | `SchemeId` | Scheme | Lookup → [Scheme](/docs/reference/entities/scheme/) | | | | `SchemeLedgerId` | Scheme Ledger | Lookup → [SchemeLedger](/docs/reference/entities/scheme-ledger/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete | Delete | DeleteListHeader | | `DeleteListRow` | Delete | Delete | DeleteListRow | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [InvoiceLine](/docs/reference/entities/invoice-line/) — looks up via `InvoiceLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — looks up via `SchemeLedgerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [SchemeAccountBudget](/docs/reference/entities/scheme-account-budget/) — looks up via `SchemeAccountBudgetId` - [Scheme](/docs/reference/entities/scheme/) — looks up via `SchemeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Scheme Account Budget — entity reference URL: https://xmatix.com/docs/reference/entities/scheme-account-budget/ Last reviewed: 2026-08-16 A spend cap for a Scheme (schemeId), in currency. A row with neither partnerAccountId nor partnerAccountGroupId is the scheme-wide (global) budget; a row with one of them caps spend for that partner or partner group. Enforcement reads live SchemeLedger consumption (netSchemeDiscount2 sums), not the stored columns. Budget configuration also gates where discounts land: a Sale Invoice only carries a scheme discount when the scheme has BOTH a global and a partner-scoped budget (unless the scheme sets ignoreBudget); incomplete configurations still apply on the Sale Order, which is a projection stage rather than the consumption of record. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BudgetAmount` | Budget Amount | Currency | | | | `BudgetAvailable` | Budget Available | Calculated (calculated) | | Display-only remainder (budgetAmount minus utilization, clamped at zero) refreshed from live SchemeLedger consumption. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountGroupId` | Partner Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Scopes the budget to one partner account. A row with neither PartnerAccountId nor PartnerAccountGroupId is the scheme-wide global budget; the Sale Invoice both-tiers rule requires one global and one partner-scoped row to exist. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SchemeId` | Scheme | Lookup → [Scheme](/docs/reference/entities/scheme/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UtilisedAmount` | Utilised Amount | Calculated (calculated) | | | | `UtilizedAmount` | Utilized Amount | Calculated (calculated) | | Display-only consumption figure recomputed from live SchemeLedger netSchemeDiscount2 sums scoped to this budget's partner account or group; enforcement reads the ledger directly. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete | Delete | DeleteListHeader | | `DeleteListRow` | Delete | Delete | DeleteListRow | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Available Budget Needs To Be Positive | Error | Scheme Budget Exceeded! | Ensures available budget is not negative unless the scheme ignores budget | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `PartnerAccountGroupId` - [Scheme](/docs/reference/entities/scheme/) — looks up via `SchemeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [SchemeAccountBudgetUtilization](/docs/reference/entities/scheme-account-budget-utilization/) — referenced by via `SchemeAccountBudgetId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Scheme Benefit — entity reference URL: https://xmatix.com/docs/reference/entities/scheme-benefit/ Last reviewed: 2026-08-16 One grant under a Scheme Slab (schemeLineId): rewardType selects the mechanics - Line Level Discount Percentage, Line Level Discount Amount, Discounted Item (a free or discounted item line for discountedItemId), Discounted Item Group (pick from discountedItemGroupId) or Reward Points. Free-item benefits either discount matching existing lines or insert new document lines flagged IsSchemeGenerated. When a slab has several benefits, the slab's rewardApplicability decides whether all apply, only the lowest- or highest-value one, or a custom-logic group. The engine copies limitExpiryDays onto the benefiting document lines. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ApplyDiscountOnMRP` | Apply Discount On MRP | Boolean | Yes | | | `ConversionRatio` | Conversion Ratio | Number | | | | `ConversionRatio1` | Conversion Ratio 1 | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DiscountAmount` | Discount Amount | Number | | | | `DiscountedItemGroupId` | Discounted Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | | | `DiscountedItemId` | Discounted Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `DiscountedItemLotTypeId` | Discounted Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `DiscountedItemQuantity` | Discounted Item Quantity | Number | | How many units of the discounted/free item one qualification grants; multiplied by the qualification count when RepeatReward or RepeatRewardsInRatio is on. | | `DiscountedItemRanking` | Discounted Item Ranking | PickList | | When several document lines are candidates for the discount, pick them ordered High To Low or Low To High by line value. Values: High To Low, Low To High. | | `DiscountedItemSKUId` | Discounted SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `DiscountedSKUId` | Discounted SKU | Lookup → [SKU](/docs/reference/entities/sku/), hidden, inactive | | | | `DiscountPercent` | Discount Percent | Percent | | | | `ExcludeDiscountedItemGroupId` | Exclude Discounted Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | Lines whose item belongs to this group are never chosen as the discounted line, even if they match the discounted item/group. | | `ExcludeQualifyingItems` | Exclude Qualifying Items | Boolean | Yes | When choosing which document lines receive the discounted-item benefit, skip the lines that themselves qualified the condition - the reward must land on other lines. | | `Id` | Id | Guid | Yes | | | `LimitExpiryDays` | Limit Expiry Days | Number | | Copied by the engine onto the document lines that receive this benefit (their LimitExpiryDays field); carries a validity horizon for the granted benefit. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecommendationText` | Recommendation Text | LongMultiLineText | | Marketing-style text shown with the scheme recommendation in the UI (product catalogue and recommendation widget); no effect on qualification or application. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RepeatReward` | Repeat Reward | Boolean | Yes | Grant the benefit once per qualification count (floor of reached over threshold) instead of once per document. See also RepeatRewardsInRatio, which scales by the achievement ratio instead. | | `RepeatRewardForEveryQualification` | Repeat Reward For Every Qualification | Boolean | | | | `RepeatRewardsInRatio` | Repeat Rewards In Ratio | Boolean | Yes | Scale the reward by the target-to-achievement ratio rather than the whole-number qualification count - takes precedence over RepeatReward when both are set. | | `RewardMultiplier` | Reward Multiplier | PickList | | For repeatable rewards, whether the multiplier is derived from Amount or from Quantity of the qualifying lines. Values: Amount. | | `RewardPoints` | Reward Points | Number | | Points granted when RewardType is Reward Points: stamped onto the document's non-generated lines as SchemeRewardPoints and mirrored into SchemeLedger.rewardPoints. | | `RewardType` | Reward Type | PickList | Yes | Mechanics of the grant: Line Level Discount Percentage (DiscountPercent off qualifying lines), Line Level Discount Amount (DiscountAmount), Discounted Item (free or discounted line for DiscountedItemId), Discounted Item Group (candidates from DiscountedItemGroupId), or Reward Points (stamps RewardPoints onto document lines and the SchemeLedger). Values: Line Level Discount Percentage, Line Level Discount Amount, Discounted Item, Discounted Item Group, Reward Points. | | `SchemeId` | Scheme | Lookup → [Scheme](/docs/reference/entities/scheme/) | | | | `SchemeLineId` | Scheme Slab | Lookup → [SchemeLine](/docs/reference/entities/scheme-line/) | | | | `SequenceNumber` | Sequence Number | Number | Yes | | | `Title` | Title | Text | | | | `UIProps` | UI Props | Text | | | | `UOM` | UOM | PickList | | Values: Pack, Each. | | `UOM1` | UOM 1 | PickList | | Values: Pack, Each. | | `UOMQuantity` | UOM Quantity | Number | | | | `UOMQuantity1` | UOM Quantity 1 | Number | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `ValidFrom` | Val From | Date | | | | `ValidTo` | Val To | Date | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListRow` | Delete | Delete | DeleteListRow | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Scheme for Scheme Slab | `SchemeLineId` | | ## Related entities - [SchemeLine](/docs/reference/entities/scheme-line/) — looks up via `SchemeLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `DiscountedItemGroupId` - [Item](/docs/reference/entities/item/) — looks up via `DiscountedItemId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `DiscountedItemLotTypeId` - [SKU](/docs/reference/entities/sku/) — looks up via `DiscountedSKUId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ExcludeDiscountedItemGroupId` - [Scheme](/docs/reference/entities/scheme/) — looks up via `SchemeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `SchemeBenefitId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `SchemeBenefitId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `SchemeBenefitId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `SchemeBenefitId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `SchemeBenefitId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `SchemeBenefitId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `SchemeBenefitId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `SchemeBenefitId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `BenefitId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Scheme Condition — entity reference URL: https://xmatix.com/docs/reference/entities/scheme-condition/ Last reviewed: 2026-08-16 One qualifying test under a Scheme Slab (schemeLineId): conditionType picks what is measured on the document or period (Quantity, Value, Value With Tax, Item Quantity/Value/Value With Tax against itemId, Item Group Quantity/Value/Value With Tax against itemGroupId, or Unique Item Count), conditionOperator compares it (Equal, Does Not Equal, Greater Than, Greater Than Or Equal, Less Than, Less Than Or Equal) with conditionQuantity or conditionValue as the threshold. For the Greater Than operators the engine also derives a qualification count (floor of reached/threshold), which drives repeatable rewards. Conditions carry their own validity window and account/account-group scoping that further narrows when they count. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `ConditionOperator` | Condition Operator | PickList | Yes | Comparison against the threshold: Equal, Does Not Equal, Greater Than, Greater Than Or Equal, Less Than, Less Than Or Equal. For the two Greater Than operators the engine also derives a qualification count of floor(reached/threshold), which multiplies repeatable rewards. Values: Equal, Does Not Equal, Greater Than, Greater Than Or Equal, Less Than, Less Than Or Equal. | | `ConditionQuantity` | Condition Quantity | Number | | Threshold for quantity-flavoured condition types (Quantity, Item Quantity, Item Group Quantity, Unique Item Count); value-flavoured types use ConditionValue instead. | | `ConditionType` | Condition Type | PickList | Yes | What the condition measures: Quantity, Value or Value With Tax over the whole document; Item Quantity, Item Value or Item Value With Tax scoped to ItemId; Item Group Quantity, Item Group Value or Item Group Value With Tax scoped to ItemGroupId; or Unique Item Count. Per Period schemes measure the same types over accumulated period totals instead of the single document. Values: Quantity, Value, Value With Tax, Item Quantity, Item Value, Item Value With Tax, Item Group Quantity, Item Group Value, Item Group Value With Tax, Unique Item Count. | | `ConditionValue` | Condition Value | Currency | | Currency threshold for value-flavoured condition types (Value, Value With Tax, Item Value, Item Group Value and their With Tax variants); quantity types use ConditionQuantity instead. | | `ConversionRatio` | Conversion Ratio | Number | | | | `ConversionRatio1` | Conversion Ratio 1 | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExcludeAccountGroupId` | Exclude Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | Documents whose account belongs to this group fail the condition's account scope - a customer carve-out. | | `ExcludeItemGroupId` | Exclude Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | Items belonging to this group are excluded from the condition's aggregation even when they match ItemId/ItemGroupId - a carve-out list for the qualification. | | `IAItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | | | `Id` | Id | Guid | Yes | | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RewardGroup` | Reward Group | Text | | | | `RoundOffConditionQuantity` | Round Off Condition Quantity | Boolean | Yes | When computing the target-to-achievement ratio, floor the reached value first - partial units do not count toward ratio-based repeat rewards. | | `SchemeId` | Scheme | Lookup → [Scheme](/docs/reference/entities/scheme/) | | | | `SchemeLineId` | Scheme Slab | Lookup → [SchemeLine](/docs/reference/entities/scheme-line/) | | | | `SequenceNumber` | Sequence Number | Number | Yes | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `Title` | Title | Text | | | | `UIProps` | UI Props | Text | | | | `UOM` | UOM | PickList | | Values: Pack, Each. | | `UOM1` | UOM 1 | PickList | | Values: Pack, Each. | | `UOMQuantity` | UOM Quantity | Number | | | | `UOMQuantity1` | UOM Quantity 1 | Number | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UseInRatioCalculation` | Use In Ratio Calculation | Boolean | Yes | Marks this condition as the one whose target-to-achievement ratio feeds ratio-based repeat rewards when the slab combines several conditions. | | `ValidFrom` | Val From | Date | | | | `ValidTo` | Val To | Date | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete | Delete | DeleteListHeader | | `DeleteListRow` | Delete | Delete | DeleteListRow | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Scheme for Scheme Condition | `SchemeLineId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ExcludeItemGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `ExcludeAccountGroupId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [SchemeLine](/docs/reference/entities/scheme-line/) — looks up via `SchemeLineId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` - [Scheme](/docs/reference/entities/scheme/) — looks up via `SchemeId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Scheme Consumption — entity reference URL: https://xmatix.com/docs/reference/entities/scheme-consumption/ Last reviewed: 2026-08-16 A summary of scheme benefit consumption per account/partner/branch/item or item group (consumedAmount, consumedQuantity). No first-party code writes this entity - it is classified as derived data (consumption is computed as benefits are drawn; SchemeLedger is the transactional record) and data sync refuses to import it. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `ConsumedAmount` | Consumed Amount | Currency | | | | `ConsumedQuantity` | Consumed Quantity | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SchemeName` | Scheme Name | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete | Delete | DeleteListHeader | | `DeleteListRow` | Delete | Delete | DeleteListRow | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [Scheme](/docs/reference/entities/scheme/) — looks up via `SchemeId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Scheme Ledger — entity reference URL: https://xmatix.com/docs/reference/entities/scheme-ledger/ Last reviewed: 2026-08-16 The applied-scheme record: one row per document line that has a scheme applied, mirrored from the line state by the scheme engine on every save (rows for lines that no longer carry a scheme are deleted). Links the scheme/slab/benefit to the exact document line across Orders, Invoices, Credit Notes, Purchase Orders, Bills and Service Orders. This ledger is the source of record for enforcement: validCount apply-count limits and scheme/partner budget utilization are computed from it live, and inserting/updating rows triggers the account-budget utilization upsert. Not user-maintained - it is derived from transactions, and data sync deliberately protects it from being imported. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `BillId` | Bill | Lookup → [Bill](/docs/reference/entities/bill/) | | | | `BillLineId` | Bill Line | Lookup → [BillLine](/docs/reference/entities/bill-line/) | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `Discount` | Discount | Percent | | The discount fraction copied from the document line's SchemeDiscount at sync time; the companion DiscountAmount carries the absolute amount and LineAmount the line's base amount. | | `DiscountAmount` | Discount Amount | Currency | | | | `Id` | Id | Guid | Yes | | | `InvoiceId` | Invoice | Lookup | | | | `InvoiceId (dup-d8cd9ff0)` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | | | `InvoiceLineId` | Invoice Line | Lookup → [InvoiceLine](/docs/reference/entities/invoice-line/) | | | | `InvoiceLineId (dup-39357cb8)` | Invoice Line | Lookup | | | | `IsClaimed` | Claimed | Boolean | Yes | Processed flag for the claim generation engine (same idiom as CreditNoteLine.IsClaimed): set once a claim has consumed this ledger row so it is not claimed twice. | | `LineAmount` | Line Amount | Currency | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | Yes | | | `NetSchemeDiscount2` | Net Scheme Discount | Currency | | The normalized currency value of the applied benefit for this line: the discount amount when one is set, otherwise line amount times discount percent. This is the figure budget utilization and the denormalized budget displays consume. | | `OpportunityId` | Opportunity | Lookup → [Opportunity](/docs/reference/entities/opportunity/) | | | | `OrderId` | Order | Lookup | | | | `OrderId (dup-30229b9d)` | Order | Lookup → [Order](/docs/reference/entities/order/) | | | | `OrderLineId` | Order Line | Lookup | | | | `OrderLineId (dup-ff82e134)` | Order Line | Lookup → [OrderLine](/docs/reference/entities/order-line/) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Partner dimension stamped at sync time; partner-scoped SchemeAccountBudget rows aggregate ledger consumption through this key. | | `PurchaseOrderId` | Purchase Order | Lookup → [PurchaseOrder](/docs/reference/entities/purchase-order/) | | | | `PurchaseOrderLineId` | Purchase Order Line | Lookup → [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) | | | | `QuoteId` | Quote | Lookup → [Quote](/docs/reference/entities/quote/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReturnId` | Sale Return | Lookup → Return | | | | `ReturnId (dup-175a25aa)` | Return | Lookup | | | | `ReturnLineId` | Return Line | Lookup | | | | `ReturnLineId (dup-43e8eca0)` | Sale Return Line | Lookup → ReturnLine | | | | `RewardPoints` | Reward Points | Number | | Reward points the applied benefit granted on this line, copied from the line's SchemeRewardPoints. | | `SchemeBenefitId` | Scheme Benefit | Lookup → [SchemeBenefit](/docs/reference/entities/scheme-benefit/) | | | | `SchemeId` | Scheme | Lookup → [Scheme](/docs/reference/entities/scheme/) | | | | `SchemeLineId` | Scheme Slab | Lookup → [SchemeLine](/docs/reference/entities/scheme-line/) | | | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | | | `ServiceOrderId (dup-3b855515)` | Service Order | Lookup | | | | `ServiceOrderLineId` | Service Order Line | Lookup | | | | `ServiceOrderLineId (dup-88cc914f)` | Service Order Line | Lookup → [ServiceOrderLine](/docs/reference/entities/service-order-line/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Quote](/docs/reference/entities/quote/) — looks up via `QuoteId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — looks up via `PurchaseOrderId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — looks up via `PurchaseOrderLineId` - [OrderLine](/docs/reference/entities/order-line/) — looks up via `OrderLineId` - [Opportunity](/docs/reference/entities/opportunity/) — looks up via `OpportunityId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [SchemeLine](/docs/reference/entities/scheme-line/) — looks up via `SchemeLineId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Bill](/docs/reference/entities/bill/) — looks up via `BillId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — looks up via `ServiceOrderLineId` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [BillLine](/docs/reference/entities/bill-line/) — looks up via `BillLineId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — looks up via `SchemeBenefitId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — looks up via `InvoiceLineId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `SchemeLedgerId` - [SchemeAccountBudgetUtilization](/docs/reference/entities/scheme-account-budget-utilization/) — referenced by via `SchemeLedgerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Scheme Slab — entity reference URL: https://xmatix.com/docs/reference/entities/scheme-line/ Last reviewed: 2026-08-16 One slab of a Scheme (schemeId): a unit of qualification pairing child SchemeCondition rows (the tests) with child SchemeBenefit rows (the grants). definitionFilterCriteria decides how the conditions combine and rewardApplicability decides which of the qualifying benefits are granted; both have Custom Logic variants driven by expressions like {1} AND ({2} OR {3}) stored in definitionCustomLogic/rewardCustomLogic. Slabs are evaluated in absoluteSequenceNumber then sequenceNumber order. When a slab applies to a document, the document lines that received the discount or free item point back via their schemeLineId, and a SchemeLedger row is written per applied line. Despite the entity name, the display label is Scheme Slab. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AbsoluteSequenceNumber` | Absolute Sequence Number | Calculated | | Primary ordering key for slab evaluation across schemes (slabs sort by this, then by SequenceNumber). | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DefinitionCustomLogic` | Definition Custom Logic | Text | | Boolean expression over condition ordinals, for example {1} AND ({2} OR {3}), used only when DefinitionFilterCriteria is Custom Logic Is Met. Each {N} refers to the Nth condition by sequence. | | `DefinitionFilterCriteria` | Definition Filter Criteria | PickList | Yes | How this slab's conditions combine: Always (No Criteria) auto-qualifies, All Conditions Are Met is an AND, Any Condition Is Met is an OR, Custom Logic Is Met evaluates the expression in DefinitionCustomLogic. Values: All Conditions Are Met, Any Condition Is Met, Always (No Criteria), Custom Logic Is Met. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Slab Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentSchemeLine` | Parent Scheme Line | Lookup → [SchemeLine](/docs/reference/entities/scheme-line/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RewardAccountGroup` | Reward Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `RewardApplicability` | Reward Applicability | PickList | Yes | Which of the slab's qualifying benefits are granted: All Rewards, Any One With Lowest Value, Any One With Highest Value, or Custom Logic (benefit groups described by the expression in RewardCustomLogic; the user or caller picks one group). Values: All Rewards, Any One With Lowest Value, Any One With Highest Value, Custom Logic. | | `RewardCustomLogic` | Reward Custom Logic | Text | | Expression over benefit ordinals ({1} AND {2} OR {3}) that partitions the slab's benefits into selectable groups when RewardApplicability is Custom Logic; the applied group is chosen by index at apply time. | | `SchemeId` | Scheme | Lookup → [Scheme](/docs/reference/entities/scheme/) | Yes | | | `SequenceNumber` | Sequence Number | Number | Yes | | | `Title` | Title | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UseLowerConditionRatio` | User Lower Ratio for Rewards | Boolean | Yes | When the slab's conditions are combined, use the LOWEST qualifying count and target-to-achievement ratio across the conditions instead of the highest - the conservative reading for repeat rewards and ratio-based repeats. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListHeader` | Delete | Delete | DeleteListHeader | | `DeleteListRow` | Delete | Delete | DeleteListRow | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Scheme](/docs/reference/entities/scheme/) — looks up via `SchemeId` - [SchemeLine](/docs/reference/entities/scheme-line/) — looks up via `ParentSchemeLine` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `RewardAccountGroup` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — referenced by via `SchemeLineId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `SchemeLineId` - [SchemeLine](/docs/reference/entities/scheme-line/) — referenced by via `ParentSchemeLine` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `SchemeLineId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `SchemeLineId` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `SchemeLineId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `SchemeLineId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `SchemeLineId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `SchemeLineId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `SchemeLineId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `SchemeLineId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `SchemeLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Scheme Period — entity reference URL: https://xmatix.com/docs/reference/entities/scheme-period/ Last reviewed: 2026-08-16 A date slice of a Scheme, generated automatically on scheme insert from the scheme's periodType (Yearly one row, Quarterly/Monthly/Weekly/Bi-Weekly/Daily one row per interval across validFrom-validTo). Used by per-period scheme types: the engine finds the period covering the document date and aggregates PerformanceKPI accrual rows keyed by schemeId + schemePeriodId to test period-total conditions. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DateFrom` | Date From | Date | | | | `DateTo` | Date To | Date | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Scheme Period Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SchemeId` | Scheme | Lookup → [Scheme](/docs/reference/entities/scheme/) | Yes | | | `Status` | Status | PickList | | Values: Not Run, Calculated, Approved, Posted. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteListRow` | Delete | Delete | EditListRow | | `Edit` | Edit | Edit | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Scheme](/docs/reference/entities/scheme/) — looks up via `SchemeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `SchemePeriodId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Scheme — entity reference URL: https://xmatix.com/docs/reference/entities/scheme/ Last reviewed: 2026-08-16 A promotional or trade scheme - the header record that makes discounts, free goods and reward points apply automatically to transactional documents. Only schemes with Status Approved are evaluated; the scheme engine runs on Orders, Invoices, Credit Notes, Purchase Orders, Bills and Service Orders, picking schemes whose schemeType matches the document, whose validFrom/validTo covers the document date and whose account/partner/account-group scoping matches. The actual qualification rules live on child SchemeLine rows (labelled Scheme Slabs), each pairing SchemeCondition rows (what must be bought) with SchemeBenefit rows (what is granted). On insert, SchemePeriod rows are generated from periodType. Every application is mirrored into SchemeLedger rows, which are the source of record for validCount limits and budget enforcement; SchemeAccountBudget rows cap spend globally and per partner. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `ApplicableTransactionType` | Applicable Transaction Type | PickList | | When set, the document's transaction type must equal this value or the scheme is skipped; empty means any transaction type. | | `Application` | Application | PickList | | How the scheme is triggered: Auto Apply schemes run automatically inside the document save; Apply On Selection schemes only surface in recommendation and qualification lists and take effect when a user explicitly applies them (the ApplyScheme server action on the document). Values: Auto Apply, Apply On Selection. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BusinessHoursId` | Business Hour | Lookup → [BusinessHours](/docs/reference/entities/business-hours/) | | | | `ClaimablePercentage` | Claimable Percentage | Percent | | | | `ClaimGenerationFrequency` | Claim Generation Frequency | PickList | | Values: Daily, Weekly, Monthly. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IgnoreBudget` | Ignore Budget | Boolean | Yes | Skips all budget gating for this scheme: it applies on both Sale Order and Sale Invoice regardless of budget configuration or remaining budget. Without it, a scheme lacking both a global and a partner-scoped SchemeAccountBudget is suppressed on the Sale Invoice. | | `IncludeChildAccountTransactions` | Include Child Account Transactions | Boolean | Yes | For Per Period schemes: also count PerformanceKPI accrual rows of the document account's child accounts toward the period totals, not just the account itself. | | `IncludeRelatedAccountTransactions` | Include Related Account Transactions | Boolean | Yes | For Per Period schemes: also count PerformanceKPI accrual rows of sibling accounts under the same parent account toward the period totals. | | `IsClaimable` | Is Claimable | Boolean | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `MultipleFulfilmentTreatment` | Multiple Fulfilment Treatment | PickList | | What happens when several slabs of this scheme qualify on the same document: Apply All Fulfilled applies every qualifying slab, Apply First Fulfilled keeps only the first qualifying slab in sequence, Apply Last Fulfilled keeps only the last. Values: Apply All Fulfilled, Apply First Fulfilled, Apply Last Fulfilled. | | `Name` | Scheme Name | Text | Yes | | | `OriginalSchemeId` | Original Scheme | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountGroupId` | Partner Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PerformCloneScheme` | Perform Clone Scheme | Boolean | Yes | | | `PeriodEndDate` | Period End Date | Date | | | | `PeriodStartDate` | Period Start Date | Date | | | | `PeriodType` | Period Type | PickList | Yes | Granularity of the SchemePeriod rows generated on insert: Yearly (one period spanning validFrom-validTo), Quarterly, Monthly, Weekly, Bi-Weekly or Daily. Missing validFrom/validTo default to today plus a year (yearly/quarterly/monthly) or a month (weekly/daily). Periods are the accrual buckets for Per Period scheme types. Values: Validity Period, Per Order. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReferenceSchemeId` | Reference Scheme | Lookup → [Scheme](/docs/reference/entities/scheme/) | | | | `RoundOffType` | Round Off Type | PickList | | Ceil or Floor rounding the engine applies to computed scheme values (for example derived free-item quantities); empty means no rounding. Values: Floor, Ceil. | | `SchemeBudget` | Scheme Budget | Decimal | | Legacy header-level global budget; a value greater than zero counts as the scheme having a global budget. The live model expresses the scheme-wide budget as a partner-less SchemeAccountBudget row instead, and this header field is normally empty on migrated data. | | `SchemeCode` | Scheme Code | Text | | | | `SchemeQuota` | Scheme Quota | Percent | | | | `SchemeType` | Scheme Type | PickList | Yes | Which document the scheme evaluates against: Per Sale Order, Per Sale Invoice, Per Sale Order And Invoice, Per Purchase Order, Per Bill, Per Purchase Order And Bill, Per Repair Order, Per Repair Order And Invoice - each qualifying on the single document - or the Per Period variants (Per Period Sale Order/Sale Invoice/Purchase Order/Bill/Repair Order), which qualify on totals accumulated in PerformanceKPI rows across the matching SchemePeriod. Values: Per Sale Order, Per Sale Invoice, Per Sale Order And Invoice, Per Purchase Order, Per Bill, Per Purchase Order And Bill, Per Repair Order, Per Repair Order And Invoice, Per Period Sale Order, Per Period Sale Invoice, Per Period Purchase Order, Per Period Bill, Per Period Repair Order, Sales Order Per Period. | | `SequenceNumber` | Sequence Number | Number | | Order in which schemes are loaded and evaluated by the engine; lower numbers are considered first. | | `Status` | Status | PickList | | Values: Draft, Pending Approval, Approved, Deactivated. | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UtilizedAmount` | Utilized Amount | Decimal | | Denormalized consumption figure refreshed from live SchemeLedger rows (sum of netSchemeDiscount2) so admins can watch the budget deplete. Display-oriented: budget enforcement compares against the larger of this stored value and the live ledger sum, so a stale figure cannot wrongly admit a scheme. | | `ValidCount` | Val Count | Number | | Cap on how many distinct documents per customer account the scheme may apply to. Enforced live against SchemeLedger: the engine counts distinct applied documents of the current type for the account (excluding the document being saved) and stops applying once the count reaches this value. Zero or empty means unlimited. | | `ValidFrom` | Val From | Date | | | | `ValidTo` | Val To | Date | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `CreateSchemeBenefit` | Create Scheme Benefit | ServerAction (`CreateSchemeBenefit`) | Seeded as a server action but no server handler implements it - executing it performs no server work; the rewards designer creates SchemeBenefit rows directly through the data API. | | `CreateSchemeCondition` | Create Scheme Condition | ServerAction (`CreateSchemeCondition`) | Seeded as a server action but no server handler implements it - executing it performs no server work; the rewards designer creates SchemeCondition rows directly through the data API. | | `CreateSchemeSlab` | Create Scheme Slabs | ServerAction (`CreateSchemeSlab`) | Seeded as a server action but no server handler implements it - executing it saves the record and performs no other work (the rewards designer creates SchemeLine slab rows directly through the data API instead). | | `Delete` | Delete | Delete | Delete In View Page | | `DeleteEntityDetail` | Delete | Delete | DeleteEntityDetail | | `DeleteInLine` | Delete | Delete | DeleteInLine | | `Edit` | Edit | Edit | Edit in View Pages | | `EditInLine` | Edit | EditInline | Edit | | `EditInList` | Edit | Edit | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `Import` | Import | UIAction | Import | | `New` | New | New | New | | `Save` | Save | ServerAction | A plain record save; no server action handler adds behavior beyond persisting the scheme (period generation runs on insert via the lifecycle handler regardless of which save path is used). | | `SubmitforApproval` | Submit for Approval | ServerAction | No server handler implements this action, so it performs no approval workflow - it is a plain save. A scheme becomes live by setting Status to Approved (only Approved schemes are evaluated by the engine). | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Valid To Rule | `ValidTo`, Error | Valid to should be greater than the valid from | Ensures Valid To date is not earlier than Valid From date | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Scheme](/docs/reference/entities/scheme/) — looks up via `ReferenceSchemeId` - [BusinessHours](/docs/reference/entities/business-hours/) — looks up via `BusinessHoursId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `PartnerAccountGroupId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [SchemeConsumption](/docs/reference/entities/scheme-consumption/) — referenced by via `SchemeId` - [Scheme](/docs/reference/entities/scheme/) — referenced by via `ReferenceSchemeId` - [SchemeAccountBudget](/docs/reference/entities/scheme-account-budget/) — referenced by via `SchemeId` - [SchemeLine](/docs/reference/entities/scheme-line/) — referenced by via `SchemeId` - [SchemePeriod](/docs/reference/entities/scheme-period/) — referenced by via `SchemeId` - [SchemeAccountBudgetUtilization](/docs/reference/entities/scheme-account-budget-utilization/) — referenced by via `SchemeId` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `SchemeId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — referenced by via `SchemeId` - [Claim](/docs/reference/entities/claim/) — referenced by via `SchemeId` - [CompensationSlab](/docs/reference/entities/compensation-slab/) — referenced by via `SchemeId` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `SchemeId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `SchemeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Service Bay — entity reference URL: https://xmatix.com/docs/reference/entities/service-bay/ Last reviewed: 2026-08-16 A physical workshop position — a bay, wash bay, van, bin or pallet, typed by ServiceBayType and optionally tied to a Branch. A bay is not scheduled directly and has no link to a service order: to make it bookable an operator creates a BookableResource of kind Facility pointing at it, after which appointment booking can require a bay type and the engine matches candidates on ServiceBay.ServiceBayType before checking capacity and overlapping bookings. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AllowInventory` | Allow Inventory | Boolean | Yes | Marks the bay as a place stock may be held, which is what lets a bay double as a storage position (bin or pallet) rather than being purely a work position. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch the bay physically belongs to; booking narrows candidate bays to the branch of the appointment (a bay with no branch is treated as available to any). | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | Text | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ServiceBayType` | Service Bay Type | PickList | | The kind of position — seeded as Workshop, Regular Bay, Washing Bay, VHC Bay, Van, Plant, Bin or Pallet. Appointment booking matches on this value when a requirement asks for a specific bay type, so it is the field that makes a bay selectable for a job, not a cosmetic label. Values: Van, Plant, Workshop, Bin, Pallet, Washing Bay, Regular Bay, VHC Bay. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `EditInLineList` | Edit | EditInline | EditInLineList | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Service Order Line — entity reference URL: https://xmatix.com/docs/reference/entities/service-order-line/ Last reviewed: 2026-08-16 A single billable or workable item on a service order. Its behaviour is decided by the linked Item's ItemType rather than by a field on the line itself: a Work Item line is labour (it carries StandardDurationHours/ActualDurationHours, WorkStatus, TechnicianId and is what a time sheet is built from), while a Part line is stock (it drives fulfilment, allocation, picking and inventory-ledger posting). PostingType then decides where the money goes — Generate Invoices (or blank) raises a customer invoice line, Generate Claims/Auto Generate Claims raises a warranty claim line. The line also carries the full pricing stack (UnitPrice/UnitPrice2, discounts, six tax slots) and the quantity ladder that every downstream action is gated on. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ActionTaken` | Action Taken | PickList | | Values: Replace, Repair. | | `ActualDurationHours` | Actual Duration (Hours) | Number | | Hours actually worked on the line. Nothing computes it from the time-sheet start and end stamps — it is captured — and it is read by resource-wise profitability reporting rather than by any billing path. | | `AllocatedInvoicedQuantity` | Allocated Invoiced Quantity | Number | | | | `AllocatedQuantity` | Allocated Quantity | Number | | Stock committed to this line by an allocation. It is also the transaction marker for the line: once it is non-zero the Item can no longer be changed and the line can no longer be deleted. | | `AlternateItemId` | AlternateItem | Lookup → [ItemAlternate](/docs/reference/entities/item-alternate/) | | | | `Amount` | Amount | Calculated (calculated) | | Calculated line value: the base amount, less the net discount and net scheme discount when discounts are applied before tax, or the untouched base amount when ApplyPostTaxDiscount is set (in which case the discounts are taken off in the gross amount instead). | | `ApplyPostTaxDiscount` | Apply Post Tax Discount | Boolean | | Switches the point at which discounts are taken: off, they reduce the line amount before tax; on, the amount stays at base and the discounts are deducted from the gross amount after tax, and percentage discounts are computed on base plus tax rather than on base alone. | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `AssetMaintenanceId` | Asset Maintenance | Lookup → [AssetMaintenance](/docs/reference/entities/asset-maintenance/) | | The scheduled asset-maintenance item this line discharges. It is also the de-duplication key when maintenance lines are pulled in: an item already present on the order is not added twice. | | `AssetServiceContractId` | Asset Service Contract | Lookup → [AssetServiceContract](/docs/reference/entities/asset-service-contract/) | | | | `AssetServiceContractLineId` | Asset Service Contract Line | Lookup → [AssetServiceContractLine](/docs/reference/entities/asset-service-contract-line/) | | | | `BaseAmount` | BaseAmount | Calculated (calculated) | | Calculated as the net quantity (ordered less cancelled) times the effective unit price, which is UnitPrice2 when positive and UnitPrice otherwise. It is the pre-discount, pre-tax value of the line. | | `BranchId` | Branch | Lookup | | | | `CancelledQuantity` | Cancelled Quantity | Number | | Quantity struck off the line without being supplied. It is subtracted in every pending-quantity calculation, and cancelling a part line in full is one of the two ways to satisfy the Work Completed gate on the order. | | `ClaimableQuantity` | Claimable Quantity | Calculated (calculated) | | Calculated quantity eligible for a warranty claim: it is quantity less cancelled less already claimed, but only when PostingType is Generate Claims or Auto Generate Claims — for any other posting type it evaluates to zero, which is what keeps billable work out of the claim run. | | `ClaimedQuantity` | Claimed Quantity | Number | | | | `ComplaintCodeId` | ComplaintCode | Lookup → [Complaint](/docs/reference/entities/complaint/) | | | | `ComplaintFaultCodeId` | ComplaintFaultCode | Lookup → [ComplaintFault](/docs/reference/entities/complaint-fault/) | | | | `ContractDiscount` | Contract Discount | Percent | | | | `ContractDiscountAmount` | Contract Discount Amount | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | | | | `DeliveryQuantity` | Delivery Quantity | Number | | | | `DiscountAmount` | Discount Amount | Currency | | | | `DiscountAmount2` | Cash Discount Amount | Currency | | | | `ExternalId` | External | Text | | | | `FailedItemDeliveredQuantity` | Failed Item Delivered Quantity | Number | | | | `FailedItemTreatment` | Failed Item Treatment | PickList | | Values: Replaced, Repaired, Inspected. | | `FailedPartInfo` | Failed Part Info | Text | | | | `FulfilmentOrderQuantity` | Fulfilment Order Quantity | Number | | | | `GrossAmount` | Gross Amount | Calculated (calculated) | | Calculated as the line amount plus tax, minus the discounts again when ApplyPostTaxDiscount is set — the post-tax discount branch is where those discounts actually bite. | | `HeaderItem` | Header Item | Text | | | | `Id` | Id | Guid | | | | `IncludedInPackage` | Included In Package | Boolean | | | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | The inventory ledger entry raised for this line's stock movement. Its presence is what marks the line as already posted: the inventory-posting action only considers lines where it is empty, and refuses to run when every line has one. | | `InventoryStockId` | Inventory Stock | Lookup → [InventoryStock](/docs/reference/entities/inventory-stock/) | | | | `InvoiceGroup` | Invoice Group | PickList | | Splits the order's lines into separate invoice documents — the seeded values are Parts and Service — so one job can bill parts and labour on different invoices. Claims are grouped the same way. Values: Parts, Service. | | `InvoiceQuantity` | Invoice Quantity | Number | | | | `IsBillable` | Billable | Boolean | | Read-only derived flag: it is true when PostingType is Generate Invoices or is blank, and its setter deliberately discards writes, so storing a value in the column has no effect. Change PostingType to change billability. | | `IsClaimed` | Claimed | Boolean | | | | `IsILPosted` | IL Posted | Boolean | | Protected inventory-ledger posting flag — the handler rejects client attempts to set or change it, so it can only be maintained by the posting engine. | | `IsILPostingApproved` | IL Posting Approved | Boolean | | | | `IsInvoiced` | Invoiced | Boolean | | Set by the invoice run on each line it actually posted. It marks that an invoice line was produced, not that the line is fully billed — check the pending invoice quantity for that. | | `IsPackageService` | Package Service | Boolean | | | | `IsSchemeGenerated` | Scheme Generated | Boolean | | | | `IsCampaignMandatory` | Campaign Mandatory | Boolean | | Marks the line as required by a campaign or recall. While set, the handler blocks changes to the item, quantity, cancelled quantity and contract on the line and blocks deleting it altogether. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | Yes | The item or operation on the line, and the thing that decides how the line behaves: an Item of type Work Item is labour and can appear on a time sheet, an Item of type Part drives allocation, picking and inventory posting. The item must be one of the Related Items configured for the header Asset's Item, and it is locked once anything has been allocated against the line. | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ItemName` | Item Name | Text | | | | `ItemServiceContractId` | Item Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | The service contract this line is executed and settled under. It drives how the line is posted — invoices are split per contract and claims are raised against it — and it is validated against the asset's contracts when set. | | `ItemServiceContractId2` | Item Service Contract2 | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | A second service contract sharing the cost of the line, used where liability is split. It only produces anything when its weightage is positive, that contract's posting treatment is Generate Invoices and it names a weightage charge item — then a proportional extra invoice line is raised against it. | | `ItemServiceContractId3` | Item Service Contract3 | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | | | `MaintenanceSubType` | Maintenance Sub-Type | PickList | | | | `MaintenanceType` | Maintenance Type | PickList | | Values: Breakdown, Predictive, Preventive. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `Name` | Name | Text | | | | `NetDiscount` | Net Discount | Calculated (calculated) | | Calculated total of the line's three discount channels — cash, secondary and contract — preferring the explicit amount for each where one is entered. The percentage branches of the formula refer to Discount, Discount2 and ContractDiscount rate fields that are not first-party fields on this entity, so in a stock configuration only the entered amounts contribute. | | `NetSchemeDiscount` | Net Scheme Discount | Calculated (calculated) | | | | `OpportunityLineId` | Opportunity Line | Lookup → [OpportunityLine](/docs/reference/entities/opportunity-line/) | | | | `OriginalItemId` | Original Item | Lookup | | | | `OTCInvoicedQuantity` | OTC Invoiced Quantity | Number | | Quantity billed over the counter, that is sold directly without going through the fulfilment chain. It is deducted when working out what is still releasable to fulfilment. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PackageClassification` | Package Classification | PickList | | Marks how the line sits inside a service package. Lines classified as "Packaged Item" are skipped by both the invoice run and the claim run, because their value is billed through the package parent rather than in their own right. | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PendiFulfilmentOrderQuantity` | Pending Fulfilment Order Quantity | Calculated (calculated) | | Calculated as quantity less fulfilment-order quantity, less over-the-counter invoiced quantity, less cancelled quantity — what is still releasable to inventory fulfilment. The release actions are refused outright when no line has a positive value here, and the field name carries a long-standing spelling error ("Pendi") that is part of the API contract. | | `PendingAllocatedInvoicedQuantity` | Pending Allocated Invoiced Quantity | Calculated (calculated) | | Calculated as allocated quantity less allocated-invoiced quantity — stock committed to the job that has not yet been billed. | | `PendingDeliveryOrder` | Pending Delivery Order | Calculated (calculated) | | | | `PendingFulfilmentAllocationQuantity` | Pending Fulfilment Allocation Quantity | Calculated (calculated) | | Calculated as quantity less allocated less cancelled — stock still to be committed. Allocation actions are gated on it, and the order cannot move to Work Completed while any Part line still has a non-zero value here that has not been cancelled instead. | | `PendingInvoiceQuantity` | Pending Invoice Quantity | Calculated (calculated) | | Calculated as quantity less cancelled less invoiced — what is still billable. Both invoice actions are refused when no line has a positive value here, and it is the quantity used when a selective invoice omits an explicit request. | | `PendingPickingQuantity` | Pending Picking Quantity | Calculated (calculated) | | | | `PickedQuantity` | Picked Quantity | Decimal | | | | `PostingType` | Posting Type | PickList | | Decides where the line's value is posted when the order is invoiced. Blank or Generate Invoices produces a customer invoice line; Generate Claims and Auto Generate Claims send it to warranty claims instead. Values: Auto Generate Claims, Generate Invoices, Generate Claims, Expense. | | `PriceAsOnDate` | Price As On Date | DateAndTime | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `PriceListRuleId` | Price List Rule | Lookup → [PriceListRule](/docs/reference/entities/price-list-rule/) | | | | `PriceListRulesId` | Price List Rules | Lookup | | | | `PurchaseOrderLineId` | Purchase Order Line | Lookup → [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) | | The purchase order line raised to buy this part in when it was not in stock. Its presence excludes the line from a further vehicle-offroad purchase order, so it doubles as the already-ordered marker. | | `Quantity` | Quantity | Number | | The quantity ordered on the line, and the base of every pending calculation — fulfilment, allocation, picking, invoicing and claiming all subtract what has already happened from this figure less the cancelled quantity. Negative values are rejected, and it cannot be changed on a line flagged as campaign-mandatory. | | `QuoteLineId` | Quote Line | Lookup → [QuoteLine](/docs/reference/entities/quote-line/) | | | | `RecommendationAmount` | Recommendation Amount | Calculated (calculated) | | Intended to expose the value of recommendation-driven work, but its calculation tests a health-check recommendation field that exists on quote lines and not on this entity, so on a service order line it evaluates to zero. | | `RecommendationId` | Recommendation | Lookup | | | | `RecommendationType` | Recommendation Type | PickList | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedQuantity` | Requested Quantity | Number | | A virtual, non-persisted field: it exists so a selective action (selective fulfilment, invoice, allocation, picking or cancellation) can carry a per-line quantity in its payload. It is validated against the relevant pending quantity, and when omitted or zero the action falls back to the whole pending amount. | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `RNAExternalId` | RNAExternal | Text | | | | `RNAServiceOrderExternalId` | RNA Service Order External | Text | | | | `SchemeBenefitId` | Scheme Benefit | Lookup → [SchemeBenefit](/docs/reference/entities/scheme-benefit/) | | | | `SchemeDiscountAmount` | Scheme Discount Amount | Currency | | | | `SchemeLineId` | Scheme Slab | Lookup → [SchemeLine](/docs/reference/entities/scheme-line/) | | | | `SchemeRewardPoints` | Scheme Reward Points | Number | | | | `CampaignId` | Campaign | Lookup → [Campaign](/docs/reference/entities/campaign/) | | | | `CampaignItemId` | Campaign Item | Lookup | | | | `ServiceContractItemId` | Service Contract Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ServiceContractWeightage` | Service Contract Weightage | Calculated (calculated) | | Calculated as one minus the second and third contract weightages — the share of the line's value that stays with the primary contract. It is derived, so adjust the second and third shares rather than this. | | `ServiceContractWeightage2` | Service Contract Weightage 2 | Decimal | | The fraction of the line's value borne by the second service contract, entered as a proportion. It both drives the extra invoice charge to that contract and reduces the primary contract's derived share. | | `ServiceContractWeightage3` | Service Contract Weightage 3 | Decimal | | | | `ServiceOrderDiscount` | Service Order Discount | Calculated (calculated) | | Intended to carry the header discount down to the line, but its calculation refers to a Discount field on the service order that does not exist in first-party metadata, so it resolves to nothing on a stock configuration. | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | | | `ServiceOrderTimeSheetId` | Service Order Time Sheet | Lookup → [ServiceOrderTimeSheet](/docs/reference/entities/service-order-time-sheet/) | | | | `ServiceRecommendationId` | Service Recommendation | Lookup → [ServiceRecommendation](/docs/reference/entities/service-recommendation/) | | The service recommendation this line was created from when the customer accepted it. When the order is invoiced, that recommendation is marked utilised and pointed back at this line, which is what stops it being offered or deleted again. | | `SkipScheme` | Skip Scheme | Boolean | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StandardDurationHours` | Standard Duration (Hours) | Number | | The book time for the operation, copied from the source quote or opportunity line when the order is populated. It is the benchmark against which actual hours are compared; it does not price the line. | | `StockAvailable` | Stock Available | Calculated (calculated) | | Live read-through of the linked inventory stock record's available quantity — free stock at the line's branch, lot and location. It is a display aid for the parts counter and is not a stored balance for the line. | | `StockInHand` | Stock In Hand | Calculated (calculated) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `Tax1` | Tax1 | Currency | | | | `Tax1Name` | TaxName1 | Text | | | | `Tax1Rate` | TaxRate1 | Currency | | | | `Tax1Type` | TaxType1 | Text | | | | `Tax2` | Tax2 | Currency | | | | `Tax2Name` | TaxName2 | Text | | | | `Tax2Rate` | TaxRate2 | Currency | | | | `Tax2Type` | TaxType2 | Text | | | | `Tax3` | Tax3 | Currency | | | | `Tax3Name` | TaxName3 | Text | | | | `Tax3Rate` | TaxRate3 | Currency | | | | `Tax3Type` | TaxType3 | Text | | | | `Tax4` | Tax4 | Currency | | | | `Tax4Name` | TaxName4 | Text | | | | `Tax4Rate` | TaxRate4 | Currency | | | | `Tax4Type` | TaxType4 | Text | | | | `Tax5` | Tax5 | Currency | | | | `Tax5Name` | TaxName5 | Text | | | | `Tax5Rate` | TaxRate5 | Currency | | | | `Tax5Type` | TaxType5 | Text | | | | `Tax6` | Tax6 | Currency | | | | `Tax6Name` | TaxName6 | Text | | | | `Tax6Rate` | TaxRate6 | Currency | | | | `Tax6Type` | TaxType6 | Text | | | | `TaxAmount` | Tax Amount | Currency | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `TechnicianId` | Technician | Lookup → [Resource](/docs/reference/entities/resource/) | | The Resource who works this line. It is copied onto the time-sheet line created for the line, and profitability attributes the line's revenue and hours to this person, falling back to the order header's technician only when the line names nobody. | | `TimeLost` | Time Lost | Number | | | | `UIProps` | UI Props | Text | | | | `UnitPrice` | Unit Price | Decimal | | The line's list price per unit, set from the applicable price list rule when the item, price list or price-as-on date changes. It is only used in the amount calculation when the override price UnitPrice2 is zero. | | `UnitPrice2` | Unit Price 2 | Number | | An override price per unit that wins over UnitPrice whenever it is greater than zero — the base amount is computed from it in preference. Use it for negotiated or contract-specific pricing on the line. | | `UpdatedDateTime` | Modified Date | DateAndTime | | | | `WorkEndedAt` | Work Ended At | DateAndTime | | When work on this line finished. It is one of the two ways a Work Item line satisfies the order's Work Completed gate — the other being a work status of "Work Ended". | | `WorkStartedBy` | Work Started By | DateAndTime | | Despite the name this is a date-and-time field, not a user reference: it holds when work on the line started. It is what the Create Time Sheet action reads from its payload to seed the sheet's work start date, and what the sheet writes back onto the line. | | `WorkStatus` | Work Status | PickList | | The line's work stage. The Work Completed gate on the order compares it against the literal "Work Ended", but the seeded picklist for this field offers only the two paused reasons (non-availability of stock, non-availability of technician), so in practice the gate is satisfied by the work-ended timestamp rather than by this value; time sheets write Started/Paused/Completed into it, which are also outside the seeded list. Values: Paused- Non-Availability Of Stock, Paused- Non-Availability Of Technician, Work Ended. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Delete2` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `DemoQAP` | Quick Add | UIAction | Demo QAP | | `Edit` | Edit | Edit | Edit | | `Edit2` | Edit | EditInline | Edit In Line | | `EditEntity` | Edit | Edit | Edit Entity | | `EditInLine` | Edit | Edit | Edit | | `EditInLinePage` | Edit | EditInline | Edit | | `New` | New | New | New | | `NewInLine` | New | NewInline | NewInLine | | `ProductCatalogue` | Product Catalogue | UIAction | Demo Product Catalogue | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Quantity Rule Validation | `Quantity`, Error | Quantity should not be less than 0 | Quantity should not be less than 0 | | Unit Price Rule Validation | `UnitPrice`, Error | Unit Price can not be less than 0 | Unit Price can not be less than 0 | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Item For Type Work Item Or Part | `ItemId` | | ## Related entities - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — looks up via `AssetMaintenanceId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — looks up via `AssetServiceContractId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId2` - [QuoteLine](/docs/reference/entities/quote-line/) — looks up via `QuoteLineId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — looks up via `OpportunityLineId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [Resource](/docs/reference/entities/resource/) — looks up via `TechnicianId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Complaint](/docs/reference/entities/complaint/) — looks up via `ComplaintCodeId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — looks up via `PriceListRuleId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [AssetServiceContractLine](/docs/reference/entities/asset-service-contract-line/) — looks up via `AssetServiceContractLineId` - [ItemAlternate](/docs/reference/entities/item-alternate/) — looks up via `AlternateItemId` - [ServiceRecommendation](/docs/reference/entities/service-recommendation/) — looks up via `ServiceRecommendationId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [ServiceOrderTimeSheet](/docs/reference/entities/service-order-time-sheet/) — looks up via `ServiceOrderTimeSheetId` - [SchemeLine](/docs/reference/entities/scheme-line/) — looks up via `SchemeLineId` - [Item](/docs/reference/entities/item/) — looks up via `ServiceContractItemId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — looks up via `PurchaseOrderLineId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — looks up via `SchemeBenefitId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId3` - [ComplaintFault](/docs/reference/entities/complaint-fault/) — looks up via `ComplaintFaultCodeId` - [Campaign](/docs/reference/entities/campaign/) — looks up via `CampaignId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `ServiceOrderLineId` - [ServiceOrderTimeSheet](/docs/reference/entities/service-order-time-sheet/) — referenced by via `ServiceOrderLineId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `ServiceOrderLineId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `ServiceOrderLineId` - [ServiceOrderTimeSheetLine](/docs/reference/entities/service-order-time-sheet-line/) — referenced by via `ServiceOrderLineId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `ServiceOrderLineId` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — referenced by via `ServiceOrderLineId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `ServiceOrderLineId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `ServiceOrderLineId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `ServiceOrderLineId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `ServiceOrderLineId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `ServiceOrderLineId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `ServiceOrderLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Service Order Time Sheet Line — entity reference URL: https://xmatix.com/docs/reference/entities/service-order-time-sheet-line/ Last reviewed: 2026-08-16 One technician-against-one-work-line row on a time sheet. It names the ServiceOrderLine worked, the Item, the resource who did the work, and the stage stamps WorkStartDate, WorkPauseDate (with PauseReason) and WorkEndDate written by the sheet's work-start/pause/end actions. Hours are held as decimals, so a ninety-minute job is 1.5; the sheet's own ActualDurationHours and StandardDurationHours are sums over these lines. It is the grain resource profitability joins on, because it links the person and the hours to the specific sold line. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ActualDurationHours` | Actual Duration (Hours) | Calculated (calculated) | | Hours actually worked on this service order line by this resource, held to two decimals so part-hours are preserved — a ninety-minute job is 1.5. It is captured rather than computed from the start and end stamps, and it is the grain resource profitability sums. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PauseReason` | Pause Reason | PickList | | Values: Paused-Non Availability of Stock. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `ServiceOrderLineId` | Service Order Line | Lookup → [ServiceOrderLine](/docs/reference/entities/service-order-line/) | | The service order line this time was worked against. It is the join that lets hours and the revenue of the thing sold meet, and a sheet line without it contributes hours but no revenue attribution. | | `ServiceOrderTimeSheetId` | Service Order Time Sheet | Lookup → [ServiceOrderTimeSheet](/docs/reference/entities/service-order-time-sheet/) | Yes | | | `StandardDurationHours` | Standard Duration Hours | Calculated (calculated) | | Book time for the line, calculated from the linked service order line's Item service duration in minutes divided by sixty, so it comes from the item master rather than being entered. | | `Status` | Status | PickList | | Values: Work Started, Work Paused, Work Ended. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `WorkEndDate` | Work End Date | DateAndTime | | | | `WorkPauseDate` | Work Pause Date | Date | | | | `WorkStartDate` | Work Start Date | DateAndTime | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | Delete Entity | | `DeleteHeader` | Delete | Delete | Delete Header | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | Edit Entity | | `EditInLineEntity` | Edit | EditInline | Edit In Line Entity | | `EditInLineHeader` | Edit | EditInline | EditInLine Header | | `EditRow` | Edit | Edit | Edit Row | | `NewHeader` | New | New | New Header | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Duration Validation Rule | `ActualDurationHours`, Error, inactive | Duration cannot be equal to Zero | Duration cannot be equal to Zero | | Work End Validation Rule | `WorkStartDate`, Error | Work End Date cannot be before Work Start Date | Work End Date cannot be before Work Start Date | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Item For Type Work Item | `ItemId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — looks up via `ServiceOrderLineId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ServiceOrderTimeSheet](/docs/reference/entities/service-order-time-sheet/) — looks up via `ServiceOrderTimeSheetId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Service Order Time Sheet — entity reference URL: https://xmatix.com/docs/reference/entities/service-order-time-sheet/ Last reviewed: 2026-08-16 A labour-capture sheet attached to a service order, created by the service order's Create Time Sheet action; one sheet is raised per invocation with a child ServiceOrderTimeSheetLine for every selected line whose Item is a Work Item (part lines are excluded). The sheet carries the work-stage flags WorkStarted/WorkPaused/WorkEnded and their dates, and its own server actions stamp the selected sheet lines and then raise the matching IsWorkStarted/IsWorkPaused/IsWorkEnded flag on the parent service order once every line has reached that stage. It does not price or bill anything — hours are read by resource-wise profitability reporting, while invoicing still comes from the service order lines. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ActualDurationHours` | Actual Duration Hours | Calculated (calculated) | | Roll-up of the actual hours on the sheet's lines. It is a protected system field — the handler rejects direct edits — so change the underlying line hours instead. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RepairPauseReason` | Work Pause Reason | PickList | | Values: Paused-Non Availability of Stock. | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | The default technician for the sheet, copied from the parent service order's Resource when the sheet is created. A sheet line with its own resource overrides it for that line's hours. | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | Yes | | | `ServiceOrderLineId` | Service Order Line | Lookup → [ServiceOrderLine](/docs/reference/entities/service-order-line/) | | An optional single service order line the whole sheet relates to. Profitability only falls back to it when the sheet has no lines of its own naming the work — normally attribution comes from the sheet lines. | | `StandardDurationHours` | Standard Duration Hours | Calculated (calculated) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `WorkEndDate` | Work End Date | DateAndTime | | | | `WorkEnded` | Work Ended | Boolean | Yes | Set when work on the sheet has finished; it raises the parent service order's IsWorkEnded flag, and only once every line of the sheet carries a work end date. | | `WorkPaused` | Work Paused | Boolean | Yes | | | `WorkPauseDate` | Work Pause Date | DateAndTime | | | | `WorkRemarks` | Work Remarks | Text | | | | `WorkStartDate` | Work Start Date | DateAndTime | | | | `WorkStarted` | Work Started | Boolean | Yes | Set when the sheet's work has begun, and mirrored up onto the parent service order's IsWorkStarted. It is raise-only at the order level, so clearing it here does not clear the order's flag. | | `WorkStatus` | Work Status | Calculated (calculated) | | Derived stage of the sheet: the service writes Started when work has begun, Paused when it is paused and Completed when it has ended. None of those three values are in this field's seeded picklist, which offers only two paused reasons, so filtering on the seeded values will not match what the engine writes. Values: Work Started, Work Paused, Work Ended. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `Edit1` | Edit | EditInline | Edit | | `EditEntity` | Edit | Edit | Edit Entity | | `EditInLine` | Edit | Edit | Edit | | `EditInLineEntity` | Edit | EditInline | EditInLine Entity | | `End` | End | ServerAction (`PerformWorkEnd`) | End Work | | `New` | New | New | New | | `Pause` | Pause | ServerAction (`PerformWorkPause`) | Pause Work | | `Start` | Start | ServerAction (`PerformWorkStart`) | Start Work | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Work Pause Reason Required | `RepairPauseReason`, Error | Work Pause Reason is required when the work is set to Paused. | Work Pause Reason is required when the work is set to Paused. | | Work End Validation Rule | `WorkStartDate`, Error | Work End Date cannot be before Work Start Date | Work End Date cannot be before Work Start Date | | Work Pause Validation Rule | `WorkStartDate`, Error | Work Pause Date cannot be before Work Start Date | Work Pause Date cannot be before Work Start Date | | Work must be started before pause/end | `WorkStarted`, Error | Work cannot be paused or ended before it has been started. | Work cannot be paused or ended before it is started. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — looks up via `ServiceOrderLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ServiceOrderTimeSheetId` - [ServiceOrderTimeSheetLine](/docs/reference/entities/service-order-time-sheet-line/) — referenced by via `ServiceOrderTimeSheetId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Service Order — entity reference URL: https://xmatix.com/docs/reference/entities/service-order/ Last reviewed: 2026-10-10 A service order is the workshop job card: one document per job taken in against a customer and, usually, an asset, with a line for every part and every unit of labour. It appears in the Service app on web and mobile. It is created directly or from a case, lead, appointment, service opportunity or service estimate, and its lines are copied from the estimate, else the opportunity, else the asset's service contract. It is numbered from document numbering (shipped series SV, separator -, date DDMMYYYY, six digits). Partner Account and Branch are locked once saved, and an asset can have only one service order that is not Delivered. Work Item lines are labour recorded on time sheets; Part lines go through fulfilment, allocation, picking and inventory posting, with a VOR purchase order for parts out of stock. Shipped business rules move Status through Draft, Work To Start, Work In Progress, Work Paused, Work Completed, Invoiced and Delivered. Invoice requires every time sheet ended and every part line allocated. There is no cancel action and no Cancelled status. Step-by-step procedures are on the Service orders page of the Service documentation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer. Filled from the asset's owner when left empty. | | `AccountName` | Account Name | Text | | | | `AdjustedAdvanceAmount` | Adjusted Advance Amount | Currency | | | | `AdvanceAmount` | Advance Amount | Currency | | | | `AmountPaid` | Amount Pa | Currency | | | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | The machine or vehicle being serviced. Only one service order that is not Delivered may exist per asset. Picking the asset fills Account from the asset's owner when Account is empty. | | `AssetServiceContractId` | Asset Service Contract | Lookup → [AssetServiceContract](/docs/reference/entities/asset-service-contract/) | | | | `BillingAddress` | Billing Address | Text | | | | `BillingAddressId` | Billing Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `BillingCity` | Billing City | PickList | | Values: Mumbai, Pune, None, Chandigarh. | | `BillingCityPlaceId` | Billing City Place | Lookup → [Place](/docs/reference/entities/place/) | | Values: Pune, Chandigarh, Mumbai. | | `BillingCountry` | Billing Country | PickList | | Values: India. | | `BillingPostalCode` | Billing Postal Code | Text | | | | `BillingRegion` | Billing Region | Text | | | | `BillingState` | BillingState | PickList | | | | `BillingStreet` | Billing Street | Text | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch doing the job. Must be active and belong to the partner account; required when the partner account has branches. Locked once saved. | | `CancelPendingQuantity` | Cancel Pending Quantity | Currency | | | | `CheckInInspectionId` | Check In Inspection | Lookup → [CheckInInspection](/docs/reference/entities/check-in-inspection/) | | The check-in inspection created by the Check In action, recording the asset's condition at reception. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | | | | `CustomerVoice` | Customer Voice | Text | | The customer's complaint in their own words. | | `DiscountGroupId` | Discount Group | Lookup → [DiscountGroup](/docs/reference/entities/discount-group/) | | | | `DocumentDate` | Document Date | Date | | The order's business date. Set to today when left empty. | | `ExternalId` | External | Text | | | | `FailureDate` | Failure Date | Date | | | | `Id` | Id | Guid | | | | `InspectionLineId` | Inspection Line | Lookup → [InspectionLine](/docs/reference/entities/inspection-line/) | | | | `IsClaimed` | Is Claimed | Boolean | | | | `IsDelivered` | Delivered | Boolean | | Set by the Delivery action, which also sets Status to Delivered, releases the bay, closes the originating inspection line and records campaign maintenance against the asset. | | `IsILPosted` | IL Posted | Boolean | | | | `IsInJobQueue` | In Job Queue | Boolean | | | | `IsInvoiceGenerated` | Invoice Generated | Boolean | | Set when the Invoice or Selective Invoice action raises documents. Drives the Invoiced status. | | `IsKPICalculated` | KPI Calculated | Boolean | | | | `IsLinePopulated` | Line Populated | Boolean | | | | `IsQuoteGenerated` | Quote Generated | Boolean | | Guard flag for the Generate Quote action rather than a status: once true, that action refuses to run again for the order. | | `IsReleasedForFulfillment` | Released For Fulfillment | Boolean | | Protected system flag that the handler refuses to let a client set or change; releasing parts is done through the release-for-fulfilment action, not by writing this field. | | `IsTimeSheetGenerated` | Is Time Sheet Generated | Boolean | | | | `IsWorkEnded` | Work Ended | Boolean | | | | `IsWorkPaused` | Is Work Paused | Boolean | | | | `IsWorkStarted` | Work Started | Boolean | | Raised to true when work begins, either directly or by a time sheet whose lines have all been started. Time sheets only ever raise this flag and never clear it, so it stays true once set even if work is later paused or the sheet is reworked. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | | | `ItemServiceContractId` | Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | The service contract covering the work. Requires an active asset service contract on the asset where the contract needs one. On a new order with no estimate and no lines, its pending entitlements are added as lines. It can be changed only while no time sheet has started work and no part has been allocated. | | `JobQueueId` | Job Queue | Lookup | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `Name` | Document Number | Text | | The service order's document number, generated on save from the Service Order Name Setting. The shipped format is SV, a hyphen, the document date as DDMMYYYY, a hyphen and a six-digit counter that restarts each day. | | `OpenAdvanceAmount` | Open Advance Amount | Calculated (calculated) | | Calculated as the advance received less the advance already adjusted against billing — the unapplied balance of the customer's deposit. | | `OpenAmount` | Open Amount | Calculated (calculated) | | Calculated as the total amount less the advance taken, i.e. what would still be collectable if the job were billed in full today. It is not driven by invoices actually raised. | | `OpportunityId` | Opportunity | Lookup → [Opportunity](/docs/reference/entities/opportunity/) | | The service opportunity or booking this job came from. Setting or changing it populates the order's lines from the opportunity lines, but only when no service estimate quote is set on the order; on create the new order's id is also stamped back onto the opportunity. | | `OrderAmount` | Order Amount | Currency | | | | `OutstandingAmount` | Outstanding Amount | Calculated (calculated) | | Calculated as total tax plus the order amount less the amount paid. Note that it is built on OrderAmount rather than on the calculated TotalAmount, so the two headline balances on the document are derived from different bases. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PackageServiceId` | Package Service | Lookup → [Item](/docs/reference/entities/item/) | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Your operating company for the job. Must be active. Locked once saved. | | `PendingFulfilmentAllocationQuantity` | Pending Allocation Quantity | Calculated (calculated) | | | | `PendingInvoiceQuantity` | Pending Invoice Quantity | Calculated (calculated) | | | | `PendingPickingQuantity` | Pending Picking Quantity | Calculated (calculated) | | | | `PerformGenerateQuote` | Perform Generate Quote | Boolean | | | | `PerformInventoryPosting` | Perform Inventory Posting | Boolean | | | | `PerformInvoiceGeneration` | Perform Invoice Generation | Boolean | | Legacy trigger checkbox from the era when saving the record with the box ticked ran the step. | | `PerformKPICalculation` | Perform KPI Calculation | Boolean | | | | `PerformPopulateChecklist` | Perform Populate Checklist | Boolean | | | | `PerformPopulateLines` | Perform Populate Lines | Boolean | | | | `PerformReleaseForFulfillment` | Perform Release For Fulfillment | Boolean | | | | `PerformWorkEnd` | Perform Work End | Boolean | | | | `PerformWorkStart` | Perform Work Start | Boolean | | | | `PopulateAssetMaintenance` | Populate Asset Maintenance | Boolean | | Unlike the other Perform/Populate checkboxes this one is live: switching it on an existing order makes the handler pull the due asset-maintenance items for the order's Asset (from opportunities flagged for maintenance) in as new service order lines, skipping any maintenance item already present on the order. | | `PriceAsOnDate` | Price As On Date | Date | | The date used to look up prices. Changing it reprices every line. | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `QuoteForItemServiceContractId` | Quote For Service Contract | Lookup → [ItemServiceContract](/docs/reference/entities/item-service-contract/) | | Selects which item service contract the Generate Quote action should quote for: only service order lines whose own item service contract matches this value become quote lines, and the action is refused when none match. | | `QuoteId` | Quote | Lookup → [Quote](/docs/reference/entities/quote/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `ResetUsageHours` | Reset Usage Hours | Boolean | | | | `ResetUsageReading` | Reset Usage Reading | Boolean | | | | `ResourceId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | The service advisor on the create form. Must be authorized for the order's partner account and branch. Used as the time sheet technician when no technician is given. | | `RNAExternalId` | RNA External | Text | | | | `RoundOff` | Round Off | Currency | | | | `ServiceAdvisorId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | The service advisor shown on the record's details. Must be authorized for the order's partner account and branch. | | `ServiceContractItemId` | Service Contract Item | Lookup → ServiceContractItem | | | | `ServiceEstimateQuoteId` | Service Estimate | Lookup → [Quote](/docs/reference/entities/quote/) | | The service-estimate Quote this job was approved from. Setting it on create, or changing it later, copies that quote's lines onto the order (item, quantity, prices, durations, contract and posting type, discounts) and takes precedence over the opportunity and contract line sources — lines are only copied when the order has none yet. | | `ServiceType` | Service Type | PickList | | The kind of job: Paid Repairs, Free Service, Warranty Service, Dealer Expense or PDI. The shipped create form offers the first four. Values: Paid Repairs, Free Service, Warranty Service, Dealer Expense. | | `ShippingAddress` | Shipping Address | Text | | | | `ShippingAddressId` | Shipping Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `ShippingCity` | Shipping City | PickList | | Values: Pune, Mumbai, Chandigarh. | | `ShippingCityPlaceId` | Shipping City | Lookup → [Place](/docs/reference/entities/place/) | | Values: Mumbai, Pune, Chandigarh. | | `ShippingCountry` | Shipping Country | PickList | | Values: India. | | `ShippingPostalCode` | Shipping Postal Code | Text | | | | `ShippingRegion` | Shipping Region | Text | | | | `ShippingState` | Shipping State | PickList | | Values: Haryana, Maharashtra, New Delhi, Punjab. | | `ShippingStreet` | Shipping Street | Text | | | | `SkipScheme` | Skip Scheme | Boolean | | When on, trade-scheme evaluation is skipped for the whole order. | | `SplitInvoices` | Split Invoices | Boolean | | Stored but not used by the platform. Invoices are split by each line's Invoice Group. | | `StandardDuration` | Standard Duration | Currency | | | | `Status` | Status | PickList | | The job's stage: Draft (the default), Work To Start, Work In Progress, Work Paused, Work Completed, Invoiced or Delivered. Shipped business rules set it from the progress flags: a time sheet created, work started, paused or ended, parts fully allocated, invoice generated, delivered. Work Completed is refused while any non-cancelled Work Item line has not ended, and no status change is allowed while a work order for subcontracted lines is still open. Values: Draft, Work To Start, Work In Progress, Work Paused, Work Completed, Invoiced, Delivered. | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | The default supplier for VOR purchase orders, used when the VOR action is not given a supplier. | | `Tax1` | Tax1 | Currency | | | | `Tax1Name` | TaxName1 | Text | | | | `Tax1Rate` | TaxRate1 | Currency | | | | `Tax1Type` | TaxType1 | Text | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `TaxId` | Tax | Lookup → [Tax](/docs/reference/entities/tax/) | | | | `TaxSupplyType` | Tax Supply Type | PickList | | Values: Within State, Outside State. | | `TCSEligibleAmount` | TCS Eligible Amount | Currency | | | | `TechnicianId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | The default technician for time sheets created from the order. | | `TotalAmount` | Total Amount | Calculated (calculated) | | Calculated header total: the line total plus tax, where tax is TotalTax when it is positive and otherwise the derived TotalTaxAmount2. It is the figure OpenAmount is measured against. | | `TotalDiscountAmount` | Total Discount Amount | Calculated (calculated) | | | | `TotalLabourAmount` | Total Labour Amount | Calculated (calculated) | | | | `TotalLineAmount` | Total Line Amount | Calculated (calculated) | | | | `TotalLineBaseAmount` | Total Line Base Amount | Calculated (calculated) | | | | `TotalLineGrossAmount` | Total Line Gross Amount | Calculated (calculated) | | | | `TotalLineTaxAmount` | Total Line Tax Amount | Calculated (calculated) | | Header roll-up of tax from the lines. Its seeded calculated formula is self-referential (it adds Tax1 to its own current value), so treat this figure with suspicion and prefer summing the lines' TaxAmount when accuracy matters. | | `TotalPackageItemsAmount` | Total Package Items Amount | Calculated (calculated) | | | | `TotalPartAmount` | Total Part Amount | Currency | | | | `TotalSchemeDiscountAmount` | Total Scheme Discount Amount | Currency | | | | `TotalTax` | Total Tax Amount | Currency | | | | `TotalTaxAmount2` | Total Tax Amount | Calculated (calculated) | | Calculated fallback tax total — the lines' tax total plus the header-level Tax1 — used by TotalAmount whenever TotalTax is zero or negative. | | `TransactionType` | Transaction Type | PickList | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | | | | `UsageReading` | Usage Reading | Decimal | | The asset's meter reading at reception. Cannot be lower than the asset's last recorded reading and, when a service contract is set, must fall inside the contract's usage band. Written to the asset when the order is invoiced. | | `UsageReadingHours` | Usage Reading (Hours) | Decimal | | The asset's hour-meter reading at reception, validated like Usage Reading. | | `WorkCompletedBy` | Work Completed By | Lookup | | | | `WorkStartedAt` | Work Started At | DateAndTime | | Timestamp of when work began on the job at header level. The per-line and per-time-sheet stamps are separate fields, and this header value is not derived from them. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `CancelAllocation` | Cancel Allocation | ServerAction (`CancelAllocation`) | CancelAllocation | | `CancelPicking` | Cancel Picking | ServerAction (`CancelPicking`) | CancelPicking | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `CreateTimeSheet` | Create Time Sheet | ServerAction (`CreateTimeSheet`) | Creates one ServiceOrderTimeSheet for the order plus a sheet line for every selected service order line whose Item is a Work Item — part lines are dropped even if selected. It copies the order's ResourceId onto the sheet, seeds the work start date from the order or the payload, stamps the sheet id and work status back onto the covered service order lines, and sets IsTimeSheetGenerated on the order. | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `DeleteList` | Delete | Delete | Delete | | `DeleteRow` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `EditInLinepage` | Edit | EditInline | Edit | | `EditRow` | Edit | EditInline | Edit | | `EndWork` | End Work | ServerAction | End Work | | `FetchTelematicsData` | Fetch Telematics Data | ServerAction (`FetchTelematicsData`) | Fetch Telematics Data | | `GetSchemeRecommendations` | Get Scheme Recommendations | ServerAction (`GetSchemeRecommendations`) | Get Scheme Recommendations | | `GetSchemeRecommendations` | Get Scheme Recommendations | ServerAction (`GetSchemeRecommendations`) | Get Scheme Recommendations | | `GetServiceRecommendation` | Get Service Recommendation | ServerAction (`GetServiceRecommendation`) | Read-only lookup that returns the recommendations to offer the customer on this job: every open recommendation for the order's Asset — not utilised, not yet accepted or rejected, and not already attached to an order or quote — plus any already attached to this service order. It returns nothing when the order has no Asset. | | `New` | New | New | New | | `PauseWork` | Pause Work | ServerAction | Pause Work | | `PerformAllocation` | Allocation | ServerAction (`PerformAllocation`) | PerformAllocation | | `PerformGenerateQuote` | Perform Generate Quote | ServerAction (`PerformGenerateQuote`) | Creates a Quote from the order for the item service contract named in QuoteForItemServiceContractId, taking only the service order lines whose own item service contract matches it. It is refused when a quote has already been generated for the order or when no line qualifies, so it is a one-shot per order rather than a re-runnable estimate. | | `PerformInvoiceGeneration` | Invoice | ServerAction (`PerformInvoiceGeneration`) | Does far more than raise an invoice. For every line with pending invoice quantity it creates customer invoice documents in Draft (split per invoice group and per item service contract, with lines matched to allocation lines where the parts were allocated), then creates warranty claims for the claimable lines, marks any service recommendations consumed by the order as utilised, updates the asset and its maintenance history, and finally sets IsInvoiceGenerated on the order. Lines classified as Packaged Item are excluded, and the action is refused when no line has pending invoice quantity. | | `PerformMarkDelivered` | Mark Delivered | ServerAction (`PerformMarkDelivered`) | PerformMarkDelivered | | `PerformPicking` | Picking | ServerAction (`PerformPicking`) | PerformPicking | | `PerformPopulateChecklist` | Populate Checklist | ServerAction (`PerformPopulateChecklist`) | Fills in the check-in inspection checklist detail for the order from the configured checklist template. It runs with no precondition checks, and because saving checklist lines is what fires the service recommendation rules, this is the step that produces the order's recommendations. | | `PerformVehicleOffroad` | VOR PO | ServerAction (`PerformVehicleOffroad`) | Creates one Purchase Order against the order's supplier and branch for parts the workshop does not have, so a stranded job can be ordered out. It considers only lines whose Item is of type Part, that have a quantity and no purchase order line yet, and it skips any part that already shows available stock for the order's branch and partner; each resulting purchase order line is linked back to the service order line it came from. | | `PostServiceRecommendation` | Post Service Recommendation | ServerAction (`PostServiceRecommendation`) | Applies the customer's accept/reject decisions from the payload to the named recommendations, then, for each newly accepted one that is not yet attached to a line, creates a service order line for its Item and links the two. Quantity on the new line is taken from the recommendation's NumericValue (falling back to 1), not from its Quantity field, so a numeric inspection reading becomes the ordered quantity. | | `ProductCatalogue` | Product Catalogue | ServerAction, inactive | Product Catalogue | | `SelectiveAllocation` | Selective Allocation | ServerAction (`SelectiveAllocation`), inactive | SelectiveAllocation | | `SelectiveCancelAllocation` | Selective Cancel Allocation | ServerAction (`SelectiveCancelAllocation`), inactive | SelectiveCancelAllocation | | `SelectiveFulfilment` | Selective Fulfilment | ServerAction (`SelectiveFulfilment`) | The same fulfilment raise as the full release, but restricted to the service order lines supplied in the action payload, each with an optional requested quantity that is validated against — and cannot exceed — that line's pending fulfilment quantity. Omitting the quantity falls back to the line's full pending amount. | | `SelectiveInvoice` | Selective Invoice | ServerAction (`SelectiveInvoice`) | Runs the same invoice-plus-claim-plus-asset-update chain as the full invoice generation, but only for the service order lines named in the payload; a requested quantity is capped at that line's pending invoice quantity and, when omitted, defaults to the whole pending amount. | | `SelectivePicking` | Selective Picking | ServerAction (`SelectivePicking`) | SelectivePicking | | `StartWork` | Start Work | ServerAction | Start Work | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Usage Reading blank | Error | Usage Reading can not be blank | Usage Reading can not be blank | | Usage Reading Validation Rule | `UsageReading`, Error | Usage Reading Cannot be Negative | Usage Reading Cannot be Negative | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Customer Account Filter | `AccountId` | | | Executive Filter | `ResourceId` | Executive | | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [InspectionLine](/docs/reference/entities/inspection-line/) — looks up via `InspectionLineId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `BillingAddressId` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — looks up via `AssetServiceContractId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Item](/docs/reference/entities/item/) — looks up via `ServiceContractItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `ItemServiceContractId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [CheckInInspection](/docs/reference/entities/check-in-inspection/) — looks up via `CheckInInspectionId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — looks up via `QuoteForItemServiceContractId` - [Item](/docs/reference/entities/item/) — looks up via `PackageServiceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Place](/docs/reference/entities/place/) — looks up via `BillingCityPlaceId` - [Place](/docs/reference/entities/place/) — looks up via `ShippingCityPlaceId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [Tax](/docs/reference/entities/tax/) — looks up via `TaxId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `ShippingAddressId` - [Resource](/docs/reference/entities/resource/) — looks up via `ServiceAdvisorId` - [Opportunity](/docs/reference/entities/opportunity/) — looks up via `OpportunityId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [Quote](/docs/reference/entities/quote/) — looks up via `ServiceEstimateQuoteId` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [DiscountGroup](/docs/reference/entities/discount-group/) — looks up via `DiscountGroupId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `ServiceOrderId` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — referenced by via `ServiceOrderId` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — referenced by via `ServiceOrderId` - [ServiceOrderTimeSheet](/docs/reference/entities/service-order-time-sheet/) — referenced by via `ServiceOrderId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `ServiceOrderId` - [Payment](/docs/reference/entities/payment/) — referenced by via `ServiceOrderId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `ServiceOrderId` - [CheckInInspection](/docs/reference/entities/check-in-inspection/) — referenced by via `ServiceOrderId` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — referenced by via `ServiceOrderId` - [ComplaintFault](/docs/reference/entities/complaint-fault/) — referenced by via `ServiceOrderId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `ServiceOrderId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `ServiceOrderId` - [Visit](/docs/reference/entities/visit/) — referenced by via `ServiceOrderId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `RepairOrderServiceOrderId` - [Claim](/docs/reference/entities/claim/) — referenced by via `ServiceOrderId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `ServiceOrderId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `ServiceOrderId` - [Quote](/docs/reference/entities/quote/) — referenced by via `ServiceOrderId` - [Case](/docs/reference/entities/case/) — referenced by via `ServiceOrderId` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — referenced by via `ServiceOrderId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ParentRecordId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ServiceOrderId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `ServiceOrderId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Service Recommendation Rule — entity reference URL: https://xmatix.com/docs/reference/entities/service-recommendation-rule/ Last reviewed: 2026-08-16 The condition that turns a checklist reading into a Service Recommendation. Each rule hangs off a checklist template line and says which Item to recommend, of which recommendation type and quantity, when the captured line matches: either the RAG value equals RAGValue, or the numeric reading is above ValueGreaterThan, below ValueLessThan, or between the two when both are set; a rule with none of these set matches any text-typed line that has a value. Rules are evaluated by the checklist-line service on insert and on update, and on update it also removes recommendations whose rule no longer matches, unless the recommendation has already been utilised. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ChecklistTemplateLineId` | Checklist Template Line | Lookup | | The checklist template line this rule watches. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Quantity` | Quantity | Number | | The quantity the rule is configured to recommend. The generation code does not copy it onto the recommendation it creates, so it currently has no effect on what is proposed or ordered. | | `RAGValue` | RAG Value | PickList | | Fires the rule when the captured checklist line's red/amber/green value matches it exactly, and only when neither numeric threshold is set — a rule cannot mix a RAG match with a numeric range. The seeded first-party data supplies only a Green value for this picklist, so amber and red rules need the values adding. Values: Green. | | `RecommendationType` | Recommendation Type | PickList | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `ValueGreaterThan` | Value Greater Than | Number | | Lower threshold: on its own it fires the rule when the checklist reading is strictly above it, and combined with the upper threshold it forms a strictly-between band. Set either threshold and the RAG match is ignored. | | `ValueLessThan` | Value Less Than | Number | | Upper threshold: on its own it fires the rule when the checklist reading is strictly below it, and combined with the lower threshold it forms a strictly-between band; the bounds themselves never match. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Service Recommendation — entity reference URL: https://xmatix.com/docs/reference/entities/service-recommendation/ Last reviewed: 2026-08-16 An upsell or follow-up work suggestion raised against an Asset — most often generated automatically when a check-in inspection checklist line is saved and a matching ServiceRecommendationRule fires, or from a complaint line. It records the observed condition (Condition holds the checklist RAG value, NumericValue/TextValue the reading), the Item being recommended, and where it came from and went to: ChecklistLineId, and the RepairOrderId/RepairOrderLineId, OpportunityId/OpportunityLineId, QuoteId/QuoteLineId pairs, which are the service-order links under their legacy repair-order names. On a service order the Get Service Recommendation action lists the open ones for the asset and Post Service Recommendation accepts or rejects them, turning accepted ones into new service order lines; a recommendation consumed on an invoiced order is flagged IsUtilized and can no longer be deleted. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AcceptLabel` | Accept Label | Text | | | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `ChecklistLineId` | Checklist Line | Lookup | | The inspection checklist line whose reading produced this recommendation. Re-saving that line re-evaluates the rules against it, updating the recommendation in place or deleting it when no rule matches any more and it has not been utilised. | | `ComplaintItemId` | Complaint Item | Lookup | | | | `ComplaintLineId` | Complaint Line | Lookup | | | | `Condition` | Condition | PickList | | The red/amber/green health verdict copied from the source checklist line's RAG value — the state observed, not the action proposed. Values: Red, Amber, Green. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | MultiLineText, unique | | | | `IconName` | Icon Name | Text | | | | `Id` | Id | Guid | Yes | | | `IsAccepted` | Is Accepted | Boolean | Yes | Set when the customer accepts the recommendation through the post-recommendation action. Newly accepted recommendations that are not yet linked to a line are what trigger creation of the service order lines. | | `IsConsumed` | Is Consumed | Boolean | Yes | | | `IsRejected` | Is Rejected | Boolean | Yes | | | `IsUtilized` | Is Utilized | Boolean | Yes | Set when the work was actually carried out and billed — the invoice run marks every recommendation behind an invoiced line as utilised. A utilised recommendation can no longer be deleted, and it is never removed by a rule re-evaluation. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `NumericValue` | Numeric Value | Number | | The numeric reading taken on the checklist line (a measurement such as a thickness or depth). Be aware that when a recommendation is accepted, this value is used as the quantity of the service order line created from it, rather than the recommendation's own Quantity field. | | `OpportunityId` | Opportunity | Lookup | | | | `OpportunityLineId` | Opportunity Line | Lookup | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Quantity` | Quantity | Number | | A quantity slot on the recommendation. Note that the accept path does not read it — the service order line it creates takes its quantity from NumericValue — so a quantity set here does not carry through. | | `QuoteId` | Quote | Lookup → [Quote](/docs/reference/entities/quote/) | | | | `QuoteLineId` | Quote Line | Lookup | | | | `Recommendation` | Recommendation | Text | | | | `RecommendationRemarks` | Recommendation Remarks | Text | | | | `RecommendationType` | Recommendation Type | PickList | | Where the recommendation came from — seeded as Health (a check sheet reading), Past (previously deferred work), Complaint or IOT. It is copied from the rule that fired and, with the item, is what identifies an existing recommendation as belonging to that rule when the checklist line is re-saved. Values: Health, Past, Complaint, IOT. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RejectLabel` | Reject Label | Text | | | | `RepairOrderId` | Repair Order | Lookup | | The ServiceOrder this recommendation was raised on or accepted into, under the legacy repair-order name. It is set when the source checklist line belongs to a service order, and a recommendation that already carries one is excluded from the open list offered for other jobs on the same asset. | | `RepairOrderLineId` | Repair Order Line | Lookup | | The ServiceOrderLine created from this recommendation when it was accepted, again under the legacy repair-order name. It is filled either when the accept action creates the line or when the order is invoiced, and it is how the platform knows the recommendation has been converted. | | `ServiceRequestId` | ServiceRequest | Guid | | | | `ServiceRequestLineId` | ServiceRequestLine | Guid | | | | `Source` | Source | PickList | | Values: Repair Order Complaint, Opportunity Complaint. | | `TextValue` | Text Value | Text | | | | `Title` | Title | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `ValueType` | Value Type | PickList | | Values: Numeric, Boolean, RAG. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `Edit2` | Edit | EditInline | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLineHeader` | Edit | EditInline | Edit In Line Header | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Quote](/docs/reference/entities/quote/) — looks up via `QuoteId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `ServiceRecommendationId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ServiceRecommendationId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `ServiceRecommendationId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Service Type — entity reference URL: https://xmatix.com/docs/reference/entities/service-type/ Last reviewed: 2026-08-16 A small reference list of work categories used to classify a job. In first-party metadata it is a bare name/label master with no other attributes and no foreign key from the service order — ServiceOrder.ServiceType is a picklist of text values (Paid Repairs, Warranty Repairs, Refurbishment, Campaign Repair), so this entity is a catalogue for tenant use rather than the value the order actually stores. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `ServiceTypeId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Settlement Allocation — entity reference URL: https://xmatix.com/docs/reference/entities/settlement-allocation/ Last reviewed: 2026-08-16 One settlement of one OpenTransaction by one settling document, and the successor of PaymentAdjustment. The settling document is a Payment (PaymentId) or, for a credit note / advance / write-off document, the polymorphic SourceEntityName + SourceRecordId pair; the single OpenTransactionId FK replaces the six nullable document FKs the legacy design used. Beyond AllocatedAmount it records the non-cash components of the settlement — discount taken, TDS, write-off and rounding — and it POSTS: the allocation carries JournalId, so the ledger and the open items can never drift apart. Reversal is a status change to Reversed, which returns the amount to the open item. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AllocatedAmount` | Allocated Amount | Currency | | The amount applied to the open item, excluding the non-cash components. Reversing the allocation adds this amount back to OpenTransaction.OpenAmount and returns that item to Open. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DiscountTaken` | Discount Taken | Currency | | Settlement (early-payment) discount granted as part of this allocation. It is a non-cash component: it closes part of the open item without money moving, and it posts on the allocation's journal. | | `Id` | Id | Guid | Yes | | | `JournalId` | Journal | Lookup → [Journal](/docs/reference/entities/journal/) | | The journal this allocation posted. Allocations post precisely so the general ledger and the open items can never disagree — the non-cash components in particular have to reach the ledger. | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | GL Account Name | Text, unique | Yes | The platform record name/number of the allocation. | | `OpenTransactionId` | Open Transaction | Lookup → [OpenTransaction](/docs/reference/entities/open-transaction/) | | The open item this allocation settles — the single required FK that replaced the legacy design's six nullable document FKs. Every allocation reduces exactly one open item. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PaymentId` | Payment | Lookup → [Payment](/docs/reference/entities/payment/) | | The payment or receipt doing the settling, when the settling document is a Payment. When it is something else — a credit note, an advance, a write-off document — this is null and the settling document is named by SourceEntityName + SourceRecordId instead. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RoundingAmount` | Rounding Amount | Currency | | Rounding difference absorbed by this settlement, the last of the non-cash components; it posts on the allocation's journal alongside discount, TDS and write-off. | | `SettlementDate` | Settlement Date | Date | | The date the settlement is effective, and the date its journal is posted on — so it decides which fiscal period the settlement (and any discount, TDS or write-off on it) lands in. | | `SourceEntityName` | Source Entity Name | Text | | Name of the settling document's entity when it is not a Payment (credit note, advance, write-off document), paired with SourceRecordId. Document reversal finds the allocations a document made by this pair and unwinds only those. | | `SourceRecordId` | Source Record | Guid | | Id of the settling document row, read together with SourceEntityName. Note this is the SETTLING side; the settled side is OpenTransactionId (whose own source pair identifies the invoice or bill). | | `Status` | Status | Text | | Posted or Reversed, defaulting to Posted. Reversal does not delete the row: the allocation is marked Reversed and the amount is returned to the open item, keeping the audit trail intact. | | `TDSAmount` | TDS Amount | Currency | | Withholding tax deducted by the payer on this settlement. Like the discount and write-off components it closes part of the open item without cash and is posted on the allocation's journal, which is why the deduction cannot leave the subledger and the GL disagreeing. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `WriteOffAmount` | Write Off Amount | Currency | | Balance written off as part of this settlement — the small residual cleared rather than chased. A non-cash component that posts on the allocation's journal. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [OpenTransaction](/docs/reference/entities/open-transaction/) — looks up via `OpenTransactionId` - [Journal](/docs/reference/entities/journal/) — looks up via `JournalId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Payment](/docs/reference/entities/payment/) — looks up via `PaymentId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Shelf Audit Result — entity reference URL: https://xmatix.com/docs/reference/entities/shelf-audit-result/ Last reviewed: 2026-08-16 One shelf-vision evaluation run over a merchandising activity's photos - the child result entity of VisitTaskActivity, one row per run so re-analysis history is kept. Carries the planogram-compliance judgment (complianceScore 0-100, complianceStatus, structured findingsJson), share-of-shelf output (shareOfShelfPct plus per-brand shareOfShelfBrandJson and totalFacings), and model observability (modelVersion, galleryVersion, unknownRate). visitId and accountId are denormalized reporting grain copied from the activity's visit at write time, never authoritative. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | Denormalized outlet for reporting, copied from the activity's visit at write time. A metadata lookup only - there is deliberately no database foreign key behind it. | | `AnalyzedAtUtc` | Analyzed At (UTC) | DateAndTime | | | | `ComplianceScore` | Compliance Score | Decimal | | | | `ComplianceStatus` | Compliance Status | PickList | | Categorical planogram judgment: Compliant, Partial, Non-compliant or Unable to Assess. Null-planogram (share-of-shelf-only) runs carry no compliance judgment. Values: Compliant, Partial, Non-compliant, Unable to Assess. | | `EvaluationSource` | Evaluation Source | MultiLineText | | What produced the row - for example the vision pipeline, a configured workflow step, an LLM QA pass, or Manual. Rows from different sources are re-analysis history for the same activity. | | `FindingsJson` | Findings Json | MultiLineText | | | | `GalleryVersion` | Gallery Version | MultiLineText | | | | `ModelVersion` | Model Version | MultiLineText | | | | `PlanogramId` | Planogram | Lookup → [Planogram](/docs/reference/entities/planogram/) | | | | `ShareOfShelfBrandJson` | Share Of Shelf Brand Json | MultiLineText | | | | `ShareOfShelfPct` | Share Of Shelf % | Decimal | | | | `TotalFacings` | Total Facings | Number | | | | `UnknownRate` | Unknown Rate | Decimal | | Fraction (0-1) of detections labeled as unknown product - the stale-recognition-gallery signal the active-learning loop watches. A rising rate means the gallery is missing current SKUs, not that the shelf is wrong. | | `VisitId` | Visit | Lookup → [Visit](/docs/reference/entities/visit/) | | Denormalized reporting grain copied from the evaluated activity's visit at write time - never authoritative; the true parent chain is visitTaskActivityId. | | `VisitTaskActivityId` | Visit Task Activity | Lookup → [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `DeleteEntity` | Delete | Delete | Delete Entity | | `DeleteHeader` | Delete | Delete | Delete Header | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | Edit Entity | | `EditInLineEntity` | Edit | EditInline | Edit In Line Entity | | `EditInLineHeader` | Edit | EditInline | EditInLineHeader | | `EditRow` | Edit | Edit | Edit Row | | `NewHeader` | New | New | New Header | ## Related entities - [Planogram](/docs/reference/entities/planogram/) — looks up via `PlanogramId` - [Visit](/docs/reference/entities/visit/) — looks up via `VisitId` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — looks up via `VisitTaskActivityId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Shelf Product Cluster — entity reference URL: https://xmatix.com/docs/reference/entities/shelf-product-cluster/ Last reviewed: 2026-08-16 A tenant-defined reporting roll-up group for shelf-vision products (for example a beverages family or a competitor cola group). Detection labels are the stable ML vocabulary; clusters are the tenant's reporting layer over them - share of shelf by cluster is the sum of its member products' shares. Its isOwnBrand flag marks every member as counting toward own share of shelf, unioning with the per-product flag. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Description` | Description | MultiLineText | | | | `IsOwnBrand` | Is Own Brand | Boolean | | Marks the whole group as the tenant's own: every member product's detection label counts toward the share-of-shelf numerator without flagging products one by one. Unions with the per-product flag - the two never subtract. | | `Label` | Label | MultiLineText | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `DeleteEntity` | Delete | Delete | Delete Entity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | Delete Row | | `EditEntity` | Edit | Edit | Edit Entity | | `EditInLineEntity` | Edit | EditInline | EditInLineEntity | | `EditInLineHeader` | Edit | EditInline | EditHeader | | `EditRow` | Edit | Edit | EditRow | | `NewHeader` | New | New | NewHeader | ## Related entities - [ShelfProduct](/docs/reference/entities/shelf-product/) — referenced by via `ClusterId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Shelf Product — entity reference URL: https://xmatix.com/docs/reference/entities/shelf-product/ Last reviewed: 2026-08-16 The tenant's reporting identity for one shelf-vision detection label: maps a stable, lowercase gallery label (detectionLabel) to a display name, an optional roll-up cluster (clusterId) and the isOwnBrand flag that drives the share-of-shelf numerator. One row per label, enforced by a filtered unique index, so reporting joins stay unambiguous. When any active rows have isOwnBrand set they supersede the feature-setting CSV fallback of target brands. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ClusterId` | Cluster | Lookup → [ShelfProductCluster](/docs/reference/entities/shelf-product-cluster/) | | | | `Description` | Description | MultiLineText | | | | `DetectionLabel` | Detection Label | MultiLineText, unique | Yes | The recognition-gallery label this product maps to - must match a gallery label verbatim (lowercase, hyphenated). One row per label, enforced by a filtered unique index; the human-friendly name lives in the row's display name, not here. | | `IsOwnBrand` | Is Own Brand | Boolean | | Counts this label toward the tenant's own share-of-shelf numerator. When any active rows set it, they supersede the feature-setting CSV of target brands; it also unions with the cluster-level own-brand flag. | | `Label` | Label | MultiLineText | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | Delete Header | | `DeleteRow` | Delete | Delete | Delete Row | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLineEntity` | Edit | EditInline | EditInLineEntity | | `EditInLineHeader` | Edit | EditInline | Edit In Line Header | | `EditRow` | Edit | Edit | Edit Row | | `NewHeader` | New | New | New Header | ## Related entities - [ShelfProductCluster](/docs/reference/entities/shelf-product-cluster/) — looks up via `ClusterId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Shipment Asset Line — entity reference URL: https://xmatix.com/docs/reference/entities/shipment-asset-line/ Last reviewed: 2026-08-16 A per-unit identity row hanging off a Shipment, and optionally off one of its lines, for serialised or asset-tracked goods such as vehicles and machines: serial, engine, component, batch and lot numbers, product code, description and family, manufacturing plant and month or year, and the eventual sale-side fields (sale date, sale invoice number, selling branch and selling partner). The serial and lot identity the running system does use travels on ItemLot instead, referenced from delivery and receipt lines. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `AssetNumber` | Asset Number | Text | | | | `BatchNo` | Batch No | Text | | | | `ComponentNumber` | Component Number | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeliveryDate` | Delivery Date | Date | | | | `EngineNumber` | Engine Number | Text | | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `LotNumber` | Lot Number | Text | | | | `ManufactureDate` | Manufacture Date | Date | | | | `ManufacturingMonth` | Manufacturing Month | Number | | | | `ManufacturingYear` | Manufacturing Year | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `Name (dup-e0e45c92)` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlantName` | Plant Name | Text | | | | `Price` | Price | Currency | | | | `ProductCode` | Product Code | Text | | | | `ProductDescription` | Product Description | Text | | | | `ProductFamily` | Product Family | PickList | | | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SaleDate` | Sale Date | Date | | | | `SaleInvoiceNumber` | Sale Invoice Number | Text | | | | `SellingBranchId` | Selling Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The branch that eventually sold this individual unit, recorded on the inbound asset row so a unit can be traced from arrival to sale. It belongs to the sale-side group with SaleDate, SaleInvoiceNumber and SellingPartnerAccountId, none of which any code populates. | | `SellingPartnerAccountId` | Selling Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `SerialNumber` | Serial Number | Text | | The manufacturer's serial or chassis number for the individual unit, kept alongside separate engine and component numbers. | | `ShipmentId` | Shipment | Lookup → [Shipment](/docs/reference/entities/shipment/) | | | | `ShipmentLineId` | Shipment Line | Lookup → [ShipmentLine](/docs/reference/entities/shipment-line/) | | Optionally narrows the asset row to one specific shipment line rather than the shipment as a whole, which is how several serialised units of the same item on one line would each get their own identity row. | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `Status` | Status | PickList | | Seeded with the values Draft, Shipped and Registered, describing where the individual unit is in its handover lifecycle. No code writes it, so it reflects only what a user or an integration puts there. Values: Shipped, Registered, Draft. | | `StatusReason` | Status Reason | PickList | | Seeded with the values Online, Standby and Offline, which describe the unit's operational condition rather than qualifying the shipment status it sits next to. Nothing in the platform sets or reads it. Values: Online, Standby, Offline. | | `StockKeepingUnit` | Product SKU | Text | | A free-text stock-keeping code as supplied by the sender, held separately from SKUId, which is the resolved lookup to the platform's own SKU record. The two can disagree and nothing reconciles them. | | `SupplierInvoiceDate` | Supplier Invoice Date | Date | | | | `SupplierInvoiceNumber` | Supplier Invoice Number | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VehicleOKDate` | Vehicle OK Date | Date | | The date the unit passed its pre-delivery inspection and was declared fit to hand over. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `EditLineDetail` | Edit | EditInline | Edit | | `New` | New | New | New | ## Related entities - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Shipment](/docs/reference/entities/shipment/) — looks up via `ShipmentId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [ShipmentLine](/docs/reference/entities/shipment-line/) — looks up via `ShipmentLineId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `SellingPartnerAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `SellingBranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Shipment Line — entity reference URL: https://xmatix.com/docs/reference/entities/shipment-line/ Last reviewed: 2026-08-16 One item line of a Shipment, carrying the in-transit quantity for a single item. Its one seeded ledger rule adds Quantity minus CancelledQuantity to the InventoryStock Pipeline bucket when the shipment is posted - not when the line is created - and stamps InventoryLedgerId, which is exactly what the goods-receipt ledger rules test to decide whether receiving converts pipeline stock or adds fresh inward stock. PendingQuantity is calculated as Quantity minus ReceiptQuantity minus CancelledQuantity and is the gate the release-receipt and cancel actions check. Unlike a delivery order line it may not carry lot or storage-location detail: the handler rejects a non-empty ItemLotId or StorageLocationId outright, so lot assignment happens at goods receipt instead. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Total Amount | Calculated (calculated) | | | | `CancelledQuantity` | Cancelled Quantity | Number | | Quantity written off by the cancel-shipment actions - goods that were dispatched but will never be received. It reduces PendingQuantity and is subtracted from the quantity posted to Pipeline, but only on the next posting pass, since a cancellation alone does not re-post the line. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeliveryOrderLineId` | Delivery Order Line | Lookup → [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) | | A lookup back to the delivery order line that caused this shipment line. | | `ExcludeInAutoOrder` | Exclude In Auto Order | Boolean | Yes | Opts this in-transit line out of the automatic replenishment calculation. Auto-ordering counts shipment lines with pending quantity as incoming supply, so setting this makes the planner ignore the line and potentially reorder the same goods. | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | Stamped when the line posts its quantity into the Pipeline bucket. Downstream it is a discriminator rather than mere provenance: the goods-receipt ledger rules test whether the source shipment line has one to choose between converting pipeline stock and adding fresh inward stock. It is a system field and cannot be set by hand. | | `InvoiceLineId` | Invoice Line | Lookup → [InvoiceLine](/docs/reference/entities/invoice-line/) | | | | `IsILPosted` | IL Posted | Boolean | Yes | A per-line inventory-posted flag that no code writes; InventoryLedgerId is the marker that actually records posting. It is nonetheless treated as a system field, so it cannot be set on insert. | | `IsILPostingApproved` | IL Posting Approved | Boolean | Yes | An approval gate for posting this line. The service that would set it in bulk is never called, but the handler does enforce a rule when it is switched to true on an update: the line is checked as postable against its ReceiptQuantity. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | Not usable on this entity: the handler rejects any shipment line with a lot set, with 'Storage Location and Item Lot is not supported for Shipment Lines'. Lot assignment happens at goods receipt, on the receipt line, not while the goods are in transit. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PendingQuantity` | Pending Quantity | Calculated (calculated) | | Calculated as Quantity minus ReceiptQuantity minus CancelledQuantity: how much of the dispatched line is neither received nor written off. Both the release-receipt and cancel actions refuse to run unless at least one line still has some, and the selective variants cap each requested quantity against it. | | `PurchaseOrderDate` | Purchase Order Date | Date | | | | `PurchaseOrderId` | Purchase Order | Lookup → [PurchaseOrder](/docs/reference/entities/purchase-order/) | | | | `PurchaseOrderLineId` | Purchase Order Line | Lookup → [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) | | | | `Quantity` | Quantity | Decimal | Yes | The quantity dispatched on this line. Posting adds Quantity minus CancelledQuantity to the Pipeline bucket, and editing Quantity (or UnitPrice) is what re-posts the line's ledger movement - changing other fields does not. | | `ReceiptQuantity` | Receipt Quantity | Number | | A live roll-up of GoodsReceiptLine.SupplierQuantity over the receipt lines pointing at this shipment line, reconciled for added, edited and deleted receipt lines alike. It is a system field: it cannot be edited directly, and a line with a non-zero value cannot be deleted. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequestedQuantity` | Requested Quantity | Number | | A virtual, non-stored argument field: the selective release-receipt and selective cancel actions pass a per-line quantity through it, validated against PendingQuantity. It is never persisted and means nothing when read back from a saved row. | | `ShipmentId` | Shipment | Lookup → [Shipment](/docs/reference/entities/shipment/) | Yes | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | Not usable on this entity: the handler rejects any shipment line that carries a storage location, for the same reason it rejects a lot - in-transit stock has not reached a bin yet. The destination bin is chosen on the goods receipt. | | `UIProps` | UI Props | Text | | | | `UnitPrice` | Unit Price | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditInList` | Edit | EditInline | Edit | | `HeaderEdit` | HeaderEdit | EditInline | edit | | `Import` | Import | UIAction | shipment Import | | `MainNew` | New | New | New | | `New` | Quick Add | NewInline | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Quantity Rule Validation | `Quantity`, Error | Quantity can't be zero | Prevents zero or negative quantity on shipment lines | | Unit Price Rule Validation | `UnitPrice`, Error | Unit Price can't be negative | Prevents zero or negative unit price on shipment lines | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Sku For Item | `SKUId` | | ## Related entities - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — looks up via `PurchaseOrderId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — looks up via `DeliveryOrderLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — looks up via `InvoiceLineId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [Shipment](/docs/reference/entities/shipment/) — looks up via `ShipmentId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — looks up via `PurchaseOrderLineId` - [ShipmentAssetLine](/docs/reference/entities/shipment-asset-line/) — referenced by via `ShipmentLineId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `ShipmentLineId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Shipment — entity reference URL: https://xmatix.com/docs/reference/entities/shipment/ Last reviewed: 2026-08-16 The in-transit leg of a goods movement, held on the receiving side: goods that have left the sender but have not yet been received, parked in the InventoryStock Pipeline bucket until a GoodsReceipt converts them to inward stock. It is the mirror of the sender's DeliveryOrder rather than a duplicate of it - releasing a shipment from a delivery order (or from an invoice) builds a Shipment in which the sender's partner account becomes SupplierAccountId and the receiving account's own Branch becomes BranchId, so one physical movement is an outbound document for the seller and an inbound document for the buying branch. A Shipment can equally stand alone against a PurchaseOrder for ordinary supplier deliveries. Its actions are PerformInventoryPosting (quantities into Pipeline), PerformReleaseReceipt and SelectiveReleaseReceipt (raise the GoodsReceipt), and CancelShipment and SelectiveCancelShipment (write off quantity that will never arrive). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The receiving branch, and the branch whose InventoryStock Pipeline bucket the posting fills. When the shipment is released from a delivery order this is resolved as the Branch whose PartnerAccountId equals the delivery's customer account, and the release fails outright when no such branch exists. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeliveryOrderDate` | Delivery Order Date | Date | | | | `DeliveryOrderNumber` | Delivery Order Number | Text | | To trace a shipment back to the delivery that created it, match on the shipment's generated name, which is the delivery order's name prefixed with SHP-. | | `DocumentDate` | Document Date | Calculated (calculated) | | Not a stored column: its getter and setter both read and write ShipmentDate, so writing either field changes the same value. It exists so shipments answer the same document-date convention as the other transaction documents. | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `InvoiceId` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | | | `IsDealerShipmentCreated` | Is Dealer Shipment Created | Boolean | | | | `IsInJobQueue` | In Job Queue | Boolean | Yes | | | `IsInventoryPosted` | Inventory Posted | Boolean | Yes | The reliable posted marker is InventoryLedgerId on the shipment lines, which is also what the goods-receipt rules read. | | `IsReceiptReleased` | Receipt Released | Boolean | Yes | Intended to mark that a goods receipt has been raised from this shipment, but no code path sets it. Look instead for GoodsReceipt rows linked to the shipment, or at the lines' ReceiptQuantity and PendingQuantity. | | `JobInterfaceQueueId` | Job Queue | Lookup → [InterfaceQueue](/docs/reference/entities/interface-queue/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The receiving company that owns this inbound document. On a shipment released from a delivery order it is the delivery's customer account, and it is validated against BranchId and locked after creation. | | `PerformInventoryPosting` | Perform Inventory Posting | Boolean | Yes | Nothing writes or reads this column. | | `PerformReleaseReceipt` | Perform Release Receipt | Boolean | Yes | | | `PurchaseOrderId` | Purchase Order | Lookup → [PurchaseOrder](/docs/reference/entities/purchase-order/) | | The purchase order this inbound shipment answers, for the ordinary supplier flow where the shipment is created directly rather than released from someone else's delivery order. It is empty on shipments generated from a delivery order or an invoice. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `ShipmentDate` | Shipment Date | Date | | The date the goods left the sender, defaulted to the current date and time when the shipment is created. It is the same underlying value as DocumentDate, which is a pass-through alias for it. | | `Status` | Status | PickList | | Seeded with three active values (Draft, Interface and a misspelled 'Recieved') but never assigned by any code path, so it does not track receipt progress. Use the line-level InventoryLedgerId, ReceiptQuantity and PendingQuantity for machine state. Values: Draft, Interface, Recieved, Partially Cancelled, Cancelled. | | `SupplierAccountId` | Supplier Account | Lookup → [Account](/docs/reference/entities/account/) | | The account the goods are coming FROM. When the shipment is released from a delivery order this is the delivery's partner account, i.e. the selling company - the party roles are swapped so the same movement reads as inbound from the receiving branch's point of view. | | `SupplierInvoiceDate` | Supplier Invoice Date | Date | | | | `SupplierInvoiceNumber` | Supplier Invoice Number | Text | | The sender's own invoice or dispatch document number, captured for reconciliation when the goods are received and billed. It is reference data - the platform does not match it automatically to a Bill. | | `TotalPendingQuantity` | Total Pending Quantity | Calculated (calculated) | | | | `TransporterName` | Transporter Name | Text | | | | `TransporterReferenceNo` | Transporter Reference No | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `CancelShipment` | Cancel Shipment | ServerAction (`CancelShipment`) | Adds each line's remaining PendingQuantity to its CancelledQuantity, closing out stock that will never be received; PendingQuantity then nets the cancellation the same way it nets receipts. It is refused when no line has PendingQuantity above zero. Be aware it does not itself reverse an already-posted Pipeline movement: the shipment line only re-posts to the ledger when Quantity or UnitPrice changes, and CancelledQuantity is not in that trigger set, so a shipment cancelled after PerformInventoryPosting leaves its pipeline stock standing until the line is re-posted. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInDetail` | Edit | EditInline | edit | | `EditInList` | Edit | EditInline | Edit | | `Import` | Import | UIAction | Import Shipment | | `New` | New | New | New | | `PerformInventoryPosting` | Post Inventory | ServerAction (`PerformInventoryPosting`) | Posts the shipment's unposted lines into the InventoryStock Pipeline bucket, making the goods visible as in-transit before they physically arrive, and stamps InventoryLedgerId on each line - the marker the goods-receipt ledger rules read to decide whether receiving converts pipeline stock or adds fresh inward stock. The quantity posted is Quantity minus CancelledQuantity, and Pipeline is not a cost event, so no cost journal is raised. Note the seeded action row itself is inactive and hidden, so it is normally invoked programmatically rather than from the UI. | | `PerformReleaseReceipt` | Release Receipt | ServerAction (`PerformReleaseReceipt`) | PerformReleaseReceipt | | `SelectiveCancelShipment` | Selective Cancel Shipment | ServerAction (`SelectiveCancelShipment`) | Same as CancelShipment but limited to the shipment lines named in the args payload under ShipmentLines, each capped by its RequestedQuantity; an empty list or ids that match no line is rejected rather than treated as 'cancel everything'. | | `SelectiveGRN` | Selective Release Receipt | ServerAction (`SelectiveReleaseReceipt`) | A second UI entry point for selective goods receipt, not a separate behaviour and not dead: its ServerActionName is SelectiveReleaseReceipt, and handler dispatch resolves on ServerActionName rather than the action name, so it runs the same selective receipt logic as the SelectiveReleaseReceipt action. The two differ only in the layout they open (SelectiveGoodsReceipt versus SelectiveReleaseReceipt) and in the confirmation dialog. | | `SelectiveReleaseReceipt` | Selective Release Receipt | ServerAction (`SelectiveReleaseReceipt`) | SelectiveReleaseReceipt | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Only Partner Account | `PartnerAccountId` | | | Only sSupplier | `SupplierAccountId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — looks up via `PurchaseOrderId` - [InterfaceQueue](/docs/reference/entities/interface-queue/) — looks up via `JobInterfaceQueueId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [Account](/docs/reference/entities/account/) — looks up via `SupplierAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `PurchaseOrderShipmentId` - [ShipmentAssetLine](/docs/reference/entities/shipment-asset-line/) — referenced by via `ShipmentId` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `ShipmentId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ParentRecordId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — referenced by via `ShipmentId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Side Conversation Message — entity reference URL: https://xmatix.com/docs/reference/entities/side-conversation-message/ Last reviewed: 2026-08-16 One message inside a SideConversation (sideConversationId is the parent). direction is Outbound or Inbound (defaults to Outbound); body, fromAddress and toAddress carry the content and addressing, and sentByUserId records the sending user. Rows are created by the StartSideConversation action (when an initial body is supplied) and by ReplySideConversation - the service records the message on the thread; automatic outbound dispatch through a messaging template is a later-phase wiring, so a stored row does not by itself mean the message left the platform. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Body` | Body | Text | | | | `Direction` | Direction | PickList | | Outbound or Inbound; defaults to Outbound when not supplied. Direction decides whether sentOn is stamped. Values: Outbound, Inbound. | | `FromAddress` | From | Text | | | | `MessagingTemplateId` | Messaging Template | Lookup | | Optional reference to the messaging template used to compose the message. Automatic outbound dispatch via the template is a later-phase wiring - the current service records the message row without sending through it. | | `SentByUserId` | Sent By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `SentOn` | Sent On | DateAndTime | | Stamped with the current UTC time only for Outbound messages at creation; Inbound rows leave it null. | | `SideConversationId` | Side Conversation | Lookup → [SideConversation](/docs/reference/entities/side-conversation/) | Yes | | | `ToAddress` | To | Text | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `EditInLine` | Edit | EditInline | Edit in page. | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Side Conversation — entity reference URL: https://xmatix.com/docs/reference/entities/side-conversation/ Last reviewed: 2026-08-16 A private message thread hung off a record - typically a Case - to coordinate with a third party or vendor without the customer seeing it (side conversations are internal-only by design and never customer-visible). channel is Email or Internal (defaults to Email when started), status is Open or Closed. The messages themselves are child SideConversationMessage rows. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Channel` | Channel | PickList | | Email or Internal. Defaults to Email when the thread is started without an explicit channel. Values: Email, Internal. | | `RecordId` | Record | Lookup → [Case](/docs/reference/entities/case/) | Yes | The id of the record this thread hangs off (a Case, or any entity with the side-conversation actions registered). Note it is the bare record id only - the entity name is not stored on the conversation; replies and closes address the conversation by its own id. | | `Status` | Status | PickList | | Open or Closed. Set to Open on start; the CloseSideConversation action flips it to Closed. Replies do not reopen a closed thread. Values: Open, Closed. | | `Subject` | Subject | Text | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `EditInLine` | Edit | EditInline | Edit in page. | ## Related entities - [Case](/docs/reference/entities/case/) — looks up via `CaseId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Skill — entity reference URL: https://xmatix.com/docs/reference/entities/skill/ Last reviewed: 2026-08-16 An agent's actual competency is a child ResourceSkill row. Note: skill-based routing currently matches by ResourceSkill.Name, and nothing reads the policy field yet - this master is structural. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Description` | Description | Text | | | | `Name` | Name | Text | | | | `Policy` | Policy | Text | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRow` | Edit | Edit | EditRow | | `NewHeader` | New | New | NewHeader | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # SKU — entity reference URL: https://xmatix.com/docs/reference/entities/sku/ Last reviewed: 2026-10-09 A SKU is one variant of an item, such as a colour or finish, that is sold, bought and stocked separately under its own code. Every SKU belongs to one item and is added from the item record's Related tab. Document lines across sales, purchasing, inventory and service carry a SKU next to the item; when a line is added, the SKU must be one of the item's own SKUs, and when the item has SKU Required switched on, the line must name a SKU. Stock is kept per partner account, branch, item, SKU and storage location, so stock without a SKU is a separate balance. Price list, discount group, tax group and trade scheme rules can target one SKU; a rule with no SKU applies to all of the item's SKUs. SKU codes are unique across the organization. The Default flag is a preference only: it is not enforced as unique, and a line you add by hand does not take its SKU from it. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | Text, unique | | A reference to this SKU in an external system, used by integrations and imports. Unique across the organization when filled. | | `Id` | Id | Guid | Yes | | | `IsDefault` | Default | Boolean | | Marks the item's preferred variant. The published catalogue lists default variants first and the purchase frequently-ordered suggestion proposes the default SKU. Nothing prevents several defaults per item, and a line you add by hand does not take its SKU from it. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | The parent item. A document line is rejected when its SKU does not belong to the line's item, and most line SKU pickers list only the SKUs of the item on the line. | | `MaximumLotQuantity` | Maximum Lot Quantity | Number | | The largest quantity one goods receipt or shipment line may carry for this variant; a larger line is split into several lines when it is added. Transfer lines split only when the cap is 1. Zero means the item's value is used; above zero, the SKU value takes precedence. Lines already saved are not re-split. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | The variant's name as people read it in pickers and lists. Required. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ProductColor` | Product Color | PickList | | The variant's colour, from the values Red, Blue, Yellow, Orange, Purple, Black, White and Grey. When set, it is the label the order-taking screen shows for the variant; otherwise the SKU code and then the name are used. Values: Red, Blue, Yellow, Orange, Purple, Black, White, Grey. | | `QuantityUnitOfMeasure` | Primary UOM | PickList | | The variant's base unit; Each is the only seeded value. Order capture prefers it over the item's unit. Alternate units and conversion ratios are maintained on the item. Values: Each. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SKUCode` | SKU Code | Text, unique | Yes | The variant's own code. Required and unique across the organization, not only within the item, so a convention that includes the item code avoids collisions. Order capture and barcode scanning can match on it. | | `UIProps` | UI Props | Text | | | | `UnitOfMeasureOfConversion` | UOM Conversion | Number | | Not used: the field stores no data. Unit conversions for an item are maintained on the item's units of measure. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | This Button help to clone the item | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit In Page | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditPopup` | Edit | Edit | EditPopup | | `New` | New | New | New | | `NewInLine` | New | NewInline | New In Line | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `SKUId` - [InspectionLine](/docs/reference/entities/inspection-line/) — referenced by via `SKUId` - [AutoPurchaseOrderLine](/docs/reference/entities/auto-purchase-order-line/) — referenced by via `SKUId` - [CycleCountLine](/docs/reference/entities/cycle-count-line/) — referenced by via `SKUId` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `SKUId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `SKUId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `SKUId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `SKUId` - [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) — referenced by via `SKUId` - [ItemRelation](/docs/reference/entities/item-relation/) — referenced by via `SKUId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `SKUId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `SKUId` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `SKUId` - [RequisitionLine](/docs/reference/entities/requisition-line/) — referenced by via `SKUId` - [ItemGroupMember](/docs/reference/entities/item-group-member/) — referenced by via `SKUId` - [ItemInventoryAttribute](/docs/reference/entities/item-inventory-attribute/) — referenced by via `SKUId` - [ItemComponent](/docs/reference/entities/item-component/) — referenced by via `ComponentSKUId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `SKUId` - [ItemMaintenanceSchedule](/docs/reference/entities/item-maintenance-schedule/) — referenced by via `ItemSKUId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `SKUId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `SKUId` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — referenced by via `SKUId` - [ItemCart](/docs/reference/entities/item-cart/) — referenced by via `SKUId` - [ItemLot](/docs/reference/entities/item-lot/) — referenced by via `SKUId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `SKUId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — referenced by via `SKUId` - [Asset](/docs/reference/entities/asset/) — referenced by via `SKUId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `SKUId` - [ItemUnitOfMeasure](/docs/reference/entities/item-unit-of-measure/) — referenced by via `SKUId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — referenced by via `DiscountedSKUId` - [StoreCategoryItem](/docs/reference/entities/store-category-item/) — referenced by via `SKUId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `SKUId` - [ItemAlias](/docs/reference/entities/item-alias/) — referenced by via `SKUId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `SKUId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `SKUId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `SKUId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — referenced by via `SKUId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `SKUId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — referenced by via `SKUId` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `SKUId` - [TransferLine](/docs/reference/entities/transfer-line/) — referenced by via `SKUId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `SKUId` - [TaxGroupRule](/docs/reference/entities/tax-group-rule/) — referenced by via `SKUId` - [ShipmentAssetLine](/docs/reference/entities/shipment-asset-line/) — referenced by via `SKUId` - [ItemComponent](/docs/reference/entities/item-component/) — referenced by via `SKUId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `SKUId` - [Lead](/docs/reference/entities/lead/) — referenced by via `SKUId` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `SKUId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # SLA — entity reference URL: https://xmatix.com/docs/reference/entities/sla/ Last reviewed: 2026-08-16 A service-level agreement catalog entry pairing a priority/severity classification with target response and resolution times. Standalone reference data: in first-party metadata nothing links SLA records to contracts, cases or service orders — associating an SLA with other records is left to tenant customization. The time targets are stored as picklist strings (for example 4 Hours), not numeric durations. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Priority` | Priority | PickList | | Priority band this SLA entry covers. Seeded values: Critical, High, Medium, Low. Values: Critical, High, Medium, Low. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `ResolutionTime` | Resolution Time | PickList | | Target time to resolution. Stored as a picklist string (seeded: 12 Hours, 24 Hours, 36 Hours, 48 Hours), not a numeric duration. Values: 12 Hours, 24 Hours, 36 Hours, 48 Hours. | | `ResponseTime` | Response Time | PickList | | Target time to first response. Stored as a picklist string (seeded: 4 Hours, 8 Hours, 12 Hours, 24 Hours), not a numeric duration — do not treat it as a number. Values: 4 Hours, 8 Hours, 12 Hours, 24 Hours. | | `SeverityLevel` | Severity Level | PickList | | Severity classification of the SLA entry. Five seeded values with inconsistent formats: Critical - Immediate Attn Req., High - Immediate Attn Req., Medium - Respond within hours, Low - Low Priority, and Medium - High. Match on the stored string exactly. Values: Critical - Immediate Attn Req., High - Immediate Attn Req., Medium - Respond within hours, Low - Low Priority, Medium - High. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `Type` | Type | PickList | | Category of the SLA entry. Picklist-typed with no first-party values seeded — the vocabulary is tenant-defined. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | EditInline | Edit | | `New` | New | New | New | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # SLA Policy — entity reference URL: https://xmatix.com/docs/reference/entities/slapolicy/ Last reviewed: 2026-08-16 Service-level targets matched to Cases: the SLA engine picks the highest-rank active policy whose matchFormula (a DynamicExpresso predicate over the Case, e.g. Priority == "High"; empty matches everything) evaluates true, then computes first-response and resolution due dates in working minutes against businessHoursId (null = 24x7 calendar time). warningPercent sets when a Warning fires; pauseStatuses is a CSV of case statuses that pause the clock. Custom milestones beyond the built-in FirstResponse/Resolution pair are child MilestoneConfig rows. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BusinessHoursId` | Business Hours | Lookup → [BusinessHours](/docs/reference/entities/business-hours/) | | | | `Description` | Description | Text | | | | `FirstResponseMinutes` | First Response (min) | Number | | | | `IsActive` | Active | Boolean | Yes | | | `IsDefault` | Default | Boolean | | | | `MatchFormula` | Match Formula | Text | | DynamicExpresso predicate evaluated against the Case to decide whether this policy applies (e.g. Priority == "High"). Null/empty matches every case - pair that with IsDefault or a low Rank as the catch-all. | | `Name` | Name | Text | | | | `PauseStatuses` | Pause Statuses | Text | | CSV of Case statuses that pause the SLA clock for cases under this policy (e.g. "Waiting on Customer,On Hold"). When empty, the engine falls back to the default waiting statuses (On Hold, Waiting on Customer, Waiting on Third Party). | | `Rank` | Rank | Number | | Tie-breaker when several active policies match the same case: the highest rank wins. | | `ResolutionMinutes` | Resolution (min) | Number | | | | `WarningPercent` | Warning % | Number | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInLineList` | Edit | EditInline | EditInLineList | | `EditRow` | Edit | Edit | EditRow | | `NewHeader` | New | New | NewHeader | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Storage Location — entity reference URL: https://xmatix.com/docs/reference/entities/storage-location/ Last reviewed: 2026-08-16 A physical or logical stock-holding place inside a branch. LocationType is required and seeded with Warehouse (the default), Store, Showroom, Site, Rack, Engine Bay and Virtual. The hierarchy is self-referencing through ParentStorageLocationId and RootStorageLocationId, alongside separately stored Location, ParentLocation and RootLocation path strings that no code derives. Setting IsMobile turns the record into a van and activates the vehicle and cargo-capacity attributes. Goods in transit are deliberately held outside any location: the transfer transit stock row is keyed with a null StorageLocationId. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AllowInventory` | Inventory | Boolean | Yes | Marks the place as one that may hold stock at all, as opposed to a structural node in the location tree that only exists to group its children. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | Yes | | | `CapacityVolumeM3` | Capacity Volume (m3) | Decimal | | Load capacity by volume in cubic metres for van (mobile) locations, used for capacity planning. | | `CapacityWeightKg` | Capacity Weight (kg) | Decimal | | Load capacity by weight in kilograms for van (mobile) locations, used for capacity planning. | | `CargoHeightCm` | Cargo Height (cm) | Decimal | | | | `CargoLengthCm` | Cargo Length (cm) | Decimal | | Internal cargo compartment length in centimetres, part of the van attributes that apply when the location is marked mobile; used for load planning alongside the volume and weight capacities. | | `CargoWidthCm` | Cargo Width (cm) | Decimal | | | | `CreatedBy` | Created By | Lookup | Yes | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DefaultResourceId` | Default Resource | ExternalId | | The usual driver or rep assigned to this van location. | | `Description` | Description | Text | | | | `ExternalId` | External | ExternalId | | | | `FulfillmentSequenceNumber` | Fulfillment Sequence Number | Number | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Active | Boolean | | Retires a location from selection without deleting it, so historical stock rows, lots and ledger movements that reference it stay intact. | | `IsMobile` | Mobile | Boolean | | | | `Location` | Location | Text | | A stored path string naming this place within its hierarchy. It is persisted rather than derived from the parent and root links, so nothing in the platform recalculates it when the tree is rearranged. | | `LocationLatitude` | LocationLatitude | LongMultiLineText | | | | `LocationLevel` | Location Level | Number | | Numeric depth of this place in the location tree, stored on the record rather than computed from the parent chain; no code path maintains it, so it is only as accurate as it was entered. | | `LocationLongitude` | Location Longitude | Text | | | | `LocationType` | Location Type | PickList | Yes | Values: Site, Virtual, Store, Showroom, Warehouse, Engine Bay, Rack. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentLocation` | ParentLocation | LongMultiLineText | | A stored path string for the enclosing place, held separately from the parent link. Nothing recalculates it, so treat the parent lookup as the authority on the hierarchy and this as a display convenience. | | `ParentStorageLocationId` | Parent Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | Parent in the location tree (a zone within a warehouse, a bin within a zone); rootStorageLocationId is denormalized to the tree's top so queries can scope to a whole warehouse without walking the hierarchy. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RootLocation` | RootLocation | LongMultiLineText | | A stored path string for the top of the hierarchy, held separately from the root lookup and not recalculated by any code path. | | `RootStorageLocationId` | Root Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | The top of this location's branch of the tree, stored alongside the immediate parent so a whole site's locations can be found in one query instead of walking the hierarchy. | | `ServiceJobType` | Service Job Type | PickList | | | | `StorageLocationCode` | Code | Text | | Short internal code for the place, used on labels and in imports where the full record name is impractical. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VehicleNumber` | Vehicle Number | MultiLineText | | Vehicle registration number when the location is a mobile storage location - a van carrying stock rather than a fixed bin. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Delete in page. | | `EditInList` | Edit | Edit | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `New` | New | New | New | | `NewInLine` | New | NewInline, inactive | New In Line | | `UIAction` | UI Action | UIAction | UI Action | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `RootStorageLocationId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `ParentStorageLocationId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `StorageLocationId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `StorageLocationId` - [InventoryValuationPolicy](/docs/reference/entities/inventory-valuation-policy/) — referenced by via `StorageLocationId` - [TransferLine](/docs/reference/entities/transfer-line/) — referenced by via `RelatedStorageLocationId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `StorageLocationId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `StorageLocationId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `StorageLocationId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `StorageLocationId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `StorageLocationId` - [InventoryOpeningLotState](/docs/reference/entities/inventory-opening-lot-state/) — referenced by via `StorageLocationId` - [CycleCount](/docs/reference/entities/cycle-count/) — referenced by via `StorageLocationId` - [TransferLine](/docs/reference/entities/transfer-line/) — referenced by via `StorageLocationId` - [StorageLocation](/docs/reference/entities/storage-location/) — referenced by via `RootStorageLocationId` - [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) — referenced by via `StorageLocationId` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `StorageLocationId` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `StorageLocationId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `StorageLocationId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `StorageLocationId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `StorageLocationId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — referenced by via `StorageLocationId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `StorageLocationId` - [CycleCountLine](/docs/reference/entities/cycle-count-line/) — referenced by via `StorageLocationId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `StorageLocationId` - [ItemLot](/docs/reference/entities/item-lot/) — referenced by via `StorageLocationId` - [Asset](/docs/reference/entities/asset/) — referenced by via `StorageLocationId` - [InspectionLine](/docs/reference/entities/inspection-line/) — referenced by via `StorageLocationId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `StorageLocationId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — referenced by via `StorageLocationId` - [StorageLocation](/docs/reference/entities/storage-location/) — referenced by via `ParentStorageLocationId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Store Category Item — entity reference URL: https://xmatix.com/docs/reference/entities/store-category-item/ Last reviewed: 2026-08-16 A sellable listing under a StoreCategory: itemId links the actual inventory Item (and skuId optionally a specific SKU), while the row carries the storefront presentation - marketing name/description, highlights, howTo, ingredients, knowMore, display pricing (mrpOfItem, price), rating/review text and sequenceNumber ordering. parentStoreCategoryItemId nests listings under a parent listing, and image assets attach via ProductCatalogueImage and StoreItemImage children. The distinct itemIds of a store's listings are what the mobile selling scope reports as the storefront item universe. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AddInLatest` | Add In Latest | Boolean | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDate` | Created Date | DateAndTime | | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrencyIsoCode` | Currency ISO Code | Text | | | | `Description` | Description | Text | | | | `ExternalId` | External | Text | | | | `Highlights` | Highlights | Text | | | | `HowTo` | How To | Text | | | | `Id` | Id | Guid, hidden | Yes | | | `Ingredients` | Ingredients | Text | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | The actual inventory Item this listing sells. The mobile selling scope collects the distinct itemIds across a store's categories as the storefront item universe for order-taking - listings with a null itemId contribute nothing to it. | | `KnowMore` | Know More | Text | | | | `Label` | Label | Text | | | | `MarketingDescription` | Marketing Description | Text | | | | `MarketingName` | Marketing Name | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `MrpOfItem` | MRP Of Item | Decimal | | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `ParentStoreCategoryItemId` | Parent Store Category Item | Lookup → [StoreCategoryItem](/docs/reference/entities/store-category-item/) | | Self-referencing parent listing - lets listings nest under a parent StoreCategoryItem; image rows also reference both the item and its parent. | | `Price` | Price | Decimal | | | | `PriceOfItem` | Price Of Item | Decimal | | | | `Quantity` | Quantity | Text | | | | `Rating` | Rating | Text | | | | `RatingReviews` | Rating Reviews | Text | | | | `Reviews` | Reviews | Text | | | | `SequenceNumber` | Sequence Number | LargeNumber | | | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StoreCategoryId` | Store Category | Lookup → [StoreCategory](/docs/reference/entities/store-category/) | | | | `Tag` | Tag | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UserCount` | User Count | LargeNumber | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | DeleteRow | | `Edit` | Edit | EditInline | Edit | | `Edit1` | Edit | EditInline | Edit | | `EditEntity` | Edit | UIAction | EditEntity | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Related entities - [StoreCategory](/docs/reference/entities/store-category/) — looks up via `StoreCategoryId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [StoreCategoryItem](/docs/reference/entities/store-category-item/) — looks up via `ParentStoreCategoryItemId` - [StoreItemImage](/docs/reference/entities/store-item-image/) — referenced by via `StoreCategoryItemId` - [StoreItemImage](/docs/reference/entities/store-item-image/) — referenced by via `ParentStoreCategoryItemId` - [ProductCatalogueImage](/docs/reference/entities/product-catalogue-image/) — referenced by via `StoreCategoryItemId` - [StoreCategoryItem](/docs/reference/entities/store-category-item/) — referenced by via `ParentStoreCategoryItemId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Store Category — entity reference URL: https://xmatix.com/docs/reference/entities/store-category/ Last reviewed: 2026-08-16 Classifies items within a storefront: belongs to a Store (storeId) and optionally to a ProductCatalogue (catalogueId), nests into subcategories via the self-referencing storeCategoryId, and holds its sellable listings as StoreCategoryItem children. The store's categories define the item universe the mobile selling scope filters order-taking against - items are collected from StoreCategoryItem rows across all of a store's categories. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CatalogueId` | Product Catalogue | Lookup → [ProductCatalogue](/docs/reference/entities/product-catalogue/) | | Optional link to the owning ProductCatalogue; the category can also hang directly off the Store via storeId. The catalogue groups categories and carries the storefront filter configuration. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrencyIsoCode` | Currency ISO Code | Text | | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid, hidden | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `ShowInCatalog` | Show In Catalog | Boolean | | Whether this category surfaces in the catalogue browse (defaults to false, so a new category is hidden until enabled). | | `StoreCategoryId` | Parent Category | Lookup → [StoreCategory](/docs/reference/entities/store-category/) | | Self-referencing parent category - non-null makes this a subcategory in the category tree, null makes it a top-level category of the store. | | `StoreId` | Store | Lookup → [Store](/docs/reference/entities/store/) | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | DeleteRow | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLineEntity` | Edit | EditInline | EditInLineEntity | | `EditRow` | Edit | Edit | Edit Row | | `New` | New | New | New | ## Related entities - [Store](/docs/reference/entities/store/) — looks up via `StoreId` - [StoreCategory](/docs/reference/entities/store-category/) — looks up via `StoreCategoryId` - [ProductCatalogue](/docs/reference/entities/product-catalogue/) — looks up via `CatalogueId` - [StoreCategoryItem](/docs/reference/entities/store-category-item/) — referenced by via `StoreCategoryId` - [StoreCategory](/docs/reference/entities/store-category/) — referenced by via `StoreCategoryId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Store Dealer — entity reference URL: https://xmatix.com/docs/reference/entities/store-dealer/ Last reviewed: 2026-08-16 Links a Store to a dealer: a partner Account (partnerAccountId) and optionally a Branch (branchId), with city/state display fields. In storefront resolution it is the second path tried - after a direct Store.partnerAccountId match and before the account-group path - and is the link most tenants can populate from the UI. When the caller's branch is known, branch-specific dealer rows win over branch-less ones; a dealer row with no branch applies everywhere. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Optional branch scope: when the caller's branch is known, branch-specific rows win over branch-less ones during storefront resolution; a row with no branch applies to every branch of the dealer. | | `City` | City | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrencyIsoCode` | Currency ISO Code | Text | | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid, hidden | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The dealer partner Account this row grants the store to. Storefront resolution tries a direct Store.partnerAccountId match first, then rows here, then the account-group path - so this is the dealer-level override link. | | `State` | State | Text | | | | `StoreId` | Store | Lookup → [Store](/docs/reference/entities/store/) | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | DeleteRow | | `Edit` | Edit | EditInline | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLineEntity` | Edit | EditInline | EditInLine Entity | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Partner Account Filter | `PartnerAccountId` | | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Store](/docs/reference/entities/store/) — looks up via `StoreId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Store Item Image — entity reference URL: https://xmatix.com/docs/reference/entities/store-item-image/ Last reviewed: 2026-08-16 An image row attached to a StoreCategoryItem - both storeCategoryItemId and parentStoreCategoryItemId are required links, and the underlying Item can be linked too. Carries linkUrl plus coordinate, shape and detail attributes on the row. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Coordinate` | Coordinate | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Detail` | Detail | Text | | | | `Id` | Id | Guid | Yes | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `LinkUrl` | Link Url | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `ParentStoreCategoryItemId` | Parent Store Category Item | Lookup → [StoreCategoryItem](/docs/reference/entities/store-category-item/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Shape` | Shape | PickList | | Stores shape like poly, rectangle, etc. | | `StoreCategoryItemId` | Store Category Item | Lookup → [StoreCategoryItem](/docs/reference/entities/store-category-item/) | Yes | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `DeleteRow` | Delete | Delete | DeleteRow | | `EditEntity` | Edit | Edit | EditEntity | | `EditHeader` | Edit | EditInline | EditHeader | | `EditRow` | Edit | Edit | EditRow | | `NewHeader` | New | New | New | ## Related entities - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [StoreCategoryItem](/docs/reference/entities/store-category-item/) — looks up via `StoreCategoryItemId` - [StoreCategoryItem](/docs/reference/entities/store-category-item/) — looks up via `ParentStoreCategoryItemId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Store — entity reference URL: https://xmatix.com/docs/reference/entities/store/ Last reviewed: 2026-08-16 A storefront: the catalog universe a partner account sells from, hosting ProductCatalogue and StoreCategory rows (whose StoreCategoryItem children name the sellable items). Ownership is resolved three ways, tried in order: directly via partnerAccountId, via a StoreDealer link, or via partnerAccountGroupId through the partner's account groups - and because Store has no active flag, the newest matching store wins as a deterministic tie-break. The mobile selling scope uses the resolved store's distinct item ids as the item universe for order-taking; a store whose categories contain no items is treated as unconfigured rather than deliberately empty. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrencyIsoCode` | Currency ISO Code | Text | | | | `Description` | Description | Text | | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid, hidden | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | | | | `PartnerAccountGroupId` | Partner Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteRow` | Delete | Delete | DeleteRow | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | EditInLine | | `EditRow` | Edit | Edit | EditRow | | `New` | New | New | New | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `PartnerAccountGroupId` - [StoreCategory](/docs/reference/entities/store-category/) — referenced by via `StoreId` - [StoreDealer](/docs/reference/entities/store-dealer/) — referenced by via `StoreId` - [ProductCatalogue](/docs/reference/entities/product-catalogue/) — referenced by via `StoreId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Subscription Setting — entity reference URL: https://xmatix.com/docs/reference/entities/subscription-settings/ Last reviewed: 2026-08-16 A dormant generic key/value settings table left over from an earlier configuration approach. Never cite it as the place a tenant setting lives or propose writing configuration into it - platform and module configuration is held by the dedicated settings entities and the module/feature settings stores instead. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `IsSystem` | Is System | Boolean | | Intended to mark a setting as platform-owned and therefore not user-editable, but nothing enforces it because no code path reads this entity at all. | | `Key` | Key | Text | | The intended setting name in this dormant key/value store. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `Value` | Value | Text | | The intended setting payload, stored as text. No code reads it, so it cannot change any platform behaviour; real configuration lives in the dedicated settings entities and the module/feature settings stores. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Subscription Usage Summary — entity reference URL: https://xmatix.com/docs/reference/entities/subscription-usage-summary/ Last reviewed: 2026-08-16 A billing-window rollup of usage under a Subscription (summaryStartDate to summaryEndDate) tracking billedQuantity against unbilledQuantity, with override fields (overrideQuantity, overrideAmount, overrideSummaryEndDate) to adjust what gets charged. The usage-billing pass selects summaries with unbilled quantity on due, non-terminated Usage subscriptions, prices them (slab pricing from the item's consumption schedule when one exists, otherwise unit price), creates invoice lines, and stamps invoiceId/invoiceLineId back on the summary while advancing the subscription's billing dates. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BilledQuantity` | Billed Quantity | Decimal | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `InvoiceId` | Sale Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | | | `InvoiceLineId` | Sale Invoice Line | Lookup → [InvoiceLine](/docs/reference/entities/invoice-line/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Summary Name | Text | Yes | | | `NextBillingDate` | Next Billing Date | Date | | | | `OverrideAmount` | Overre Amount | Currency | | | | `OverrideQuantity` | Overre Quantity | Decimal | | | | `OverrideSummaryEndDate` | Overre Summary End Date | Date | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SubscriptionId` | Subscription | Lookup → [Subscription](/docs/reference/entities/subscription/) | | | | `SummaryEndDate` | Summary End Date | Date | | | | `SummaryStartDate` | Summary Start Date | Date | | | | `UIProps` | UI Props | Text | | | | `UnbilledQuantity` | Unbilled Quantity | Decimal | | | | `UnitPrice` | Unit Price | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Subscription](/docs/reference/entities/subscription/) — looks up via `SubscriptionId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — looks up via `InvoiceLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `SubscriptionUsageSummaryId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Subscription Usage — entity reference URL: https://xmatix.com/docs/reference/entities/subscription-usage/ Last reviewed: 2026-08-16 One metered-consumption entry under a Subscription: a quantity of an item, optionally a specific itemFeature, consumed by an account or asset. These raw entries are the source for usage-based billing, which is settled at the SubscriptionUsageSummary level - the summary tracks billed versus unbilled quantities and links to the invoice lines that billed them. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ItemFeatureId` | Item Feature | Lookup → [ItemFeature](/docs/reference/entities/item-feature/) | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Usage Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Quantity` | Quantity | Decimal | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SubscriptionId` | Subscription | Lookup → [Subscription](/docs/reference/entities/subscription/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `UsageDateTime` | Usage Date Time | DateAndTime | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Edit` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ItemFeature](/docs/reference/entities/item-feature/) — looks up via `ItemFeatureId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [Subscription](/docs/reference/entities/subscription/) — looks up via `SubscriptionId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `SubscriptionUsageId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Subscription — entity reference URL: https://xmatix.com/docs/reference/entities/subscription/ Last reviewed: 2026-08-16 A recurring-billing arrangement for an account covering one item (or itemComponent): quantity, pricing (priceList/priceListRule, unitPrice, unitCost, markup fields, taxGroup), billingFrequency and chargeType, and the billing clock (startDate, endDate, lastBillingDate, nextBillingDate, terminatedDate, goodwillDays). chargeType splits the billing model: Recurring subscriptions whose nextBillingDate has arrived (and which are not terminated or ended) get an invoice generated directly from the subscription, while Usage subscriptions are billed from their SubscriptionUsageSummary rollups, with slab pricing applied from the item's consumption schedule. Each billing pass stamps lastBillingDate and advances nextBillingDate by the billing frequency. Often originates from an Order/OrderLine and can be tied to an Asset; child SubscriptionUsage rows carry the raw metered consumption. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Amount` | Amount | Currency | | | | `AssetId` | Asset | Lookup → [Asset](/docs/reference/entities/asset/) | | | | `BillingFrequency` | Billing Frequency | PickList | | Monthly, Quarterly, Semiannual or Annual - the step nextBillingDate advances by on each billing pass. An unrecognized or empty value advances monthly. Values: Semiannual. | | `BillingType` | Billing Type | PickList | | Values: Advance, Arrears. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `ChargeType` | Charge Type | PickList | | Splits the billing model: Recurring subscriptions are invoiced directly from the subscription when nextBillingDate arrives, while Usage subscriptions are billed from their SubscriptionUsageSummary rollups with slab pricing from the item's consumption schedule. Values: Recurring, Usage. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EndDate` | End Date | Date | | | | `GoodwillDays` | Goodwill Days | Number | | | | `Id` | Id | Guid | Yes | | | `InvoiceGroup` | Invoice Group | PickList | | Invoice Group(Future Use) | | `IsPriceBundled` | Is Price Bundled | Boolean | | | | `ItemComponentId` | Item Component | Lookup → [ItemComponent](/docs/reference/entities/item-component/) | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `LastBillingDate` | Last Billing Date | Date | | | | `LastModifiedById` | LastModifiedBy | Guid | | | | `MarkupAmount` | Markup Amount | Currency | | Markup Amount (Future use) | | `MarkupRate` | MarkupRate | Decimal | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Subscription Name | Text | Yes | | | `NextBillingDate` | Next Billing Date | Date | | The due date the billing passes select on: subscriptions with this date arrived (and not terminated or ended) are picked up, invoiced, and the date is advanced by the billing frequency while lastBillingDate is stamped. Invoice lines created against the subscription outside the batch pass advance it the same way. | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | | | `OrderLineId` | Order Line | Lookup → [OrderLine](/docs/reference/entities/order-line/) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PriceListId` | Price List | Lookup → [PriceList](/docs/reference/entities/price-list/) | | | | `PriceListRuleId` | Price List Rule | Lookup → [PriceListRule](/docs/reference/entities/price-list-rule/) | | | | `PricingMethod` | Pricing Method | PickList | | Pricing Method(Future Use). Values: List Price. | | `Quantity` | Quantity | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SchemeLineId` | SchemeLine | Lookup → [SchemeLine](/docs/reference/entities/scheme-line/) | | | | `StartDate` | Start Date | Date | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | | | `TerminatedDate` | Terminated Date | Date | | | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | Unit Cost(Future use) | | `UnitPrice` | Unit Price | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | EditInline | Edit Subscription | | `Edit` | Edit | Edit | Edit | | `Editinlist` | Edit | Edit | Editlistrom | | `New` | New | New | New | | `New` | New | New | New Subscription | ## Related entities - [ItemComponent](/docs/reference/entities/item-component/) — looks up via `ItemComponentId` - [Asset](/docs/reference/entities/asset/) — looks up via `AssetId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [PriceList](/docs/reference/entities/price-list/) — looks up via `PriceListId` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [OrderLine](/docs/reference/entities/order-line/) — looks up via `OrderLineId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [PriceListRule](/docs/reference/entities/price-list-rule/) — looks up via `PriceListRuleId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `SubscriptionId` - [SubscriptionUsageSummary](/docs/reference/entities/subscription-usage-summary/) — referenced by via `SubscriptionId` - [SubscriptionUsage](/docs/reference/entities/subscription-usage/) — referenced by via `SubscriptionId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `SubscriptionId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Task — entity reference URL: https://xmatix.com/docs/reference/entities/task/ Last reviewed: 2026-08-16 A placeholder whose first-party definition carries only the system fields (id, name, owner, record type, audit stamps) - no business fields, views, layouts or relations ship for it, and the compiled data model contains no table for it. Operational to-dos on this platform are Activity rows with activityType 'Task': approval processes create them for their submission/approval/rejection/recall task actions, and macro CreateTask steps append them the same way. Query activities rather than this entity when asked about tasks. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Tax Declaration Line — entity reference URL: https://xmatix.com/docs/reference/entities/tax-declaration-line/ Last reviewed: 2026-08-16 One deduction or exemption claim on a TaxDeclaration, identified by its SectionCode and carrying both what the employee declared and what the verifier allowed. Lines are only read at all when the parent declaration's status is Verified or Approved. The platform defines a per-line lifecycle vocabulary (Declared, Submitted, Verified, Rejected, ResubmissionRequired) but this entity has no status field to hold it, so per-line verification cannot currently be recorded — verification is a header-level decision. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeclaredAmount` | Declared Amount | Currency | | What the employee claimed. It is used only as the fallback when VerifiedAmount is blank, and only once the parent declaration reaches Verified or Approved — a declared amount on a Draft or Submitted declaration reduces nothing. | | `Description` | Description | Text | | Free-text note about the specific investment or payment claimed (policy number, lender, institution). Not read by the tax computation; it exists for the verifier and for the proof audit trail. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SectionCode` | Section Code | Text | | The deduction section claimed, matched case-insensitively against a TaxDeductionSection master for the same financial year and company. | | `TaxDeclarationId` | Tax Declaration | Lookup → [TaxDeclaration](/docs/reference/entities/tax-declaration/) | | The parent declaration, and the only route to the employee, financial year and status — a line carries none of those itself, which is why the computation reaches the employee through this link and applies the header's status gate to every line. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VerifiedAmount` | Verified Amount | Currency | | What the verifier allowed after checking proof, and the figure the computation prefers. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this TaxDeclarationLine. | | `Edit` | Edit | Edit | Edit this TaxDeclarationLine. | | `New` | New | New | Create a TaxDeclarationLine. | | `NewInLine` | New | NewInline | New | | `View` | View | View | View this TaxDeclarationLine. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [TaxDeclaration](/docs/reference/entities/tax-declaration/) — looks up via `TaxDeclarationId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Tax Declaration — entity reference URL: https://xmatix.com/docs/reference/entities/tax-declaration/ Last reviewed: 2026-08-16 An employee's yearly investment and deduction declaration, the header over TaxDeclarationLine claims, used to reduce taxable income in the salary-TDS projection. Keyed on ResourceId and scoped by FinancialYear. Lines from Draft, Submitted or Rejected declarations are ignored entirely, so an employee with declared-but-unverified investments is deducted as if they had claimed nothing. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `FinancialYear` | Financial Year | Text | | Indian financial year label in the form 2026-27, matched exactly against the year the projection derives from the payroll period's end date. A declaration filed under a differently formatted or wrong year is not found and contributes nothing, with no warning. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Regime` | Regime | PickList | | Values: Old Regime, New Regime. | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | The employee this declaration belongs to, keyed on Resource rather than on Employee — Resource is the canonical payroll and subledger key across the platform, and the TDS projection matches declarations to employees through the employee's ResourceId. | | `Status` | Status | PickList | | Values: Draft, Submitted, Verified, Approved, Rejected. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete this TaxDeclaration. | | `DeleteHeader` | Delete | Delete | DeleteHeader | | `Edit` | Edit | Edit | Edit this TaxDeclaration. | | `EditInLine` | Edit | EditInline | Edit | | `New` | New | New | Create a TaxDeclaration. | | `View` | View | View | View this TaxDeclaration. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | PartnerAccountFilter | `PartnerAccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [TaxDeclarationLine](/docs/reference/entities/tax-declaration-line/) — referenced by via `TaxDeclarationId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Tax Deduction Section — entity reference URL: https://xmatix.com/docs/reference/entities/tax-deduction-section/ Last reviewed: 2026-08-16 The master for a Chapter VI-A deduction section (Chapter VIII from FY 2026-27): its own ceiling, its senior-citizen variant, which regimes allow it, and — separately — whether the EMPLOYER may allow it against salary TDS at all. It is the source of truth that replaced free-text section codes on declaration lines, and it exists to prevent three specific errors: uncapped summing of declarations, capping 80C, 80CCC and 80CCD(1) independently instead of under the single shared 80CCE ceiling, and allowing sections against salary TDS that the employer must not (80G being the significant case, where the employee claims it in their own return instead). SectionCodeNew carries the Income-tax Act, 2025 number alongside the 1961 one (80C becomes 123, 80D becomes 126) so a single row serves both years. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AggregateCapAmount` | Aggregate Cap Amount | Currency | | Ceiling of the cap group. | | `AggregateCapGroup` | Aggregate Cap Group | PickList | | Shared ceiling this section participates in (80CCE). Values: 80 CCE. | | `AllowedInNewRegime` | Allowed In New Regime | Boolean | | Whether the section survives into the New regime — true only for 80CCD(2) and 80CCH. This per-section flag, not the regime-level switch, is what actually admits those two, so a section left false is disallowed in the New regime even where the regime rule permits Chapter VI-A generally. | | `AllowedInOldRegime` | Allowed In Old Regime | Boolean | | Whether the section may be claimed under the Old regime. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `EmployerMayAllow` | Employer May Allow | Boolean | | False where the employer must not allow it against salary TDS (80G). | | `EvidenceKind` | Evidence Kind | Text | | What proof the section calls for (rent receipts, premium certificate, lender statement). Reference material for the verifier and the declaration UI; no computation reads it. | | `FinancialYear` | Financial Year | Text | | The year this ceiling applies to. Null is a deliberate wildcard here — a row with no year matches every year, which is how a section whose limits have not moved is seeded once instead of per year. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `Label` | Label | Text | | | | `MaxAmount` | Max Amount | Currency | | The section's own ceiling, applied to each claim before any shared group ceiling. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RequiresProof` | Requires Proof | Boolean | | Records that section 192(2D) and Rule 26C evidence is needed in Form 12BB before the deduction is allowed. It is declarative: no code path enforces it, and proof discipline is exercised instead through the declaration header status, since only Verified or Approved declarations feed the computation at all. | | `SectionCode` | Section Code | Text | | The Income-tax Act, 1961 section code such as 80C, 80D or 80CCD(1B), and the join key declaration lines are matched against case-insensitively. | | `SectionCodeNew` | Section Code (2025 Act) | Text | | The equivalent Income-tax Act, 2025 section number (80C becomes 123, 80D becomes 126), carried alongside the 1961 code so one row serves both numbering eras and the UI can label a field with the new number and the familiar old one. Declaration lines are matched on SectionCode, not on this field. | | `SeniorMaxAmount` | Senior Max Amount | Currency | | The higher ceiling where the beneficiary is a senior citizen (for example 80D and 80DDB). | | `SortOrder` | Sort Order | Number | | Display order, and quietly load-bearing inside an aggregate cap group: when 80C, 80CCC and 80CCD(1) claims together exceed the shared ceiling, the calculator allocates the ceiling in SortOrder sequence (section code breaking ties) and cuts off the rest. Changing the order changes which section absorbs the shortfall, though not the total allowed. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Delete` | Delete | Delete | Delete the Tax Deduction Section | | `DeleteBulk` | Delete | Delete | Delete the selected Tax Deduction Section records | | `Edit` | Edit | Edit | Edit the Tax Deduction Section | | `EditHeader` | Edit | Edit | Edit | | `EditInLine` | Edit Inline | EditInline | Edit the Tax Deduction Section inline | | `New` | New | New | Create a new Tax Deduction Section | | `View` | View | View | View the Tax Deduction Section | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Tax Group Rule — entity reference URL: https://xmatix.com/docs/reference/entities/tax-group-rule/ Last reviewed: 2026-08-16 Decides which TaxGroup a document line receives for its item — the Item entity itself carries no tax group, so this is the only mapping. A rule matches when its item, SKU and item lot type are each either equal to the line's or left blank, its TaxSupplyType equals the header's exactly (including both being empty), the parent group's partner account and branch fit the header, and the header's creation timestamp falls inside the effective-date window. It is the header's CreatedDateTime, not its document date, that is tested against the window. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DateEffectiveFrom` | Date Effective From | Date | | Tested against the parent document's CreatedDateTime — the record's creation timestamp, not its document date — so a back-dated document is matched by when it was entered, and a rule dated from today will apply to a document keyed today for last month. | | `DateEffectiveTill` | Date Effective Till | Date | | End of validity, compared against the same document creation timestamp. Empty leaves the rule open-ended. | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | Because the item, SKU and lot-type tests all pass on a blank value, a rule scoped only by item group matches every line it is offered rather than only the group's items. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | Empty turns the rule into a catch-all that matches every line. Combined with ordering by the parent group's sequence alone, a stray blank-item rule in a high-sequence group is the usual cause of an unexpected tax group on a line. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | Optional narrowing to one item lot type; empty matches any. Like SKU it filters but does not raise the rule's precedence. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlaceOfSupplyType` | PlaceOfSupplyType | Text | | Stored on the rule but read nowhere in the platform, so it narrows nothing; supply typing is done through TaxSupplyType alone. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ServiceContractItemId` | Service Contract Item | Lookup → [Item](/docs/reference/entities/item/) | | Not consulted by the tax resolver, so it cannot be used to give service-contract lines a different tax group; such a rule behaves as an unscoped one. | | `SKUId` | SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | Optional narrowing to one SKU; empty matches any SKU. It never promotes a rule in the ordering — only the parent group's sequence decides which matching rule wins. | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | The group the rule hands to the line: the winning rule's value is written straight into the line's TaxGroupId, and every tax component of that group is then applied. | | `TaxSupplyType` | Tax Supply Type | PickList | | Compared for exact equality with the header's supply type, empty included — a rule naming a supply type can never match a header that leaves it blank, and a rule that leaves it blank can never match a header that sets one. The seeded vocabulary is 'Within State' and 'Outside State'. Values: Within State, Outside State. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `NewInLine` | New | NewInline | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Date Effective Till Rule Validation | `DateEffectiveTill`, Error | Date Effective Till should not be Backdated | Ensures effective-till date is not on or before effective-from date | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Sku For Item | `SKUId` | SKU For Item | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [Item](/docs/reference/entities/item/) — looks up via `ServiceContractItemId` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Tax Group — entity reference URL: https://xmatix.com/docs/reference/entities/tax-group/ Last reviewed: 2026-08-16 A set of Tax components applied together, referenced from document headers and lines through TaxGroupId. TaxGroupService decides which group a line gets: it keeps active groups whose partner account, branch and partner account group fit the header (membership from AccountGroupMember rows in an account group of type Tax), gathers their TaxGroupRule rows, and orders the candidates by SequenceNumber descending — the only precedence signal in the whole tax path, so a high-sequence group's catch-all rule beats a low-sequence group's precisely scoped one. A separate header-level path uses the document's own Tax reference against TCSEligibleAmount for a single levy such as tax collected at source. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | Confines the group to documents raised in that branch, checked at both the candidate-gathering and rule-matching stages. Empty makes the group available in every branch. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Active | Boolean | | Must be true for the group's rules to be considered at all — inactive groups are dropped before rule matching, so deactivating a group is the way to retire its whole rule set at once. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text, unique | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountGroupId` | Partner Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | Confines the group to documents whose partner account belongs to that group, resolved from active AccountGroupMember rows whose account group is of type Tax. Groups of any other type are ignored here. | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | Confines the group to documents for that partner account, checked both when the candidate groups are gathered and again when a rule is matched against the header. Empty means every partner. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SequenceNumber` | Sequence Number | Number | | The only precedence signal in the entire tax-resolution path: candidate rules are sorted by their parent group's sequence descending and the first that matches is taken. A catch-all rule inside a high-sequence group therefore beats a precisely scoped rule inside a lower one. | | `TaxApplicability` | Tax Applicability | PickList | | Values: Apply All Taxes, Apply Any Tax. | | `TaxCustomLogic` | Tax Custom Logic | Text | | | | `TaxGroupType` | Tax Group Type | PickList | | Whether a group acts on a header or on a line is decided by which field references it, not by this value. Values: Document Level, Line Level. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit In Page | | `EditInList` | Edit | Edit | Edit | | `EditListHeader` | Edit | EditInline | EditListHeader | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch for Partner Account | `BranchId` | | | Partner Account | `PartnerAccountId` | | ## Related entities - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `PartnerAccountGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Order](/docs/reference/entities/order/) — referenced by via `TaxGroupId` - [Requisition](/docs/reference/entities/requisition/) — referenced by via `TaxGroupId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `TaxGroupId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `TaxGroupId` - [Tax](/docs/reference/entities/tax/) — referenced by via `TaxGroupId` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `TaxGroupId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `TaxGroupId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `TaxGroupId` - [TaxGroupRule](/docs/reference/entities/tax-group-rule/) — referenced by via `TaxGroupId` - [Quote](/docs/reference/entities/quote/) — referenced by via `TaxGroupId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `TaxGroupId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `TaxGroupId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `TaxGroupId` - [Bill](/docs/reference/entities/bill/) — referenced by via `TaxGroupId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `TaxGroupId` - [RequisitionLine](/docs/reference/entities/requisition-line/) — referenced by via `TaxGroupId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `TaxGroupId` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `TaxGroupId` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `TaxGroupId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `TaxGroupId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `TaxGroupId` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `TaxGroupId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `TaxGroupId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Tax Regime Rule — entity reference URL: https://xmatix.com/docs/reference/entities/tax-regime-rule/ Last reviewed: 2026-08-16 The per-regime, per-financial-year scalars of the salary income-tax computation that are not slab bands: standard deduction, the section 87A rebate ceiling and cap and its marginal relief, the surcharge maximum and the special-rate surcharge cap, health and education cess, statutory rounding, and what the regime permits at all (Chapter VI-A deductions, house-property loss set-off and its cap). These are data rather than constants deliberately, because the figures move every Budget and the section numbering itself changed with the Income-tax Act, 2025. A company-specific row wins over a shared row with a null PartnerAccountId. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AllowsChapterViaDeductions` | Allows Chapter VI-A Deductions | Boolean | | | | `AllowsHousePropertyLossSetOff` | Allows House Property Loss Set-Off | Boolean | | | | `CessRate` | Cess Rate | Currency | | Health and education cess as a percentage, charged on tax plus surcharge after all reliefs and rebates. It is applied last before relief under section 89 and the statutory rounding, so it compounds on top of surcharge rather than being levied on base tax alone. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FinancialYear` | Financial Year | Text | | Financial year label in the form 2026-27, derived from the payroll period's end date. The projection requires a row for this exact year in BOTH regimes; when either is absent it writes no projection at all and salary TDS for that month deducts nothing. | | `HousePropertyLossSetOffCap` | House Property Loss Set-Off Cap | Currency | | The section 71(3A) ceiling on setting a house-property loss (typically home-loan interest) against salary — two lakh in the Old regime. Only ever applied when AllowsHousePropertyLossSetOff is not false, and only to a negative house-property figure; positive house-property income is always added in full. In the current projection the house-property input is always nil, so this cap is configuration awaiting a path that supplies it. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The legal entity this rule set belongs to. Null means it applies to every company in the tenant; where both a shared and a company-specific row exist for the same regime and year, the company-specific one wins. | | `RebateIncomeCeiling` | Rebate Income Ceiling | Currency | | The total income at or below which the section 87A rebate applies. It is a cliff, not a taper: a rupee over the ceiling and the entire rebate is lost, which is precisely why RebateMarginalReliefEnabled exists. It is also the reference point the marginal-relief cap is measured from. | | `RebateMarginalReliefEnabled` | Rebate Marginal Relief Enabled | Boolean | | New regime: tax above the ceiling is capped at the income that crossed it. | | `RebateMaxAmount` | Rebate Max Amount | Currency | | The maximum section 87A rebate. The rebate given is the lower of this figure and the tax on slab-rate income — tax on dividends and on section 111A/112/112A gains is netted off first and never attracts rebate. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Regime` | Regime | PickList | | Old or New, matched exactly when the rule pack is assembled. Both regimes are always computed, so a missing or misspelt value for either one aborts the projection for that employee entirely rather than falling back to the other. Values: Old Regime, New Regime. | | `RoundingUnit` | Rounding Unit | Currency | | The statutory rounding unit under section 288B, ordinarily 10 rupees. It is applied twice: to total taxable income and again to the final net tax payable, rounding to the nearest multiple away from zero. Zero or null disables rounding and leaves paise on the figure. | | `SpecialRateSurchargeCapRate` | Special Rate Surcharge Cap | Currency | | The surcharge ceiling on the slice of tax attributable to dividends and to section 111A/112/112A capital gains. When special-rate income is present the surcharge is blended — the ordinary rate on the normal slice and this capped rate on the special slice — because applying one rate across the whole tax overstates it. | | `StandardDeduction` | Standard Deduction | Currency | | The flat deduction from salary income under section 16(ia) (section 19 in the 2025 Act), applied in BOTH regimes with only the amount differing. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `SurchargeMaxRate` | Surcharge Max Rate | Currency | | The highest surcharge rate the regime permits. It is enforced as a clamp on whatever the surcharge bands resolve to, so a New-regime row set to 25 keeps a shared 37% band from ever applying, without needing a separate band set per regime. | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Delete` | Delete | Delete | Delete the Tax Regime Rule | | `DeleteBulk` | Delete | Delete | Delete the selected Tax Regime Rule records | | `Edit` | Edit | Edit | Edit the Tax Regime Rule | | `EditHeader` | Edit | Edit | Edit | | `EditInLine` | Edit Inline | EditInline | Edit the Tax Regime Rule inline | | `New` | New | New | Create a new Tax Regime Rule | | `View` | View | View | View the Tax Regime Rule | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Tax Surcharge Slab — entity reference URL: https://xmatix.com/docs/reference/entities/tax-surcharge-slab/ Last reviewed: 2026-08-16 A surcharge band on income tax, per regime and financial year. Distinct from SalaryTaxSlab in three ways: surcharge is a flat percentage of the TAX rather than of income, it steps at total-income thresholds (50 lakh, 1 crore, 2 crore, 5 crore), and each step carries marginal relief so the extra tax can never exceed the extra income that crossed the threshold. FromIncome is the exclusive start of the band and a null ToIncome means open-ended. The rate resolved from these rows is clamped to the regime's SurchargeMaxRate, which is why the New regime never exceeds 25% and the 5 crore step only produces relief under the Old regime. Where the employee has special-rate income the surcharge rate is blended rather than applied flat. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FinancialYear` | Financial Year | Text | | Financial year label in the form 2026-27, matched exactly. A row whose year does not match the year being computed is not picked up at all, and a regime with no surcharge rows simply attracts no surcharge. | | `FromIncome` | From Income | Currency | | The total income at which the band starts, applied EXCLUSIVELY — at exactly this figure the lower band's rate still applies. It is also the threshold at which marginal relief is tested, so it must be the statutory step (50 lakh, 1 crore, and so on) rather than a rounded approximation. | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Rate` | Rate | Currency | | Surcharge as a percentage of the tax (10 / 15 / 25 / 37). | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Regime` | Regime | PickList | | Old or New. Unlike the income slabs, surcharge rows are matched on an exact regime match — a null does not act as a wildcard here, so a row with no regime is never used. Values: Old Regime, New Regime. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `ToIncome` | To Income | Currency | | The top of the band, inclusive; null means open-ended. Where several bands match, the one with the highest FromIncome wins. | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Delete` | Delete | Delete | Delete the Tax Surcharge Slab | | `DeleteBulk` | Delete | Delete | Delete the selected Tax Surcharge Slab records | | `Edit` | Edit | Edit | Edit the Tax Surcharge Slab | | `EditHeader` | Edit | Edit | Edit | | `EditInLine` | Edit Inline | EditInline | Edit the Tax Surcharge Slab inline | | `New` | New | New | Create a new Tax Surcharge Slab | | `View` | View | View | View the Tax Surcharge Slab | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Tax Transaction — entity reference URL: https://xmatix.com/docs/reference/entities/tax-transaction/ Last reviewed: 2026-08-16 The raw GST ledger: one row per tax component (CGST, SGST, IGST or Cess) of one document line, captured when a tax-bearing document (invoice, bill, credit/debit note) is saved - the line-level analytics the general ledger deliberately does not store, since it posts summarized. Links polymorphically to the source via SourceEntityName/SourceRecordId/SourceLineId and is stamped with the GSTRegistration, own and party GSTIN, place of supply, HSN/SAC code, supply type and category. Everything downstream derives from it: the GSTR-1 outward materialization, GSTR-3B reverse-charge and blocked-ITC boxes, GSTR-6 ISD received documents, GSTR-9 books lane and HSN summaries, and 2B reconciliation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BlockedReason` | Blocked Reason | Text | | The section 17(5) clause when ItcEligibility is Blocked, e.g. motor vehicles - the why behind a permanent ITC reversal, carried into the GSTR-3B 4B(1) derivation. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `Component` | Component | Text | | Which GST head this row carries: CGST, SGST, IGST or Cess. A document line under intra-state supply produces separate CGST and SGST rows; inter-state produces IGST - so summing tax for a line means grouping its component rows. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Direction` | Direction | Text | | Output (sales-side tax you owe) or Input (purchase-side tax you may claim as ITC). Return materializations filter on it: GSTR-1 reads Output rows, ITC and ISD flows read Input rows. | | `DocumentDate` | Document Date | Date | | | | `DocumentNumber` | Document Number | Text | | | | `GSTRegistrationId` | GST Registration | Lookup → [GSTRegistration](/docs/reference/entities/gstregistration/) | | | | `HsnSacCode` | Hsn Sac Code | Text | | | | `Id` | Id | Guid | Yes | | | `IsReverseCharge` | Is Reverse Charge | Boolean | | True on purchase-side rows where the recipient owes the tax (RCM). GSTR-3B box 3.1(d) inward reverse-charge liability is derived from Input rows with this flag - GSTR-2B cannot supply it because GSTN does not know your reverse-charge maths. | | `IsService` | Is Service | Boolean | | | | `ItcCategory` | Itc Category | Text | | | | `ItcEligibility` | Itc Eligibility | Text | | Input-direction classification: Eligible, Blocked or Ineligible. Blocked rows (section 17(5)) are what GSTR-3B box 4B(1) permanent reversals are derived from - only the books know which credits the company blocked, so this never comes from GSTR-2B. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | GL Account Name | Text, unique | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `OwnGstin` | Own Gstin | Text | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyAccountId` | Party Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyGstin` | Party Gstin | Text | | | | `PlaceOfSupply` | Place Of Supply | Text | | | | `Rate` | Rate | Currency | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SourceEntityName` | Source Entity Name | Text | | | | `SourceLineId` | Source Line | Guid | | | | `SourceRecordId` | Source Record | Guid | | | | `SupplyCategory` | Supply Category | Text | | | | `SupplyType` | Supply Type | Text | | Supply nature mirroring the invoice: Within State, Outside State, Export, SEZ or Exempt. Drives which GSTR-1 section a supply lands in and whether IGST or CGST+SGST components are produced. | | `TaxableValue` | Taxable Value | Currency | | | | `TaxAmount` | Tax Amount | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GSTRegistration](/docs/reference/entities/gstregistration/) — looks up via `GSTRegistrationId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Tax — entity reference URL: https://xmatix.com/docs/reference/entities/tax/ Last reviewed: 2026-08-16 One tax component inside a TaxGroup: a rate plus the line slot it posts into. TaxService applies every component of the line's resolved group — the taxable base is quantity (less cancelled quantity) times the first non-zero of UnitPrice2, UnitPrice, UnitCost2 and UnitCost, reduced by the scheme, first, second and contract discounts — and each component's amount is that base times its rate, with the total written to the line's TaxAmount. PostingFieldName decides which of the six Tax1..Tax6 slots receives the amount, rate, name and type. Tax is always computed on top of the line value: the platform has no inclusive-tax handling anywhere, so a rate can never be back-solved out of a gross price. When the document's partner is flagged for post-tax discounting, the discounts are left in the base and applied after tax instead. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `LastModifiedById` | LastModifiedBy | Guid | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PostingFieldName` | Posting Field Name | PickList | | Names which of the line's six tax slots takes this component; the value is normalised (spaces stripped, first letter capitalised, the rest lower-cased) before the amount, rate, name and type are written into that slot and its companion columns. Leaving it blank does not skip the component — its amount still counts toward the line's TaxAmount, it simply never appears in a visible slot. Values: Tax1, Tax2, Tax3, Tax4, Tax5, Tax6. | | `Rate` | Rate | Percent | | A percent-typed fraction — eighteen percent is stored as 0.18 while the API presents it as 18 — multiplied directly by the line's taxable base to give this component's amount. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `TaxGroupId` | Tax Group | Lookup → [TaxGroup](/docs/reference/entities/tax-group/) | | Required: a tax exists only inside a group. Every component of the group resolved for a line is applied, and their amounts are summed into the line's TaxAmount. | | `TaxName` | TaxName | Text | | A descriptive name the calculation never uses — the line's slot name column is filled from the record's Name field instead, so editing this does not change what appears on a document line. | | `Type` | Tax Type | PickList | | A classification copied to the line's slot type alongside the amount, seeded with CGST, SGST, IGST, TCS and TDS. Nothing in the calculation branches on it: a component typed as a withholding is still computed and added exactly like any other. Values: SGST, TCS, TDS, CGST, IGST. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit In Page | | `EditListHeader` | Edit | EditInline | EditListHeader | | `EditListRow` | Edit | Edit | EditListRow | | `New` | New | New | New | | `NewQAP` | New | NewInline | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Posting Field Validation | Error | Posting Field Name must be 'Tax1' when Tax Group Type is 'Document Level'. | Requires Posting Field Name to be 'Tax1' when Tax Group Type is 'Document Level' | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [TaxGroup](/docs/reference/entities/tax-group/) — looks up via `TaxGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Quote](/docs/reference/entities/quote/) — referenced by via `TaxId` - [Bill](/docs/reference/entities/bill/) — referenced by via `TaxId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `TaxId` - [Requisition](/docs/reference/entities/requisition/) — referenced by via `TaxId` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `TaxId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `TaxId` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `TaxId` - [Order](/docs/reference/entities/order/) — referenced by via `TaxId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # TDS Certificate — entity reference URL: https://xmatix.com/docs/reference/entities/tds-certificate/ Last reviewed: 2026-08-16 A withholding-certificate register row - Form 131 (non-salary TDS, ex-16A), Form 16 (salary) or Form 27D (TCS) - one per deductee per FILED quarterly return, generated by the certificate action with numbering TAN/kind/FY/quarter/sequence and totals rolled up from the return's rows. The certificate number is stamped back onto the underlying TdsTransaction rows so ledger, reconciliation and register cite the same reference. Status runs Draft to Issued; regeneration replaces Draft rows but a return with Issued certificates is locked. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CertificateNumber` | Certificate Number | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `FyStartYear` | Fy Start Year | Number | | | | `Id` | Id | Guid | Yes | | | `IssuedOn` | Issued On | Date | | | | `Kind` | Kind | PickList | | Certificate form: Form131 (non-salary TDS, generated from Form-140 returns), Form16 (salary, from Form-138), Form27D (TCS, from Form-143). Values: Form 131 — vendor TDS (ex-16A), Form 16 — salary, Form 27D — TCS. | | `LineCount` | Line Count | Number | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account Id | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyAccountId` | Party Account Id | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyName` | Party Name | Text | | | | `PartyPan` | Party Pan | Text | | | | `Quarter` | Quarter | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource Id | Lookup → [Resource](/docs/reference/entities/resource/) | | The employee for a Form 16 certificate - employees are Resources, not Accounts, so salary certificates link here while vendor/customer certificates use PartyAccountId. | | `Status` | Status | PickList | | Values: Draft, Issued. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TdsReturnId` | Tds Return Id | Lookup → [TdsReturn](/docs/reference/entities/tds-return/) | | | | `TotalAmountPaid` | Total Amount Paid | Currency | | | | `TotalTaxDeducted` | Total Tax Deducted | Currency | | | | `TotalTaxDeposited` | Total Tax Deposited | Currency | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `DeleteListRow` | Delete | Delete | Delete | | `EditHeader` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | Edit | | `New` | New | New | New | | `PreviewTdsCertificate` | Certificate Document | UIAction | Open the statutory certificate document (Form 131 / Form 27D / Form 16). Print & Save attaches the printed copy to this record. | | `PrintTdsCertificate` | Print Certificate | Print, inactive | Superseded by the Certificate Document action (the component prints and attaches). Kept inactive in case a banded report design is bound later. | | `PrintTdsCertificateListRow` | Print | Print, inactive | Superseded by the Certificate Document action. | ## Related entities - [TdsReturn](/docs/reference/entities/tds-return/) — looks up via `TdsReturnId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # TDS Challan Allocation — entity reference URL: https://xmatix.com/docs/reference/entities/tds-challan-allocation/ Last reviewed: 2026-08-16 The link row between one withholding event and the deposit challan that carried its tax to the government: TdsTransactionId, TdsChallanId and the amount consumed. Written by challan preparation; the quarterly return's compute follows these links to map each deductee row to its challan row. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Amount` | Amount | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TdsChallanId` | Tds Challan Id | Lookup → [TdsChallan](/docs/reference/entities/tds-challan/) | | | | `TdsTransactionId` | Tds Transaction Id | Lookup → [TdsTransaction](/docs/reference/entities/tds-transaction/) | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `DeleteListRow` | Delete | Delete | Delete | | `EditHeader` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — looks up via `TdsTransactionId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [TdsChallan](/docs/reference/entities/tds-challan/) — looks up via `TdsChallanId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # TDS Challan — entity reference URL: https://xmatix.com/docs/reference/entities/tds-challan/ Last reviewed: 2026-08-16 A vendor-TDS/TCS deposit challan (ITNS 281) - one per company, deduction month, payment code and major head (0020 company deductees / 0021 others; mixed groups are split). Prepared as Draft from the month's undeposited TdsTransaction rows with the deductions linked through TdsChallanAllocation; posting computes both interest legs as of the deposit date (1 percent per month for late deduction, 1.5 percent per month for late deposit), posts the deposit journal (debit the withholding payable and interest expense, credit bank) and marks the allocated transactions Deposited. The CIN recorded after bank payment - BSR code, tender date, challan serial - is what the quarterly return's challan rows cite, and it can be verified against the portal's CSI file. The salary-TDS analog is PayrollStatutoryChallan. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BankGLAccountId` | BankGL Account Id | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BsrCode` | Bsr Code | Text | | | | `ChallanSerial` | Challan Serial | Text | | | | `CorrectionCount` | Corrections | Number | | | | `CorrectionLog` | Correction Log | LongMultiLineText | | Append-only JSON audit of every post-deposit correction: when, the bank/portal reference, and each corrected field's old and new value. Amounts are immutable in a correction - only head, payment code or CIN fields change - and CorrectionCount tracks how many corrections were applied. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `CsiVerified` | Csi Verified | Boolean | | True once the challan's CIN (BSR code + tender date + serial) has been matched against the portal's Challan Status Inquiry file via the verify action - the pre-filing proof that the bank actually reported the deposit. | | `DepositDate` | Deposit Date | Date | | | | `DueDate` | Due Date | Date | | Statutory deposit due date: the 7th of the month following the deduction month, except March TDS which is due 30 April. Deposits after this date accrue the 1.5 percent per month late-deposit interest. | | `FeeAmount` | Fee Amount | Currency | | | | `GLId` | GL Id | Lookup → [Journal](/docs/reference/entities/journal/) | | | | `Id` | Id | Guid | Yes | | | `InterestAmount` | Interest Amount | Currency | | The late-DEPOSIT interest leg: 1.5 percent per month or part thereof from the deduction month to the deposit month. Kept separate from LateDeductionInterestAmount so the two statutory interest heads stay auditable; TotalAmount carries both. | | `Label` | Label | Text | | | | `LastCorrectionReference` | Last Correction Ref | Text | | | | `LateDeductionInterestAmount` | Late-Deduction Interest | Currency | | The late-DEDUCTION interest leg: 1 percent per month or part thereof from the date the tax became deductible to the date it was actually deducted (driven by the gap between a transaction's DocumentDate and DeductionDate). Separate from the 1.5 percent late-deposit leg in InterestAmount. | | `MajorHead` | Major Head | PickList | | ITNS 281 major head derived from the deductees' classification: 0020 Corporation Tax for company deductees, 0021 Income Tax Other than Companies. One challan carries exactly one major head - preparation splits a payment-code group with mixed deductee types into two challans. Values: 0020 — Corporation Tax (Companies), 0021 — Income Tax (Other than Companies). | | `MinorHead` | Minor Head | PickList | | Values: 200 — Regular, 400 — Demand. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Nature` | Nature | PickList | | Values: TDS — deducted on payables, TCS — collected on receivables. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account Id | Lookup → [Account](/docs/reference/entities/account/) | | | | `PayableGLAccountId` | PayableGL Account Id | Lookup → [GLAccount](/docs/reference/entities/glaccount/) | | | | `PaymentCode` | Payment Code | Number | | | | `PeriodMonth` | Period Month | Number | | | | `PeriodYear` | Period Year | Number | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SectionCode` | Section Code | Text | | | | `Status` | Status | PickList | | Values: Draft, Deposited, Verified. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TaxAmount` | Tax Amount | Currency | | | | `TotalAmount` | Total Amount | Currency | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `CorrectTdsChallan` | Correct Challan | ServerAction (`CorrectTdsChallan`) | Records a bank/portal challan correction in the books: head, payment code or CIN fields may change while amounts stay immutable. Appends the change to the challan's correction log with the correction reference, increments the correction count, and resets CSI verification so the corrected CIN must be re-verified. | | `DeleteListRow` | Delete | Delete | Delete | | `EditHeader` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | Edit | | `GenerateChallan` | Generate Challan | UIAction | Generate Challan | | `New` | New | New, inactive | New | | `PostTdsChallan` | Deposit Challan | ServerAction (`PostTdsChallan`) | Posts the deposit: computes both interest legs as of the deposit date (1 percent per month late-deduction, 1.5 percent per month late-deposit), posts the journal debiting the TDS/TCS payable control for the tax and interest expense for interest/fee against a bank credit for the total, links the journal via GLId, and marks the allocated transactions Deposited. | | `PrepareTdsChallans` | Prepare Monthly Challans | ServerAction (`PrepareTdsChallans`) | Drafts the month's deposit challans from undeposited TdsTransaction rows: one challan per payment code (legacy rows: per section code) and ITNS 281 major head, linking each deduction through a TdsChallanAllocation and stamping the branch from the allocated deductions. Reports how many challans were created or topped up and how much tax was allocated; re-runs pick up only still-undeposited transactions. | | `VerifyTdsChallanCsi` | Verify Against CSI | ServerAction (`VerifyTdsChallanCsi`) | Matches deposited challans' CINs (BSR code, tender date, serial) against the content of the portal's Challan Status Inquiry file supplied by the caller, setting CsiVerified on matches - the pre-filing tie-out that the bank reported each deposit. | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `PayableGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [GLAccount](/docs/reference/entities/glaccount/) — looks up via `BankGLAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [TdsChallanAllocation](/docs/reference/entities/tds-challan-allocation/) — referenced by via `TdsChallanId` - [TdsReturnChallan](/docs/reference/entities/tds-return-challan/) — referenced by via `TdsChallanId` - [Journal](/docs/reference/entities/journal/) — referenced by via `SourceRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # TDS Return Challan — entity reference URL: https://xmatix.com/docs/reference/entities/tds-return-challan/ Last reviewed: 2026-08-16 A challan-detail (CD) row of a quarterly withholding return - the return-side projection of one deposit challan: CIN snapshot (BSR code, tender date, serial), payment code and amounts, plus how much of the deposit this return's deductee rows consume. Rebuilt from the ledger on every compute. For salary returns the row projects a payroll statutory challan instead of a vendor/TCS challan - the two source links are mutually exclusive. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BsrCode` | Bsr Code | Text | | | | `ChallanSerial` | Challan Serial | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `InterestAmount` | Interest Amount | Currency | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account Id | Guid | | | | `PaymentCode` | Payment Code | Number | | | | `PayrollStatutoryChallanId` | Payroll Statutory Challan | Lookup → [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) | | For salary (Form 138) returns, the payroll statutory challan this CD row projects - mutually exclusive with TdsChallanId, which is used for vendor-TDS and TCS challans. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Sequence` | Sequence | Number | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TaxAmount` | Tax Amount | Currency | | | | `TdsChallanId` | Tds Challan Id | Lookup → [TdsChallan](/docs/reference/entities/tds-challan/) | | | | `TdsReturnId` | Tds Return Id | Lookup → [TdsReturn](/docs/reference/entities/tds-return/) | | | | `TenderDate` | Tender Date | Date | | | | `TotalAmount` | Total Amount | Currency | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `UtilizedAmount` | Utilized Amount | Currency | | Tax consumed by this return's deductee rows mapped to this challan. Must not exceed TaxAmount - the utilization tie-out is one of the pre-file validation rules, and the year-end reconciliation reports challans whose deposits are under- or over-consumed. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `DeleteListRow` | Delete | Delete | Delete | | `EditHeader` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [TdsReturn](/docs/reference/entities/tds-return/) — looks up via `TdsReturnId` - [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) — looks up via `PayrollStatutoryChallanId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [TdsChallan](/docs/reference/entities/tds-challan/) — looks up via `TdsChallanId` - [TdsReturnDeducteeLine](/docs/reference/entities/tds-return-deductee-line/) — referenced by via `ReturnChallanId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # TDS Return Deductee Line — entity reference URL: https://xmatix.com/docs/reference/entities/tds-return-deductee-line/ Last reviewed: 2026-08-16 A deductee-detail (DD) row of a quarterly withholding return - the return-side projection of one TdsTransaction: party PAN and name snapshot, deductee classification, payment code, payment date, amount paid, tax deducted and deposited, rate, remarks code, and the challan (CD) row whose deposit it consumes. Rebuilt from the ledger on every compute; a row with no ReturnChallanId is an unmapped deduction, which fails validation until its tax is deposited and the return recomputed. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AmountPaid` | Amount Paid | Currency | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DeducteeType` | Deductee Type | PickList | | Statutory deductee classification snapshot taken at compute time (company versus individual/HUF and so on) - it decides the challan major head and which rate row of a dual-rate section applied. Values: Individual, HUF, Company, Firm / LLP, AOP / BOI, Local Authority, Government, Trust. | | `Id` | Id | Guid | Yes | | | `LdcCertificateNumber` | Ldc Certificate Number | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account Id | Guid | | | | `PartyAccountId` | Party Account Id | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyName` | Party Name | Text | | | | `PartyPan` | Party Pan | Text | | | | `PaymentCode` | Payment Code | Number | | | | `PaymentDate` | Payment Date | Date | | | | `Rate` | Rate | Currency | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RemarksCode` | Remarks Code | PickList | | Statutory remarks on the row: A lower-rate certificate, B nil certificate (both citing the certificate number in LdcCertificateNumber), C penal no-PAN rate. Empty means normal-rate deduction. Values: A — Lower deduction (s.395), B — Nil deduction (s.395), C — Higher rate (PAN missing). | | `ReturnChallanId` | Return Challan Id | Lookup → [TdsReturnChallan](/docs/reference/entities/tds-return-challan/) | | The CD (challan) row this deduction's deposit maps to, followed through the challan allocations. Empty means the deduction's tax has not been deposited yet - a validation failure until a challan covering it is posted and the return recomputed. | | `SectionCode` | Section Code | Text | | | | `Sequence` | Sequence | Number | | | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TaxDeducted` | Tax Deducted | Currency | | | | `TaxDeposited` | Tax Deposited | Currency | | | | `TdsReturnId` | Tds Return Id | Lookup → [TdsReturn](/docs/reference/entities/tds-return/) | | | | `TdsTransactionId` | Tds Transaction Id | Lookup → [TdsTransaction](/docs/reference/entities/tds-transaction/) | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `DeleteListRow` | Delete | Delete | Delete | | `EditHeader` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | Edit | | `New` | New | New | New | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [TdsReturnChallan](/docs/reference/entities/tds-return-challan/) — looks up via `ReturnChallanId` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — looks up via `TdsTransactionId` - [TdsReturn](/docs/reference/entities/tds-return/) — looks up via `TdsReturnId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # TDS Return Salary Detail — entity reference URL: https://xmatix.com/docs/reference/entities/tds-return-salary-detail/ Last reviewed: 2026-08-16 The Annexure II row of a Q4 salary return (Form 138, ex-24Q): one employee's full-year salary and tax computation - gross salary, exempt allowances, section-16 deductions, other income, Chapter VI-A claims, the slab/rebate/surcharge/cess waterfall and the deducted-versus-liability position - snapshotted from the payroll ledger and the income-tax calculator at compute time. Feeds the FVU salary-detail records and Form 16 Part B (a Form 16 certificate links back to its row). Rebuilt on every Q4 compute; returns for quarters 1-3 carry none. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `Cess` | Cess | Currency | | | | `ChapterViaDeductions` | Chapter VI-A Deductions | Currency | | | | `ComputationJson` | Computation Breakup | LongMultiLineText | | Line-level computation breakup as compact JSON - each exemption, section-16 and Chapter VI-A claim with claimed versus allowed amounts - the itemization Form 16 Part B renders. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `EmployeeName` | Employee Name | Text | | | | `ExemptAllowances` | Exempt Allowances (s.10) | Currency | | | | `GrossSalary` | Gross Salary | Currency | | | | `GrossTotalIncome` | Gross Total Income | Currency | | | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OtherIncome` | Other Income | Currency | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Pan` | PAN | Text | | | | `PartnerAccountId` | Partner Account Id | Guid | | | | `Rebate87A` | Rebate (87A) | Currency | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Regime` | Regime | PickList | | Tax regime the employee's year was computed under: Old or New. Under the New regime Chapter VI-A deductions are zero except employer-contribution class rows. Values: New Regime, Old Regime. | | `ResourceId` | Employee | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `Section16Deductions` | Section 16 Deductions | Currency | | | | `Sequence` | Sequence | Number | | | | `ShortfallExcess` | Shortfall / Excess | Currency | | Total tax liability minus TDS actually deducted through payroll: positive means short-deducted, negative means excess deduction (refundable to the employee via assessment). | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `Surcharge` | Surcharge | Currency | | | | `TaxableIncome` | Taxable Income | Currency | | | | `TaxOnIncome` | Tax on Income | Currency | | | | `TdsDeducted` | TDS Deducted | Currency | | | | `TdsDeposited` | TDS Deposited | Currency | | Of the payroll TDS deducted for the year, the part whose payroll statutory challans are Paid - deposited and deducted can differ when a challan is still pending. | | `TdsReturnId` | TDS Return | Lookup → [TdsReturn](/docs/reference/entities/tds-return/) | | | | `TotalTaxLiability` | Total Tax Liability | Currency | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `DeleteListRow` | Delete | Delete | Delete | | `EditHeader` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | Edit | | `New` | New | New | New | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # TDS Return — entity reference URL: https://xmatix.com/docs/reference/entities/tds-return/ Last reviewed: 2026-10-10 One quarterly withholding statement for one company: Form 140 (resident non-salary TDS), Form 143 (TCS) or Form 138 (salary TDS) for a financial-year quarter; Form 144 can be stored but not computed. Draft returns for Forms 140, 143 and 138 are created by the Provision TDS/TCS compliance job for every company with a TAN, or by hand. Compute Return rebuilds the challan and deductee rows from the withholding register (salary returns from posted payroll) and never recalculates tax; only Deposited or Verified challans become challan rows. Validate Return runs the pre-file checklist, Export e-Return File renders the statement text for the government utilities, Mark Filed records the acknowledgment and any late fee, and Generate Certificates builds the certificate register from a Filed return. Status runs Draft, Computed, Validated, Filed; a Filed return cannot be recomputed and is corrected through Create Correction, which drafts a separate Correction return. See the TDS returns guide in the Tax Center documentation. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AckNumber` | Ack Number | Text | | The portal acknowledgment for the filing. Required by Mark Filed. | | `ChallanCount` | Challan Count | Number | | Number of challan rows built by the last Compute Return; only Deposited or Verified challans count. | | `ComputedOn` | Computed On | Date | | When Compute Return last rebuilt the return. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DeducteeCount` | Deductee Count | Number | | Number of deductee rows built by the last Compute Return. | | `DueDate` | Due Date | Date | | Statutory filing due date: 31 July for Q1, 31 October for Q2, 31 January for Q3 and 31 May for Q4 (the following calendar year for Q3 and Q4). A date entered by hand on or after the end of the quarter is kept, so an official extension survives recomputing. Used for the late fee. | | `FiledOn` | Filed On | Date | | Date the return was filed on the portal, entered in Mark Filed; today when left empty. | | `FormCode` | Form Code | PickList | | Which quarterly statement this is: 140 resident non-salary TDS, 143 TCS, 138 salary TDS, 144 non-resident. Decides the source data and the certificate kind (Form 131, Form 27D or Form 16). Form 144 can be saved but Compute Return refuses it; any other value is refused on save. Values: 138, 140, 143, 144. | | `FyStartYear` | Fy Start Year | Number | | Calendar year in which the financial year starts: 2026 means FY 2026-27. Required by Compute Return. | | `Id` | Id | Guid | Yes | | | `Label` | Label | Text | | Display name. The compliance job sets it as Form, financial year and quarter, for example Form 140 · FY 2026-27 Q2; it defaults to Name when left empty. | | `LateFee` | Late Fee | Currency | | Late-filing fee set by Mark Filed: 200 rupees for each day after the due date up to and including the filing date, capped at Total Tax Deducted. Zero when filed on or before the due date. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | Identifier of the return. Required. The compliance job names it by form, financial year, quarter and company. | | `OriginalReturnId` | Original Return Id | Lookup → [TdsReturn](/docs/reference/entities/tds-return/) | | The Filed return that this Correction statement amends. Set by Create Correction; required when Return Type is Correction. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account Id | Lookup → [Account](/docs/reference/entities/account/) | | The deducting company. Required by Compute Return; the compliance job sets it, and on a hand-made return it is checked on the Filing & Validation tab. | | `Quarter` | Quarter | Number | | Quarter of the financial year: 1 April-June, 2 July-September, 3 October-December, 4 January-March. Values outside 1-4 are refused on save. Required by Compute Return. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ReturnType` | Return Type | PickList | | Regular (default) or Correction. A Correction is created by Create Correction against a Filed return and must reference it through Original Return. Values: Regular, Correction. | | `Status` | Status | PickList | | Draft on creation, Computed after Compute Return, Validated when Validate Return finds no error, Filed after Mark Filed. A Filed return cannot be recomputed and is the only kind certificate generation and the year-end books reconciliation read. Set by the actions, not by hand. Values: Draft, Computed, Validated, Filed. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `Tan` | Tan | Text | | The deducting company's TAN, copied from the company account by the compliance job or by Compute Return when empty. When filled it must be four letters, five digits and a letter; a missing or malformed TAN fails validation. | | `TotalTaxDeducted` | Total Tax Deducted | Currency | | Tax on all deductee rows of the last compute. Also the cap for the late fee. | | `TotalTaxDeposited` | Total Tax Deposited | Currency | | Part of the tax covered by paid challans. Lower than Total Tax Deducted means some deductions are not deposited, which validation reports as an error. | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | | `ValidationResults` | Validation Results | LongMultiLineText | | The individual findings of the last Validate Return, each with a code, severity, message and row count: TAN, PAN structure, PAN verification, PAN coverage below 85 percent, undeposited deductions, challan over-use, incomplete CIN, short deposit, negative amounts, missing lower-deduction certificate numbers and, on the Q4 salary return, the annual salary detail checks. | | `ValidationStatus` | Validation Status | PickList | | Outcome of the last Validate Return: Pass (no findings), Warnings (warnings only) or Fail (at least one error). Cleared by Compute Return. Values: Pass, Warnings, Fail. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `AddToReturn` | Add to Return | ServerAction, hidden | Reconciliation remedy: ensure the quarter's return exists and recompute it from the ledger. | | `AllocateToNextChallan` | Allocate to Next Challan | ServerAction, hidden | Reconciliation remedy: attach an unallocated deduction to its month's Draft challan. | | `CarryForwardChallanBalance` | Carry Forward Balance | ServerAction, hidden | Reconciliation remedy: earmark a challan's unconsumed deposit for a later period. | | `ComputeTdsReturn` | Compute Return | ServerAction (`ComputeTdsReturn`) | Idempotent wipe-and-rebuild of the return's challan (CD) and deductee (DD) child rows from the TdsTransaction ledger for the header's financial-year quarter (salary returns source from posted payroll). Never recomputes tax - the ledger already carries the assessed amounts. Deposits are mapped through the challan allocations; deductions with no allocation become unmapped rows the validation flags. Refused on a Filed return. Returns row counts, deducted/deposited totals and the unmapped count. | | `CreateTdsCorrectionReturn` | Create Correction | ServerAction (`CreateTdsCorrectionReturn`) | Drafts a Correction statement against this Filed return: a new TdsReturn header with ReturnType Correction and OriginalReturnId pointing back, ready to be computed and filed independently. The filed original stays frozen. | | `DeleteListRow` | Delete | Delete | Delete | | `EditHeader` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | Edit | | `ExportTdsFvuText` | Export e-Return File | ServerAction (`ExportTdsFvuText`) | Renders the computed return as the caret-delimited e-TDS/TCS statement text - one file-header line, one batch-header line, then the challan and deductee record lines in sequence - the structural skeleton the Protean RPU imports and the FVU validates. Returns the file name, format version, line count and content; amounts are plain decimals, dates ddMMyyyy. | | `GenerateSourceDocument` | Generate Source Document | ServerAction, hidden | Reconciliation remedy: raise the missing Bill/Invoice as a Draft from a filed deductee line. | | `GenerateTdsCertificates` | Generate Certificates | ServerAction (`GenerateTdsCertificates`) | Generates the withholding-certificate register from this FILED return: one TdsCertificate per deductee (Form 131 for Form-140 returns, Form 27D for Form-143, Form 16 register rows for Form-138), numbered TAN/kind/FY/quarter/sequence, stamping the certificate number back onto the underlying TdsTransaction rows so the ledger and register cite the same reference. Regeneration wipes Draft certificates and rebuilds; a return with Issued certificates is locked. | | `ImportPanVerificationResults` | Import PAN Verification | ServerAction (`ImportPanVerificationResults`) | Imports the TRACES bulk PAN verification result file: each row's verdict (Verified, Invalid, Name Mismatch) is applied so PAN problems surface before filing rather than as portal rejections afterwards. | | `MarkTdsReturnFiled` | Mark Filed | ServerAction (`MarkTdsReturnFiled`) | Records the portal filing: stamps the acknowledgment number and filed date, computes the late-filing fee when overdue (200 rupees per day capped at the tax amount), and advances Status to Filed - after which recompute is refused. Filing itself happens on the government portal; this records the outcome. | | `New` | New | New | New | | `OpenTdsReconciliationConsole` | Reconciliation Console | UIAction | Open the books-vs-returns-vs-challans console: drill into a period and resolve each case. | | `RebuildStrictLine` | Rebuild Line (Strict) | ServerAction, hidden | Reconciliation remedy: align a non-filed return line's rate and tax to its ledger row. | | `ReconcileBooks` | Verify Books vs Returns | UIAction | Pick company, financial year and nature, then reconcile the withholding ledger against the filed returns and their challan deposits. | | `ReconcileTdsBooks` | Reconcile Books vs Returns | ServerAction (`ReconcileTdsBooks`), hidden | Year-end deductor-side reconciliation for one company, financial year and nature: ties the TdsTransaction ledger quarter by quarter to what the FILED returns reported and what their challans deposited, surfacing unreturned ledger rows, orphan return lines with no live ledger row behind them, and challans whose deposits are under- or over-consumed by filed returns. | | `ValidateTdsReturn` | Validate Return | ServerAction (`ValidateTdsReturn`) | Runs the pre-file checklist over the computed rows - PAN structure and coverage, deduction-to-challan mapping, challan utilization tie-out, CIN completeness - and stores the findings on the header (ValidationStatus plus the itemized ValidationResults JSON). | ## Related entities - [TdsReturn](/docs/reference/entities/tds-return/) — looks up via `OriginalReturnId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [TdsCertificate](/docs/reference/entities/tds-certificate/) — referenced by via `TdsReturnId` - [TdsReturnChallan](/docs/reference/entities/tds-return-challan/) — referenced by via `TdsReturnId` - [TdsReturn](/docs/reference/entities/tds-return/) — referenced by via `OriginalReturnId` - [TdsReturnDeducteeLine](/docs/reference/entities/tds-return-deductee-line/) — referenced by via `TdsReturnId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # TDS Section — entity reference URL: https://xmatix.com/docs/reference/entities/tds-section/ Last reviewed: 2026-08-16 A withholding-tax section master under the Income-tax Act: TDS sections (contractors, professional fees, purchase of goods, commission and so on) and TCS sections, holding the statutory rate, the PAN-not-available penal rate, the per-transaction and annual exemption thresholds, and when the levy triggers. The calculation service reads this master to decide whether and how much to deduct or collect on each transaction. Rate rows are effective-dated and may be scoped to a deductee bucket, so dual-rate sections are two rows sharing a section code; from FY 2026-27 rows carry the Income-tax Act 2025 payment code that challans and quarterly returns cite, and the ProvisionTdsStatutoryCatalog action upserts the shipped statutory catalog and end-dates superseded old-era rows. An Account can pin a default section for its transactions. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DeducteeTypeScope` | Deductee Type Scope | PickList | | Which deductees this rate row applies to: empty/Any, IndividualHuf, or Others. Dual-rate sections (like contractor payments at 1 or 2 percent) are two rows sharing a SectionCode, split by this scope and matched to the party's deductee classification. Values: Individual / HUF, Others. | | `DeductionPoint` | Deduction Point | PickList | | When the levy is recognized: at bill booking, at payment/receipt, or whichever is earlier (deduped so an earlier-of section is withheld exactly once whichever event fires first). Defaults to bill booking. Values: At bill booking, At payment / receipt, Earlier of bill or payment. | | `Description` | Description | Text | | | | `EffectiveFrom` | Effective From | DateAndTime | | | | `EffectiveTo` | Effective To | Date | | | | `FormCode` | Form Code | PickList | | Values: 138 — Salary (ex-24Q), 140 — Resident non-salary (ex-26Q), 143 — TCS (ex-27EQ), 144 — Non-resident (ex-27Q). | | `Id` | Id | Guid | Yes | | | `IsActive` | Is Active | Boolean | | | | `LeviedOnExcessOverThreshold` | Levied On Excess Over Threshold | Boolean | | True for sections that levy only on the amount exceeding the annual threshold (the 194Q-style 0.1 percent on purchases above 50 lakh). False means once the threshold is crossed the rate applies to the full transaction value. | | `MinorHead` | Minor Head | PickList | | Values: 200 — Regular, 400 — Demand. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Nature` | Nature | PickList | | TDS (tax deducted from amounts payable to vendors) or TCS (tax collected on amounts receivable from customers). Drives which payable control the postings hit and which quarterly form the transactions report on. Values: TDS — deducted on payables, TCS — collected on receivables. | | `NewSectionRef` | New Section Ref | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PaymentCode` | Payment Code | Number | | Income-tax Act 2025 payment code (1001-1092) cited on the ITNS 281 challan and in quarterly-return deductee rows from FY 2026-27. Null on pre-2026 legacy rows, which keep reporting by SectionCode; section resolution transparently maps a legacy-tagged line to the payment-code row valid on the transaction date. | | `Rate` | Rate | Currency | | | | `RateNoPAN` | Rate No PAN | Currency | | Penal rate applied when the party's PAN is missing or invalid (s.206AA for TDS, s.206CC for TCS). A deduction at this rate is reported with remarks code C on the return. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SectionCode` | Section Code | Text | | | | `ThresholdAnnual` | Threshold Annual | Currency | | Annual aggregate exemption: deduction starts once the party's financial-year-to-date base crosses this amount. Whether the levy then applies to the full value or only the excess is controlled by LeviedOnExcessOverThreshold. | | `ThresholdSingle` | Threshold Single | Currency | | Per-transaction exemption: a single payment below this amount is never deducted, regardless of the annual aggregate. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `DeleteListRow` | Delete | Delete | Delete | | `EditHeader` | Edit | EditInline | Edit | | `EditListRow` | Edit | Edit | Edit | | `New` | New | New | New TDS | | `ProvisionTdsStatutoryCatalog` | Provision Statutory Catalog | ServerAction (`ProvisionTdsStatutoryCatalog`) | Upserts the shipped FY 2026-27 statutory withholding catalog (Income-tax Act 2025) into this tenant's section master - one row per payment code for the relevant TDS and TCS entries - and end-dates superseded old-era rows. Idempotent, keyed on payment code: a re-run re-asserts the statutory rates and thresholds without duplicating rows, so a Finance Act change ships as a catalog update plus re-run; deliberate tenant adjustments after provisioning are possible but a re-provision re-asserts the shipped values. | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — referenced by via `DefaultTdsSectionId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `TdsSectionId` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — referenced by via `TdsSectionId` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `TdsSectionId` - [LowerDeductionCertificate](/docs/reference/entities/lower-deduction-certificate/) — referenced by via `TdsSectionId` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — referenced by via `TdsSectionId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # TDS Transaction — entity reference URL: https://xmatix.com/docs/reference/entities/tds-transaction/ Last reviewed: 2026-08-16 One withholding event - TDS deducted from a vendor bill/payment or TCS collected on a customer sale - recorded per source document line, mirroring how TaxTransaction captures GST. Written by the posting service when a bill line carries a TDS section: the levy is assessed cumulatively for the fiscal year against the section's thresholds and, when leviable, an adjusting journal is posted (debit the payable control the bill credited, credit TDS payable) with the journal linked back via GLId. Drives section-wise threshold tracking, the withholding payable control balance, monthly deposit challans (via TdsChallanAllocation) and the quarterly return's deductee rows. Status moves from Computed to Deposited when a challan covering it is posted; Reversed rows drop out of reporting. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `BusinessUnitId` | Business Unit | Lookup → [BusinessUnit](/docs/reference/entities/business-unit/) | | | | `CertificateNumber` | Certificate Number | Text | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created On | DateAndTime | Yes | | | `DeductionDate` | Deduction Date | DateAndTime | | The date tax was actually deducted. Equals DocumentDate in every normal posting; later only for a catch-up deduction on a back-dated correction, and that gap is what drives the 1 percent per month late-deduction interest leg on the challan. | | `DocumentDate` | Document Date | DateAndTime | | | | `DocumentNumber` | Document Number | Text | | | | `FiscalPeriodId` | Fiscal Period | Lookup → [FiscalPeriod](/docs/reference/entities/fiscal-period/) | | | | `FiscalYearId` | Fiscal Year | Lookup → [FiscalYear](/docs/reference/entities/fiscal-year/) | | | | `GLId` | GL | Lookup → [Journal](/docs/reference/entities/journal/) | | | | `Id` | Id | Guid | Yes | | | `LdcCertificateId` | Lower Deduction Certificate | Lookup → [LowerDeductionCertificate](/docs/reference/entities/lower-deduction-certificate/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `Nature` | Nature | PickList | | TDS (deducted, payable to the government on the vendor's behalf) or TCS (collected from the customer). Determines which payable control the posting credits and which quarterly form reports the row. Values: TDS — deducted on payables, TCS — collected on receivables. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PanAvailable` | PAN Available | Boolean | | False when the party's PAN was unavailable at deduction time and the penal no-PAN rate was applied (reported with remarks code C on the return). | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyAccountId` | Party Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PartyPan` | Party PAN | Text | | | | `PaymentCode` | Payment Code | Number | | | | `Rate` | Rate | Currency | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RemarksCode` | Remarks Code | PickList | | Return remarks: A (lower-rate certificate applied), B (nil certificate), C (penal no-PAN rate). Empty means deducted at the normal statutory rate. A and B cite the lower-deduction certificate linked via LdcCertificateId. Values: A — Lower deduction (s.395), B — Nil deduction (s.395), C — Higher rate (PAN missing). | | `SectionCode` | Section Code | Text | | | | `SourceEntityName` | Source Entity Name | Text | | | | `SourceRecordId` | Source Record | Guid | | | | `Status` | Status | PickList | | Computed (levy recorded, not yet deposited), Deposited (a posted challan covers it, via its allocation), or Reversed. Challan preparation picks up only undeposited rows. Values: Computed, Deposited, Reversed. | | `TaxableBase` | Taxable Base | Currency | | The portion of the transaction actually subjected to the levy - the full value for ordinary sections, or only the excess over the annual threshold for excess-levy sections. TaxAmount = TaxableBase times Rate; do not recompute from TransactionAmount. | | `TaxAmount` | Tax Amount | Currency | | | | `TdsSectionId` | TDS Section | Lookup → [TdsSection](/docs/reference/entities/tds-section/) | | | | `TransactionAmount` | Transaction Amount | Currency | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Updated On | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `Edit` | Edit | EditInline | Edit | | `New` | New | New | New | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — looks up via `FiscalPeriodId` - [Journal](/docs/reference/entities/journal/) — looks up via `GLId` - [FiscalYear](/docs/reference/entities/fiscal-year/) — looks up via `FiscalYearId` - [Account](/docs/reference/entities/account/) — looks up via `PartyAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [TdsSection](/docs/reference/entities/tds-section/) — looks up via `TdsSectionId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [LowerDeductionCertificate](/docs/reference/entities/lower-deduction-certificate/) — looks up via `LdcCertificateId` - [TdsSection](/docs/reference/entities/tds-section/) — looks up via `TdsSectionId` - [BusinessUnit](/docs/reference/entities/business-unit/) — looks up via `BusinessUnitId` - [TdsChallanAllocation](/docs/reference/entities/tds-challan-allocation/) — referenced by via `TdsTransactionId` - [TdsReturnDeducteeLine](/docs/reference/entities/tds-return-deductee-line/) — referenced by via `TdsTransactionId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Terms — entity reference URL: https://xmatix.com/docs/reference/entities/term/ Last reviewed: 2026-08-16 A terms-and-conditions text block for contract documents. Rows flagged Is Template act as reusable boilerplate, categorized by terms type, line of business and the contract duration they apply to; Sequence number orders the blocks. Standalone in first-party metadata — no foreign key ties a Term to a specific Contract, and no first-party server code consumes its display toggles (Show Scope, Show item Breakup, Show Summary). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ContractDuration` | Contract Duration | PickList | | Contract length this terms block applies to, stored as a picklist string (seeded: 6 months, 12 months, 24 months), not a number. Values: 6 months, 12 months, 24 months. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Description` | Description | Text | | | | `Id` | Id | Guid | Yes | | | `IsTemplate` | Is Template | Boolean | | Marks the row as a reusable boilerplate block rather than one-off terms text. Defaults to false. | | `LOB` | LOB | PickList | | Line of business the terms block applies to. Seeded values: Scientific Services, Automobile Services. Values: Scientific Services, Automobile Services. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Sequencenumber` | Sequence number | Number | | Ordering position of this block relative to other terms records. | | `ShowitemBreakup` | Show item Breakup | Boolean | | Boolean display toggle stored with the block. No first-party server code consumes it; any effect comes from tenant document templates. | | `ShowScope` | Show Scope | Boolean | | Boolean display toggle stored with the block. No first-party server code consumes it; any effect comes from tenant document templates. | | `ShowSummary` | Show Summary | PickList | | Display toggle like ShowScope and ShowitemBreakup, but stored as text rather than boolean in both the domain model and metadata — expect string values where the neighbouring toggles hold true/false. | | `SubscriptionKey` | Subscription Key | Guid, hidden | Yes | | | `TermsType` | Terms Type | PickList | | Category of the terms block. Picklist with a single seeded value, Contract Terms; further values are tenant-defined. Values: Contract Terms. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `New` | New | New | New | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Transcript — entity reference URL: https://xmatix.com/docs/reference/entities/transcript/ Last reviewed: 2026-08-16 A conversation transcript, generic and channel-agnostic: one row per transcribed conversation on any channel (channel: Voice, Chat, SMS, messaging apps, Email, Web), polymorphically linked to the source conversation record via relatedEntityName/relatedEntityId (e.g. a Call). content holds the full text, summary an optional AI summary, and status the pipeline state (None/Pending/Ready/Failed). Transcripts of calls and chats live in this one store - the Call entity only carries a status pointer. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `Channel` | Channel | PickList | | Values: Voice, Chat, SMS, messaging apps, Email, Web. | | `ContactId` | Contact | Lookup → [Contact](/docs/reference/entities/contact/) | | | | `Content` | Transcript | MultiLineText | | | | `Direction` | Direction | PickList | | Values: Inbound, Outbound. | | `EndUtc` | End | DateAndTime | | | | `Language` | Language | Text | | | | `Provider` | Provider | Text | | | | `RelatedEntityId` | Source record id | Lookup, hidden | | | | `RelatedEntityLabel` | Source | Text | | | | `RelatedEntityName` | Source entity | Text | | | | `StartUtc` | Start | DateAndTime | | | | `Status` | Status | PickList | | Values: None, Pending, Ready, Failed. | | `Summary` | Summary | MultiLineText | | | | `WordCount` | Words | Number | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit in page. | | `New` | New | New | New | ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Transfer Inward Line — entity reference URL: https://xmatix.com/docs/reference/entities/transfer-inward-line/ Last reviewed: 2026-08-16 The receiving line of an Inward transfer, normally generated by releasing an outward line rather than entered: TransferOutwardLineId points back at the dispatch line and Quantity equals exactly the batch that was released. Receiving adds to ReceivedQuantity and sets IsReceived — which is set on any partial receipt, so the header can read as fully received while quantity is outstanding. Receiving does not post stock: the inward ledger rows are written later by the header's PerformInventoryPosting, and the save-time hook only re-posts lines that already carry an InventoryLedgerId. Watch the shortage interaction: once anything is received, ShortageQuantity absorbs the remainder and PendingReceivedQuantity falls to zero, so a short receipt closes the line rather than leaving it open. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | The receiving branch. When the line is generated by an outward release it is taken from the outward line's related branch — the two lines' branch fields are deliberately swapped. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DamagedQuantity` | Damaged Quantity | Number | | Damage recorded while receiving; selective receive validates it (and the requested quantity) as non-negative. | | `ExcessQuantity` | Excess Quantity | Calculated (calculated) | | Calculated overage when the receipt exceeds the dispatched quantity; it posts to the Excess stock bucket on update. | | `ExternalId` | External | Text, unique | | | | `Id` | Id | Guid | Yes | | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | Empty until inventory posting runs. The header's calculated posted flags are derived from whether every inward line has one. | | `InventoryStockId` | Stock | Lookup → [InventoryStock](/docs/reference/entities/inventory-stock/) | | Stamped on insert by matching branch, item, lot type and SKU; the stock read-throughs on this line resolve through it, so an unmatched key leaves them reading zero. | | `IsApproved` | Approved | Boolean | | Written by no code path. The flag the posting engine consults is IsILPostingApproved, and receipt is recorded through IsReceived. | | `IsILPosted` | IL Posted | Boolean | Yes | | | `IsILPostingApproved` | IL Posting Approved | Boolean | | | | `IsReceived` | Is Received | Boolean | | | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | On an inward line this is already the destination-branch lot (the clone minted at outward release), not the source lot; the source lot is reachable through the outward line. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Text | | Calculated text mirror of the parent's destination partner. The in-transit bucket only balances when this and the branch match the outward line's related partner and branch — a historical mismatch is what produced 'InTransit cannot go negative' failures. | | `PendingReceivedQuantity` | Pending Received Quantity | Calculated (calculated) | | | | `Quantity` | Quantity | Number | Yes | | | `ReceivedQuantity` | Received Quantity | Number | | Cumulative quantity actually received: receive actions add the requested (or full pending) amount rather than overwrite, supporting multiple partial receipts. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RelatedBranchId` | RelatedBranch | Calculated | | The source branch the stock came from (the outward side); the line's own branchId is the receiving branch. | | `RelatedItemLotId` | Related Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | | | `RelatedPartnerAccountId` | Related Partner Account | Calculated (calculated) | | | | `RequestedQuantity` | Requested Quantity | Decimal | | Carried only in the selective receive payload. Unlike the outward selective action it is not capped against the pending quantity during validation — only negative values are rejected. | | `ShortageQuantity` | Shortage Quantity | Calculated (calculated) | | Calculated as the unreceived balance as soon as anything has been received. Because the pending figure also subtracts it, a short receipt drives pending to zero and closes the line — the remainder cannot simply be received later. It posts to the Shortage stock bucket. | | `SKUId` | Item SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StockAvailable` | StockAvailable | Calculated (calculated) | | | | `StockInHand` | Stock In Hand | Calculated (calculated) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `TransferId` | Transfer | Lookup → [Transfer](/docs/reference/entities/transfer/) | | | | `TransferOutwardLineId` | Transfer Outward Line | Lookup → [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) | | The outward line this inward line was generated from. Every receive recomputes the outward line's closed quantity as the sum of received inward quantities, so the pair always reconciles. | | `TransferType` | Transfer Type | PickList (calculated) | | Calculated from the parent document's type, so on an inward line it resolves to 'Inward' — yet the seeded ledger rules compare it against 'On Hand Transfer' and 'Pending Deliveries Transfer'. Values: On Hand Transfer, Pending Deliveries Transfer. | | `Type` | Type | Calculated | | Left unwritten on inward lines: the parent's document type is mirrored into TransferType here, whereas on single-step and outward lines it lands in this field. Do not rely on it to tell inward from outward. | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | Copied from the dispatching outward line at release, so the receiving branch inherits the source valuation rather than recomputing it. | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Blocked once the line carries a quantity. Generated receiving lines belong to the outward release that created them, so removing them by hand would strand the dispatch's in-transit quantity. | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit | | `New` | New | New | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | XM_QuantityValidation | `Quantity`, Error | Quantity should be greater than zero | Quantity should be greater than zero | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Branch](/docs/reference/entities/branch/) — looks up via `RelatedBranchId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — looks up via `TransferOutwardLineId` - [Transfer](/docs/reference/entities/transfer/) — looks up via `TransferId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `RelatedItemLotId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — looks up via `InventoryStockId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ParentRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Transfer Line — entity reference URL: https://xmatix.com/docs/reference/entities/transfer-line/ Last reviewed: 2026-08-16 The item line of a Single Step transfer: one save books both the outward effect against the source and the inward effect against the destination, which is why single-step moves never park quantity in transit. ItemLotId and StorageLocationId are the source lot and bin; posting clones a fresh destination ItemLot from that source lot and stamps the clone into RelatedItemLotId, while RelatedStorageLocationId holds the destination bin. Damaged, shortage and excess quantities post to their own InventoryStock buckets on update, never on create. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Calculated (calculated) | | Calculated mirror of the header's source branch, stored as text rather than as a lookup — so it cannot be joined or filtered like a normal branch reference. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DamagedQuantity` | Damaged Quantity | Number | | Manually entered. Above zero it books a Damaged effect into the Damaged stock bucket — and only on update, since the seeded rule deliberately does not fire on create. | | `ExcessQuantity` | Excess Quantity | Calculated (calculated) | | Calculated overage when more was received than planned; it posts to the Excess stock bucket on update. | | `FieldSaleLineId` | FieldSaleLine | Guid | | | | `FieldSalesLineId` | Field Sales Line | Lookup → [FieldSalesLine](/docs/reference/entities/field-sales-line/) | | Metadata-only field with no matching property or column in the data model — it can never hold a value. The real link is FieldSaleLineId, spelled without the second 's'. | | `Id` | Id | Guid | Yes | | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | Stamped with the created InventoryLedger row's id when the line is posted; a non-empty value is the was-posted marker, and PerformILPosting refuses when every line already carries one. | | `IsILPosted` | IL Posted | Boolean | Yes | | | `IsILPostingApproved` | IL Posting Approved | Boolean | Yes | Release flows set it as part of releasing. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | The source lot. Posting clones a fresh destination lot from it — same batch, serial, cost and dates, retargeted to the destination branch and partner — and records the clone in RelatedItemLotId. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Calculated (calculated) | | | | `PendingReceivedQuantity` | Pending Received Quantity | Calculated (calculated) | | On a Single Step transfer line, the quantity still awaiting posting; SelectiveTransferPosting validates each requested quantity against it and refuses when no selected line has anything pending. | | `Quantity` | Quantity | Number | | The quantity this single-step document moves; the same value books both the outward effect against the source and the inward effect against the destination in one save. | | `ReceivedQuantity` | Received Quantity | Decimal | | Only incremented by the selective posting action. Plain single-step posting approves the lines without touching it, so a fully posted line can still show its whole quantity as pending received. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RelatedBranchId` | Related Branch | Calculated (calculated) | | Calculated mirror of the header's destination branch, again stored as text; it is the receiving side of this one-document movement. | | `RelatedItemLotId` | Related Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | The counterpart lot on the destination side. On single-step posting the ledger engine books the inward movement against this lot while itemLotId remains the source lot. | | `RelatedPartnerAccountId` | Related Partner Account | Calculated (calculated) | | | | `RelatedStorageLocationId` | Destination Storgae Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | The destination bin/location: the inward half of a single-step posting books stock into this location, while storageLocationId is the source location the stock left. | | `RequestedQuantity` | Requested Quantity | Decimal | | Virtual, never stored: the argument slot the selective transfer actions read. Pass lines with id plus this quantity to act on part of the pending amount; zero or empty means act on the full pending quantity. | | `ShortageQuantity` | Shortage Quantity | Calculated (calculated) | | Calculated as the unreceived remainder once a receipt has been recorded. It posts to the Shortage stock bucket rather than reducing the transfer, so shortages are tracked, not written off. | | `SKUId` | Item SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StorageLocationId` | Source Storgae Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | | | `TransferId` | Transfer | Lookup → [Transfer](/docs/reference/entities/transfer/) | Yes | The parent document. | | `TransferType` | Transfer Type | PickList | | Carries special movement vocabularies: the value Pending Deliveries Transfer makes ledger posting skip the in-transit movement entirely, so the transfer only re-buckets sold-but-undelivered stock. Values: On Hand Transfer, Pending Deliveries Transfer. | | `Type` | Type | Calculated (calculated) | | Calculated mirror of the parent document's type. It is not the movement kind — that is TransferType, which decides whether the posting touches on-hand or the pending-deliveries bucket. | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditinHeader` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit, inactive | Edit | | `New` | New | New | New | | `New1` | New | UIAction, inactive | New | | `NewInLine` | Quick Add | NewInline | New | ## Related entities - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `RelatedStorageLocationId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `RelatedItemLotId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Transfer](/docs/reference/entities/transfer/) — looks up via `TransferId` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [FieldSalesLine](/docs/reference/entities/field-sales-line/) — looks up via `FieldSalesLineId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ParentRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Transfer Outward Line — entity reference URL: https://xmatix.com/docs/reference/entities/transfer-outward-line/ Last reviewed: 2026-08-16 The dispatch line of an Outward transfer. Quantity is the plan, ReleasedQuantity is the running total dispatched, CurrentReleasedQuantity holds only the batch released by the most recent call — and that last one is what the ledger rules actually post — while PendingReleaseQuantity is Quantity minus ReleasedQuantity and ClosedQuantity is back-filled as the paired inward lines confirm receipt (PendingInwardQuantity is ReleasedQuantity minus ClosedQuantity). Releasing approves the line for posting, clones a destination ItemLot into RelatedItemLotId, creates the paired Inward Transfer document and its inward line, and moves stock into the in-transit bucket, which is keyed with no storage location because goods in transit sit in no bin. StockAvailable and StockInHand are read-throughs of the linked InventoryStock row, not reservations. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Calculated (calculated) | | Calculated text mirror of the header's source branch. When the inward line is generated it receives this value as its related branch, and the related branch as its own. | | `ClosedQuantity` | Closed Quantity | Number | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrentReleasedQuantity` | Current Released Quantity | Decimal | | | | `ExternalId` | External | Text | | | | `Id` | Id | Guid | Yes | | | `InventoryLedgerId` | Inventory Ledger | Lookup → [InventoryLedger](/docs/reference/entities/inventory-ledger/) | | Stamped with the outward ledger row written at release; the header's calculated posted flag is derived from every line having one. | | `InventoryStockId` | Stock | Lookup → [InventoryStock](/docs/reference/entities/inventory-stock/) | | The stock bucket the line was matched to (branch + item + lot type), resolved by the service before posting. | | `InwardTransferId` | Inward Transfer | Lookup → [Transfer](/docs/reference/entities/transfer/) | | Metadata-only field with no matching property or column in the data model, so it can never hold a value. The outward-to-inward link lives on the headers as InwardTransferId / OutwardTransferId on Transfer. | | `IsApproved` | Approved | Boolean | Yes | Written by no code path; the flag that actually gates posting is IsILPostingApproved, which the release action sets. | | `IsILPosted` | IL Posted | Boolean | Yes | | | `IsILPostingApproved` | IL Posting Approved | Boolean | Yes | Set true by the release action, which is what causes the save pipeline to write the outward ledger rows. Creating the line moves no stock — release does. | | `ItemId` | Item | Lookup → [Item](/docs/reference/entities/item/) | | | | `ItemLotId` | Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | The source lot. At release the platform clones a destination lot from it — same batch, serial, cost and dates, retargeted to the destination branch and partner — and stores the clone in RelatedItemLotId, which then becomes the receiving line's lot. | | `ItemLotTypeId` | Item Lot Type | Lookup → [ItemLotType](/docs/reference/entities/item-lot-type/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Calculated (calculated) | | | | `PendingInwardQuantity` | Pending Inward Quantity | Calculated (calculated) | | | | `PendingReleaseQuantity` | Pending Release Quantity | Calculated (calculated) | | Quantity not yet released to an inward document. Both release actions require it above zero on at least one (selected) line; the header only flips isOutwardReleased when every line reaches zero, so this drives partial-release behavior. | | `Quantity` | Quantity | Number | | The planned dispatch for this line. Pending release is this minus what has already been released, and the header only reads as released once no line has any pending. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RelatedBranchId` | Related Branch | Calculated (calculated) | | Destination-side branch key: the generated inward line's branchId is taken from here, and its relatedBranchId from this line's branchId - the two sides mirror each other. | | `RelatedItemLotId` | Related Item Lot | Lookup → [ItemLot](/docs/reference/entities/item-lot/) | | The destination-branch item-lot clone minted at release time - a copy of the source lot (batch, serial, cost, dates) re-owned by the destination partner and branch. The generated inward line receives it as its itemLotId. | | `RelatedPartnerAccountId` | Related Partner | Calculated (calculated) | | Destination-side owning company for cross-company transfers; used when generating the inward line's partner keys, falling back to the header's destination partner. | | `ReleasedQuantity` | Released Quantity | Decimal | | | | `RequestedQuantity` | Requested Quantity | Number | | Virtual argument slot for SelectiveOutwardRelease: quantity to release now, validated against pendingReleaseQuantity; zero or empty releases the full pending amount. | | `RequisitionId` | Requisition | Lookup → [Requisition](/docs/reference/entities/requisition/) | | Set when the dispatch was raised to satisfy a requisition; the line quantity is aggregated back onto the requisition line's stock-transfer quantity. | | `RequisitionLineId` | Requisition Line | Lookup → [RequisitionLine](/docs/reference/entities/requisition-line/) | | The requisition line this outward line satisfies; the line quantity aggregates onto that requisition line's stock-transfer quantity rollup. | | `SKUId` | Item SKU | Lookup → [SKU](/docs/reference/entities/sku/) | | | | `StockAvailable` | Stock Available | Calculated (calculated) | | Read-through of the linked stock row's available figure; it reads zero when no stock row is linked, so it is not a safe availability check before dispatch. | | `StockInHand` | Stock In Hand | Calculated (calculated) | | | | `StorageLocationId` | Storage Location | Lookup → [StorageLocation](/docs/reference/entities/storage-location/) | | The bin the goods are dispatched from. The in-transit stock row is deliberately keyed with no storage location, because goods in transit are in no bin. | | `TransferId` | Transfer | Lookup → [Transfer](/docs/reference/entities/transfer/) | | | | `TransferType` | Transfer Type | PickList | | Decides which seeded outward rule fires: 'Pending Deliveries Transfer' draws the batch down from the pending-deliveries bucket, anything else books a normal outward movement. It defaults to 'On Hand Transfer' and is copied onto the generated inward line. Values: Pending Deliveries Transfer, On Hand Transfer. | | `Type` | Type | Calculated (calculated) | | Calculated mirror of the parent document's type; distinct from TransferType, which is the stock-movement kind. | | `UIProps` | UI Props | Text | | | | `UnitCost` | Unit Cost | Currency | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEnitity` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `New` | Quick Add | NewInline | New | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | XM_QuantityValidation | `ClosedQuantity`, Error | Closed Quantity cannot be greater than Quantity! | Closed Quantity cannot be greater than Quantity! | ## Related entities - [Requisition](/docs/reference/entities/requisition/) — looks up via `RequisitionId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `ItemLotId` - [Item](/docs/reference/entities/item/) — looks up via `ItemId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — looks up via `InventoryLedgerId` - [Transfer](/docs/reference/entities/transfer/) — looks up via `TransferId` - [Transfer](/docs/reference/entities/transfer/) — looks up via `InwardTransferId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — looks up via `ItemLotTypeId` - [ItemLot](/docs/reference/entities/item-lot/) — looks up via `RelatedItemLotId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [RequisitionLine](/docs/reference/entities/requisition-line/) — looks up via `RequisitionLineId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — looks up via `InventoryStockId` - [StorageLocation](/docs/reference/entities/storage-location/) — looks up via `StorageLocationId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [SKU](/docs/reference/entities/sku/) — looks up via `SKUId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `TransferOutwardLineId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ParentRecordId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Transfer — entity reference URL: https://xmatix.com/docs/reference/entities/transfer/ Last reviewed: 2026-08-16 The header of a stock movement between branches or partner companies, whose Type decides which of three line collections it uses: Outward (dispatch leg, TransferOutwardLines), Inward (receiving leg, TransferInwardLines) or Single Step (TransferLines, one document that books both effects with no transit leg). A two-step move is therefore two documents, not two line sets: releasing an outward transfer generates a whole new Inward Transfer record plus one inward line per released batch, cross-linked by OutwardTransferId and InwardTransferId. The four Is* flags are calculated over the lines and are the real machine state; Status is only ever written as 'Draft' by the field-sales van-load generator and by its default formula, so it does not track progress. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | From Branch | Lookup → [Branch](/docs/reference/entities/branch/) | Yes | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DocumentDate` | Document Date | DateAndTime | | Stamped with the server's current time when the transfer is inserted. | | `ExecutiveResourceId` | Executive | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `ExternalId` | External | Text, unique | | | | `FieldSalesId` | Field Sales | Lookup → [FieldSales](/docs/reference/entities/field-sales/) | | Links the document to a field-sales run: the van-load generator creates an Outward transfer and the take-in generator an Inward transfer, both stamped with this key and both left in Draft. | | `Id` | Id | Guid | Yes | | | `InwardTransferId` | Inward Document | Lookup → [Transfer](/docs/reference/entities/transfer/) | | | | `IsILPosted` | IL Posted | Calculated (calculated) | | Calculated: true only when the document has lines and every line across all three collections carries an InventoryLedgerId. It is never stamped by the posting code, so it cannot drift from the lines. | | `IsInwardPosted` | Inward Posted | Calculated (calculated) | | Calculated: true when the document has inward lines and none of them is still missing an InventoryLedgerId — that is, the receiving leg has reached the ledger. | | `IsInwardReceived` | Inward Received | Boolean | | Flips true when every inward line has been received. Once true, PerformInwardReceive and SelectiveInwardReceive refuse to run again. | | `IsOutwardReleased` | Outward Released | Calculated (calculated) | | Set true by outward release only when every outward line has no pending release quantity left - a partial (selective) release leaves it false so the document can be released again. PerformOutwardRelease refuses once it is true. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Document Number | Text | | | | `OutwardTransferId` | Outward Document | Lookup → [Transfer](/docs/reference/entities/transfer/) | | On an Inward transfer, points back at the Outward transfer whose release created it (the outward document gets inwardTransferId stamped in the same operation). A transfer with this set was system-generated by PerformOutwardRelease rather than keyed by hand. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | From Partner Account | Lookup → [Account](/docs/reference/entities/account/) | Yes | The source partner company. | | `PerformILPosting` | Perform IL Posting | Boolean | | | | `PerformInwardPosting` | Perform Inward Posting | Boolean | | | | `PerformInwardReceive` | Perform Inward Receive | Boolean | | | | `PerformOutwardRelease` | Perform Outward Release | Boolean | | | | `PurchaseRequisitionId` | Purchase Requisition | Lookup → [Requisition](/docs/reference/entities/requisition/) | | The purchase Requisition this transfer was raised to satisfy (requisition-driven stock transfers); the individual outward lines link back via their requisitionLineId and aggregate their quantity onto the requisition line's stock-transfer rollup. | | `ReceivedResourceId` | Received By | Lookup → [Resource](/docs/reference/entities/resource/) | | The resource who will receive the stock at the destination. Outward release - full or selective - refuses to run until this is set. | | `ReceivedTime` | Received Time | Date | | Written by no code path. Receipt is evidenced on the inward lines through IsReceived and ReceivedQuantity, and on the header through the calculated IsInwardReceived. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Status` | Status | PickList | | Values: Draft, Pending Approval - Outward, Approved - Outward, Released, Pending Approval - Inward, Approved - Inward, Received. | | `ToBranchId` | To Branch | Lookup → [Branch](/docs/reference/entities/branch/) | Yes | The destination branch of the movement; the source branch is branchId (whose navigation is named FromBranch). Outward release copies both onto the generated inward document, and destination item-lot clones are created under this branch. | | `ToPartnerAccountId` | To Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | The destination owning company when a transfer crosses companies. Item-lot clones minted for the destination are owned by this account, falling back to partnerAccountId when empty - so leaving it blank means an intra-company transfer. | | `TotalClosedQuantity` | Total Closed Quantity | Calculated (calculated) | | | | `TotalQuantity` | Total Quantity | Calculated (calculated) | | Calculated per document type: inward lines for Inward, outward lines for Outward, otherwise the single-step lines. A document whose lines sit in a different collection than its type implies therefore totals zero. | | `TransferredByResourceId` | Transferred By | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `TransferTime` | Transfer Time | DateAndTime | | Also stamped with the server's current time on insert; it is not moved forward when the outward release actually happens, so it records document creation rather than dispatch. | | `Type` | Type | PickList | Yes | Values: Inward, Single Step, Outward. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | EditInline | Edit | | `EditEntityDetails` | Edit | Edit | Edit Entity | | `EditInLines` | Edit | EditInline | Edit | | `New` | New | New | New | | `PerformILPosting` | Post Inventory | ServerAction (`PerformILPosting`) | Perform Inventory Posting | | `PerformInventoryPosting` | Post Inventory | ServerAction (`PerformInventoryPosting`) | This action perform inventory posting. | | `PerformInwardReceive` | Inward Recieve | ServerAction (`PerformInwardReceive`) | Receive TransferOutwardLine as InwardLines | | `PerformOutwardRelease` | Release Outward | ServerAction (`PerformOutwardRelease`) | Releases Outward Document. | | `SelectiveInwardReceive` | Selective Inward Receive | ServerAction (`SelectiveInwardReceive`) | Selective Inward Receive | | `SelectiveOutwardRelease` | Selective Release Outward | ServerAction (`SelectiveOutwardRelease`) | Selective Release Outward | | `SelectiveTransferPosting` | Selective Transfer | ServerAction (`SelectiveTransferPosting`) | Selective Transfer Posting | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Restrict Inward Create | `Type`, Error | Inward Document cannot be generated without an Outward Transfer Document. | Restrict Inward Create | | Branch Rule Validation | `BranchId`, Error, inactive | Branch can't be same | Branch can't be same | | XM_DocumentDateChangeValidation | `DocumentDate`, Error | You cannot change Document Date | You cannot change Document Date | | XM_ReceivedTimeRuleValidation | `ReceivedTime`, Error | Received Time should be greater than transfer time | Received Time should be greater than transfer time | | Required Fields | Error | Selection of To Partner Account and To Branch is mandatory. | Selection of To Partner Account and To Branch is mandatory. | | XM_TimeValidation | `TransferTime`, Error | Transfer Time can't be less than received time | Transfer Time can't be less than received time | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | FromBranch For Partner Account | `BranchId` | | | To Branch For Partner Account | `ToBranchId` | | ## Related entities - [Branch](/docs/reference/entities/branch/) — looks up via `ToBranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ReceivedResourceId` - [Transfer](/docs/reference/entities/transfer/) — looks up via `InwardTransferId` - [Account](/docs/reference/entities/account/) — looks up via `ToPartnerAccountId` - [Resource](/docs/reference/entities/resource/) — looks up via `TransferredByResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Transfer](/docs/reference/entities/transfer/) — looks up via `OutwardTransferId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [Requisition](/docs/reference/entities/requisition/) — looks up via `PurchaseRequisitionId` - [Resource](/docs/reference/entities/resource/) — looks up via `ExecutiveResourceId` - [FieldSales](/docs/reference/entities/field-sales/) — looks up via `FieldSalesId` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `InwardTransferId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `TransferId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `InwardTransferId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `TransferId` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `OutwardTransferId` - [TransferLine](/docs/reference/entities/transfer-line/) — referenced by via `TransferId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # User Account — entity reference URL: https://xmatix.com/docs/reference/entities/user-account/ Last reviewed: 2026-10-09 A User Account is one person, or one built-in system identity, in the organization: it holds the sign-in username, e-mail, phone, first, last and display names, the audience (Internal for employees, External for portal and partner users), the active flag, the person's language, locale and time zone, and an optional delegated approver. Every record's Owner, Created By and Modified By point to a user account. Accounts are managed under Setup, Access Control, Users. Saving an active account that has a username or e-mail and no sign-in identity yet provisions the identity in the background and sends the welcome e-mail; inactive accounts are never provisioned. The username must equal the e-mail or be a plain name without @ of up to 64 letters, digits and . - _ ! # ^ ~. A new account defaults to active and Internal, the display name is composed from first and last name when blank, and the name is taken from the username, then the e-mail, then the display name. A delegated approver receives, and may decide, every approval step that resolves to this user, alongside the user. A user's time zone and locale override the organization defaults for that person. Profiles, roles, teams, license seats and company access are separate records attached to the account. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | Yes | The account's record name, set when the account is created from the username, or the e-mail, or the display name when both are blank. Distinct from the display name shown across the product. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [AutoPurchaseOrderLineRelation](/docs/reference/entities/auto-purchase-order-line-relation/) — referenced by via `OwnerId` - [GSTR6ISDRecipientAllocation](/docs/reference/entities/gstr6-isdrecipient-allocation/) — referenced by via `CreatedById` - [Adjustment](/docs/reference/entities/adjustment/) — referenced by via `OwnerId` - [Item](/docs/reference/entities/item/) — referenced by via `OwnerId` - [FiscalYear](/docs/reference/entities/fiscal-year/) — referenced by via `ModifiedById` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — referenced by via `OwnerId` - [IncentiveResourceTarget](/docs/reference/entities/incentive-resource-target/) — referenced by via `CreatedById` - [PayrollPaymentBatchLine](/docs/reference/entities/payroll-payment-batch-line/) — referenced by via `OwnerId` - [TdsSection](/docs/reference/entities/tds-section/) — referenced by via `ModifiedById` - [SubscriptionUsageSummary](/docs/reference/entities/subscription-usage-summary/) — referenced by via `ModifiedById` - [LWFRule](/docs/reference/entities/lwfrule/) — referenced by via `ModifiedById` - [ExpenseReimbursementBatch](/docs/reference/entities/expense-reimbursement-batch/) — referenced by via `ModifiedById` - [TdsSection](/docs/reference/entities/tds-section/) — referenced by via `OwnerId` - [ProfessionalTaxSlab](/docs/reference/entities/professional-tax-slab/) — referenced by via `ModifiedById` - [ClaimGenerationSetupRule](/docs/reference/entities/claim-generation-setup-rule/) — referenced by via `OwnerId` - [GSTR3BRule37Tracker](/docs/reference/entities/gstr3-brule37-tracker/) — referenced by via `ModifiedById` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — referenced by via `CreatedById` - [VisitTaskTemplateActivity](/docs/reference/entities/visit-task-template-activity/) — referenced by via `CreatedById` - [ClaimSettlementSetup](/docs/reference/entities/claim-settlement-setup/) — referenced by via `CreatedById` - [CurrencyRevaluation](/docs/reference/entities/currency-revaluation/) — referenced by via `ModifiedById` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `CreatedById` - [DiscountGroup](/docs/reference/entities/discount-group/) — referenced by via `ModifiedById` - [ResourceGroup](/docs/reference/entities/resource-group/) — referenced by via `ModifiedById` - [GSTR3BSection31](/docs/reference/entities/gstr3-bsection31/) — referenced by via `ModifiedById` - [Account](/docs/reference/entities/account/) — referenced by via `ModifiedById` - [TdsChallanAllocation](/docs/reference/entities/tds-challan-allocation/) — referenced by via `CreatedById` - [ClaimReconciliationLine](/docs/reference/entities/claim-reconciliation-line/) — referenced by via `OwnerId` - [TaxDeclaration](/docs/reference/entities/tax-declaration/) — referenced by via `CreatedById` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — referenced by via `ModifiedById` - [ExpenseReimbursementBatch](/docs/reference/entities/expense-reimbursement-batch/) — referenced by via `CreatedById` - [GSTR6ISDSourceDocument](/docs/reference/entities/gstr6-isdsource-document/) — referenced by via `ModifiedById` - [CompanyCardReconciliation](/docs/reference/entities/company-card-reconciliation/) — referenced by via `OwnerId` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — referenced by via `ModifiedById` - [AssetBlock](/docs/reference/entities/asset-block/) — referenced by via `ModifiedById` - [PaymentAdjustment](/docs/reference/entities/payment-adjustment/) — referenced by via `CreatedById` - [AccountStock](/docs/reference/entities/account-stock/) — referenced by via `ModifiedById` - [GSTR6ISDSourceDocument](/docs/reference/entities/gstr6-isdsource-document/) — referenced by via `CreatedById` - [LandedCost](/docs/reference/entities/landed-cost/) — referenced by via `CreatedById` - [EInvoice](/docs/reference/entities/einvoice/) — referenced by via `ModifiedById` - [KPIDataDetail](/docs/reference/entities/kpidata-detail/) — referenced by via `CreatedById` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `CreatedById` - [ServiceOrderTimeSheetLine](/docs/reference/entities/service-order-time-sheet-line/) — referenced by via `ModifiedById` - [GSTR3BItcAvailable](/docs/reference/entities/gstr3-bitc-available/) — referenced by via `OwnerId` - [ClaimGenerationSetup](/docs/reference/entities/claim-generation-setup/) — referenced by via `CreatedById` - [SettlementAllocation](/docs/reference/entities/settlement-allocation/) — referenced by via `CreatedById` - [DocumentServiceContractLine](/docs/reference/entities/document-service-contract-line/) — referenced by via `ModifiedById` - [ResourceBusinessHours](/docs/reference/entities/resource-business-hours/) — referenced by via `ModifiedById` - [ClaimReconciliation](/docs/reference/entities/claim-reconciliation/) — referenced by via `ModifiedById` - [ItemLotType](/docs/reference/entities/item-lot-type/) — referenced by via `CreatedById` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `ModifiedById` - [PurchaseOrderRequisition](/docs/reference/entities/purchase-order-requisition/) — referenced by via `CreatedById` - [CheckInInspection](/docs/reference/entities/check-in-inspection/) — referenced by via `OwnerId` - [CheckInTemplate](/docs/reference/entities/check-in-template/) — referenced by via `CreatedById` - [ContactAddress](/docs/reference/entities/contact-address/) — referenced by via `CreatedById` - [ClaimBatch](/docs/reference/entities/claim-batch/) — referenced by via `CreatedById` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — referenced by via `OwnerId` - [BankStatement](/docs/reference/entities/bank-statement/) — referenced by via `ModifiedById` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `CreatedById` - [TdsChallan](/docs/reference/entities/tds-challan/) — referenced by via `CreatedById` - [LowerDeductionCertificate](/docs/reference/entities/lower-deduction-certificate/) — referenced by via `ModifiedById` - [CostCenter](/docs/reference/entities/cost-center/) — referenced by via `CreatedById` - [Bill](/docs/reference/entities/bill/) — referenced by via `OwnerId` - [PeriodClose](/docs/reference/entities/period-close/) — referenced by via `OwnerId` - [ItemAlias](/docs/reference/entities/item-alias/) — referenced by via `ModifiedById` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `OwnerId` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — referenced by via `CreatedById` - [TaxGroupRule](/docs/reference/entities/tax-group-rule/) — referenced by via `CreatedById` - [Lead](/docs/reference/entities/lead/) — referenced by via `CreatedById` - [ItemGroupRule](/docs/reference/entities/item-group-rule/) — referenced by via `CreatedById` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — referenced by via `CreatedById` - [PayrollPeriod](/docs/reference/entities/payroll-period/) — referenced by via `OwnerId` - [Currency](/docs/reference/entities/currency/) — referenced by via `CreatedById` - [SchemeLine](/docs/reference/entities/scheme-line/) — referenced by via `CreatedById` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `ModifiedById` - [ExpenseAdvanceSettlement](/docs/reference/entities/expense-advance-settlement/) — referenced by via `CreatedById` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `ModifiedById` - [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) — referenced by via `OwnerId` - [ExpenseReceipt](/docs/reference/entities/expense-receipt/) — referenced by via `OwnerId` - [EWayBill](/docs/reference/entities/eway-bill/) — referenced by via `CreatedById` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `CreatedById` - [ServiceOrderTimeSheet](/docs/reference/entities/service-order-time-sheet/) — referenced by via `OwnerId` - [PayrollPaymentBatchLine](/docs/reference/entities/payroll-payment-batch-line/) — referenced by via `OwnerId` - [BusinessHours](/docs/reference/entities/business-hours/) — referenced by via `OwnerId` - [ResourceLeave](/docs/reference/entities/resource-leave/) — referenced by via `OwnerId` - [KYCDocument](/docs/reference/entities/kycdocument/) — referenced by via `CreatedById` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — referenced by via `ModifiedById` - AccountGroupCloneTestv5 — referenced by - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `ModifiedById` - [TaxTransaction](/docs/reference/entities/tax-transaction/) — referenced by via `CreatedById` - [IncentivePeriod](/docs/reference/entities/incentive-period/) — referenced by via `OwnerId` - [BankStatementLine](/docs/reference/entities/bank-statement-line/) — referenced by via `CreatedById` - [VisitTask](/docs/reference/entities/visit-task/) — referenced by via `CreatedById` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `ModifiedById` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `CreatedById` - [ResourceBusinessHours](/docs/reference/entities/resource-business-hours/) — referenced by via `CreatedById` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `CreatedById` - [CurrencyRevaluation](/docs/reference/entities/currency-revaluation/) — referenced by via `CreatedById` - [AccountStock](/docs/reference/entities/account-stock/) — referenced by via `CreatedById` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `CreatedById` - [FieldSalesLine](/docs/reference/entities/field-sales-line/) — referenced by via `OwnerId` - [SchemeAccountBudget](/docs/reference/entities/scheme-account-budget/) — referenced by via `OwnerId` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — referenced by via `OwnerId` - [ResourceAssignmentRule](/docs/reference/entities/resource-assignment-rule/) — referenced by via `OwnerId` - [DebitNoteLine](/docs/reference/entities/debit-note-line/) — referenced by via `ModifiedById` - [BranchTimeSlotBooking](/docs/reference/entities/branch-time-slot-booking/) — referenced by via `ModifiedById` - [BusinessUnit](/docs/reference/entities/business-unit/) — referenced by via `OwnerId` - [GSTR6ISDDocumentSeries](/docs/reference/entities/gstr6-isddocument-series/) — referenced by via `OwnerId` - [AutoPurchaseOrderLineRelation](/docs/reference/entities/auto-purchase-order-line-relation/) — referenced by via `CreatedById` - [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) — referenced by via `ModifiedById` - [EInvoice](/docs/reference/entities/einvoice/) — referenced by via `OwnerId` - [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) — referenced by via `OwnerId` - [BudgetCommitment](/docs/reference/entities/budget-commitment/) — referenced by via `OwnerId` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `CreatedById` - [VisitRouteStop](/docs/reference/entities/visit-route-stop/) — referenced by via `OwnerId` - [PayrollRunComponentLine](/docs/reference/entities/payroll-run-component-line/) — referenced by via `CreatedById` - [ResourceAssignmentRule](/docs/reference/entities/resource-assignment-rule/) — referenced by via `CreatedById` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — referenced by via `CreatedById` - [ItemServiceContractLine](/docs/reference/entities/item-service-contract-line/) — referenced by via `CreatedById` - [PartyPeriodBalance](/docs/reference/entities/party-period-balance/) — referenced by via `ModifiedById` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `OwnerId` - [Complaint](/docs/reference/entities/complaint/) — referenced by via `OwnerId` - [ItemFeature](/docs/reference/entities/item-feature/) — referenced by via `ModifiedById` - [ClaimReconciliation](/docs/reference/entities/claim-reconciliation/) — referenced by via `OwnerId` - [BookValuationAdjustment](/docs/reference/entities/book-valuation-adjustment/) — referenced by via `ModifiedById` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `OwnerId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `CreatedById` - [ExpenseReimbursementBatch](/docs/reference/entities/expense-reimbursement-batch/) — referenced by via `OwnerId` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — referenced by via `ModifiedById` - [SchemeAccountBudgetUtilization](/docs/reference/entities/scheme-account-budget-utilization/) — referenced by via `ModifiedById` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — referenced by via `CreatedById` - [PriceList](/docs/reference/entities/price-list/) — referenced by via `ModifiedById` - [TdsCertificate](/docs/reference/entities/tds-certificate/) — referenced by via `ModifiedById` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — referenced by via `OwnerId` - [ITCLedger](/docs/reference/entities/itcledger/) — referenced by via `CreatedById` - [Scheme](/docs/reference/entities/scheme/) — referenced by via `CreatedById` - [CampaignMember](/docs/reference/entities/campaign-member/) — referenced by via `ModifiedById` - [FinanceCase](/docs/reference/entities/finance-case/) — referenced by via `ModifiedById` - [GSTR6ISDRecipientTurnover](/docs/reference/entities/gstr6-isdrecipient-turnover/) — referenced by via `OwnerId` - [Resource](/docs/reference/entities/resource/) — referenced by via `CreatedById` - [PaymentBatch](/docs/reference/entities/payment-batch/) — referenced by via `CreatedById` - [PaymentBatchLine](/docs/reference/entities/payment-batch-line/) — referenced by via `CreatedById` - [PostingDefinition](/docs/reference/entities/posting-definition/) — referenced by via `CreatedById` - [ExpensePolicyRule](/docs/reference/entities/expense-policy-rule/) — referenced by via `CreatedById` - [BankStatement](/docs/reference/entities/bank-statement/) — referenced by via `OwnerId` - [AutoOrder](/docs/reference/entities/auto-order/) — referenced by via `CreatedById` - [PriceListRule](/docs/reference/entities/price-list-rule/) — referenced by via `ModifiedById` - [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) — referenced by via `OwnerId` - [ClaimBatchLine](/docs/reference/entities/claim-batch-line/) — referenced by via `OwnerId` - [ResourceLeave](/docs/reference/entities/resource-leave/) — referenced by via `ModifiedById` - [ChequeTransaction](/docs/reference/entities/cheque-transaction/) — referenced by via `ModifiedById` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `CreatedById` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `OwnerId` - [FinancerScheme](/docs/reference/entities/financer-scheme/) — referenced by via `CreatedById` - [BookValuationAdjustment](/docs/reference/entities/book-valuation-adjustment/) — referenced by via `OwnerId` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — referenced by via `ModifiedById` - [FieldSalesLine](/docs/reference/entities/field-sales-line/) — referenced by via `CreatedById` - [InventoryLedgerSetting](/docs/reference/entities/inventory-ledger-setting/) — referenced by via `CreatedById` - [CurrencyRevaluationLine](/docs/reference/entities/currency-revaluation-line/) — referenced by via `CreatedById` - [ChequeRegister](/docs/reference/entities/cheque-register/) — referenced by via `OwnerId` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — referenced by via `OwnerId` - [Tax](/docs/reference/entities/tax/) — referenced by via `OwnerId` - [ResourceSkill](/docs/reference/entities/resource-skill/) — referenced by via `CreatedById` - [IncentiveLine](/docs/reference/entities/incentive-line/) — referenced by via `ModifiedById` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `OwnerId` - [LeaveType](/docs/reference/entities/leave-type/) — referenced by via `OwnerId` - [TaxGroupRule](/docs/reference/entities/tax-group-rule/) — referenced by via `ModifiedById` - [Grade](/docs/reference/entities/grade/) — referenced by via `OwnerId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — referenced by via `CreatedById` - [GSTR3BPayment](/docs/reference/entities/gstr3-bpayment/) — referenced by via `CreatedById` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `OwnerId` - [ItemGroupRule](/docs/reference/entities/item-group-rule/) — referenced by via `ModifiedById` - [LoanAdvanceRecovery](/docs/reference/entities/loan-advance-recovery/) — referenced by via `OwnerId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — referenced by via `ModifiedById` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — referenced by via `CreatedById` - [LandedCost](/docs/reference/entities/landed-cost/) — referenced by via `OwnerId` - [GSTR3BPayment](/docs/reference/entities/gstr3-bpayment/) — referenced by via `OwnerId` - [PartnerResource](/docs/reference/entities/partner-resource/) — referenced by via `ModifiedById` - AccountGroupCloneTestv5 — referenced by - [GSTRegistration](/docs/reference/entities/gstregistration/) — referenced by via `ModifiedById` - [AccountLocation](/docs/reference/entities/account-location/) — referenced by via `CreatedById` - [AssetServiceContractLine](/docs/reference/entities/asset-service-contract-line/) — referenced by via `OwnerId` - [BranchTimeSlotBooking](/docs/reference/entities/branch-time-slot-booking/) — referenced by via `CreatedById` - [EWayBill](/docs/reference/entities/eway-bill/) — referenced by via `OwnerId` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `CreatedById` - [Branch](/docs/reference/entities/branch/) — referenced by via `CreatedById` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `OwnerId` - [PeriodCloseCheck](/docs/reference/entities/period-close-check/) — referenced by via `OwnerId` - [PostingErrorLog](/docs/reference/entities/posting-error-log/) — referenced by via `OwnerId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — referenced by via `OwnerId` - [LeaveRequest](/docs/reference/entities/leave-request/) — referenced by via `CreatedById` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `CreatedById` - [IncentiveResource](/docs/reference/entities/incentive-resource/) — referenced by via `ModifiedById` - [DebitNote](/docs/reference/entities/debit-note/) — referenced by via `CreatedById` - [CompensationSlab](/docs/reference/entities/compensation-slab/) — referenced by via `CreatedById` - [Item](/docs/reference/entities/item/) — referenced by via `ModifiedById` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `ModifiedById` - [SubscriptionUsage](/docs/reference/entities/subscription-usage/) — referenced by via `OwnerId` - [InventoryLedgerSetting](/docs/reference/entities/inventory-ledger-setting/) — referenced by via `OwnerId` - [FullAndFinalSettlementLine](/docs/reference/entities/full-and-final-settlement-line/) — referenced by via `OwnerId` - [ExchangeRate](/docs/reference/entities/exchange-rate/) — referenced by via `ModifiedById` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `CreatedById` - [CompanyCardReconciliation](/docs/reference/entities/company-card-reconciliation/) — referenced by via `ModifiedById` - [SchemeAccountBudgetUtilization](/docs/reference/entities/scheme-account-budget-utilization/) — referenced by via `OwnerId` - [PriceList](/docs/reference/entities/price-list/) — referenced by via `CreatedById` - [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) — referenced by via `CreatedById` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `OwnerId` - [KPIDataDetail](/docs/reference/entities/kpidata-detail/) — referenced by via `OwnerId` - [Payslip](/docs/reference/entities/payslip/) — referenced by via `OwnerId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `CreatedById` - [PaymentBatchLine](/docs/reference/entities/payment-batch-line/) — referenced by via `ModifiedById` - [FieldSalesLine](/docs/reference/entities/field-sales-line/) — referenced by via `ModifiedById` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — referenced by via `CreatedById` - [SKU](/docs/reference/entities/sku/) — referenced by via `ModifiedById` - [Tax](/docs/reference/entities/tax/) — referenced by via `CreatedById` - [BudgetLine](/docs/reference/entities/budget-line/) — referenced by via `CreatedById` - [SalaryTaxSlab](/docs/reference/entities/salary-tax-slab/) — referenced by via `ModifiedById` - [ItemFeature](/docs/reference/entities/item-feature/) — referenced by via `OwnerId` - [Scheme](/docs/reference/entities/scheme/) — referenced by via `OwnerId` - [IncentiveLine](/docs/reference/entities/incentive-line/) — referenced by via `CreatedById` - [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) — referenced by via `OwnerId` - [LoanAdvanceRecovery](/docs/reference/entities/loan-advance-recovery/) — referenced by via `CreatedById` - [PayrollPaymentBatchLine](/docs/reference/entities/payroll-payment-batch-line/) — referenced by via `CreatedById` - [ExpenseAdvanceSettlement](/docs/reference/entities/expense-advance-settlement/) — referenced by via `ModifiedById` - [InspectionLine](/docs/reference/entities/inspection-line/) — referenced by via `OwnerId` - [CheckInTemplateLine](/docs/reference/entities/check-in-template-line/) — referenced by via `CreatedById` - [ComplaintFault](/docs/reference/entities/complaint-fault/) — referenced by via `ModifiedById` - [PaymentBatch](/docs/reference/entities/payment-batch/) — referenced by via `OwnerId` - [CycleCountLine](/docs/reference/entities/cycle-count-line/) — referenced by via `CreatedById` - [PublishedStatement](/docs/reference/entities/published-statement/) — referenced by via `CreatedById` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `CreatedById` - [RevenueRecognitionSchedule](/docs/reference/entities/revenue-recognition-schedule/) — referenced by via `ModifiedById` - [SubscriptionUsage](/docs/reference/entities/subscription-usage/) — referenced by via `CreatedById` - [SchemePeriod](/docs/reference/entities/scheme-period/) — referenced by via `CreatedById` - [AccountGroup](/docs/reference/entities/account-group/) — referenced by via `OwnerId` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `ModifiedById` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `ModifiedById` - [Form26ASLine](/docs/reference/entities/form26-asline/) — referenced by via `CreatedById` - [MonthlyTdsProjection](/docs/reference/entities/monthly-tds-projection/) — referenced by via `OwnerId` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — referenced by via `OwnerId` - [PayrollRunComponentLine](/docs/reference/entities/payroll-run-component-line/) — referenced by via `ModifiedById` - [ExpenseReimbursementBatch](/docs/reference/entities/expense-reimbursement-batch/) — referenced by via `CreatedById` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `CreatedById` - [ServiceBay](/docs/reference/entities/service-bay/) — referenced by via `CreatedById` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — referenced by via `ModifiedById` - [TdsChallanAllocation](/docs/reference/entities/tds-challan-allocation/) — referenced by via `ModifiedById` - [BankAccount](/docs/reference/entities/bank-account/) — referenced by via `OwnerId` - [ItemGroupMember](/docs/reference/entities/item-group-member/) — referenced by via `OwnerId` - [AccountGroupRule](/docs/reference/entities/account-group-rule/) — referenced by via `CreatedById` - [ExpenseAdvanceSettlement](/docs/reference/entities/expense-advance-settlement/) — referenced by via `ModifiedById` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — referenced by via `OwnerId` - [Journal](/docs/reference/entities/journal/) — referenced by via `PostedById` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — referenced by via `OwnerId` - [ExpenseReimbursementBatchLine](/docs/reference/entities/expense-reimbursement-batch-line/) — referenced by via `ModifiedById` - [RevenueRecognitionScheduleLine](/docs/reference/entities/revenue-recognition-schedule-line/) — referenced by via `OwnerId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `CreatedById` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `OwnerId` - [TaxDeclarationLine](/docs/reference/entities/tax-declaration-line/) — referenced by via `ModifiedById` - [BankReconciliationLine](/docs/reference/entities/bank-reconciliation-line/) — referenced by via `ModifiedById` - [BusinessHours](/docs/reference/entities/business-hours/) — referenced by via `ModifiedById` - [TdsReturnChallan](/docs/reference/entities/tds-return-challan/) — referenced by via `ModifiedById` - [Compensation](/docs/reference/entities/compensation/) — referenced by via `CreatedById` - [AccountingBook](/docs/reference/entities/accounting-book/) — referenced by via `CreatedById` - [Individual](/docs/reference/entities/individual/) — referenced by via `ModifiedById` - [BankingTransaction](/docs/reference/entities/banking-transaction/) — referenced by via `ModifiedById` - [CampaignItem](/docs/reference/entities/campaign-item/) — referenced by via `ModifiedById` - [Journal](/docs/reference/entities/journal/) — referenced by via `CreatedById` - [Compensation](/docs/reference/entities/compensation/) — referenced by via `OwnerId` - [ClaimGenerationSetupRule](/docs/reference/entities/claim-generation-setup-rule/) — referenced by via `ModifiedById` - [GSTR3BRule37Tracker](/docs/reference/entities/gstr3-brule37-tracker/) — referenced by via `OwnerId` - [BranchPostalCode](/docs/reference/entities/branch-postal-code/) — referenced by via `ModifiedById` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — referenced by via `ModifiedById` - [IncentiveResource](/docs/reference/entities/incentive-resource/) — referenced by via `CreatedById` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `ModifiedById` - [PayrollRunComponentLine](/docs/reference/entities/payroll-run-component-line/) — referenced by via `ModifiedById` - [GSTRegistration](/docs/reference/entities/gstregistration/) — referenced by via `OwnerId` - [ItemInventoryAttribute](/docs/reference/entities/item-inventory-attribute/) — referenced by via `OwnerId` - [ExpensePolicy](/docs/reference/entities/expense-policy/) — referenced by via `ModifiedById` - [Place](/docs/reference/entities/place/) — referenced by via `CreatedById` - [ChequeTransaction](/docs/reference/entities/cheque-transaction/) — referenced by via `OwnerId` - [ExpenseReimbursementBatchLine](/docs/reference/entities/expense-reimbursement-batch-line/) — referenced by via `OwnerId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `CreatedById` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `ModifiedById` - [ItemLot](/docs/reference/entities/item-lot/) — referenced by via `OwnerId` - [BusinessUnit](/docs/reference/entities/business-unit/) — referenced by via `CreatedById` - [SalaryTaxSlab](/docs/reference/entities/salary-tax-slab/) — referenced by via `CreatedById` - [Case](/docs/reference/entities/case/) — referenced by via `OwnerId` - [PayrollRun](/docs/reference/entities/payroll-run/) — referenced by via `OwnerId` - [ExpenseAdvanceSettlement](/docs/reference/entities/expense-advance-settlement/) — referenced by via `OwnerId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — referenced by via `ModifiedById` - [PurchaseOrderRequisition](/docs/reference/entities/purchase-order-requisition/) — referenced by via `OwnerId` - [ResourceGroup](/docs/reference/entities/resource-group/) — referenced by via `OwnerId` - [TdsReturn](/docs/reference/entities/tds-return/) — referenced by via `ModifiedById` - [ItemComponent](/docs/reference/entities/item-component/) — referenced by via `ModifiedById` - [ChequeTransaction](/docs/reference/entities/cheque-transaction/) — referenced by via `CreatedById` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `OwnerId` - [TdsChallan](/docs/reference/entities/tds-challan/) — referenced by via `OwnerId` - [Item](/docs/reference/entities/item/) — referenced by via `CreatedById` - [GSTR3BItcAvailable](/docs/reference/entities/gstr3-bitc-available/) — referenced by via `ModifiedById` - [ServiceRecommendationRule](/docs/reference/entities/service-recommendation-rule/) — referenced by via `ModifiedById` - [InventoryValuationPolicy](/docs/reference/entities/inventory-valuation-policy/) — referenced by via `ModifiedById` - [Quote](/docs/reference/entities/quote/) — referenced by via `ModifiedById` - [JournalLine](/docs/reference/entities/journal-line/) — referenced by via `CreatedById` - [InventoryNrvAssessment](/docs/reference/entities/inventory-nrv-assessment/) — referenced by via `OwnerId` - [BudgetCommitment](/docs/reference/entities/budget-commitment/) — referenced by via `CreatedById` - [ChecklistTemplateLine](/docs/reference/entities/checklist-template-line/) — referenced by via `CreatedById` - [InventoryValuationPolicy](/docs/reference/entities/inventory-valuation-policy/) — referenced by via `CreatedById` - [PublishedStatement](/docs/reference/entities/published-statement/) — referenced by via `OwnerId` - [ItemMaintenanceSchedule](/docs/reference/entities/item-maintenance-schedule/) — referenced by via `OwnerId` - [CampaignRule](/docs/reference/entities/campaign-rule/) — referenced by via `CreatedById` - [EWayBill](/docs/reference/entities/eway-bill/) — referenced by via `ModifiedById` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — referenced by via `ModifiedById` - [CompanyCard](/docs/reference/entities/company-card/) — referenced by via `OwnerId` - [VisitPlan](/docs/reference/entities/visit-plan/) — referenced by via `ModifiedById` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `OwnerId` - [BookValuationAdjustment](/docs/reference/entities/book-valuation-adjustment/) — referenced by via `CreatedById` - [PartnerResource](/docs/reference/entities/partner-resource/) — referenced by via `OwnerId` - [ExpenseReimbursementBatchLine](/docs/reference/entities/expense-reimbursement-batch-line/) — referenced by via `OwnerId` - [BankReconciliation](/docs/reference/entities/bank-reconciliation/) — referenced by via `ModifiedById` - [InventoryOpeningLotState](/docs/reference/entities/inventory-opening-lot-state/) — referenced by via `CreatedById` - [Form26ASReconciliationEntry](/docs/reference/entities/form26-asreconciliation-entry/) — referenced by via `ModifiedById` - [ResourceLeave](/docs/reference/entities/resource-leave/) — referenced by via `CreatedById` - [VisitRoute](/docs/reference/entities/visit-route/) — referenced by via `CreatedById` - [Payment](/docs/reference/entities/payment/) — referenced by via `OwnerId` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `OwnerId` - [StorageLocation](/docs/reference/entities/storage-location/) — referenced by via `OwnerId` - [ConsolidationGroupMember](/docs/reference/entities/consolidation-group-member/) — referenced by via `ModifiedById` - [CycleCountRule](/docs/reference/entities/cycle-count-rule/) — referenced by via `CreatedById` - AccountGroupCloneTestv5 — referenced by - [Quote](/docs/reference/entities/quote/) — referenced by via `CreatedById` - [GSTRegistration](/docs/reference/entities/gstregistration/) — referenced by via `CreatedById` - [PostingDefinition](/docs/reference/entities/posting-definition/) — referenced by via `ModifiedById` - [TdsReturnDeducteeLine](/docs/reference/entities/tds-return-deductee-line/) — referenced by via `OwnerId` - [Holiday](/docs/reference/entities/holiday/) — referenced by via `CreatedById` - [IncentivePlan](/docs/reference/entities/incentive-plan/) — referenced by via `OwnerId` - [Asset](/docs/reference/entities/asset/) — referenced by via `CreatedById` - [GLAccountPeriodBalance](/docs/reference/entities/glaccount-period-balance/) — referenced by via `ModifiedById` - [ConsolidationGroupMember](/docs/reference/entities/consolidation-group-member/) — referenced by via `OwnerId` - [GSTR3BFilingLog](/docs/reference/entities/gstr3-bfiling-log/) — referenced by via `CreatedById` - [TaxGroup](/docs/reference/entities/tax-group/) — referenced by via `CreatedById` - [FieldSales](/docs/reference/entities/field-sales/) — referenced by via `OwnerId` - [BankReconciliation](/docs/reference/entities/bank-reconciliation/) — referenced by via `OwnerId` - [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) — referenced by via `ModifiedById` - [Account](/docs/reference/entities/account/) — referenced by via `CreatedById` - [TdsReturnDeducteeLine](/docs/reference/entities/tds-return-deductee-line/) — referenced by via `ModifiedById` - [AssetServiceContract](/docs/reference/entities/asset-service-contract/) — referenced by via `CreatedById` - [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) — referenced by via `OwnerId` - [CostCenter](/docs/reference/entities/cost-center/) — referenced by via `ModifiedById` - [GSTR3BSection311](/docs/reference/entities/gstr3-bsection311/) — referenced by via `OwnerId` - [ExpenseReimbursementBatchLine](/docs/reference/entities/expense-reimbursement-batch-line/) — referenced by via `ModifiedById` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `CreatedById` - [FinanceCase](/docs/reference/entities/finance-case/) — referenced by via `OwnerId` - [ExpenseAdvanceSettlement](/docs/reference/entities/expense-advance-settlement/) — referenced by via `CreatedById` - [BranchPostalCode](/docs/reference/entities/branch-postal-code/) — referenced by via `CreatedById` - [BankStatement](/docs/reference/entities/bank-statement/) — referenced by via `CreatedById` - [ExpenseCategory](/docs/reference/entities/expense-category/) — referenced by via `OwnerId` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `CreatedById` - [ItemGroup](/docs/reference/entities/item-group/) — referenced by via `OwnerId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `OwnerId` - [VisitTaskTemplateEntry](/docs/reference/entities/visit-task-template-entry/) — referenced by via `OwnerId` - [StorageLocation](/docs/reference/entities/storage-location/) — referenced by via `ModifiedById` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — referenced by via `CreatedById` - [ExpenseReimbursementBatchLine](/docs/reference/entities/expense-reimbursement-batch-line/) — referenced by via `CreatedById` - [ConsolidationGroup](/docs/reference/entities/consolidation-group/) — referenced by via `OwnerId` - [IncentiveLine](/docs/reference/entities/incentive-line/) — referenced by via `OwnerId` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — referenced by via `CreatedById` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `CreatedById` - [CycleCountLine](/docs/reference/entities/cycle-count-line/) — referenced by via `OwnerId` - [SubscriptionSettings](/docs/reference/entities/subscription-settings/) — referenced by via `CreatedById` - [ItemLot](/docs/reference/entities/item-lot/) — referenced by via `CreatedById` - [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) — referenced by via `OwnerId` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — referenced by via `ModifiedById` - [KPIRules](/docs/reference/entities/kpirules/) — referenced by via `ModifiedById` - [InventoryStock](/docs/reference/entities/inventory-stock/) — referenced by via `ModifiedById` - [RecurringDepreciation](/docs/reference/entities/recurring-depreciation/) — referenced by via `CreatedById` - [Complaint](/docs/reference/entities/complaint/) — referenced by via `ModifiedById` - [PayrollAdjustment](/docs/reference/entities/payroll-adjustment/) — referenced by via `OwnerId` - [Form26ASLine](/docs/reference/entities/form26-asline/) — referenced by via `ModifiedById` - [LandedCostLine](/docs/reference/entities/landed-cost-line/) — referenced by via `OwnerId` - [Holiday](/docs/reference/entities/holiday/) — referenced by via `ModifiedById` - [ServiceRecommendation](/docs/reference/entities/service-recommendation/) — referenced by via `CreatedById` - [GSTR9Return](/docs/reference/entities/gstr9-return/) — referenced by via `ModifiedById` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `OwnerId` - [ItemLot](/docs/reference/entities/item-lot/) — referenced by via `ModifiedById` - [CheckListLine](/docs/reference/entities/check-list-line/) — referenced by via `CreatedById` - [Form26ASReconciliationEntry](/docs/reference/entities/form26-asreconciliation-entry/) — referenced by via `OwnerId` - [AssetMaintenance](/docs/reference/entities/asset-maintenance/) — referenced by via `OwnerId` - [TaxTransaction](/docs/reference/entities/tax-transaction/) — referenced by via `ModifiedById` - [PayrollPaymentBatchLine](/docs/reference/entities/payroll-payment-batch-line/) — referenced by via `ModifiedById` - [LandedCostLine](/docs/reference/entities/landed-cost-line/) — referenced by via `CreatedById` - [ServiceRecommendation](/docs/reference/entities/service-recommendation/) — referenced by via `ModifiedById` - [TdsSection](/docs/reference/entities/tds-section/) — referenced by via `CreatedById` - [Branch](/docs/reference/entities/branch/) — referenced by via `OwnerId` - [QuoteLine](/docs/reference/entities/quote-line/) — referenced by via `OwnerId` - [ItemMaintenanceSchedule](/docs/reference/entities/item-maintenance-schedule/) — referenced by via `CreatedById` - [PayrollRun](/docs/reference/entities/payroll-run/) — referenced by via `ModifiedById` - [VisitTaskTemplateEntry](/docs/reference/entities/visit-task-template-entry/) — referenced by via `CreatedById` - [LoanAdvanceRecovery](/docs/reference/entities/loan-advance-recovery/) — referenced by via `CreatedById` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `ModifiedById` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `OwnerId` - [ServiceRecommendationRule](/docs/reference/entities/service-recommendation-rule/) — referenced by via `OwnerId` - [RecurringJournal](/docs/reference/entities/recurring-journal/) — referenced by via `ModifiedById` - [SchemeLine](/docs/reference/entities/scheme-line/) — referenced by via `ModifiedById` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `ModifiedById` - [GSTR3B](/docs/reference/entities/gstr3-b/) — referenced by via `ModifiedById` - [BusinessUnit](/docs/reference/entities/business-unit/) — referenced by via `ModifiedById` - [LowerDeductionCertificate](/docs/reference/entities/lower-deduction-certificate/) — referenced by via `OwnerId` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — referenced by via `CreatedById` - [AutoPurchaseOrderLineRelation](/docs/reference/entities/auto-purchase-order-line-relation/) — referenced by via `ModifiedById` - [RecurringJournalLine](/docs/reference/entities/recurring-journal-line/) — referenced by via `ModifiedById` - [FinancerScheme](/docs/reference/entities/financer-scheme/) — referenced by via `ModifiedById` - [Subscription](/docs/reference/entities/subscription/) — referenced by via `ModifiedById` - [Contact](/docs/reference/entities/contact/) — referenced by via `CreatedById` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `OwnerId` - [ServiceOrderTimeSheetLine](/docs/reference/entities/service-order-time-sheet-line/) — referenced by via `CreatedById` - [PurchaseReturn](/docs/reference/entities/purchase-return/) — referenced by via `ModifiedById` - [InsuranceScheme](/docs/reference/entities/insurance-scheme/) — referenced by via `CreatedById` - [Journal](/docs/reference/entities/journal/) — referenced by via `OwnerId` - [ItemInventoryAttribute](/docs/reference/entities/item-inventory-attribute/) — referenced by via `CreatedById` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — referenced by via `ModifiedById` - [ItemComponent](/docs/reference/entities/item-component/) — referenced by via `CreatedById` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `CreatedById` - [GSTR3B](/docs/reference/entities/gstr3-b/) — referenced by via `CreatedById` - [ServiceOrderTimeSheet](/docs/reference/entities/service-order-time-sheet/) — referenced by via `CreatedById` - [LowerDeductionCertificate](/docs/reference/entities/lower-deduction-certificate/) — referenced by via `CreatedById` - [DiscountGroupRule](/docs/reference/entities/discount-group-rule/) — referenced by via `CreatedById` - [MonthlyTdsProjection](/docs/reference/entities/monthly-tds-projection/) — referenced by via `ModifiedById` - [Scheme](/docs/reference/entities/scheme/) — referenced by via `ModifiedById` - [GSTR3B](/docs/reference/entities/gstr3-b/) — referenced by via `OwnerId` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `ModifiedById` - [ExpenseAdvance](/docs/reference/entities/expense-advance/) — referenced by via `ModifiedById` - [SettlementAllocation](/docs/reference/entities/settlement-allocation/) — referenced by via `OwnerId` - [Payslip](/docs/reference/entities/payslip/) — referenced by via `CreatedById` - [TaxGroup](/docs/reference/entities/tax-group/) — referenced by via `ModifiedById` - [ExpenseCategory](/docs/reference/entities/expense-category/) — referenced by via `CreatedById` - [Resource](/docs/reference/entities/resource/) — referenced by via `UserId` - [SchemeAccountBudgetUtilization](/docs/reference/entities/scheme-account-budget-utilization/) — referenced by via `CreatedById` - [Employee](/docs/reference/entities/employee/) — referenced by via `CreatedById` - [ItemMaintenanceSchedule](/docs/reference/entities/item-maintenance-schedule/) — referenced by via `ModifiedById` - [ItemAlias](/docs/reference/entities/item-alias/) — referenced by via `OwnerId` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — referenced by via `OwnerId` - [StorageLocation](/docs/reference/entities/storage-location/) — referenced by via `CreatedById` - [LeaveRequest](/docs/reference/entities/leave-request/) — referenced by via `ModifiedById` - [ExpensePolicyViolation](/docs/reference/entities/expense-policy-violation/) — referenced by via `CreatedById` - [Financer](/docs/reference/entities/financer/) — referenced by via `CreatedById` - [PayrollPaymentBatchLine](/docs/reference/entities/payroll-payment-batch-line/) — referenced by via `CreatedById` - [GLAccount](/docs/reference/entities/glaccount/) — referenced by via `OwnerId` - [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) — referenced by via `OwnerId` - [PurchaseOrderRequisition](/docs/reference/entities/purchase-order-requisition/) — referenced by via `ModifiedById` - [ItemGroupMember](/docs/reference/entities/item-group-member/) — referenced by via `ModifiedById` - [AutoOrder](/docs/reference/entities/auto-order/) — referenced by via `OwnerId` - [LandedCost](/docs/reference/entities/landed-cost/) — referenced by via `ModifiedById` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `OwnerId` - [ClaimGenerationSetupRule](/docs/reference/entities/claim-generation-setup-rule/) — referenced by via `CreatedById` - [ItemAlias](/docs/reference/entities/item-alias/) — referenced by via `CreatedById` - [Lead](/docs/reference/entities/lead/) — referenced by via `OwnerId` - [PayrollAdjustment](/docs/reference/entities/payroll-adjustment/) — referenced by via `CreatedById` - [Place](/docs/reference/entities/place/) — referenced by via `ModifiedById` - [PostingErrorLog](/docs/reference/entities/posting-error-log/) — referenced by via `ModifiedById` - [AccountingBook](/docs/reference/entities/accounting-book/) — referenced by via `OwnerId` - [ResourceGroup](/docs/reference/entities/resource-group/) — referenced by via `CreatedById` - [RevenueRecognitionScheduleLine](/docs/reference/entities/revenue-recognition-schedule-line/) — referenced by via `ModifiedById` - [GSTR9Return](/docs/reference/entities/gstr9-return/) — referenced by via `CreatedById` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `ModifiedById` - [ResourceAssignmentRule](/docs/reference/entities/resource-assignment-rule/) — referenced by via `ModifiedById` - [ChequeRegister](/docs/reference/entities/cheque-register/) — referenced by via `ModifiedById` - [FieldSalesInvoice](/docs/reference/entities/field-sales-invoice/) — referenced by via `CreatedById` - [InventoryStock](/docs/reference/entities/inventory-stock/) — referenced by via `OwnerId` - [ItemGroupRule](/docs/reference/entities/item-group-rule/) — referenced by via `OwnerId` - [ProfessionalTaxSlab](/docs/reference/entities/professional-tax-slab/) — referenced by via `OwnerId` - [PayrollRun](/docs/reference/entities/payroll-run/) — referenced by via `CreatedById` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `ModifiedById` - [SubscriptionUsage](/docs/reference/entities/subscription-usage/) — referenced by via `ModifiedById` - [ItemComponent](/docs/reference/entities/item-component/) — referenced by via `OwnerId` - [ItemGroup](/docs/reference/entities/item-group/) — referenced by via `ModifiedById` - [ItemServiceContractLine](/docs/reference/entities/item-service-contract-line/) — referenced by via `OwnerId` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `ModifiedById` - [DebitNote](/docs/reference/entities/debit-note/) — referenced by via `OwnerId` - [ExpenseAdvanceSettlement](/docs/reference/entities/expense-advance-settlement/) — referenced by via `OwnerId` - [LeaveEntitlement](/docs/reference/entities/leave-entitlement/) — referenced by via `CreatedById` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `CreatedById` - [ServiceOrderTimeSheetLine](/docs/reference/entities/service-order-time-sheet-line/) — referenced by via `OwnerId` - [AssetServiceContractLine](/docs/reference/entities/asset-service-contract-line/) — referenced by via `CreatedById` - [BankReconciliationLine](/docs/reference/entities/bank-reconciliation-line/) — referenced by via `CreatedById` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `ModifiedById` - [BankStatementLine](/docs/reference/entities/bank-statement-line/) — referenced by via `ModifiedById` - [Requisition](/docs/reference/entities/requisition/) — referenced by via `CreatedById` - [ITCLedger](/docs/reference/entities/itcledger/) — referenced by via `ModifiedById` - [AccountGroup](/docs/reference/entities/account-group/) — referenced by via `CreatedById` - [RecurringJournalLine](/docs/reference/entities/recurring-journal-line/) — referenced by via `OwnerId` - [ClaimSettlementSetup](/docs/reference/entities/claim-settlement-setup/) — referenced by via `OwnerId` - [Claim](/docs/reference/entities/claim/) — referenced by via `OwnerId` - [InventoryFulfilmentAllocationLine](/docs/reference/entities/inventory-fulfilment-allocation-line/) — referenced by via `ModifiedById` - [CheckInInspectionLine](/docs/reference/entities/check-in-inspection-line/) — referenced by via `ModifiedById` - [GSTR3BItcIneligible](/docs/reference/entities/gstr3-bitc-ineligible/) — referenced by via `CreatedById` - [FinancerScheme](/docs/reference/entities/financer-scheme/) — referenced by via `OwnerId` - [BudgetLine](/docs/reference/entities/budget-line/) — referenced by via `OwnerId` - [Financer](/docs/reference/entities/financer/) — referenced by via `ModifiedById` - [PostingErrorLog](/docs/reference/entities/posting-error-log/) — referenced by via `CreatedById` - [AccountStock](/docs/reference/entities/account-stock/) — referenced by via `OwnerId` - [ResourceGroupMember](/docs/reference/entities/resource-group-member/) — referenced by via `OwnerId` - [ResourceSkill](/docs/reference/entities/resource-skill/) — referenced by via `OwnerId` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — referenced by via `ModifiedById` - [ChequeRegister](/docs/reference/entities/cheque-register/) — referenced by via `CreatedById` - [DocumentName](/docs/reference/entities/document-name/) — referenced by via `ModifiedById` - [Journal](/docs/reference/entities/journal/) — referenced by via `ModifiedById` - [ShipmentAssetLine](/docs/reference/entities/shipment-asset-line/) — referenced by via `OwnerId` - [ServiceBay](/docs/reference/entities/service-bay/) — referenced by via `OwnerId` - [CreditLimit](/docs/reference/entities/credit-limit/) — referenced by via `CreatedById` - [PayrollRunComponentLine](/docs/reference/entities/payroll-run-component-line/) — referenced by via `OwnerId` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `ModifiedById` - [TdsReturnDeducteeLine](/docs/reference/entities/tds-return-deductee-line/) — referenced by via `CreatedById` - [ContactAddress](/docs/reference/entities/contact-address/) — referenced by via `OwnerId` - [JournalLine](/docs/reference/entities/journal-line/) — referenced by via `ModifiedById` - [ServiceType](/docs/reference/entities/service-type/) — referenced by via `CreatedById` - [ResourceAvailabilityData](/docs/reference/entities/resource-availability-data/) — referenced by via `CreatedById` - [BankingTransaction](/docs/reference/entities/banking-transaction/) — referenced by via `CreatedById` - [InterfaceQueue](/docs/reference/entities/interface-queue/) — referenced by via `CreatedById` - [BudgetLine](/docs/reference/entities/budget-line/) — referenced by via `ModifiedById` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `CreatedById` - [GSTR6ISDDistribution](/docs/reference/entities/gstr6-isddistribution/) — referenced by via `CreatedById` - [Currency](/docs/reference/entities/currency/) — referenced by via `OwnerId` - [CreditLimit](/docs/reference/entities/credit-limit/) — referenced by via `OwnerId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — referenced by via `OwnerId` - [Individual](/docs/reference/entities/individual/) — referenced by via `OwnerId` - [VisitTaskTemplateActivity](/docs/reference/entities/visit-task-template-activity/) — referenced by via `ModifiedById` - [SubscriptionUsageSummary](/docs/reference/entities/subscription-usage-summary/) — referenced by via `OwnerId` - [InspectionLine](/docs/reference/entities/inspection-line/) — referenced by via `CreatedById` - [CycleCount](/docs/reference/entities/cycle-count/) — referenced by via `OwnerId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `ModifiedById` - [CheckInTemplate](/docs/reference/entities/check-in-template/) — referenced by via `ModifiedById` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `CreatedById` - [AccountBalance](/docs/reference/entities/account-balance/) — referenced by via `CreatedById` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `OwnerId` - [PriceList](/docs/reference/entities/price-list/) — referenced by via `OwnerId` - [ClaimReconciliationLine](/docs/reference/entities/claim-reconciliation-line/) — referenced by via `ModifiedById` - [LoanAdvanceRecovery](/docs/reference/entities/loan-advance-recovery/) — referenced by via `ModifiedById` - [ResourceAvailability](/docs/reference/entities/resource-availability/) — referenced by via `OwnerId` - [Budget](/docs/reference/entities/budget/) — referenced by via `CreatedById` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `CreatedById` - [DeliveryOrderLine](/docs/reference/entities/delivery-order-line/) — referenced by via `CreatedById` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `CreatedById` - [AssetBlock](/docs/reference/entities/asset-block/) — referenced by via `CreatedById` - [Resource](/docs/reference/entities/resource/) — referenced by via `ModifiedById` - [SchemeConsumption](/docs/reference/entities/scheme-consumption/) — referenced by via `OwnerId` - [Campaign](/docs/reference/entities/campaign/) — referenced by via `CreatedById` - [ResourceAvailabilityData](/docs/reference/entities/resource-availability-data/) — referenced by via `OwnerId` - [GSTR6ISDRecipientTurnover](/docs/reference/entities/gstr6-isdrecipient-turnover/) — referenced by via `ModifiedById` - [SchemeConsumption](/docs/reference/entities/scheme-consumption/) — referenced by via `CreatedById` - [ExpensePolicyViolation](/docs/reference/entities/expense-policy-violation/) — referenced by via `ModifiedById` - [ItemInventoryAttribute](/docs/reference/entities/item-inventory-attribute/) — referenced by via `ModifiedById` - [ExpenseReimbursementBatch](/docs/reference/entities/expense-reimbursement-batch/) — referenced by via `OwnerId` - [PurchaseReturnLine](/docs/reference/entities/purchase-return-line/) — referenced by via `ModifiedById` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `ModifiedById` - [GSTR6ISDRecipientAllocation](/docs/reference/entities/gstr6-isdrecipient-allocation/) — referenced by via `ModifiedById` - [PartyPeriodBalance](/docs/reference/entities/party-period-balance/) — referenced by via `CreatedById` - [ServiceOrder](/docs/reference/entities/service-order/) — referenced by via `ModifiedById` - [SKU](/docs/reference/entities/sku/) — referenced by via `CreatedById` - [GSTR6ISDSourceDocument](/docs/reference/entities/gstr6-isdsource-document/) — referenced by via `OwnerId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `ModifiedById` - [InventoryCostConsumption](/docs/reference/entities/inventory-cost-consumption/) — referenced by via `OwnerId` - [GSTR6ISDRecipientAllocation](/docs/reference/entities/gstr6-isdrecipient-allocation/) — referenced by via `OwnerId` - [DocumentNameSetting](/docs/reference/entities/document-name-setting/) — referenced by via `ModifiedById` - [Project](/docs/reference/entities/project/) — referenced by via `OwnerId` - [Order](/docs/reference/entities/order/) — referenced by via `ModifiedById` - [ExchangeRate](/docs/reference/entities/exchange-rate/) — referenced by via `CreatedById` - [SchemeAccountBudget](/docs/reference/entities/scheme-account-budget/) — referenced by via `ModifiedById` - [InventoryNrvAssessment](/docs/reference/entities/inventory-nrv-assessment/) — referenced by via `CreatedById` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — referenced by via `CreatedById` - [PeriodClose](/docs/reference/entities/period-close/) — referenced by via `ModifiedById` - [PeriodCloseCheck](/docs/reference/entities/period-close-check/) — referenced by via `ModifiedById` - [Individual](/docs/reference/entities/individual/) — referenced by via `CreatedById` - [TdsCertificate](/docs/reference/entities/tds-certificate/) — referenced by via `OwnerId` - [GSTR3BItcReversed](/docs/reference/entities/gstr3-bitc-reversed/) — referenced by via `ModifiedById` - [PriceListRule](/docs/reference/entities/price-list-rule/) — referenced by via `CreatedById` - [Contact](/docs/reference/entities/contact/) — referenced by via `OwnerId` - [AccountingBook](/docs/reference/entities/accounting-book/) — referenced by via `ModifiedById` - [GSTR6](/docs/reference/entities/gstr6/) — referenced by via `CreatedById` - [TdsTransaction](/docs/reference/entities/tds-transaction/) — referenced by via `OwnerId` - [Payslip](/docs/reference/entities/payslip/) — referenced by via `ModifiedById` - [GSTR6ISDRecipientTurnover](/docs/reference/entities/gstr6-isdrecipient-turnover/) — referenced by via `CreatedById` - [PayrollAdjustment](/docs/reference/entities/payroll-adjustment/) — referenced by via `ModifiedById` - [PaymentAdjustment](/docs/reference/entities/payment-adjustment/) — referenced by via `OwnerId` - [Budget](/docs/reference/entities/budget/) — referenced by via `ModifiedById` - [ItemServiceContract](/docs/reference/entities/item-service-contract/) — referenced by via `ModifiedById` - [FullAndFinalSettlementLine](/docs/reference/entities/full-and-final-settlement-line/) — referenced by via `CreatedById` - [TdsChallan](/docs/reference/entities/tds-challan/) — referenced by via `ModifiedById` - [CompanyCard](/docs/reference/entities/company-card/) — referenced by via `CreatedById` - [CurrencyRevaluationLine](/docs/reference/entities/currency-revaluation-line/) — referenced by via `OwnerId` - [Compensation](/docs/reference/entities/compensation/) — referenced by via `ModifiedById` - [ItemFeature](/docs/reference/entities/item-feature/) — referenced by via `CreatedById` - [SubscriptionUsageSummary](/docs/reference/entities/subscription-usage-summary/) — referenced by via `CreatedById` - [SubscriptionSettings](/docs/reference/entities/subscription-settings/) — referenced by via `ModifiedById` - [ClaimReconciliationLine](/docs/reference/entities/claim-reconciliation-line/) — referenced by via `CreatedById` - [KPIRules](/docs/reference/entities/kpirules/) — referenced by via `OwnerId` - [ITCLedger](/docs/reference/entities/itcledger/) — referenced by via `OwnerId` - [RecurringDepreciation](/docs/reference/entities/recurring-depreciation/) — referenced by via `ModifiedById` - [ItemUnitOfMeasure](/docs/reference/entities/item-unit-of-measure/) — referenced by via `ModifiedById` - [GSTR6](/docs/reference/entities/gstr6/) — referenced by via `ModifiedById` - [PaymentBatch](/docs/reference/entities/payment-batch/) — referenced by via `ModifiedById` - [FullAndFinalSettlementLine](/docs/reference/entities/full-and-final-settlement-line/) — referenced by via `CreatedById` - [InventoryValuationPolicy](/docs/reference/entities/inventory-valuation-policy/) — referenced by via `OwnerId` - [DocumentServiceContractLine](/docs/reference/entities/document-service-contract-line/) — referenced by via `CreatedById` - [PayrollRunComponentLine](/docs/reference/entities/payroll-run-component-line/) — referenced by via `CreatedById` - [InsuranceScheme](/docs/reference/entities/insurance-scheme/) — referenced by via `ModifiedById` - [InterfaceQueue](/docs/reference/entities/interface-queue/) — referenced by via `ModifiedById` - [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) — referenced by via `CreatedById` - [PriceListRule](/docs/reference/entities/price-list-rule/) — referenced by via `OwnerId` - [ComplaintFault](/docs/reference/entities/complaint-fault/) — referenced by via `OwnerId` - [LeaveType](/docs/reference/entities/leave-type/) — referenced by via `CreatedById` - [ResourceGroupMember](/docs/reference/entities/resource-group-member/) — referenced by via `ModifiedById` - [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) — referenced by via `ModifiedById` - [TdsChallanAllocation](/docs/reference/entities/tds-challan-allocation/) — referenced by via `OwnerId` - [TdsReturn](/docs/reference/entities/tds-return/) — referenced by via `OwnerId` - [CycleCountRule](/docs/reference/entities/cycle-count-rule/) — referenced by via `OwnerId` - [VisitRoute](/docs/reference/entities/visit-route/) — referenced by via `OwnerId` - [GSTR6](/docs/reference/entities/gstr6/) — referenced by via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — referenced by via `CreatedById` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `OwnerId` - [MonthlyTdsProjection](/docs/reference/entities/monthly-tds-projection/) — referenced by via `CreatedById` - [SalaryTaxSlab](/docs/reference/entities/salary-tax-slab/) — referenced by via `OwnerId` - [KPIDataDetail](/docs/reference/entities/kpidata-detail/) — referenced by via `ModifiedById` - [TransferLine](/docs/reference/entities/transfer-line/) — referenced by via `OwnerId` - [Payment](/docs/reference/entities/payment/) — referenced by via `ModifiedById` - [Claim](/docs/reference/entities/claim/) — referenced by via `ModifiedById` - [SKU](/docs/reference/entities/sku/) — referenced by via `OwnerId` - [SchemeAccountBudget](/docs/reference/entities/scheme-account-budget/) — referenced by via `CreatedById` - [ItemGroup](/docs/reference/entities/item-group/) — referenced by via `CreatedById` - [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) — referenced by via `ModifiedById` - [ResourceAvailability](/docs/reference/entities/resource-availability/) — referenced by via `ModifiedById` - [TdsReturnChallan](/docs/reference/entities/tds-return-challan/) — referenced by via `CreatedById` - [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) — referenced by via `OwnerId` - [Lead](/docs/reference/entities/lead/) — referenced by via `ModifiedById` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `OwnerId` - [TaxTransaction](/docs/reference/entities/tax-transaction/) — referenced by via `OwnerId` - [GSTR6ISDDocumentSeries](/docs/reference/entities/gstr6-isddocument-series/) — referenced by via `ModifiedById` - [DocumentNameSetting](/docs/reference/entities/document-name-setting/) — referenced by via `OwnerId` - [ESIRule](/docs/reference/entities/esirule/) — referenced by via `CreatedById` - [ServiceType](/docs/reference/entities/service-type/) — referenced by via `OwnerId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `OwnerId` - [DiscountGroup](/docs/reference/entities/discount-group/) — referenced by via `CreatedById` - [ClaimBatch](/docs/reference/entities/claim-batch/) — referenced by via `ModifiedById` - [GSTR9Return](/docs/reference/entities/gstr9-return/) — referenced by via `OwnerId` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `ModifiedById` - [LoanAdvanceRecovery](/docs/reference/entities/loan-advance-recovery/) — referenced by via `OwnerId` - [ExpensePolicyViolation](/docs/reference/entities/expense-policy-violation/) — referenced by via `ModifiedById` - [SchemeCondition](/docs/reference/entities/scheme-condition/) — referenced by via `OwnerId` - [CampaignItem](/docs/reference/entities/campaign-item/) — referenced by via `CreatedById` - [BranchTimeSlotBooking](/docs/reference/entities/branch-time-slot-booking/) — referenced by via `OwnerId` - [CostCenter](/docs/reference/entities/cost-center/) — referenced by via `OwnerId` - [GSTR3BSection311](/docs/reference/entities/gstr3-bsection311/) — referenced by via `CreatedById` - [BankStatementLine](/docs/reference/entities/bank-statement-line/) — referenced by via `OwnerId` - [GSTR9HsnSummary](/docs/reference/entities/gstr9-hsn-summary/) — referenced by via `OwnerId` - [Visit](/docs/reference/entities/visit/) — referenced by via `OwnerId` - [ESIRule](/docs/reference/entities/esirule/) — referenced by via `ModifiedById` - [CampaignMember](/docs/reference/entities/campaign-member/) — referenced by via `CreatedById` - [PurchaseReturn](/docs/reference/entities/purchase-return/) — referenced by via `OwnerId` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — referenced by via `CreatedById` - [FieldSalesInvoice](/docs/reference/entities/field-sales-invoice/) — referenced by via `ModifiedById` - [PartyPeriodBalance](/docs/reference/entities/party-period-balance/) — referenced by via `OwnerId` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — referenced by via `OwnerId` - [Holiday](/docs/reference/entities/holiday/) — referenced by via `OwnerId` - [ComplaintFault](/docs/reference/entities/complaint-fault/) — referenced by via `CreatedById` - [PurchaseOrder](/docs/reference/entities/purchase-order/) — referenced by via `CreatedById` - [IncentiveResourceTarget](/docs/reference/entities/incentive-resource-target/) — referenced by via `OwnerId` - [Budget](/docs/reference/entities/budget/) — referenced by via `OwnerId` - [ExpensePolicyViolation](/docs/reference/entities/expense-policy-violation/) — referenced by via `CreatedById` - [Form26ASStatement](/docs/reference/entities/form26-asstatement/) — referenced by via `ModifiedById` - [AccountGroupMember](/docs/reference/entities/account-group-member/) — referenced by via `CreatedById` - [KPIData](/docs/reference/entities/kpidata/) — referenced by via `ModifiedById` - [Grade](/docs/reference/entities/grade/) — referenced by via `CreatedById` - [Transfer](/docs/reference/entities/transfer/) — referenced by via `OwnerId` - [ItemLotType](/docs/reference/entities/item-lot-type/) — referenced by via `ModifiedById` - [Shipment](/docs/reference/entities/shipment/) — referenced by via `OwnerId` - [RevenueRecognitionSchedule](/docs/reference/entities/revenue-recognition-schedule/) — referenced by via `CreatedById` - [PurchaseReturnLine](/docs/reference/entities/purchase-return-line/) — referenced by via `OwnerId` - [CheckInInspection](/docs/reference/entities/check-in-inspection/) — referenced by via `CreatedById` - [PaymentAdjustment](/docs/reference/entities/payment-adjustment/) — referenced by via `ModifiedById` - [AccountLocation](/docs/reference/entities/account-location/) — referenced by via `OwnerId` - [KYCDocument](/docs/reference/entities/kycdocument/) — referenced by via `ModifiedById` - [VisitRoute](/docs/reference/entities/visit-route/) — referenced by via `ModifiedById` - [PeriodClose](/docs/reference/entities/period-close/) — referenced by via `CreatedById` - [VisitRouteGroup](/docs/reference/entities/visit-route-group/) — referenced by via `CreatedById` - [FieldSales](/docs/reference/entities/field-sales/) — referenced by via `CreatedById` - [PublishedStatement](/docs/reference/entities/published-statement/) — referenced by via `ModifiedById` - [EInvoice](/docs/reference/entities/einvoice/) — referenced by via `CreatedById` - [PartnerResource](/docs/reference/entities/partner-resource/) — referenced by via `CreatedById` - [Asset](/docs/reference/entities/asset/) — referenced by via `OwnerId` - [ClaimReconciliation](/docs/reference/entities/claim-reconciliation/) — referenced by via `CreatedById` - [AccountGroupRule](/docs/reference/entities/account-group-rule/) — referenced by via `ModifiedById` - [ClaimBatchLine](/docs/reference/entities/claim-batch-line/) — referenced by via `ModifiedById` - [VisitTaskTemplateEntry](/docs/reference/entities/visit-task-template-entry/) — referenced by via `ModifiedById` - [CampaignItem](/docs/reference/entities/campaign-item/) — referenced by via `OwnerId` - [CurrencyRevaluationLine](/docs/reference/entities/currency-revaluation-line/) — referenced by via `ModifiedById` - [PurchaseReturn](/docs/reference/entities/purchase-return/) — referenced by via `CreatedById` - [CheckInInspectionLine](/docs/reference/entities/check-in-inspection-line/) — referenced by via `OwnerId` - [ExpensePolicy](/docs/reference/entities/expense-policy/) — referenced by via `OwnerId` - [GSTR3BFilingLog](/docs/reference/entities/gstr3-bfiling-log/) — referenced by via `OwnerId` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `ModifiedById` - [Project](/docs/reference/entities/project/) — referenced by via `CreatedById` - [ClaimLine](/docs/reference/entities/claim-line/) — referenced by via `CreatedById` - [InventoryCostConsumption](/docs/reference/entities/inventory-cost-consumption/) — referenced by via `ModifiedById` - [PostalCode](/docs/reference/entities/postal-code/) — referenced by via `CreatedById` - [Visit](/docs/reference/entities/visit/) — referenced by via `CreatedById` - [FullAndFinalSettlementLine](/docs/reference/entities/full-and-final-settlement-line/) — referenced by via `ModifiedById` - [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) — referenced by via `CreatedById` - [ConsolidationGroupMember](/docs/reference/entities/consolidation-group-member/) — referenced by via `CreatedById` - [CycleCount](/docs/reference/entities/cycle-count/) — referenced by via `ModifiedById` - [ResourceAvailabilityCheckIn](/docs/reference/entities/resource-availability-check-in/) — referenced by via `CreatedById` - [ClaimSettlementSetup](/docs/reference/entities/claim-settlement-setup/) — referenced by via `ModifiedById` - [Employee](/docs/reference/entities/employee/) — referenced by via `ModifiedById` - [Claim](/docs/reference/entities/claim/) — referenced by via `CreatedById` - [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) — referenced by via `CreatedById` - [GLAccountPeriodBalance](/docs/reference/entities/glaccount-period-balance/) — referenced by via `OwnerId` - [CheckInInspection](/docs/reference/entities/check-in-inspection/) — referenced by via `ModifiedById` - [BankingTransaction](/docs/reference/entities/banking-transaction/) — referenced by via `OwnerId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `OwnerId` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `OwnerId` - [OpportunityLine](/docs/reference/entities/opportunity-line/) — referenced by via `CreatedById` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `UserId` - [SchemeLine](/docs/reference/entities/scheme-line/) — referenced by via `OwnerId` - [GSTR3BSection311](/docs/reference/entities/gstr3-bsection311/) — referenced by via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — referenced by via `OwnerId` - [RecurringJournalLine](/docs/reference/entities/recurring-journal-line/) — referenced by via `CreatedById` - [IncentiveResource](/docs/reference/entities/incentive-resource/) — referenced by via `OwnerId` - [InsuranceScheme](/docs/reference/entities/insurance-scheme/) — referenced by via `OwnerId` - [TdsReturnChallan](/docs/reference/entities/tds-return-challan/) — referenced by via `OwnerId` - [CurrencyRevaluation](/docs/reference/entities/currency-revaluation/) — referenced by via `OwnerId` - [GoodsReceipt](/docs/reference/entities/goods-receipt/) — referenced by via `OwnerId` - [ResourceBusinessHours](/docs/reference/entities/resource-business-hours/) — referenced by via `OwnerId` - [CompensationLine](/docs/reference/entities/compensation-line/) — referenced by via `ModifiedById` - [Bill](/docs/reference/entities/bill/) — referenced by via `CreatedById` - [ResourceGroupMember](/docs/reference/entities/resource-group-member/) — referenced by via `CreatedById` - [GSTR3B](/docs/reference/entities/gstr3-b/) — referenced by via `OwnerId` - [FullAndFinalSettlementLine](/docs/reference/entities/full-and-final-settlement-line/) — referenced by via `OwnerId` - [ExpenseClaimLine](/docs/reference/entities/expense-claim-line/) — referenced by via `ModifiedById` - [JournalLine](/docs/reference/entities/journal-line/) — referenced by via `OwnerId` - [Payment](/docs/reference/entities/payment/) — referenced by via `CreatedById` - [Form26ASLine](/docs/reference/entities/form26-asline/) — referenced by via `OwnerId` - [Campaign](/docs/reference/entities/campaign/) — referenced by via `OwnerId` - [AutoPurchaseOrderLine](/docs/reference/entities/auto-purchase-order-line/) — referenced by via `ModifiedById` - [ProductDemo](/docs/reference/entities/product-demo/) — referenced by via `OwnerId` - [PostingDefinition](/docs/reference/entities/posting-definition/) — referenced by via `OwnerId` - [CheckListLine](/docs/reference/entities/check-list-line/) — referenced by via `ModifiedById` - [RecurringDepreciation](/docs/reference/entities/recurring-depreciation/) — referenced by via `OwnerId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — referenced by via `OwnerId` - [GSTR3BItcIneligible](/docs/reference/entities/gstr3-bitc-ineligible/) — referenced by via `ModifiedById` - [TransferLine](/docs/reference/entities/transfer-line/) — referenced by via `ModifiedById` - [SubscriptionSettings](/docs/reference/entities/subscription-settings/) — referenced by via `OwnerId` - [PostalCode](/docs/reference/entities/postal-code/) — referenced by via `ModifiedById` - [GSTR3B](/docs/reference/entities/gstr3-b/) — referenced by via `ModifiedById` - [AccountGroupMember](/docs/reference/entities/account-group-member/) — referenced by via `ModifiedById` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `ModifiedById` - [AccountGroupMember](/docs/reference/entities/account-group-member/) — referenced by via `OwnerId` - [TdsReturn](/docs/reference/entities/tds-return/) — referenced by via `CreatedById` - [VisitTask](/docs/reference/entities/visit-task/) — referenced by via `ModifiedById` - [PayrollPeriod](/docs/reference/entities/payroll-period/) — referenced by via `ModifiedById` - [GSTR3BPayment](/docs/reference/entities/gstr3-bpayment/) — referenced by via `ModifiedById` - [Order](/docs/reference/entities/order/) — referenced by via `OwnerId` - [GSTR3BItcReversed](/docs/reference/entities/gstr3-bitc-reversed/) — referenced by via `CreatedById` - [CycleCountLine](/docs/reference/entities/cycle-count-line/) — referenced by via `ModifiedById` - [RecurringJournal](/docs/reference/entities/recurring-journal/) — referenced by via `OwnerId` - [ItemServiceContractLine](/docs/reference/entities/item-service-contract-line/) — referenced by via `ModifiedById` - [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) — referenced by via `CreatedById` - [ProfessionalTaxSlab](/docs/reference/entities/professional-tax-slab/) — referenced by via `CreatedById` - [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) — referenced by via `CreatedById` - [ClaimGenerationSetup](/docs/reference/entities/claim-generation-setup/) — referenced by via `OwnerId` - [ItemGroupMember](/docs/reference/entities/item-group-member/) — referenced by via `CreatedById` - [Bill](/docs/reference/entities/bill/) — referenced by via `ModifiedById` - [CompanyCardReconciliation](/docs/reference/entities/company-card-reconciliation/) — referenced by via `ModifiedById` - [BranchPostalCode](/docs/reference/entities/branch-postal-code/) — referenced by via `OwnerId` - [LeaveType](/docs/reference/entities/leave-type/) — referenced by via `ModifiedById` - [FieldSalesInvoice](/docs/reference/entities/field-sales-invoice/) — referenced by via `OwnerId` - [FullAndFinalSettlement](/docs/reference/entities/full-and-final-settlement/) — referenced by via `CreatedById` - [GLAccount](/docs/reference/entities/glaccount/) — referenced by via `ModifiedById` - [Employee](/docs/reference/entities/employee/) — referenced by via `OwnerId` - [FiscalYear](/docs/reference/entities/fiscal-year/) — referenced by via `CreatedById` - [ServiceType](/docs/reference/entities/service-type/) — referenced by via `ModifiedById` - [ServiceOrderTimeSheet](/docs/reference/entities/service-order-time-sheet/) — referenced by via `ModifiedById` - [RequisitionLine](/docs/reference/entities/requisition-line/) — referenced by via `ModifiedById` - [Resource](/docs/reference/entities/resource/) — referenced by via `OwnerId` - [TaxDeclaration](/docs/reference/entities/tax-declaration/) — referenced by via `ModifiedById` - [SchemePeriod](/docs/reference/entities/scheme-period/) — referenced by via `ModifiedById` - [PayrollPeriod](/docs/reference/entities/payroll-period/) — referenced by via `CreatedById` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `OwnerId` - [KPIRules](/docs/reference/entities/kpirules/) — referenced by via `CreatedById` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `ModifiedById` - [InventoryFulfilment](/docs/reference/entities/inventory-fulfilment/) — referenced by via `ModifiedById` - [CompanyCardReconciliation](/docs/reference/entities/company-card-reconciliation/) — referenced by via `OwnerId` - [RevenueRecognitionSchedule](/docs/reference/entities/revenue-recognition-schedule/) — referenced by via `OwnerId` - [DebitNote](/docs/reference/entities/debit-note/) — referenced by via `ModifiedById` - [GSTR3BItcIneligible](/docs/reference/entities/gstr3-bitc-ineligible/) — referenced by via `OwnerId` - [ClaimBatch](/docs/reference/entities/claim-batch/) — referenced by via `OwnerId` - [ExpenseReceipt](/docs/reference/entities/expense-receipt/) — referenced by via `CreatedById` - [PFRule](/docs/reference/entities/pfrule/) — referenced by via `OwnerId` - [CampaignRule](/docs/reference/entities/campaign-rule/) — referenced by via `OwnerId` - [TransferOutwardLine](/docs/reference/entities/transfer-outward-line/) — referenced by via `CreatedById` - [Requisition](/docs/reference/entities/requisition/) — referenced by via `ModifiedById` - [DebitNoteLine](/docs/reference/entities/debit-note-line/) — referenced by via `OwnerId` - [AccountGroupRule](/docs/reference/entities/account-group-rule/) — referenced by via `OwnerId` - [VisitTask](/docs/reference/entities/visit-task/) — referenced by via `OwnerId` - [AccountBalance](/docs/reference/entities/account-balance/) — referenced by via `OwnerId` - [GSTR3BSection31](/docs/reference/entities/gstr3-bsection31/) — referenced by via `OwnerId` - [ClaimBatchLine](/docs/reference/entities/claim-batch-line/) — referenced by via `CreatedById` - [KPIConfiguration](/docs/reference/entities/kpiconfiguration/) — referenced by via `ModifiedById` - [ServiceBay](/docs/reference/entities/service-bay/) — referenced by via `ModifiedById` - [ExpensePolicyViolation](/docs/reference/entities/expense-policy-violation/) — referenced by via `OwnerId` - [GSTR3BFilingLog](/docs/reference/entities/gstr3-bfiling-log/) — referenced by via `ModifiedById` - [Adjustment](/docs/reference/entities/adjustment/) — referenced by via `ModifiedById` - [ServiceRecommendationRule](/docs/reference/entities/service-recommendation-rule/) — referenced by via `CreatedById` - [InventoryNrvAssessment](/docs/reference/entities/inventory-nrv-assessment/) — referenced by via `ModifiedById` - [TaxGroup](/docs/reference/entities/tax-group/) — referenced by via `OwnerId` - [Complaint](/docs/reference/entities/complaint/) — referenced by via `CreatedById` - [PeriodCloseCheck](/docs/reference/entities/period-close-check/) — referenced by via `CreatedById` - [GSTR3BItcAvailable](/docs/reference/entities/gstr3-bitc-available/) — referenced by via `CreatedById` - [Asset](/docs/reference/entities/asset/) — referenced by via `ModifiedById` - [InterfaceQueue](/docs/reference/entities/interface-queue/) — referenced by via `OwnerId` - [PayrollPaymentBatch](/docs/reference/entities/payroll-payment-batch/) — referenced by via `ModifiedById` - [ItemLotType](/docs/reference/entities/item-lot-type/) — referenced by via `OwnerId` - [PayrollStatutoryChallan](/docs/reference/entities/payroll-statutory-challan/) — referenced by via `ModifiedById` - [TaxDeclarationLine](/docs/reference/entities/tax-declaration-line/) — referenced by via `CreatedById` - [VisitRouteStop](/docs/reference/entities/visit-route-stop/) — referenced by via `CreatedById` - [Place](/docs/reference/entities/place/) — referenced by via `OwnerId` - [ItemUnitOfMeasure](/docs/reference/entities/item-unit-of-measure/) — referenced by via `CreatedById` - [PerformanceKPI](/docs/reference/entities/performance-kpi/) — referenced by via `OwnerId` - [GoodsReceiptLine](/docs/reference/entities/goods-receipt-line/) — referenced by via `OwnerId` - [LeaveEntitlement](/docs/reference/entities/leave-entitlement/) — referenced by via `OwnerId` - [PFRule](/docs/reference/entities/pfrule/) — referenced by via `CreatedById` - [CampaignRule](/docs/reference/entities/campaign-rule/) — referenced by via `ModifiedById` - [KYCDocument](/docs/reference/entities/kycdocument/) — referenced by via `OwnerId` - [VisitPlan](/docs/reference/entities/visit-plan/) — referenced by via `OwnerId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `OwnerId` - [ItemAlternate](/docs/reference/entities/item-alternate/) — referenced by via `CreatedById` - [ItemUnitOfMeasure](/docs/reference/entities/item-unit-of-measure/) — referenced by via `OwnerId` - [Account](/docs/reference/entities/account/) — referenced by via `OwnerId` - [AvailabilityRequest](/docs/reference/entities/availability-request/) — referenced by via `ModifiedById` - [RecurringJournal](/docs/reference/entities/recurring-journal/) — referenced by via `CreatedById` - [InventoryLedgerSetting](/docs/reference/entities/inventory-ledger-setting/) — referenced by via `ModifiedById` - [DiscountGroup](/docs/reference/entities/discount-group/) — referenced by via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — referenced by via `ModifiedById` - [Opportunity](/docs/reference/entities/opportunity/) — referenced by via `ModifiedById` - [ChecklistTemplateLine](/docs/reference/entities/checklist-template-line/) — referenced by via `OwnerId` - [AccountBalance](/docs/reference/entities/account-balance/) — referenced by via `ModifiedById` - [InventoryCostConsumption](/docs/reference/entities/inventory-cost-consumption/) — referenced by via `CreatedById` - [DebitNoteLine](/docs/reference/entities/debit-note-line/) — referenced by via `CreatedById` - [GSTR6ISDDocumentSeries](/docs/reference/entities/gstr6-isddocument-series/) — referenced by via `CreatedById` - [PayrollComponent](/docs/reference/entities/payroll-component/) — referenced by via `OwnerId` - [CycleCountRule](/docs/reference/entities/cycle-count-rule/) — referenced by via `ModifiedById` - [CreditNote](/docs/reference/entities/credit-note/) — referenced by via `ModifiedById` - [DocumentName](/docs/reference/entities/document-name/) — referenced by via `OwnerId` - [ResourceSkill](/docs/reference/entities/resource-skill/) — referenced by via `ModifiedById` - [CheckInTemplate](/docs/reference/entities/check-in-template/) — referenced by via `OwnerId` - [ConsolidationGroup](/docs/reference/entities/consolidation-group/) — referenced by via `ModifiedById` - [LoanAdvance](/docs/reference/entities/loan-advance/) — referenced by via `ModifiedById` - [DocumentName](/docs/reference/entities/document-name/) — referenced by via `CreatedById` - [Grade](/docs/reference/entities/grade/) — referenced by via `ModifiedById` - [BillLine](/docs/reference/entities/bill-line/) — referenced by via `OwnerId` - [ExpenseReceipt](/docs/reference/entities/expense-receipt/) — referenced by via `ModifiedById` - [PayrollPaymentBatchLine](/docs/reference/entities/payroll-payment-batch-line/) — referenced by via `ModifiedById` - [ExpensePolicy](/docs/reference/entities/expense-policy/) — referenced by via `CreatedById` - [GSTR3B](/docs/reference/entities/gstr3-b/) — referenced by via `CreatedById` - [ExchangeRate](/docs/reference/entities/exchange-rate/) — referenced by via `OwnerId` - [ResourceAvailabilityCheckIn](/docs/reference/entities/resource-availability-check-in/) — referenced by via `ModifiedById` - [LeaveEntitlement](/docs/reference/entities/leave-entitlement/) — referenced by via `ModifiedById` - [TdsCertificate](/docs/reference/entities/tds-certificate/) — referenced by via `CreatedById` - [FiscalYear](/docs/reference/entities/fiscal-year/) — referenced by via `OwnerId` - [CompanyCardReconciliation](/docs/reference/entities/company-card-reconciliation/) — referenced by via `CreatedById` - [CheckInInspectionLine](/docs/reference/entities/check-in-inspection-line/) — referenced by via `CreatedById` - [ClaimGenerationSetup](/docs/reference/entities/claim-generation-setup/) — referenced by via `Modified By` - [ResourceAvailability](/docs/reference/entities/resource-availability/) — referenced by via `CreatedById` - [CompanyCardTransaction](/docs/reference/entities/company-card-transaction/) — referenced by via `OwnerId` - [VisitPlan](/docs/reference/entities/visit-plan/) — referenced by via `CreatedById` - [ServiceOrderLine](/docs/reference/entities/service-order-line/) — referenced by via `CreatedById` - [InventoryOpeningLotState](/docs/reference/entities/inventory-opening-lot-state/) — referenced by via `OwnerId` - [FieldSales](/docs/reference/entities/field-sales/) — referenced by via `ModifiedById` - [Contact](/docs/reference/entities/contact/) — referenced by via `ModifiedById` - [PFRule](/docs/reference/entities/pfrule/) — referenced by via `ModifiedById` - [KPIData](/docs/reference/entities/kpidata/) — referenced by via `CreatedById` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `ModifiedById` - [CreditLimit](/docs/reference/entities/credit-limit/) — referenced by via `ModifiedById` - [Form26ASStatement](/docs/reference/entities/form26-asstatement/) — referenced by via `OwnerId` - [Project](/docs/reference/entities/project/) — referenced by via `ModifiedById` - [BusinessHours](/docs/reference/entities/business-hours/) — referenced by via `CreatedById` - [SchemeConsumption](/docs/reference/entities/scheme-consumption/) — referenced by via `ModifiedById` - [BankReconciliationLine](/docs/reference/entities/bank-reconciliation-line/) — referenced by via `OwnerId` - [Requisition](/docs/reference/entities/requisition/) — referenced by via `OwnerId` - [ShipmentAssetLine](/docs/reference/entities/shipment-asset-line/) — referenced by via `ModifiedById` - [BankReconciliation](/docs/reference/entities/bank-reconciliation/) — referenced by via `CreatedById` - [ItemAlternate](/docs/reference/entities/item-alternate/) — referenced by via `ModifiedById` - [KPIData](/docs/reference/entities/kpidata/) — referenced by via `OwnerId` - [PayrollComponent](/docs/reference/entities/payroll-component/) — referenced by via `ModifiedById` - [CheckInTemplateLine](/docs/reference/entities/check-in-template-line/) — referenced by via `OwnerId` - [SchemeLedger](/docs/reference/entities/scheme-ledger/) — referenced by via `CreatedById` - [VisitTaskTemplateActivity](/docs/reference/entities/visit-task-template-activity/) — referenced by via `OwnerId` - [OrderLine](/docs/reference/entities/order-line/) — referenced by via `ModifiedById` - [ESIRule](/docs/reference/entities/esirule/) — referenced by via `OwnerId` - [PurchaseReturnLine](/docs/reference/entities/purchase-return-line/) — referenced by via `CreatedById` - [GSTR3BItcReversed](/docs/reference/entities/gstr3-bitc-reversed/) — referenced by via `OwnerId` - [GSTR6ISDDistribution](/docs/reference/entities/gstr6-isddistribution/) — referenced by via `OwnerId` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — referenced by via `ModifiedById` - [ShipmentAssetLine](/docs/reference/entities/shipment-asset-line/) — referenced by via `CreatedById` - [Form26ASStatement](/docs/reference/entities/form26-asstatement/) — referenced by via `CreatedById` - [AutoOrder](/docs/reference/entities/auto-order/) — referenced by via `ModifiedById` - [FinanceCase](/docs/reference/entities/finance-case/) — referenced by via `CreatedById` - [GSTR3BRule37Tracker](/docs/reference/entities/gstr3-brule37-tracker/) — referenced by via `CreatedById` - [ItemAlternate](/docs/reference/entities/item-alternate/) — referenced by via `OwnerId` - [InventoryFulfilmentOrderLine](/docs/reference/entities/inventory-fulfilment-order-line/) — referenced by via `OwnerId` - [BranchTimeSlot](/docs/reference/entities/branch-time-slot/) — referenced by via `ModifiedById` - [TaxDeclaration](/docs/reference/entities/tax-declaration/) — referenced by via `OwnerId` - [InventoryFulfilmentPickingLine](/docs/reference/entities/inventory-fulfilment-picking-line/) — referenced by via `OwnerId` - [Tax](/docs/reference/entities/tax/) — referenced by via `ModifiedById` - [ExpenseClaim](/docs/reference/entities/expense-claim/) — referenced by via `CreatedById` - [Adjustment](/docs/reference/entities/adjustment/) — referenced by via `CreatedById` - [VisitRouteGroup](/docs/reference/entities/visit-route-group/) — referenced by via `ModifiedById` - [Form26ASReconciliationEntry](/docs/reference/entities/form26-asreconciliation-entry/) — referenced by via `CreatedById` - [AssetBlock](/docs/reference/entities/asset-block/) — referenced by via `OwnerId` - [ExpensePolicyRule](/docs/reference/entities/expense-policy-rule/) — referenced by via `OwnerId` - [IncentivePeriod](/docs/reference/entities/incentive-period/) — referenced by via `ModifiedById` - [ContactAddress](/docs/reference/entities/contact-address/) — referenced by via `ModifiedById` - [DocumentNameSetting](/docs/reference/entities/document-name-setting/) — referenced by via `CreatedById` - [TransferInwardLine](/docs/reference/entities/transfer-inward-line/) — referenced by via `ModifiedById` - [DocumentServiceContractLine](/docs/reference/entities/document-service-contract-line/) — referenced by via `OwnerId` - [AssetServiceContractLine](/docs/reference/entities/asset-service-contract-line/) — referenced by via `ModifiedById` - [BankAccount](/docs/reference/entities/bank-account/) — referenced by via `CreatedById` - [CompensationSlab](/docs/reference/entities/compensation-slab/) — referenced by via `OwnerId` - [ChecklistTemplateLine](/docs/reference/entities/checklist-template-line/) — referenced by via `ModifiedById` - [LWFRule](/docs/reference/entities/lwfrule/) — referenced by via `OwnerId` - [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) — referenced by via `ModifiedById` - [IncentiveResourceTarget](/docs/reference/entities/incentive-resource-target/) — referenced by via `ModifiedById` - [InventoryOpeningLotState](/docs/reference/entities/inventory-opening-lot-state/) — referenced by via `ModifiedById` - [ExpenseReimbursementBatchLine](/docs/reference/entities/expense-reimbursement-batch-line/) — referenced by via `CreatedById` - [ExpenseCategory](/docs/reference/entities/expense-category/) — referenced by via `ModifiedById` - [CheckListLine](/docs/reference/entities/check-list-line/) — referenced by via `OwnerId` - [GeneralLedger](/docs/reference/entities/general-ledger/) — referenced by via `CreatedById` - [IncentiveTarget](/docs/reference/entities/incentive-target/) — referenced by via `OwnerId` - [VisitRouteStop](/docs/reference/entities/visit-route-stop/) — referenced by via `ModifiedById` - [Order](/docs/reference/entities/order/) — referenced by via `CreatedById` - [AutoPurchaseOrderLine](/docs/reference/entities/auto-purchase-order-line/) — referenced by via `CreatedById` - [CreditNoteLine](/docs/reference/entities/credit-note-line/) — referenced by via `CreatedById` - [Financer](/docs/reference/entities/financer/) — referenced by via `OwnerId` - [GSTR9HsnSummary](/docs/reference/entities/gstr9-hsn-summary/) — referenced by via `ModifiedById` - [AvailabilityRequest](/docs/reference/entities/availability-request/) — referenced by via `CreatedById` - [ConsolidationGroup](/docs/reference/entities/consolidation-group/) — referenced by via `CreatedById` - [CheckInTemplateLine](/docs/reference/entities/check-in-template-line/) — referenced by via `ModifiedById` - [GSTR6ISDDistribution](/docs/reference/entities/gstr6-isddistribution/) — referenced by via `ModifiedById` - [ShipmentLine](/docs/reference/entities/shipment-line/) — referenced by via `CreatedById` - [RequisitionLine](/docs/reference/entities/requisition-line/) — referenced by via `OwnerId` - [LandedCostLine](/docs/reference/entities/landed-cost-line/) — referenced by via `ModifiedById` - [CompanyCardReconciliation](/docs/reference/entities/company-card-reconciliation/) — referenced by via `CreatedById` - [VisitRouteGroup](/docs/reference/entities/visit-route-group/) — referenced by via `OwnerId` - [InvoiceLine](/docs/reference/entities/invoice-line/) — referenced by via `OwnerId` - [AvailabilityRequest](/docs/reference/entities/availability-request/) — referenced by via `OwnerId` - [PaymentBatchLine](/docs/reference/entities/payment-batch-line/) — referenced by via `OwnerId` - [ExpensePolicyViolation](/docs/reference/entities/expense-policy-violation/) — referenced by via `OwnerId` - [AccountLocation](/docs/reference/entities/account-location/) — referenced by via `ModifiedById` - [IncentivePeriod](/docs/reference/entities/incentive-period/) — referenced by via `CreatedById` - [AccountGroup](/docs/reference/entities/account-group/) — referenced by via `ModifiedById` - [TransferLine](/docs/reference/entities/transfer-line/) — referenced by via `CreatedById` - [PostalCode](/docs/reference/entities/postal-code/) — referenced by via `OwnerId` - [TaxGroupRule](/docs/reference/entities/tax-group-rule/) — referenced by via `OwnerId` - [BudgetCommitment](/docs/reference/entities/budget-commitment/) — referenced by via `ModifiedById` - [CompanyCard](/docs/reference/entities/company-card/) — referenced by via `ModifiedById` - [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) — referenced by via `OwnerId` - [LWFRule](/docs/reference/entities/lwfrule/) — referenced by via `CreatedById` - [SettlementAllocation](/docs/reference/entities/settlement-allocation/) — referenced by via `ModifiedById` - [Shipment](/docs/reference/entities/shipment/) — referenced by via `CreatedById` - [PurchaseOrderLine](/docs/reference/entities/purchase-order-line/) — referenced by via `ModifiedById` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `OwnerId` - [AutoPurchaseOrderLine](/docs/reference/entities/auto-purchase-order-line/) — referenced by via `OwnerId` - [SchemeBenefit](/docs/reference/entities/scheme-benefit/) — referenced by via `CreatedById` - [Visit](/docs/reference/entities/visit/) — referenced by via `ModifiedById` - [InventoryLedger](/docs/reference/entities/inventory-ledger/) — referenced by via `ModifiedById` - [Campaign](/docs/reference/entities/campaign/) — referenced by via `ModifiedById` - [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) — referenced by via `ModifiedById` - [ExpensePolicyRule](/docs/reference/entities/expense-policy-rule/) — referenced by via `ModifiedById` - [PayrollRunComponentLine](/docs/reference/entities/payroll-run-component-line/) — referenced by via `OwnerId` - [PartnerAccountMapping](/docs/reference/entities/partner-account-mapping/) — referenced by via `CreatedById` - [ServiceRecommendation](/docs/reference/entities/service-recommendation/) — referenced by via `OwnerId` - [InventoryCostLot](/docs/reference/entities/inventory-cost-lot/) — referenced by via `CreatedById` - [Branch](/docs/reference/entities/branch/) — referenced by via `ModifiedById` - [Shipment](/docs/reference/entities/shipment/) — referenced by via `ModifiedById` - [FiscalPeriod](/docs/reference/entities/fiscal-period/) — referenced by via `CreatedById` - [GSTR3BSection31](/docs/reference/entities/gstr3-bsection31/) — referenced by via `CreatedById` - [CycleCount](/docs/reference/entities/cycle-count/) — referenced by via `CreatedById` - [RevenueRecognitionScheduleLine](/docs/reference/entities/revenue-recognition-schedule-line/) — referenced by via `CreatedById` - [GSTR9HsnSummary](/docs/reference/entities/gstr9-hsn-summary/) — referenced by via `CreatedById` - [BankAccount](/docs/reference/entities/bank-account/) — referenced by via `ModifiedById` - [Case](/docs/reference/entities/case/) — referenced by via `CreatedById` - [AdjustmentLine](/docs/reference/entities/adjustment-line/) — referenced by via `CreatedById` - [ResourceAvailabilityData](/docs/reference/entities/resource-availability-data/) — referenced by via `ModifiedById` - [PayrollComponent](/docs/reference/entities/payroll-component/) — referenced by via `CreatedById` - [CompensationSlab](/docs/reference/entities/compensation-slab/) — referenced by via `ModifiedById` - [InspectionLine](/docs/reference/entities/inspection-line/) — referenced by via `ModifiedById` - [CampaignMember](/docs/reference/entities/campaign-member/) — referenced by via `OwnerId` - [ResourceAvailabilityCheckIn](/docs/reference/entities/resource-availability-check-in/) — referenced by via `OwnerId` - [InventoryStock](/docs/reference/entities/inventory-stock/) — referenced by via `CreatedById` - [TaxDeclarationLine](/docs/reference/entities/tax-declaration-line/) — referenced by via `OwnerId` - [Currency](/docs/reference/entities/currency/) — referenced by via `ModifiedById` - [GLAccount](/docs/reference/entities/glaccount/) — referenced by via `CreatedById` - [Quote](/docs/reference/entities/quote/) — referenced by via `OwnerId` - [LeaveRequest](/docs/reference/entities/leave-request/) — referenced by via `OwnerId` - [GLAccountPeriodBalance](/docs/reference/entities/glaccount-period-balance/) — referenced by via `CreatedById` - [RequisitionLine](/docs/reference/entities/requisition-line/) — referenced by via `CreatedById` - [FullAndFinalSettlementLine](/docs/reference/entities/full-and-final-settlement-line/) — referenced by via `ModifiedById` - [SchemePeriod](/docs/reference/entities/scheme-period/) — referenced by via `OwnerId` - [LoanAdvanceRecovery](/docs/reference/entities/loan-advance-recovery/) — referenced by via `ModifiedById` - [ExpenseReimbursementBatch](/docs/reference/entities/expense-reimbursement-batch/) — referenced by via `ModifiedById` - [Case](/docs/reference/entities/case/) — referenced by via `ModifiedById` - [OpenTransaction](/docs/reference/entities/open-transaction/) — referenced by via `OwnerId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Visit Plan — entity reference URL: https://xmatix.com/docs/reference/entities/visit-plan/ Last reviewed: 2026-08-16 One rep's route execution over a date window (planStartDate..planEndDate): the container the day's Visits are generated into. On create (and on relevant updates) the handler cascades generation - one visit per stop of the linked route (visitRouteId; the stored current RouteSequence orderings are stamped onto the visits), or one per member of accountGroupId, or one per pending delivery order when visitPurpose is Order Delivery - and defaults partner, purpose and task template from the route. assignedToResourceId names the rep meant to walk it (resolved from the route's seat holder when the route is position-owned, else the route's resource) and only that rep may execute (VisitAssignmentGuard); executedByResourceId records who actually did. Setting Status to Completed cancels every child visit that is not already Completed, Cancelled or Rescheduled; settled plan statuses are Completed, Executed, Cancelled and Lapsed. planType distinguishes Order Taking (default), Van Sales and Field Service execution modes. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AcceptanceStatus` | Acceptance Status | PickList | | Values: Accept, Decline, Not Sure. | | `AccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `ActualPlanEndDate` | Actual Plan End Date | DateAndTime | | | | `ActualPlanStartDate` | Actual Plan Start Date | DateAndTime | | | | `AssignedToResourceId` | Assigned To Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | The rep meant to walk the route - the identity the execution guard compares against. Auto-resolved for plans created by hand or API against a route: the route's seat holder when the route is position-owned, else the route's resource; an explicit assignee is never overridden. Salesperson-specific stored route orderings are also picked by this resource. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `City` | City | PickList | | Values: New Delhi. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `EndLocation` | End Location | GeoLocation | | When set, the route optimizer treats it as the fixed endpoint of the plan's optimized visit order. Geography point, wire shape latitude/longitude. | | `ExecutedByResourceId` | Executed By Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | Who actually executed the plan, as distinct from assignedToResourceId (who it was allocated to). Reported side by side in visit compliance reporting. | | `Id` | Id | Guid | Yes | | | `IncludePendingDeliveryCheckouts` | Include Pending Delivery Checkouts | Boolean | | | | `IncludePendingDeliveryOrders` | Include Pending Delivery Orders | Boolean | Yes | | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | | | `ModeofTransport` | Mode of Transport | PickList | | Values: Two Wheeler. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PlanEndDate` | Plan End Date | DateAndTime | | | | `PlanName` | PlanName | LongMultiLineText | | | | `PlanStartDate` | Plan Start Date | DateAndTime | | | | `PlanType` | Plan Type | PickList | | Execution mode: Order Taking (default), Van Sales or Field Service. Van Sales / Field Service plans dispatch stock to a mobile storage location (the van) and gate plan start on the load take-in. Values: Order Taking, Van Sales, Field Service. | | `PostalCode` | Postal Code | Text | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `RouteMethod` | Route Method | PickList | | Values: By Map Selection, By Pincode, By Account Group. | | `StartLocation` | Start Location | GeoLocation | | Geography point the road-network route optimizer anchors on when the rep's current location is not supplied to OptimizeRoute. Wire shape latitude/longitude. | | `State` | State | PickList | | | | `Status` | Status | PickList | | Plan lifecycle. Execution states (In Progress, Started, Paused, Completed, Executed) may only be entered by the assigned resource; settled states are Completed, Executed, Cancelled and Lapsed. The transition to Completed cancels every child visit that is not already Completed, Cancelled or Rescheduled, in the same save. Values: Draft, Assigned, Started, Executed, Lapsed, Cancelled, Completed. | | `TotalVisit` | Total Visit | Calculated (calculated) | | total visit in a visit plan | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VisitCompliance` | Visit Compliance | Calculated (calculated) | | how many visit has been completed under a visit plan | | `VisitPurpose` | Visit Purpose | PickList | | Defaulted from the route. The value Order Delivery is load-bearing: it makes plan generation create visits from pending, undelivered delivery orders matching the plan's branch, partner and date window. Values: Order Capture, Courtesy Visit, Order Delivery, Field Service, Product Demo, Service Touch, Payment Collection. | | `VisitRouteGroupId` | Visit Route Group | Lookup → [VisitRouteGroup](/docs/reference/entities/visit-route-group/) | | | | `VisitRouteId` | Visit Route | Lookup → [VisitRoute](/docs/reference/entities/visit-route/) | | | | `VisitTaskTemplateId` | Visit Task Template | Lookup → [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `ApplySequenceToPlan` | Apply Sequence To Plan | ServerAction (`ApplySequenceToPlan`), inactive | Stamps this plan's visits with a stored RouteSequence's ordering as the new PLANNED order: rewrites sequenceNumber and plannedSequence, compacted to 1..n over the plan's visits, with visits whose stop is not in the sequence trailing in their current order. Args: routeSequenceId (required guid). Returns the count of visits re-sequenced. | | `BulkDelete` | Delete | Delete | Delete the selected records. | | `ClearRoute` | Clear Route | UIAction, inactive | Clear Route | | `Clone` | Clone | ServerAction (`Clone`), inactive | Create a copy of this record | | `ConfigureRoute` | Configure Route | UIAction, inactive | Configure Route | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInList` | Edit | Edit | Edit In List Header | | `EditListHeader` | Edit | EditInline | EditListHeader | | `GetAllVisits` | View All Visits | ServerAction (`GetAllVisits`) | Read-only fetch of every Visit belonging to this plan, each returned with its account and task template embedded - the data source behind the plan's all-visits view. Modifies nothing. | | `New` | New | New | New | | `OptimiseRoute` | Optimise Route | ServerAction (`OptimizeRoute`) | Optimise Route | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [VisitRoute](/docs/reference/entities/visit-route/) — looks up via `VisitRouteId` - [Resource](/docs/reference/entities/resource/) — looks up via `ExecutedByResourceId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [Resource](/docs/reference/entities/resource/) — looks up via `AssignedToResourceId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` - [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) — looks up via `VisitTaskTemplateId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [VisitRouteGroup](/docs/reference/entities/visit-route-group/) — looks up via `VisitRouteGroupId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [Visit](/docs/reference/entities/visit/) — referenced by via `VisitPlanId` - [Order](/docs/reference/entities/order/) — referenced by via `VisitPlanId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `VisitPlanId` - [ProspectPlace](/docs/reference/entities/prospect-place/) — referenced by via `VisitPlanId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Visit Route Group — entity reference URL: https://xmatix.com/docs/reference/entities/visit-route-group/ Last reviewed: 2026-08-16 A container grouping related VisitRoutes and their VisitPlans, carrying shared context (branchId, partnerAccountId, visitPurpose, visitTaskTemplateId, resourceId). It is the host of territory planning: the PlanTerritory action splits a set of accounts across executives and creates one VisitRoute per executive under this group, sequenced over real road times. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VisitPurpose` | Visit Purpose | PickList | | Values: Order Delivery, Product Demo, Order Capture, Ready Stock Sales, Van Sales. | | `VisitRouteCode` | Visit Route Code | Text | | | | `VisitTaskTemplateId` | Visit Task Template | Lookup → [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | Edit | Edit in page. | | `EditInList` | Edit | EditInline | Edit In List Header | | `New` | New | New | New | | `PlanTerritory` | Plan Territory | ServerAction (`PlanTerritory`, async) | Multi-executive territory planning (vehicle-routing solve): splits a set of accounts across the given executives or seats and sequences each route over real road travel times, persisting one VisitRoute per executive under this group (stops in solver order) plus a RouteSequence audit run each. Args: executiveResourceIds[] or positionIds[] (positions win and stamp seat ownership), accountIds[] or accountGroupId or partnerAccountId, travelMode, maxStopsPerRoute, replaceExisting (default true). Requires the road-matrix provider; marked async it runs on the background worker at any size, while a synchronous invocation is capped to a small account count so the chunked matrix fits the request budget. The result reports per-route load, dropped and un-geocoded accounts, and deactivated prior routes. | ## Related entities - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) — looks up via `VisitTaskTemplateId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [VisitPlan](/docs/reference/entities/visit-plan/) — referenced by via `VisitRouteGroupId` - [VisitRoute](/docs/reference/entities/visit-route/) — referenced by via `VisitRouteGroupId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Visit Route Stop — entity reference URL: https://xmatix.com/docs/reference/entities/visit-route-stop/ Last reviewed: 2026-10-10 One outlet's place on a beat (visit route): the customer account visited, its position in the authored order, an optional time window, its coordinates and a check-in tolerance. Every approved stop becomes one visit on each plan the beat generates, carrying the stop's account, start and end time, sequence number, visit purpose, geofencing tolerance and location. Stops proposed from the field app's nearby-onboarding flow are Proposed and generate no visits until approved; a proposal for an account already on the beat is refused. Outlet Transfer moves a stop to another beat by re-pointing it, so its visit history stays attached. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | The customer account visited at this stop. Only active customer accounts can be picked. Copied onto every visit generated from the stop. | | `AccountLocation` | Account Location | GeoLocation | | The stop's own coordinates. Copied onto generated visits as their planned position; when empty, the account's stored geo-location is used instead. Route optimization uses only this field, so stops without it trail at the end of an optimized order. | | `AllowedGeofencingTolerance` | Allowed Geofencing Tolerance (KM) | Number | | How far from the outlet a check-in can be before the field app warns that the executive is off-site. Copied onto each generated visit. Although the label says KM, the field app reads the number in metres; empty means 100 metres. The warning does not stop the visit from starting. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DayNumbers` | Day Numbers | Text | | Day numbers recorded on the stop. Plan generation does not read them; the route's schedule decides which days a plan is generated. | | `Duration` | Duration | Calculated (calculated) | | Minutes between Start Time and End Time, calculated automatically; empty unless both are set. | | `EndTime` | End Time | TimeOnly | | The planned end of the visit at this outlet, copied onto each generated visit as its planned end time. The latest end time among a beat's stops sets the plan's end. | | `FridayAvailable` | Friday Available | Boolean | Yes | Availability switch recorded on the stop. Plan generation uses the route's day switches, not the stop's. | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `MondayAvailable` | Monday Available | Boolean | Yes | Availability switch recorded on the stop. Plan generation uses the route's day switches, not the stop's. | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | Free-text notes about the stop. Stops proposed from the field app say they are an onboard request from the visit plan agenda. | | `SaturdayAvailable` | Saturday Available | Boolean | Yes | Availability switch recorded on the stop. Plan generation uses the route's day switches, not the stop's. | | `SequenceNumber` | Sequence Number | Number | | The stop's position in the authored (Planned) order of the beat. Generated visits take it as their sequence number and planned rank; stops with an empty number sort last. When a stop is transferred it is renumbered after the target beat's highest number. | | `StartTime` | Start Time | TimeOnly | | The planned start of the visit at this outlet, copied onto each generated visit as its planned start time. | | `Status` | Status | PickList | | The stop's membership of the beat: Approved, Proposed or Rejected. Stops created on the web default to Approved; stops proposed from the field app are Proposed. Only Approved stops (or older stops with no status) generate visits and take part in route optimization. Values: Proposed, Approved, Rejected. | | `StopName` | Stop Name | Text | | The name the outlet carries on this beat. Stops proposed from the field app take the outlet's name. | | `SundayAvailable` | Sunday Available | Boolean | Yes | Availability switch recorded on the stop. Plan generation uses the route's day switches, not the stop's. | | `ThursdayAvailable` | Thursday Available | Boolean | Yes | Availability switch recorded on the stop. Plan generation uses the route's day switches, not the stop's. | | `TuesdayAvailable` | Tuesday Available | Boolean | Yes | Availability switch recorded on the stop. Plan generation uses the route's day switches, not the stop's. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VisitPurpose` | Visit Purpose | PickList | | Why the outlet is visited. Copied onto each visit generated from the stop. Values: Field Service, Order Capture, Courtesy Visit, Service Touch, Payment Collection, Asset Deactivation, Sale Order, Quote or Invoice Collection, New Asset Data Collection (FIR), Order Delivery, Product Demo. | | `VisitRouteId` | Visit Route | Lookup → [VisitRoute](/docs/reference/entities/visit-route/) | | The beat this stop belongs to. Changed only by Outlet Transfer, which re-points the stop so its visits and sequence history stay attached. | | `VisitTaskTemplateId` | Visit Task Template | Lookup → [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) | | A visit task template recorded on the stop. Plan generation does not use it: generated visits take the route's visit task template. | | `WednesdayAvailable` | Wednesday Available | Boolean | Yes | Availability switch recorded on the stop. Plan generation uses the route's day switches, not the stop's. | | `WeekNumbers` | Week Numbers | Text | | Week-of-month numbers recorded on the stop. Plan generation does not read them; the route's schedule decides which weeks a plan is generated. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditDetails` | Edit | Edit | EditDetails | | `EditEntity` | Edit | UIAction | EditEntity | | `EditInLine` | Edit | Edit | Edit in page. | | `EditInList` | Edit | EditInline | Edit In List Header | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Customer Account | `AccountId` | | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) — looks up via `VisitTaskTemplateId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [VisitRoute](/docs/reference/entities/visit-route/) — looks up via `VisitRouteId` - [ProspectPlace](/docs/reference/entities/prospect-place/) — referenced by via `OnboardedVisitRouteStopId` - [RouteSequenceEntry](/docs/reference/entities/route-sequence-entry/) — referenced by via `VisitRouteStopId` - [Visit](/docs/reference/entities/visit/) — referenced by via `VisitRouteStopId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Visit Route — entity reference URL: https://xmatix.com/docs/reference/entities/visit-route/ Last reviewed: 2026-08-16 The beat master: a named, reusable journey whose outlets are child VisitRouteStop rows and whose recurrence drives visit-plan generation (weekday flags plus weekNumbers, or a cron expression that overrides them). Owned either by a person (resourceId) or, in position-based assignment, by a seat (positionId) - in the latter case resourceId is a system-maintained cache of the seat's current holder. Carries defaults that flow to plans and their visits (visitPurpose, visitTaskTemplateId, partnerAccountId, accountGroupId, itemGroupId) and holds the stored orderings of its stops as child RouteSequence runs. Grouped under a VisitRouteGroup for territory planning. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `CoverageMidpointDistance` | Coverage Midpoint Distance (KM) | Number | | | | `CoverageMidpointLocation` | Coverage Midpoint Location | GeoLocation | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DayNumbers` | Day Numbers | Text | | CSV of ISO weekday numbers (1=Monday..7=Sunday) kept two-way in sync with the seven boolean day flags by the handler: editing the CSV rewrites the flags and vice versa. Together with weekNumbers it drives when plans are generated for the route, unless scheduleCron overrides. | | `EffectiveFrom` | Effective From | DateAndTime | | | | `EffectiveTo` | Effective To | DateAndTime | | | | `FridayAvailable` | Friday Available | Boolean | | | | `Id` | Id | Guid | Yes | | | `IsActive` | Active | Boolean | | | | `ItemGroupId` | Item Group | Lookup → [ItemGroup](/docs/reference/entities/item-group/) | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `MondayAvailable` | Monday Available | Boolean | | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountGroupId` | Partner Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PositionId` | Position | Lookup → [Position](/docs/reference/entities/position/) | | The seat that owns this route. When set, Resource is kept in sync with the seat's current holder automatically. | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | Text | | | | `ResourceId` | Resource | Lookup → [Resource](/docs/reference/entities/resource/) | | The route's owning salesperson. On seat-owned routes (positionId set) this is a derived cache of the seat's current holder and is restamped automatically on handovers - do not treat a manual edit as durable there. | | `RouteName` | Route Name | LongMultiLineText | | | | `RoutingPriority` | Routing Priority | PickList | | Values: Shortest Distance, Shortest Time. | | `SaturdayAvailable` | Saturday Available | Boolean | | | | `StartTime` | Start Time | TimeOnly | | | | `SundayAvailable` | Sunday Available | Boolean | | | | `ThursdayAvailable` | Thursday Available | Boolean | | | | `TuesdayAvailable` | Tuesday Available | Boolean | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VisitPurpose` | Visit Purpose | PickList | | Values: Service Touch, Order Capture, Order Delivery, Field Service, Product Demo, Courtesy Visit, Payment Collection. | | `VisitRouteGroupId` | Visit Route Group | Lookup → [VisitRouteGroup](/docs/reference/entities/visit-route-group/) | | | | `VisitTaskTemplateId` | Visit Task Template | Lookup → [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) | | Default execution playbook for the route: copied onto plans created from the route and from there onto generated visits (a stop-level template overrides it per stop). | | `WednesdayAvailable` | Wednesday Available | Boolean | | | | `WeekNumbers` | Week Numbers | Text | | Restricts plan generation to specific weeks of the month alongside the weekday flags; ignored when scheduleCron is set. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `AssignPositionsFromOwners` | Assign Positions from Owners | ServerAction (`AssignPositionsFromOwners`) | Converts person-owned routes to seat ownership: finds each route executive's Position (their open Executive Position mapping), creating the Position and mapping when none exists, then stamps the route. Idempotent - routes already on a position are skipped | | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditInList` | Edit | EditInline | Edit In List Header | | `EditPopup` | Edit | Edit | Edit | | `New` | New | New | New | | `OptimizeRouteSequence` | Optimize Route Sequence | ServerAction (`OptimizeRouteSequence`) | Paid road-network optimization of the route's APPROVED stops via the configured routing provider, appended as the new current Optimized RouteSequence - unlike the nearest-neighbour runs its distance and duration are real driving totals. The planner picks the new order up on the next plan creation; already-generated plans are untouched. Geo-less stops trail in authored order. Fails validation (without spending a provider request) when the provider is unconfigured or the route has no approved, geocoded stops. | | `RecomputeRouteSequences` | Recompute Sequences | ServerAction (`RecomputeRouteSequences`) | Refreshes the route's stored orderings in the RouteSequence source of record: one route-generic Optimized run (free nearest-neighbour over the approved stops' coordinates) plus MostlyFollowed runs computed from actual visit history - route-generic and one per salesperson with started-visit history. Each new run becomes current within its family; superseded runs keep their rows as history. Costs no external provider request. | ## Validations | Validation | Applies to | Error message | Notes | |---|---|---|---| | Effective From Field Validation | `EffectiveFrom`, Error, inactive | Effective From date cannot be in the past. | Effective From date cannot be in the past. | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Partner Account | `PartnerAccountId` | | | ActiveResource | `ResourceId` | | ## Related entities - [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) — looks up via `VisitTaskTemplateId` - [Position](/docs/reference/entities/position/) — looks up via `PositionId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Resource](/docs/reference/entities/resource/) — looks up via `ResourceId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `PartnerAccountGroupId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ItemGroup](/docs/reference/entities/item-group/) — looks up via `ItemGroupId` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` - [VisitRouteGroup](/docs/reference/entities/visit-route-group/) — looks up via `VisitRouteGroupId` - [VisitPlan](/docs/reference/entities/visit-plan/) — referenced by via `VisitRouteId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `VisitRouteId` - [Order](/docs/reference/entities/order/) — referenced by via `VisitRouteId` - [ProspectPlace](/docs/reference/entities/prospect-place/) — referenced by via `VisitRouteId` - [Visit](/docs/reference/entities/visit/) — referenced by via `VisitRouteId` - [RouteSequence](/docs/reference/entities/route-sequence/) — referenced by via `VisitRouteId` - [VisitRouteStop](/docs/reference/entities/visit-route-stop/) — referenced by via `VisitRouteId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Visit Task Activity — entity reference URL: https://xmatix.com/docs/reference/entities/visit-task-activity/ Last reviewed: 2026-08-16 One data-capture step under a VisitTask (visitTaskId, with visitId denormalized): the runtime instance of a VisitTaskTemplateActivity (visitTaskTemplateActivityId). A generic multi-type row - activityType decides the mobile renderer (checklist via checklistTemplateId, entity-form captures like Lead Capture / Log Case / Custom Form, photo and merchandising-audit captures that feed shelf-vision evaluation, order taking, payment collection) and the typed value slots (textValue, numericValue, currencyValue, dateValue, booleanValue, geolocationValue, longTextValue, email, phone, url) hold what was captured. The service auto-flips Status to Completed when any captured value changes on a not-yet-completed row. Writes are gated to the assigned rep, including inserts, because the mobile client materializes template activities as inserts already in an execution state. Links created documents back via orderId, serviceOrderId, deliveryOrderId, invoiceId, paymentId and productDemoId. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ActivityName` | Activity Name | Text | | | | `ActivityType` | Activity Type | PickList | | Picks the capture behavior and mobile renderer: checklist types work through checklistTemplateId, entity-form types (Lead Capture, Log Case, Custom Form) open a create form for the target entity, photo/merchandising types capture images that shelf-vision evaluation consumes, and order/payment types create business documents linked back to the activity. Values: Take Order, Checklist, Digital Signature, Photo Capture, General Task, Stock Check, Payment Collection, Returns Pickup, Merchandising Audit, Asset Verification, Competitor Capture, New Outlet Registration, Parts Consumption, Meter Reading, Proof of Delivery, Time & Expense, Barcode Scan, Safety Compliance, Schedule Follow-up, Lead Capture, Log Case, Custom Form, Product Demo, Generate Invoice, Delivery Fulfillment, Service Order Execution. | | `BooleanValue` | Boolean Value | Boolean | Yes | | | `ChecklistTemplateId` | Checklist Template | Lookup → [ChecklistTemplate](/docs/reference/entities/checklist-template/) | | The questionnaire a checklist-type activity fills. Answers are stored as CheckListLine rows related to this activity by default, or to the visit's service order when the template activity routes them there. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `CurrencyValue` | Currency Value | Currency | | | | `Date` | Date | TimeOnly | | | | `DateTimeValue` | Date Time Value | DateAndTime | | | | `DateValue` | Date Value | DateAndTime | | | | `DecimalValue` | Decimal Value | Number | | | | `DeliveryOrderId` | Delivery Order | Lookup → [DeliveryOrder](/docs/reference/entities/delivery-order/) | | | | `Duration` | Duration | Calculated (calculated) | | | | `Email` | Email | Text | | | | `EndTime` | End Time | TimeOnly | | | | `FieldName` | Field Name | Text | | | | `FieldValue` | Field Value | Text | | | | `FormLayoutId` | Form Layout | ExternalId | | Create-layout override for entity-form activity types, copied from the template activity so runtime rows carry it too; absent means the target entity's default Create layout is used. | | `GeolocationValue` | Geo Location Value | Text | | | | `Id` | Id | Guid | Yes | | | `InvoiceId` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | | | `IsActivityCompleted` | Is Activity Completed | Boolean | | | | `IsDisabled` | Is Disabled | Boolean | Yes | | | `IsHidden` | Is Hden | Boolean | Yes | | | `LongTextValue` | Long Text Value | MultiLineText | | Holds the full capture JSON stamped at completion (fields, lines, readings depending on the renderer), while textValue carries the short human summary. Parse it rather than treating it as free text. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `NumericValue` | Numeric Value | Number | | | | `ObjectName` | Object Name | PickList | | For entity-form activity types: the metadata entity the capture creates (copied from the template's designer-authored target). The Custom Form type has no fixed entity and relies entirely on this field. Values: Sale Order, Sale Invoice, Repair Order. | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PaymentId` | Payment | Lookup → [Payment](/docs/reference/entities/payment/) | | | | `PerformAutomatically` | Perform Automatically | Boolean | Yes | | | `Phone` | Phone | Text | | | | `PlannedDuration` | Planned Duration | Calculated (calculated) | | | | `PlannedEndTime` | Planned End Time | Date | | | | `PlannedStartTime` | Planned Start Time | TimeOnly | | | | `ProductDemoId` | Product Demo | Lookup → [ProductDemo](/docs/reference/entities/product-demo/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RNAExternalId` | RNA External | Text | | | | `SequenceNumber` | Sequence Number | Number | | | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | | | `StartTime` | Start Time | TimeOnly | | | | `Status` | Status | PickList | | Auto-managed: the service flips a not-yet-completed activity to Completed as soon as any captured value slot changes (text, numeric, currency, dates, boolean, geolocation, linked document ids and so on). Status timestamps mirror the visit-task pattern - Completed stamps endTime. Values: Started, Draft. | | `TextValue` | Text Value | Text | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `URL` | URL | Text | | | | `VisitId` | Visit | Lookup → [Visit](/docs/reference/entities/visit/) | | | | `VisitTaskId` | Visit Task | Lookup → [VisitTask](/docs/reference/entities/visit-task/) | | | | `VisitTaskTemplateActivityId` | Visit Task Template Activity | Lookup → [VisitTaskTemplateActivity](/docs/reference/entities/visit-task-template-activity/) | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit | | `EditInList` | Edit | EditInline | Edit In List Header | | `New` | New | New | New | ## Related entities - [VisitTask](/docs/reference/entities/visit-task/) — looks up via `VisitTaskId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [Visit](/docs/reference/entities/visit/) — looks up via `VisitId` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — looks up via `DeliveryOrderId` - [Payment](/docs/reference/entities/payment/) — looks up via `PaymentId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [VisitTaskTemplateActivity](/docs/reference/entities/visit-task-template-activity/) — looks up via `VisitTaskTemplateActivityId` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — looks up via `ChecklistTemplateId` - [ProductDemo](/docs/reference/entities/product-demo/) — looks up via `ProductDemoId` - [ShelfAuditResult](/docs/reference/entities/shelf-audit-result/) — referenced by via `VisitTaskActivityId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Visit Task Template Activity — entity reference URL: https://xmatix.com/docs/reference/entities/visit-task-template-activity/ Last reviewed: 2026-08-16 One activity definition under a VisitTaskTemplateEntry (visitTaskTemplateEntryId): the designer-authored spec a runtime VisitTaskActivity is instantiated from. activityType picks the capture kind; checklist activities point at a CheckListTemplate (checklistTemplateId) and can route their answers via checklistStorageTarget; entity-form activities name their target entity (objectName) and can override the create layout (formLayoutId). isMandatory activities gate the other activities within their task on mobile; isHidden ones are never surfaced at runtime. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `ActivityType` | ActivityType | PickList | | Values: Checklist, Take Order, Digital Signature, Photo Capture, General Task, Stock Check, Payment Collection, Returns Pickup, Merchandising Audit, Asset Verification, Competitor Capture, New Outlet Registration, Parts Consumption, Meter Reading, Proof of Delivery, Time & Expense, Barcode Scan, Safety Compliance, Schedule Follow-up, Lead Capture, Log Case, Custom Form, Product Demo, Generate Invoice, Delivery Fulfillment, Service Order Execution, Generic Component. | | `ChecklistTemplateId` | Checklist Template | Lookup → [ChecklistTemplate](/docs/reference/entities/checklist-template/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DashboardURL` | Dashboard URL | LongMultiLineText | | | | `Description` | Description | Text | | | | `Duration` | Duration (Mins) | Number | | | | `FieldName` | Field Name | Text | | | | `FieldValue` | Field Value | Text | | | | `FormLayoutId` | Form Layout | ExternalId | | Create-layout override for entity-form activity types (Lead Capture, Log Case, Custom Form): the mobile drawer opens this layout instead of the target entity's default Create layout when set. | | `Id` | Id | Guid | Yes | | | `IsHidden` | Is Hidden | Boolean | Yes | | | `IsMandatory` | Is Mandatory | Boolean | Yes | Mandatory activities gate the other activities within their task on the mobile execution screen - optional ones unlock once the first required activity is done. | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `ObjectApiName` | Object Api Name | Text | | | | `ObjectName` | Object Name | PickList | | Designer-authored target entity for entity-form activity types - the record kind the rep's capture creates. Drives the Custom Form type, which has no fixed entity of its own. Values: Delivery Order, Payment, Order, Account Stock. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordId` | Record | Text, unique | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `RelatedActivityAction` | Related Activity Action | PickList | | Values: Repeat By Value, Visible By Value, Enabled By Value. | | `RelatedVisitTaskTemplateActivityId` | Related Visit Task Template Activity | Lookup → [VisitTaskTemplateActivity](/docs/reference/entities/visit-task-template-activity/) | | | | `ReportURL` | Report URL | LongMultiLineText | | | | `RequirePicture` | Require Picture | Boolean | Yes | | | `SequenceNumber` | Sequence Number | Number | | | | `ShowDetails` | Show Details | Boolean | | | | `UIProps` | UI Props | Text | | | | `UniqueIdentifier` | Unique entifier | Text, unique | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VisitTaskTemplateEntryId` | Visit Task Template Entry | Lookup → [VisitTaskTemplateEntry](/docs/reference/entities/visit-task-template-entry/) | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInList` | Edit | EditInline | Edit in List Header | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [ChecklistTemplate](/docs/reference/entities/checklist-template/) — looks up via `ChecklistTemplateId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [VisitTaskTemplateEntry](/docs/reference/entities/visit-task-template-entry/) — looks up via `VisitTaskTemplateEntryId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [VisitTaskTemplateActivity](/docs/reference/entities/visit-task-template-activity/) — looks up via `RelatedVisitTaskTemplateActivityId` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — referenced by via `VisitTaskTemplateActivityId` - [VisitTaskTemplateActivity](/docs/reference/entities/visit-task-template-activity/) — referenced by via `RelatedVisitTaskTemplateActivityId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Visit Task Template Entry — entity reference URL: https://xmatix.com/docs/reference/entities/visit-task-template-entry/ Last reviewed: 2026-08-16 One task definition inside a VisitTaskTemplate (visitTaskTemplateId): name, taskType, sequence, duration and hidden flag. When a visit is generated with the template, each entry becomes a VisitTask (visitTaskTemplateEntryId links back) and the entry's child VisitTaskTemplateActivity definitions become the task's runtime activities. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CanExecuteOutOfSequence` | Execute Out Of Sequence | Boolean | | Allows the generated task to be worked outside the template's authored order; without it the mobile flow holds tasks to their sequence. | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | | | | `Description` | Description | Text | | | | `EntryName` | EntryName | LongMultiLineText | | | | `Id` | Id | Guid | Yes | | | `IsHidden` | Hidden | Boolean | | | | `IsMandatory` | Mandatory | Boolean | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordId` | Record | Text | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SequenceNumber` | Sequence Number | Number | | | | `TaskDuration` | Task Duration (Mins) | Number | | Planned minutes for the task, authored on the template. Runtime VisitTask rows expose it as their derived taskDuration. | | `TaskType` | Task Type | PickList | | Values: Perform Visit Activities. | | `TotalActivities` | Total Activities | Calculated (calculated) | | | | `UIProps` | UI Props | Text | | | | `UniqueIdentifier` | Unique entifier | Text, unique | | | | `UpdatedDateTime` | Modified Date | DateAndTime | | | | `VisitTaskTemplateId` | Visit Task Template | Lookup → [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditInList` | Edit | Edit | Edit | | `New` | New | New | New | | `NewInLine` | New | NewInline | NewInLine | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) — looks up via `VisitTaskTemplateId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [VisitTask](/docs/reference/entities/visit-task/) — referenced by via `VisitTaskTemplateEntryId` - [VisitTaskTemplateActivity](/docs/reference/entities/visit-task-template-activity/) — referenced by via `VisitTaskTemplateEntryId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Visit Task Template — entity reference URL: https://xmatix.com/docs/reference/entities/visit-task-template/ Last reviewed: 2026-08-16 The visit execution playbook header: which task cards a visit shows and which mobile options it exposes (showAcceptRejectOption, showVisitStartEndOption, showGetDirectionOption, showRescheduleOption, showProgressPanel - copied onto visits built with the template). Its child VisitTaskTemplateEntry rows become VisitTask rows on every visit that references the template via visitTaskTemplateId; routes, route stops and plans all carry a template pointer that flows down to generated visits. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | | | | `Description` | Description | Text | | | | `Duration` | Duration (Mins) | Number | | | | `Id` | Id | Guid | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | Template Name | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `ShowAcceptRejectOption` | Show Accept/Reject Option | Boolean | | | | `ShowGetDirectionOption` | Show Get Direction Option | Boolean | | | | `ShowProgressPanel` | Show Progress Panel | Boolean | | | | `ShowRescheduleOption` | Show Reschedule Option | Boolean | | | | `ShowVisitStartEndOption` | Show Visit Start/End Option | Boolean | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | | | | `VisitTaskId` | Visit Task | Lookup → [VisitTask](/docs/reference/entities/visit-task/) | | | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete the selected records. | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete in a list page | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit in page. | | `EditInList` | Edit | EditInline | Edit In List Header | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [VisitTask](/docs/reference/entities/visit-task/) — looks up via `VisitTaskId` - [VisitRoute](/docs/reference/entities/visit-route/) — referenced by via `VisitTaskTemplateId` - [VisitTaskTemplateEntry](/docs/reference/entities/visit-task-template-entry/) — referenced by via `VisitTaskTemplateId` - [VisitRouteStop](/docs/reference/entities/visit-route-stop/) — referenced by via `VisitTaskTemplateId` - [Visit](/docs/reference/entities/visit/) — referenced by via `VisitTaskTemplateId` - [VisitPlan](/docs/reference/entities/visit-plan/) — referenced by via `VisitTaskTemplateId` - [VisitRouteGroup](/docs/reference/entities/visit-route-group/) — referenced by via `VisitTaskTemplateId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Visit Task — entity reference URL: https://xmatix.com/docs/reference/entities/visit-task/ Last reviewed: 2026-08-16 One task card inside a Visit's execution flow (visitId), materialized from a VisitTaskTemplateEntry when the visit's task template is set - the handler deletes and recreates the visit's tasks when visitTaskTemplateId changes. Carries the entry's taskType, sequence and hidden flag; Status transitions stamp actuals (Started sets startTime, Completed sets endTime). The actual data capture happens in child VisitTaskActivity rows. Updates are gated to the resource the parent plan is assigned to (VisitAssignmentGuard). ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `Duration` | Duration | Calculated (calculated) | | | | `EndTime` | End Time | TimeOnly | | | | `Id` | Id | Guid | Yes | | | `IsHidden` | Is Hden | Boolean | Yes | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `Name` | Name | Text | | | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PlannedDuration` | Planned Duration | Calculated (calculated) | | | | `PlannedEndTime` | Planned End Time | TimeOnly | | | | `PlannedStartTime` | Planned Start Time | TimeOnly | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `SequenceNumber` | Sequence Number | Number | | | | `StartTime` | Start Time | TimeOnly | | | | `Status` | Status | PickList | | Task lifecycle (Pending, Started, Completed on mobile). Entering Started stamps startTime and Completed stamps endTime; execution updates are gated to the plan's assigned resource. Values: Planned, Started, Completed, Cancelled. | | `TaskDuration` | Task Duration | Calculated (calculated) | | Derived from the linked template entry's taskDuration (the planned minutes authored on the template), not an independent stored value on the task. | | `TaskName` | TaskName | LongMultiLineText | | | | `TaskNumber` | TaskNumber | Number | | | | `TaskType` | Task Type | PickList | | Values: Perform Visit Activities. | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VisitId` | Visit | Lookup → [Visit](/docs/reference/entities/visit/) | Yes | | | `VisitTaskTemplateEntryId` | Visit Task Template Entry | Lookup → [VisitTaskTemplateEntry](/docs/reference/entities/visit-task-template-entry/) | | The template entry this task instantiates. Changing it repopulates the task's activity rows from the entry's template activities. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `Delete` | Delete | Delete | Delete | | `DeleteEntity` | Delete | Delete | DeleteEntity | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditEntity` | Edit | Edit | EditEntity | | `EditInLine` | Edit | EditInline | Edit | | `EditInListHeader` | Edit | EditInline | Edit In List Header | | `New` | New | New | New | ## Related entities - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Visit](/docs/reference/entities/visit/) — looks up via `VisitId` - [VisitTaskTemplateEntry](/docs/reference/entities/visit-task-template-entry/) — looks up via `VisitTaskTemplateEntryId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — referenced by via `VisitTaskId` - [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) — referenced by via `VisitTaskId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Visit — entity reference URL: https://xmatix.com/docs/reference/entities/visit/ Last reviewed: 2026-08-16 One stop a field rep executes: a dated call on an outlet (accountId), normally generated under a VisitPlan from the route's stops (visitRouteStopId links back), from an account group's members, or from pending delivery orders. Lifecycle runs through visitStatus (Planned, Assigned, Started, Paused, Completed, Cancelled, Rescheduled); entering Started stamps the actual start (documentDate + startTime, kept on resume from Paused), Completed stamps endTime, and only the resource the plan is assigned to may move a visit into an execution state (VisitAssignmentGuard). Execution work hangs off child VisitTask rows (materialized from the visit's visitTaskTemplateId), and business documents created during the visit link back: the first Order/ServiceOrder created against the visit is stamped as its canonical orderId/serviceOrderId (never overwritten; later documents stay children via their own visitId). Also carries deliveryOrderId, invoiceId, paymentId and productDemoId links, the captured GPS point (visitLocation) versus the planned point (assignedLocation), and three stored orderings of the day's route (plannedSequence, optimizedSequence, mostlyFollowedSequence) behind the mobile Timeline/Map views. ## Fields | Field | Label | Type | Required | What it does | |---|---|---|---|---| | `AccountGroupId` | Account Group | Lookup → [AccountGroup](/docs/reference/entities/account-group/) | | | | `AccountId` | Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `AssignedLocation` | Assigned Location | GeoLocation | | The planned position of the stop, stamped at visit generation from the route stop's own coordinates or, when the stop was authored without them, the account's stored geo-location. Geography point, JSON wire shape latitude/longitude. | | `BranchId` | Branch | Lookup → [Branch](/docs/reference/entities/branch/) | | | | `CreatedById` | Created By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `CreatedDateTime` | Created Date | DateAndTime | Yes | | | `DeliveryOrderId` | Delivery Order | Lookup → [DeliveryOrder](/docs/reference/entities/delivery-order/) | | | | `DocumentDate` | DocumentDate | DateAndTime | | Stamped with the actual start timestamp (UTC) when the visit first enters Started - not a user-entered document date. Kept unchanged when a paused visit resumes. | | `EndTime` | End Time | TimeOnly | | | | `GeofencingTolerance` | Geofencing Tolerance (KM) | Number | | | | `Id` | Id | Guid | Yes | | | `InvoiceId` | Invoice | Lookup → [Invoice](/docs/reference/entities/invoice/) | | | | `Latitude` | Latitude | Decimal | | | | `Longitude` | Longitude | Decimal | | | | `ModifiedById` | Modified By | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `MostlyFollowedSequence` | Mostly Followed Sequence | Number | | The order reps have mostly followed historically on this route: the average actual visit order by start time across earlier plans, copied from the current MostlyFollowed RouteSequence (or computed inline for routes without stored history). Null when the route has no history yet. | | `Name` | Name | Text | | | | `NonProductiveReason` | Non-Productive Reason | PickList | | Why a visit produced no business outcome (picklist). The grain of the Non-Productive Visit report, which groups these by the plan's assigned executive. | | `OptimizedSequence` | Optimized Sequence | Number | | The geo-optimized order for this plan's visits: copied from the route's current Optimized RouteSequence at generation (nearest-neighbour, or real road-network order when the paid optimizer ran), and refreshed by the plan's OptimizeRoute action. | | `OrderId` | Order | Lookup → [Order](/docs/reference/entities/order/) | | The visit's canonical sales order under the one-order-per-visit rule: stamped automatically when the first Order is created against the visit, and never overwritten - later orders for the same visit remain children via Order.visitId only. | | `OwnerId` | Owner | Lookup → [UserAccount](/docs/reference/entities/user-account/) | Yes | | | `PartnerAccountId` | Partner Account | Lookup → [Account](/docs/reference/entities/account/) | | | | `PaymentId` | Payment | Lookup → [Payment](/docs/reference/entities/payment/) | | | | `PlannedDate` | Planned Date | Date | | | | `PlannedDuration` | Planned Duration | Calculated (calculated) | | | | `PlannedEndTime` | Planned End Time | TimeOnly | | | | `PlannedSequence` | Planned Sequence | Number | | The authored route order as planned: seeded from the route stops' sequence at generation and updated together with sequenceNumber when the planned order is deliberately restamped. One of three stored orderings behind the Timeline/Map route views. | | `PlannedStartTime` | Planned Start Time | TimeOnly | | | | `ProductDemoId` | Appointment | Lookup → [ProductDemo](/docs/reference/entities/product-demo/) | | | | `RecordTypeId` | Record Type | Guid, hidden | | | | `Remarks` | Remarks | MultiLineText | | | | `SequenceNumber` | Sequence Number | Number | | The canonical CURRENT order of the visit within its plan - what the mobile Timeline walks. Seeded from the route stop sequence, kept in sync by the rep's drag-reorder, and rewritten by ApplySequenceToPlan and OptimizeRoute (with apply). | | `ServiceOrderId` | Service Order | Lookup → [ServiceOrder](/docs/reference/entities/service-order/) | | The visit's canonical service order: stamped automatically when the first ServiceOrder is created against the visit and never overwritten afterwards - later service orders stay children via their own visitId. | | `ShowAcceptRejectOption` | Show Accept/Reject Option | Boolean | Yes | | | `ShowGetDirectionOption` | Show Get Direction Option | Boolean | Yes | | | `ShowProgressPanel` | Show Progress Panel | Boolean | | | | `ShowRescheduleOption` | Show Reschedule Option | Boolean | Yes | | | `ShowVisitStartEndOption` | Show Visit Start/End Option | Boolean | Yes | | | `StartTime` | Start Time | TimeOnly | | | | `UIProps` | UI Props | Text | | | | `UpdatedDateTime` | Modified Date | DateAndTime | Yes | | | `VisitCancellationReason` | Visit Cancellation Reason | PickList | | Values: Insufficient Information, Non Availability. | | `VisitCity` | Visit City | PickList | | Values: Pune, Chandigarh, Mumbai. | | `VisitContactAddressId` | Visit Address | Lookup → [ContactAddress](/docs/reference/entities/contact-address/) | | | | `VisitCountry` | Visit Country | PickList | | Values: India. | | `VisitDate` | Visit Date | Date | | | | `VisitDuration` | Visit Duration | Calculated (calculated) | | Derived, not stored input: minutes between startTime and endTime (0 until both are set). Writing to it has no effect. | | `VisitLocation` | Visit Location | GeoLocation | | The GPS point captured during execution, stored as a geography point (SRID 4326); the JSON wire shape is an object with latitude and longitude. Compare with assignedLocation, the planned position. | | `VisitPlanId` | Visit Plan | Lookup → [VisitPlan](/docs/reference/entities/visit-plan/) | | | | `VisitPostalCode` | Visit Postal Code | Text | | | | `VisitPurpose` | Visit Purpose | PickList | | Values: Payment Collection, Order Capture, Order Delivery, Field Service, Product Demo, Courtesy Visit, Service Touch. | | `VisitRegion` | Visit Region | Text | | | | `VisitRouteId` | Visit Route | Lookup → [VisitRoute](/docs/reference/entities/visit-route/) | | | | `VisitRouteStopId` | Visit Route Stop | Lookup → [VisitRouteStop](/docs/reference/entities/visit-route-stop/) | | | | `VisitState` | Visit State | PickList | | Values: Maharashtra, Punjab, New Delhi, Haryana. | | `VisitStatus` | Visit Status | PickList | | Execution lifecycle: Planned, Assigned, Started, Paused, Completed, Cancelled, Rescheduled (the mobile client also uses Ongoing for Started). First entry into Started stamps documentDate and startTime (a resume from Paused keeps the originals); Completed stamps endTime. Transitions into execution states are restricted to the plan's assigned resource, and plan completion force-cancels visits not already Completed/Cancelled/Rescheduled. Values: Planned, Assigned, Started, Completed, Rescheduled, Cancelled. | | `VisitStreet` | Visit Street | Text | | | | `VisitTaskTemplateId` | Visit Task Template | Lookup → [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) | | The execution playbook for this visit. Setting or changing it regenerates the visit's VisitTask rows from the template's entries - existing tasks are removed and recreated, so it is not a passive reference. | | `VisitTimeDeviation` | Visit Time Deviation | Calculated (calculated) | | Derived: plannedStartTime minus actual startTime in minutes (positive = started early, negative = late; 0 until both exist). Writing to it has no effect. | ## Actions | Action | Label | Type | What it does | |---|---|---|---| | `BulkDelete` | Delete | Delete | Delete | | `Clone` | Clone | ServerAction (`Clone`) | Create a copy of this record | | `ConvertLead` | Convert Lead 2 | ServerAction (`serverActionConvert`) | asdf | | `Delete` | Delete | Delete | Delete | | `DeleteInList` | Delete | Delete | Delete | | `Edit` | Edit | Edit | Edit | | `EditInLine` | Edit | EditInline | Edit | | `EditInList` | Edit | EditInline | Edit In List Header | | `EditPopup` | Edit | Edit | Edit | | `GetNearbyToOnboard` | Get Nearby To Onboard | ServerAction (`GetNearbyToOnboard`), hidden | Read-only feed for the mobile agenda: returns existing Accounts within a radius of the visit's location that are not yet on the plan or route, plus not-yet-onboarded ProspectPlace rows, both ranked by geodesic distance. Origin is the supplied currentLocation, else the visit's captured location, else its assigned location - with none of these it fails validation. Args radiusMeters (default 3000, max 100000) and maxResults (default 8, max 50). Creates nothing and calls no external provider. | | `New` | New | New | New | ## Lookup filters | Filter | Lookup field | Notes | |---|---|---| | Branch For Partner Account | `BranchId` | | | Only Partner Account | `PartnerAccountId` | | ## Related entities - [VisitPlan](/docs/reference/entities/visit-plan/) — looks up via `VisitPlanId` - [Branch](/docs/reference/entities/branch/) — looks up via `BranchId` - [AccountGroup](/docs/reference/entities/account-group/) — looks up via `AccountGroupId` - [Account](/docs/reference/entities/account/) — looks up via `AccountId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — looks up via `DeliveryOrderId` - [Order](/docs/reference/entities/order/) — looks up via `OrderId` - [ServiceOrder](/docs/reference/entities/service-order/) — looks up via `ServiceOrderId` - [VisitRoute](/docs/reference/entities/visit-route/) — looks up via `VisitRouteId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `OwnerId` - [Payment](/docs/reference/entities/payment/) — looks up via `PaymentId` - [Invoice](/docs/reference/entities/invoice/) — looks up via `InvoiceId` - [VisitTaskTemplate](/docs/reference/entities/visit-task-template/) — looks up via `VisitTaskTemplateId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `CreatedById` - [Account](/docs/reference/entities/account/) — looks up via `PartnerAccountId` - [VisitRouteStop](/docs/reference/entities/visit-route-stop/) — looks up via `VisitRouteStopId` - [ContactAddress](/docs/reference/entities/contact-address/) — looks up via `VisitContactAddressId` - [UserAccount](/docs/reference/entities/user-account/) — looks up via `ModifiedById` - [ProductDemo](/docs/reference/entities/product-demo/) — looks up via `ProductDemoId` - [Invoice](/docs/reference/entities/invoice/) — referenced by via `VisitId` - [VisitTaskActivity](/docs/reference/entities/visit-task-activity/) — referenced by via `VisitId` - [DeliveryOrder](/docs/reference/entities/delivery-order/) — referenced by via `VisitId` - [VisitTask](/docs/reference/entities/visit-task/) — referenced by via `VisitId` - [ShelfAuditResult](/docs/reference/entities/shelf-audit-result/) — referenced by via `VisitId` - [Order](/docs/reference/entities/order/) — referenced by via `VisitId` ## Related topics - [Entity reference index](/docs/reference/entities/) - [Customizing xMatix](/docs/customization/) ---- # Entity reference URL: https://xmatix.com/docs/reference/ Last reviewed: 2026-09-01 The entity reference documents the xMatix data model itself: every business entity, every field on it, and what that field does to the process the entity drives. Where the product manuals explain *how to work* — create an order, run payroll, close a ticket — this section explains *what the data is*. Each entity page carries: - **The field table** — every field with its name, label, type, whether it is required, picklist values where they apply, and a note on what the field does and how it affects downstream behavior (pricing, posting, approval, sync). - **Actions** — the buttons and server actions the entity exposes, with what executing each one actually does. - **Validations** — the rules that block a save, with the error message each produces. - **Lookup filters** — how the entity's lookup fields constrain which records can be picked. - **Lookups as links** — a field that points at another entity links straight to that entity's own reference page, so you can walk the model. - **Related entities** — the relationships in and out. ## Where to start - [All entities](/docs/reference/entities/) — the alphabetical index. - [Using entity screens](/docs/reference/using-entity-screens/) — a screenshot-led walkthrough of a populated list, every Account creation tab, and every Account detail tab. - Working with records day to day? Start with the [product manuals](/docs/) instead and use this section when you need to know exactly what a field means. - Building on the model — custom fields, rules, integrations? Pair this with [Customization](/docs/customization/) and the [Developer guide](/docs/developer/). ## Common questions ### How current is this reference? It is kept in sync with the production data model, so what you read here matches the product you are using. If a field exists in your tenant but not here, it is most likely a custom field added by your administrators — custom fields are tenant-specific and are not part of the platform reference. ### Why is a field's note blank? The field's name, label, type and requiredness always reflect the current model, but the explanatory notes are written and reviewed by people. A blank note means that write-up is still in progress. ## Related topics - [Administration guide](/docs/administration/) - [Customizing xMatix](/docs/customization/) ---- # Working with entity list, new and detail pages URL: https://xmatix.com/docs/reference/using-entity-screens/ Last reviewed: 2026-09-01 Most xMatix business records use the same three-part journey: locate a record in an entity list, enter the new record's core and tabbed fields, then work from a detail page that brings the record's related processes together. This guide uses **Account** because it demonstrates the entire pattern. Other entities may expose fewer tabs, different fields or additional actions, but the way you search, create, open and move between tabs remains consistent. ## Procedure ### Step 1 — Read the entity list @[guided-image](_img/account-list.png) The heading and view selector identify the entity and the active saved view. Summary cards describe the current population, while search, filters, refresh and column controls refine or reshape the grid without changing records. Each visible row is real synthetic demo2 data: names, types, ownership and other values are intentionally shown so you can see how a populated list behaves. Select a linked record name to open its detail page; choose **New** only when you have confirmed the current entity and view are the intended ones. ### Step 2 — Enter the Account header and Classification fields @[guided-image](_img/account-new-classification.png) The untabbed header holds the account's identity and commercial type: name, code, account type, revenue and location. The **Classification** tab adds the source, rating and site plus statutory identifiers and withholding-tax controls. Complete these values from an authoritative source. GSTIN, PAN, TAN and TDS choices are not descriptive notes; downstream tax, invoicing and withholding behavior can depend on them. ### Step 3 — Set the account's operational roles @[guided-image](_img/account-new-categorisation.png) The **Categorisation** tab determines whether the same party can act as a partner, supplier, customer or any combination of those roles. **Active** controls ordinary availability, **GL Posting Enabled** allows accounting use where configured, and **Create Account Contact** tells the create flow whether it should also build a contact from the contact tab. Select only roles the relationship genuinely performs; role flags change which lookups and processes can use this record. ### Step 4 — Capture the first contact @[guided-image](_img/account-new-contact.png) The **Contact Details** tab captures salutation, first name, last name, phone and email for the initial contact created with the account. It is most useful when **Create Account Contact** is enabled. Use an address and number that belong to the business contact, check spelling before saving, and add further people later from the detail page's **Contact & Address Info** tab rather than overloading this first contact. ### Step 5 — Confirm the billing address @[guided-image](_img/account-new-billing.png) The **Billing Address** tab records the invoicing destination as structured address, city, state, region, country and postal-code fields. Select reference values where the form provides them instead of typing variations. Billing geography can affect tax determination, document output and integrations, so do not copy the shipping address automatically unless it is genuinely the registered billing location. ### Step 6 — Confirm the shipping address @[guided-image](_img/account-new-shipping.png) The **Shipping Address** tab holds the default fulfilment destination. It mirrors the billing structure but serves a different purpose: delivery planning, fulfilment documents and logistics integrations can read these values. Enter the operational receiving location, including the correct state, region, country and postal code. Additional delivery sites can be added after saving without replacing the account's billing identity. ### Step 7 — Review the Sales tab on the detail page @[guided-image](_img/account-detail-sales.png) After saving or opening an account, the **Sales** tab gathers sales-side records related to that account, including opportunities and orders. Counts show whether related records exist; each embedded list retains its own columns and actions. Use this tab to understand the commercial history in context, then open a linked document for its complete lifecycle rather than attempting to manage the whole document inside the account page. ### Step 8 — Review Procurement relationships @[guided-image](_img/account-detail-procurement.png) The **Procurement** tab is relevant when the account is also a supplier. It groups purchase orders and goods receipts, making the source-to-receipt trail visible from the party master. Empty panels are meaningful: they indicate that no matching procurement record is currently related to this account, not that the page failed to load. ### Step 9 — Review Service activity @[guided-image](_img/account-detail-service.png) The **Service** tab brings together service opportunities, quotes, service orders and other enabled service records. Use the separate counts to distinguish an account with no service demand from one whose work is already in progress. Open the relevant linked document for scheduling, entitlement, parts, labour or invoicing details. ### Step 10 — Review Financials @[guided-image](_img/account-detail-financials.png) The **Financials** tab exposes commercial controls attached to the account, such as credit limits, price lists and discount groups. These records govern what the customer can buy and how transactions price; they are not merely historical output. Verify company, branch, effective status and default indicators before creating a new control, because overlapping active configuration can change transaction results. ### Step 11 — Maintain contacts and addresses @[guided-image](_img/account-detail-contact.png) The **Contact & Address Info** tab separates named contacts from structured contact addresses. Use **New** in the appropriate panel, keep each person and location as its own record, and mark defaults deliberately. This preserves clean selection in orders, invoices, service work and integrations while retaining more than one contact or destination for the same account. ### Step 12 — Review partner mappings @[guided-image](_img/account-detail-mappings.png) The **Partner Mappings** tab connects the account to partner account groups across an effective date window. These mappings can scope pricing, schemes, integrations or partner-specific behavior. Check both dates and the target group; an expired mapping should remain as history, while a genuinely new period should normally be represented by a new effective row. ### Step 13 — Read the consolidated Details tab @[guided-image](_img/account-detail-details.png) The **Details** tab is the read-only consolidated view of the account itself. It groups identity, statutory classification, operational flags, billing address and shipping address so reviewers can verify the current master without opening edit mode. Use it for confirmation and audit; choose **Edit** only when a value is wrong and you know the authoritative replacement. ### Step 14 — Check for likely duplicates @[guided-image](_img/account-detail-duplicates.png) The **Duplicates** tab searches for records that resemble the open account. Refresh after significant name, contact or address corrections. A result is a candidate for human review, not proof of duplication; compare identifiers and relationships before merging or deactivating anything. **No likely duplicates** means the current matching rules found no candidate at that time. ### Step 15 — Inspect change history @[guided-image](_img/account-detail-history.png) The **Change History** tab provides the record's audit trail where history is enabled. Use it to establish what changed, who changed it and when, especially before reversing a surprising master-data value. History explains prior state; it does not replace correcting the current field through the governed edit process. ## Expected result You can move from a populated entity list to a new-record form and then to a saved record's complete detail surface without losing context. Every creation tab has been reviewed before save, and every detail tab is understood as either master data, a related-record workspace or an audit tool. The record's visible data remains internally consistent across sales, procurement, service, financial and contact uses. ## Common questions ### Why does another entity have different tabs? Tabs come from that entity's configured layout and relationships. Your tenant can also add custom fields or layouts, so use the same navigation pattern but follow the labels shown in your environment. The individual [entity reference](/docs/reference/entities/) explains the platform fields and actions. ### Why is an embedded list empty? An empty embedded list usually means no related record matches the relationship and your access scope. Confirm the account and active view, then check permissions if another authorized user can see records you cannot. Do not create a replacement record merely to make a tab non-empty. ## Related topics - [Entity reference overview](/docs/reference/) - [All entities](/docs/reference/entities/) - [Accounts](/docs/crm/accounts/) - [Apps, entities and records](/docs/concepts/apps-entities-records/) ---- # xMatix release notes URL: https://xmatix.com/docs/release-notes/ Last reviewed: 2026-09-01 This section carries the monthly release summaries for xMatix. Each issue describes what changed in the platform that month, grouped by module, and links to the documentation pages that were updated for the change — so a release note is always one click from the full explanation of the feature it announces. ## When it starts Monthly summaries begin with the **September 2026** issue, covering that month's changes. Until the first issue is published, this page is deliberately empty of release content — nothing is listed here retroactively. ## How to judge currency in the meantime Every page in this Knowledge Center carries a **Last reviewed** date. Until the monthly summaries begin, that date is the currency signal: a recently reviewed page reflects the product as it currently behaves. When the summaries start, each issue will point at the pages re-reviewed for that release, giving you both signals together. ## Related topics - [xMatix frequently asked questions](/docs/faq/) - [Troubleshooting xMatix](/docs/troubleshooting/) - [Getting started with xMatix](/docs/getting-started/) ---- # Compensation records, lines and slabs URL: https://xmatix.com/docs/rewards/compensation/ Last reviewed: 2026-09-02 ## Read evaluated compensation Compensation is where incentive evaluation lands. A **compensation record** is the payout header for one plan, one period and (optionally) one partner account or branch; its **compensation lines** each hold one participant's evaluated result — what they achieved and what they earned. What they *can* earn is defined up front on the [incentive plan](/docs/rewards/incentive-plans/) as **compensation slabs**: bands of achievement, each with a reward. Treat the compensation screens as evidence to review, not a place to type a replacement result: every save of a line re-runs the evaluation and overwrites the computed figures. Start from the register described in [Tracking incentives](/docs/rewards/tracking/), then open the record whose plan, period, participant and amount you need to explain. @[guided-image](_img/compensation-detail-details.png) ## Where to find it Open the **Rewards** app and choose **Compensations** in the app navigation. The list opens as *All Compensations*; click a record name to open it in a workspace tab. The record shows the child **Compensation Line** grid on the left and the **Details** tab on the right. A user needs read access to the Compensation and Compensation Line entities in their security profile to see the screen, and the Rewards app itself must be enabled for the tenant's licence. ## Compensation records The header carries the scope and lifecycle of a payout run: | Field | What it holds | | --- | --- | | Name | The record number (auto-generated) | | Incentive Plan | The plan whose lines and slabs the evaluation used | | Incentive Period | The performance window whose KPI accruals were counted | | Account | The partner account the header is scoped to, for partner-member plans | | Branch | The branch the header is scoped to, for branch-member plans | | Status | The review or payout state. The values are tenant-defined picklist entries and the engine never changes them; setting them is a manual step | | Total Incentive Amount | The header total. The engine writes amounts on the lines only — it does not roll them up into this field, so reconcile the header against the sum of the lines' Incentive Amount when you review a run | Plan and period on the header are for reading; the engine evaluates against the plan and period stored on each *line*. ## Compensation lines Each line names the participant (the plan's **Incentive Resource**), the **Incentive Plan** and the **Incentive Period**. Saving a line — creating it or editing any field — triggers the incentive engine for that line. The run: 1. Skips silently when the line has no Incentive Plan or no Incentive Period, or when the plan's status is not **Approved** (the engine only loads lines of approved plans). 2. Loads the plan's incentive lines in sequence order, with their targets and slabs, and the period's KPI accruals for the plan. 3. For every target, finds the participant's **Incentive Resource Target** (the quota assigned to this resource for this target). A participant with no quota for a target, or a quota of zero, scores nothing on that target. 4. Sums the matching KPI rows — matched to the participant by the plan's member type (Resource, Partner, Branch or Customer) and narrowed by the target's item, account or item-group filter — and stamps the summed **achieved figure** on the line. 5. Computes the achievement percentage, picks the qualifying slab (see below) and writes the **reward**. Achieved figures are stamped per target type so the result is auditable: No of Bookings (for *No Of Sale Orders* targets), No of Invoices, Sale Order Amount, Sale Amount, Sale Order Quantity, Sale Quantity (for *Invoice Quantity*), Purchase Order Amount, Purchase Order Quantity, No Of Unique Invoices (distinct accounts), No Of Unique Items (distinct items) and Custom KPI Value. The reward depends on the qualifying slab's compensation type: an **Incentive Amount**, **Gifts** plus **Points**, a linked **Scheme**, or a linked **Discount Group**. Beyond the engine-written fields a line carries review fields the engine never touches: **Status** (tenant-defined picklist), **Override Incentive Amount** for a manually agreed figure kept separate from the computed one, and **Is Compensation Received** to record that the payout reached the participant. Use these rather than editing the computed amount, which the next save would overwrite anyway. ## Compensation slabs Slabs live on the plan, attached to an incentive line, and state what each band of achievement earns. A slab has a percentage band — **From Percentage** and **To Percentage** of target achievement — a **Sequence Number** that sets evaluation order, and a **Compensation Type**: | Compensation type | The participant earns | | --- | --- | | Fixed Amount | The slab's Incentive Fixed Amount | | Amount Per Unit | Incentive Amount Per Unit × the achieved value of the target the slab qualified through | | Amount Per Unit Incremental | The same product, doubled | | Percentage On Value | Amount Percentage of the achieved value | | Gifts | The slab's Gifts and Reward Points, copied onto the line | | Discount Group | The slab's Discount Group, linked on the line | | Scheme Rewards | The slab's Scheme, linked on the line | Only the types above have a payout branch in the engine. The picklist also offers *KPI Reward Value*, *KPI Reward Value Percentage*, *Reward Points* and *Slab Reward Percentage*, and the slab has *Percentage on Profit*, *From Value*, *To Value*, *Target Percentage* and *Member Resource Type* fields — a slab configured with any of these qualifies like any other but writes no reward. Choose one of the seven implemented types. The default picklist does not include *Scheme Rewards*; an administrator must add that value under Setup before a slab can use it. ## How a slab is picked For each target the engine computes the participant's achievement percentage — reached ÷ quota × 100, rounded **down** to a whole number — and walks the line's slabs in sequence order. The first slab whose band contains the percentage qualifies; **From Percentage** empty counts as 0, and **To Percentage** empty or 0 makes the band open-ended upward. Design bands to meet cleanly: with slabs 0–80 and 81–120, an achievement of 80.9 floors to 80 and lands in the first band. Two computation details worth knowing: - **Percentage On Value** compares before it writes: if the line already carries an Incentive Amount from an earlier slab, the percentage-based amount replaces it only when it is higher. Every other amount type simply overwrites — when several targets or incentive lines qualify on one save, the last amount written wins. - **Amount-per-unit types** multiply by the achieved value of the target the slab qualified through — quantity targets pay per unit achieved, value targets per unit of value. An incentive line whose definition criteria is **Always (No Criteria)** qualifies without evaluating its targets, so no slab is matched and no reward is written; give every paying line real targets and a criteria of *All* or *Any* conditions. ## Common questions ### Why did the amount on a line change when I saved it? Saving a compensation line re-runs the evaluation against the current KPI data, target quotas and plan definition. If performance accrued, a quota changed, or a slab was edited since the last save, the freshly computed achieved figures and reward replace the previous ones. Record a reviewed figure in **Override Incentive Amount**, which the engine does not write. ### A line saved but shows no achieved figures and no amount. Why? Check, in order: the line has both an Incentive Plan and an Incentive Period; the plan's status is **Approved**; the participant has an Incentive Resource Target with a non-zero value for each target; KPI rows exist for that plan and period and match the participant according to the plan's member type. Any one of these missing makes the engine skip or score zero without an error. [Troubleshooting](/docs/rewards/troubleshooting/) walks through each check. ### Can a slab reward something other than money? Yes — **Gifts** writes Gifts and Points to the line, **Discount Group** links a discount group, and **Scheme Rewards** links a [trade scheme](/docs/sales/trade-schemes/). The last two bridge into the pricing and scheme machinery, so an incentive can pay out as better commercial terms rather than cash. They are written to separate fields, so a line can hold a cash amount and a gift or scheme at the same time. ### What happens between two slabs' bands? Nothing — an achievement percentage that no band contains qualifies no slab, and no reward is written for that target. Make the *From* of each slab continue where the previous *To* ends, and leave the top slab's *To* empty so over-achievement still pays. ### Does the header total update when I add or re-save lines? No. Total Incentive Amount is stored on the header and nothing recomputes it from the lines. Sum the lines' Incentive Amount (or use a report on Compensation Line grouped by Compensation) and set the header figure as part of your review. ## Related topics - [Incentive plans](/docs/rewards/incentive-plans/) - [Running an incentive cycle](/docs/rewards/running-incentives/) - [Tracking incentives](/docs/rewards/tracking/) - [Troubleshooting](/docs/rewards/troubleshooting/) - [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/) ---- # Rewards configuration reference URL: https://xmatix.com/docs/rewards/configuration/ Last reviewed: 2026-08-15 This page is the administrator's reference for the Rewards module: what the platform validates and locks on incentive plans, how periods are generated, which actions ship on the Rewards entities, and exactly which KPI field each target type reads. For the concepts behind these rules, start at [Incentive plans](/docs/rewards/incentive-plans/). ## Access The Rewards app appears in a user's navigation when granted through their [security profile](/docs/administration/security-profiles/). Its entities — Incentive Plan, Compensation, KPI Configuration, Resource, Resource Group, Scheme — follow the platform's [record security](/docs/administration/record-security/) like any other entity. ## Plan validation rules Enforced when an incentive plan is saved: | Rule | Detail | | --- | --- | | Scope exclusivity | A partner account group cannot be combined with a partner account or a branch — pick group scoping or direct scoping | | Resource type gating | Member resource type may only be set when the member type is Resource | | Period length | Daily, Weekly and Bi Weekly plans are limited to one year between period start and end | | Date order | Valid-from must not fall after valid-to | | Locked fields | Once the plan has incentive resources or targets: branch, member type, partner account, partner account group, period type and member resource type can no longer change | ## Period generation Periods are generated once, when the plan is created, from its period type and start/end dates: | Period type | Generates | | --- | --- | | Yearly | One period covering the range | | Quarterly | One period per three months, from the first of the start month | | Monthly | One period per calendar month | | Weekly / Bi Weekly | One period per week or fortnight, weeks aligned to Monday | | Daily | One period per day | Period names are derived from their dates (for example a monthly period is named after its month and year). Because generation happens at creation, changing dates later does not add or remove periods — plan the range before saving. ## Seeded actions The Rewards entities ship with the standard **New**, **Edit** and **Delete** actions (list, row and detail variants) on Incentive Plan, Incentive Line, Incentive Target, Incentive Period, Incentive Resource, Incentive Resource Target, Compensation, Compensation Line and Compensation Slab. The Incentive Plan detail page additionally carries three create actions: | Action | Creates | | --- | --- | | Create Incentive Target | A measure definition on the plan | | Create Incentive Line | A qualification line grouping targets | | Create Compensation Slab | A payout band on a line | The plan page's slab builder widget drives the same three record types as one guided flow, and the target grids edit incentive resource target values in bulk. ## Evaluation trigger The incentive engine runs inside the save pipeline of **Compensation Line** records — every create or update of a line evaluates it once against the current plan definition, target values and Performance KPI data. Only plans with status **Approved** are considered. There is no separate scheduler to configure: evaluation frequency is entirely a function of when compensation lines are saved. See [execution order](/docs/concepts/execution-order/) for where save-pipeline logic sits generally. ## Target type reference What each target type reads from the member's matching Performance KPI records, and where the achieved figure is stamped on the compensation line: | Target type | Sums (Performance KPI) | Stamped on line as | | --- | --- | --- | | No Of Sale Orders | Number of orders | No of Bookings | | No Of Invoices | Number of invoices | No of Invoices | | Sale Order Amount | Total sale order amount | Sale Order Amount | | Sale Amount | Total sale invoice amount | Sale Amount | | Sale Order Quantity | Total sale order quantity | Sale Order Quantity | | Invoice Quantity | Total sale invoice quantity | Sale Quantity | | Purchase Order Amount | Total purchase order amount | Purchase Order Amount | | Purchase Order Quantity | Total purchase order quantity | Purchase Order Quantity | | No Of Unique Invoices | Count of distinct accounts | No Of Unique Invoices | | No Of Unique Items | Count of distinct items | No Of Unique Items | | Custom KPI | The field named on the target | Custom KPI value | KPI records match a member by the plan's member type — resource plans match the record's resource, partner plans its partner account, branch plans its branch, customer plans its account — and then by the target's item, item group (SKU-aware) and account filters. ## Common questions ### Why can't a user edit member type or period type on a plan? The plan has incentive resources or targets — from that point the structural fields are locked because periods, assignments and KPI matching all derive from them. The fix is a new plan, not an edit. ### Do all lines need slabs? Rewards are written from slabs that qualify through targets, so a line without slabs — or with the filter criteria **Always (No Criteria)**, which skips target evaluation — produces no payout. Every paying line needs at least one target and one slab whose percentage bands cover the achievement range you intend to reward, including an open-ended top band. ### What should an administrator check before a period goes live? Plan status Approved; every member enrolled with the correct member reference for the plan's member type; a target value per member per period (no zeros — a zero target can never qualify); slabs whose bands meet without gaps. The [troubleshooting page](/docs/rewards/troubleshooting/) is the after-the-fact version of this list. ## Related topics - [Incentive plans](/docs/rewards/incentive-plans/) - [Security profiles](/docs/administration/security-profiles/) - [Execution order](/docs/concepts/execution-order/) - [Troubleshooting](/docs/rewards/troubleshooting/) ---- # Incentive plans URL: https://xmatix.com/docs/rewards/incentive-plans/ Last reviewed: 2026-09-02 ## What an incentive plan is An incentive plan answers four questions: *who* is being incentivised (its members), *over what timeframe* (its periods), *measured on what* (its targets) and *earning what* (its incentive lines and their [compensation slabs](/docs/rewards/compensation/)). Once the plan's status is **Approved**, the incentive engine evaluates each member's KPI performance against that member's own quota and writes the earned reward to the member's [compensation line](/docs/rewards/compensation/). ## Where to find it Open the **Rewards** app and choose **Incentive Plans**. The list opens as *All Incentive Plans*; **New** opens the create form with four sections — **Details** (Member Resource Type, Member Type, Status), **Compensation Eligibility**, **Period Definition** (Period Start Date, Period End Date and Period Type, all required) and **Resource Member Filters**. Click a plan's name to open the saved record, which adds a status stage bar and four tabs: **Related**, **Targets by Resources**, **Targets by KPI** and **Compensations**. @[guided-image](_img/incentive-plan-detail-related.png) ## The plan header | Field | What it does | | --- | --- | | Name | The plan number, generated on save | | Member Type | Who the members are. The engine matches KPI records for **Resource** (by resource), **Partner** (by partner account), **Branch** (by branch) and **Customer** (by account). Any other value in the picklist has no matching rule, so members of such a plan never accrue achievement | | Member Resource Type | Narrows a Resource plan to one resource type. Saving fails if it is set on a plan whose Member Type is not Resource. It is recorded for enrolment; the engine matches on the enrolled resource itself | | Resource Group | Optional member resource group, recorded on the plan for enrolment; not read by the engine | | Status | **Draft → Pending Approval → Approved**, shown as the stage bar on the saved record. Only Approved plans are evaluated | | Period Start Date / Period End Date / Period Type | The plan's window and how it is sliced into periods. Required. The engine's generator supports Yearly, Quarterly, Monthly, Weekly, Bi Weekly and Daily; the default picklist ships with Weekly, Monthly and Yearly, so an administrator adds the other values under Setup before they can be chosen | | Account, Account Group, Branch | Scope the plan to one partner account, one partner account group or one branch. An account group cannot be combined with an account or a branch — saving fails with *Either Partner Account Group or Partner Account can be selected* | | Compensation Eligibility / Compensation Eligibility Formula | Stored on the plan and shown on the form, but no evaluation step reads them in the current release. Do not rely on them as a payout gate | | Copy Source Targets / Incentive Plan (source) | Intended to copy target assignments from another plan. In the current release saving with the box ticked only clears the box — no targets are copied. Enter or import resource targets directly | | Business Hours | Intended to skip non-working days when generating Daily periods; the generator currently creates a period for every calendar day | ## What happens when you save - **On create**, the plan's **incentive periods** are generated from the period type across the date range: one period for a Yearly plan; one per quarter, month, week (aligned to Monday), fortnight or day otherwise. Periods are named after their dates (for example *July - 2026*). They are generated once — changing the dates later does not regenerate them, so add or delete Incentive Period rows by hand if the window changes. - **Validation** rejects an end date before the start date, and limits Daily, Weekly and Bi Weekly plans to at most one year. - **Once the plan has members or targets**, six fields lock: Branch, Member Type, Account, Account Group, Period Type and Member Resource Type. Changing any of them is rejected. Set these right before you enrol anyone. - **Partner-member plans** also refresh the partner portal's target cards on every save: the plan is the single source of the goal a partner sees and the number the engine pays on. Only ordered/invoiced quantity and value targets are mirrored; count, purchase and custom-KPI targets are skipped, and hand-authored portal targets are never overwritten. See [Partner portals](/docs/portals/). ## Periods Targets, KPI records and compensation lines all attach to a specific **Incentive Period**, so one month's achievement never mixes with the next. Each period carries Date From, Date To and a Status (**Draft** / **Calculated**) that is informational — the engine does not set or check it. Periods are listed on the plan's **Compensations** tab. ## Members and their targets Each member is enrolled as an **Incentive Resource** row on the plan, pointing at the person (Resource), Partner Account, Branch or Contact that matches the member type. Targets then come in two layers: - An **Incentive Target** defines *what* is measured: an **Incentive Target Type** (see below), optional filters — a specific **Item**, an **Item Group** (SKU-aware) or an **Account** — a **Sequence Number** that gives it a position in the line's logic, and for Custom KPI targets the **Custom KPI Field Name** to read. The target's own Value, Value Percentage, Operation and Target Value Type fields are stored but not read by the engine; the quota always comes from the member's assignment. - An **Incentive Resource Target** assigns a target to one member for one period with the **Value** that member must reach, and names the **KPI Configuration** it belongs to. Achievement is always computed against the member's own value — a member with no assignment, or a value of zero, never qualifies. The target types the engine evaluates, and what each one sums from the member's matching [Performance KPI](/docs/rewards/kpi-configurations/) records: | Target type | Measures | | --- | --- | | No Of Sale Orders / Sale Order Amount / Sale Order Quantity | Count, value or quantity of sale orders | | No Of Invoices / Sale Amount / Invoice Quantity | Count, value or quantity of sale invoices | | Purchase Order Amount / Purchase Order Quantity | Value or quantity of purchase orders | | No Of Unique Invoices | Distinct accounts across the matching KPI records | | No Of Unique Items | Distinct items across the matching KPI records | | Custom KPI | The field named in Custom KPI Field Name, read from each KPI record | The Incentive Target Type picklist offers many more values (bills, finance, insurance, repair orders, hours and so on). A target of any type not listed above sums nothing and stamps nothing. Note also that the picklist value **Sale Invoice Quantity** is not the engine's **Invoice Quantity** — a target saved with the picklist spelling scores zero until an administrator adds the engine's spelling to the picklist. ## Incentive lines: combining targets into a qualification An **Incentive Line** groups targets under a qualification rule and carries the [compensation slabs](/docs/rewards/compensation/) that state the reward. Its **Definition Filter Criteria** decides how the targets combine: - **All Conditions Are Met** — every target must qualify. - **Any Condition Is Met** — one qualifying target is enough. - **Custom Logic Is Met** — **Definition Custom Logic** holds an expression such as `{1} AND {2} OR {3}`, where `{N}` is the target at sequence position N. `OR` splits first, `AND` binds within each branch. A malformed expression qualifies nothing. - **Always (No Criteria)** — the line qualifies without evaluating targets. Because rewards attach to slabs that qualify *through* targets, a line set to Always writes no reward. The default picklist ships with the first two values; add the other two under Setup if you need them. Lines are evaluated in **Sequence** order, and a plan can carry several lines with different rules and slabs. The line's **Reward Applicability**, **Reward Custom Logic** and **Use Slab Absolute Value** fields are not read by the incentive engine (they mirror trade-scheme line settings); every qualified slab on a line is applied. ## The saved plan's tabs **Related** shows the configuration behind the header: an **Incentive Line** grid (with each line's Definition Filter Criteria, Definition Custom Logic and reward settings), an **Incentive Resource** grid of enrolled members with their Resource, Partner Account and Branch, one collapsible panel per incentive line above the grids, and an *Add Incentive Line* panel. **New** on either grid opens the child form. An approved plan whose Related tab shows no lines or no members cannot produce compensation. @[guided-image](_img/incentive-plan-detail-targets-resources.png) **Targets by Resources** is a participant-first pivot of the plan's Incentive Resource Target rows: pick a **KPI Configuration** in the drop-down, and the grid lists every enrolled member down the side with one column per period. Cells are editable — type a quota, and a **Save** button appears with the count of pending changes; nothing is written until you click it. Use the search box to find a member and the refresh icon to reload after imports. @[guided-image](_img/incentive-plan-detail-targets-kpi.png) **Targets by KPI** is the measure-first view of the same rows: pick a **member** in the drop-down and the grid lists each KPI configuration with the member's quota per period. It is the quickest way to spot a member with a missing or zero quota for one KPI. @[guided-image](_img/incentive-plan-detail-compensations.png) **Compensations** shows the plan's **Incentive Period** grid (Date From, Date To, Status) and the **Compensation** headers evaluated against the plan, with their Incentive Period, Account and Total Incentive Amount. Open a compensation to see the per-member lines and their achieved figures. ## How the engine evaluates a plan Evaluation runs when a [compensation line](/docs/rewards/compensation/) is saved for a member, plan and period: 1. The engine loads the plan's incentive lines (approved plans only), the member's target assignments, and the Performance KPI records for that plan and period. 2. Per target, it sums the KPI records that match the member (by the plan's member type) and the target's filters, producing the **reached value**, and stamps it onto the compensation line so you can see what was counted. 3. Achievement is computed as a percentage of the member's quota, rounded down: reached ÷ value × 100. 4. The line's slabs are checked in sequence; the first slab whose band contains the percentage qualifies. 5. Target results combine per the line's filter criteria; if the line qualifies, each qualified slab's reward is written to the compensation line. ## Common questions ### Why isn't my plan paying anything? The most common reason is status: only plans with status **Approved** are evaluated — a draft plan is invisible to the engine, no matter how complete. After that, check that the member has an Incentive Resource Target with a non-zero value for the target and period, that the target's type is one the engine evaluates, and that KPI records exist for that plan and period. The [troubleshooting page](/docs/rewards/troubleshooting/) walks the full checklist. ### Can different members have different targets in the same plan? Yes — that is exactly what incentive resource targets are for. The target defines the measure once; each member's assignment carries their own value, and achievement is always a percentage of that personal value. Two reps on the same plan with values of 100 and 200 both hit 100% by reaching their own number. Enter them in **Targets by Resources**. ### How do I write "target 1 and target 2, or target 3 alone"? Set the line's Definition Filter Criteria to **Custom Logic Is Met** and its Definition Custom Logic to `{1} AND {2} OR {3}`. The numbers refer to the targets' sequence positions on the line. `OR` has lower precedence, so the expression reads as (1 and 2) or (3). ### Can I change the period type after the plan is live? No. Periods are generated when the plan is created, and once the plan has members or targets the period type — along with member type and the plan's scoping fields — is locked. To move from monthly to quarterly, create a new plan. ### Does Copy Source Targets copy the quotas from another plan? Not in the current release: saving with the box ticked clears it and copies nothing. Enter quotas in **Targets by Resources** or import Incentive Resource Target rows with [Data import](/docs/administration/data-management/import-data/). ## Related topics - [KPI configurations](/docs/rewards/kpi-configurations/) - [Compensation](/docs/rewards/compensation/) - [Running an incentive cycle](/docs/rewards/running-incentives/) - [Trade schemes](/docs/sales/trade-schemes/) ---- # xMatix Rewards URL: https://xmatix.com/docs/rewards/ Last reviewed: 2026-09-05 xMatix Rewards pays people for performance. An **Incentive Plan** names who is in it — your own people, partner accounts, dealers, branches or roles — sets each member a target per period, and defines in slabs what each level of achievement earns. The incentive engine evaluates a member's achievement against the performance KPIs the platform has accrued and writes the outcome to **Compensation** lines, which are then reviewed and paid outside the module. Rewards is the counterpart to [trade schemes](/docs/sales/trade-schemes/), and the distinction matters: a **trade scheme** rewards the *buyer* on a *document* — a discount or free goods applied to an order or invoice at the moment it qualifies. An **incentive plan** rewards a *member of the plan* for *accumulated performance* over a period, measured against a target set for them personally. Schemes discount transactions; incentives compensate people. The two can meet: an incentive slab can hand out a trade scheme or a discount group as its reward. ## The Rewards app @[guided-image](_img/rewards-overview.png) Open the **App Launcher** (the grid icon next to the logo), search for **Rewards** and select it. The app appears only when your administrator has enabled the Rewards module and granted your security profile access; Claims is a separate module and is not part of Rewards. | Entry | What it holds | | --- | --- | | Home | Landing page | | Schemes | Trade schemes, shared with the Sales module — usable as incentive rewards | | Incentive Plans | Plans, with their periods, members, lines, targets and slabs, on a designed plan page | | KPI Configurations | Definitions of measures that targets can reference | | Compensations | Compensation records and their lines — the evaluated results | | Resources, Resource Groups | The people (and groupings) plans enrol as members | | Reports, Dashboards | The seeded Rewards reports and the Incentives & Targets dashboard | | Settings | The module's settings page | ## How the pieces connect 1. **Define the plan.** Create an Incentive Plan with its Member Type (Partner, Dealer, Branch, Resource or Role), Period Type (Weekly, Monthly or Yearly on the form), Period Start and End dates and validity. Saving generates the plan's **Incentive Periods** between the dates — once, at creation; extending the end date later creates no new periods. Member Type, Period Type and the partner scope lock as soon as the plan has members, targets or lines. 2. **Enrol members and set targets.** Add **Incentive Resources** (the members), then **Incentive Lines** (a qualification rule plus its reward slabs) and **Incentive Targets** (what is measured — sale amount, number of orders, billed hours, a custom KPI, and so on). Each member gets a personal target value per period in the plan page's **Targets by Resources** grid. 3. **Accrue performance.** Performance KPI rows are written when a source document — invoice, order, bill, purchase order, service order, opportunity — is saved with its **Perform KPI Calculation** flag set; each row is stamped with the plan, period and target it counts toward. Nothing runs on a schedule. 4. **Evaluate.** Create a **Compensation** record for the plan, period and account, and add a **Compensation Line** per member. Saving a line runs the incentive engine: it measures the member's achievement against their target, finds the matching slab, and writes the **Incentive Amount** (or gifts, points, a scheme or discount group) onto the line. Nothing generates compensation records or lines for you, and lines do not refresh themselves when later KPIs land — re-save the line to re-evaluate. 5. **Review and pay.** Compensation totals and lines are reviewed on the record, the dashboard and the reports. There is no approval process and no hand-off to Payroll or Finance: payout is recorded by the line's **Is Compensation Received** flag, which you set by hand. ## Section map | Page | What it covers | | --- | --- | | [Incentive plans](/docs/rewards/incentive-plans/) | Plans, periods, members, targets and lines — and how the engine evaluates them | | [KPI configurations](/docs/rewards/kpi-configurations/) | Defining the measures plans can reference, and their limits | | [Compensation](/docs/rewards/compensation/) | Compensation records, lines and slabs — what gets paid and how it is computed | | [Running an incentive cycle](/docs/rewards/running-incentives/) | The period cycle: set targets, accrue performance, evaluate, review | | [Tracking incentives](/docs/rewards/tracking/) | The plan page grids, the Compensations tracker, the dashboard and reports, on web and mobile | | [Configuration reference](/docs/rewards/configuration/) | Administrator reference: validations, period generation, actions, engine triggers | | [Troubleshooting](/docs/rewards/troubleshooting/) | Missing lines, unexpected amounts, and what to check | ## Common questions ### How is an incentive plan different from a trade scheme? A trade scheme evaluates one document and gives its benefit to the customer on that document. An incentive plan evaluates a member's accumulated KPI performance over a period against a target assigned to that member, and writes what they earned to a compensation line. "5% off orders over 50,000" is a [trade scheme](/docs/sales/trade-schemes/); "reps who hit 120% of quarterly quota earn a bonus" is an incentive plan. ### Who can an incentive plan reward? The plan's **Member Type** decides: **Resource** (your own people — optionally narrowed by Member Resource Type or a resource group), **Partner** (partner accounts), **Dealer**, **Branch** or **Role**. Each enrolled member gets their own target values, and achievement is measured against those personal values. A Partner-member plan also derives partner targets for the partner portal automatically. ### Does an incentive plan need approval before it runs? No. The plan's Status offers Draft, Pending Approval and Approved, but no approval process is seeded and the engine does not check the status — treat it as a label your team agrees on. ### Where do people see what they've earned? On the plan page (targets and periods in the grids, results under its Compensations tab), on the Compensations list and records, on the **Incentives & Targets** dashboard and in the seeded Rewards reports. See [Tracking incentives](/docs/rewards/tracking/). ## Related topics - [Trade schemes](/docs/sales/trade-schemes/) - [Rewards product page](/products/rewards/) - [Apps, entities and records](/docs/concepts/apps-entities-records/) ---- # KPI configurations URL: https://xmatix.com/docs/rewards/kpi-configurations/ Last reviewed: 2026-09-05 A KPI configuration is the named definition of a measure — which entity's records are meant to count, which field supplies the value, how the values are meant to aggregate and who is being measured. Incentive plans reference KPI configurations from their targets and from each member's target assignment, and the plan's target grids group by that reference. Separately, **Performance KPI** rows hold the per-document, per-period accruals that the incentive engine sums when it scores a target. Both record types are covered here, together with what each one does and does not drive today. ## Where to find it Open the **Rewards** app and choose **KPI Configurations** in the app navigation. The list view **All KPI Configurations** shows the name, KPI name, parent KPI configuration, active flag, the partner-account and resource field mappings, the trigger object and who created the row; **New** opens the create form. Opening a row shows a **Details** panel with the full definition and two related grids, **All KPI Rules** and **KPI Data**. The entity belongs only to the Rewards app; if your current app is a different one, the same screens open under that app's navigation bar. Creating and editing a KPI configuration needs create/edit access to the KPI Configuration and KPI Rules entities in your [security profile](/docs/administration/security-profiles/), and the Rewards module must be licensed for the tenant. ## Read the KPI Configuration screens @[guided-image](_img/kpi-configuration-list.png) The list is the registry of definitions a plan author can pick from. Check it before creating a new one: two configurations that differ only in name make plan evidence harder to explain, because targets and compensation lines carry the reference, not the description. @[guided-image](_img/new-kpi-configuration.png) The create form is a single page of collapsible sections. Only **Is Active**, **Member Type**, **Date Field Name** and **Include Child Resources** are mandatory; everything else describes the measure and is stored as entered. Field names are typed as the source entity's field names (for example `DocumentDate`, `SalesExecutiveId`) — the form does not validate them against the entity named in **Trigger Object Name**. @[guided-image](_img/kpi-configuration-detail.png) The saved record is the verification surface for a definition a plan references. The related grids are usually empty: KPI Rules only exist if someone added them, and KPI Data is written by nothing in the current release (see below), so an empty grid is not a sign that the configuration is broken. ## The KPI Configuration record The form groups the fields into these sections: | Section | Fields | What they record | | --- | --- | --- | | Information | KPI Name, Is Active | The display name plan authors see, and whether the definition is offered for use. The record's **Name** is the auto-generated document number (`KPIC…`) or a name you type in the list. | | Trigger Configuration Details | Trigger Event, Trigger Object Name, Member Type | The source entity (typed, for example `Order` or `ServiceOrder`), the event meant to feed it (`Scheduled`, `AFTER_INSERT`, `AFTER_UPDATE`, `AFTER_DELETE`) and whom the KPI measures — `Branch`, `Resource` or `Customer`. | | Calculation Fields (Decimal) | Value Field Name (two), Reward Field Name | Which numeric fields on the source record carry the measured value and an optional reward-side value. | | Data Fields | Date Field Name, Item Field Name, Partner Account Field Name, Branch Field Name, Resource Field Name, Account Field Name | The source-record fields that identify when the record counts and which company, branch, resource, account and item it belongs to. | | Filters | Include First N Records, Include Last N Records, Include Child Resources | Sampling limits and whether a resource's subordinates roll up into its figure. | | Result Fields | Value Function, Reward Function, Formula Value Field Name, Formula Reward Field Name | The intended aggregation — Value Function offers `Count`, `Average` and `Formula`; Reward Function offers `Sum` — and the fields a formula result would be written to. | | Rule Criteria | Rule Success Criteria, Rule Success Custom Logic | How the KPI rules combine. The default picklist only seeds `Always (No Criteria)`; custom logic is free text such as `(1 AND 2) OR 3`. | Fields that exist on the record but are not on the default form: **Account Group**, **Partner Account Group** and **Item Group** (scope lookups), **Is Group** and **Parent KPI Configuration** (the hierarchy the list's *KPI Configuration* column shows), **Last Executed** timestamp and **Job Queue**. Add them to the layout through the [form layout designer](/docs/customization/layouts/design-a-form-layout/) if you use them. ### KPI rules A configuration can carry **KPI Rule** rows — each a field name, an operation (`Not Equal`, `Greater Than` or `In`), a value and a sequence number — meant to restrict which source records count. They are created from the **All KPI Rules** grid on the record. ## What a KPI configuration drives today Be precise about this when you explain a payout. In the current release the KPI configuration is a **definition and grouping key**, not an executed calculation: - **Incentive targets** and **incentive resource targets** carry a KPI configuration reference. The plan's **Targets by Resources** and **Targets by KPI** tabs group and filter the target grid by exactly this reference, so a plan with several KPIs gets one set of member targets per KPI — see [Incentive plans](/docs/rewards/incentive-plans/). - **Compensation lines** and **compensation slabs** carry the reference too, so a paid line stays traceable to the KPI it was scored under. - Nothing evaluates the definition. No server code reads Trigger Object Name, Trigger Event, the field-name mappings, the value or reward functions or the KPI rules; no process writes **KPI Data** or **KPI Data Detail** rows, and **Last Executed** is never stamped. The measured figures that actually decide a payout come from Performance KPI rows and the target's **type**, described next. If a plan needs a measure the target types do not offer, the working route is a **Custom KPI** target (below), not a KPI configuration with a formula. ## Performance KPI records The incentive engine scores a target by summing **Performance KPI** rows keyed by plan, period and target, and by the performer — account, partner account, branch or resource — optionally broken down by item and SKU. The rows are written by the Performance KPI engine when a trading document goes through its KPI calculation action: sale orders, sale invoices, purchase orders, bills and opportunities feed it. Each document produces a parent row with document counts and header amounts, plus one item row per item a target selects. The measures a target can read: | Measure family | Fields | | --- | --- | | Counts | Number of orders, invoices, bills, quotes, leads, opportunities, purchase orders, repair orders, service requests | | Sale values | Total sale order amount, total sale invoice amount, total amount, total tax amount | | Quantities | Total sale order quantity, total sale invoice quantity, total quantity | | Purchase side | Total purchase order amount and quantity, total bill amount and quantity | | Service side | Total repair order amount and quantity, total service request amount and quantity | The target's **Incentive Target Type** picks the field: *No Of Sale Orders*, *No Of Unique Invoices*, *No Of Unique Items*, *Sale Order Amount*, *Sale Amount* (invoice amount), *Sale Order Quantity*, *Purchase Order Amount*, *Purchase Order Quantity* and **Custom KPI**, which reads the Performance KPI field named in the target's *Custom KPI Field Name* (the field's technical name, for example `TotalBillAmount`). The engine also recognises *No Of Invoices* and *Invoice Quantity*, but those two labels are not in the default picklist (it offers *Sale Invoice Quantity* instead, which the engine does not match). Any other target type — including the bill, finance, insurance, hours and repair-order types the picklist lists — contributes zero. ## Common questions ### What is the difference between KPI Data and Performance KPI? KPI Data is the aggregated-result table designed for KPI configurations — one row per member and period with a per-document detail breakdown. In the current release nothing writes it, so the grid on a configuration stays empty. Performance KPI is the per-document accrual the incentive engine actually sums when it evaluates a target; if you need to explain an achieved figure, look at the Performance KPI rows for the plan and period, not at KPI Data. ### How does a plan use a custom measure? Set the target type to **Custom KPI** and enter the Performance KPI field to read in *Custom KPI Field Name*. The engine reads that field from every matching Performance KPI row, sums it into the achieved figure and stamps the result on the compensation line as the custom KPI value. Referencing a KPI configuration on the target does not change what is measured — it labels and groups the target. ### Can one KPI configuration serve several plans? Yes. The configuration is independent of any plan; targets and member assignments in any number of plans can reference it, and the plan grids group by it per plan. ### Why is the KPI Configurations tab showing under a different app? The current app is a per-user preference; the KPI Configuration screens open under whichever app you last used, even though the entity belongs to Rewards. Switch to the Rewards app from the app launcher if you want the Rewards navigation around it. ## Related topics - [Incentive plans](/docs/rewards/incentive-plans/) - [Compensation](/docs/rewards/compensation/) - [Running an incentive cycle](/docs/rewards/running-incentives/) - [Import data](/docs/administration/data-management/import-data/) ---- # Running an incentive cycle URL: https://xmatix.com/docs/rewards/running-incentives/ Last reviewed: 2026-09-01 An incentive period runs in four movements: targets are set for each member, performance accrues as KPI records, the engine evaluates achievement into compensation lines, and the results are reviewed and marked paid. This page walks the cycle on a plan that is already built — see [Incentive plans](/docs/rewards/incentive-plans/) for the plan structure itself. ## Prerequisites - An incentive plan with status **Approved** — draft plans are never evaluated. - Members enrolled (incentive resources) matching the plan's member type. - At least one incentive line with targets and [compensation slabs](/docs/rewards/compensation/). ## Procedure ### Step 1 — Set targets for the period Give every member a target value for the period. The incentive plan page offers two routes: - **The target grids.** The plan page's *Targets by Resources* tab is an editable grid — members as rows, periods as columns, a KPI dropdown to switch measures. Type the values into the cells and **Save**; edits batch into one update. The *Targets by KPI* tab shows the same assignments pivoted by measure. - **The plan page actions.** **Create Incentive Target** defines a new measure, **Create Incentive Line** adds a qualification line, and **Create Compensation Slab** adds a payout band — the plan page's slab builder walks the same three pieces together as a form. Individual member assignments are incentive resource target records: one member, one target, one period, one value. A member without an assignment — or with a value of zero — cannot qualify, so a complete grid is the checkpoint before the period starts. ### Step 2 — Performance accrues During the period, performance builds up as **Performance KPI** records tied to the plan, the period and the target — each row carrying who performed (account, partner, branch or resource, per the plan's member type), optionally which item, and the counts, amounts and quantities the [target types](/docs/rewards/incentive-plans/) read. These records arrive from your transaction flows or are loaded in bulk — see [Import data](/docs/administration/data-management/import-data/) — and the engine evaluates whatever is present at evaluation time, so KPI completeness is what makes results trustworthy. ### Step 3 — Evaluate into compensation lines Evaluation is triggered by saving a compensation line. Create a compensation record for the plan and period, add a line per member (naming the member, plan and period), and save. On save the engine: 1. Confirms the plan is Approved and loads its lines, the member's target assignments and the period's KPI records. 2. Sums the matching KPI records per target and stamps the achieved figures onto the line. 3. Computes achievement percentages, qualifies slabs, and writes the reward — amount, gifts, discount group or scheme. To re-evaluate — after late KPI data or a slab correction — save the line again; the engine recomputes from current data and replaces the previous result. ### Step 4 — Review and close out Review the compensation record: the header carries the total incentive amount across its lines. Per line, check the achieved figures against expectations (they show exactly what the engine counted), record an **override incentive amount** where a reviewed figure should stand next to the computed one, set the line's status per your process, and mark **is compensation received** once the payout reaches the member. The [Rewards reports](/docs/rewards/tracking/) give the period-wise and per-member views for sign-off. ## Expected result Every eligible member has a non-zero target for the intended period, the KPI population is complete through the cutoff, and saving each compensation line produces achieved values that can be traced to those records. The compensation header equals the reviewed line totals, overrides remain explicit rather than replacing the computed evidence, and **is compensation received** is set only after payout. If a result is unexpected, compare member eligibility, period boundaries, target assignment and KPI completeness in that order before re-saving the line. ## Common questions ### When exactly does evaluation run? When a compensation line is saved — creation and updates both trigger it. There is no waiting on a schedule: the moment the line for a member, plan and period is saved, the result is on it. That also means nothing is evaluated until compensation lines exist for the period. ### Targets changed mid-period — what happens? Nothing retroactive on its own. Evaluation always reads the *current* target values and KPI data, so the next save of each affected compensation line recomputes against the new targets. Re-save the period's lines after any target correction. ### Can I run the same plan for the next period without rebuilding it? Yes — periods were generated for the plan's whole date range when it was created. Set the members' target values for the next period (a new column in the target grid), let KPI records accrue, and create that period's compensation lines when it closes. ## Related topics - [Incentive plans](/docs/rewards/incentive-plans/) - [Compensation](/docs/rewards/compensation/) - [Tracking incentives](/docs/rewards/tracking/) - [Troubleshooting](/docs/rewards/troubleshooting/) ---- # Tracking incentives URL: https://xmatix.com/docs/rewards/tracking/ Last reviewed: 2026-09-05 Incentives are tracked in four places: the incentive plan page (targets, definitions and results together), the **Compensations** list and records (the evaluated results across plans), the **Incentives & Targets** dashboard, and the seeded Rewards reports. Nothing here needs building — the plan page ships as a designed layout with purpose-built widgets, and the dashboard and reports are seeded. Two facts shape how you read all of them: numbers move only when something is saved (a source document with its KPI flag, or a compensation line), and the platform stores the earned amount but not an achievement percentage — the percentage is computed in memory when a line is evaluated and is not persisted. ## The Compensations tracker @[guided-image](_img/rewards-tracking-context.png) Open the **Rewards** app (App Launcher → search *Rewards*) and choose **Compensations**. Each record ties a plan, an incentive period and an account to a **Total Incentive Amount**; open it for the **Compensation Lines** — one per member — carrying **Achieved Value**, **Value** (the target), **Incentive Amount**, **Override Incentive Amount**, **Gifts** and **Gift Points**, **Is Compensation Received**, **Status** and the KPI roll-up columns (sale amount, number of invoices, unique items, billed hours and so on) the engine copied in. Track progress by filtering to one plan and period, reconciling the member count against the plan's members, then comparing the total with its lines. A missing record points upstream — compensation records are created by an operator, not generated — and an unexpected amount is explained line by line against the plan's slabs. Lines carry a Status of Draft or Rejected only; there is no approved or paid state. Payout is recorded by ticking **Is Compensation Received** on the line by hand — no service sets it, and nothing flows from here into Payroll or Finance. ## The incentive plan page The plan's detail page is organised into tabs: - **Targets by Resources** — the target grid: members as rows, incentive periods as columns, each cell a member's target value for that period, with a dropdown to switch between KPI configurations and a search box over rows. Cells are editable; edits collect as you type and persist together on **Save**, and **Refresh** re-reads. Lookup values render as names, and period columns carry their dates. - **Targets by KPI** — the same assignments for one member at a time: pick the member in the selector, and the grid shows KPI configurations as rows and periods as columns ("Incentive KPI Target : "). Use it to read one person's measures across the timeline; use Targets by Resources for bulk entry. - **Compensations** — the plan's compensation records and lines, where evaluated results land after each [incentive cycle](/docs/rewards/running-incentives/). - **Related** — the plan's definition widget: add an incentive line (sequence, title, qualification criteria, reward applicability), then per line a condition-and-reward slab builder whose fields adapt to the selected types, and a collapsible list of saved lines with edit and delete. ## The Incentives & Targets dashboard **Dashboards** in the Rewards app includes the seeded **Incentives & Targets** dashboard, filterable by incentive period and branch. Its tiles show Target Achievement, Reps vs Target, Incentive Payable (the sum of compensation lines' Incentive Amount), Active Plans, KPI Records and Scheme Budget Utilised; its charts include Attainment by Rep as a percentage of target with a 100% reference line, Target vs Actual by Branch, Targets by Plan and Rep, Attainment Spread by Branch, Incentive Payable by Period, Compensation Lines by Status and KPI Value by Month, plus a Rep × Period actuals table and two embedded reports. Attainment here is computed live from performance KPI rows against target values — it is the one place an achievement percentage is visible. ## Rewards reports **Reports** in the Rewards app includes a seeded **Rewards** folder: | Report | Shows | | --- | --- | | Incentive Plan Report | Plans with their periods and members | | Incentive Target with Incentive Plan | Targets in plan context, grouped by partner | | DMS Incentive Target with Account | Targets with their account context | | New KPIs Report | Performance KPI records by period, grouped by partner | | New KPIs with Incentive Target Report | KPI records joined to the targets they feed | | KPIs with Account Report | KPI performance grouped by period, by account | | KPIs with Incentive Plan Report | KPI performance in plan context | | Periods wise Incentive | Incentive results period by period | | Quartely Incentive Report | The quarterly incentive view, grouped by period and partner | | Resource Compensation Report | Salary-structure assignments — a Payroll record that shares the name, not incentive results | Reports follow the platform's report tooling — filter, group and export like any other report. ## What refreshes the numbers - Saving an invoice, order, bill, purchase order, service order or opportunity with its **Perform KPI Calculation** flag set writes or updates the performance KPI rows — this is where attainment comes from. - Saving a **Compensation Line** runs the engine for that line and rewrites its Incentive Amount and KPI roll-ups. Existing lines do not recompute when later KPIs land; re-save them. - Dashboards and reports query live, so they reflect the rows above immediately. - Nothing runs on a schedule, and no notification is sent when a target is reached or a line is evaluated. ## On mobile The mobile app registers the same two purpose-built widgets as the web under the same component names — the target grid (first column frozen, horizontal scroll) and the slab builder — so the **Targets by Resources** grid and the Related tab's builder behave identically, with matching field names and saved payloads: a target entered on a phone is the record a manager sees in the web grid. The seeded plan layout also references a pivot-grid and a plan-table widget that neither platform registers, so those regions render nothing on either; the Targets by KPI view is the target grid itself, pivoted for one member. Dashboards are read in the mobile Dashboards area. See [Using the mobile app](/docs/getting-started/mobile-app/). ## Common questions ### Can targets be edited straight from the grid? Yes — that is the grid's purpose. Type into the cells; pending edits are highlighted and saved together with **Save**, so filling a whole period column is one batch, not one save per member. The KPI dropdown scopes which measure's assignments you are editing. ### Do mobile users see the same numbers as web users? Yes. Both platforms render the same layout over the same records with the same widgets, so there is no separate mobile dataset to reconcile. ### Where does a member see what they earned? On the plan page's Compensations tab, on the Compensations list and record, and in the *Periods wise Incentive* and *Quartely Incentive Report* reports. Each compensation line shows the achieved figures it was computed from, so "what did I earn and why" is one record — but there is no personal self-service view; members see what their security profile lets them open. ## Related topics - [Running an incentive cycle](/docs/rewards/running-incentives/) - [Compensation](/docs/rewards/compensation/) - [Using the mobile app](/docs/getting-started/mobile-app/) ---- # Troubleshooting rewards URL: https://xmatix.com/docs/rewards/troubleshooting/ Last reviewed: 2026-09-01 Incentive evaluation is deterministic: the engine reads the plan, the member's target values and the period's Performance KPI records, and writes what follows. When a result looks wrong, one of those inputs is wrong — this page maps the symptoms to the input to check. ## A compensation line shows no reward Work down this list — evaluation stops silently at the first missing piece: 1. **Plan status** — only **Approved** plans are evaluated. A draft or unapproved plan writes nothing, with no error. 2. **Line references** — the compensation line must carry the incentive plan, the incentive period *and* the member (incentive resource). A line missing any of the three is skipped. 3. **Target assignment** — the member needs an incentive resource target for the line's target. No assignment, no evaluation of that target for that member. 4. **Target value** — an assignment with a value of zero can never qualify: achievement is a percentage of the member's own value. 5. **KPI data** — Performance KPI records must exist for that plan and period, tied to the target, and must match the member: a resource plan matches on the record's resource, a partner plan on its partner account, a branch plan on its branch, a customer plan on its account. Records attributed to the wrong party sum to zero. 6. **Target filters** — an item, item group or account filter on the target excludes KPI records that don't carry the matching reference (item group matching is SKU-aware). 7. **Slab coverage** — the achievement percentage must fall inside some slab's from–to band. Gaps between bands, or a top band that ends too low, qualify nothing. 8. **Line criteria** — with **All Conditions Are Met**, one failing target fails the line; with custom logic, check the `{N}` positions refer to the sequence numbers you think they do. A line whose filter criteria is **Always (No Criteria)** qualifies without evaluating targets — but since rewards attach to slabs qualified *through* targets, such a line writes no slab reward. If a line is meant to pay, give it targets. ## The amount is not what was expected - **The percentage is floored.** Reached ÷ target × 100 is rounded down before slab matching — 80.9% is 80, and lands in a band ending at 80, not the one starting at 81. - **First matching slab wins.** Slabs are checked in sequence order and matching stops at the first hit. Overlapping bands pay the earlier slab, not the richer one. - **Open-ended bands.** A *to* percentage left empty (or zero) extends the band upward without limit — an over-generous top band catches everything above it. - **Per-unit types multiply.** Amount Per Unit pays the per-unit amount × the achieved value of the target the slab qualified through; the Incremental variant pays double that. A value-based target makes "per unit" mean per unit of value. - **Percentage On Value keeps the higher figure.** It replaces the line's incentive amount only when the computed amount is higher — a smaller recomputation does not lower an amount another slab already wrote. - **Re-evaluation replaces.** Every save recomputes from current data. If KPI records or targets changed since the last save, the new result is not a bug — it is the current truth. Use the override incentive amount to preserve a reviewed figure. ## The achieved figures on the line look wrong The engine stamps what it counted onto the line — use those figures to localise the problem: - **A figure is zero but performance exists** — member mismatch (the KPI records name a different resource/partner/branch/account than the member's enrolment) or a target filter excluding them. - **A figure is too high** — the KPI records for the period include rows you did not expect; the achieved figure is the sum of everything that matched. Check for duplicate or misdated KPI rows in that period. - **Unique counts surprise you** — *No Of Unique Invoices* counts distinct accounts across the matching KPI records, and *No Of Unique Items* distinct items; they are distinct-counts, not row-counts. - **Custom KPI reads zero** — the target's custom KPI field name must exactly name a field carried by Performance KPI records; a misspelt name reads as zero. ## Common questions ### Nothing at all is being evaluated for a period — why? Because nothing asked to be: evaluation runs when compensation lines are saved, and a period with no compensation lines has simply never been evaluated. Create the compensation record and its lines for the period — see [Running an incentive cycle](/docs/rewards/running-incentives/). ### How do I force a recalculation? Save the compensation line again. Every save re-evaluates from the current plan, targets and KPI data and replaces the previous result. There is no cache to clear and no job to wait for. ### Who should fix a plan-level problem — the user or the admin? Target values and compensation lines are user-fixable. Plan structure — member type, period type, scoping — locks once the plan has members or targets, so structural mistakes need an administrator and usually a new plan; the [configuration reference](/docs/rewards/configuration/) lists the exact validations and locks. ## Related topics - [Running an incentive cycle](/docs/rewards/running-incentives/) - [Compensation](/docs/rewards/compensation/) - [Configuration reference](/docs/rewards/configuration/) - [Incentive plans](/docs/rewards/incentive-plans/) ---- # Role guide: developer URL: https://xmatix.com/docs/roles/developer/ Last reviewed: 2026-09-06 This guide is for the person handed the requests configuration can't satisfy. Your xMatix work lives at the top of the customization ladder: expressions and business rules where declarative tools still reach, scripts and workflows where they don't, and the developer surface — data API, MCP endpoint, CLI — when xMatix has to talk to the rest of the stack. ## Where you work Almost everything you build is authored inside **Setup**, in two studios: | Setup area | What you do there | | --- | --- | | **Design Studio → Entities** | The data model: entities, fields, relations, record types, views, actions and layouts — the contract every script, rule, API call and MCP tool runs against | | **Process Studio → Business Rules** | Declarative save-time logic: conditions, set-value and validation actions, ordered and prioritized per entity | | **Process Studio → Scripts** | Automation scripts: C# lifecycle hooks and server actions, each with versions and an active version | | **Process Studio → UI Components** | Custom components when the standard widgets cannot express the experience | | **Process Studio → Workflows** | Long-running, multi-step orchestration in the visual designer | | **Process Studio → Approvals** | Approval processes and their steps | | **Process Studio → Integrations / Sync Profiles** | Connected systems and the sync engine's profiles | | **Platform Operations → Monitoring** | Jobs, Tracing, Audit Trail, Message Log and the Sync Monitor — where you read what your logic actually did | @[guided-image](_img/developer.png) The Scripts page is the register of every automation script in the tenant. Each row carries a name, a description, a lifecycle **Status** and an **Active Version** — a script only executes when it is active *and* a version has been set active, which is why the two columns sit side by side. Before you create anything here, prove that a business rule or workflow cannot meet the requirement; when code is warranted, describe it precisely, version changes deliberately and keep the active version traceable to reviewed source. Outside Setup, the developer surface is the same platform reached from your own tools: the **data API** (REST over every entity, invoking the same actions and firing the same automation as the UI), the **MCP endpoint** (the platform's tools exposed to AI clients) and the **CLI** (a git-friendly round trip of scripts, rules, workflows, dashboards and metadata). None of them grants more than the signed-in user is permitted. ## Access you need Setup areas are gated by named capabilities, granted per security profile on the profile's **Entitlements** tab (Setup → Access Control → Profiles). The seeded **SystemAdmin** profile holds the whole catalog; a dedicated developer profile needs the keys for the areas it works in: | Area | Capability key | | --- | --- | | Design Studio → Entities, Localization | `setup.metadata.model.manage` | | Apps, app pages, mobile app | `setup.metadata.apps.manage` | | Business Rules | `setup.automation.businessrules.manage` | | Scripts | `setup.automation.scripts.manage` | | Workflows | `setup.automation.workflows.manage` | | UI Components | `setup.automation.customcomponents.manage` | | Approvals | `setup.metadata.approval.manage` | | Integrations, Sync Profiles, Sync Monitor | `setup.integration.manage` | | Jobs, Tracing | `setup.diagnostics.jobs.view`, `setup.diagnostics.tracing.view` | | Data Import, Data Export | `setup.data.import.manage`, `setup.data.export.manage` | A capability belongs to a feature, so the profile must hold the owning feature too, and a Setup entry simply disappears from navigation when its capability is missing. Capabilities do not replace entity grants: to read or write the records your script or API call touches, the identity you test with still needs the ordinary [profile grants](/docs/administration/security-profiles/) on those entities, and API, MCP and CLI calls inherit exactly that identity's rights. The developer surface has no separate license; it follows the products your organization has [licensed](/docs/administration/licensing/). ## Your path 1. [The customization ladder](/docs/concepts/customization-ladder/) — where code sits, and why it's the last resort, not the first. 2. [What runs when you save a record](/docs/concepts/execution-order/) — the execution pipeline your logic plugs into; read this before writing any of it. 3. [The data model](/docs/customization/data-model/) — entities, fields, relations and record types: the schema everything targets. 4. [Expressions: formulas and query filters](/docs/customization/expressions/) — the shared expression language used across rules, filters and formulas. 5. [Business rules: automating the save](/docs/customization/business-rules/) — declarative save-time logic; exhaust this before scripting. 6. [Your first automation script](/docs/customization/automation-scripts/quickstart/) — the script runtime, from zero to a working handler. 7. [Build a workflow in the visual designer](/docs/customization/workflows/) — long-running, multi-step orchestration beyond a single save. 8. [xMatix developer documentation](/docs/developer/) — the section index for the data API, the MCP endpoint and the CLI; several pages there (the CLI set among them) are in preview, so start from the index. 9. [The xMatix data API](/docs/developer/data-api/) — programmatic access to records from outside the platform. 10. [The MCP endpoint](/docs/developer/mcp-server/) — exposing your tenant's data and actions to AI tooling. ## Day to day Real developer work here starts with placement, not code: given a request, [the ladder](/docs/concepts/customization-ladder/) and [the execution order](/docs/concepts/execution-order/) decide whether it's an [expression](/docs/customization/expressions/), a [business rule](/docs/customization/business-rules/), a [script](/docs/customization/automation-scripts/quickstart/) or a [workflow](/docs/customization/workflows/) — and everything you build runs inside that same save pipeline, so debugging means reading it. When a module team reports that an action refuses — a fulfilment that won't allocate, a service order that won't complete, a bill the match blocks — the module troubleshooting pages ([sales](/docs/sales/troubleshooting/), [service](/docs/service/troubleshooting/), [procurement](/docs/procurement/troubleshooting/), [warehouse](/docs/warehouse/troubleshooting/), [inventory](/docs/inventory/troubleshooting/), [support](/docs/support/troubleshooting/), [payroll](/docs/payroll/troubleshooting/)) list the built-in refusals, so you can tell a product guard rail from your own rule before opening a script. Integration work moves you to the [developer section](/docs/developer/): the [data API](/docs/developer/data-api/) for records in and out, the [MCP endpoint](/docs/developer/mcp-server/) for AI tooling, and the CLI — documented in preview from the section index — for scripting the platform itself. ## Common questions ### Business rule, script or workflow — how do I choose? By reach, then by lifetime: if declarative [business rules](/docs/customization/business-rules/) can express it, stop there; a single-save behavior beyond them is a [script](/docs/customization/automation-scripts/quickstart/); anything long-running or multi-step is a [workflow](/docs/customization/workflows/). [The customization ladder](/docs/concepts/customization-ladder/) is the fuller decision guide. ### Something fires on save and I don't know what — how do I debug it? Read the pipeline in order — [What runs when you save a record](/docs/concepts/execution-order/) lists every stage (validations, rules, scripts, workflows) in the sequence they execute, which is usually enough to name the culprit. Then check the Business Rules register for overlapping enabled rules on the entity, and the Scripts register for an active version you did not expect. ### I can see Process Studio but not the Scripts entry — why? Your profile lacks `setup.automation.scripts.manage`, or holds it without the owning feature; Setup hides entries the API would refuse. Ask an administrator to grant the capability on the profile's **Entitlements** tab, then refresh your session. ### How do I move what I build between environments? With the CLI's metadata tooling — the CLI docs are in preview, so start from [the developer section index](/docs/developer/) for the current state of workspaces, seed-packs and CI recipes. ## Related topics - [Entity behavior](/docs/customization/entity-behavior/) — views, validations, actions and mappings on an entity. - [Outbound integration](/docs/integrations/outbound/) — how data leaves xMatix, webhook by webhook. - [Extending Sense with your own capabilities](/docs/sense-ai/extending-sense/) — teaching the platform's AI your custom operations. - [Troubleshooting the developer surface](/docs/developer/troubleshooting/) — sign-in, workspace, push and API symptoms. - [Role guide: tenant administrator](/docs/roles/tenant-administrator/) — the other half of the customization conversation. ---- # Role guide: dispatch manager URL: https://xmatix.com/docs/roles/dispatch-manager/ Last reviewed: 2026-09-06 This guide is for the person who decides who goes where. Your xMatix day is the allocation console: incoming work on one side, resources and their calendars on the other, and your job is matching them — by skill, by capacity, by location — while keeping promises the business already made. When routing runs itself, you handle the exceptions. ## Where you work The **Allocation Console** is an app page your administrator places in an app and points at one kind of work record — visit plans, cases, service orders or another entity — so the bar it sits on depends on your tenant. In the field-sales configuration shown below it lives in the **Field Sales** app beside Visit Plans, Route Planner, Route Optimization, Visits, Orders, Visit Routes, Accounts and Resources; a service configuration places it in the **Service** app next to Service Orders. Whichever app hosts it, the console has the same parts: a **Map / Gantt / Board** toggle, **scope** chips, a **Today / Week / Month** horizon with an **Unassigned** filter, a health strip, a resource pane and the live map. Everything it does is deterministic — drags write assignments, drops write schedule times, **Optimize day** fills free slots by fixed rules — and nothing is placed by AI. @[guided-image](_img/dispatch-manager.png) Read the console in this order: scope, then horizon, then the health strip. **Resources**, **Live now**, **Tracking**, **Off grid**, **Plans today** (with the unassigned remainder) and **Coverage** are the morning's exceptions list; a console that looks empty is more often scoped to the wrong branch or date than genuinely idle, and the console tells you when it has capped what it loaded. Only then move work — on the Board for who-does-what, on the Gantt for when, on the Map for where. The work itself is created and executed in the Service module: the [service order](/docs/service/service-orders/) is the job card, [time sheets](/docs/service/timesheets/) record the labour, [checklists](/docs/service/checklists/) the inspection, and the technician's day runs on mobile. Field Service is the allocation layer on top — it decides *who* and *when*, then follows the resource through the day. ## Access you need Two grants make a dispatcher. First, the console page itself: app pages are allowlisted per security profile, so your profile must hold view access to the hosting app and to the Allocation Console page. Second, the work entity: placing a job is an update to the record (and often a change of owner), so you need **Update** — and **Assign** where ownership moves — on visit plans, service orders or cases, with **View All** if you dispatch work you do not own. There is no shipped dispatcher profile; of the seeded profiles only the administrative ones carry these entities in full, so your administrator builds one. Live positions on the Map appear only where your organization has enabled location tracking on the mobile app, and the travelled path is subject to the same setting. If the page or an entity is missing from your navigation, start with [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/). ## Your path 1. [xMatix Field Service](/docs/field-service/) — the product overview; where Field Service ends and Service begins. 2. [The dispatch console](/docs/field-service/dispatch-console/) — your home screen: scoping, the Board, the Gantt, Optimize day and the Map. 3. [Skills, capacity and work routing](/docs/field-service/skills-and-routing/) — the eligibility ladder and routing models that place queued work on their own. 4. [Automatic owner assignment](/docs/field-service/assignment-rules/) — the rules that assign owners before you ever see the job. 5. [Resource availability and slot holds](/docs/field-service/availability/) — dated availability, branch-slot booking, holds, and why a technician still shows on the Gantt. 6. [The service order lifecycle](/docs/service/service-orders/) — the record every dispatched service job lives on: lines, status and the Work Completed gate. 7. [The technician's day](/docs/field-service/technician-day/) — what your decisions look like from the van, and which actions need a live connection. 8. [Location and the travelled path](/docs/field-service/location-and-proof/) — seeing where the team actually went. 9. [The supervisor console](/docs/engagement/supervisor/) — live oversight of your team's calls, where telephony is in use. ## Day to day The morning starts on the [console](/docs/field-service/dispatch-console/): overnight work has been placed by [routing](/docs/field-service/skills-and-routing/) and [assignment rules](/docs/field-service/assignment-rules/), so your first pass is the exceptions — the unassigned, the overbooked, the job whose slot no longer holds against [availability](/docs/field-service/availability/). Through the day you rebalance as reality drifts: a job overruns (the [time sheet](/docs/service/timesheets/) shows work paused or still open), a technician calls in sick, an urgent ticket jumps the queue. A [service order](/docs/service/service-orders/) that cannot be completed usually names its own reason — [Troubleshooting service](/docs/service/troubleshooting/) lists the refusals — and the [travelled path](/docs/field-service/location-and-proof/) tells you how the field is really doing, not just what the board says. ## Common questions ### A job didn't get assigned automatically — why? Usually no resource passed the ladder: not in the queue's resource group, not linked to a user, not marked available, no matching skill name, or no capacity left. Check the job against [skills and routing](/docs/field-service/skills-and-routing/) and the [assignment rules](/docs/field-service/assignment-rules/) in force; [Troubleshooting field service](/docs/field-service/troubleshooting/) lists the frequent causes. ### Can two jobs end up in the same slot? Where the booking path uses holds, a hold reserves the slot from the moment it is offered; not every channel uses holds, and the console's drags do not check them. [Resource availability and slot holds](/docs/field-service/availability/) explains which paths do what. ### Why is a technician on leave still shown on the Gantt? Because the console shows the resource and marks availability separately — and the resolver treats any leave row not Rejected or Cancelled as leave, while half-day and absent values are not excluded the same way. Read the markers before dragging; [The dispatch console](/docs/field-service/dispatch-console/) spells out the current behaviour. ### Can I see where a technician is right now? You can see the last known position and the travelled path, subject to what your organization has enabled — the Map's *Live now* and *Off grid* counters tell you how much of the fleet is actually reporting. [Location and the travelled path](/docs/field-service/location-and-proof/) covers what's captured and who can see it. ## Related topics - [Field service configuration reference](/docs/field-service/configuration/) — resources, skills, resource groups and the console page settings. - [Service checklists](/docs/service/checklists/) — what the technician fills in on site. - [Dashboards in xMatix](/docs/analytics/dashboards/) — tracking first-time-fix, utilization and backlog. - [Role guide: field service technician](/docs/roles/field-service-technician/) — the day you're scheduling. ---- # Role guide: field sales representative URL: https://xmatix.com/docs/roles/field-sales-representative/ Last reviewed: 2026-09-02 ## Native workspace evidence This role works primarily in the React Native visit workspace. A phone-width web Visit form is not the native layout and cannot evidence its offline queue, visit widgets or device capture controls, so this guide deliberately stays text-only until an authenticated demo2 mobile-build capture is available. On the device, treat partner account, branch and outlet as a pre-flight check before capturing orders, photos or checklist responses, then verify the outbox after an offline save instead of submitting the visit again. This guide is for the rep who works a beat: your xMatix day starts and ends on the mobile app — mark attendance, open the day's visit plan, work each outlet through its checklist, take orders (or sell off the van), and let the app sync whenever the network allows. You may go hours without signal; the app is built for that. ## Your path 1. [Signing in to xMatix](/docs/getting-started/sign-in/) — your first sign-in from the invitation email. 2. [Using xMatix on mobile](/docs/getting-started/mobile-app/) — install the app and get it set up. 3. [How the mobile app is organized](/docs/mobile/navigation/) — where your work lives on the phone. 4. [Visits and the field day](/docs/field-sales/visits/) — the visit is the unit of your day; learn its shape. 5. [Complete a visit on mobile](/docs/field-sales/visits/complete-a-visit/) — the core procedure, step by step. 6. [Checklists, tasks and visit activities](/docs/field-sales/checklists-and-tasks/) — the in-outlet work a visit asks of you. 7. [Creating a sales order](/docs/sales/orders/create-order/) — taking the order while you're standing in the outlet. 8. [Van sales: load, sell, settle](/docs/field-sales/van-sales/) — if you carry stock, this is your load-out and settlement loop. 9. [Mobile attendance](/docs/field-sales/attendance/) — marking the start and end of your working day. 10. [Working offline: sync status and recovery](/docs/mobile/working-offline/) — what the sync indicators mean and how to recover. ## Day to day Mark [attendance](/docs/field-sales/attendance/) when the day starts, then open today's route — it comes from a [visit plan](/docs/field-sales/visit-plans/) someone scheduled for you. At each outlet you [complete the visit](/docs/field-sales/visits/complete-a-visit/): work the [checklist](/docs/field-sales/checklists-and-tasks/), capture what the outlet needs, and [create the order](/docs/sales/orders/create-order/) — or invoice straight off the vehicle in [van sales](/docs/field-sales/van-sales/). Between outlets, glance at the [sync status](/docs/mobile/working-offline/); everything you captured uploads on its own when signal returns. ## Common questions ### Can I work with no signal? Yes — the whole visit flow works offline, and your captures queue up and sync when the network returns. [How offline-first mobile works](/docs/concepts/offline-mobile/) explains the model; [Working offline](/docs/mobile/working-offline/) shows the indicators and what to do if something won't sync. ### Where do the photos and readings I capture go? Onto the record you captured them against — visit, outlet or order — and up to the server on the next sync. [Capture data in the field](/docs/mobile/capturing-data/) covers photos, signatures, locations and forms. ### The app is misbehaving — frozen list, stuck sync, missing screen? Start with [Troubleshooting the mobile app](/docs/mobile/troubleshooting/) — most fixes are a refresh or a re-sync, not a reinstall. ## Related topics - [xMatix Field Sales](/docs/field-sales/) — the full product section, including planograms and prospecting. - [Beats and routes](/docs/field-sales/routes/) — how the route you're driving got planned. - [Sense on mobile](/docs/mobile/sense-on-mobile/) — asking the built-in assistant for help in the field. - [Role guide: sales manager](/docs/roles/sales-manager/) — the person reviewing your orders. ---- # Role guide: field service technician URL: https://xmatix.com/docs/roles/field-service-technician/ Last reviewed: 2026-09-02 ## Native workspace evidence This role works in the React Native service-order workspace. A responsive web Service Order list does not prove the native saved-view controls, local availability or offline status changes, so this guide has no screenshot until an authenticated demo2 mobile-build capture is available. On the device, confirm the saved view and filters before treating a job as missing; after opening the correct order, verify customer, location, appointment and status before updating the sequence, checklist, time, parts and proof that the dispatcher and back office will read. This guide is for the technician in the van. Your xMatix day arrives as assigned work on the mobile app: drive to the job, work the checklist, log your time and parts, capture proof, and move to the next one — with the app carrying you through basements and dead zones where there's no signal at all. ## Your path 1. [Using xMatix on mobile](/docs/getting-started/mobile-app/) — install the app and get signed in. 2. [The technician's day](/docs/field-service/technician-day/) — the anchor page: your schedule, your jobs, your statuses. 3. [The service order lifecycle](/docs/service/service-orders/) — the record behind every job, and what each status change means. 4. [Checklists on service orders](/docs/service/checklists/) — the structured steps a job asks you to complete. 5. [Recording labour with time sheets](/docs/service/timesheets/) — logging the hours the job took. 6. [Capture data in the field](/docs/mobile/capturing-data/) — photos, signatures and readings as proof of work. 7. [Working offline: sync status and recovery](/docs/mobile/working-offline/) — what the sync indicators mean and how to recover. ## Day to day Open the app and your day is already there — [The technician's day](/docs/field-service/technician-day/) shows the jobs in order. At each site you move the [service order](/docs/service/service-orders/) through its statuses, work the [checklist](/docs/service/checklists/), [capture](/docs/mobile/capturing-data/) the photos and the customer's signature, and log your hours on a [time sheet](/docs/service/timesheets/). No signal on site changes nothing: finish the job as normal and it [syncs](/docs/mobile/working-offline/) on the drive out. ## Common questions ### Can I complete a job with no signal? Yes — statuses, checklists, captures and time all work offline and upload when the network returns. [How offline-first mobile works](/docs/concepts/offline-mobile/) explains why you can trust it; [Working offline](/docs/mobile/working-offline/) covers the indicators and recovery. ### Where does my next job come from? From the dispatcher — work is routed by skills and capacity, and [automatic assignment rules](/docs/field-service/assignment-rules/) decide the owner. If your schedule looks wrong, that conversation starts at the [dispatch console](/docs/field-service/dispatch-console/), not on your phone. ### Where do I verify what was billed from the job? Review the service-order line's pending invoice quantity, posting type and generated document links. [Invoicing a service order](/docs/service/estimates-and-invoicing/) explains full versus selective generation and why covered work may become a claim instead of a customer invoice. ## Related topics - [xMatix Field Service](/docs/field-service/) — the full product section your work runs on. - [Service recommendations](/docs/service/service-recommendations/) — upsell prompts that may appear on your jobs. - [Troubleshooting the mobile app](/docs/mobile/troubleshooting/) — first stop when the app misbehaves. - [Role guide: dispatch manager](/docs/roles/dispatch-manager/) — the other side of your schedule. ---- # Role guide: finance user URL: https://xmatix.com/docs/roles/finance-user/ Last reviewed: 2026-09-06 This guide is for the accountant. In xMatix, most entries post themselves — invoices, bills, receipts, payroll runs and stock movements all write the ledger when their posting action runs — so your day is what's left: the manual journals, the payments to apply, the bank to reconcile, the statements to read, and at month-end, the close. ## Where you work The first-party **Finance** app carries the documents and the finance-only screens on one bar: **Invoices**, **Bills**, **Expenses**, **Payments**, **Journals**, **Adjustments** (credit and debit notes), **Banking** (bank transfers, statements, cheque transactions and registers), **Chart of Accounts** and the **Statements** screens, plus Reports and Dashboards. Bank reconciliation has its own **Banking** app entry, and the masters that decide how things post — accounting books, fiscal periods, valuation policies — sit in the **Finance Setup** list. Documents that originate elsewhere are read in their own apps and reflected here: a supplier [bill](/docs/procurement/bills/) is raised in Procurement, a [payroll run](/docs/payroll/payroll-runs/) posts its accrual journal from the Payroll app, a customer [invoice](/docs/sales/invoicing-and-payments/) is generated from a sales order, and stock movements post from Inventory and Warehouse — each leaves a journal you can open from the Journals register. @[guided-image](_img/finance-user.png) The **All Journal** view is your evidence register. The cards split it by posting state and provenance — posted against draft, manual against auto-generated — and total the posted debit and credit values; the columns underneath locate each journal by document date, partner account and branch, and establish where it came from through **Journal Type Name** and **Source Entity Name**. Read those two together: *Manual* is the create-form default and document-generated draft journals can carry it too, so the source entity and narration, not the type, tell you whether a person keyed the entry. Posted journals are immutable; the supported correction is a linked reversal. ## Access you need Finance permissions follow the same profile model as everything else, with posting kept separate from editing: **Post**, **Reverse**, **Close Period** and the document posting actions are entity actions a profile grants individually, so an accountant can be allowed to draft and edit journals without being allowed to post them, and only a controller may close or reopen a period. A working finance profile grants read, create and update on Journal, Journal Line, Payment, Bank Account, Bank Statement and the adjustment documents, read on GL Account, Fiscal Period and Accounting Book, and the posting actions the person is trusted with. No finance profile ships in the seed — the seeded profiles that carry these entities are the administrative ones — so your administrator builds it; Finance is licensed as its own product. A closed or locked fiscal period refuses postings regardless of permission, which is the point of the close. If a screen or button is missing, start with [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/). ## Your path 1. [xMatix Finance & Accounting](/docs/finance/) — the product overview; the mental model of journals, document-specific posting and statements read from the posted ledger. 2. [Chart of accounts, books and periods](/docs/finance/chart-of-accounts/) — the structure everything posts into. 3. [Working with journals](/docs/finance/journals/) — finding an existing journal, the manual entry, balanced lines, posting, reversal and recurring journals. 4. [AR and AP subledgers](/docs/finance/subledgers/) — how documents post, open items and settlement, ageing, and reconciling to the control accounts. 5. [Recording and applying payments](/docs/finance/payments/) — money in and out, matched to what it settles. 6. [Banking in xMatix Finance](/docs/finance/banking/) — bank accounts, statements, transfers, the cheque register and payment batches. 7. [Reconciling a bank account](/docs/finance/banking/bank-reconciliation/) — the match workspace and its rule gates. 8. [Financial statements](/docs/finance/statements/) — trial balance, P&L and balance sheet, on demand from posted balances. 9. [Closing a period](/docs/finance/period-close/) — reconcile, close through the Fiscal Period action, reopen only for an approved correction, lock after sign-off. 10. [Running payroll](/docs/payroll/payroll-runs/) and [payroll run approval](/docs/payroll/approvals/) — the accrual journal and payables the payroll cycle leaves behind, and the posting evidence to check. ## Day to day The routine day is exceptions and money: post the [journals](/docs/finance/journals/) the automation can't know about, [apply the payments](/docs/finance/payments/) that arrived, and keep the [subledgers](/docs/finance/subledgers/) clean — unapplied cash and aged balances are tomorrow's problems arriving early. Supplier [bills](/docs/procurement/bills/) that failed the [three-way match](/docs/procurement/three-way-match/) come to you as a question, not a block, so read the match before paying. [Bank reconciliation](/docs/finance/banking/bank-reconciliation/) is best done little and often. Month-end, the rhythm changes: check the [payroll run](/docs/payroll/payroll-runs/) actually posted (its posting status and linked journal, not its status alone), run the [statements](/docs/finance/statements/), chase what looks wrong back through the subledgers, then [close the period](/docs/finance/period-close/) so nothing can rewrite a month you've signed off. ## Common questions ### A statement figure looks wrong — how do I trace it? Drill down, don't guess: [statements](/docs/finance/statements/) break into account balances, account balances into postings, and customer or supplier lines into the [subledger](/docs/finance/subledgers/) documents behind them. The wrong figure is almost always a real document, findable in a few clicks — and an [inventory valuation](/docs/inventory/valuation/) figure traces the same way through the stock ledger. ### Can anyone post into a closed period? No — that's the point of the close. What the lock covers, who can reopen, and how late adjustments are handled are all in [Closing a period](/docs/finance/period-close/); [Troubleshooting inventory](/docs/inventory/troubleshooting/) covers the stock-side refusal when the inventory period is closed. ### A journal says Manual but nobody keyed it — is something wrong? No. *Manual* is the create-form default and generated draft journals can carry it. Use **Source Entity Name**, **Source Record** and the narration to establish provenance, as [Working with journals](/docs/finance/journals/) explains. ### The bank reconciliation won't balance — what's usually the cause? Timing, almost always: transactions in the books the bank hasn't cleared, or bank charges nobody recorded. [Reconciling a bank account](/docs/finance/banking/bank-reconciliation/) shows how to isolate and clear each difference. ## Related topics - [Fixed assets in xMatix](/docs/finance/fixed-assets/) — the asset register and [running depreciation](/docs/finance/fixed-assets/depreciation/). - [Budgets and budget control](/docs/finance/budgets/) — plans against actuals, and spend control. - [Revenue recognition](/docs/finance/revenue-recognition/) — when earned revenue differs from billed revenue. - [Interest on overdue payments](/docs/finance/interest-on-overdue/) — charging for late receivables. - [Statutory deductions and challans](/docs/payroll/statutory/) — the payroll-side payables that reach your books. ---- # Role-based guides URL: https://xmatix.com/docs/roles/ Last reviewed: 2026-09-02 ## Read a role-ready workspace Every role starts with a different set of licensed and permitted workspaces. Open the **App Launcher** to see the apps and entities available to the current account, then choose the guide that matches the work you actually perform. If a guide names an app or entity that is absent from the launcher, resolve licensing and access with an administrator before trying to follow its procedures. @[guided-image](_img/roles-overview.png) The role guides connect those available workspaces to a practical daily sequence and point to the canonical procedure whenever an action requires exact field-level instructions. They do not imply that every tenant or user receives the same apps, records or actions. Every role sees a different slice of xMatix. These guides are curated learning paths: each one orients a single job role, then links the canonical documentation pages in the order worth reading them. They never repeat what those pages say — they tell you which pages matter for your job, and why. ## The guides - [Field sales representative](/docs/roles/field-sales-representative/) — a mobile-first day of attendance, visits, orders and van sales, on or off the network. - [Sales manager](/docs/roles/sales-manager/) — order oversight, approvals, trade schemes, credit, dashboards and incentives. - [Field service technician](/docs/roles/field-service-technician/) — assigned work on mobile, checklists, time sheets and offline recovery. - [Dispatch manager](/docs/roles/dispatch-manager/) — the dispatch console, routing, availability and supervisor views. - [Warehouse operator](/docs/roles/warehouse-operator/) — receive, pick, dispatch, count and transfer stock. - [Procurement user](/docs/roles/procurement-user/) — requisition to purchase order to receipt to bill, and the three-way match. - [Finance user](/docs/roles/finance-user/) — journals, subledgers, banking, statements and period close. - [Support agent](/docs/roles/support-agent/) — cases, SLAs, macros, knowledge and collaboration. - [Tenant administrator](/docs/roles/tenant-administrator/) — users, security, licensing, data management and monitoring. - [Developer](/docs/roles/developer/) — the customization deep end: scripts, workflows, expressions and the developer tools. ## How to use a guide Read the opening paragraph to confirm the guide fits your job, then work through **Your path** in order — each link is a real documentation page, and the one-liner tells you what you'll get from it. The **Day to day** section shows how those pages fit a normal working day. ## Related topics - [Getting started with xMatix](/docs/getting-started/) — the pre-role basics: signing in, navigation, mobile setup. - [xMatix platform concepts](/docs/concepts/) — the ideas underneath every product, worth skimming whatever your role. ---- # Role guide: procurement user URL: https://xmatix.com/docs/roles/procurement-user/ Last reviewed: 2026-09-06 This guide is for the buyer. Your xMatix day follows one chain — requisition, purchase order, goods receipt, supplier bill — and your job is keeping that chain moving and honest: ordering what the business actually needs, chasing what hasn't arrived, and only paying for what was ordered and received. ## Where you work The first-party **Procurement** app carries the whole document chain on its bar: **Requisitions**, **Auto Orders**, **Purchase Orders**, **Shipments**, **Goods Receipts** and **Bills**, plus Reports, Dashboards and a **Settings** entry that opens the procurement masters (items and the module settings). Documents connect through **release** actions rather than through a wizard — a requisition releases into a purchase order (or a stock transfer), a purchase order releases into a goods receipt or a bill, and a goods receipt can release a bill — so most of your work happens on a document's detail page and its action buttons. Supplier balances and the bills' accounting side are read in the Finance app's [AR and AP subledgers](/docs/finance/subledgers/); the stock a receipt creates is read in the Inventory app's [ledger](/docs/inventory/ledger/). @[guided-image](_img/procurement-user.png) The **All Purchase Orders** view is the buyer's queue. The cards above the register count the last 30 days' orders and how many have progressed to a goods receipt or a bill; the register underneath carries document number and date, branch, supplier account, total amount and status. Status here is the release trail — *Draft* until a downstream document exists, then *Goods Receipt* or *Bill* — so filter by status and supplier to find what is still open, open the order, and read its lines' pending quantities before creating anything new. ## Access you need xMatix does not ship a buyer profile — of the seeded profiles, only the administrative ones carry the procurement entities — so your administrator grants a procurement profile read, create and update on Requisition, Purchase Order, Shipment, Goods Receipt, Bill, Auto Order and their lines, view access to the Procurement app, and the release and receive actions explicitly: each of **Release Purchase Order**, **Release Goods Receipt**, **Release Bill**, **Perform Receive** and the inspection actions is an entity action a profile can allow or withhold. That separation is deliberate — a buyer can be allowed to raise and release orders while only the warehouse may run **Perform Receive**, and only finance may post. Purchase-order approval, where your organization uses it, is an [approval process](/docs/customization/approvals/) on the order rather than a permission. Procurement is licensed as its own product; if the app or an action is missing, start with [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/). ## Your path 1. [xMatix Procurement](/docs/procurement/) — the product overview; the document chain your day runs on. 2. [Requisitions: from request to purchase order](/docs/procurement/requisitions/) — where demand enters, what is pending, and the release to an order or a transfer. 3. [The purchase order lifecycle](/docs/procurement/purchase-orders/) — the central document: header, lines, how line quantities drive the lifecycle, and the two release paths. 4. [Receive goods against a purchase order](/docs/procurement/goods-receipts/) — the three quantities on a line, receiving into stock, inspection, releasing the bill, posting the accrual. 5. [Supplier bills](/docs/procurement/bills/) — recording what the supplier is asking to be paid, and where it lands in finance. 6. [Three-way match: order, receipt and bill](/docs/procurement/three-way-match/) — how the comparison works, the link contract, and the release-path limitation that decides whether a bill is matched at all. 7. [Auto-order: rules-based purchase suggestions](/docs/procurement/auto-order/) — letting reorder rules draft the routine buying for you. 8. [Frequently ordered item suggestions](/docs/procurement/frequently-ordered/) — faster lines on the orders you place by hand. 9. [Receiving into the warehouse](/docs/warehouse/receiving/) — what the floor does with your order when the truck arrives. ## Day to day Mornings start with the queue: new [requisitions](/docs/procurement/requisitions/) to review and release, and [auto-order suggestions](/docs/procurement/auto-order/) to accept or trim before they become [purchase orders](/docs/procurement/purchase-orders/). As deliveries land, [goods receipts](/docs/procurement/goods-receipts/) record what arrived against the order — the warehouse's [receiving](/docs/warehouse/receiving/) puts it into a storage location — and as [bills](/docs/procurement/bills/) arrive, the [three-way match](/docs/procurement/three-way-match/) tells you which agree with order and receipt and which need a conversation with the supplier. Orders still in *Draft* status with pending quantities on their lines are your chasing list. Stock questions — did the receipt really land, what did it cost — are answered in the [inventory ledger](/docs/inventory/ledger/) and [valuation](/docs/inventory/valuation/). ## Common questions ### A bill disagrees with the order — why isn't it blocked? Because the match service compares and reports; it does not itself block posting or payment. [Three-way match](/docs/procurement/three-way-match/) explains exactly which numbers are compared, and the link contract that decides whether a bill is even in scope — a bill released from the receipt keeps only the receipt-line link, so release bills from the order when receipts exist. ### Does a goods receipt change stock, or just paperwork? Both, in two steps: creating the receipt stages quantities, and **Perform Receive** posts real stock into the storage location named on each line. [Receive goods against a purchase order](/docs/procurement/goods-receipts/) walks the three quantities on a line; [the inventory ledger](/docs/inventory/ledger/) shows the movement it creates. ### Why does a line still show pending quantity after we received? Pending counters are derived from downstream line quantities, and the order's receipt progress reads the receipt line's ordered quantity — staging, not proof of posting. Check the receipt's own status and lines; [The purchase order lifecycle](/docs/procurement/purchase-orders/) and [Troubleshooting procurement](/docs/procurement/troubleshooting/) cover the exact refusals and counters. ### Who approves my purchase orders? Whoever the approval process names — orders can be gated the same way any record is. [Approval processes](/docs/customization/approvals/) explains the mechanics; the thresholds are your organization's own [configuration](/docs/procurement/configuration/). ## Related topics - [Procurement configuration reference](/docs/procurement/configuration/) — the settings behind numbering, matching and approvals. - [AR and AP subledgers](/docs/finance/subledgers/) — where your bills land in finance, and the view to check when a supplier balance looks wrong. - [Inventory valuation and costing](/docs/inventory/valuation/) — how your purchase prices become stock cost. - [Transferring stock between branches](/docs/inventory/transfers/) — the alternative to buying when another branch already holds the item. - [Role guide: warehouse operator](/docs/roles/warehouse-operator/) — the team receiving what you order. ---- # Role guide: sales manager URL: https://xmatix.com/docs/roles/sales-manager/ Last reviewed: 2026-09-06 This guide is for the manager a sales team reports into. Your xMatix day is oversight: the orders your reps booked yesterday, the approvals waiting on you, the schemes and credit limits shaping what gets sold, and the dashboards that tell you whether the month is on track. You live mostly on the web app, with approvals following you to mobile. ## Where you work Apps and their entries are metadata your administrator can rearrange, but the first-party apps a sales manager uses are: | App | Entries you use | Why | | --- | --- | --- | | **Sales** | Orders, Invoices, Payments, Accounts, Bulk Conversion, Reports, Dashboards, Settings | The order-to-cash register and the bulk invoicing screen | | **Field Sales** | Visit Plans, Visits, Orders, Accounts, Credit Limits, Positions and Executive Positions | The field team's coverage, and the credit-limit control records | | **Rewards** | Schemes, Incentive Plans, Compensations, KPI Configuration | The promotions applying to orders and the incentive cycle | | **Claims** | Claims, Claim Batches, Reconciliations, Generation and Settlement Setups | Trade claims raised from scheme spend — a separately licensed product | | **Data Studio** and each app's **Reports / Dashboards** | The shared report library and dashboards | Your morning read on the team's numbers | @[guided-image](_img/sales-manager.png) The **All Sale Orders** view in the Sales app is where oversight starts. The summary cards above the register are last-30-day signals — total and draft orders, booked amount, scheme discount and total discount — and the register underneath is the evidence: document number and date, partner account and branch, the customer account, the responsible executive, the amount and the status. Read the cards to decide where to look, then narrow the register with search, column filters or a different saved view before acting; bulk and row actions apply to what is selected in the current view, so an unscoped **All** view is easy to act on by mistake. ## Access you need xMatix ships a **Sales Manager** security profile alongside **Sales Executive**, and the two are deliberately different. The seeded Sales Manager profile grants every operation — read, create, update, delete, share, assign, view all and modify all — on the sales documents (Order, Invoice, Payment, Scheme, Credit Limit, Visit Plan and their lines) and view access to the Sales, Field Sales, CRM, Rewards, Claims, Analytics and neighbouring apps. The seeded Sales Executive profile sees only the Sales app, cannot delete orders, and can read and update visit plans but not create them. Your administrator may have created organization-specific profiles instead; the shape is what matters — a manager needs **View All** or **Modify All** on the documents to see the whole team's work, and **Assign** to move an order between executives. Record visibility beyond your own records comes from the org structure: the shipped sample role hierarchy runs CEO → Chief Revenue Officer → VP Sales → Regional Sales Director → Sales Manager, and a manager positioned above a rep's role sees that rep's records without any sharing. Approvals reach you because an approval process names you, your role or a team you belong to. Licensing is per product: Sales for orders and invoices, Rewards for schemes and incentives, Claims for the claims app — and a seat on each you use. If an app or button described here is missing, read [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/) before asking for a broader profile. ## Your path 1. [xMatix Sales](/docs/sales/) — the product overview; how orders, pricing, schemes and credit fit together. 2. [The sales order lifecycle](/docs/sales/orders/) — every stage an order moves through, the pending counters, and what the status means. 3. [Create a sales order](/docs/sales/orders/create-order/) — how your reps build an order, so you can read one critically. 4. [Bulk order processing](/docs/sales/orders/bulk-processing/) — confirming, allocating and invoicing the day's orders at scale. 5. [Allocating stock to orders](/docs/sales/orders/allocation/) — why an order allocates or refuses, and how to release a reservation. 6. [Approval processes](/docs/customization/approvals/) — how approval gates work and what your approve/reject does. 7. [Work with approvals on mobile](/docs/mobile/approvals-on-mobile/) — clearing the queue from your phone. 8. [Trade schemes](/docs/sales/trade-schemes/) — slabs, conditions, benefits, budgets, and why a scheme did or did not apply. 9. [Credit limits](/docs/sales/credit-limits/) — what counts as exposure, how the gate works, and who can release a blocked customer. 10. [Trade claims](/docs/sales/claims/) — how scheme spend becomes claims, batches and settlements. 11. [Dashboards in xMatix](/docs/analytics/dashboards/) — your morning read on the team's numbers. 12. [Tracking incentives](/docs/rewards/tracking/) — following your team's incentive attainment through the cycle. ## Day to day Mornings start on a [dashboard](/docs/analytics/dashboards/) — orders booked, coverage, pipeline against target. Then the approval queue: anything gated by an [approval process](/docs/customization/approvals/) waits on you, and [mobile approvals](/docs/mobile/approvals-on-mobile/) mean it needn't wait long. Through the day you [process orders in bulk](/docs/sales/orders/bulk-processing/) and release the exceptions — usually a [credit-limit](/docs/sales/credit-limits/) block, an [allocation](/docs/sales/orders/allocation/) that found no stock at the branch, or a [scheme](/docs/sales/trade-schemes/) question — and check [incentive tracking](/docs/rewards/tracking/) as the cycle progresses. What happens after you approve is the warehouse's day: [picking and fulfilment](/docs/sales/orders/picking-and-fulfilment/) turns the confirmed order into picked stock and a delivery order. ## Common questions ### An order is stuck — where do I look? Check its status and pending counters against [the order lifecycle](/docs/sales/orders/) first; most "stuck" orders are waiting on an [approval](/docs/customization/approvals/), a [credit-limit release](/docs/sales/credit-limits/) or an allocation that found no eligible stock at the order's branch. [Troubleshooting sales](/docs/sales/troubleshooting/) lists the exact refusals — no pending allocation quantities, item lot not found, available stock not found — and what each means. ### Why did a scheme not apply to my rep's order? Because the order did not qualify at pricing time: the scheme's period, conditions or slabs did not match, or its budget was exhausted. [Trade schemes](/docs/sales/trade-schemes/) explains qualification, slabs, benefits and the scheme ledger; the order's own scheme section shows what was evaluated. ### Who can see the dashboards I build? Only the people they're shared with — and every backing report needs the same sharing, or viewers see gaps. [Who can see a report or dashboard](/docs/analytics/sharing-and-access/) explains the model; [subscriptions](/docs/analytics/subscriptions/) can mail the numbers out on a schedule. ### How are my team's incentives actually calculated? From incentive plans run against the period's results — [Running an incentive cycle](/docs/rewards/running-incentives/) walks the calculation, and [Incentive plans](/docs/rewards/incentive-plans/) explains the rules underneath. ## Related topics - [Territory planning](/docs/field-sales/territory-planning/) — shaping the beats and coverage your reps work. - [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/) — how an order's price is built. - [Invoicing and payments](/docs/sales/invoicing-and-payments/) — what happens to an order after your approval. - [Claim generation setups](/docs/sales/claims/generation-setups/) — for the manager who also owns how claims are configured. - [Role guide: field sales representative](/docs/roles/field-sales-representative/) — your team's side of the day. ---- # Role guide: support agent URL: https://xmatix.com/docs/roles/support-agent/ Last reviewed: 2026-09-06 This guide is for the agent working a queue. Your xMatix day is cases: they arrive routed to you, each carrying an SLA clock, and you work them to resolution — answering from the knowledge base, saving keystrokes with macros, and pulling in colleagues or escalating when a case outgrows you. ## Where you work Cases are records like any other, so they live in whichever app your administrator hosts the support desk in — the first-party **CRM** app carries **Cases** next to Leads, Opportunities, Quotes, Accounts and the Call Register, and the App Launcher's entity search opens the Case list whatever app is current. Everything you do to a case is an action on the record: **Escalate**, **Route**, **Merge**, **Run Macro**, **Email Article**, plus the status transitions of the lifecycle. Knowledge articles have their own list, macros are built under Setup → Feature Hub → Service → Macros, and the queues, SLA policies, business hours and skills that shape your day are configured by an administrator in the CRM Settings app. @[guided-image](_img/support-agent.png) The **All Cases** view is the register behind every queue. The cards above it summarize the desk — total, escalated, high-priority, SLA-breached and average CSAT — and the columns underneath carry what you need to choose the next case: source, subject, priority and severity, customer tier and the working owner. Your own queue is a saved view of this same register, so verify the view name and filters before concluding a case is absent, then open the record and read its details, activities and SLA tabs before acting. ## Access you need There is no shipped support-agent profile — the seeded profiles that carry case permissions are the administrative ones — so your administrator creates an agent profile that grants read, create and update on Case and its related records (case milestones and SLA events, knowledge articles, activities) and explicitly allows the case actions you may run. Each action is an entity action with its own grant: an agent who may Run Macro but not Merge is a normal configuration, and a team member's descriptive access level on a case does not grant an action. Being *routable* is a separate matter from permissions: the routing engine only offers work to a resource record that is active, linked to your user account, currently *Available*, and under its declared capacity — if any of those is false you can still open cases, but the queue will not push work to you. Support is licensed as part of the product your organization has enabled; a missing Cases entry or a greyed action is diagnosed with [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/). ## Your path 1. [xMatix Support](/docs/support/) — the product overview; how cases, queues, SLAs and knowledge fit together. 2. [The case lifecycle](/docs/support/cases/) — the operational states, which transitions are allowed, owner versus assigned-to, and what a case creation stamps. 3. [Queues and omni-channel routing](/docs/support/queues-and-routing/) — who is eligible, the routing models, and what accept, decline, transfer and reassign do. 4. [SLA policies and milestones](/docs/support/slas/) — how a policy is chosen, the first-response and resolution clocks, business hours, pausing, and how breaches surface. 5. [Build and run macros](/docs/support/macros/) — ordered steps that update fields, add notes, send email or call a case action in one click. 6. [Author and share knowledge articles](/docs/support/knowledge-base/) — finding answers, surfacing an article on a case, emailing it to the customer, and writing down what you discover. 7. [Collaborating on cases](/docs/support/collaboration/) — following, team members, side conversations, duplicate detection and merging. 8. [Escalating a case](/docs/support/escalation/) — what Escalate changes, and how SLA breaches escalate automatically. ## Day to day Work arrives through [queues and routing](/docs/support/queues-and-routing/); your job is to keep each case moving through [its lifecycle](/docs/support/cases/) before its [SLA milestones](/docs/support/slas/) come due. The fast path on a familiar issue is a [knowledge article](/docs/support/knowledge-base/) plus a [macro](/docs/support/macros/); the honest path on an unfamiliar one is [collaboration](/docs/support/collaboration/) early and [escalation](/docs/support/escalation/) before the breach, not after. When a case is really a service job — a repair, a site visit — it becomes a [service order](/docs/service/service-orders/) that the service team executes while the case keeps the customer conversation. Every call and message along the way lands on the case as an [activity](/docs/engagement/activities/), so the next agent inherits the whole story. ## Common questions ### Which case do I pick up first? The one closest to breaching — SLA milestones, not arrival order, set the priority. [SLA policies and milestones](/docs/support/slas/) explains the clocks; your queue views can sort by them, and the SLA-breached card on the case list tells you how many are already over. ### Does the SLA clock stop while I wait on the customer? Only if the policy says so — pausing is a per-policy choice tied to specific statuses, and it does not apply retroactively. [SLA policies and milestones](/docs/support/slas/) covers pause conditions; [the case lifecycle](/docs/support/cases/) shows which statuses count as waiting. ### The case was routed to me but still shows another owner — why? Routing creates an offer; ownership moves when you accept it, and it moves to the user linked to your resource record. [Queues and omni-channel routing](/docs/support/queues-and-routing/) walks accept, decline and transfer; if nothing ever reaches you, check with your administrator that your resource is active, linked to your account and marked available. ### I solved something new — where should the answer live? In the knowledge base, before you forget it — [Author and share knowledge articles](/docs/support/knowledge-base/) covers writing it once so every future case gets the benefit. ## Related topics - [Troubleshooting the support desk](/docs/support/troubleshooting/) — when routing, SLAs or case actions misbehave. - [Using the softphone](/docs/engagement/softphone/) — taking calls without leaving the case. - [Asking Sense about your data](/docs/sense-ai/chat/) — quick answers about your own caseload. - [Support configuration reference](/docs/support/configuration/) — the settings behind your queues and policies. - [The service order lifecycle](/docs/service/service-orders/) — where a case goes when it needs hands-on work. ---- # Role guide: tenant administrator URL: https://xmatix.com/docs/roles/tenant-administrator/ Last reviewed: 2026-09-06 This guide is for the person who runs xMatix for everyone else. Your day is arrivals and departures (users, seats, access), the security model that decides who sees what, the data that needs loading or extracting, and the quiet monitoring that catches problems before users report them. You'll also field every "can xMatix do X?" — so knowing the customization ladder is part of the job. ## Where you work Almost all of it is under **Setup**, which the App Launcher opens like any other app. The groups you live in: | Setup group | What you administer there | | --- | --- | | **Access Control** | Users, Business Units, Profiles, Roles, Teams, Policies — the whole security model | | **Feature Hub → Administration** | Licenses (tenant entitlements and seats), License Usage, Organization Settings, Themes | | **Feature Hub → each module** | The module's own **Settings** entry — master switches and behaviour options for Sales, Service, Inventory, Procurement, Finance, Portals, Sense AI | | **Platform Operations → Monitoring** | Jobs, Tracing, Audit Trail, Message Log, Sync Monitor | | **Platform Operations → Data Import / Data Export** | Bulk loads with per-row history, and extracts | | **Design Studio / Process Studio** | The customization ladder — usually the developer's ground, but you decide when a request climbs there | Business configuration that is not security — document numbering, storage locations, payroll components, SLA policies — lives in each module's own setup list rather than in Setup, and each module's configuration reference tells you where: [Sales](/docs/sales/pricing-and-discounts/), [Procurement](/docs/procurement/configuration/), [Warehouse](/docs/warehouse/configuration/), [Inventory](/docs/inventory/configuration/), [Service](/docs/service/configuration/), [Support](/docs/support/configuration/), [Payroll](/docs/payroll/configuration/). @[guided-image](_img/tenant-administrator.png) The **Users** register is where most days start. Each row carries the account's **Active** flag and its **Sign-in** state — *Ready* once identity provisioning has completed, *Not provisioned* until then — and opening a row reaches the tabs that decide what the person can actually do: **Profile Assignments**, **Role Assignments**, **Team Assignments**, **License Allocations** and **Access Diagnostics**. **New** creates the account and sends it for provisioning but assigns nothing, so an invitation is only finished when at least one active profile is attached. Clearing **Active** is not a sign-in suspension for an already provisioned identity; offboarding uses the row's **Delete** action after work and seats have been reassigned. ## Access you need Setup areas are gated by named capabilities, granted per profile on the **Entitlements** tab. The built-in **SystemAdmin** profile holds the entire catalog and its core security capabilities cannot be revoked, so there is always a recovery hatch; a narrower administrator profile needs the specific keys: | Task | Capability key | | --- | --- | | Users (create, edit, delete accounts) | `setup.security.users.manage` | | Profiles, roles, teams, business units, policies | `setup.security.manage` | | Audit Trail | `setup.security.audit.view` | | Licenses, License Usage, seat allocations | `setup.licensing.admin` | | Module settings under Feature Hub | `setup.featurehub.settings.manage` (the Feature Hub group itself also needs `setup.licensing.admin`) | | Organization Settings, Themes | `setup.org.settings.manage` | | Data Import, Data Export | `setup.data.import.manage`, `setup.data.export.manage` | | Jobs, Tracing, Message Log | `setup.diagnostics.jobs.view`, `setup.diagnostics.tracing.view`, `setup.messaging.log.view` | | Sync Monitor and integrations | `setup.integration.manage` | Two built-ins are worth knowing by name: **SystemAdmin** and **StandardUser** cannot be renamed or deleted, and StandardUser is the default for ordinary internal users — it grants a handful of core entities and app visibility, not the modules, so a new user who "can see the apps but nothing in them" is usually holding StandardUser alone. Access is additive across profiles with no deny, so narrowing someone means moving them to a smaller profile, not adding a restrictive one. ## Your path 1. [xMatix administration guide](/docs/administration/) — your home section; skim it to know what's where. 2. [Invite a user](/docs/administration/users/invite-a-user/) — the most common task, end to end: account, provisioning, profile, seats. 3. [How the xMatix security model works](/docs/concepts/security-model/) — the mental model everything else builds on. 4. [Security profiles and the grant matrix](/docs/administration/security-profiles/) — what a user may do, entity by entity, plus fields, apps, actions and capabilities. 5. [Roles, teams and business units](/docs/administration/roles-teams-business-units/) — the org structure access flows through. 6. [Record-level security and sharing](/docs/administration/record-security/) — who sees which records, and why. 7. [Licensing: products, features and seats](/docs/administration/licensing/) — what your organization has bought, who holds a seat, and how licensing composes with profiles. 8. [Offboard or suspend a user](/docs/administration/users/deactivate-a-user/) — the checklist that Active does not replace. 9. [Import data with the import wizard](/docs/administration/data-management/import-data/) — loading records in bulk, safely. 10. [Monitoring mobile sync failures](/docs/mobile/admin-sync-monitoring/) — the field team's problems, visible before they call. 11. [The customization ladder](/docs/concepts/customization-ladder/) — which tool fits which request, from setting to script. ## Day to day Most days are user lifecycle — [invites](/docs/administration/users/invite-a-user/), seat and [license](/docs/administration/licensing/) changes, [offboarding](/docs/administration/users/deactivate-a-user/) — and access questions, which nearly always resolve inside the [security model](/docs/concepts/security-model/): a [profile grant](/docs/administration/security-profiles/), an org-structure position, or [record-level sharing](/docs/administration/record-security/). Module owners bring you their configuration asks — a new document number series, a payroll component, an SLA policy — and the module configuration references ([procurement](/docs/procurement/configuration/), [warehouse](/docs/warehouse/configuration/), [inventory](/docs/inventory/configuration/), [service](/docs/service/configuration/), [support](/docs/support/configuration/), [payroll](/docs/payroll/configuration/)) say what each setting does before you change it. Data work comes in waves ([import](/docs/administration/data-management/import-data/) at rollout, [export](/docs/administration/data-management/export-data/) forever after), and a periodic look at [mobile sync health](/docs/mobile/admin-sync-monitoring/) and the [background job ledger](/docs/troubleshooting/background-work/) keeps you ahead of trouble. Change requests go up the [customization ladder](/docs/concepts/customization-ladder/) — settings before configuration, configuration before code. ## Common questions ### A user says they can't see a record — where do I start? With the user's **Access Diagnostics** tab and the checklist, not with guesswork — [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/) walks the causes in the order they're likely: license, profile grant, org scope, record sharing, [restriction rules](/docs/administration/restriction-rules/), view filters. Have the user refresh their session after any fix before you conclude it failed. ### How do I set up access for a new team or region? Copy a working pattern: [Worked security scenarios](/docs/administration/security-scenarios/) shows complete, tested setups — territory scoping, manager rollups, cross-team sharing — you can adapt rather than invent. The role guides for [sales managers](/docs/roles/sales-manager/), [warehouse operators](/docs/roles/warehouse-operator/), [buyers](/docs/roles/procurement-user/) and [support agents](/docs/roles/support-agent/) each list the entities and actions their profile needs. ### Someone's asking for a change — settings, configuration or developer? Climb the ladder from the bottom: [The customization ladder](/docs/concepts/customization-ladder/) tells you which tool fits, and [Customizing xMatix](/docs/customization/) is the section to hand over when the answer is configuration. ### I revoked a capability and lost my own Setup access — now what? The core security capabilities cannot be removed from the SystemAdmin profile, so any SystemAdmin holder can restore yours; keep at least one active SystemAdmin at all times. For anything else, [Security profiles](/docs/administration/security-profiles/) explains which capability opens which area. ## Related topics - [Setup Copilot: configuring xMatix by asking](/docs/sense-ai/setup-copilot/) — describe the change; it drafts the configuration. - [AI Studio: governing Sense in your organization](/docs/sense-ai/ai-studio/) — the admin's controls over AI features. - [Configuring the mobile app](/docs/mobile/admin-configuration/) — what the field team's app shows, decided by you. - [Troubleshooting access and sign-in](/docs/troubleshooting/access-and-sign-in/) — the consolidated triage when someone cannot get to their work. - [Role guide: developer](/docs/roles/developer/) — for the requests that reach the top of the ladder. ---- # Role guide: warehouse operator URL: https://xmatix.com/docs/roles/warehouse-operator/ Last reviewed: 2026-09-06 This guide is for the person on the warehouse floor. Your xMatix day is physical stock and the documents that move it: trucks to receive in the morning, pick lists against the day's orders, delivery orders out the gate, counts to keep the system honest, and transfers when another branch needs what you have. ## Where you work Open the **Warehouse** app from the App Launcher — it sits behind **More** when it is not pinned. Its bar carries the four operational documents, **Fulfilment Orders**, **Delivery Orders**, **Transfers** and **Cycle Counts**, plus **Items**, **Branches**, Reports, Dashboards and Settings. Two things you use are deliberately elsewhere: **goods receipts** live in the Procurement app, because they are released from purchase orders, and **storage locations** and **lot types** live in the Warehouse Settings app, reachable through the launcher's entity search. The flow is lean by design — goods are received straight into the storage location named on each receipt line (no separate putaway document), and dispatch goes straight from picked lines to a delivery order (no packing document) — so the steps you perform are exactly the ones that change stock truth: receive, allocate, pick, deliver, count. @[guided-image](_img/warehouse-operator.png) The **All Fulfillments** list is the outbound work queue and the natural landing page. Each row is one fulfilment document released from a sales or service order: partner account and branch say whose stock moves from where, the customer account says for whom, and **Status** with **Allocated** say how far it has gone — a row that is *New* with *Allocated = False* is work nobody has started. Filter by branch or status, open the document, and work its allocation, picking and delivery lines in order; do not create a fulfilment by hand to force stock out when the source order cannot be found. ## Access you need Warehouse work is governed by ordinary security profiles, and the actions are the sensitive part: **allocate**, **perform picking**, **confirm picking**, **picked delivery**, the delivery order's **release shipment** and **create invoice**, the cycle count's start, finish and variance release, and the goods receipt's **perform receive** are each an entity action a profile can allow or withhold, so an operator can be allowed to pick without being allowed to release the delivery, or to count without being allowed to post the variance. A working operator profile needs read on Items, Branches and Storage Locations; read, create and update on Inventory Fulfilment (with its order, allocation and picking lines), Delivery Order, Transfer and Cycle Count; read and update on Goods Receipt if you receive; and the specific actions above. Every posting writes the [inventory ledger](/docs/inventory/ledger/), and a **closed inventory period** refuses postings regardless of permission. xMatix ships a **Parts Manager** profile name, but it carries no grants out of the box — your administrator builds the operator profile; if a document or button is missing, start with [Troubleshooting: a user can't see something](/docs/administration/user-cant-see-x/). ## Your path 1. [xMatix Warehouse](/docs/warehouse/) — the product overview; the documents your day runs on and where Warehouse ends and Inventory begins. 2. [Storage locations and vans](/docs/warehouse/storage-locations/) — the map of your warehouse: branch, type, hierarchy, and the vehicle attributes that make a location a van. 3. [Receiving into the warehouse](/docs/warehouse/receiving/) — inbound stock, from the procurement goods receipt to the shelf. 4. [Fulfilment picking](/docs/warehouse/fulfilment-picking/) — allocate, perform and confirm picking, release the delivery, and undo in the right order. 5. [Delivery orders and dispatch](/docs/warehouse/delivery-orders/) — the delivery checklist, transport details, releasing the shipment, creating the invoice. 6. [Cycle counting](/docs/warehouse/cycle-counting/) — scope a count, start it (optionally locking the counted stock), record quantities, finish, release the variance as an adjustment. 7. [Branch transfers: the warehouse view](/docs/warehouse/branch-transfers/) — outward release, in-transit and inward receive, and what each means for the bins at both ends. 8. [The inventory ledger](/docs/inventory/ledger/) — why every action you run leaves a posted entry, and how to read the balance it produces. ## Day to day The day usually opens inbound: [receive](/docs/warehouse/receiving/) the morning's deliveries into their [locations](/docs/warehouse/storage-locations/) — the buyer's [goods receipt](/docs/procurement/goods-receipts/) is the document you complete. Then outbound takes over — work the [fulfilment documents](/docs/warehouse/fulfilment-picking/), stage the stock, and close each [delivery order](/docs/warehouse/delivery-orders/) as the vehicle leaves. In the gaps, the [cycle count](/docs/warehouse/cycle-counting/) schedule tells you which bins to count today, and any [branch transfer](/docs/warehouse/branch-transfers/) in either direction gets released or received like any other movement. Lot-tracked items carry their [lot](/docs/inventory/lots/) through every step. Every one of these actions posts to the [ledger](/docs/inventory/ledger/) — nothing moves off the books, and a correction is a new entry, never an edit. ## Common questions ### The system says we have stock I can't find — what now? Trace it first, then correct it: [the inventory ledger](/docs/inventory/ledger/) shows every movement that produced the number, and if the shelf is right and the system wrong, an [adjustment](/docs/inventory/adjustments/) — or a targeted [cycle count](/docs/warehouse/cycle-counting/) that releases its variance as one — puts it straight. [Troubleshooting inventory](/docs/inventory/troubleshooting/) is the method. ### I'm receiving against a purchase order — is that different? The floor work is the same, but the receipt is matched to the purchase order line by line and **Perform Receive** is what posts the stock — [Receive goods against a purchase order](/docs/procurement/goods-receipts/) covers the three quantities on a line and short or excess delivery; [Receiving into the warehouse](/docs/warehouse/receiving/) covers what the warehouse controls on it. ### A receipt, pick or dispatch won't post? The action tells you why in its own words — "no pending picking quantities", "cannot create delivery for picking lines that are not confirmed", "no branch found for account" — and [Troubleshooting warehouse operations](/docs/warehouse/troubleshooting/) translates each message into the step you skipped or the document that is in the wrong state. ## Related topics - [xMatix Inventory](/docs/inventory/) — the stock ledger and rules underneath every warehouse document. - [Transferring stock between branches](/docs/inventory/transfers/) — the transfer document end to end. - [Picking and fulfilment](/docs/sales/orders/picking-and-fulfilment/) — the sales-order side of what you pick. - [Item lots and lot types](/docs/inventory/lots/) — when stock is tracked lot by lot. - [Warehouse configuration reference](/docs/warehouse/configuration/) — locations, lot types, numbering, delivery checklist templates and the van capacity check. ---- # Authoring a claim generation setup URL: https://xmatix.com/docs/sales/claims/generation-setups/ Last reviewed: 2026-09-05 A claim generation setup turns a class of transactions into claims on a schedule, entirely through configuration — no code per claim type. This page walks through authoring one safely. The concepts behind each element are covered in [Trade claims](/docs/sales/claims/); the entity-level field reference is under [Claim Generation Setup](/docs/reference/entities/claim-generation-setup/) and [Claim Settlement Setup](/docs/reference/entities/claim-settlement-setup/). Setups live in the Claims app under **Claim Generation Setups** (`/ClaimGenerationSetup`). A setup record has two tabs: **Details**, where every pipeline field sits in five collapsible sections, and **Rules**, which holds the child **Claim Generation Setup Rule** rows. You need create and edit permission on both entities (both belong to the Claims product licence), and access to **Setup → Administration → Jobs** to read run results, because generation always runs as a background job. Saving a setup that names a **Source Entity** compiles and executes the main source query with a one-row limit, so a bad field path or filter expression fails at save time. The netting query gets the same probe only when both **Netting Source Entity** and **Netting Filter Expression** are present. This is a structural check, not a financial reconciliation of the whole population. A setup with a custom **Target Entity** and no **Processed Flag Field** is refused outright. A newly created setup defaults to **Active** off and **Simulate Mode** on. A setup copied from another can carry any persisted values, including active and non-simulated, so inspect the exact row instead of assuming a state from its name. ## Procedure @[guided-image](_img/new-claim-generation-setup.png) The create form asks only for the identity, source, grouping and scheduling fields; everything else is completed on the Details and Rules tabs after the first save. Keep **Active** off and **Simulate Mode** on until a full simulated cycle reconciles independently. ### Step 1 — Create the setup and name its source Choose **New** on the Claim Generation Setups list. Give the setup a **Document Number** (its name), a **Claim Type** and the **Source Entity** whose records earn the claim — scheme ledger accruals, invoice lines, credit-note lines, goods-receipt lines, purchase-order lines or any entity including custom ones. Choose the source before **Grouping Fields**, because that list is built from the source entity's fields. The claim type is normally fixed from the setup. **Claim Type Source** set to `SourceField:` (on Details after the first save) reads it per source row instead, falling back to the setup's Claim Type when the path is empty; if both resolve to nothing the run fails. The setup's Claim Type picklist is the generation engine's coded vocabulary and must equal the **Claim Type** of the settlement setup that will settle the claims. Assign a **Schedule Group** with a **Run Order** (default 100). The shipped groups are `Nightly`, `Weekly` and `Monthly (Day 1)`; organizations can add their own picklist values. A setup with no schedule group can still be run manually but never runs on a schedule. **Batch Size** (default 200, clamped to 1–5000 at run time) is the number of source rows read per page; it affects memory and progress reporting, not the result. Save. ### Step 2 — Define selection Open the **Details** tab, section **Source & Selection**, and the **Rules** tab. Restrict the source three ways, all optional but usually combined: - **Rule rows** on the **Rules** tab — **Sequence**, **Field Name**, **Operation** and **Field Value**. Operations are Equals, Not Equal, Greater Than, Less Than, Contains, In and Not In (the grid shows the stored operator code). **Rule Success Criteria** combines the rows with AND (default) or OR; **Rule Custom Logic** such as `(1 AND 2) OR NOT 3` overrides the criteria and references sequence numbers. A formula that names a sequence with no rule row, or contains an unknown word, fails the run rather than being ignored; a rule row with a blank Field Name is silently dropped, which is the usual way a formula ends up pointing at a missing sequence. - **Filter Expression** — a dynamic-LINQ predicate for conditions rules cannot express, for example `Quantity > 0`. It is ANDed with the rule rows, never a replacement for them. - **Date Window** (`None`, `Last Month`, `This Month`, `Last N Days` with **Date Window Days**) applied to **Date Field**, which may be a navigation path such as a line's parent document date. Windows are resolved from the UTC date; `Last N Days` runs from N days ago up to and including today. `None` disables date filtering whatever the field says, and a window with a blank Date Field is silently inert. Name the **Processed Flag Field** (section **Mappings & Output**) when the source has a suitable Boolean field. The query then excludes flagged rows, and a successful claim write flags its contributors in the same transaction. For a normal Claim target this flag is optional because Claim also has a generation-key guard; without it the source is read again on every run even though an identical key is skipped. For a custom **Target Entity** the flag is mandatory. ### Step 3 — Choose grouping and aggregation In **Grouping & Amount**, **Grouping Fields** is a comma-separated list of field paths whose joined values form each claim's group key — one claim per distinct combination, typically partner, branch and scheme, or supplier and item. It is mandatory: the run fails on the first source row it meets without it (a source that returns no rows completes quietly). Set **Partner Account Path** and **Branch Path** when the partner and branch are not direct `PartnerAccountId`/`BranchId` columns on the source row; the generated claim's Partner Account and Branch come from these paths. Then choose the **Aggregate Function**. **Sum** accumulates **Amount Field** across the group into one claim line (quantity 1), optionally transforming each contribution through **Amount Formula**, where the raw value is available as `amount` and the source row's own fields are in scope. **Per Record** maps one claim line per source row. Sum configured without an amount field fails the run. ### Step 4 — Map the claim **Header Mapping** and **Line Mapping** (section **Mappings & Output**) are JSON objects that map target field names to source paths or tokens. A plain value is read as a navigation path on the source row; the tokens are `@Item:` (look up an item by name), `@const:` (a literal), `@amount` (the aggregated amount), `@parent` (the id of the claim header being written) and `@format:{Path}-{Other.Path}` (interpolate several paths into one string). A target field name that does not exist on the claim is stored in the record's custom-field bag rather than rejected, so check spellings. Header mapping is evaluated once from the first row that opens each group, before any amounts have been accumulated — keep it to values that are constant within the group key and do not use `@amount` there. Set **Owner Resolution**: `None`, `Resource User` (the user behind the active field-sales resource of the claim's partner, matched on branch when the resource has a default branch) or `Branch Owner` (the branch's owner). An unmatched owner leaves the claim unowned rather than failing. **Supplier Account** is the party the claims are raised on; batching later skips claims that have none. ### Step 5 — Add netting, if the claim type needs it The **Netting Leg** section subtracts a second source's total per group before the claim is written — sale returns against a discount computation, payouts already made against a fresh calculation. Set **Netting Source Entity** and **Netting Amount Field** (mandatory once a source is named — the run fails rather than netting zero), and optionally **Netting Filter Expression**, **Netting Partner Path**, **Netting Branch Path** (both default to `PartnerAccountId`/`BranchId`), **Netting Date Field** and **Netting Date Window**. The netting window has no day count of its own, so `Last N Days` on the netting leg means today only. Netting reduces the first claim line, so it is meaningful for Sum setups; groups that net to zero or below produce no claim. Because save probes the netting query only when both its source entity and filter expression are present, a successful save does not prove a partially configured netting leg can run. ### Step 6 — Configure settlement for the claim type Under **Claim Settlement Setups**, create or review the active setup for this claim type; the settlement job picks the active setup whose **Claim Type** equals the claim's type exactly. **Settlement Document** decides what an approved claim produces: **Credit Note** (default), **Invoice** (bill the counterparty from the approved values), **Adjustment (Part to Part)** (an inventory adjustment from the approved quantities, the shortage-claim path) or **None** (nothing is created; only the configured event is raised). **Apply To Open Invoices** knocks a credit note off against the partner's open invoices oldest-first and applies to the credit-note path only; **Auto GL Posting** posts the resulting document (inventory posting for an adjustment); **Raise Event Name** publishes a business-rule event after settlement, best-effort. **Header Mapping** and **Line Mapping** shape the document with the tokens `@approvedAmount`, `@approvedQuantity` and `@const:`. **Settlement Grouping** is **Per Claim** (default, one document per approved claim) or **Per Batch (consolidated)**, in which case **Batch Grouping Fields**, **Batch Period** (None or Month) and **Batch Filter** drive the batching sweep described in [Trade claims](/docs/sales/claims/). Save refuses Per Batch together with Adjustment and dry-runs the batch filter. A new settlement setup also starts in **Simulate Mode**; keep it there until approved quantities and mapped output agree with an independent calculation — in simulate mode the settle job reports the document it would have created and leaves the claim unsettled. ### Step 7 — Run in simulate mode and read the job result Run the setup with its **Generate Claims** action while it is still in simulate mode. The action does not generate inline: it enqueues a background run scoped to this one setup and returns the job run id, so open **Setup → Administration → Jobs** to read the outcome. The enqueue key is bucketed to the minute, so a double-click collapses into one run while a deliberate re-run a minute later goes through. The run summary reports, per setup, claims written, lines written and candidates skipped, and for a simulated run the number of candidates with a preview of the first few groups and amounts — without creating anything or flagging any source row. Auto-submit is skipped entirely in simulate mode. Compare a full cycle against the process being replaced and investigate every difference until it has an explanation. ### Step 8 — Activate Switch **Simulate Mode** off and mark the setup **Active** only when it should join scheduled group runs. A schedule-group run selects the active setups of its group and executes them in ascending **Run Order**; the manual **Generate Claims** action runs the selected setup regardless of its Active flag and ignores Run Order. The schedule itself is a job schedule: create one per schedule group under **Setup → Administration → Jobs → Schedules** for the *Generate claims* job with the group's stored value in the payload (for example `{"scheduleGroup":"MonthlyD1"}`) — no schedule is shipped. Optionally enable **Auto Submit For Approval**: each newly written claim is submitted to its approval process straight after the run, and submission failures (no process configured, already pending) are written to the application log without failing generation. ## Expected result Saving the setup proves the main query can return at most one sampled row without a compilation or runtime error; it does not prove the complete population or every optional netting configuration. A simulated run reports the candidate groups, lines and amounts in the job summary without creating target records or changing processed flags. After activation, the schedule creates normal claims in **Draft** status per eligible key and flags sources when configured. For a custom target, verify target and source state before every retry because header, lines and flags are not written in one transaction. ## Verify the saved setup @[guided-image](_img/claim-generation-detail-details.png) The **Details** tab exposes every part of the pipeline in five collapsible sections: **Source & Selection**, **Grouping & Amount**, **Mappings & Output**, **Netting Leg** and **Scheduling & Execution** (Schedule Group, Run Order, Batch Size, Strategy Key, Active, Simulate Mode). Re-open each section after save and compare the persisted fields with the reviewed design; a successful query probe does not validate business meaning. @[guided-image](_img/claim-generation-detail-rules.png) The **Rules** tab is the child rule list combined by **Rule Success Criteria** or the custom logic formula. Confirm Sequence, Field Name, Operation and Field Value for every row. When a filter expression is also present, it is combined with these rows rather than replacing them. ## Common questions ### What happens if two setups could sweep the same source records? When a processed flag is configured, a successful claim write commits the claim, lines and source flags together, and later queries skip those rows. Without a flag, both setups can read them; the Claim generation key only prevents a second claim with the same claim type, group and run month. Partition overlapping setups explicitly and do not assume one setup's key protects another claim type or grouping. ### How is the period in the generation key derived? From the month the run executes in (UTC), not from the date window or the source dates. The key is `ClaimType|GroupKey|Period` with the period as `yyyy-MM`, so a setup re-run next month for the same group produces a second claim unless a processed flag excludes the already-claimed rows. Within a month a rerun is skipped and counted as such. ### Can a setup write something other than a claim? Yes. **Target Entity** and **Target Line Entity** redirect the output to a different document type, including a custom entity, written through the metadata-driven data service. Its source **Processed Flag Field** is mandatory because custom targets have no generation-key guard, and simulate runs for such a target never report skips. The writer persists header, child lines and source flags through separate calls; if a failure occurs after header creation but before source flagging, a retry may create another header. Inspect and repair the partial result before rerunning. ### How do I test changes to a live setup? Switch it back to simulate mode and run **Generate Claims**, then compare the job summary before re-activating. The save-time dry run guards the query itself, but only a simulation shows you the groups and amounts. ### Why does the claim type list differ from the one on a claim? The setup's **Claim Type** picklist is the generation engine's own vocabulary of coded scheme and incentive types, and generated claims carry those values verbatim. The Claim entity's own claim-type picklist drives **Perform Populate Lines** on manually created claims and does not need to overlap; what matters for settlement is that an active Claim Settlement Setup exists for exactly the value the setup stamps. ## Related topics - [Trade claims](/docs/sales/claims/) - [Trade schemes](/docs/sales/trade-schemes/) - [Service claims](/docs/service/service-claims/) ---- # Trade claims URL: https://xmatix.com/docs/sales/claims/ Last reviewed: 2026-09-05 A trade claim in xMatix is an amount a partner is owed — or owes — that is raised as a document, reviewed line by line and then settled by another document. Scheme payouts, price support, damaged or short deliveries, transport reimbursement and service reimbursements are all claims; what differs is the **claim type**, which decides how lines are populated and which settlement setup applies. Claims can be typed in by hand or produced in bulk by a **claim generation setup** that sweeps a source entity on a schedule. ## Where claims live Claims have their own **Claims** app: **Claim Overview Dashboard**, **Claims**, **Claim Batches**, **Claim Reconciliations**, **Claim Generation Setups**, **Claim Settlement Setups**, **Reports**, **Dashboards** and **Settings**. The Sales app does not host claims. Claims is also its own product licence; the Claim, Claim Line, Claim Batch, Claim Reconciliation, Claim Generation Setup and Claim Settlement Setup entities are only reachable when the licence is assigned to the organization and to the user's security profile, and the user's profile must additionally grant entity permissions on Claim and Claim Line. Claims that come out of a generation setup are ordinary Claim records, so the same screens and permissions apply. ## Find a claim @[guided-image](_img/claim-list.png) The **All Claims** view lists Name, Partner Account, Branch, Claim Type, Status and Total Amount, with summary cards above the register; other saved views (for example a per-claim-type filter) are selected from the view menu next to the heading. Search by claim number, then filter by partner, branch, claim type and status so review starts from the intended population. Open a record from its name. ## Read a claim @[guided-image](_img/claim-detail-lines.png) The record header shows the claim number, its status tag, Partner Account, Branch and Claim Type, and the actions **Approve All**, **Perform Populate Lines**, **Perform Reconciliation** and, under the arrow, **Reject All**. The stepper underneath (Draft, Pending Approval, Approved, Rejected, Settled) is a fixed illustration of the lifecycle; the authoritative value is the status tag, whose picklist is described below. **Claim Lines** is the approval basis. Each line carries an item or description, its own line claim type (**Part To Part**, **Reimbursment**, **Shortage** or **Damaged**), the claimed quantity and amount, a unit price, and the approved and rejected quantities that approval writes. Lines have a row action **Open Checklist** and can be added with **New**. The **Claim Checklist** tab and the **Checklist** panel beside the lines are manual review aids built into the standard layout. Their Pass/Fail and Yes/No choices are not bound to any field, so nothing is saved: they help a reviewer work through a warranty-style check, but they are not evidence that a review, approval or settlement happened. Organizations can replace the layout with their own checklist. **Related** lists documents linked to the claim — delivery orders, invoices and adjustments — and is populated only after a settlement or reconciliation has created one of them; on an unsettled claim every list is empty. @[guided-image](_img/claim-detail-details.png) **Details** has two sections. **Key Information** holds Partner Account, Branch, Supplier Account (the party the claim is claimed from), Status, Claim Type and Name. **Related Source** holds the optional back-links of a manually created claim — Bill Return, Sale Invoice, Goods Receipt, Service Contract and Service Order — which **Perform Populate Lines** reads. The **Approval** tab shows the approval process history once the claim has been submitted. ## Actions on a claim | Action | What it does | | --- | --- | | Perform Populate Lines | Builds claim lines from the linked source by claim type: **Service** reads the linked service order; **Purchase**, **Damaged**, **Shortage** and **Excess** read the credit-note lines of the linked bill return. **Sale** is a stub that creates nothing, and **Scheme**, **Transport** and **Part To Part** have no populate path — lines for those types are generated or entered by hand. | | Approve All / Reject All | Copies the claimed quantity into the approved quantity (and zeroes the rejected quantity) or the reverse, on every line. Both buttons run the same routine, which is driven by the **Approve All** and **Reject All** flags on the claim rather than by which button was pressed: with neither flag set the buttons change nothing, and if both are set the approve path wins. They write quantities only, never the line status or the claim status. | | Perform Reconciliation | The legacy adjustment-plus-invoice path described in the Reconciliation section below. | | Edit, Delete | Standard record maintenance; a claim in a batch or already settled should not be deleted. | ## Status and approval The Claim **Status** picklist ships with **Draft** (default), **Pending Approval**, **Claim Approved**, **Claim Rejected** and **Reconcile**. Two more values are written by code rather than chosen: generation creates claims as **Draft**, and every settlement path sets **Settled**. Approval is an approval process on the Claim entity. No first-party approval process is shipped for claims, so the organization configures one (Setup → Automation → Approval Processes): its submission rule moves the claim to Pending Approval, and its final-approval field updates decide which status text is written on approval and rejection. Settlement listens to the approval decision, not to the status text: a decision of **Approved** on a Claim queues the per-claim settlement job for that claim; a rejection queues nothing. Claim types whose settlement setup is **Per Batch** are left for the batching sweep instead. Approval is partial by design. Approvers set the approved quantity per line (or use Approve All and then correct individual lines); whatever is approved settles, and the rejected remainder never becomes a payout. ## Config-driven generation @[guided-image](_img/claim-generation-list.png) A claim generation setup names a source entity and describes the whole pipeline declaratively — no code per claim type. The register shows each setup's claim type, source entity, schedule group, run order and its **Active** and **Simulate Mode** flags; inspect those two flags on the exact row before running anything, because a copied setup can carry a different state from the one its name suggests. | Setup element | What it controls | | --- | --- | | Source entity + filter expression | Which records are candidates | | Rules | Field/operator/value conditions on the Rules tab, combined with AND, OR or a custom logic formula | | Date window | Restricts candidates by a date field (last month, this month, last N days) | | Grouping fields | Which candidates merge into one claim | | Aggregation | **Sum** an amount field (with an optional formula) into one line, or **Per Record** — one claim line per source row | | Header and line mappings | Field-by-field mapping from source to claim, with tokens for constants, items, the aggregated amount and formatted text | | Netting | Subtract a second source's total per group (for example credit notes already issued) | | Owner resolution and supplier | Who owns the claim and who it is claimed from | | Claim type | Fixed on the setup, or read from a source field | Each run streams the source in batches, groups and aggregates, then builds a generation key `ClaimType|GroupKey|Period`, where the period is the month the run executes in. A claim with the same key is skipped on a rerun, whether or not a processed-source flag was configured; groups whose netting leaves nothing positive produce no claim. A setup that writes to a different target entity than Claim relies on the processed flag instead of the key. The full field reference and authoring procedure are in [Authoring a claim generation setup](/docs/sales/claims/generation-setups/). ## Scheduled runs and simulate mode Setups belong to a **schedule group** (Nightly, Weekly, Monthly (Day 1)) and carry a **Run Order**. A scheduled run executes only the active setups of its group in ascending run order, as a background job. The **Generate Claims** action on a setup enqueues that one setup regardless of its Active flag and returns a job run id; results are read on the **Jobs** screen (Setup → Administration → Jobs), where the run summary counts claims, lines and skipped candidates per setup. A simulated run reports what it would have written — including a preview of the first groups — without creating records or flagging sources. A setup can also auto-submit its new claims to the approval process; if that fails for a claim, generation is still successful and the failure is logged. ## Settlement setups A **Claim Settlement Setup** tells the settlement job what approval produces for one claim type. The job picks the active setup whose **Claim Type** equals the claim's type exactly; without one it stops with "No settlement setup for claim type". | Field | Meaning | | --- | --- | | Claim Type | Must match the value stamped on the claims. The setup's picklist is the generation engine's coded vocabulary and can differ from the Claim entity's own claim-type list. | | Settlement Document | **Credit Note** (default), **Invoice**, **Adjustment (Part to Part)** or **None** | | Header Mapping / Line Mapping | Optional JSON that shapes the resulting document; tokens `@approvedAmount`, `@approvedQuantity` and `@const:` are available | | Auto GL Posting | Posts the credit note or invoice after creation; for an adjustment it runs inventory posting | | Apply To Open Invoices | Knocks a credit note off against the partner's open invoices, oldest first; ignored for other document types | | Raise Event Name | Publishes a business-rule event after settlement, best-effort — it fires even when the document is None | | Settlement Grouping | **Per Claim** (default) or **Per Batch (consolidated)** | | Batch Grouping Fields, Batch Period, Batch Filter | How the batching sweep groups approved claims (see below) | | Active, Simulate Mode | Only active setups are used; a new setup starts in simulate mode | Saving refuses **Per Batch** together with **Adjustment**, and compiles the batch filter expression as a dry run. Keep **Simulate Mode** on until the approved quantities and mapped output agree with an independent calculation: in simulate mode the job reports the document it would have created and leaves the claim unsettled. ## Settlement Only an **Approved** approval decision queues the per-claim settlement job. The job follows the active setup for the claim type and works from the approved values only — lines with a zero approved quantity are dropped, and each remaining line is priced at unit price × approved quantity: - **Credit Note** — one line per approved claim line, linked back to the claim, optionally applied to open invoices and posted. - **Invoice** — bills the counterparty from the approved values and links the invoice to the claim. - **Adjustment** — a part-to-part inventory adjustment from the approved quantities, the shortage-claim path. - **None** — creates nothing and only raises the configured event. Every path checks its back-link (the claim's credit note, or an adjustment or invoice already carrying the claim id) before creating another document, so a rerun does not duplicate. On success the claim's status becomes **Settled**. The job appears as *Settle claim* on the Jobs screen, runs one claim at a time per organization, retries up to three times and can be triggered manually from there. ## Batches For a setup with **Per Batch** grouping, the *Batch claims for settlement* job sweeps claims of that type that have no batch and no credit note yet and that pass the setup's **Batch Filter** (default `Status == "Approved"`). Because the shipped status picklist has no plain "Approved" value, either the approval process must write exactly that text or the filter must be changed to match the status your process writes — otherwise the sweep finds nothing. Claims are grouped by **Batch Grouping Fields** (default partner account, branch and supplier account), plus the calendar month when **Batch Period** is Month; claims with no supplier account are skipped with a message. Each group becomes a Claim Batch named `CB-` in Draft status. An existing Draft, unreconciled batch for the same partner, branch and supplier is reused; a monthly batch is never reused. The sweep itself never settles anything. Settlement of a batch is started with the **Settle Batch** action on the Claim Batch record. It consolidates the approved claims into one credit note or one invoice (Adjustment is never batched); while any claim in the batch is still undecided the action is blocked unless it is run with the allow-partial option, which releases the undecided claims from the batch and settles the rest. Every settled claim is marked **Settled**. ## Reconciliation The Claim entity keeps a legacy **Perform Reconciliation** action. It attempts two things: an inventory adjustment from lines whose line claim type is part-to-part, and a sale invoice from **Reimbursment** lines with an approved quantity, then marks the claim reconciled (a flag; the status text is unchanged). The adjustment leg compares the line type against `Part to Part` while the shipped picklist value is `Part To Part`, so in practice only the invoice leg produces a document. It does not create a Claim Reconciliation record — that register in the app is a separate, manually maintained entity — and it is unrelated to the settlement job. Use it only where that adjustment-plus-invoice workflow is the organization's intended process. ## Common questions ### What does simulate mode actually do? On a generation setup it runs selection, rules, grouping, aggregation and netting, then reports the candidate groups in the job summary; it creates no records and changes no processed flags. On a settlement setup it makes the settlement job report the document it would have created and leave the claim unsettled. Read the flag on the exact setup you are about to run rather than trusting a name or an old screenshot. ### Can the same source records generate a claim twice? Not within a month for a plain Claim target: the `ClaimType|GroupKey|Period` key blocks a second claim for the same type, group and run month, and the run counts it as skipped. A rerun in the following month produces a new period and therefore a new claim unless a processed flag was configured. A custom target entity has no key guard and depends entirely on its processed flag; see the authoring page before using that mode. ### What happens when a claim is only partly approved? It settles partially. The credit note, invoice or adjustment is built from the approved quantities, so a claim approved at 60% produces a 60% document. The rejected remainder simply never becomes a payout. ### Why did an approved claim not settle? Check, in order: the approval decision was Approved (a status edit by hand does not trigger anything); an active Claim Settlement Setup exists whose Claim Type equals the claim's type exactly; that setup is not in simulate mode; the type is not Per Batch (which waits for a batch and Settle Batch); and the *Settle claim* job run on the Jobs screen for the claim's error text. ## Related topics - [Authoring a claim generation setup](/docs/sales/claims/generation-setups/) - [Trade schemes](/docs/sales/trade-schemes/) - [Invoicing and payments](/docs/sales/invoicing-and-payments/) - [xMatix Sales overview](/docs/sales/) ---- # Credit limits URL: https://xmatix.com/docs/sales/credit-limits/ Last reviewed: 2026-09-05 A credit limit in xMatix caps how much a customer may owe one selling company. It is a **Credit Limit** record keyed by **Partner Account** (the company extending credit) and **Account** (the customer), and its **Credit Limit Amount** is checked against the customer's live receivable exposure when a sales order or invoice is created. A customer over the limit is blocked from new documents with a message that names the customer, the open amount, the document amount and the limit. ## Where the records live Credit limits are ordinary records of the **Credit Limit** entity. In the first-party configuration they sit in the Field Sales setup list, so open the Field Sales app and choose **Credit Limits** from its settings entries; your administrator may also have added the entity to another app. Maintaining them is an administrator or finance task granted through the [security profile](/docs/administration/security-profiles/). ## Find the control record @[guided-image](_img/credit-limit-list.png) Start from the **All Credit Limits** list and find the exact selling-company/customer pair. The list shows the generated name, **Credit Limit Amount**, **Avaliable Limit** (the property really is spelled this way in the schema, so a query using the correct spelling matches nothing), **Utilized Limit** and **Credit Days**; open a record to see its **Partner Account** and **Account**. A record for a different pair does not govern the document: the handlers look the limit up by the document's partner account and customer account, and a limit stamped with another company is simply not found. ## Create or update a limit @[guided-image](_img/credit-limit-concept.png) Choose **New**, select the **Partner Account** and **Account**, enter a positive **Credit Limit Amount** and save. That amount is the only value the enforcement service reads: a null or zero limit is treated as *no limit*, not as zero credit, and lets every document through. **Credit Days** is informational; the gate compares amounts and never ages receivables, so due dates and overdue behaviour come from the documents themselves. **Utilized Limit** and **Avaliable Limit** are stored values that no first-party code refreshes or reads — do not type a calculated exposure into them and assume it is authoritative. The record has a **Status** of Draft, Pending Approval or Approved and shows an **Approval Process** panel, so your organization can route changes to a limit through an approval flow. Enforcement does not inspect that status: the check selects the row by company and customer alone, so a limit still in Draft blocks orders and invoices exactly as an Approved one does. Do not save an unapproved positive limit against a live customer as a staging step. Raising a limit is a credit decision: collect or settle valid balances, correct erroneous open items, and document approval before increasing risk. ## Read a saved record @[guided-image](_img/credit-limit-detail.png) The detail page shows the partner account in the header, the status stepper, **Credit Details** (limit, utilised, available) and **Account Details** (credit days, customer). Treat it as the configuration record, not as a live credit dashboard. To decide whether a document should pass, combine the positive ceiling here with the customer's current open receivable balance from the finance subledger. ## What counts as exposure Exposure is the sum of the customer's **open receivable transactions** with the selling company — receivable open items that are neither *Settled* nor *Reversed*, summed on their remaining open amount. These open items are created when invoices (and other receivable documents) are posted to the general ledger, and reduced when posted payments and credit notes are allocated against them. Exposure is recomputed from the subledger at the moment of the check, so collecting and posting a payment reduces it immediately; nothing is recalculated overnight, and the stored utilised and available columns play no part. ## How the gate works | Document | When checked | Rule | | --- | --- | --- | | Sales order | Header creation | Current exposure plus **Finance Amount** (falling back to **Total Amount**, then zero) must not exceed the limit. In interactive entry the lines do not exist yet, so the proposed amount is normally zero and the check gates the customer's existing position; API and import callers can supply an amount. | | Sales invoice | Header creation | Only when the invoice carries a positive **Finance Amount**: current exposure plus that amount must not exceed the limit. An invoice with no finance amount is not checked. | A clean breach rejects the save with *Credit limit exceeded for <customer>: open <amount> + this order/invoice <amount> would exceed the limit of <limit>*, pointing at the Account field. Edits to existing documents are not re-checked; only creation is. Both checks fail open. A customer with **no positive credit limit configured is never gated**, whatever their open receivables. The invoice check also skips silently if the finance subledger service cannot be resolved or queried, so monitoring that service is part of the control. And when the Sales module setting **Route credit limit breaches to an approval process** is on (Setup → Feature Hub → Sales → Settings, Credit Limit group; off by default), neither handler blocks — the tenant is expected to configure an approval process that gates the override instead. ## Releasing a blocked customer Three levers, in the order usually tried: 1. **Collect.** Record and post payments, or apply credit notes, against the customer's open invoices; the allocated open items shrink exposure at once. 2. **Adjust.** Settle or reverse stale open items that no longer reflect reality. 3. **Raise the ceiling.** Increase **Credit Limit Amount** on the record for that company/customer pair once the business has approved new terms. Editing **Utilized Limit** or **Avaliable Limit** does not release the gate because neither field participates in the calculation. ## Common questions ### Why was a small order blocked when the order itself fits easily? Because the customer was already over the limit before the order — the order-time gate normally weighs the customer's existing open position, since the new order has no lines yet. Even a tiny order is refused until exposure comes down; the message shows the open amount that caused it. ### Does an unpaid order count as exposure? No. Exposure comes from the receivables subledger, so it is the posted-but-unpaid position that counts. Orders not yet invoiced, and invoices not yet posted to the ledger, do not add to exposure — which is why the invoice-time check exists as the second gate. ### Can the same customer have different limits with different selling companies? Yes. Limits are kept per customer per partner account, and the check always runs in the context of the document's partner account — a customer can be blocked with one company and clear with another. ### Does the approval status on the credit limit matter? Only to your review process. A Draft, Pending Approval or Approved record is enforced identically; use the approval flow to control who may change the amount, not to hold a limit back from taking effect. ## Related topics - [Creating a sales order](/docs/sales/orders/create-order/) - [Invoicing and payments](/docs/sales/invoicing-and-payments/) - [Troubleshooting](/docs/sales/troubleshooting/) ---- # xMatix Sales URL: https://xmatix.com/docs/sales/ Last reviewed: 2026-09-05 xMatix Sales is the order-to-cash module of xMatix: it takes a sales order from capture through stock allocation, picking and delivery to invoicing and payment, with pricing driven by price lists and discount groups, ordering gated by customer credit limits, promotions applied by the trade scheme engine, and partner payouts handled as trade claims. This page maps the module and links every topic in this section. ## Read the workspace @[guided-image](_img/sales-overview.png) The **Orders** entry of the Sales app is the module's working register. Summary cards across the top report the last 30 days: total and draft sales orders show captured versus uncommitted demand, total amount shows value, and scheme discount versus total discount separates promotion cost from all other price concessions. The rows are sample business data, so you can follow the same customer, branch, amount and status from a card into an order. Use the register to explain those summaries. Document date, partner account (the selling company), branch, customer account and executive establish scope and ownership; total amount and status connect value to lifecycle. Filter a management question down to a concrete population, then open the source order to inspect lines, pricing, credit, tax, allocation and fulfilment evidence before intervening. The view switcher next to the list title changes which saved list you are looking at; **All Sale Orders** is the unfiltered register. ## The Sales app The Sales app appears in your app launcher when your administrator has granted it. Apps and their entries are metadata, so your tenant may differ, but the first-party Sales app is built around these entries: | Entry | What it holds | | --- | --- | | Home | Landing page with summary cards | | Orders | Sales orders and their lifecycle actions | | Invoices | Sales invoices, printing, e-invoice and e-way bill actions | | Payments | Payments recorded against orders and invoices | | Accounts | Customer accounts | | Bulk Conversion (or Order Processing) | The screen that invoices many orders at once | | Reports, Dashboards | Sales reporting | | Settings | The module's masters (below) | The **Settings** entry opens the Sales setup list, which holds the masters the module runs on: **Account**, **Account Group**, **Item**, **Item Group**, **Price List**, **Tax Group**, **Discount Group** and **Branch**. Orders, invoices and payments reference these, so set them up first. **Credit Limit** records live under the Field Sales setup list, and trade **Scheme** records under the Rewards app; both are linked below. ## What happens on an order Nothing downstream is produced by changing an order's status. Every stage is an explicit server action on the order, gated on per-line pending-quantity counters: - **Fulfilment** creates an inventory fulfilment document that reserves stock; **Auto Allocation** and **Manual Allocation** pick the lots. - **Delivery** (or its allocation- and picking-based variants) creates a delivery order. - **Invoice (OTC)** creates an invoice straight from the order, drawing stock over the counter; **Invoice** invoices the allocated lines; **Bulk Order** does the same for many orders at once. - **Payment** opens the payment form against the order so a receipt is recorded. - **Apply Scheme** commits a qualifying promotion slab; **Cancel** cancels all pending quantities. Line prices come from price-list rule resolution against the order's price list, discount-group rules add contract discounts, the tax-group service stamps header tax, and the credit-limit check runs when the order is first saved. Each of these is documented on its own page below. ## Section map | Page | What it covers | | --- | --- | | [The sales order lifecycle](/docs/sales/orders/) | The stages an order moves through and how partial processing works | | [Creating a sales order](/docs/sales/orders/create-order/) | Capturing an order: account, lines, pricing, schemes, submit | | [Allocating stock to orders](/docs/sales/orders/allocation/) | Automatic and selective allocation, plus cancelling reservations | | [Picking and fulfilment](/docs/sales/orders/picking-and-fulfilment/) | The fulfilment document: picking, confirmation, delivery release | | [Bulk order processing](/docs/sales/orders/bulk-processing/) | Invoicing many orders at once from the bulk conversion screen | | [Invoices](/docs/sales/invoices/) | Working with an invoice: post, deliver, print, e-invoice, cancel — fields, permissions and settings | | [Invoicing and payments](/docs/sales/invoicing-and-payments/) | Invoice release paths, payments, e-invoice and e-way bill (India) | | [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/) | Price lists, discount groups, tax groups, repricing | | [Credit limits](/docs/sales/credit-limits/) | How customer credit limits gate orders and invoices | | [Trade schemes](/docs/sales/trade-schemes/) | Scheme conditions, benefits, slabs, budgets and applying them | | [Trade claims](/docs/sales/claims/) | Config-driven claim generation, approval, batching and settlement | | [Troubleshooting](/docs/sales/troubleshooting/) | The situations sales users actually hit, and what to check | ## Common questions ### Do I need every master before I can take an order? You do not need every optional commercial master, but a valid order needs a customer account, a partner account (the selling company), a branch that belongs to that partner, and at least one item line. Without a matching price-list rule you must enter the unit price; without a discount-group rule no contract discount is added; without a matching tax rule no tax group is derived for the line. Configure [pricing, discounts and taxes](/docs/sales/pricing-and-discounts/) early so those defaults are predictable. ### Where do orders come from besides manual entry? Orders are created by hand in the Sales app. The **Order** action on a quote, opportunity or lead creates one from that record (a quote's lines are copied onto the order; a lead skips the opportunity and quote stages). Field-sales flows attach a captured order to its visit, and the dealer flow can pull a purchase order's lines into an order. The [order lifecycle](/docs/sales/orders/) page describes what happens after capture, whatever the source. ### Is xMatix Sales separate from field sales? They are separate apps on the same data. Field Sales covers routes, beats and in-store visit execution; the orders a rep captures on a visit are ordinary sales orders that flow through the lifecycle documented in this section. See the [Field Sales product page](/products/field-sales/). ### Who can see and use the Sales app? The app, each entity in it and each server action are granted through the user's [security profile](/docs/administration/security-profiles/) and the tenant's Sales licence. A user who can open the Orders list but cannot see an action such as **Fulfilment** or **Invoice** is missing the action permission, not the data. ## Related topics - [Navigating xMatix: apps, lists and records](/docs/getting-started/navigation/) - [Apps, entities and records](/docs/concepts/apps-entities-records/) - [Sales product overview](/products/sales/) ---- # Invoices URL: https://xmatix.com/docs/sales/invoices/ Last reviewed: 2026-10-10 A sales invoice is the xMatix document that bills a customer for goods or services and turns the sale into a receivable in the ledger. It is the last commercial step of order-to-cash: an order is captured, stock is allocated or drawn over the counter, the invoice is released, and payments then settle it. You find invoices in the **Sales** app and the **Finance** app, under **Invoices**. ## Overview An invoice has a header — the customer (**Account**), the selling company (**Partner Account**) and its **Branch**, the **Executive**, pricing and tax settings, addresses — and **Lines**, one per item billed. Almost every money figure on the header is calculated from the lines, so you change amounts by changing lines, not by typing totals. The invoice moves through three statuses: **Draft** while it is being prepared, **Posted** once its journal has been posted to the general ledger, and **Cancelled** once it has been cancelled. You do not pick the status yourself; posting and cancelling set it. For the bigger picture — the different ways invoices are released from orders, and how payments and advances settle them — see [Invoicing and payments](/docs/sales/invoicing-and-payments/). ## When to use it Most invoices are created for you by an action on an order (**Invoice (OTC)**, **Invoice**, the selective variants or bulk order processing), on a delivery order (**Create Invoice**) or by claim settlement. Use this page whenever you work with an invoice after that point — reviewing it, posting it, creating its delivery or shipment, printing it, raising its e-invoice or e-way bill, or cancelling it. Create an invoice by hand with **New** only when there is no order to bill from, for example a one-off charge. ## How xMatix handles it ### Read the screen The **Invoices** list opens on the **All Invoices** view. Summary cards across the top cover the last 30 days: **Total Invoices**, **Total Outstanding**, **Total Invoiced**, **Total Scheme Discount**, **Total Discount** and **Overdue Receivables** (outstanding invoices whose **Due Date** has passed). The shipped views are: | View | Shows | | --- | --- | | All Invoices | Every invoice (the default) | | Draft Invoices | Invoices whose status is Draft | | Posted Invoices | Invoices whose status is Posted | | Outstanding Invoices | Invoices with an **Outstanding Amount** above zero | Opening an invoice shows the header band with **Document Date**, **Order**, **Partner Account**, **Branch**, **Account**, **Executive** and **Status**, then three tabs: - **Lines** — the billed items with **Item**, **Quantity**, **Unit Price**, **Amount**, **Tax Amount** and **Gross Amount**. You add, edit and delete lines here. - **Details** — collapsible panels: **Key Details**, **Amounts**, **Taxes**, **GST & Place of Supply**, **e - Invoice**, **e - Way Bill**, **Billing Address**, **Shipping Address**, **Additional Information** and **System Details**. - **Related** — the records linked to this invoice, such as payments, delivery orders, shipments and journals. On the right, the **Amount Summary** panel shows the base amount, scheme discount, other discounts, any additional discount, tax and the total, then each payment recorded against the invoice and the remaining **Outstanding** figure. Below it, **Scheme Recommendations** lists trade schemes the invoice could qualify for. ### Which buttons you see, and when The header buttons depend on the invoice's status. On the shipped layout: | Button | Shown when | | --- | --- | | **Post General Ledger** | The invoice is Draft and has quantity still waiting for delivery | | **Post Inventory** | The invoice is Draft, has quantity waiting for delivery, and not every line has reached the inventory ledger | | **Delivery** | The invoice is Draft and has quantity waiting for delivery | | **Apply Scheme**, **Product Configurator** | The invoice is Draft and has quantity waiting for delivery | | **Create Shipment** | The invoice is Draft, has quantity waiting for delivery and was created from an order | | **Print Invoice** | The invoice is Posted and is not a repair-order invoice | | **Print Service Invoice** | The invoice is Posted and is linked to a repair order | | **E Invoice Generator**, **E Way Bill** | The invoice is Posted | | **Cancel** | The invoice is Posted | | **Full Page Invoice Print**, **Half Print**, **Edit**, **Delete** | Always | Each button also needs a grant on your security profile (see [Permissions](#permissions)). Layouts are tenant metadata, so your administrator may have changed this arrangement. ### What happens when an invoice is created Whichever path creates the invoice, the save does the following: - **Number.** The invoice gets a **Document Number** from document numbering. The shipped series is `INV`, followed by the day, month and year and a six-digit counter, joined by hyphens. - **Date.** **Document Date** is set to today when it is empty. A date in the future is pulled back to today — an invoice can never be dated ahead of the day it is saved. An earlier date supplied by the creating process is kept. - **Status.** The invoice starts as **Draft**. - **Company checks.** The partner account and branch are validated: the partner account must be an active partner account, the branch must belong to it and be active, and a branch is required when the partner account has branches. - **Credit check.** When the customer has a credit limit with this partner account, the invoice must fit under it — see [Credit limits](/docs/sales/credit-limits/). - **Tax supply type (India).** The invoice's **Tax Supply Type** is derived from where the goods are supplied from and to — Within State, Outside State or Exempt — and GSTIN, vehicle-number and contact-number formats are checked. ## Prerequisites - The **Sales** or **Finance** app is in your app launcher, and your security profile grants access to invoices and the actions you need. - The customer exists as an active customer account, and the selling company exists as an active partner account with its branches. - To post: the selling company's account has **GL Posting Enabled** switched on, the chart of accounts and posting definitions cover the invoice's items and taxes, and the accounting period of the document date is open. See [Chart of accounts](/docs/finance/chart-of-accounts/). - For e-invoices and e-way bills: your administrator has connected the GST integration. See [E-invoicing](/docs/finance/tax-center/e-invoicing/) and [E-way bills](/docs/finance/tax-center/e-way-bills/). ## Procedure ### Step 1 — Find an invoice Open **Sales** (or **Finance**) and choose **Invoices**. Pick a view from the view switcher — **Draft Invoices** for work in progress, **Posted Invoices** for billed documents, **Outstanding Invoices** for invoices still waiting for payment. Use search, column filters and sort to narrow the list, then open the invoice by its document number. An invoice released from an order also appears under that order's related records. ### Step 2 — Create an invoice by hand (only when there is no order) On the **Invoices** list choose **New**. The New Invoice form asks for: 1. **Account** (required) — the customer you are billing — and optionally **Contact**. Only active customer accounts are offered, and only contacts of that account. 2. **Invoice Configuration** tab — **Executive**, **Tax Supply Type**, **Price List** and **Discount Group**. 3. **Billing Address** and **Shipping Address** tabs — pick a saved address or fill street, city, state, postal code and country. 4. **System Details** tab — **Partner Account**, **Branch** (only branches of the chosen partner account are offered), **Supplier Branch** and **Tax Group**. Save. The invoice opens as **Draft** with its document number. Account, partner account and branch cannot be changed afterwards, so check them before saving. ### Step 3 — Add or correct lines On the **Lines** tab choose **New** to add a line, pick the **Item** and enter **Quantity**. **Unit Price** comes from the price list where a matching price rule exists; otherwise enter it. Edit or delete a line from its row. The line's **Amount**, **Tax Amount** and **Gross Amount**, and the header totals, recalculate when you save. To commit a qualifying promotion, choose **Apply Scheme** (see [Trade schemes](/docs/sales/trade-schemes/)). ### Step 4 — Post the invoice to the general ledger While the invoice is **Draft**, choose **Post General Ledger**. xMatix marks the invoice approved for posting, posts one balanced journal — the customer's receivable against sales and output tax — and opens a receivable item for the customer that payments later settle. GST tax records and any TCS or TDS postings are written at the same time. **Status** changes to **Posted**, and **GL Posting Status** shows the result. If the selling company does not have GL posting enabled, no journal is created. If an account cannot be resolved for a line, a tax or the header, posting stops with a message naming what is missing (see [Common problems](#common-problems)). ### Step 5 — Post the stock movement Choose **Post Inventory** to move the invoiced quantities out of stock for every line that has not yet reached the inventory ledger. The button disappears once every line is posted. If nothing is left to post, xMatix replies "No Invoice Lines found for Inventory Posting." ### Step 6 — Create the delivery or shipment - **Delivery** creates a delivery order from the lines that still have quantity to deliver. With nothing left to deliver, you see "No pending delivery quantities found in invoice lines to create delivery order." - **Create Shipment** creates a shipment for the invoiced lines; **Selective Create Shipment** does the same for the lines you choose. A shipment needs a **Supplier Branch** on the invoice when your organization uses branches. The new delivery order or shipment appears on the **Related** tab. ### Step 7 — Record a payment Choose **Payment** in the **Amount Summary** panel (or the **Payment** action) to open a payment form already linked to this invoice. Save the payment: **Amount Paid** goes up and **Outstanding Amount** goes down. Part-payments are fine — each one is its own record. Payments and advances are explained in [Invoicing and payments](/docs/sales/invoicing-and-payments/) and [Recording and applying payments](/docs/finance/payments/). ### Step 8 — Print or preview the invoice Once the invoice is **Posted**, choose **Print Invoice** (or **Print Service Invoice** for a repair-order invoice) to render the print format and open your browser's print dialog. **Full Page Invoice Print** and **Half Print** render the full-page and half-page formats. To print many invoices at once, select them on the list and run a print action there: each invoice starts on a new page of one PDF. Print formats are document reports your administrator maintains — see [Document reports](/docs/analytics/document-reports/). ### Step 9 — Generate the e-invoice and e-way bill (India) On a **Posted** invoice: 1. Choose **E Invoice Generator**. xMatix builds the e-invoice from the invoice and its lines and sets **Status (eInvoice)** to *Pending*. The connected GST integration registers it and writes back the **Invoice Reference Number (eInvoice)**, acknowledgement and **QR Code (eInvoice)**, and the status becomes *Generated*. 2. Choose **E Way Bill** to open the e-way bill panel, enter the distance, transport mode (Road, Rail, Air or Ship) and, for road transport, the vehicle number, and submit. The e-way bill number and date are recorded on the invoice when the integration returns them. Full details, including cancelling an e-way bill, are in [E-invoicing](/docs/finance/tax-center/e-invoicing/) and [E-way bills](/docs/finance/tax-center/e-way-bills/). ### Step 10 — Cancel an invoice Choose **Cancel** on a **Posted** invoice and confirm **Yes, cancel**. xMatix: - sets every line's cancelled quantity to its full quantity; - reverses the inventory movement; - reverses payments settled against the invoice, returning them to the customer's account; - reverses the invoice's journals, including any TCS journal, which clears the receivable; - removes the invoice's GST tax records. **Status** becomes **Cancelled**. Cancelling is allowed only within the cancellation window your administrator sets (24 hours from the document date unless changed). Past the window, raise a credit note instead. Cancelling does not cancel a registered e-invoice — handle that through your GST process. ### Step 11 — Copy or delete an invoice **Clone** creates a new Draft invoice with the same header and lines. **Delete** removes a Draft invoice permanently. An invoice whose journal has been posted cannot be deleted — cancel it instead. ### Step 12 — Work with invoices on mobile The Sales and Finance apps show invoices in the xMatix mobile app too. From an invoice you can record a payment, generate the e-invoice and work with its e-way bill. E-invoice and e-way bill actions need a connection: offline, the app says "e-Invoice generation is not available offline." or "E-way bills are not available offline." Save a new invoice before using them. ## Fields Header fields, in the order they appear on the New Invoice form and then the **Details** tab. | Field | What it means | Notes | | --- | --- | --- | | Account | The customer being billed | Required. Active customer accounts only. Cannot be changed after the invoice is saved | | Contact | The person at the customer | Only contacts of the chosen account | | Executive | The sales executive responsible | Active resources only. Required on the New Invoice form | | Tax Supply Type | Whether the supply is within the state, outside it or exempt | Within State, Outside State, Exempt. Derived from supply locations in India | | Price List | The price list line prices are read from | Read-only on the saved invoice | | Discount Group | The contract discount rules applied to lines | Read-only on the saved invoice | | Billing Address, Billing Street, Billing City, Billing State, Billing Postal Code, Billing Country | Where the invoice is addressed | Pick a saved address or fill the parts | | Shipping Address and its parts | Where the goods go | Same structure as billing | | Partner Account | The company that issues the invoice | Active partner accounts only. Cannot be changed after saving | | Branch | The issuing branch of that company | Only branches of the partner account. Cannot be changed after saving | | Supplier Branch | The branch the goods ship from | Needed to create a shipment | | Tax Group | The header tax group | Line taxes come from each line's tax group | | GL Account | The account the invoice posts against | | | Status | Draft, Posted or Cancelled | Set by posting and cancelling, never typed | | Total Line Amount | Sum of line amounts after discounts, before tax | Calculated | | Total Discount Amount | Sum of line discounts | Calculated | | Total Amount | Sum of line gross amounts plus any round-off | Calculated. This is what the customer owes | | Finance Amount | Amount a financier has disbursed against this invoice | System field, read-only | | Outstanding Amount | Total Amount minus Amount Paid | Calculated. Drives the Outstanding Invoices view | | Open Amount | Total Amount minus payment adjustments applied | Calculated | | Total Amount In Words | The total spelled out, for printing | Refreshed when the invoice is updated | | GSTIN, GST Invoice Type | The customer's GST number and the GST invoice type | GSTIN format is checked in India | | Place of Supply, Source of Supply | The states supplied to and from | Drive the tax supply type | | GL Posting Status | Draft, Partially Posted or Posted | Read-only | | Inventory Posting Status | Draft, Partially Posted or Posted, by lines posted to the inventory ledger | Calculated | | GL Posting Approved | Whether the invoice has been approved for ledger posting | Set by **Post General Ledger** | | Is IL Posting Approved | Whether every line has reached the inventory ledger | Calculated | | Skip Scheme | Keeps trade schemes from being applied to this invoice | | | Status (eInvoice) | Pending, Generated, Cancelled, Error, Ready For IRN | Maintained by the e-invoice actions and the integration | | QR Code (eInvoice), Invoice Reference Number (eInvoice) | The signed QR code and IRN returned on registration | Read-only; the IRN is unique | | Reverse Charge (eInvoice) | Whether reverse charge applies | | | Transaction Type | Claim Settlement for invoices raised by claim settlement | | | Order | The order the invoice was released from | Cannot be changed after saving | | Price As On Date | The date prices were read for | | | Payment Terms | The agreed payment terms, as text | Free text | | Claim, Claim Batch | The trade claim this invoice settles | | | Repair Order | The repair order this service invoice bills | Switches printing to **Print Service Invoice** | | Due Date | When payment is due | Drives the **Overdue Receivables** card | | Remarks | Free notes | | Line fields on the **Lines** tab: **Item**, **Quantity** and **Unit Price** (both default to 0), **Amount** (base amount less discounts and scheme discounts), **Tax Amount** and **Gross Amount** (amount plus tax). See the [Invoice Line reference](/docs/reference/entities/invoice-line/) for every line field. ## Business rules - **Numbering.** Every new invoice gets its **Document Number** from the *Invoice Document Name Setting*. A save that fails uses no number; a deleted invoice leaves a gap. - **No future dates.** A future **Document Date** is reset to the moment of saving. - **Fixed parties.** **Account**, **Partner Account**, **Branch** and **Order** cannot be changed once they have been saved with a value. - **Calculated money.** Totals, outstanding and open amounts are calculated from the lines and from payments; they cannot be typed. - **Status follows posting.** Shipped business rules set **Status** to *Posted* when the invoice is approved for ledger posting and to *Cancelled* when any line has a cancelled quantity. Changing the status by hand out of step with posting shows "Invoice Status Not Editable". - **Posting.** Posting needs the selling company's **GL Posting Enabled** switch, resolvable accounts for every line, tax and the header, and an open period. A cancelled invoice cannot be posted. - **Payments.** Each saved payment linked to the invoice updates **Amount Paid** and **Outstanding Amount**, on insert, change and delete. - **Cancellation.** Allowed only for a posted, not yet cancelled invoice, within the configured window measured from **Document Date**, while some line still has quantity to cancel. - **Deletion.** An invoice with a posted journal cannot be deleted. - **E-invoice.** Once an invoice has an IRN, the e-invoice cannot be generated again. ## Example A distributor's sales executive releases an invoice from an order for 40 cartons of tea at 250 each for a retail customer, *Sunrise General Store*, in the same state as the selling branch. The invoice opens as Draft with document number `INV-10102026-000318`, **Tax Supply Type** *Within State*, and lines carrying CGST and SGST. The **Amount Summary** shows a base of 10,000, a 500 scheme discount, tax of 475 and a **Total Amount** of 9,975. The executive's manager reviews the lines and chooses **Post General Ledger**: the status becomes **Posted** and the receivable appears for the customer. **Post Inventory** moves the 40 cartons out of stock, **Delivery** creates the delivery order, and **Print Invoice** produces the copy that travels with the goods. **E Invoice Generator** stages the e-invoice; a few minutes later the IRN and QR code appear in the **e - Invoice** panel. Next week the customer pays 5,000 in cash; the payment is recorded from the **Amount Summary** panel and **Outstanding Amount** drops to 4,975, which keeps the invoice in the **Outstanding Invoices** view until the balance is paid. ## Training ### Practice exercise In a sandbox tenant with a partner account whose **GL Posting Enabled** is on: 1. Open a confirmed sales order with at least two lines and release an invoice with **Invoice (OTC)**. 2. Open the invoice. Check that its status is **Draft**, note its document number and compare the **Amount Summary** total with the order total. 3. Choose **Post General Ledger**. Expected result: **Status** is **Posted**, and a journal appears on the **Related** tab. 4. Choose **Post Inventory**. Expected result: the button disappears and **Inventory Posting Status** reads *Posted*. 5. Record a payment for half the total from the **Amount Summary** panel. Expected result: **Outstanding Amount** equals the other half, and the invoice is listed in **Outstanding Invoices**. 6. Choose **Cancel** and confirm. Expected result: **Status** is **Cancelled**, and the payment is no longer settled against the invoice. ### Quick reference - Invoices live in **Sales → Invoices** and **Finance → Invoices**. - Status is never typed: posting makes it **Posted**, cancelling makes it **Cancelled**. - Change amounts by changing lines — header totals are calculated. - Account, partner account and branch are fixed once the invoice is saved. - Post the ledger and the stock separately: **Post General Ledger**, then **Post Inventory**. - Print, e-invoice, e-way bill and cancel appear only on a **Posted** invoice. - Cancel within the window (24 hours by default); after that, raise a credit note. - A posted invoice cannot be deleted. ## Permissions Access is set on [security profiles](/docs/administration/security-profiles/): - **Entity access.** Read, Create, Update and Delete on Invoice decide whether a user sees invoices and can create, edit and delete them. The shipped *Sales*, *Sales Executive*, *Sales Manager* and *Service* profiles have full access. - **Actions.** Every invoice button needs its own grant on the profile's **Actions** tab; without it the button is not shown. The shipped grants are: | Action | Shipped profiles granted | | --- | --- | | New | Sales Manager, Standard User, System Admin | | Edit (record form) | Sales Executive, Standard User, System Admin | | Delete | Sales Executive, Sales Manager, Standard User, System Admin | | Post General Ledger | Sales Manager, Standard User | | Post Inventory | Sales Manager, Standard User, System Admin | | Delivery | Sales Executive, Sales Manager, Standard User | | Create Shipment | Sales Executive, Standard User, System Admin | | Apply Scheme | Sales Executive, Sales Manager, Standard User, System Admin | | Payment | Sales Manager, Standard User, System Admin | | Print Invoice | Sales Manager, Standard User | | Print Service Invoice, Preview | Standard User, System Admin | | E Invoice Generator, E Way Bill | Sales Executive, Sales Manager, Standard User | | Cancel | Sales Executive, Standard User, System Admin | | Clone | Sales Executive, Standard User, System Admin | **Full Page Invoice Print** and **Half Print** have no shipped grant: add them to the profiles that should print those formats. The actions that record e-way bill results from the integration are granted to System Admin only and should stay with administrators or the integration's profile. A print action also needs the document report it renders to be shared with the user. ## Configuration Administrators tailor invoices in these places: - **Cancellation window.** **Setup → Feature Hub → Administration → Module Settings → Sales**, group **Invoicing**: **Cancel Invoice allowed within (hours, 0 = no limit)**. Default 24, range 0 to 8760; 0 allows cancellation at any time. The window is measured from the invoice's document date. The confirmation dialog's text mentions 24 hours whatever value you set, so tell users if you change it. - **Credit-limit enforcement.** Same page, group **Credit Limit**: **Route credit limit breaches to an approval process**. Off (default) blocks an invoice that breaches the customer's limit; on skips the block so that an approval process you configure can govern overrides. See [Credit limits](/docs/sales/credit-limits/). - **Free item stock.** Same page, group **Schemes**: **Check free item stock when adding an invoice line**. Off (default) checks stock for scheme free items only at inventory posting; on refuses a line whose earned free item is out of stock. - **Imported invoice rounding.** Same page, group **Invoicing**: **Round imported invoice tax by group**, for invoices imported from another system. - **Document numbering.** **Setup → Feature Hub → Platform → Document Settings**, *Invoice Document Name Setting* (series `INV`, date part, six-digit counter). Changing the series or date format restarts the counter. See [Email templates and document numbering](/docs/administration/templates/). - **GL posting.** Switch on **GL Posting Enabled** on the selling company's account record. Without it, posting creates no journal. Posting definitions and the chart of accounts decide which accounts each line and tax hits — see [Chart of accounts](/docs/finance/chart-of-accounts/). - **Print formats.** The print buttons render document reports. Change a format in the report designer and wire new print buttons as entity actions — see [Document reports](/docs/analytics/document-reports/). - **Pricing, discounts and taxes.** Price lists, discount groups and tax groups decide line prices and taxes — see [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/). - **Layouts and views.** The record layout, the button visibility conditions and the list views are tenant metadata you can change in Design Studio. - **Business rules.** The shipped rules that set the status to Posted and Cancelled are editable business rules; keep them in step with posting if you change them. See [Business rules](/docs/customization/business-rules/). - **GST integration.** E-invoice registration and e-way bill generation need the GST integration connected — see [E-invoicing](/docs/finance/tax-center/e-invoicing/). ## Common problems ### I can't find Post General Ledger, Delivery or Apply Scheme On the shipped layout these buttons show only while the invoice is **Draft** and still has quantity waiting for delivery. A posted invoice no longer shows them. If the invoice is Draft and they are still missing, your profile lacks the action grant. ### "Only a posted invoice can be cancelled." The invoice's journal has not been posted, or it is already cancelled. Post it first, or — if it is still Draft — delete it instead of cancelling. ### "An invoice can only be cancelled within 24 hours." The cancellation window, counted from the document date, has passed. The message gives the invoice's date and how many hours ago that was. Raise a credit note instead. Administrators can change the window in the Sales module settings. ### "No eligible invoice lines found to cancel." Every line has already been cancelled. There is nothing left to reverse. ### "Invoice 'INV-…' has a posted GL journal and cannot be deleted. Reverse or un-approve it first." A posted invoice cannot be deleted because its journal and receivable would be left behind. Cancel it within the window, or raise a credit note. ### "Credit limit exceeded for …" The customer's open receivables plus this invoice would exceed their credit limit with this company. Collect payment, raise the limit, or ask your administrator about approval-based overrides. See [Credit limits](/docs/sales/credit-limits/). ### "Key fields are not editable once the related objects are added." You tried to change **Account**, **Partner Account**, **Branch** or **Order** after the invoice was saved with a value in it. These fields are fixed for the life of the invoice. Create a new invoice for the other party instead. ### "No GL account resolved for line '…'. Configure a PostingDefinition or a chart-of-accounts default." Posting could not find the account for an item, a tax, the header or the counterpart. An administrator needs to add a posting definition or a chart-of-accounts default for it, then post again. A similar message appears for tax lines, round-off and reverse-charge GST. ### "A cancelled invoice cannot be posted." The invoice is cancelled. Create a new invoice if the sale is still valid. ### "This invoice already has an IRN; an e-invoice cannot be regenerated." The invoice is already registered. Corrections after registration go through credit notes. ### "HSN/SAC code is required for e-invoicing on line '…'." A line's item has no HSN or SAC code. Add it to the item, then generate the e-invoice again. ### "Supplier Branch is required to create a shipment." Fill **Supplier Branch** on the invoice, then choose **Create Shipment** again. ### I posted the invoice but no journal appeared The selling company's account does not have **GL Posting Enabled** switched on, so posting was skipped. Ask an administrator to switch it on, then post again. ## Common questions ### Why can't I change the status myself? Status reflects what has happened in the ledger. Shipped business rules set it to Posted when the invoice is approved for posting and to Cancelled when its lines are cancelled. Typing a status that disagrees with the posting would make the invoice say it was billed when no journal exists, so xMatix shows "Invoice Status Not Editable" instead. Use **Post General Ledger** or **Cancel** to move it. ### Do I have to post the ledger and the stock separately? Yes. **Post General Ledger** writes the accounting entries and the customer's receivable; **Post Inventory** moves the stock out of the warehouse. They are separate so that finance and the warehouse can act independently. **GL Posting Status** and **Inventory Posting Status** on the **Details** tab show where each stands. ### What is the difference between Outstanding Amount and Open Amount? **Outstanding Amount** is the total minus every payment linked to the invoice. **Open Amount** is the total minus payment adjustments applied to it. They agree once every payment has also been applied. The ledger's own view of what the customer owes is the receivable item created at posting. ### Can I change the date of an invoice? You can set an earlier date, and posting uses the document date for the journal, provided that accounting period is still open. You cannot date an invoice in the future: a future date is reset to the time of saving. Keep in mind that the cancellation window is measured from the document date, so an older date shortens the time left to cancel. ### Why does the Cancel confirmation say 24 hours when our window is different? The confirmation text is fixed. The window that is actually enforced is the one in the Sales module settings, and the error message when it has passed shows the real number of hours. ## Related topics - [Invoicing and payments](/docs/sales/invoicing-and-payments/) - [The sales order lifecycle](/docs/sales/orders/) - [Bulk order processing](/docs/sales/orders/bulk-processing/) - [Credit limits](/docs/sales/credit-limits/) - [Trade schemes](/docs/sales/trade-schemes/) - [Recording and applying payments](/docs/finance/payments/) - [E-invoicing](/docs/finance/tax-center/e-invoicing/) - [E-way bills](/docs/finance/tax-center/e-way-bills/) - [Document reports](/docs/analytics/document-reports/) - [Invoice — entity reference](/docs/reference/entities/invoice/) ---- # Invoicing and payments URL: https://xmatix.com/docs/sales/invoicing-and-payments/ Last reviewed: 2026-10-10 Invoices in xMatix Sales are released from orders — over the counter for pending quantities, or for allocated lines at the end of the warehouse flow — and can also be created from delivery orders, in bulk, or by hand. Payments are their own records: a payment tagged to an invoice rolls up into the invoice's paid and outstanding figures and, when posted, settles the receivable open item in the ledger. For India, the invoice carries the e-invoice (IRN) and e-way bill actions. ## Read the screen @[guided-image](_img/invoices-list-concept.png) The **Invoices** entry of the Sales app opens the register with 30-day summary cards: total invoices, total outstanding, total invoiced, scheme discount, total discount and overdue receivables. Read a row as both a commercial document and a future settlement target: document date and number establish identity, partner account and branch establish the billing company, account identifies the debtor, total amount establishes exposure and status shows whether the invoice has reached the ledger. Do not infer settlement from the existence of an invoice; open it and read the payments behind the outstanding figure. ### Read an invoice record @[guided-image](_img/invoice-detail-lines.png) **Lines** is the billed detail. Each line carries item, quantity, unit price, net discount, net scheme discount, tax group and tax amount, and every money field on the header is a roll-up of these lines rather than a typed value. The **Amount Summary** panel restates the roll-ups — base amount, scheme and other discounts, tax and total — and lists every payment tagged to the invoice with the resulting **Total Paid** and **Outstanding**. @[guided-image](_img/invoice-detail-details.png) **Details** groups the header: **Key Details** (partner account, branch, customer account, executive, GL account, status and e-invoice status), **Amounts** and **Taxes**. **Status** is Draft, Posted or Cancelled: it follows the GL posting approval flag and cancellation rather than being typed. **Status (eInvoice)** is a separate lifecycle: Ready For IRN, then Pending once the payload is staged, then the IRN and acknowledgement once the GST integration has returned them. **Related** lists the delivery orders released from the invoice and the journals posted for it. ## How an invoice is created | Path | Action | Behaviour | | --- | --- | --- | | Over the counter | **Invoice (OTC)** on the order | Invoices the order's pending quantities directly, drawing available stock | | From allocation | **Invoice** on the order | Invoices the quantities already allocated to the order | | Selective | **Selective Invoice OTC** / **Selective Invoice** on the order | Chosen lines and quantities only | | In bulk | [Bulk order processing](/docs/sales/orders/bulk-processing/) | Many orders at once, with shortfall reporting | | From delivery | **Create Invoice** on the delivery order | Invoices the delivered lines that still have pending invoice quantity; refuses when none do | | From a claim | Claim and claim-batch settlement | See [Trade claims](/docs/sales/claims/) | | By hand | **New** on the Invoices list | A Draft header you add lines to yourself | Whichever path creates it, the invoice header gets today's document date (a caller-supplied earlier date is honoured on insert; a future date is never accepted), a generated document number and **Draft** status. Account, partner account and branch are then fixed. **Credit check.** When the invoice is created with a finance amount and the customer has a credit limit with this partner account, the customer's open receivables plus this invoice must fit under the limit, or the save is rejected with a message naming the party, the open amount and the limit. The check is deliberately fail-open: if the finance subledger cannot be resolved or queried, or the Sales module setting *credit limit override requires approval* is on (an approval process then governs the override), the invoice is created without a hard block. Finance administrators should monitor the subledger rather than treat every created invoice as proof of a passed check. ## Working on an invoice | Action | What it does | | --- | --- | | **Post General Ledger** | Sets the GL posting approval flag and posts one balanced journal (Dr Accounts Receivable / Cr Sales plus output tax) together with a Receivable open item — the row the AR subledger ages and settles. Re-posting is reverse-then-repost. A business rule moves **Status** to Posted. | | **Post Inventory** | Runs the inventory ledger for lines that have not yet reached it; refused when every line is already posted. | | **Delivery** | Creates a delivery order from the lines with pending delivery quantity; refused when nothing is pending. | | **Create Shipment** / **Selective Create Shipment** | Create a shipment for the invoiced lines. | | **Payment** | Opens a form to record a new Payment tagged to this invoice (also available from the Amount Summary panel). Nothing runs on the server for the action itself; the saved payment is what changes the figures. | | **Reprice**, **Apply Scheme** and the other scheme actions | Behave as on the order; see [Trade schemes](/docs/sales/trade-schemes/). | | **Print Invoice**, **Preview** | Print or preview the document template. | | **Clone** | Copies the invoice into a new Draft. | | **Cancel** | Only a **Posted** invoice can be cancelled, only inside the *invoice cancellation window hours* configured for the Sales module (0 turns the window off), and only while at least one line still has quantity to cancel. Cancelling reverses the invoice's inventory movement, any payment received against it and its GL journals; the window defaults to 24 hours, and outside it the message tells you to raise a credit note instead. | A GL-posted invoice cannot be hard-deleted — deleting it would orphan its journal and receivable open item. ## Payments, advances and adjustments A **Payment** record is a single money movement. **Payment Type** gives it direction — *Payment Taken* is a customer receipt, *Payment Given* a disbursement — and **Amount** is always positive. **Mode Of Payment** (Cash, Cheque, Electronic Transfer) chooses the money-side ledger account when the payment posts; Cheque parks the amount in a cheques-in-hand account until it clears. - **Tagged to an invoice.** Set **Invoice** on the payment. The invoice's **Amount Paid** roll-up is recomputed on insert, edit and delete, and **Outstanding Amount** (total minus amount paid) falls with it. When the payment posts, a settlement allocation reduces the invoice's receivable open item. - **Tagged to an order (advance).** Set **Order** instead. The money accumulates as the order's **Advance Amount**; **Open Amount** is the order total minus that advance. Applying the advance to the order's invoices later is recorded as a payment adjustment against the order and is capped at the order's **Open Advance Amount** — you cannot adjust more than remains open. - **No document.** A receipt with no invoice or order posts as an unapplied, on-account open item for the customer that can be allocated later. Payments post as soon as they are inserted when the owning company has GL posting enabled; **Post General Ledger** on a payment simply turns the approval flag on for one that was withheld. The payment's own **Status** picklist is not maintained by the platform — judge posting from the GL flags and application from the open and adjusted amounts. A payment adjustment pairs a payment with an invoice or order (exactly two documents), and an adjustment larger than the invoice's current **Open Amount** is rejected. Settlement credit notes from [trade claims](/docs/sales/claims/) are netted against the partner's open invoices oldest-first through the same mechanism. ## E-invoice and e-way bill (India) **E Invoice Generator** on the invoice builds the e-invoice payload from the invoice and its lines, stores it on the invoice and moves **Status (eInvoice)** to *Pending*. The GST integration flow your administrator has connected transmits the payload to the invoice registration portal and writes the returned IRN, acknowledgement number and date and signed QR code back onto the invoice. Once an IRN exists the action refuses with "This invoice already has an IRN; an e-invoice cannot be regenerated." **Set E-Invoice Status** lets the integration (or an administrator) move the status explicitly. **E Way Bill** creates a Draft e-way bill register entry (the Part A consignment record) for the invoice, with optional distance, transport mode (Road by default) and vehicle number; the connected flow generates the e-way bill number and records it on the invoice. Delivery orders show e-way bill fields, but their own **E Way Bill** button is not bound to a handler and does nothing; generate from the invoice, and treat the delivery order's fields as manual capture. Both actions stage and record; the exchange with the GST systems is done by the integration. Without it, staged documents stay Pending. ## Common questions ### What is the difference between Invoice (OTC) and Invoice? **Invoice (OTC)** invoices the order's pending quantities immediately, drawing stock as it goes — no allocation needed. **Invoice** invoices only the quantities already allocated to the order, so what was reserved is exactly what is billed. Use OTC for counter sales and the allocated path for warehouse-fulfilled orders. ### Why do Outstanding Amount and Open Amount differ? They measure different things. **Outstanding Amount** is total minus the payments tagged to the invoice. **Open Amount** is total minus payment adjustments applied to it. They agree only when every payment has also been applied as an adjustment; the ledger's own view is the receivable open item created at posting. ### Can I regenerate an e-invoice? Not once an IRN has been recorded — the generator blocks with an explicit message, because a registered invoice must not be registered twice. Corrections after registration are handled through credit notes and the GST processes your organization follows. ### How do part-payments show up? Each payment is its own record. The invoice's Amount Summary lists every tagged payment with its mode and date, then Total Paid, Outstanding and the percentage paid. Nothing requires a single full payment. ## Related topics - [Invoices](/docs/sales/invoices/) — step-by-step procedures, fields, permissions and settings - [The sales order lifecycle](/docs/sales/orders/) - [Bulk order processing](/docs/sales/orders/bulk-processing/) - [Credit limits](/docs/sales/credit-limits/) - [Working with journals](/docs/finance/journals/) ---- # Allocating stock to orders URL: https://xmatix.com/docs/sales/orders/allocation/ Last reviewed: 2026-09-06 Allocation reserves specific stock against a sales order's lines before picking or invoicing. For a lot-tracked item it draws item lots at the order's branch, oldest first; for other inventory-tracked items it draws from the stock on hand; an item that tracks neither is skipped. Each reservation is an **allocation line** that posts immediately to the [inventory ledger](/docs/inventory/ledger/) into the stock's *Allocation* bucket, so the quantity stays in hand but stops being available to anyone else. Only stock at the order's own branch and partner account (selling company) counts. Every allocation action consumes the line's *pending fulfilment allocation quantity* (quantity − allocated − cancelled) and skips lines with nothing pending. ## Where allocation runs Allocation is available on two documents. Which one you use decides what happens when stock runs short. | Document | Actions | When a lot-tracked line cannot be fully covered | | --- | --- | --- | | Order (Sales app) | **Allocate** (labelled *Auto Allocation* in some tenants), **Selective Allocation**, **Manual Allocation**, **Fulfilment and Auto Allocate** | The action fails: *Item Lot not found for allocation.* Nothing is reserved for that run | | Fulfilment document (Warehouse app → Fulfilment Orders) | **Allocation** (*Perform Allocation*), **Selective Allocation** | The action reserves what eligible lots exist and leaves the remainder pending, without an error | Non-lot inventory items fail the same way on both documents when no stock is found: *Available stock not found for allocation.* A stock-out on the order side is therefore loud, while a shortfall on the fulfilment side is quiet — read the allocation lines and the remaining pending quantity after a warehouse-side run rather than assuming the whole demand was covered. ## Prerequisites - A saved order with lines whose pending fulfilment allocation quantity is above zero, or a fulfilment document released from it (see [Picking and fulfilment](/docs/sales/orders/picking-and-fulfilment/)). - Item lots (for lot-tracked items) or stock on hand (for other inventory items) at the order's branch and partner account. Lots carrying a hold code are never drawn. - Permission to run the allocation actions through your [security profile](/docs/administration/security-profiles/). ## Procedure @[guided-image](_img/allocation-pending-demand.png) ### Step 1 — Check what is pending On the order, open the lines and read each line's pending fulfilment allocation quantity; on a fulfilment document the **Inventory Fulfillment Order Line** grid shows **Quantity**, **Pending Allocation Quantity** and **Allocated Quantity** side by side. Lines with zero pending — already fully allocated, cancelled or never released — are skipped by every allocation action, and an action with nothing to do stops with *No pending allocation quantities found in order lines to create inventory fulfilment allocation.* (order) or *No pending allocated quantities found in fulfillment order lines to create allocation.* (fulfilment document). ### Step 2 — Allocate automatically Run **Allocate** on the order, or **Allocation** on the fulfilment document. For each eligible line the engine looks for lots (or stock) matching the item, the order's partner account and branch, and the line's SKU where one is set; it prefers the line's storage location but falls back to any location at the branch; it honours a preferred lot named on the line all-or-nothing; it excludes held lots; and where the line sets a *Limit Expiry Days* it excludes lots that expire too soon or carry no expiry date. Lots are consumed oldest first by creation time. One allocation line is written per lot or stock record drawn, each linked back to the order line and the fulfilment order line. ### Step 3 — Or allocate selected lines Run **Selective Allocation**, tick the lines and enter a **Requested Quantity** per line. An empty or zero request means the line's full pending quantity; a request above the pending quantity is rejected with *Requested quantity (n) cannot exceed the pending quantity (m).* **Manual Allocation** on the order goes one step further: it lists the available lots for a line (oldest or newest first) and reserves exactly the lots and quantities you pick, so it is the tool for choosing a specific batch for a customer. ### Step 4 — Verify the reservation Open the fulfilment document's **Allocation Line** grid (or the order's **Related** tab). Each positive row names the item, SKU, lot, storage location and stock record it reserved, with its quantity and the pending picking, delivery and invoice quantities that later actions will consume. The header's **Allocated Quantity** and **Pending Allocation Quantity** roll the lines up. An empty grid after a "successful" fulfilment-side run means no eligible lot existed — the action does not report that as an error. ### Step 5 — Undo if needed **Cancel Allocation** releases every allocation on the document; **Selective Cancel Allocation** releases chosen lines and quantities. A cancellation never edits the original row: it writes a negative allocation line pointing at it, which reverses the ledger posting and hands the quantity back to free stock and to the line's pending counter. Only quantity that has not moved on can be released — the cap is the line's *Eligible Return Quantity*, which is the allocation net of anything picked, delivered or invoiced — so cancel picking first where picking lines exist. ## Expected result Every order line's allocated and pending allocation quantities reconcile to its quantity, each allocation line traces to a lot or stock record at the order's branch, and the ledger shows the reserved quantity in the *Allocation* bucket without any stock leaving the warehouse. A second run consumes only the remainder; a cancellation restores exactly the released quantity. If the totals disagree, stop before picking or invoicing and inspect the allocation lines and the source availability rather than rerunning the action. ## Common problems - ***No pending allocation quantities found …*** — every line is already allocated or has nothing left; check the counters. - ***Item Lot not found for allocation.*** — an order-side run found no eligible lot for a lot-tracked line: none at this branch and partner account, all on hold, none meeting the expiry limit, or the preferred lot is unavailable. Fix the stock or allocate from the fulfilment document, which reserves what it can. - ***Available stock not found for allocation.*** — the same for a non-lot inventory item, on either document. - A quiet shortfall after a warehouse-side run — the allocation lines add up to less than the demand and the pending quantity is still positive. This is by design on the fulfilment document; replenish and run again. See [Troubleshooting](/docs/sales/troubleshooting/) for the wider checklist. ## Common questions ### In what order are lots consumed? Oldest first by the lot's creation time, on both documents. Storage-location sequencing is not applied. [Bulk order processing](/docs/sales/orders/bulk-processing/) and **Manual Allocation** offer a newest-first option for the stock they draw; the standard **Allocate** action does not. ### Can I allocate more than the ordered quantity? No. Every allocation action is capped at the line's pending fulfilment allocation quantity. To sell more, increase the order line's quantity first — while its transacted quantity still allows the change. ### Does allocation reduce stock on hand? It reduces stock *available*, not stock in hand: the allocation line posts the quantity into the ledger's *Allocation* bucket the moment it is saved. The stock leaves the warehouse when the delivery order or the invoice posts. Cancelling an allocation posts the reverse entry. ### Does the fulfilment document's status tell me whether it is allocated? Not reliably. The status badge and the *Allocated* flag on the fulfilment header are not maintained by the allocation actions; read the **Allocated Quantity** and **Pending Allocation Quantity** columns and the allocation lines instead. ## Related topics - [The sales order lifecycle](/docs/sales/orders/) - [Picking and fulfilment](/docs/sales/orders/picking-and-fulfilment/) - [Fulfilment picking (warehouse view)](/docs/warehouse/fulfilment-picking/) - [Bulk order processing](/docs/sales/orders/bulk-processing/) ---- # Bulk order processing URL: https://xmatix.com/docs/sales/orders/bulk-processing/ Last reviewed: 2026-09-05 The **Order Processing** screen in the Sales app (the page itself is titled **Bulk Processing**, and the Sales navigation entry may carry either label) advances many orders at once: it lists the orders in your scope that still have quantity pending invoicing, lets you select whole orders or individual lines, and turns the selection into draft invoices — drawing available stock as it goes and leaving anything it could not draw pending on the order. It needs no prior allocation, so it is the fastest route from confirmed orders to invoices for a branch and a day. ## Prerequisites - View access to the Order Processing page and the **Bulk Order** server action on Order (granted to the Sales Manager, Standard User and System Admin profiles by default), plus update permission on Order. - A field-sales resource linked to your user: the screen pre-fills Partner Account, Branch and Sales Executive from it. Without one you choose them by hand. - Orders with pending invoice quantity for the partner account, branch and document-date range you filter on. Pending invoice quantity is quantity minus cancelled minus already invoiced, per line. ## Procedure ### Step 1 — Set the scope The list loads as soon as the four mandatory filters are set — there is no search button. **Partner Account** (the selling company, in the header bar), **Branch**, **From Date** and **To Date** (both default to today) scope the query to orders whose document date falls in the range; **Sales Executive**, **Route** and **Account** narrow it further. Route offers only the routes of the chosen executive, and Account offers only the accounts on that route's stops, so changing an upstream filter clears the ones below it. Up to 500 orders are shown, newest first, and the header **Search** box filters them by document number, partner, branch, account or status. The screen title shows how many items match and when the list was last refreshed; **Refresh** reloads it. ### Step 2 — Choose the processing scope Work in one of two tabs. **Orders** processes whole orders: ticking an order selects every pending line at its full pending quantity. **Order Lines** lists the pending lines with **Available Stock**, **Quantity**, **Pending Invoice Quantity** and an editable **Requested Quantity**; ticking a line seeds the requested quantity from the pending quantity, and typing a quantity ticks the line. A requested quantity below the pending amount invoices just that much and leaves the rest pending. Lines from several orders can be selected together — each order is still processed with only its own lines. The requested quantity is validated on screen: it must be greater than zero, must not exceed the pending quantity, and for stock-tracked items must not exceed the available stock at the selected branch and partner account. Offending rows are listed in a **Please review the information below** dialog when you press Process. ### Step 3 — Pick the stock-draw options Choose the lot draw order — **FIFO** (first in, first out, the default) or **LIFO** — used for lot-tracked items; lots are ordered by their creation time and lots on hold are never drawn. **Exclude Stock Out** does two things. If any selected line currently fails the on-screen validation, pressing it unticks exactly those lines (a message reports how many were excluded) and leaves the valid selection ready. Whether or not lines were unticked, it also switches the server-side option on, so an order from which nothing at all can be drawn is skipped instead of failing. The button shows the number of failing lines while there are any. ### Step 4 — Process Press **Process** (it shows the selection count). The page is blocked with a **Processing...** overlay while the server works through the selection, one order per transaction, so keep the page open. For each order, lot-tracked lines draw from item lots in the chosen order, other stock-tracked lines draw from stock on hand, and lines with no item or a non-stock item (services, charges) are invoiced as-is. Stock is matched on the order's own branch and partner account and, where the line specifies them, its SKU, lot type and storage location; stock consumed by an earlier line in the same run is not available to a later one. A line that spans several lots becomes several invoice lines with the discount pro-rated. ### Step 5 — Review the result On success a **Processing Completed** dialog states how many orders were processed; on a mixed result a warning lists each rejected order with its reason and how many were accepted. Processed orders leave the Orders list, and processed lines leave the Order Lines list; rejected orders stay so you can correct and retry them. Each processed order has become a new **Invoice** in **Draft** status linked to the order, carrying the order's account, executive, price list and discount group. Nothing is posted: open the invoices (Sales → Invoices) to review, post and print them as described in [Invoicing and payments](/docs/sales/invoicing-and-payments/). ## Expected result Every selected order with at least one line that could draw stock has a draft invoice for the quantities drawn. A line that was only partly available is invoiced for the available quantity and keeps the remainder as pending invoice quantity on the order, so a later run picks it up after replenishment. The server records a per-line shortfall (no stock available, or partially fulfilled with the achieved quantity) for each such order, but the current screen only shows the success or failure count — read the resulting invoices against the orders to see what was short. With **Exclude Stock Out** on, an order from which nothing could be drawn produces no invoice but is still counted as processed and disappears from the list until the list is refreshed. ## Common problems An order that fails with "No stock available to allocate for item …" had no line with available stock: enable **Exclude Stock Out** to skip such orders, or fix the stock (right branch, right partner account, unheld lots for lot-tracked items). An order missing from the screen either has no pending invoice quantity left or falls outside your filters — check the date range first, since both dates default to today. An invoice smaller than expected is a partial-stock case; the remainder is still pending on the order. An Account list that seems incomplete is scoped to the first 60 accounts of the selected route's stops. ## Common questions ### Does bulk processing allocate stock or invoice it? It invoices. The screen creates draft invoices across the selection, drawing stock at invoice time without requiring prior allocation. Orders you want reserved ahead of invoicing should go through [allocation](/docs/sales/orders/allocation/) instead. ### Are the invoices posted? No. They are created in Draft with the current date as document date and are not posted to inventory or the general ledger; posting, e-invoicing and printing happen on each invoice afterwards. ### What exactly does Exclude Stock Out change? On the **Order Lines** tab, pressing it while selected rows fail validation first unticks exactly those rows. In both tabs it then turns on the server option under which an order with no drawable stock at all is skipped and reported as successful instead of failing. Partial availability is unaffected: the available quantity is invoiced and the rest stays pending. ### Can one order be processed twice? Each run consumes pending invoice quantity, so a fully invoiced order has nothing left and drops out of the query. A partly invoiced order reappears with its remaining pending quantity until it is completed or cancelled. ## Related topics - [The sales order lifecycle](/docs/sales/orders/) - [Invoicing and payments](/docs/sales/invoicing-and-payments/) - [Allocating stock to orders](/docs/sales/orders/allocation/) ---- # Creating and managing sales orders URL: https://xmatix.com/docs/sales/orders/create-order/ Last reviewed: 2026-10-10 A sales order records what a customer has agreed to buy from you: the customer, the selling company and branch, and one line per item with its quantity, price, discounts and tax. Every later step — releasing stock to the warehouse, allocating, delivering, invoicing and taking payment — is an action run on the order. It usually follows a [quote](/docs/crm/quotes/), an [opportunity](/docs/crm/opportunities/) or a field [visit](/docs/field-sales/visits/), and leads to [invoices and payments](/docs/sales/invoicing-and-payments/). This page covers creating and looking after the order itself. The stages that follow are explained in [the sales order lifecycle](/docs/sales/orders/). ## Overview Sales orders live in the **Sales** app under **Orders**. They are also listed in the **Commerce** app and open in the mobile app. The default list view is **All Orders**. A saved order has: - a header showing **Document Date**, **Partner Account**, **Branch**, **Account** and **Executive**, with the order's action buttons; - a **Status** stepper; - three tabs — **Lines**, **Related** (allocation lines, invoices and delivery orders) and **Details**; - an **Amount Summary**, **Scheme Recommendations** and **Sense AI insights** panel beside the tabs. ## When to use it Create a sales order when a customer commits to a purchase and you want the platform to reserve, deliver, invoice and track it. Typical cases: - a customer accepts a quote — create the order from the quote so it keeps the offered prices; - a deal is won on an opportunity — raise the order from the opportunity; - a field representative takes an order on a visit, often on the mobile app; - an order arrives by phone or at the counter and you capture it directly. If you only want to make a price offer, use a [quote](/docs/crm/quotes/) instead. To buy goods from a supplier, use a [purchase order](/docs/procurement/purchase-orders/). ## How xMatix handles it ### Where orders come from | Source | How | What is copied | | --- | --- | --- | | Created directly | **New** on the **Orders** list | Nothing — you enter the header, then add lines | | Quote | **Order** on the quote | The account, partner account and branch, and every quote line with its item, quantity, prices, discounts, tax group, SKU and lot type. A quote gives one order only. | | Opportunity | **Order** on the opportunity | The account, partner account, branch and executive, and each line's pending quantity. It can be run again for quantity added later. | | Visit | **Take Order** on the mobile app | The order is linked to the visit. Opening Take Order again on the same visit opens that order. | | Purchase order from another organization on the platform | **Dealer Order** on their purchase order | A sale order at your branch for the pending quantity, with the purchase order linked | ### Lines drive everything Each line keeps running counters of what has been released to fulfilment, allocated, picked, delivered, invoiced, cancelled and returned. Each action draws only on the matching *pending* quantity, so you can process an order in parts. The order header adds the counters up. The formulas are on [the sales order lifecycle](/docs/sales/orders/) page. ### Status and Document State **Status** is the stage shown on the stepper and in the list. The shipped values are *Draft*, *Fulfilment*, *Invoicing*, *Delivery* and *Cancelled*; your administrator can add more. A new order starts at *Draft*. Shipped business rules move Status whenever the order is saved, based on the pending quantities (see [Business rules](#business-rules)). Running an action never sets Status directly. **Document State** is a separate read-only field that records the last lifecycle action that succeeded. Its values are *Fulfilment Released*, *Fulfilment Partially Released*, *Allocated*, *Partially Allocated*, *Picked*, *Invoiced*, *Partially Invoiced*, *Delivered*, *Partially Delivered*, *Inventory Posted* and *Cancelled*. It is not on the shipped screens; add it to a list view if you want to see it. ### Pricing, discounts and tax When the order is created, the platform fills in: - the **Price List** (only if you left it empty), matched on the selling company, branch and the customer's account groups; - a matching **Discount Group**; - the account's default contact; - the account's default billing and shipping addresses. Each new line is then priced from the price list in force on the pricing date, discounted from the discount group, and taxed from the tax rules for its **Tax Supply Type**. If you type a non-zero unit price yourself, it is kept. Trade schemes set to apply automatically are evaluated as lines change. See [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/) and [Trade schemes](/docs/sales/trade-schemes/). ## Prerequisites - Your security profile gives you access to Order and Order Line, and to the actions you will run — see [Permissions](#permissions). - The customer is an active account marked as a customer. Only those can be picked in **Account**. - The selling company is an active partner account. If it has branches, you need one of its active branches. - The **Executive** is an active resource who is allowed to sell for that partner account and branch. - The items are active. Price-list rules exist for them, or you will type the unit prices. ## Procedure ### Step 1 — Find an order Open **Sales → Orders**. The cards at the top cover the last 30 days: - **Total Sale Orders** — the number of orders; - **Draft Sale Orders** — orders still at *Draft*; - **Total Amount**, **Total Scheme Discount** and **Total Discount** — sums for those orders. Switch views to see **Closed Orders**, **High-Value Order** (orders over 50,000) or **Pending Orders**. Search, filter and sort the columns, then open an order from its number. A row's menu also offers **Edit**, **Delete**, **Preview** (the printable order document) and **Attachments**. ### Step 2 — Create the order header Choose **New**. The form opens with **Account**, **Contact**, **Contact Number** and **Mobile** at the top, and four tabs: 1. **Order Configuration** — **Executive**, **Price List** and **Tax Supply Type** (*Within State* or *Outside State*), plus **Discount Group** where your organization's form includes it. 2. **Billing Address** — pick one of the account's addresses or type one. 3. **Shipping Address** — the same for the delivery destination. 4. **System Details** — **Partner Account** (the selling company) and **Branch** (the location it sells from). @[guided-image](_img/new-sales-order.png) **Account** and **Executive** are marked as required. Fill **Partner Account** and **Branch** too: saving without a partner account is refused. **Contact** lists only the chosen account's contacts, and **Branch** lists only the partner account's branches. @[guided-image](_img/order-tab-system.png) ### Step 3 — Check the addresses and commercial context Leave **Price List** empty to let the platform choose one when you save. The billing and shipping addresses are filled from the account's default addresses. Check them for customers with depots or job sites: the shipping address goes onto delivery documents, but stock is always drawn from the order's own partner account and branch. @[guided-image](_img/order-tab-billing.png) ### Step 4 — Save Choose **Save**. The order gets a number such as `SO-10102026-000001`, today's **Document Date** and Status *Draft*. The credit check runs at this point. If the customer's open receivables with this partner account are already over their credit limit, the save is refused with a message naming the customer, the open amount and the limit. See [Credit limits](/docs/sales/credit-limits/). **Account**, **Branch** and **Document Date** cannot be changed after this save. ### Step 5 — Add lines On the **Lines** tab, add items with: - the quick-add form; - **Product Catalogue**, a browsable item picker; - **Import**; - barcode scanning. The quick-add form asks for **Item**, **SKU**, **Item Lot Type**, **Quantity**, **Unit Price**, **Tax Group** and **Description**. It shows an **Item 360** panel with stock, schemes and alternates for the item. A line needs an item, or a description for a charge with no item. When you save a line, it is priced, discounted and taxed, and the **Amount Summary** updates. A package item with configurable components can be set up with **Product Configurator**. ### Step 6 — Review discounts and schemes If your administrator has added the header **Discount** field to the order page, a percentage entered there is copied to every line as **Order Discount**. It is not on the shipped forms. Schemes marked to apply automatically write their discounts or free items as lines change. Tick **Skip Scheme** (on **Details → Additional Details**) to turn them off for this order. Use **Apply Scheme** to apply a scheme you choose, and read the **Scheme Recommendations** panel for offers the order nearly qualifies for. To re-price every line from the price list, choose **Reprice**. Changing **Price As On Date** does the same for the price list in force on the new date. ### Step 7 — Get approval, if your organization uses it No approval process is shipped for sales orders. If your administrator has configured one, submit the order from the approval panel or the **Submit for Approval** button they added to the page. ### Step 8 — Process the order The buttons in the header change with the order's quantities. Each button appears only when there is something for it to do: | Button | Shown when | | --- | --- | | **Auto Allocation**, **Manual Allocation** | Lines are still to be allocated and nothing has been invoiced over the counter | | **Invoice ( OTC )**, **Selective Invoice OTC** | Something is still to be invoiced and nothing is allocated | | **Invoice**, **Selective Invoice** | Something is still to be invoiced and stock is allocated | | **Delivery**, **Selective Delivery** | Something is still to be delivered and nothing is waiting for allocation | | **Cancel Allocation** | Stock is allocated and Status is *Fulfilment* | | **Reprice**, **Product Configurator**, **Product Catalogue** | Status is *Draft* and lines are still to be allocated | | **Apply Scheme** | Status is *Draft* and something is still to be invoiced | | **Cancel Order** | Status is *Draft* | What each path creates is explained in [the sales order lifecycle](/docs/sales/orders/), [Allocating stock to orders](/docs/sales/orders/allocation/), [Picking and fulfilment](/docs/sales/orders/picking-and-fulfilment/) and [Bulk order processing](/docs/sales/orders/bulk-processing/). The documents an action creates appear on the **Related** tab. ### Step 9 — Record a payment When **Outstanding Amount** is above zero, the **Amount Summary** shows **Payment**. Choose it to open a payment form for the order, enter the receipt and save. See [Invoicing and payments](/docs/sales/invoicing-and-payments/). ### Step 10 — Change, cancel, clone or delete - **Change a line.** Edit its quantity, price or discount. You cannot lower a quantity below what has already been released to fulfilment, cancelled or returned. - **Cancel the rest of an order.** Use **Cancel Order** while Status is *Draft*. It cancels every line's quantity not yet released to fulfilment, and sets Document State to *Cancelled*. Quantity already released stays as it is. - **Copy an order.** **Clone** is available while Status is *Draft*. It asks you to confirm, then creates a new, separately numbered order from this one. Check the copy's lines, dates and prices before you process it. - **Delete.** **Delete** removes the order after you confirm. It cannot be undone. A line that has been released to fulfilment cannot be deleted. For an order that has already produced documents, use **Cancel Order** instead. ### Step 11 — Work on mobile On the mobile app, orders are usually taken during a visit with **Take Order**. You browse the catalogue (or scan barcodes), fill a cart and review the order summary. This works offline: prices, taxes and contract discounts are worked out on the device, and the order is sent when the device reconnects. It is saved at Status *Draft*. While it is still *Draft*, opening Take Order again on the same visit lets you edit it; at any other status it opens read-only. A saved order also opens on mobile with its **Lines**, **Related** and **Details** tabs, the same processing actions, and the **Amount Summary** with **Payment**. See [Complete a visit](/docs/field-sales/visits/complete-a-visit/). ## Fields ### Header | Field | What it means | Notes | | --- | --- | --- | | Document Number | The order's number | Generated on save; shipped format `SO-` + date as DDMMYYYY + six digits | | Document Date | The order's business date | Set to the current date and time on save; a future date is pulled back to now. Locked after save | | Account | The customer | Required. Active customer accounts only. Locked after save | | Contact, Contact Name, Contact Number, Mobile | The person you deal with at the customer | **Contact** lists the account's contacts. The default contact is filled in when you leave it empty | | Executive | Your sales person responsible for the order | Required on the form. Must be an active resource allowed to sell for the partner account and branch | | Partner Account | Your selling company | Required by the server. Active partner accounts only. May be hidden if your organization runs a single company | | Branch | The location you sell from | Must belong to the partner account and be active; required when the partner account has branches. Locked after save | | Price List | The price rules the lines are priced from | Filled on save when empty | | Discount Group | The discount rules for the lines | Filled on save when a matching group exists. Shown on **Details → Additional Details** | | Price As On Date | The date prices are taken from | Changing it re-prices every line | | Tax Supply Type | *Within State* or *Outside State* | Used to pick each line's tax group | | Tax Group | Header-level tax | Shown on **Details → Tax Details** | | Billing Address, Shipping Address | Where to invoice and where to deliver | A saved address of the account, plus Street, City, State, Postal Code and Country. Filled from the account's defaults | | Discount | A percentage applied to every line | Copied to each line as **Order Discount**. Not on the shipped forms | | Skip Scheme | Turns off automatic scheme evaluation for this order | On **Details → Additional Details** | | Remark | Free-text note | | | Status | The order's stage | *Draft* by default; moved by business rules — see below | | Advance Amount, Adjusted Advance Amount | Advance taken against the order, and how much of it has been used | **Open Amount** is **Total Amount** − **Advance Amount** | ### Amounts (read-only) | Field | What it means | | --- | --- | | Total Line Base Amount | Quantity × unit price over all lines, before discounts | | Total Scheme Amount | Discounts from trade schemes | | Total Discount Amount | Line discounts other than schemes | | Additional Discount | Discount given through discounted-item lines | | Total Line Tax Amount | Tax over all lines | | Total Line Amount | Sum of line amounts after discounts, before tax | | Total Amount | The order total including tax | | Outstanding Amount | Total Line Amount + tax − amount paid − financed amount. **Payment** appears while it is above zero | | Total Credit Amount | Amount paid less the financed amount | ### Lines | Field | What it means | Notes | | --- | --- | --- | | Item | What is sold | Required unless a Description is given. Must be active | | SKU | The variant of the item | Required for items that need one; must belong to the item | | Item Lot Type | The lot type to sell from | Takes part in price and tax matching | | Quantity | Quantity ordered | Required, above zero. Cannot drop below what is already released, cancelled or returned | | Unit Price | Price per unit | Filled from the price list; a non-zero price you type is kept. Bundled package components cannot be priced | | Tax Group | The line's taxes | Filled from tax rules | | Description | Free text, or the charge itself on a line without an item | | | Discount, Order Discount, Net Discount | Line discount, the header discount, and the resolved discount value | Percentages must be between 0 and 100 | | Net Scheme Discount | Discount from schemes on this line | | | Cancelled Quantity | Quantity cancelled | Cannot exceed the quantity | Every field, including system and calculated ones, is listed in the [Order entity reference](/docs/reference/entities/order/). ## Business rules - **Numbering.** Orders are numbered from the *Order Document Name Setting*: series `SO`, separator `-`, the document date as DDMMYYYY, and a six-digit counter. - **Partner, branch and customer.** The partner account must be given and active. The branch must belong to it and be active, and is required when the partner account has branches. The customer must be active. - **Executive.** Must be allowed to sell for the order's partner account and branch. - **Locked fields.** Account, Branch and Document Date cannot change once saved. - **Credit check.** Runs only when the order is first saved. It is skipped when the Sales setting routes credit-limit breaches to an approval process. - **Header changes reach the lines.** Changing **Discount** updates every line's Order Discount. Changing **Price As On Date** re-prices every line. Changing **Skip Scheme** re-evaluates schemes. - **Line quantities.** A line's quantity cannot be reduced below its released, cancelled and returned quantity, and cannot be cancelled beyond what is still pending. A line with quantity released to fulfilment cannot be deleted. - **Status rules.** Four shipped rules run before every save of the order (a rule only fires when the order has lines): | Rule | Sets Status to | When | | --- | --- | --- | | *Set Sale Order Status To Closed* | Closed | Nothing left to deliver and nothing left to invoice | | *Set Sale Order Status To Delivery* | Delivery | Nothing left to deliver | | *Set Sales Order Status To Invoicing* | Invoicing | Nothing left to invoice | | *Set Sale Order Status To Fulfilment* | Fulfilment | Nothing left to allocate | When more than one applies, the first one in the table wins. - **Manual status changes.** The rule *Order Status Not Editable* refuses a hand-made change to *Fulfilment*, *Invoicing*, *Delivery* or *Closed* while the matching quantity is still pending. - **Downstream links.** Lines created from an opportunity or a dealer purchase order count against the source line, so the same quantity is not ordered twice. ## Example A building-materials distributor takes a phone order from a contractor for 200 bags of cement and 40 lengths of steel bar. The sales coordinator opens **Sales → Orders**, chooses **New** and picks the contractor as **Account** and themself as **Executive**. On **System Details** they choose the distributor's company and its north depot, then save. The order opens as `SO-10102026-000007` at *Draft*, and the sale price list has been filled in. They add two lines. Cement is priced at 380 per bag and steel bar at 610 per length from the price list, and an automatic volume scheme adds a 2% scheme discount on the cement. The Amount Summary shows the total with tax. The contractor needs the cement first, so the coordinator runs **Selective Invoice OTC** for the 200 bags of cement only. A draft invoice appears on the **Related** tab, and the cement line has nothing left to invoice; the steel bar is still pending, so Status stays *Draft*. The following week the coordinator runs **Invoice ( OTC )**, which invoices just the 40 lengths of steel bar. With nothing left to invoice on any line, the next save of the order sets Status to *Invoicing*. Delivery then follows the path described in [the sales order lifecycle](/docs/sales/orders/). ## Training ### Practice exercise In a sandbox, as a user with the Sales Executive or System Admin profile: 1. Create an order for a test customer, partner account and branch. Expected: an `SO-` number, today's document date and Status *Draft*. 2. Try to change **Branch** with **Edit**. Expected: the save is refused with *Key fields are not editable once the related objects are added.*, naming the field. 3. Add a line for a stock item, quantity 10, and leave **Unit Price** empty. Expected: the price is filled from the price list and the Amount Summary updates. 4. Run **Selective Invoice OTC** for 4 of the 10. Expected: a draft invoice on **Related**, 6 still pending to invoice, and Status still *Draft*. 5. Run **Invoice ( OTC )**. Expected: a second draft invoice for the remaining 6, and Status *Invoicing* after the order is next saved. 6. Create a second order with one line and choose **Cancel Order**. Expected: the line's quantity moves to Cancelled Quantity and Document State becomes *Cancelled*; Status does not change. 7. Choose **Cancel Order** again. Expected: *No eligible order lines found to cancel.* ### Quick reference - Account, Branch and Document Date lock on the first save — check them first. - Leave Price List empty to get the default; a typed unit price is kept. - Buttons appear only when their quantity is pending. - *Invoice ( OTC )* invoices without allocation; *Invoice* bills allocated stock. - Status follows the quantities through business rules; Document State records the last action. - **Cancel Order** cancels the unreleased remainder; it works only at *Draft*. - **Skip Scheme** stops automatic schemes on one order. - Orders taken on a visit on mobile work offline and stay at *Draft*. ## Permissions Access is set on [security profiles](/docs/administration/security-profiles/) in **Setup → Access Control → Profiles**. - **Entity access.** The shipped *System Admin*, *Standard User*, *Sales Manager* and *Sales Executive* profiles have full access to Order — read, create, edit, delete, share, assign, View All and Modify All. Users who add or change lines also need access to Order Line. - **Actions.** Each action button — Auto Allocation, Invoice ( OTC ), Delivery, Reprice, Apply Scheme, Cancel Order, Clone and the others — is granted separately on the profile's **Actions** tab. A user without the grant does not see the button. If the action is run another way, it is refused with *The current user is not allowed to execute server action '…' on entity 'Order'.* - **Record sharing.** Orders are owned by a user; which colleagues' orders you see follows your organization's sharing settings — see [record security](/docs/administration/record-security/). - **Approvals.** Submitting for approval needs edit access to the order. ## Configuration - **Document numbering.** **Setup → Feature Hub → Platform → Document Settings**, *Order Document Name Setting*: series `SO`, separator `-`, date format DDMMYYYY, six digits. Because the date includes the day, the counter starts again at 000001 each day. Order lines have their own setting. See [Email templates and document numbering](/docs/administration/templates/). - **Sales settings.** **Setup → Feature Hub → Sales → Settings**, group **Credit Limit**: **Route credit limit breaches to an approval process** (off by default). Off: an order for a customer over the limit is refused when it is saved. On: the check is skipped, so that an approval process you configure can govern it. The limits themselves are set per partner account and customer — see [Credit limits](/docs/sales/credit-limits/). - **Approval.** No approval process is shipped for orders. Create one in **Setup → Process Studio → Approvals** (or in the Order entity's **Approval Processes**). Add the approval panel or a **Submit for Approval** button to the order page so users can submit. See [Approval processes](/docs/customization/approvals/). - **Status rules.** The four *Set … Status To …* rules and *Order Status Not Editable* are in **Setup → Process Studio → Business Rules**. Deactivate or change them there if your organization tracks status differently — for example, from Document State. The *Closed* rule writes a value that is not in the shipped Status picklist. Add *Closed* to the picklist if you want it on the stepper; the **Closed Orders** and **Pending Orders** views filter on it. See [Business rules](/docs/customization/business-rules/). - **Status picklist.** Add values such as an approval stage in the Order entity's field settings. If you add values, keep the list views and business rules in step. - **Shipped validations.** *Booking Amount Validation* and *DMS Credit Check Validation* take effect only when Status is *Booked* or *Credit Verified*. Those values are not in the shipped picklist, so the validations do nothing unless you add them. - **Layouts, views and buttons.** The create form, record page, header buttons and the conditions that show them, and the list views and cards, are metadata you change in Design Studio. Some actions are shipped but not on the record page — for example **Fulfilment**, **Selective Fulfilment**, **Fulfilment and Auto Allocate**, **Allocation Delivery**, **Selective Cancel Allocation**, **Reset Scheme** and **Post Inventory**. Add them where your process needs them. The picking actions on the order are shipped switched off; picking runs on the fulfilment document. - **Lookup filters.** The shipped filters limit **Account** to active customer accounts, **Partner Account** to active partner accounts, **Branch** to the partner account's branches, **Contact** to the account's contacts, **Executive** to active resources and **Discount Group** to active groups. - **Pricing.** Price lists, discount groups and tax rules are kept in the Sales app's **Settings → Pricing & Tax**. See [Pricing, discounts and taxes](/docs/sales/pricing-and-discounts/). Trade schemes are set up in the Rewards app — see [Trade schemes](/docs/sales/trade-schemes/). - **Print.** The row **Preview** on the list uses the shipped order document report. See [Document reports](/docs/analytics/document-reports/). - **Mobile.** The Take Order screen on visits, suggested quantities and frequently ordered items are configured for field sales — see [Field sales](/docs/field-sales/). ## Common problems ### "Invalid Partner Account." or "Branch is required for this Partner Account." **Partner Account** on **System Details** is empty, or the partner account has branches and none was chosen. Fill both. *Invalid Branch for Partner Account.* means the branch belongs to another company. ### "Resource is not authorized for Partner Account '…'." or "… for branch '…'." The **Executive** is not set up to sell for this company or branch. Choose another executive, or ask your administrator to extend the resource's partner and branch assignments. ### "Credit limit exceeded for …" The customer's open receivables with this selling company are already over their credit limit. Collect payment or ask for the limit to be raised — see [Credit limits](/docs/sales/credit-limits/). ### "Key fields are not editable once the related objects are added. Field Name : …" You changed **Account**, **Branch** or **Document Date** on a saved order. These cannot change. Cancel the order with **Cancel Order** and create a new one. ### "Transacted quantity (…) cannot be reduced. Attempted quantity: …" Part of the line has already been released to fulfilment, cancelled or returned. Enter a quantity at least that high. To stop the rest, use **Cancel Order**. ### "Cannot cancel quantity beyond pending invoice and fulfillment order quantities." The cancelled quantity you entered is more than is still pending on the line. Lower it. ### "There are downstream transactions. The record cannot be deleted." The line has quantity released to fulfilment. Leave the line and cancel its remaining quantity instead. ### "Select an Item or enter a Description." A line needs either an item or, for a charge with no item, a description. ### "SKU is required for this item." or "Invalid SKU selected for this item." The item is sold by SKU. Pick one of that item's SKUs. ### "This is a bundled item. You can not specify price for it" The line is a component of a package priced as a bundle. Its price comes from the package, so leave **Unit Price** alone. ### "Order Status Not Editable" You set Status by hand to a stage the quantities do not support yet. Run the action instead; Status follows on save. ### "No Order Line found for Repricing." **Reprice** needs at least one line. Add lines first. ### "No eligible order lines found to cancel." Every line's quantity has already been released to fulfilment or cancelled, so **Cancel Order** has nothing left to cancel. ### A button I need is missing Buttons show only when their condition is met (see Step 8), and only if your profile grants the action. For example, **Invoice ( OTC )** disappears once stock is allocated — use **Invoice** then. **Cancel Order**, **Clone** and **Reprice** show only at *Draft*. ### The unit price stays empty No price-list rule is in force for the item on the order's pricing date. Check the rule's dates and the order's **Price List**, or type the price. ## Common questions ### Can I raise more than one order from the same quote or opportunity? From a quote, no: **Order** works once and a second run is refused with *Order has already been generated for this quote.* From an opportunity, yes. Each run of **Order** creates a ne