Skip to content

Asset Purchases and Returns

Backlog fieldValue
Story IDAP-FA-005
EpicFixed Assets
Story typeBusiness workflow
Review statusDraft - business analyst and business owner review required
Source evidenceAppsPortal.Apis controller, application command/query handlers, validators, domain entities, and matching MFE workflow where available
Last source review2026-07-10

User story

As asset accountants, I want to record asset acquisitions and eligible purchase returns so that asset cost, payables, tax, and accounting remain aligned.

Posting reference: AppsPortal Posting Ledger explains debit/credit construction. Delegation and Interaction Contracts explains module ownership, delegated commands, linked records, commit boundaries, and reversal propagation.

Acceptance criteria

  1. Only authorized users can view or execute the feature's actions.
  2. Required business data, active dependencies, tenant/branch scope, and current document state are validated.
  3. Invalid requests return actionable validation errors without applying a partial change.
  4. Search, list, view, print, and export operations use the same authorized business scope.
  5. Material create, edit, status, approval, posting, reversal, and integration actions are auditable where applicable.
  6. Financial or stock effects are applied atomically and no more than once.

Posting details

  1. Purchase Post validates Draft/open period/vendor/assets/cost/tax and resolves Vendor Payable through Purchase plus Asset account from configured asset/group data.
  2. Delegate the purchase journal to Accounting: debit Asset accounts, debit input VAT, credit Vendor Payable; activate/update acquired asset values and mark Posted.
  3. Return Post validates the posted source, returnable eligible assets, period, vendor, tax, and later lifecycle/depreciation dependencies.
  4. Delegate the return journal: debit Vendor Payable, credit Asset and VAT; for depreciated returns debit Accumulated Depreciation and credit Depreciation Expense using asset then group fallback.
  5. Journal, asset state/value, source return status, and document status commit atomically.

General ledger posting

TransactionDebitCreditConditional rows
Asset purchaseAsset GL and Input TaxVendor PayableAsset/group, tax/group, vendor/category resolution.
Asset returnVendor PayableAsset GL and Input Tax reversalReverses eligible source values.
Return after depreciationAccumulated DepreciationDepreciation ExpenseAsset then group accounts; only for posted depreciation being reversed.

Other module and document effects

AreaEffectConditional/no effect
Asset registerPurchase creates/activates cost; return removes/restores eligible lifecycle state/value.No Inventory Stock In/Out for fixed-asset register items.
VendorPurchase creates payable/due balance; return reduces it.Cash moves only through Payment Out/In.
Source purchaseReturn updates remaining returnable assets/status.Later sale/disposal/depreciation can block return.

Core acceptance scenarios

  1. Given a valid Draft asset purchase with vendor/tax/group accounts, when the user clicks Post, then asset acquisition values/status and purchase journal commit together.
  2. Given an eligible posted purchase is returned, when the operation is attempted, then the return reverses payable/asset/tax and applicable depreciation using asset then group accounts.
  3. Given the same Post request is retried after success, when the source is no longer Draft, then no duplicate journal, stock, balance, payment, or lifecycle effect is created.

Purchase requirements and Post

Draft invoice, vendor, open period, currency/rate, eligible asset lines, positive cost, tax, and asset group/account setup are required. Vendor payable resolves through Purchase vendor rules. Asset account currently resolves from Asset Group for purchase lines. Post debits each Asset account by local amount after discount, debits input VAT to Tax account, credits Vendor Payable for grand total, activates/updates acquired assets, links journal, and marks Posted.

Return requirements and Post

Return requires a posted source purchase, Draft return, returnable assets/amounts, open period, and valid vendor/tax/accounts. It debits Vendor Payable, credits Asset account, reverses VAT, and when depreciation exists debits accumulated-depreciation account and credits depreciation-expense account. Accumulated depreciation and expense resolve asset first then asset group. Source return status becomes Partially or Fully Returned. Active/ineligible assets or dependent later activity block return.

Frontend page coverage

The following UI coverage is sourced from the pulled MFE route configuration. A Module-level supporting artifact mapping is evidence of a reachable screen, but requires BA confirmation that it belongs to this story rather than a more specific feature story.

Route/pageComponentModeRoute permission/guardMapping confidenceSource
(module default)AssetPurchaseInvoiceListComponentList/navigationPermission: AppFixedAssetsPermissions.AssetsPurchaseInvoice_List; Guards: PolicyAuthGuardExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/assets-purchase-invoice-routing.module.ts:20
(module default)AssetPurchaseInvoiceMainComponentList/navigationPermission: AppFixedAssetsPermissions.AssetsPurchaseInvoice_List; Guards: PolicyAuthGuardExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/assets-purchase-invoice-routing.module.ts:12
(module default)AssetPurchaseInvoiceReturnListComponentList/navigationPermission: AppFixedAssetsPermissions.AssetsReturnPurchaseInvoice_List; Guards: PolicyAuthGuardExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/assets-purchase-invoice-return-routing.module.ts:20
(module default)AssetPurchaseInvoiceReturnMainComponentList/navigationPermission: AppFixedAssetsPermissions.AssetsReturnPurchaseInvoice_List; Guards: PolicyAuthGuardExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/assets-purchase-invoice-return-routing.module.ts:12
addAssetPurchaseInvoiceAddComponentAddPermission: AppFixedAssetsPermissions.AssetsPurchaseInvoice_Add; Guards: PolicyAuthGuardExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/assets-purchase-invoice-routing.module.ts:30
addAssetPurchaseInvoiceReturnAddComponentAddPermission: AppFixedAssetsPermissions.AssetsReturnPurchaseInvoice_Add; Guards: PolicyAuthGuardExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/assets-purchase-invoice-return-routing.module.ts:30
assets-purchase-invoiceLazy-loaded routeList/navigationNo route-level permission/guard found in source windowExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/transactions-routing.module.ts:13
assets-purchase-invoice-returnLazy-loaded routeList/navigationNo route-level permission/guard found in source windowExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/transactions-routing.module.ts:48
assets-return-purchase-invoiceLazy-loaded routeList/navigationNo route-level permission/guard found in source windowExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/transactions-routing.module.ts:20
edit/:idAssetPurchaseInvoiceEditComponentEditPermission: AppFixedAssetsPermissions.AssetsPurchaseInvoice_Edit; Guards: PolicyAuthGuardExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/assets-purchase-invoice-routing.module.ts:40
edit/:idAssetPurchaseInvoiceReturnEditComponentEditPermission: AppFixedAssetsPermissions.AssetsReturnPurchaseInvoice_Edit; Guards: PolicyAuthGuardExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/assets-purchase-invoice-return-routing.module.ts:40
sequenceSequenceComponentSequenceNo route-level permission/guard found in source windowExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/assets-purchase-invoice-routing.module.ts:60
sequenceSequenceComponentSequenceNo route-level permission/guard found in source windowExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/assets-purchase-invoice-return-routing.module.ts:60
view/:idAssetPurchaseInvoiceReturnViewComponentView/detailPermission: AppFixedAssetsPermissions.AssetsReturnPurchaseInvoice_View; Guards: PolicyAuthGuardExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/assets-purchase-invoice-return-routing.module.ts:50
view/:idAssetPurchaseInvoiceViewComponentView/detailPermission: AppFixedAssetsPermissions.AssetsPurchaseInvoice_View; Guards: PolicyAuthGuardExplicit frontend feature ruleapps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/assets-purchase-invoice-routing.module.ts:50

Observed frontend fields and validation

ComponentControlObserved frontend ruleComponent source
AssetPurchaseInvoiceAddHeaderComponentdateRequired in component validatorapps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/component/asset-purchase-invoice-add-header/asset-purchase-invoice-add-header.component.ts
AssetPurchaseInvoiceAddHeaderComponentdescriptionVisible control; optional or API-dependentapps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/component/asset-purchase-invoice-add-header/asset-purchase-invoice-add-header.component.ts
AssetPurchaseInvoiceAddHeaderComponentpaymentTermIdRequired in component validatorapps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/component/asset-purchase-invoice-add-header/asset-purchase-invoice-add-header.component.ts
AssetPurchaseInvoiceAddHeaderComponentreferenceVisible control; optional or API-dependentapps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/component/asset-purchase-invoice-add-header/asset-purchase-invoice-add-header.component.ts
AssetPurchaseInvoiceAddHeaderComponentvendorIdRequired in component validatorapps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/component/asset-purchase-invoice-add-header/asset-purchase-invoice-add-header.component.ts
AssetsPurchaseReturnHeaderComponentassetsPurchaseInvoiceHeaderIdConditionally required/validated in componentapps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/component/assets-purchase-return-header/assets-purchase-return-header.component.ts
AssetsPurchaseReturnHeaderComponentdateRequired in component validatorapps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/component/assets-purchase-return-header/assets-purchase-return-header.component.ts
AssetsPurchaseReturnHeaderComponentdescriptionVisible control; optional or API-dependentapps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/component/assets-purchase-return-header/assets-purchase-return-header.component.ts
AssetsPurchaseReturnHeaderComponentreferenceVisible control; optional or API-dependentapps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/component/assets-purchase-return-header/assets-purchase-return-header.component.ts
AssetsPurchaseReturnHeaderComponentvendorIdRequired in component validatorapps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/component/assets-purchase-return-header/assets-purchase-return-header.component.ts

Observed frontend actions

ComponentClick action/handlerBusiness review requirementComponent source
AssetPurchaseInvoiceAddDetailsComponentdeleteInvoiceLineAvailable only in deletable states with Delete permission; identify the record in confirmation, call delete once, remove/refresh the list row on success, and retain the row with the API reason on failure.apps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/component/asset-purchase-invoice-add-details/asset-purchase-invoice-add-details.component.ts
AssetPurchaseInvoiceAddDetailsComponentopenDialogOpen the item/lookup/tracking dialog with the current warehouse, item, UOM, and remaining quantity context; accepted values must return to the correct line and cancel must not mutate it.apps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/component/asset-purchase-invoice-add-details/asset-purchase-invoice-add-details.component.ts
AssetPurchaseInvoiceListComponentonDeleteAvailable only in deletable states with Delete permission; identify the record in confirmation, call delete once, remove/refresh the list row on success, and retain the row with the API reason on failure.apps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/pages/asset-purchase-invoice-list/asset-purchase-invoice-list.component.ts
AssetPurchaseInvoiceListComponentonEditOpen the identified editable record only with Edit permission; posted/locked records remain blocked by route or action state and list context must be recoverable on return.apps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/pages/asset-purchase-invoice-list/asset-purchase-invoice-list.component.ts
AssetPurchaseInvoiceListComponentonPostAvailable only for a postable Draft and Post permission; confirm the document, prevent a second submission, call the posting API, and refresh status, journal/stock links, and row actions. Failure must keep the pre-post state.apps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/pages/asset-purchase-invoice-list/asset-purchase-invoice-list.component.ts
AssetPurchaseInvoiceListComponentonViewOpen the authorized record in view mode with its status, totals, lines, source and generated-document links; handle deleted, forbidden, and missing records without exposing stale data.apps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/pages/asset-purchase-invoice-list/asset-purchase-invoice-list.component.ts
AssetPurchaseInvoiceListComponentprintoutGenerate the printout for the selected record and authorized branch/tenant; use posted/current values and surface print, template, ZATCA/ETA, or popup failures without changing transaction state.apps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/pages/asset-purchase-invoice-list/asset-purchase-invoice-list.component.ts
AssetPurchaseInvoiceListComponentrouteToJournalViewOpen the authorized record in view mode with its status, totals, lines, source and generated-document links; handle deleted, forbidden, and missing records without exposing stale data.apps/fixedAssets/src/app/remote-entry/transactions/asset-purchase-invoice/pages/asset-purchase-invoice-list/asset-purchase-invoice-list.component.ts
AssetPurchaseInvoiceReturnListComponentonDeleteAvailable only in deletable states with Delete permission; identify the record in confirmation, call delete once, remove/refresh the list row on success, and retain the row with the API reason on failure.apps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/pages/asset-purchase-invoice-return-list/asset-purchase-invoice-return-list.component.ts
AssetPurchaseInvoiceReturnListComponentonEditOpen the identified editable record only with Edit permission; posted/locked records remain blocked by route or action state and list context must be recoverable on return.apps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/pages/asset-purchase-invoice-return-list/asset-purchase-invoice-return-list.component.ts
AssetPurchaseInvoiceReturnListComponentonPostAvailable only for a postable Draft and Post permission; confirm the document, prevent a second submission, call the posting API, and refresh status, journal/stock links, and row actions. Failure must keep the pre-post state.apps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/pages/asset-purchase-invoice-return-list/asset-purchase-invoice-return-list.component.ts
AssetPurchaseInvoiceReturnListComponentonPrintOutGenerate the printout for the selected record and authorized branch/tenant; use posted/current values and surface print, template, ZATCA/ETA, or popup failures without changing transaction state.apps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/pages/asset-purchase-invoice-return-list/asset-purchase-invoice-return-list.component.ts
AssetPurchaseInvoiceReturnListComponentonViewOpen the authorized record in view mode with its status, totals, lines, source and generated-document links; handle deleted, forbidden, and missing records without exposing stale data.apps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/pages/asset-purchase-invoice-return-list/asset-purchase-invoice-return-list.component.ts
AssetPurchaseInvoiceReturnListComponentrouteToJournalViewOpen the authorized record in view mode with its status, totals, lines, source and generated-document links; handle deleted, forbidden, and missing records without exposing stale data.apps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/pages/asset-purchase-invoice-return-list/asset-purchase-invoice-return-list.component.ts
AssetPurchaseReturnDetailsComponentdeleteInvoiceLineAvailable only in deletable states with Delete permission; identify the record in confirmation, call delete once, remove/refresh the list row on success, and retain the row with the API reason on failure.apps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/component/assets-purchase-return-details/assets-purchase-return-details.component.ts
AssetsPurchaseReturnHeaderComponentopenInvoiceDialogOpen the item/lookup/tracking dialog with the current warehouse, item, UOM, and remaining quantity context; accepted values must return to the correct line and cancel must not mutate it.apps/fixedAssets/src/app/remote-entry/transactions/assets-purchase-return/component/assets-purchase-return-header/assets-purchase-return-header.component.ts

Page-specific frontend acceptance criteria

  1. (module default) - List/navigation: Load an authorized paged/searchable list or navigation page; preserve filters/sort/paging and expose only permitted row and bulk actions. Security observed: Permission: AppFixedAssetsPermissions.AssetsReturnPurchaseInvoice_List; Guards: PolicyAuthGuard
  2. add - Add: Render permitted fields, required indicators, defaults, dependent lookups, validation, Save/Cancel, loading, success, and API-error states. Security observed: Permission: AppFixedAssetsPermissions.AssetsReturnPurchaseInvoice_Add; Guards: PolicyAuthGuard
  3. assets-purchase-invoice - List/navigation: Load an authorized paged/searchable list or navigation page; preserve filters/sort/paging and expose only permitted row and bulk actions. Security observed: No route-level permission/guard found in source window
  4. assets-purchase-invoice-return - List/navigation: Load an authorized paged/searchable list or navigation page; preserve filters/sort/paging and expose only permitted row and bulk actions. Security observed: No route-level permission/guard found in source window
  5. assets-return-purchase-invoice - List/navigation: Load an authorized paged/searchable list or navigation page; preserve filters/sort/paging and expose only permitted row and bulk actions. Security observed: No route-level permission/guard found in source window
  6. edit/:id - Edit: Load the identified record, enforce state/permission field locks, preserve concurrency identity, validate changes, and return without losing filters. Security observed: Permission: AppFixedAssetsPermissions.AssetsReturnPurchaseInvoice_Edit; Guards: PolicyAuthGuard
  7. sequence - Sequence: Show current numbering scope and permit only authorized, valid sequence configuration without retroactively renumbering posted documents. Security observed: No route-level permission/guard found in source window
  8. view/:id - View/detail: Load an authorized immutable/detail representation with status-aware actions, linked records, print/export where exposed, and not-found/forbidden handling. Security observed: Permission: AppFixedAssetsPermissions.AssetsPurchaseInvoice_View; Guards: PolicyAuthGuard

Internal Documentation — Microtec