Skip to main content

PDF (AI)

PDFs — supplier invoices, purchase orders received by email — carry no structure an X++ parser can rely on. The framework's approach: send the PDF to an AI provider with a prompt describing the expected fields, get structured JSON back, and process that JSON like any other inbound document.

Calling an LLM from X++

The framework provides the classes for this call, so a processing class only has to say which prompt and which file:

  • DEVIntegAIPromptDefinition — the table holding the prompt text and the expected response format, maintained in AI prompt definitions.
  • DEVIntegAIProviderBase — the provider base: constructFromPromptDefinition() builds it from a prompt, setFileContainer() attaches a file, and callAPIJson() / callAPIText() make the call and return the answer as a DEVIntegJObject or plain text. getStatistics() reports duration and token usage.
  • DEVIntegAIProviderGemini — the Google Gemini implementation; extend DEVIntegAIProviderBase for another provider.
DEVIntegAIPromptDefinition promptDefinition = DEVIntegAIPromptDefinition::find(messageTypeTable.AIPromptDefinitionId);
DEVIntegAIProviderBase aiProvider = DEVIntegAIProviderBase::constructFromPromptDefinition(promptDefinition);

aiProvider.setFileContainer(messageTable.Name, messageTable.getMessageData().FileData);

DEVIntegJObject mainJSON = aiProvider.callAPIJson();

The prompt lives in setup rather than in code, so it can be tuned and tested against sample files from the form without a deployment.

Reading a PDF is the obvious use — OCR-style document recognition, as in the sample below — but the same call takes any file the model accepts (scanned images, for example), or no file at all when you just want to send a prompt.

Sample: purchase order import from PDF

Classes DEVIntegTutorialPurchOrderOCRProcess (processing) and DEVIntegTutorialPurchOrderOCRManualImport (user-driven import). The flow:

  1. A user selects New order import and uploads the PDF.
  2. The framework calls the configured AI prompt (Google Gemini in the sample) and receives header/lines JSON.
  3. The JSON lands in staging tables where totals are validated against the document (total amount, total quantity) before a purchase order is created — the safeguard against recognition errors.

Operation parameters cover practical import questions, such as whether tax comes from the document or is calculated in D365FO.

Tutorial: Import purchase orders from PDF using AI — including a full production prompt for multi-page invoices.