# Custom Document Creation (Custom Processing)

## Table of Contents

1. [Overview](#bkmrk-overview)
2. [Understanding the Document Flow](#bkmrk-understanding-the-do)
3. [JSON Data Structure](#bkmrk-json-data-structure)
4. [Quick Start: Simple Custom Processing](#bkmrk-quick-start%3A-simple-)

---

## Overview

This guide explains how to create custom Business Central documents from JSON data provided by DEXPRO Core. The system receives documents with status **"Custom Processing"**, which third-party developers can transform into any BC document type (Purchase Orders, Sales Orders, G/L Journals, Service Orders, etc.).

### What You'll Learn

- How to intercept documents marked for custom processing
- The JSON structure containing document header, lines, metadata, and custom fields
- How to create your custom document

---

## Understanding the Document Flow

### Core Workflow

```
┌─────────────────────────────────────────────────────────────────┐
│ 1. Document Import                                              │
│    JSON Raw Data → DXP Document (Status: Imported)              │
└────────────────────────┬────────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│ 2. Source Document Creation                                     │
│    ISourceDocument.CreateSource() → Your Source Tables          │
│    (e.g., SQZ Document Header/Lines or Your Custom Tables)      │
└────────────────────────┬────────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│ 3. Validation & Plausibility Checks                             │
│    ISourceDocument.IsSourceDataPlausible()                      │
│    → Validates data quality, checks for errors                  │
└────────────────────────┬────────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│ 4. <span class="hljs-keyword">Create</span> Processed <span class="hljs-keyword">JSON</span>                                        │
│    ISourceDocument.CreateProcessedJsonFromSource()              │
│    → Builds <span class="hljs-keyword">JSON</span> structure <span class="hljs-keyword">for</span> target <span class="hljs-keyword">document</span>                  │
└────────────────────────┬────────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│ <span class="hljs-number">5.</span> <span class="hljs-keyword">Update</span> Core <span class="hljs-keyword">Document</span> <span class="hljs-keyword">with</span> <span class="hljs-string">"Custom Processing"</span> <span class="hljs-keyword">Status</span>         │
│    UpdateDocument() → <span class="hljs-keyword">Sets</span> <span class="hljs-keyword">Status</span> <span class="hljs-keyword">to</span> <span class="hljs-string">"Custom Processing"</span>        │
│    → Stores <span class="hljs-keyword">JSON</span> Processed <span class="hljs-keyword">in</span> DXP <span class="hljs-keyword">Document</span>                      │
└────────────────────────┬────────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│ <span class="hljs-number">6.</span> Your Custom Processing (THIS <span class="hljs-keyword">IS</span> <span class="hljs-keyword">WHERE</span> YOU HOOK <span class="hljs-keyword">IN</span>!)          │
│    Subscribe <span class="hljs-keyword">to</span> <span class="hljs-keyword">events</span> <span class="hljs-keyword">or</span> implement <span class="hljs-keyword">interface</span>                   │
│    → <span class="hljs-keyword">Read</span> <span class="hljs-keyword">JSON</span> Processed <span class="hljs-keyword">from</span> DXP <span class="hljs-keyword">Document</span>                      │
│    → <span class="hljs-keyword">Create</span> your target BC <span class="hljs-keyword">document</span>                             │
└────────────────────────┬────────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│ <span class="hljs-number">7.</span> <span class="hljs-keyword">Final</span> <span class="hljs-keyword">Status</span> <span class="hljs-keyword">Update</span>                                          │
│    <span class="hljs-keyword">Document</span> <span class="hljs-keyword">Status</span> → Transferred <span class="hljs-keyword">or</span> Finished                    │
│    Linked-<span class="hljs-keyword">to</span> <span class="hljs-built_in">Record</span> <span class="hljs-keyword">Id</span> → Your created BC <span class="hljs-keyword">document</span>               │
└─────────────────────────────────────────────────────────────────┘

```

### Key Status Values

<table id="bkmrk-status-description-i"><thead><tr><th>Status</th><th>Description</th></tr></thead><tbody><tr><td>**Imported**</td><td>Raw JSON received, not yet processed</td></tr><tr><td>**Transferred**</td><td>Source document created, ready for processing</td></tr><tr><td>**Custom Processing**</td><td>**Your target status** - Document ready for custom handling</td></tr><tr><td>**Finished**</td><td>Target document successfully created</td></tr><tr><td>**Deleted**</td><td>Processing complete, document archived</td></tr></tbody></table>

---

## JSON Data Structure

### Overview

The `"JSON Processed"` blob in the `DXP Document` table contains a structured JSON object with all information needed to create your target document.

### Complete JSON Structure

```
{
  <span class="hljs-comment">// ═══════════════════════════════════════════════════════════</span>
  <span class="hljs-comment">// HEADER SECTION - Document-level information</span>
  <span class="hljs-comment">// ═══════════════════════════════════════════════════════════</span>

  <span class="hljs-string">"Type"</span>: <span class="hljs-string">"Invoice"</span>,                    <span class="hljs-comment">// Document type: Invoice, Credit Memo, Order, etc.</span>
  <span class="hljs-string">"VendorNo"</span>: <span class="hljs-string">"VENDOR001"</span>,              <span class="hljs-comment">// Vendor/Customer number</span>
  <span class="hljs-string">"DocumentDate"</span>: <span class="hljs-string">"2025-10-15"</span>,         <span class="hljs-comment">// Document date</span>
  <span class="hljs-string">"PostingDate"</span>: <span class="hljs-string">"2025-10-16"</span>,          <span class="hljs-comment">// Posting date</span>
  <span class="hljs-string">"DocumentReference"</span>: <span class="hljs-string">"INV-2025-001"</span>,  <span class="hljs-comment">// External document number</span>
  <span class="hljs-string">"OrderNo"</span>: <span class="hljs-string">"PO-12345"</span>,                <span class="hljs-comment">// Reference to order (if applicable)</span>
  <span class="hljs-string">"PostingDescription"</span>: <span class="hljs-string">"Invoice Q4"</span>,   <span class="hljs-comment">// Posting description</span>
  <span class="hljs-string">"NetAmount"</span>: <span class="hljs-number">1000.00</span>,                 <span class="hljs-comment">// Net amount (excluding tax)</span>
  <span class="hljs-string">"TotalAmount"</span>: <span class="hljs-number">1190.00</span>,               <span class="hljs-comment">// Gross amount (including tax)</span>
  <span class="hljs-string">"TaxAmount"</span>: <span class="hljs-number">190.00</span>,                  <span class="hljs-comment">// Total tax amount</span>
  <span class="hljs-string">"Currency"</span>: <span class="hljs-string">"EUR"</span>,                    <span class="hljs-comment">// Currency code</span>

  <span class="hljs-comment">// ───────────────────────────────────────────────────────────</span>
  <span class="hljs-comment">// DIMENSIONS - Header-level dimensions as key-value pairs</span>
  <span class="hljs-comment">// ───────────────────────────────────────────────────────────</span>

  <span class="hljs-string">"Dimensions"</span>: {
    <span class="hljs-string">"DEPARTMENT"</span>: <span class="hljs-string">"SALES"</span>,
    <span class="hljs-string">"PROJECT"</span>: <span class="hljs-string">"PROJ001"</span>,
    <span class="hljs-string">"COSTCENTER"</span>: <span class="hljs-string">"CC-100"</span>
  },

  <span class="hljs-comment">// ───────────────────────────────────────────────────────────</span>
  <span class="hljs-comment">// CUSTOM FIELDS - Additional header fields (see below)</span>
  <span class="hljs-comment">// ───────────────────────────────────────────────────────────</span>

  <span class="hljs-string">"CustomFields"</span>: [
    {
      <span class="hljs-string">"Id"</span>: <span class="hljs-number">50100</span>,
      <span class="hljs-string">"Name"</span>: <span class="hljs-string">"CustomerNo"</span>,
      <span class="hljs-string">"Value"</span>: <span class="hljs-string">"CUST001"</span>,
      <span class="hljs-string">"Caption"</span>: <span class="hljs-string">"Customer Number"</span>
    },
    {
      <span class="hljs-string">"Id"</span>: <span class="hljs-number">50101</span>,
      <span class="hljs-string">"Name"</span>: <span class="hljs-string">"DeliveryTerms"</span>,
      <span class="hljs-string">"Value"</span>: <span class="hljs-string">"EXW"</span>,
      <span class="hljs-string">"Caption"</span>: <span class="hljs-string">"Delivery Terms"</span>
    }
  ],

  <span class="hljs-comment">// ───────────────────────────────────────────────────────────</span>
  <span class="hljs-comment">// METADATA - System-generated field mappings</span>
  <span class="hljs-comment">// ───────────────────────────────────────────────────────────</span>

  <span class="hljs-string">"Metadata"</span>: [
    {
      <span class="hljs-string">"DocumentClass"</span>: <span class="hljs-string">"DXP Invoice / Credit Memo"</span>,
      <span class="hljs-string">"FieldType"</span>: <span class="hljs-string">"Header"</span>,
      <span class="hljs-string">"FieldId"</span>: <span class="hljs-number">101</span>,
      <span class="hljs-string">"Value"</span>: <span class="hljs-string">"Additional Info"</span>
    }
  ],

  <span class="hljs-comment">// ═══════════════════════════════════════════════════════════</span>
  <span class="hljs-comment">// LINES SECTION - Document line items</span>
  <span class="hljs-comment">// ═══════════════════════════════════════════════════════════</span>

  <span class="hljs-string">"Lines"</span>: [
    {
      <span class="hljs-comment">// ─────────────────────────────────────────────────────────</span>
      <span class="hljs-comment">// Line Basic Information</span>
      <span class="hljs-comment">// ─────────────────────────────────────────────────────────</span>

      <span class="hljs-string">"Type"</span>: <span class="hljs-string">"Item"</span>,                   <span class="hljs-comment">// Item, G/L Account, Charge (Item), Fixed Asset</span>
      <span class="hljs-string">"No"</span>: <span class="hljs-string">"ITEM001"</span>,                  <span class="hljs-comment">// Item/Account number</span>
      <span class="hljs-string">"Description"</span>: <span class="hljs-string">"Product A"</span>,       <span class="hljs-comment">// Line description</span>
      <span class="hljs-string">"VendorItemNo"</span>: <span class="hljs-string">"VEND-SKU-123"</span>,   <span class="hljs-comment">// Vendor's item number</span>
      <span class="hljs-string">"Quantity"</span>: <span class="hljs-number">10.0</span>,                 <span class="hljs-comment">// Quantity</span>
      <span class="hljs-string">"UnitOfMeasure"</span>: <span class="hljs-string">"PCS"</span>,          <span class="hljs-comment">// Unit of measure</span>
      <span class="hljs-string">"DirectUnitCost"</span>: <span class="hljs-number">100.00</span>,        <span class="hljs-comment">// Unit price</span>
      <span class="hljs-string">"LineDiscount"</span>: <span class="hljs-number">5.0</span>,             <span class="hljs-comment">// Line discount percentage</span>

      <span class="hljs-comment">// ─────────────────────────────────────────────────────────</span>
      <span class="hljs-comment">// Line Amounts & Tax</span>
      <span class="hljs-comment">// ─────────────────────────────────────────────────────────</span>

      <span class="hljs-string">"NetAmount"</span>: <span class="hljs-number">950.00</span>,             <span class="hljs-comment">// Line net amount</span>
      <span class="hljs-string">"TotalAmount"</span>: <span class="hljs-number">1130.50</span>,          <span class="hljs-comment">// Line gross amount</span>
      <span class="hljs-string">"TaxRate"</span>: <span class="hljs-number">19.0</span>,                 <span class="hljs-comment">// Tax percentage</span>
      <span class="hljs-string">"VATBusPostingGroup"</span>: <span class="hljs-string">"DOMESTIC"</span>,
      <span class="hljs-string">"VATProdPostingGroup"</span>: <span class="hljs-string">"STANDARD"</span>,
      <span class="hljs-string">"GenBusPostingGroup"</span>: <span class="hljs-string">"DOMESTIC"</span>,
      <span class="hljs-string">"GenProdPostingGroup"</span>: <span class="hljs-string">"RETAIL"</span>,

      <span class="hljs-comment">// ─────────────────────────────────────────────────────────</span>
      <span class="hljs-comment">// Order Reference (for matching)</span>
      <span class="hljs-comment">// ─────────────────────────────────────────────────────────</span>

      <span class="hljs-string">"OrderNo"</span>: <span class="hljs-string">"PO-12345"</span>,           <span class="hljs-comment">// Referenced order number</span>
      <span class="hljs-string">"OrderLineNo"</span>: <span class="hljs-number">10000</span>,            <span class="hljs-comment">// Referenced order line number</span>
      <span class="hljs-string">"ReceiptNo"</span>: <span class="hljs-string">"RCP-001"</span>,          <span class="hljs-comment">// Referenced receipt number</span>
      <span class="hljs-string">"ReceiptLineNo"</span>: <span class="hljs-number">10000</span>,          <span class="hljs-comment">// Referenced receipt line number</span>

      <span class="hljs-comment">// ─────────────────────────────────────────────────────────</span>
      <span class="hljs-comment">// Line Dimensions</span>
      <span class="hljs-comment">// ─────────────────────────────────────────────────────────</span>

      <span class="hljs-string">"Dimensions"</span>: {
        <span class="hljs-string">"DEPARTMENT"</span>: <span class="hljs-string">"PROD"</span>,
        <span class="hljs-string">"PROJECT"</span>: <span class="hljs-string">"PROJ001"</span>
      },

      <span class="hljs-comment">// ─────────────────────────────────────────────────────────</span>
      <span class="hljs-comment">// Line Custom Fields</span>
      <span class="hljs-comment">// ─────────────────────────────────────────────────────────</span>

      <span class="hljs-string">"CustomFields"</span>: [
        {
          <span class="hljs-string">"Id"</span>: <span class="hljs-number">50200</span>,
          <span class="hljs-string">"Name"</span>: <span class="hljs-string">"SerialNo"</span>,
          <span class="hljs-string">"Value"</span>: <span class="hljs-string">"SN-12345"</span>,
          <span class="hljs-string">"Caption"</span>: <span class="hljs-string">"Serial Number"</span>
        }
      ],

      <span class="hljs-comment">// ─────────────────────────────────────────────────────────</span>
      <span class="hljs-comment">// Line Metadata</span>
      <span class="hljs-comment">// ─────────────────────────────────────────────────────────</span>

      <span class="hljs-string">"Metadata"</span>: [
        {
          <span class="hljs-string">"DocumentClass"</span>: <span class="hljs-string">"DXP Invoice / Credit Memo"</span>,
          <span class="hljs-string">"FieldType"</span>: <span class="hljs-string">"Line"</span>,
          <span class="hljs-string">"FieldId"</span>: <span class="hljs-number">201</span>,
          <span class="hljs-string">"Value"</span>: <span class="hljs-string">"Line-specific metadata"</span>
        }
      ]
    }
    <span class="hljs-comment">// ... additional lines</span>
  ]
}

```

### Custom Fields vs. Metadata

**Custom Fields:**

- User-defined fields from your app
- Mapped via Custom Field Mapping
- Can be mapped to any field in the Squeeze Validation
- Example: Adding a "Customer No." to the Squeeze Validation

**Metadata:**

- System-generated fields
- Extracted by the Squeeze System but not mapped to any Field in BC

---

## Quick Start: Simple Custom Processing

### Scenario

You want to create a custom document type (e.g., a Warehouse Shipment) from documents marked with "Custom Processing" status.

### Step 1: Subscribe to the Integration Event

Create a codeunit to intercept documents with "Custom Processing" status:

```
codeunit <span class="hljs-number">50100</span> <span class="hljs-string">"My Custom Document Handler"</span>
{
    [EventSubscriber(ObjectType::Codeunit, Codeunit::<span class="hljs-string">"DXP Document Mgt."</span>, 
        <span class="hljs-string">'OnAfterWriteProcessedJsonToBlob'</span>, <span class="hljs-string">''</span>, <span class="hljs-literal">true</span>, <span class="hljs-literal">true</span>)]
    local <span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">OnAfterWriteProcessedJsonToBlob</span><span class="hljs-params">(
        <span class="hljs-keyword">var</span> Document: Record "DXP Document"; 
        <span class="hljs-keyword">var</span> ProcessedJSONObj: JsonObject)</span>
    <span class="hljs-title">begin</span>
        <span class="hljs-comment">// Only handle Custom Processing status</span>
        <span class="hljs-title">if</span> <span class="hljs-title">Document</span>.<span class="hljs-title">Status</span> <> <span class="hljs-title">Document</span>.<span class="hljs-title">Status</span>:</span>:<span class="hljs-string">"Custom Processing"</span> <span class="hljs-keyword">then</span>
            <span class="hljs-keyword">exit</span>;

        // Create your custom document
        CreateMyCustomDocument(Document, ProcessedJSONObj);
    <span class="hljs-keyword">end</span>;

    local <span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">CreateMyCustomDocument</span><span class="hljs-params">(
        <span class="hljs-keyword">var</span> Document: Record "DXP Document"; 
        ProcessedJSON: JsonObject)</span>
    <span class="hljs-title">var</span>
        <span class="hljs-title">CoreTokenMgt</span>:</span> Codeunit <span class="hljs-string">"DXP Core Token Mgt."</span>;
        JsonHelper: Codeunit <span class="hljs-string">"DXP Json Helper"</span>;
        MyCustomHeader: Record <span class="hljs-string">"My Custom Document Header"</span>;
        MyCustomLine: Record <span class="hljs-string">"My Custom Document Line"</span>;
        LineJArray: JsonArray;
        LineJToken: JsonToken;
        LineJObj: JsonObject;
    <span class="hljs-keyword">begin</span>
        // ═══════════════════════════════════════════════════════
        // <span class="hljs-number">1</span>. CREATE HEADER
        // ═══════════════════════════════════════════════════════

        MyCustomHeader.Init();
        MyCustomHeader.<span class="hljs-string">"No."</span> := <span class="hljs-string">''</span>;  // Will be assigned by number series

        // Read standard header fields
        MyCustomHeader.<span class="hljs-string">"Vendor No."</span> := 
            JsonHelper.ValAsTxt(ProcessedJSON, CoreTokenMgt.GetVendorNoTok(), <span class="hljs-literal">false</span>);
        MyCustomHeader.<span class="hljs-string">"Document Date"</span> := 
            JsonHelper.ValAsDate(ProcessedJSON, CoreTokenMgt.GetDocDateTok(), <span class="hljs-literal">false</span>);
        MyCustomHeader.<span class="hljs-string">"Document Reference"</span> := 
            JsonHelper.ValAsTxt(ProcessedJSON, CoreTokenMgt.GetDocReferenceTok(), <span class="hljs-literal">false</span>);

        MyCustomHeader.Insert(<span class="hljs-literal">true</span>);

        // ═══════════════════════════════════════════════════════
        // <span class="hljs-number">2</span>. PROCESS DIMENSIONS (<span class="hljs-keyword">if</span> your document supports them)
        // ═══════════════════════════════════════════════════════

        ProcessHeaderDimensions(ProcessedJSON, MyCustomHeader);

        // ═══════════════════════════════════════════════════════
        // <span class="hljs-number">3</span>. PROCESS CUSTOM FIELDS
        // ═══════════════════════════════════════════════════════

        ProcessCustomFields(ProcessedJSON, MyCustomHeader);

        // ═══════════════════════════════════════════════════════
        // <span class="hljs-number">4</span>. CREATE LINES
        // ═══════════════════════════════════════════════════════

        LineJArray := JsonHelper.ReadJArrayFromObj(ProcessedJSON, CoreTokenMgt.GetLinesTok());

        foreach LineJToken <span class="hljs-keyword">in</span> LineJArray <span class="hljs-keyword">do</span> <span class="hljs-keyword">begin</span>
            LineJObj := LineJToken.AsObject();

            MyCustomLine.Init();
            MyCustomLine.<span class="hljs-string">"Document No."</span> := MyCustomHeader.<span class="hljs-string">"No."</span>;
            MyCustomLine.<span class="hljs-string">"Line No."</span> := GetNextLineNo(MyCustomHeader.<span class="hljs-string">"No."</span>);

            // Read line fields
            MyCustomLine.<span class="hljs-string">"Item No."</span> := 
                JsonHelper.ValAsTxt(LineJObj, CoreTokenMgt.GetNoTok(), <span class="hljs-literal">false</span>);
            MyCustomLine.Description := 
                JsonHelper.ValAsTxt(LineJObj, CoreTokenMgt.GetDescriptionTok(), <span class="hljs-literal">false</span>);
            MyCustomLine.Quantity := 
                JsonHelper.ValAsDec(LineJObj, CoreTokenMgt.GetQtyTok(), <span class="hljs-literal">false</span>);
            MyCustomLine.<span class="hljs-string">"Unit of Measure"</span> := 
                JsonHelper.ValAsTxt(LineJObj, CoreTokenMgt.GetUoMTok(), <span class="hljs-literal">false</span>);

            MyCustomLine.Insert(<span class="hljs-literal">true</span>);

            // Process line dimensions <span class="hljs-keyword">and</span> custom fields <span class="hljs-keyword">if</span> needed
            ProcessLineDimensions(LineJObj, MyCustomLine);
            ProcessLineCustomFields(LineJObj, MyCustomLine);
        <span class="hljs-keyword">end</span>;

        // ═══════════════════════════════════════════════════════
        // <span class="hljs-number">5</span>. UPDATE CORE DOCUMENT STATUS
        // ═══════════════════════════════════════════════════════

        UpdateCoreDocument(Document, MyCustomHeader);
    <span class="hljs-keyword">end</span>;

    local <span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">ProcessHeaderDimensions</span><span class="hljs-params">(ProcessedJSON: JsonObject; <span class="hljs-keyword">var</span> MyCustomHeader: Record "My Custom Document Header")</span>
    <span class="hljs-title">var</span>
        <span class="hljs-title">CoreTokenMgt</span>:</span> Codeunit <span class="hljs-string">"DXP Core Token Mgt."</span>;
        DocTransferMgt: Codeunit <span class="hljs-string">"DXP Document Transfer Mgt."</span>;
        DimensionsJObj: JsonObject;
        DimSetID: Integer;
    <span class="hljs-keyword">begin</span>
        // Read dimensions from JSON
        <span class="hljs-keyword">if</span> ProcessedJSON.Contains(CoreTokenMgt.GetDimensionsTok()) <span class="hljs-keyword">then</span> <span class="hljs-keyword">begin</span>
            ProcessedJSON.Get(CoreTokenMgt.GetDimensionsTok(), DimensionsJObj);

            // Convert <span class="hljs-keyword">to</span> Dimension Set ID
            <span class="hljs-keyword">if</span> DocTransferMgt.GetDimSetIdFromJsonObj(DimensionsJObj, DimSetID) <span class="hljs-keyword">then</span> <span class="hljs-keyword">begin</span>
                MyCustomHeader.<span class="hljs-string">"Dimension Set ID"</span> := DimSetID;
                MyCustomHeader.Modify(<span class="hljs-literal">true</span>);
            <span class="hljs-keyword">end</span>;
        <span class="hljs-keyword">end</span>;
    <span class="hljs-keyword">end</span>;

    local <span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">ProcessCustomFields</span><span class="hljs-params">(ProcessedJSON: JsonObject; <span class="hljs-keyword">var</span> MyCustomHeader: Record "My Custom Document Header")</span>
    <span class="hljs-title">var</span>
        <span class="hljs-title">CoreTokenMgt</span>:</span> Codeunit <span class="hljs-string">"DXP Core Token Mgt."</span>;
        JsonHelper: Codeunit <span class="hljs-string">"DXP Json Helper"</span>;
        CustomFieldsJArray: JsonArray;
        CustomFieldJToken: JsonToken;
        CustomFieldJObj: JsonObject;
        FieldName: Text;
        FieldValue: Text;
    <span class="hljs-keyword">begin</span>
        // Read custom fields array
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> ProcessedJSON.Contains(CoreTokenMgt.GetCustomFieldsTok()) <span class="hljs-keyword">then</span>
            <span class="hljs-keyword">exit</span>;

        CustomFieldsJArray := JsonHelper.ReadJArrayFromObj(ProcessedJSON, CoreTokenMgt.GetCustomFieldsTok());

        foreach CustomFieldJToken <span class="hljs-keyword">in</span> CustomFieldsJArray <span class="hljs-keyword">do</span> <span class="hljs-keyword">begin</span>
            CustomFieldJObj := CustomFieldJToken.AsObject();
            FieldName := JsonHelper.ValAsTxt(CustomFieldJObj, CoreTokenMgt.GetNameTok(), <span class="hljs-literal">false</span>);
            FieldValue := JsonHelper.ValAsTxt(CustomFieldJObj, CoreTokenMgt.GetValueTok(), <span class="hljs-literal">false</span>);

            // Map <span class="hljs-keyword">to</span> your custom fields
            <span class="hljs-keyword">case</span> FieldName <span class="hljs-keyword">of</span>
                <span class="hljs-string">'CustomerNo'</span>:
                    MyCustomHeader.<span class="hljs-string">"Customer No."</span> := CopyStr(FieldValue, <span class="hljs-number">1</span>, <span class="hljs-number">20</span>);
                <span class="hljs-string">'DeliveryTerms'</span>:
                    MyCustomHeader.<span class="hljs-string">"Delivery Terms"</span> := CopyStr(FieldValue, <span class="hljs-number">1</span>, <span class="hljs-number">10</span>);
                // Add more field mappings as needed
            <span class="hljs-keyword">end</span>;
        <span class="hljs-keyword">end</span>;

        MyCustomHeader.Modify(<span class="hljs-literal">true</span>);
    <span class="hljs-keyword">end</span>;

    local <span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">ProcessLineDimensions</span><span class="hljs-params">(LineJObj: JsonObject; <span class="hljs-keyword">var</span> MyCustomLine: Record "My Custom Document Line")</span>
    <span class="hljs-title">var</span>
        <span class="hljs-title">CoreTokenMgt</span>:</span> Codeunit <span class="hljs-string">"DXP Core Token Mgt."</span>;
        DocTransferMgt: Codeunit <span class="hljs-string">"DXP Document Transfer Mgt."</span>;
        DimensionsJObj: JsonObject;
        DimSetID: Integer;
    <span class="hljs-keyword">begin</span>
        <span class="hljs-keyword">if</span> LineJObj.Contains(CoreTokenMgt.GetDimensionsTok()) <span class="hljs-keyword">then</span> <span class="hljs-keyword">begin</span>
            LineJObj.Get(CoreTokenMgt.GetDimensionsTok(), DimensionsJObj);

            <span class="hljs-keyword">if</span> DocTransferMgt.GetDimSetIdFromJsonObj(DimensionsJObj, DimSetID) <span class="hljs-keyword">then</span> <span class="hljs-keyword">begin</span>
                MyCustomLine.<span class="hljs-string">"Dimension Set ID"</span> := DimSetID;
                MyCustomLine.Modify(<span class="hljs-literal">true</span>);
            <span class="hljs-keyword">end</span>;
        <span class="hljs-keyword">end</span>;
    <span class="hljs-keyword">end</span>;

    local <span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">ProcessLineCustomFields</span><span class="hljs-params">(LineJObj: JsonObject; <span class="hljs-keyword">var</span> MyCustomLine: Record "My Custom Document Line")</span>
    <span class="hljs-title">var</span>
        <span class="hljs-title">CoreTokenMgt</span>:</span> Codeunit <span class="hljs-string">"DXP Core Token Mgt."</span>;
        JsonHelper: Codeunit <span class="hljs-string">"DXP Json Helper"</span>;
        CustomFieldsJArray: JsonArray;
        CustomFieldJToken: JsonToken;
        CustomFieldJObj: JsonObject;
        FieldName: Text;
        FieldValue: Text;
    <span class="hljs-keyword">begin</span>
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> LineJObj.Contains(CoreTokenMgt.GetCustomFieldsTok()) <span class="hljs-keyword">then</span>
            <span class="hljs-keyword">exit</span>;

        CustomFieldsJArray := JsonHelper.ReadJArrayFromObj(LineJObj, CoreTokenMgt.GetCustomFieldsTok());

        foreach CustomFieldJToken <span class="hljs-keyword">in</span> CustomFieldsJArray <span class="hljs-keyword">do</span> <span class="hljs-keyword">begin</span>
            CustomFieldJObj := CustomFieldJToken.AsObject();
            FieldName := JsonHelper.ValAsTxt(CustomFieldJObj, CoreTokenMgt.GetNameTok(), <span class="hljs-literal">false</span>);
            FieldValue := JsonHelper.ValAsTxt(CustomFieldJObj, CoreTokenMgt.GetValueTok(), <span class="hljs-literal">false</span>);

            // Map <span class="hljs-keyword">to</span> your line custom fields
            <span class="hljs-keyword">case</span> FieldName <span class="hljs-keyword">of</span>
                <span class="hljs-string">'SerialNo'</span>:
                    MyCustomLine.<span class="hljs-string">"Serial No."</span> := CopyStr(FieldValue, <span class="hljs-number">1</span>, <span class="hljs-number">50</span>);
                // Add more field mappings
            <span class="hljs-keyword">end</span>;
        <span class="hljs-keyword">end</span>;

        MyCustomLine.Modify(<span class="hljs-literal">true</span>);
    <span class="hljs-keyword">end</span>;

    local <span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">UpdateCoreDocument</span><span class="hljs-params">(<span class="hljs-keyword">var</span> Document: Record "DXP Document"; MyCustomHeader: Record "My Custom Document Header")</span>
    <span class="hljs-title">var</span>
        <span class="hljs-title">DocumentMgt</span>:</span> Codeunit <span class="hljs-string">"DXP Document Mgt."</span>;
    <span class="hljs-keyword">begin</span>
        // Update the core document <span class="hljs-keyword">to</span> link it <span class="hljs-keyword">to</span> your created document
        Document.Status := Document.Status::Transferred;
        Document.<span class="hljs-string">"Linked-to Record Id"</span> := MyCustomHeader.RecordId;
        Document.Modify(<span class="hljs-literal">true</span>);

        // Optionally, transfer attachments from Core <span class="hljs-keyword">to</span> your document
        TransferAttachments(Document, MyCustomHeader);
    <span class="hljs-keyword">end</span>;

    local <span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">TransferAttachments</span><span class="hljs-params">(Document: Record "DXP Document"; MyCustomHeader: Record "My Custom Document Header")</span>
    <span class="hljs-title">var</span>
        <span class="hljs-title">DocAttachment</span>:</span> Record <span class="hljs-string">"DXP Document Attachment"</span>;
        MyDocAttachment: Record <span class="hljs-string">"Document Attachment"</span>;
        InStr: InStream;
    <span class="hljs-keyword">begin</span>
        DocAttachment.SetRange(<span class="hljs-string">"Document No."</span>, Document.<span class="hljs-string">"No."</span>);
        <span class="hljs-keyword">if</span> DocAttachment.FindSet() <span class="hljs-keyword">then</span>
            <span class="hljs-keyword">repeat</span>
                MyDocAttachment.Init();
                MyDocAttachment.ID := <span class="hljs-number">0</span>;

                DocAttachment.<span class="hljs-string">"File Content"</span>.CreateInStream(InStr);
                MyDocAttachment.SaveAttachmentFromStream(
                    InStr, 
                    MyCustomHeader.RecordId, 
                    DocAttachment.<span class="hljs-string">"File Name"</span>);
            <span class="hljs-keyword">until</span> DocAttachment.Next() = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">end</span>;

    local <span class="hljs-function"><span class="hljs-keyword">procedure</span> <span class="hljs-title">GetNextLineNo</span><span class="hljs-params">(DocumentNo: Code[20])</span>:</span> Integer
    <span class="hljs-keyword">var</span>
        MyCustomLine: Record <span class="hljs-string">"My Custom Document Line"</span>;
    <span class="hljs-keyword">begin</span>
        MyCustomLine.SetRange(<span class="hljs-string">"Document No."</span>, DocumentNo);
        <span class="hljs-keyword">if</span> MyCustomLine.FindLast() <span class="hljs-keyword">then</span>
            <span class="hljs-keyword">exit</span>(MyCustomLine.<span class="hljs-string">"Line No."</span> + <span class="hljs-number">10000</span>);
        <span class="hljs-keyword">exit</span>(<span class="hljs-number">10000</span>);
    <span class="hljs-keyword">end</span>;
}

```

### Key Helper Codeunits

<table id="bkmrk-codeunit-purpose-dxp"><thead><tr><th>Codeunit</th><th>Purpose</th></tr></thead><tbody><tr><td>**DXP Core Token Mgt.**</td><td>Provides token names for JSON fields (GetVendorNoTok(), GetDocDateTok(), etc.)</td></tr><tr><td>**DXP Json Helper**</td><td>JSON parsing utilities (ValAsTxt(), ValAsDate(), ReadJArrayFromObj(), etc.)</td></tr><tr><td>**DXP Document Transfer Mgt.**</td><td>Dimension processing, metadata transfer, custom field handling</td></tr><tr><td>**DXP Document Mgt.**</td><td>Core document management (UpdateDocument(), UpdateDocumentStatus(), etc.)</td></tr></tbody></table>

---

*For questions or clarifications, please contact DEXPRO Solutions GmbH.*