Skip to main content

Inbound

An inbound message type brings external data into D365FO. Every file, queue item, or API response becomes a record in the Incoming messages log with the payload attached, then a processing class turns it into a D365FO document.

How it works

  1. A Load batch job reads the source (file share, queue, or web service) and, for each item, creates a record in Incoming messages with status Ready and the payload attached. Files are moved to an Archive folder — there is no error folder, because failures stay visible in the message log.
  2. A Process step calls your class's processMessage() for each unprocessed message. It runs outside a transaction, so the class decides the transaction boundary — one per message, per journal, or per line.
  3. Processing is two steps: first parse the payload into a staging table, then create the D365FO document from staging. The message ends as Processed, or Error with a log.

Inbound processing flow

The two-step staging is what makes the framework supportable: when processing fails, the parsed values sit in staging where a user can inspect them, fix the cause (create the missing master data or a mapping), and reprocess — all from the message log, no developer needed. A message can also be set to Hold when a user decides not to process it.

Setting up and running

Configure the message type

In Inbound message types, set the Details (incoming and archive folders, and the processing class), any Operation parameters the class needs — for example a journal name, an auto-post flag, or the file type — and Advanced options such as parallel processing:

Inbound message type setup

Run and monitor

The Load operation reads the source and creates messages; Process turns them into documents (Load can run processing straight after). Both run as batch jobs. Every message — with its payload, status, statistics, and error log — is on the Incoming messages form, where you filter by status, view the file, view the staging data, or reprocess:

Incoming messages form

Import file on the message type loads a single file straight from your PC for testing, without a live connection.

Building the process class

An inbound class extends DEVIntegProcessMessageBase and implements one method, processMessage, called once per message outside a transaction. The public sample DEVIntegTutorialImportLedgerJournal reads a CSV/Excel file into staging and creates a ledger journal:

class DEVIntegTutorialImportLedgerJournal extends DEVIntegProcessMessageBase
{
void processMessage(DEVIntegMessageTable _messageTable, DEVIntegMessageProcessResult _messageProcessResult)
{
messageTable = _messageTable;
messageProcessResult = _messageProcessResult;

if (! messageTable.IsParsed) // step 1 — parse the payload into staging
{
ttsbegin;
delete_from stagingHeader where stagingHeader.MessageId == _messageTable.RecId;
this.readFileToStaging();
ttscommit;
}

this.createDataFromStaging(); // step 2 — build the document from staging
}

public str getDescription()
{
return "Ledger journal import CSV sample";
}
}

Parsing reads the payload with a format-agnostic reader and writes staging rows:

DEVFileReaderBase fileReader = messageTypeTable.openFileReader(messageTable.getFileStream());
fileReader.readHeaderRow();

while (fileReader.readNextRow())
{
stagingLine.clear();
stagingLine.MainAccount = fileReader.getStringByName('MainAccount');
stagingLine.Amount = fileReader.getRealByName('Amount');
stagingLine.insert();
}
messageTable.IsParsed = true; // a reprocess then skips straight to document creation

Creating the document validates staging (counting errors on messageProcessResult) and builds the target — here a ledger journal through LedgerJournalEngine, optionally posted. Throwing an exception marks the message Error and rolls back that step.

Any payload format

openFileReader handles CSV and Excel; the same two-step shape covers other formats by swapping the parse step:

Error handling

Because processing runs outside a transaction and always leaves evidence, the common failures each have a clear resolution — all from the message log:

FailureWhat the user seesHow to fix it
Format — file can't be readError, no stagingSend the file to a developer, or return it and set Hold
Data — values don't existError, staging populatedCreate the missing master data or a mapping, then reprocess
Posting — e.g. unbalanced journalError, document not postedFix the data and reprocess
Wrong result — document looks wrongProcessedInspect the staging data to see exactly what was read

Staging data behind a failed message

Tutorials