Monday, October 2, 2023

Change SSRS Report Design Based On Condition , D365 ,X++

 To change Sales Invoice control document's design based on condition use following code.

Here I have created COC of salesInvoiceController class to handle designs



[ExtensionOf(classstr(SalesInvoiceController))]
final class KA_SalesInvoiceController_Extension
{


    //public static void main(Args _args)
    //{


    //    //<GEEPL>
    //    #ISOCountryRegionCodes
    //    RecordSortedList journalList;
    //    CustInvoiceJour custInvoiceJour;
    //    CustInvoiceTrans  custInvoiceTrans;
    //    InventTable inventTable;
    //    EcoResProduct ecoResProduct;
    //    //</GEEPL>
    //    // <GTE><GIN>
    //    Common common;
    //    // </GTE></GIN>

    //    GiroPrintMgmtFormLetterController formLetterController = SalesInvoiceController::construct();

    //    formLetterController.parmArgs(_args);

    //    journalList = _args.record() ? FormLetter::createJournalListCopy(_args.record()) : _args.object();
    //    journalList.first(custInvoiceJour);

    //    dialog dialog;
    //    MenuFunction    menuFunction;
    //    CustInvoiceJour custInvoiceJourUpdate;
    //    dialogGroup dialogGroup;
    //    dialogField dialogField;
    //    dialog = new Dialog("Is sales tax invoice?");

    //    Args args = new Args();
    //    dialogField = dialog.addField(enumStr(NoYes));

    //    if (dialog.run())
    //    {
    //        formLetterController.parmArgs(_args);
    //        if(dialogField.value() == NoYes::Yes)
    //            formLetterController.parmReportName(ssrsReportStr(SalesInvoiceCopy, SalesTaxInvoice));                ///sales tax invoice
    //        else
    //            formLetterController.parmReportName(ssrsReportStr(SalesInvoiceCopy, Report));
    //        formLetterController.parmShowDialog(true);
    //        formLetterController.parmDialogCaption("@SYS22766");
    //        formLetterController.startOperation();

    //    }
    //    next main( _args);



    //}

    //protected void outputReport()
    //{
    //    SRSCatalogItemName          reportDesign;


    //    if(this.parmReportName() == ssrsReportStr(SalesInvoiceCopy, SalesTaxInvoice))
    //    {
    //        reportDesign = ssrsReportStr(SalesInvoiceCopy, SalesTaxInvoice);
    //    }
    //    else
    //    {
    //        reportDesign = ssrsReportStr(SalesInvoiceCopy, Report);
    //    }

    //    this.parmReportName(reportDesign);
    //    this.parmReportContract().parmReportName(reportDesign);

    //    formLetterReport.parmReportRun().settingDetail().parmReportFormatName(reportDesign);

    //    next outputReport();

    //}

}



Cancel Super Lookup Call D365 , X++

 write this code in the OnLookup event handler after your lookup code.


 FormControlCancelableSuperEventArgs ce = e as FormControlCancelableSuperEventArgs;
            ce.CancelSuperCall();


For example see below code :

 [FormControlEventHandler(formControlStr(InventJournalMovement, InventJournalTrans_ItemId), FormControlEventType::Lookup)]
    public static void InventJournalTrans_ItemId_OnLookup(FormControl sender, FormControlEventArgs e)
    {
        InventJournalTrans InventJournalTrans = sender.formRun().dataSource("InventJournalTrans").cursor();
        inventJournalTable inventJournalTable = inventJournalTable::find(InventJournalTrans.JournalId);
       
            Query query = new Query();
            QueryBuildDataSource queryBuildDataSource;
            QueryBuildRange queryBuildRange;
            SysTableLookup sysTableLookup =
            SysTableLookup::newParameters(tableNum(InventTable), sender);
            sysTableLookup.addLookupField(fieldNum(InventTable, ItemId));
            sysTableLookup.addLookupField(fieldNum(InventTable, NameAlias));
            queryBuildDataSource = query.addDataSource(tableNum(InventTable));
          //  queryBuildDataSource.addRange(fieldNum(InventTable , PowerPlantItem)).value(enum2Str(NoYes::Yes));
            sysTableLookup.parmQuery(query);
            sysTableLookup.performFormLookup();
//To cancel super call add these two lines
            FormControlCancelableSuperEventArgs ce = e as FormControlCancelableSuperEventArgs;
            ce.CancelSuperCall();
        
       
    }



Call .Net class method in X++ code

You need to create .Net Class Library project if you want to consumen .Net functionality in you X++ project 

then On X++ class define .Net namespace like this


using KAFileFormatting;


then If you method is statis then you can call it like this 



KAFileFormatting.KATest::excelToPDF(memoryStream);


Here KAFileFormatting is the Namespace name of .Net project , KATest is the Class name and excelToPDF is the method name . Method can take multiple parameters.

Note: For Class library project your framework should be less than or equal to the framework of your X++ project. otherwise system cannot identify your namespace of .Net in X++ class.

Calculate Sales Tax amount through X++ , D365

 This code demonstrate you how you can calculate sales tax using TaxGroup , TaxItemGroup fields



    public real calculateLineTaxAmount(TaxGroup _taxGroup , TaxItemGroup _taxItemGroup , Amount _lineAmount)
    {
        real TaxAmount=0 , TaxValue = 0;
        TaxOnItem TaxOnItem;
        TaxGroupData TaxGroupData;
        TaxTable TaxTable;
        while select TaxOnItem
                    where TaxOnItem.TaxItemGroup == _taxItemGroup
        {
             if(TaxOnItem)
             {
                 TaxGroupData.clear();
                 select TaxGroupData
                 where TaxGroupData.TaxGroup == _taxGroup && TaxGroupData.TaxCode == TaxOnItem.TaxCode;
                     if(TaxGroupData)
                     {
                          TaxTable.clear();
                          select * from TaxTable
                                where TaxTable.TaxCode == TaxGroupData.TaxCode;
               
                         if(TaxTable)
                          {
                                TaxValue  = TaxData::find(TaxTable.TaxCode, Systemdateget(), 0).TaxValue;
                                TaxAmount = TaxAmount + (_lineAmount * TaxValue) / 100;
                             //  tempTable.UnitPriceInc = TaxAmount;
                          }
                    }
             }
        }
        return TaxAmount;
    } 



Schedule a Batch Job Through x++ , D365

 You can schedule a batch job from front end as well as through coding 

This Post provides you the code for scheduling Batch Job through X++



class KA_SMSBatchSchedular
{        

    // <summary>
    // Runs the class with the specified arguments.
    // </summary>
    // <param name = "_args">The specified arguments.</param>
    // public static void main(Args _args)
    // {        
    //    BatchHeader batHeader;
    //    BatchInfo batInfo;
    //    RunBaseBatch rbbTask;
    //    str sParmCaption = "My Demonstration (b351)";
    //    ;
    //    rbbTask = new KA_SendSMSBatchJob();
    //    batInfo = rbbTask .batchInfo();
    //    batInfo .parmCaption(sParmCaption);
    //    batInfo .parmGroupId(""); // The "Empty batch group".
    //    batHeader = BatchHeader ::construct();
    //    batHeader .addTask(rbbTask);
    //    batHeader .save();
    //    info(strFmt("'%1' batch has been scheduled.", sParmCaption));
    // }

   // static void batchJobSchedule(Args _args)
    public static void main(Args _args)
    {
        BatchHeader objBatchheader;
        SysRecurrenceData sysRecurrenceData;
        Batch batch;
        BatchJob batchJob;
        KA_SendSMSBatchJob smsBatcjJob;
        BatchInfo objBatchInfo;
        BatchRetries noOfRetriesOnFailure = 0;
        ;

        // Setup the RunBaseBatch Job
        objBatchheader = Batchheader::construct();
        smsBatcjJob = new KA_SendSMSBatchJob();
        objBatchInfo = smsBatcjJob.batchInfo();
        objBatchInfo.parmRetriesOnFailure(noOfRetriesOnFailure);
        objBatchInfo.parmCaption("SMS sending batch job!"); // Description Batch Job
        objBatchInfo.parmGroupId(''); // Batch Gorup
        objBatchInfo.parmBatchExecute(NoYes::Yes);
        objBatchheader.addTask(smsBatcjJob);

        // Set the recurrence data
        sysRecurrenceData = SysRecurrence::defaultRecurrence();
        SysRecurrence::setRecurrenceStartDateTime(sysRecurrenceData, DateTimeUtil::addSeconds(DateTimeUtil::applyTimeZoneOffset(DateTimeUtil::getSystemDateTime() , DateTimeUtil::getUserPreferredTimeZone()), 2)); // Set range of recurrence
        SysRecurrence::setRecurrenceNoEnd(sysRecurrenceData);
        SysRecurrence::setRecurrenceUnit(sysRecurrenceData, SysRecurrenceUnit::Minute); // Set reccurence pattern
        objBatchheader.parmRecurrenceData(sysRecurrenceData);
        // Set the batch alert configurations
     //   objBatchheader.parmAlerts(NoYes::No, NoYes::Yes, NoYes::No, NoYes::Yes, NoYes::Yes);
        objBatchheader.parmAlerts(NoYes::Yes, NoYes::Yes, NoYes::No, NoYes::Yes, NoYes::Yes);
        objBatchheader.save();

        // Update the frequency to run the job to every two minutes
        ttsbegin;
        select forupdate batchJob
            join batch
            where batchJob.RecId == batch.BatchJobId
            && batch.ClassNumber == classnum(KA_SendSMSBatchJob);

        sysRecurrenceData = batchJob.RecurrenceData;
        sysRecurrenceData = conpoke(sysRecurrenceData, 8, [10]);
        batchJob.RecurrenceData = sysRecurrenceData;
        batchJob.update();
        ttscommit;
    }

}


just call this class to schedule your Batch job . you can create a action menuitem and give object of this class in menuItem .

Sunday, October 1, 2023

Apply Range In Datasource

You can add range in Datasource object like that through coding.

If you want to add range in report then you can this code in DP class. If you want to add range in Form datasource then you can write this code in executeQuery() method of form . Or else anywhere where you want to add range in dataSource object.



  QueryBuildDataSource qbds;

            QueryBuildRange         qbr;

            qbds = this.query().dataSourceTable(tableNum(CMSProspectParentTable));

            qbr = qbds .addRange(fieldNum(CMSProspectParentTable , ParentId));

            qbr.value("CMS-00001");

            qbr.status(2);



Change SSRS Report Design Based On Condition , D365 ,X++

 To change Sales Invoice control document's design based on condition use following code. Here I have created COC of salesInvoiceControl...