Monday, May 24, 2021

To find out which table access is missing - event create rule permission in d365fo

 class EventSecurity, method isFilterAccessible.


To find out which table access is missing you can change this method in a TEST environment to:

public boolean isFilterAccessible(Query   query)
{
    QueryBuildDataSource    qbds;
    Counter                 i;

    for (i=1;i<=query.dataSourceCount();i++)
    {
        qbds=query.dataSourceNo(i);
        if (! this.isTableAccessible(qbds.table()))
        {
            info(tableId2name(qbds.table()));
            //return false;
        }
    }

    return true;
}

get last workflow approver in d365fo

  while select workflowTrackingTable  order by CreatedDateTime asc 

                                            where workflowTrackingTable.CreatedDateTime >= fromDateTimeValue

                                              &&  workflowTrackingTable.CreatedDateTime <= toDateTimeValue                             

        {

            actionTakenByName = DirPersonUser::userId2Name(workflowTrackingTable.User);//xUserInfo::find(true,workflowTrackingTable.User).name;


            select workflowTrackingStatusTable where workflowTrackingStatusTable.RecId == workflowTrackingTable.WorkflowTrackingStatusTable;


            select workflowCommentTable where workflowCommentTable.WorkflowTrackingTable == workflowTrackingTable.RecId;


            select workflowWorkItemTable where workflowWorkItemTable.CorrelationId == workflowTrackingStatusTable.CorrelationId;


            if(workflowTrackingStatusTable)

            {

                ttsbegin;

                afzWorkflowInquiryTable.DateTime            = workflowTrackingTable.CreatedDateTime;

                afzWorkflowInquiryTable.DocumentType        = workflowTrackingStatusTable.DocumentType;

                afzWorkflowInquiryTable.WorkflowInstance    = workflowTrackingStatusTable.InstanceNumber;

                afzWorkflowInquiryTable.WorkflowStatus      = workflowTrackingStatusTable.TrackingStatus;

                afzWorkflowInquiryTable.WorkflowStatusString = enum2Str(workflowTrackingStatusTable.TrackingStatus);

                afzWorkflowInquiryTable.SubmittedBy         = workflowTrackingStatusTable.getSubmitterUserName();

                afzWorkflowInquiryTable.Document            = workflowTrackingStatusTable.Document;

                if(actionTakenByName)

                    afzWorkflowInquiryTable.ActionTakenBy   = actionTakenByName;

                else

                    afzWorkflowInquiryTable.ActionTakenBy   = workflowTrackingTable.User;

                afzWorkflowInquiryTable.TrackingType        = workflowTrackingTable.TrackingType;

                afzWorkflowInquiryTable.Context             = workflowTrackingTable.TrackingContext;

                afzWorkflowInquiryTable.CompanyName         = workflowTrackingStatusTable.ContextCompanyId;

                afzWorkflowInquiryTable.Comment             = workflowCommentTable.Comment;

                afzWorkflowInquiryTable.TrackingMessage     = workflowCommentTable.TrackingMessage;

                afzWorkflowInquiryTable.Name                = workflowTrackingTable.Name;

                afzWorkflowInquiryTable.DocumentRecId       = workflowTrackingStatusTable.ContextRecId;

                afzWorkflowInquiryTable.insert();

                ttscommit;

            }

                        

        }



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Get only last approver detail: - 


 select workflowTrackingStatus order by CreatedDateTime desc

            where workflowTrackingStatus.ContextTableId == tableNum(purchtable)

            && workflowTrackingStatus.ContextRecId == purchtable.recid

            && workflowTrackingStatus.TrackingStatus == WorkflowTrackingStatus::Completed

            join workflowTrackingTable order by CreatedDateTime desc

            where workflowTrackingTable.WorkflowTrackingStatusTable == workflowTrackingStatus.RecId

            && workflowtrackingtable.TrackingContext == workflowtrackingcontext::WorkItem

            && workflowTrackingTable.TrackingType == WorkflowTrackingType::Approval

            join userInfo

            where userInfo.id == workflowTrackingTable.User;


        //_purchaseOrderHeader.User =   HcmWorker::findByPerson(DirPersonuser::find(currentUserId).PersonParty).name();


        _purchaseOrderHeader.User =   UserInfoHelp::userName(workflowTrackingTable.User);

        _purchaseOrderHeader.UserPrintedBy =  UserInfoHelp::userName(curUserId());

        _purchaseOrderHeader.UserOriginator =  UserInfoHelp::userName(purchtable.CreatedBy);

        

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


SQL Workflow Approval code

select * from workflowTrackingStatusTable a -- order by createdDateTime Asc
inner join WorkflowTrackingTable b
on a.RecId = b.WorkflowTrackingStatusTable
and a.TrackingStatus = 1
and a.ContextRecId = 5637145328 --(PurchTable/ PurchReqTable RecID)
and a.ContextTableId = 20050 --(PurchTable/ PurchReqTable TableId)
and b.TrackingType = 4
and b.trackingContext = 5
order by a.createdDateTime, b.createdDateTime Asc


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SQL Get Table ID

select * from SysTableIdView where Name = 'PURCHTABLE'


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


Sunday, May 23, 2021

get last approver in purchase order in d365fo

 public void getLastApprover(PurchPurchaseOrderHeader    tempTable = tempTable)

    {

        AFZWorkflowStatusTable      afzWorkflowStatusTable;

        WorkflowTrackingStatusTable workflowTrackingStatus;

        WorkflowTrackingTable workflowTrackingTable;

        WorkflowTrackingCommentTable workflowTrackingCommentTable;

        UserInfo userInfo;

        RecId _recId;

        Name _name;

        HcmWorkerRecId  workerRecId;

        HcmWorker       hcmWorker;

        _recId = PurchTable::find(tempTable.PurchId).RecId;


        delete_from afzWorkflowStatusTable;


        while select workflowTrackingStatus order by createdDateTime asc

            where workflowTrackingStatus.ContextTableId             == tableNum(PurchTable)

                && workflowTrackingStatus.ContextRecId              == _recId

                && workflowTrackingStatus.TrackingStatus            == WorkflowTrackingStatus::Completed

        join workflowTrackingTable order by createdDateTime asc

            where workflowTrackingTable.WorkflowTrackingStatusTable == workflowTrackingStatus.RecId

                && workflowtrackingtable.TrackingContext            == workflowtrackingcontext::WorkItem

                && workflowTrackingTable.TrackingType               == WorkflowTrackingType::Approval

        join userInfo

            where userInfo.id                                       == workflowTrackingTable.User

        {

            select firstonly workflowTrackingCommentTable

                where workflowTrackingCommentTable.WorkflowTrackingTable    == workflowTrackingTable.RecId;


            afzWorkflowStatusTable.clear();

            afzWorkflowStatusTable.ContextCompanyId             = workflowTrackingStatus.ContextCompanyId;

            afzWorkflowStatusTable.ContextTableId               = workflowTrackingStatus.ContextTableId;

            afzWorkflowStatusTable.ContextRecId                 = workflowTrackingStatus.ContextRecId;

            afzWorkflowStatusTable.WorkflowTrackingStatusTable  = workflowTrackingStatus.RecId;

            afzWorkflowStatusTable.TrackingStatus               = workflowTrackingStatus.TrackingStatus;

            afzWorkflowStatusTable.WorkflowTrackingTable        = workflowTrackingTable.RecId;

            afzWorkflowStatusTable.TrackingType                 = workflowTrackingTable.TrackingType;

            afzWorkflowStatusTable.TrackingContext              = workflowtrackingtable.TrackingContext;

            afzWorkflowStatusTable.UserId                       = workflowTrackingTable.User;

            afzWorkflowStatusTable.UserName                     = userInfo.name;

            afzWorkflowStatusTable.Comment                      = workflowTrackingCommentTable.Comment;

            afzWorkflowStatusTable.TrackingMessage              = workflowTrackingCommentTable.TrackingMessage;

            afzWorkflowStatusTable.WorkflowTrackingCommentTable = workflowTrackingCommentTable.RecId;

            afzWorkflowStatusTable.TrackingId                   = workflowTrackingCommentTable.TrackingId;

            afzWorkflowStatusTable.ApprovalDateTime             = workflowTrackingTable.CreatedDateTime;

            afzWorkflowStatusTable.Key                          = afzWorkflowStatusTable.ContextCompanyId + '-' + int2Str(afzWorkflowStatusTable.ContextTableId) + '-' +

                                                                  int642Str(afzWorkflowStatusTable.ContextRecId) + '-' + int642Str(afzWorkflowStatusTable.WorkflowTrackingTable) + '-' +

                                                                  int642Str(afzWorkflowStatusTable.WorkflowTrackingCommentTable);

            afzWorkflowStatusTable.insert();

        }


        select firstonly afzWorkflowStatusTable

            Order by afzWorkflowStatusTable.ApprovalDateTime desc

            where afzWorkflowStatusTable.ContextRecId   == _recId;


        _name = afzWorkflowStatusTable.RecId ? afzWorkflowStatusTable.UserName : '';


        if(tempTable.AFZApproverName == '')

        {

            tempTable.AFZApproverName =  _name;

            //workerRecId   = HcmWorker::userId2Worker(userInfo.id);

        

            HcmPositionWorkerAssignment workerAssignment;

            HcmPosition hcmPosition;

            HcmPositionDetail   hcmPositionDetail;

            HcmPositionRecId primaryPositionRecId;


            workerRecId   = HcmWorker::userId2Worker(afzWorkflowStatusTable.UserId);


            select recid, person from hcmWorker

            join worker, position from workerAssignment

            where workerAssignment.Worker == workerRecId;


            primaryPositionRecId = HcmWorkerHelper::getPrimaryPosition(workerAssignment.Worker);


            select recid from hcmPosition

            where hcmPosition.RecId == primaryPositionRecId

            join position, description from hcmPositionDetail

            where hcmPositionDetail.Position == hcmPosition.RecId;

            //select recid, person from hcmWorker

            //join worker, position from workerAssignment

            //where workerAssignment.Worker == workerRecId

            //join recid from hcmPosition

            //where hcmPosition.RecId == workerAssignment.Position

            //join position, description from hcmPositionDetail

            //where hcmPositionDetail.Position == hcmPosition.RecId;

            {

                tempTable.AFZDesignation = hcmPositionDetail.Description;

            }

        }


    }


SQL Workflow Approval code

select * from workflowTrackingStatusTable a -- order by createdDateTime Asc
inner join WorkflowTrackingTable b
on a.RecId = b.WorkflowTrackingStatusTable
and a.TrackingStatus = 1
and a.ContextRecId = 5637145328 --(PurchTable/ PurchReqTable RecID)
and a.ContextTableId = 20050 --(PurchTable/ PurchReqTable TableId)
and b.TrackingType = 4 -- 4 for approval, 9 for creation
and b.trackingContext = 5
order by a.createdDateTime, b.createdDateTime Asc

Monday, May 17, 2021

Update workflow status through code in d365fo

 Purchase Requisition

if(PurchReqWFStatusTransitionHelper::setPurchReqTable2InReview(purchReqTable.RecId))

{
Workflow::activateFromWorkflowType(‘PurchReqReview’,
purchReqTable.RecId,
‘Auto-Submitted into workflow’,
false,
curUserId() );
}

PurchReqWFStatusTransitionHelper::setPurchReqTable2Approved(purchReqTable.RecId,false);

ttsCommit;
info(purchReqTable.PurchReqId);
}

Tuesday, May 4, 2021

purchase order controller in d365fo

 class AVAPurchPurchaseOrderControllerExt extends PurchPurchaseOrderController

{
    public static void main(Args _args)
    {
        SrsReportRunController              formLetterController = AVAPurchPurchaseOrderControllerExt::construct();
        AVAPurchPurchaseOrderControllerExt  controller = formLetterController;
       
        controller.parmReportName(ssrsReportStr(AVAPurchPurchaseOrder, Report));
        controller.parmArgs(_args);
        controller.parmShowDialog(false);
        controller.startOperation();
    }

    public static AVAPurchPurchaseOrderControllerExt construct()
    {
        return new AVAPurchPurchaseOrderControllerExt();
    }

    public static SrsReportDataContract newDataContract(Args _args)
    {
        AVAPurchPurchaseOrderControllerExt formLetterController = AVAPurchPurchaseOrderControllerExt::construct();

        if (_args.dataset() != tableNum(VendPurchOrderJour))
        {
            throw error(strFmt("@SYS19306",funcName()));
        }
        
        formLetterController.initDataContract(_args, PrintMgmtDocType::construct(PrintMgmtDocumentType::PurchaseOrderConfirmationRequest).getDefaultReportFormat());
      
        return formLetterController.parmReportContract();
    }

    /// <summary>
    /// 34124  - add the PO number in the email subject
    /// </summary>
    public void runReport()
    {
        PurchaseOrderId purchId = vendPurchOrderJour::findByPurchId(vendPurchOrderJour.PurchId).PurchOrderDocNum;
        
        if (reportContract.parmPrintSettings().printMediumType() == SRSPrintMediumType::Email)
        {
            reportContract.parmPrintSettings().emailSubject(Global::strReplace(reportContract.parmPrintSettings().emailSubject(),"@PurchId@",purchId));
        }
        super();
    }

}