Fixed asset disposal posted
Fires when a fixed asset disposal transaction is written to the asset ledger, either a disposal by sale or a disposal by scrap, and also for the rows a transaction reversal or an asset reclassification writes with those transaction types, which the payload flags with isReversal and isReclassification. The event captures the asset, its book, the amount in the company currency, the voucher and the transaction date so downstream systems can record the retirement of the asset and reconcile gain/loss on disposal.
| Event class | MGCLatticeFixedAssetDisposalPostedBusinessEvent |
| Contract class | MGCLatticeFixedAssetDisposalPostedBusinessEventContract |
| Category | Fixed assets |
| Module | ModuleAxapta::FixedAssets |
| Label IDs | FixedAssetDisposalPostedBusinessEventName / FixedAssetDisposalPostedBusinessEventDescription |
| Trigger | AssetTrans.insert() -> TransType == DisposalSale or DisposalScrap |
Trigger / Hook
- Extension class:
MGCLatticeAssetTrans_Table_Extension,[ExtensionOf(tableStr(AssetTrans))] - CoC method signature:
void insert() - Firing condition: after
next insert(), the newAssetTransrecord'sTransTypeis checked. The disposal event is sent only whenTransType == AssetTransType::DisposalSale || TransType == AssetTransType::DisposalScrap. (AnAcquisitiontransaction in the same method sends the sibling acquisition event instead.) - One event per
AssetTransrow of those types: a disposal posted to several books, including derived books, raises one event per book. Disposal by sale can be posted from a fixed assets journal or from a customer invoice line for the asset; both write aDisposalSalerow. - The disposal posting also writes summary rows that reverse the asset's acquisition, depreciation and other values and record the net book value and profit or loss. Those rows use other transaction types (for example
AcqThisYear,DepPriorYears,NetBookValue,ProfitLoss) and do not raise this event. - Who writes disposal rows: asset posting, the transaction reversal function, and asset reclassification. All of them raise the event:
- Posting -
isReversalandisReclassificationare bothfalse. - Reversal - the Reverse transaction function writes a copy of the original row with the amount negated; revoking a reversal writes another copy with the original sign. Both rows have
isReversal=true. They are marked byMGCLatticeTransactionReversal_Asset_Class_Extension, which wrapsTransactionReversal_Asset.createAssetTrans()in anMGCLatticeAssetTransOriginContextreversal scope; nothing on the row itself identifies a reversal when it is inserted. - Reclassification - asset reclassification copies every transaction of a book that is still open to the new asset and writes a negated copy on the old asset, so a disposal row on such a book raises the event twice, with
isReclassification=true(from the reclassification scope thatMGCLatticeAssetReclassification_Class_Extensionopens aroundAssetReclassification.run(), and, in Germany and Austria, from D365's ownAssetTrans.Reclassificationflag).
- Posting -
- Inserts that bypass the table's
insert()method (doInsert(), or set-based inserts with data methods skipped) do not raise it. - Timing:
AssetTransrows are written inside the posting, reversal or reclassification transaction.send()writes the event to the business events commit log in that transaction and it is delivered after commit, so a posting that rolls back never delivers the event. - Enablement gate:
BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeFixedAssetDisposalPostedBusinessEvent))must return true before the event is sent.
void insert()
{
next insert();
boolean isAcquisition = this.TransType == AssetTransType::Acquisition;
boolean isDisposal = this.TransType == AssetTransType::DisposalSale || this.TransType == AssetTransType::DisposalScrap;
if (!isAcquisition && !isDisposal)
{
return;
}
// Read the writer's scope now: the reversal link that would identify a reversing row is written after it.
boolean isReversal = MGCLatticeAssetTransOriginContext::isReversalInProgress();
boolean isReclassification = MGCLatticeAssetTransOriginContext::isReclassificationInProgress();
if (isAcquisition)
{
if (BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeFixedAssetAcquisitionPostedBusinessEvent)))
{
MGCLatticeFixedAssetAcquisitionPostedBusinessEvent::newFromAssetTrans(this, isReversal, isReclassification).send();
}
}
else
{
if (BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeFixedAssetDisposalPostedBusinessEvent)))
{
MGCLatticeFixedAssetDisposalPostedBusinessEvent::newFromAssetTrans(this, isReversal, isReclassification).send();
}
}
}
Payload Contract
Fields in declaration order, populated by MGCLatticeFixedAssetDisposalPostedBusinessEventContract::initialize(AssetTrans _assetTrans, boolean _isReversal, boolean _isReclassification):
| JSON field | Display label | Type / EDT | Source | Notes |
|---|---|---|---|---|
legalEntity | Legal Entity | DataAreaId | _assetTrans.DataAreaId | Company ID the disposal was posted in, in lower case (for example usmf) |
assetId | Asset ID | AssetId | _assetTrans.AssetId | Fixed asset being disposed; for a reclassification, the old or the new asset |
bookId | Book ID | AssetBookId | _assetTrans.BookId | Book the transaction posted to |
disposalAmountMST | Disposal Amount MST | AmountMST | _assetTrans.AmountMST | Amount of the sale or scrap row in the accounting (company) currency, signed as on the asset transaction. A sale posts the sale proceeds as a negative amount; a reversal carries the opposite sign |
transDate | Transaction Date | TransDate | _assetTrans.TransDate | Date of the asset transaction (the reversal or reclassification date for those rows); "\/Date(ms)\/" form |
voucher | Voucher | Voucher | _assetTrans.Voucher | Voucher of the asset transaction; a reversal and a reclassification each have their own voucher |
isReversal | Is Reversal | boolean | Reversal scope when the row was inserted | true when the transaction reversal function wrote the row (a reversal, or the revoke of one); written as true/false |
isReclassification | Is Reclassification | boolean | Reclassification scope, or _assetTrans.Reclassification | true when the row belongs to an asset reclassification; written as true/false |
crossReferences | Cross references | List of MGCLatticeCrossReferenceEventContract | MGCLatticeCrossReferenceEventHelper::listForFixedAsset(AssetTrans.AssetId, AssetTrans.DataAreaId) | Keys external systems hold for the fixed asset: one { externalSystem, externalKey } object per external system, ordered by external system, historical keys included; [] when it has none. See Cross-reference keys. |
Every Lattice event also carries the Lattice ordering and correlation envelope, inherited from MGCLatticeBusinessEventContractBase: eventSequence (Int64 - increasing across the whole catalog and all companies, allocated when the event is raised inside the business transaction, not when it commits; it orders the events of one business record, gaps are permanent and normal, and it must not be used to re-sequence the whole stream), correlationId (String, always Scope:Key - groups emissions that belong to one logical run; an event that joins no run carries Event: followed by a lower-case GUID unique to this emission) and schemaVersion (Int - the payload shape version; 1 for this contract). D365 F&O also adds its standard envelope fields to every business event payload: BusinessEventId, BusinessEventLegalEntity, ContextRecordSubject, ControlNumber, EventId, EventTime, EventTimeIso8601, InitiatingUserAADObjectId, MajorVersion, MinorVersion, and ParentContextRecordSubjects. Do not rely on the order of members in the delivered JSON.
This event does not join a run: correlationId is unique to each emission (rows for several books do not share it).
Example Payload
{
"BusinessEventId": "MGCLatticeFixedAssetDisposalPostedBusinessEvent",
"ControlNumber": 587213,
"EventId": "B0D2F4C1-9E3A-4D7B-A6C2-1F8E5A9C3B47",
"EventTime": "\/Date(1790265909000)\/",
"EventTimeIso8601": "2026-09-24T16:05:09.6544460Z",
"MajorVersion": 0,
"MinorVersion": 0,
"BusinessEventLegalEntity": "USMF",
"ContextRecordSubject": "",
"InitiatingUserAADObjectId": "{AA096874-424B-0B47-EC96-B70A962844A7}",
"ParentContextRecordSubjects": [],
"eventSequence": 48655,
"correlationId": "Event:81c6e0a3-d95f-4b2e-a437-6e0b2f8d1c94",
"schemaVersion": 1,
"legalEntity": "usmf",
"assetId": "COMP-000071",
"bookId": "200_SLLR",
"disposalAmountMST": -5000.00,
"transDate": "\/Date(1790208000000)\/",
"voucher": "FADS000042",
"isReversal": false,
"isReclassification": false,
"crossReferences": [
{
"externalSystem": "LEGACYERP",
"externalKey": "FA-7731"
}
]
}
Reversing that disposal raises the event again for the same asset and book with "disposalAmountMST": 5000.00, the reversal's own voucher and date, and "isReversal": true.
Activation
In the D365FO client, go to System administration > Setup > Business events > Business events catalog. Find the event by name ("Fixed asset disposal posted") or by filtering the Category column to Fixed assets. Select the event and use Activate to bind it to an endpoint (for example an Azure Service Bus queue, Event Grid topic, or Power Automate Flow).
Related Events
- Fixed asset acquisition posted - sibling event fired from the same
MGCLatticeAssetTrans_Table_Extension.insert()CoC forAcquisitiontransactions.