Monday, September 29, 2025

Read json using Newtonsoft.Json x++ d365fo

 Request message:

{

  "docType": {

    "alias": "RANDOM_DOC"

  },

  "streamName": "abc123",

  "fromParty": {

    "idTag": "SUPPLIER_XYZ"

  },

  "toParty": {

    "idTag": "BUYER_ABC"

  },

  "payload": {

    "records": [

      {

        "headerBlock": [

          {

            "headerCode": "999",

            "headerNumber": "001"

          }

        ],

        "beginBlock": [

          {

            "purpose": "06",

            "shipmentId": "SHIP123",

            "dateVal": "20230930",

            "timeVal": "1210",

            "structCode": "0001"

          }

        ],

        "loopBlock": [

          {

            "levelBlock": [

              {

                "levelId": "1",

                "parentLevel": "0",

                "levelCode": "S"

              }

            ],

            "carrierBlock": [

              {

                "packCode": "CAS",

                "qty": "2",

                "weightType": "G",

                "weightVal": "4.5",

                "uom": "LB"

              }

            ]

          },

          {

            "levelBlock": [

              {

                "levelId": "2",

                "parentLevel": "1",

                "levelCode": "O"

              }

            ],

            "orderRef": [

              {

                "orderNum": "PO987654321"

              }

            ]

          },

          {

            "levelBlock": [

              {

                "levelId": "3",

                "parentLevel": "2",

                "levelCode": "I"

              }

            ],

            "itemBlock": [

              {

                "itemId": "1234567890",

                "sku": "SKU-1111"

              }

            ],

            "descBlock": [

              {

                "text": "Random Sunglasses (X1001)"

              }

            ],

            "shipBlock": [

              {

                "lineId": "10",

                "qtyShipped": "25",

                "unitCode": "EA"

              }

            ]

          }

        ]

      }

    ]

  }

}

-------------------------------------------------------------------------------------------------------------------
class RandomJsonRunnable
{
    public static void main(Args args)
    {
        Dialog dialog = new Dialog("Random JSON Parser");
        DialogField field = dialog.addField(extendedTypeStr(Notes), "Paste Random JSON:");
        dialog.run();
        if (dialog.closedOk())
        {
            RandomJsonRunnable::readJson(field.value());
        }
    }

    public static str readJson(Notes _notes)
    {
        str response;
        try
        {
            // Root JSON object
            Newtonsoft.Json.Linq.JObject root = Newtonsoft.Json.JsonConvert::DeserializeObject(_notes);

            // Navigate down: payload → records
            Newtonsoft.Json.Linq.JObject payload = root.GetValue('payload');
            Newtonsoft.Json.Linq.JArray records = payload.GetValue('records');

            for (int r = 0; r < records.Count; r++)
            {
                Newtonsoft.Json.Linq.JObject record = records.get_Item(r);

                // loopBlock array
                Newtonsoft.Json.Linq.JArray loopBlock = record.GetValue('loopBlock');

                str orderNum = "";
                for (int l = 0; l < loopBlock.Count; l++)
                {
                    Newtonsoft.Json.Linq.JObject loop = loopBlock.get_Item(l);

                    Newtonsoft.Json.Linq.JArray levelBlock = loop.GetValue('levelBlock');
                    str levelCode = "";
                    if (levelBlock && levelBlock.Count > 0)
                    {
                        Newtonsoft.Json.Linq.JObject levelObj = levelBlock.get_Item(0);
                        levelCode = levelObj.GetValue('levelCode') ? levelObj.GetValue('levelCode').ToString() : "";

                        
                            Newtonsoft.Json.Linq.JArray orderRef = loop.GetValue('orderRef');
                            if (orderRef && orderRef.Count > 0)
                            {
                                Newtonsoft.Json.Linq.JObject orderRefObj = orderRef.get_Item(0);
                                orderNum = orderRefObj.GetValue('orderNum') ? orderRefObj.GetValue('orderNum').ToString() : "";
                            }

                        
                            Newtonsoft.Json.Linq.JObject itemBlockObj = loop.GetValue('itemBlock').get_Item(0);
                            Newtonsoft.Json.Linq.JObject descBlockObj = loop.GetValue('descBlock').get_Item(0);
                            Newtonsoft.Json.Linq.JObject shipBlockObj = loop.GetValue('shipBlock').get_Item(0);

                            str itemId = (itemBlockObj && itemBlockObj.GetValue('itemId')) ? itemBlockObj.GetValue('itemId').ToString() : "";
                            str description = (descBlockObj && descBlockObj.GetValue('text')) ? descBlockObj.GetValue('text').ToString() : "";
                            str lineId = (shipBlockObj && shipBlockObj.GetValue('lineId')) ? shipBlockObj.GetValue('lineId').ToString() : "";
                            str qtyShipped = (shipBlockObj && shipBlockObj.GetValue('qtyShipped')) ? shipBlockObj.GetValue('qtyShipped').ToString() : "";
                            str unit = (shipBlockObj && shipBlockObj.GetValue('unitCode')) ? shipBlockObj.GetValue('unitCode').ToString() : "";

                            response = strFmt("Order:%1, Item:%2, Desc:%3, Line:%4, Qty:%5, Unit:%6",
                                orderNum, itemId, description, lineId, qtyShipped, unit);
                            
                    }
                }
            }
        }
        catch (Exception::CLRError)
        {
            error(AifUtil::getClrErrorMessage());
        }
        return response;
    }
}

Sunday, September 21, 2025

Business event [Purchase order confirmation] using x++ D365fo

 Business Event Class – POConfirmationBusinessEvent:


[BusinessEvents(classStr(POConfirmationContract),"POConfirmationBE",

    "POConfirmationBEDesc",ModuleAxapta::PurchaseOrder)]

public final class POConfirmationBusinessEvent extends BusinessEventsBase

{

    PurchTable purchTable;

    private PurchTable parmPurchTable(PurchTable _purchTable = purchTable)

    {

        purchTable = _purchTable;

        return purchTable;

    }

    private void new()

    {

    }

    public static POConfirmationBusinessEvent construct(PurchTable _purchTable)

    {

        var event = new POConfirmationBusinessEvent();

        event.parmPurchTable(_purchTable);

        return event;

    }

    public BusinessEventsContract buildContract()

    {

        return POConfirmationContract::newFromPurchTable(purchTable);

    }

}


Contract Class – POConfirmationContract:

[DataContract]

internal final class POConfirmationContract extends BusinessEventsContract

{

    str jsonFormat;

    public static POConfirmationContract newFromPurchTable(PurchTable _purchTable)

    {

        var contract = new POConfirmationContract();

        contract.initialize(_purchTable);

        return contract;

    }

    public void initialize(PurchTable _purchTable)

    {

        jsonFormat = this.buildJson(_purchTable); 

    }

    public str buildJson(PurchTable _purchTable)

{

    System.IO.StringWriter stringWriter = new System.IO.StringWriter();

    Newtonsoft.Json.JsonTextWriter jsonWriter = new Newtonsoft.Json.JsonTextWriter(stringWriter);

    PurchLineAllVersions purchLineAllVersions;

    InventDistinctProductExpanded productInfo;

    VendParameters vendParams = VendParameters::find();

    jsonWriter.WriteStartObject();

    jsonWriter.WritePropertyName("documentID");

    jsonWriter.WriteValue(vendParams.DocumentId);


    jsonWriter.WritePropertyName("customerReference");

    jsonWriter.WriteStartObject();

    jsonWriter.WritePropertyName("documentID");

    jsonWriter.WriteValue(_purchTable.VendorRef);

    jsonWriter.WriteEndObject();


    jsonWriter.WritePropertyName("supplierID");

    jsonWriter.WriteValue(""); // Optional: static or configured value


    jsonWriter.WritePropertyName("buyerID");

    jsonWriter.WriteValue(vendParams.BuyerPartyId);


    jsonWriter.WritePropertyName("consigneeID");

    jsonWriter.WriteValue(_purchTable.DealerNumber);


    jsonWriter.WritePropertyName("orderLines");

    jsonWriter.WriteStartArray();


    while select LineNumber, ItemId, PurchQty from purchLineAllVersions

        join SearchName from productInfo

        where purchLineAllVersions.PurchId == _purchTable.PurchId &&

              purchLineAllVersions.ItemId == productInfo.ItemId

    {

        jsonWriter.WriteStartObject();


        jsonWriter.WritePropertyName("lineID");

        jsonWriter.WriteValue(any2Str(purchLineAllVersions.LineNumber));


        jsonWriter.WritePropertyName("itemID");

        jsonWriter.WriteValue(purchLineAllVersions.ItemId);


        jsonWriter.WritePropertyName("itemName");

        jsonWriter.WriteValue(productInfo.SearchName);


        jsonWriter.WritePropertyName("quantity");

        jsonWriter.WriteValue(any2Str(purchLineAllVersions.PurchQty));


        jsonWriter.WritePropertyName("deliveryDate");

        jsonWriter.WriteValue(date2Str(_purchTable.DeliveryDate, 321, 2, '-', 2, '-', 4));


        jsonWriter.WriteEndObject();

    }

    jsonWriter.WriteEndArray();

    jsonWriter.WriteEndObject();

    return stringWriter.ToString();

}

    [DataMember("JsonFormat"), BusinessEventsDataMember("JsonFormat")]

    public str parmJson(str _jsonFormat = jsonFormat)

    {

        jsonFormat = _jsonFormat;

        return jsonFormat;

    }

}



Thursday, September 4, 2025

Dynamic query x++ D365FO

// **Create a data source for LedgerJournalTrans table in the query**

QueryBuildDataSource ledgerJournalTrans_ds = query.addDataSource(tableNum(LedgerJournalTrans));


// **Prevent adding additional fields to the query (restrict fields auto-expansion)**

ledgerJournalTrans_ds.allowAdd(QueryAllowAdd::NoFields);


// **Enable update access on this datasource**

ledgerJournalTrans_ds.update(true);


// **Add a range for filtering by AccountType (Cust/Vend/Ledger etc.)**

ledgerJournalTrans_ds.addRange(fieldNum(LedgerJournalTrans, AccountType));


// **Add a dimension attribute range on LedgerDimension (main account dimension filtering)**

SysQuery::addDimensionAttributeRange( query,ledgerJournalTrans_ds.name(),fieldStr(LedgerJournalTrans, LedgerDimension),

    DimensionComponent::LedgerDimensionDisplayValue,'', '', true);


// **Add a range for filtering by OffsetAccountType**

ledgerJournalTrans_ds.addRange(fieldNum(LedgerJournalTrans, OffsetAccountType));


// **Add a dimension attribute range on OffsetLedgerDimension (offset account dimension filtering)**

SysQuery::addDimensionAttributeRange(query,ledgerJournalTrans_ds.name(),fieldStr(LedgerJournalTrans, OffsetLedgerDimension),DimensionComponent::LedgerDimensionDisplayValue, '', '', true);

// **Add a locked range on PaymentStatus field**

qbdsLedgerJournalTrans.addRange(fieldNum(LedgerJournalTrans, PaymentStatus)).status(RangeStatus::Locked);

// **Add dimension attribute filters for all dimensions that belong to Ledger dimension set**

DimensionAttributeSetItem dimAttrSetItemTb;

while select DimensionAttribute from dimAttrSetItemTb where dimAttrSetItemTb.DimensionAttributeSet ==DimensionCache::getDimensionAttributeSetForLedger()

{

    SysQuery::addDimensionAttributeRange(query,ledgerJournalTrans_ds.name(),

        fieldStr(LedgerJournalTrans, DefaultDimension),DimensionComponent::DimensionAttribute,

        '', DimensionAttribute::find(dimAttrSetItemTb.DimensionAttribute).Name);

}

// **Filter ledger lines where PaymentStatus is either None or Rejected**

ledgerJournalTrans_ds.rangeField(fieldNum(LedgerJournalTrans, PaymentStatus))

                     .value(strFmt('%1,%2', CustVendPaymStatus::None, CustVendPaymStatus::Rejected));

// **Join VendPaymTable with LedgerJournalTrans on PaymMode field**

QueryBuildDataSource qbdsPaymModeTable = qbdsLedgerJournalTrans.addDataSource(tableNum(VendPaymTable));

qbdsPaymModeTable.addLink(fieldNum(LedgerJournalTrans, PaymMode), tableNum(VendPaymTable), fieldNum(VendPaymTable, PaymMode));


// **Make it an InnerJoin (only matching records are included)**

qbdsPaymModeTable.joinMode(JoinMode::InnerJoin);


// **Allow updates on VendPaymTable datasource**

qbdsPaymModeTable.update(true);


// **Disable this datasource (fields not directly editable in query execution)**

qbdsPaymModeTable.enabled(false);


Wednesday, September 3, 2025

Create custom service in d365foa for list type request using x++

 Request message:

{

  "PurchaseOrders": [

    {

      "PurchaseOrderId": "PO00078901",

      "VendorId": "VEND-1001",

      "VendorName": "ABC Raw Materials Pvt Ltd",

      "OrderDate": "2025-08-18",

      "ExpectedDeliveryDate": "2025-08-25",

      "Currency": "USD",

      "PurchaseOrderLines": [

        {

          "LineNumber": 1,

          "ProductId": "MAT-STEEL-001",

          "ProductName": "Mild Steel Rod 10mm",

          "OrderedQuantity": 500,

          "UnitOfMeasure": "KG",

          "UnitPrice": 2.50,

          "LineAmount": 1250.00,

          "WarehouseId": "WH-DELHI-01"

        },

        {

          "LineNumber": 2,

          "ProductId": "MAT-CEM-002",

          "ProductName": "Cement Grade A",

          "OrderedQuantity": 200,

          "UnitOfMeasure": "BAG",

          "UnitPrice": 5.00,

          "LineAmount": 1000.00,

          "WarehouseId": "WH-DELHI-01"

        }

      ]

    }

  ]

}

Monday, September 1, 2025

Cancle the partial quantity of purch order using x++ d365fo

purchTable = PurchTable::find(purchId, true);

if (purchTable != null)

{

    // Proceed only if PO is in "Confirmed" state

    if (purchTable.DocumentState == VersioningDocumentState::Confirmed)

    {

        try

        {

            ttsbegin;

            // Loop through all purchase lines for the given PO

            while select forupdate * from purchLine

                where purchLine.PurchId == purchTable.PurchId

            {

                // Check if line is not received/invoiced and can be cancelled

                if (purchLine && purchLine.receivedInTotal() == 0 && purchLine.invoicedInTotal() == 0)

                {

                    purchLine.selectForUpdate(true);

                    purchLine.reread();

                    // Reset purchase quantity to 0

                    purchLine.PurchQty = 0.00;

                    purchLine.update();

                    // Update inventory buffer accordingly

                    InventMovement::bufferSetRemainQty(purchLine);

                }

            }

            // Update purchase order header status

            purchTable.PurchStatus  = PurchStatus::Canceled;

            purchTable.ReqAttention = "Test";   // Custom flag for follow-up

            purchTable.update();


            // Post cancellation through PurchFormLetter (PurchaseOrder)

            purchFormLetter = PurchFormLetter::construct(DocumentStatus::PurchaseOrder);


            purchFormLetter.update( purchTable,purchTable.PurchId,

                DateTimeUtil::getSystemDate(DateTimeUtil::getCompanyTimeZone()), // Posting date

                PurchUpdate::All,       // Cancel all lines

                AccountOrder::None,     // No specific vendor account order

               false,               // Whether this is proforma

                false,                // Whether to print PO

                false                 // Whether to reprint PO

            );

            ttscommit;

        }

        catch (Exception::Error)

        {

            // Rollback transaction on error

            ttsabort;

            error(strFmt("Error while cancelling purchase order %1", purchId));

        }

    }

}


Create and post the purch order product receipt using x++ D365fo

PurchFormLetter                          purchFormLetter;

PurchFormletterParmData          purchFormLetterParmData;

PurchParmUpdate                      purchParmUpdate;

PurchParmTable                       purchParmTable;

PurchParmLine                        purchParmLine;

PurchTable                               purchTable;

PurchLine                                purchLine;

    changecompany(_dataAreaId)

    {

        // Find purchase order header

        purchTable = PurchTable::find("Test001");

        if (purchTable.RecId != 0)

        { 

            try

            {

                ttsbegin;

                // Initialize Parm Data for Packing Slip

                purchFormLetterParmData = PurchFormletterParmData::newData(DocumentStatus::PackingSlip, 

                                                VersioningUpdateType::Initial);

                purchFormLetterParmData.parmOnlyCreateParmUpdate(true);

                purchFormLetterParmData.createData(false);

                purchParmUpdate = purchFormLetterParmData.parmParmUpdate();

                // Create ParmTable entry (Header level)

                purchParmTable.clear();

                purchParmTable.initValue();

                purchParmTable.TransDate                = 12/08/2025;     // Posting date

                purchParmTable.Ordering                 = DocumentStatus::PackingSlip;

                purchParmTable.ParmJobStatus            = ParmJobStatus::Waiting;

                purchParmTable.Num                      = "TestPR001";       // Product receipt number

                purchParmTable.PurchId                  = purchTable.PurchId;      // Link to PO

                purchParmTable.PurchName                = purchTable.PurchName;

                purchParmTable.DeliveryName             = purchTable.DeliveryName;

                purchParmTable.DeliveryPostalAddress    = purchTable.DeliveryPostalAddress;

                purchParmTable.OrderAccount             = purchTable.OrderAccount;

                purchParmTable.CurrencyCode             = purchTable.CurrencyCode;

                purchParmTable.InvoiceAccount           = purchTable.InvoiceAccount;

                purchParmTable.ParmId                   = purchParmUpdate.ParmId;

                purchParmTable.insert();

                // Loop through purchase lines and create ParmLine entries

                while select * from purchLine

                    where purchLine.PurchId     == purchTable.purchId

                       && purchLine.IsDeleted   == NoYes::No

                {

                    purchParmLine.clear();

                    purchParmLine.initValue();

                    purchParmLine.initFromPurchLine(purchLine);

                    purchParmLine.ReceiveNow    = purchLine.PurchQty;  // Receive full line qty

                    purchParmLine.modifiedReceiveNow();

                    purchParmLine.ParmId        = purchParmTable.ParmId;

                    purchParmLine.TableRefId    = purchParmTable.TableRefId;

                    // Calculate qty and line amount

                    purchParmLine.setQty(DocumentStatus::PackingSlip, false, true);

                    purchParmLine.setLineAmount();

                    purchParmLine.insert();

                }

                // Build Form Letter object for Packing Slip Posting

                purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);

                purchFormLetter.transDate(12/08/2025);

                purchFormLetter.proforma(false);                  // Not a proforma posting

                purchFormLetter.printFormLetter(false);           // Do not print immediately

                purchFormLetter.specQty(PurchUpdate::All);        // Post all quantities

                purchFormLetter.purchTable(purchTable);

                purchFormLetter.parmParmTableNum(purchParmTable.ParmId);

                purchFormLetter.parmId(purchParmTable.ParmId);

                purchFormLetter.purchParmUpdate(purchFormLetterParmData.parmParmUpdate());

                // Execute posting

                purchFormLetter.run();

                ttscommit;

            }

            catch (Exception::Error)

            {

                // Rollback in case of posting errors

                ttsabort;

                error(strFmt("Error posting product receipt %1 for PO %2", _productReceiptId, _purchId));

            }

        

    }

}


Cancel purch order all quantity using x++ D365fo

 PurchTable          purchTableLoc;

PurchLine           purchLineLoc;

InventTrans         inventTransLoc;

InventTransOrigin   inventTransOriginLoc;

ttsBegin;

purchTableLoc = PurchTable::find(_purchId, true);

if (purchTable != null)

{                    

    while select forupdate * from purchLineLoc

        where purchLineLoc.PurchId     == purchTableLoc.PurchId

           && purchLineLoc.PurchStatus == PurchStatus::Backorder

    join  inventTransLoc

    exists join inventTransOriginLoc

        where inventTransOriginLoc.RecId         ==  inventTransLoc.InventTransOrigin

           && inventTransOriginLoc.InventTransId == purchLineLoc.InventTransId

    {

  // to check the purch lines are not received

        if(inventTrans.StatusReceipt == StatusReceipt::Ordered)

        {

            purchLineLoc.RemainInventPhysical = 0.00;

            purchLineLoc.RemainPurchPhysical  = 0.00;

            purchLineLoc.reread();

            purchLineLoc.update();

            InventMovement::bufferSetRemainQty(purchLineLoc);

        }

    }

    purchTableLoc.PurchStatus = PurchStatus::Canceled;

    purchTableLoc.update();

}

ttsCommit;

Create request change to purchase order using x++ D365fo

  purchTable = PurchTable::find(purchId, true);

 if (purchTable != null)

 {

     try

     {

         VersioningPurchaseOrder::newPurchaseOrder(purchTable).createChangeRequest();

     }

     catch ()

     {

            // write your error

      }

use global::RunAsync using x++ d365fo

         Global::runAsync(classNum("MyTesrClass"), staticMethodStr(MyTesrClass, myMethod),

    "pass your parametervalue", System.Threading.CancellationToken::None, classNum(MyTesrClass),

    staticMethodStr(MyTesrClass, myMethod));


Confirm purch order using x++ d365FO

 PurchFormLetter purchFormLetter;

 PurchTable      purchTable;

purchTable = PurchTable::find(_purchId);

if (purchTable != null)

{    

    ttsbegin;

    purchFormLetter = PurchFormLetter::construct(DocumentStatus::PurchaseOrder);

 purchFormLetter.update( purchTable,purchTable.PurchId,DateTimeUtil::getSystemDate(DateTimeUtil::getCompanyTimeZone()),PurchUpdate::All,AccountOrder::None, false, false, false);

    ttscommit;

}


Submit the purch order workflow using x++ d365fo

 PurchTable purchTable;

  purchTable = PurchTable::find("Test001");

    changecompany (purchTable.dataAreaId)

    {

        if (purchTable != null && purchTable.canSubmitToWorkflow(workflowTypeStr(PurchTableTemplate)))

        {

            purchTable.submitToWorkflow(workFlowTypeStr(PurchTableTemplate), '', false);

        }

    }

Attach file to docuref from outside stream using x++ d365fo

public DocuRef attachFile(purchtable_purchTable, System.IO.Stream _stream, str _filePath, str _attachmentName, DocuType _docuType, FileId _fileId)

{

    DocuRef ret;

    if (!_purchTable.RecId || !_docuType.RecId || !_attachmentName || !_stream || !_filePath)

    {

        throw error(error::missingParameter(null));

    }

    if (_stream.CanSeek)

    {

        _stream.Seek(0, System.IO.SeekOrigin::Begin);

    }

    if (!Docu::validateFileSize(_docuType, _stream.Length))

    {

        throw error("file size is large");

    }

    try

    {

        using (System.IO.MemoryStream localStream = new System.IO.MemoryStream())

        {

            _stream.CopyTo(localStream);

            if (localStream.CanSeek)

            {

                localStream.Seek(0, System.IO.SeekOrigin::Begin);

            }

            ttsbegin;

            ret.RefTableId     = DocuRef::GetRootTableID(_purchTable.TableId);

            ret.RefRecId       = _purchTable.RecId;

            ret.RefCompanyId   = _purchTable.DataAreaId;

            ret.TypeId         = _docuType.TypeId;

            ret.Name           = _attachmentName;

            ret.insert();

            boolean result = this.Attachment( ret, _docuType,_filePath,System.Web.MimeMapping::GetMimeMapping(_filePath),

   localStream,_fileId);

            if (!result)

            {

                throw error("ErrorWhileAttaching");

            }

            ttscommit;

        }

    }

    catch

    {

        // Optional: add error handling or logging if needed

        throw;

    }

    return ret;

}

public boolean Attachment(DocuRef _docuRef, DocuType _docuType, str _fileName, str _contentType, System.IO.Stream _fileContents, FileId _fileId)

{

    boolean ret = false;

    str fileExtension = Docu::GetFileExtension(_fileName);

    if (fileExtension && !Docu::validateExtension(fileExtension))

    {

        return checkFailed(strFmt("@ElectronicReporting:AttachmentTypeIsNotAllowed", strFmt('.%1', fileExtension)));

    }

    DocuUploadResult result = this.createDocuValueTabe(_fileContents, _fileName, _docuType, _contentType, _docuRef.Name, _fileId);

    if (result.getUploadStatus())

    {

        DocuValue docuValue = DocuValue::findByFileId(result.fileId());

        _docuRef.selectForUpdate(true);

        _docuRef.ValueRecId = docuValue.RecId;

        _docuRef.update();

        ret = true;

    }

    else

    {

        throw error("@ElectronicReporting:FileTemplateNotFound");

    }

    return ret;

public FileUploadResultBase createDocuValueTabe( System.IO.Stream _stream, str _fileName,DocuType _docuType,

    str _contentType = null,Description _name = '', FileId _fileId = newGuid())

{

    Microsoft.Dynamics.AX.Framework.FileManagement.IDocumentStorageProvider storageProvider = 

        Docu::GetStorageProvider(_docuType, true, curUserId());

    if (storageProvider)

    {

        str uniqueFileName           = storageProvider.GenerateUniqueName(_fileName);

        str fileNameWithoutExtension = System.IO.Path::GetFileNameWithoutExtension(uniqueFileName);

        str fileExtension            = Docu::GetFileExtension(uniqueFileName);

        str name                     = _name ? _name : fileNameWithoutExtension;

        if (Docu::validateExtension(fileExtension))

        {

            DocuValue docValue;

            docValue.Name              = name;

            docValue.FileId            = _fileId;

            docValue.FileName          = fileNameWithoutExtension;

            docValue.FileType          = fileExtension;

            docValue.OriginalFileName  = _fileName;

            docValue.Type              = DocuValueType::Others;

            docValue.StorageProviderId = storageProvider.ProviderId;

            if (_stream.CanSeek)

            {

                _stream.Seek(0, System.IO.SeekOrigin::Begin);

            }

            DocumentLocation location;

            var overwritableStorageProvider = storageProvider as IOverwriteableDocumentStorageProvider;

            if (overwritableStorageProvider != null)

            {

                location = overwritableStorageProvider.SaveFileWithOverwrite(docValue.FileId, uniqueFileName, _contentType, _stream);

            }

            else

            {

                location = storageProvider.SaveFile(docValue.FileId, uniqueFileName, _contentType, _stream);

            }

            if (location != null)

            {

                if (location.NavigationUri)

                {

                    docValue.Path = location.get_NavigationUri().ToString();

                }

                if (location.AccessUri)

                {

                    docValue.AccessInformation = location.get_AccessUri().ToString();

                }

                if (docValue.validateWrite())

                {

                    docValue.insert();

                    return new DocuUploadResult(_fileName, _contentType, true, '', _fileId);

                }

            }

        }

    }

    return null;

}


Call API using x++ D365FO

 System.Net.HttpWebRequest    request; System.Net.HttpWebResponse   response; System.IO.Stream             dataStream; System.IO.StreamReade...