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​