Thursday, November 27, 2025

Changing instance of class to extension class to trigger logic on extension layer

Details:

In case, extensible support for class instance to reinstance with different class to execute on Extension layer.


public static SANSyncInventTable construct(Common _record, Common _record_orig, boolean _isUpdate)

{

    SANSyncInventTable syncRecordInventTable;

    syncRecordInventTable = new SANSyncInventTable(_record, _record_orig, _isUpdate);

    return syncRecordInventTable;

}


[PostHandlerFor(classStr(SANSyncInventTable), staticMethodStr(SANSyncInventTable, construct))]

public static void SANSyncInventTable_Post_construct(XppPrePostArgs args)

{

    args.setReturnValue(SAN_SANSyncInventTable::construct(args.getArg(identifierStr(_record))

        ,args.getArg(identifierStr(_record_orig))

        ,args.getArg(identifierStr(_isUpdate))));

}


Wednesday, November 19, 2025

DMF export using X++

Base class for extract

 /// <summary>

/// Class for extract data

/// </summary>

class SAN_SalesReportDailyService

{

    Filename                filename;

    int                     recordCnt;


    /// <summary>

    /// Import warranty claims

    /// </summary>

    /// <param name = "_contract">Contract of type <b>SAN_SalesReportDailyContract</b></param>

    [SysEntryPointAttribute(false)]

    public void processImport(SAN_SalesReportDailyContract _contract)

    {

        contract            = _contract;


        try

        {

            this.exportSalesInvoiceData();

              

            if (recordCnt)

            {

                info(strFmt("@SANaris:FileExportInfo", filename));

            }

        }

        catch

        {

            error("@SYP4861341");

        }


    }


    public void exportSalesInvoiceData()

    {

        #DMF

        SharedServiceUnitFileID fileId;

        SAN_DataEntityExporter exporter = new SAN_DataEntityExporter();


        DMFDefinitionGroupName definitionGroupName = SalesParameters::find().SAN_SalesDailyReportDefinitionGroup; //TODO create new parameter field to get DMF execution

        DMFDefinitionGroupEntity dmfDefinitionGroupEntity = SAN_SalesReportDailyService::findDMFDefinitionGroupEntity(definitionGroupName);


        if (dmfDefinitionGroupEntity)

        {

            this.updateQueryData(dmfDefinitionGroupEntity);

            this.setFileName();

 

            exporter.parmFilename(filename);

            exporter.exportDataEntity(definitionGroupName, dmfDefinitionGroupEntity.Entity);

        }

        else

        {

            throw error(strFmt("@SANaris:DataEntityMapError", definitionGroupName));

        }

    }


    public str setFileName()

    {

        #File

        str priFix;


        priFix = 'SalesReportSAN_';


        filename = priFix +

            date2str(systemDateGet(),123,DateDay::Digits2,DateSeparator::None,DateMonth::Digits2,DateSeparator::None,DateYear::Digits4) + #xlsx;


        return filename;

    }


    private void updateQueryData(DmfDefinitionGroupEntity _dmfDefinitionGroupEntity)

    {

        container queryData = _dmfDefinitionGroupEntity.QueryData;


        if (queryData == connull())

        {

            queryData = DMFUtil::getDefaultQueryForEntityV3(_dmfDefinitionGroupEntity.Entity, _dmfDefinitionGroupEntity.DefinitionGroup);

        }


        QueryRun queryRun = new QueryRun(queryData);

        Query query = queryRun.query();


        QueryBuildDataSource qbds = query.dataSourceTable(tableNum(SAN_SalesReportDailyEntity));

        SysQuery::findOrCreateRange(qbds, fieldNum(SAN_SalesReportDailyEntity, InvoiceDate)).value(queryRange(fromDate, toDate));

        if (warehouseId)

        {

            SysQuery::findOrCreateRange(qbds, fieldNum(SAN_SalesReportDailyEntity, Warehouse)).value(queryValue(warehouseId));

        }


        queryRun = new QueryRun(query);

        queryData = queryRun.pack();

        

        recordCnt = SysQuery::countTotal(queryRun);

        if (recordCnt < 1)

        {

            throw error("@SYS4205");

        }


        ttsbegin;

        _dmfDefinitionGroupEntity.reread();

        _dmfDefinitionGroupEntity.selectForUpdate(true);

        _dmfDefinitionGroupEntity.QueryData = queryData;

        _dmfDefinitionGroupEntity.update();

        ttscommit;

    }


    /// <summary>

    /// Finds the <c>DMFDefinitionGroupEntity</c> record in the given definition group for the Line active view record entity.

    /// </summary>

    /// <param name = "_definitionGroupName">The name if the definition group</param>

    /// <returns>the <c>DMFDefinitionGroupEntity</c> record if found, otherwise null</returns>

    public static DMFDefinitionGroupEntity findDMFDefinitionGroupEntity(DMFDefinitionGroupName _definitionGroupName)

    {

        DMFDefinitionGroupEntity definitionGroupEntity;

        DMFEntity dmfEntity;

        str targetEntityName;


        targetEntityName = 'SAN_SalesReport';


        select firstonly RecId, Entity, DefinitionGroup from definitionGroupEntity

            exists join dmfEntity

                where definitionGroupEntity.DefinitionGroup == _definitionGroupName

                    && dmfEntity.EntityName == definitionGroupEntity.Entity

                    && dmfEntity.TargetEntity == targetEntityName;


        return definitionGroupEntity;

    }


}



Helper class:

/// <summary>

/// Data entity data export helper class.

/// </summary>

public class SAN_DataEntityExporter

{

    Filename filename;

    

    /// <summary>

    /// set file name

    /// </summary>

    /// <param name = "_filename">file name to export data</param>

    /// <returns>file name</returns>

    public Filename parmFilename(Filename _filename = filename)

    {

        filename = _filename;


        return filename;

    }


    /// <summary>

    /// Export an entity to file

    /// </summary>

    /// <param name = "_definitionGroupName">Definition group to reuse</param>

    /// <param name = "_entityName">Entity label</param>

    public void exportDataEntity(DMFDefinitionGroupName _definitionGroupName, DMFEntityName _entityName)

    {

        #DMF

        SharedServiceUnitFileID fileId;


        try

        {

            DMFEntityExporter exporter = new DMFEntityExporter();

            fileId = exporter.exportToFile(_entityName,

                                            _definitionGroupName,

                                            '',

                                            BudgetPlanningConstants::Excel,

                                            #FieldGroupName_AllFields,

                                            conNull(),

                                            curExt()

                                            );

 

            if (fileId != '')

            {

                this.sendFileToDestination(fileId);

            }

            else

            {

                // DMF execution failed and details were written to the execution log.

                throw error("@CashManagement:DMFExportCallFailedToExecutionLog");

            }

        }

        catch

        {

            error("@SYP4861341");

        }

    }


    /// <summary>

    /// Creates a stream, puts it into temp storage (like SendFileToTempStore), and redirects the user to that file to cause it to be downloaded by the user's browser.

    /// </summary>

    /// <param name = "_fileId">The file name of the stream.</param>

    public client void sendFileToDestination(SharedServiceUnitFileID _fileId)

    {

        str downloadUrl = DMFDataPopulation::getAzureBlobReadUrl(str2Guid(_fileId));

        

        System.IO.Stream stream = File::UseFileFromURL(downloadUrl);

        File::SendFileToUser(stream, filename);

    }


}

Tuesday, November 4, 2025

Purchase transport days in X++ D365FO

VendTable localVendTable = VendTable::find(<VendAccount>, false);


VendCustTransportPointCalculateInput input = VendCustTransportPointCalculateInput::construct();

input.ShippingAddress = localVendTable.postalAddress();

input.ReceivingAddress =  <Current logictics delivery address>;

input.DeliveryMode = <Current mode of delivery>;

input.PurchaseCalendarId = localVendTable.PurchCalendarId;

input.VendorShipCalendarId = <Current Ship calendar Id (from PO line)>;

input.CalculateDirection = <Forward or bacward>;

input.LeadTime = _leadtime;

input.UseCalendarDays = _useCalendarDays;

input.RequestedShipDateInPast = PurchParameters::find().RequestedShipDateInPast;

 input.VendorShipCalendarId = '';

 input.ConfirmedShipDate = _confirmedShipDate;

 input.ConfirmedReceiptDate = _confirmedReceiptDate;

 VendCustTransportPointCalculateOutput output = VendCustTransportPointLine::calculateConfirmedShipAndReceiptDate(input);

Dynamically setting entire Form security access through Extension in D365FO

/// <summary> /// To check if user can get access to the Parameter form /// </summary> class SAN_ParamFormsAccessCtrl {     prot...