using Microsoft.Dynamics.ApplicationPlatform.Environment;

class CPLDevCapexUtility
{
  
  //---------------------Vendor Approval Notification-----------------------------------

    public static void sendFinanceForVendorApprovalNotification1(UserId	_usrId, AccountNum _vendor)
  {
    SystemNotificationDataContract notification = new SystemNotificationDataContract();
    notification.Users().value(1, _usrId);
    notification.Title("Vendor Approved");
    notification.RuleId('ExcelStaticExport');
    notification.Message(strFmt("%1 new vendor has added, please approved.", _vendor));
    notification.ExpirationDateTime(DateTimeUtil::addHours(DateTimeUtil::utcNow(), 72));

    ////// Set up the action associated with the notification
    ////SystemNotificationActionDataContract action = new SystemNotificationActionDataContract();
    ////action.Message("Click to download");
    ////action.Type(SystemNotificationActionType::AxActionMenuFunction);

    ////SystemNotificationMenuFunctionDataContract actionData = new SystemNotificationMenuFunctionDataContract();
    ////actionData.MenuItemName(menuItemActionStr(ExportToExcelStaticOpenFileAction));
    ////actionData.Data(fileName);
    ////action.Data(FormJsonSerializer::serializeClass(actionData));
    ////notification.Actions().value(1, action);

    SystemNotificationsManager::AddSystemNotification(notification);

  }

    public static void sendFinanceForVendorApprovalEmail(UserId	_usrId, AccountNum _vendor)
  {
    //SysEmailTable   sysEmailTable;
    SysEmailParameters  sysEmailParameters = SysEmailParameters::find();
    //SysUserInfo        userInfo = SysUserInfo::find(_usrId, false);
    UserInfo userInfo;
    select * from userInfo where userInfo.Id==_usrId;
    var messageBuilder = new SysMailerMessageBuilder();

    //select firstonly sysEmailTable;

    //if(userInfo.Email)
    if(userInfo.networkAlias)
    {
      messageBuilder.setFrom(sysEmailParameters.SMTPUserName);
     // messageBuilder.addTo(userInfo.Email);
      messageBuilder.addTo(userInfo.networkAlias);
      //messageBuilder.addCc("cc@example.com");
      //messageBuilder.addBcc("bcc@example.com");
      messageBuilder.setSubject("New Vendor added, need to approve");
      messageBuilder.setBody(strFmt('%1 new vendor is added, please approve the vendor.', _vendor, curUserId()));
      SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(messageBuilder.getMessage());
    }

  }

    //---------------------Vendor Approval Notification End-----------------------------------

  //---------------------Vendor Approved Notification-----------------------------------
  public static void sendVendorApprovalNotification1(UserId	_usrId, AccountNum _vendor)
  {
      SystemNotificationDataContract notification = new SystemNotificationDataContract();
      notification.Users().value(1, _usrId);
      notification.Title("Vendor Approved");
      notification.RuleId('ExcelStaticExport');
      notification.Message(strFmt("%1 vendor has approved by finance team", _vendor));
      notification.ExpirationDateTime(DateTimeUtil::addHours(DateTimeUtil::utcNow(), 72));

      //// Set up the action associated with the notification
      //SystemNotificationActionDataContract action = new SystemNotificationActionDataContract();
      //action.Message("Click to download");
      //action.Type(SystemNotificationActionType::AxActionMenuFunction);

      //SystemNotificationMenuFunctionDataContract actionData = new SystemNotificationMenuFunctionDataContract();
      //actionData.MenuItemName(menuItemActionStr(ExportToExcelStaticOpenFileAction));
      //actionData.Data(fileName);
      //action.Data(FormJsonSerializer::serializeClass(actionData));
      //notification.Actions().value(1, action);

      SystemNotificationsManager::AddSystemNotification(notification);

  }

    public static void sendVendorApprovalEmail(UserId	_usrId, AccountNum _vendor)
  {
    //SysEmailTable   sysEmailTable;
    SysEmailParameters  sysEmailParameters = SysEmailParameters::find();
    //SysUserInfo        userInfo = SysUserInfo::find(_usrId, false);
    UserInfo userInfo;
    select * from userInfo where userInfo.id==_usrId;
    var messageBuilder = new SysMailerMessageBuilder();

    //select firstonly sysEmailTable;

    if(userInfo.networkAlias)
    {
      messageBuilder.setFrom(sysEmailParameters.SMTPUserName);
      messageBuilder.addTo(userInfo.networkAlias);
     // messageBuilder.addTo(userInfo.Email);
      //messageBuilder.addCc("cc@example.com");
      //messageBuilder.addBcc("bcc@example.com");
      messageBuilder.setSubject("Vendor Approved by finance team");
      messageBuilder.setBody(strFmt('%1 vendor has been approved by %2', _vendor, curUserId()));
      SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(messageBuilder.getMessage());
    }

  }

    //---------------------Vendor Approved Notification End-----------------------------------
  
  
  //---------------------Fixed Asset Approval Notification -----------------------------------
  public static void sendFinanceForFixedAssetApprovalNotification1(UserId	_usrId, AssetId _assetId)
  {
    SystemNotificationDataContract notification = new SystemNotificationDataContract();
    notification.Users().value(1, _usrId);
    notification.Title("New Fixed Asset");
    notification.RuleId('ExcelStaticExport');
    notification.Message(strFmt("%1 new fixed asset has added, need to approve", _assetId));
    notification.ExpirationDateTime(DateTimeUtil::addHours(DateTimeUtil::utcNow(), 72));
    
    SystemNotificationsManager::AddSystemNotification(notification);
  }

    public static void sendFinanceForFixedAssetApprovalEmail(UserId	_usrId, AssetId _assetId)
  {
    //SysEmailTable   sysEmailTable;
    SysEmailParameters  sysEmailParameters = SysEmailParameters::find();
    SysUserInfo        userInfo = SysUserInfo::find(_usrId, false);
    var messageBuilder = new SysMailerMessageBuilder();

    //select firstonly sysEmailTable;

    if(userInfo.Email)
    {
      messageBuilder.setFrom(sysEmailParameters.SMTPUserName);
      messageBuilder.addTo(userInfo.Email);
      //messageBuilder.addCc("cc@example.com");
      //messageBuilder.addBcc("bcc@example.com");
      messageBuilder.setSubject("New Fixed Asset added");
      messageBuilder.setBody(strFmt('%1 new fixed asset has added, need to approve', _assetId));
      SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(messageBuilder.getMessage());
    }

  }

    //---------------------Fixed Asset Approval Notification End-----------------------------------
  
  //---------------------Fixed Asset Approved Notification-----------------------------------
    public static void sendFixedAssetApprovalNotification1(UserId	_usrId, AssetId _assetId)
  {
    SystemNotificationDataContract notification = new SystemNotificationDataContract();
    notification.Users().value(1, _usrId);
    notification.Title("Fixed Asset Approved");
    notification.RuleId('ExcelStaticExport');
    notification.Message(strFmt("%1 fixed asset has been approved by finance team", _assetId));
    notification.ExpirationDateTime(DateTimeUtil::addHours(DateTimeUtil::utcNow(), 72));

    SystemNotificationsManager::AddSystemNotification(notification);

  }

    public static void sendFixedAssetApprovalEmail(UserId	_usrId, AssetId _assetId)
  {
    //SysEmailTable   sysEmailTable;
    SysUserInfo        userInfo = SysUserInfo::find(_usrId, false);
    var messageBuilder = new SysMailerMessageBuilder();
    SysEmailParameters  sysEmailParameters = SysEmailParameters::find();

    //select firstonly sysEmailTable;

    if(userInfo.Email)
    {
      messageBuilder.setFrom(sysEmailParameters.SMTPUserName);
      messageBuilder.addTo(userInfo.Email);
      //messageBuilder.addCc("cc@example.com");
      //messageBuilder.addBcc("bcc@example.com");
      messageBuilder.setSubject("Fixed asset Approved by finance team");
      messageBuilder.setBody(strFmt('%1 fixed asset has been approved by %2', _assetId, curUserId()));
      SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(messageBuilder.getMessage());
    }

  }

    //---------------------Fixed Asset Approved Notification End-----------------------------------
  
  //-------------------------------------------------------------------------------------------------------------------------------------

  public static void sendNotificationToCreaterForCapexApproval1(UserId	_usrId, CPLDevCapexRequestNo _capexReqNo)
  {
    SystemNotificationDataContract notification = new SystemNotificationDataContract();
    notification.Users().value(1, _usrId);
    notification.Title("Capex Approved");
    notification.RuleId('ExcelStaticExport');
    notification.Message(strFmt("%1 Capex has been approved by the team", _capexReqNo));
    notification.ExpirationDateTime(DateTimeUtil::addHours(DateTimeUtil::utcNow(), 72));

    SystemNotificationsManager::AddSystemNotification(notification);

  }

    public static void sendEmailToCreaterForCapexApprovalOld(UserId	_usrId, CPLDevCapexRequestNo _capexReqNo)
  {
    str             emailBody = '';
    SysEmailTable   sysEmailTable;
    CPLDevCapexHeader cplCapexHeader;
    SysEmailParameters  sysEmailParameters = SysEmailParameters::find();
    SysUserInfo        userInfo = SysUserInfo::find(_usrId, false);
    var messageBuilder = new SysMailerMessageBuilder();

    select firstonly sysEmailTable;

    select firstonly cplCapexHeader where cplCapexHeader.CapexRequestNo == _capexReqNo;

    if(userInfo.Email)
    {
      messageBuilder.setFrom(sysEmailParameters.SMTPUserName);
      messageBuilder.addTo(userInfo.Email);
      //messageBuilder.addCc("cc@example.com");
      //messageBuilder.addBcc("bcc@example.com");

      emailBody = '<html>';
      emailBody = '<head><style>table, th, td{border: 1px solid black;border-collapse: collapse;}</style></head>';
      emailBody = '<html><body>';
      emailBody += '<p1>Hi ' + CPLDevCapexUtility::getUserName(_usrId) + '</p><br>';
      emailBody += 'This is to inform you that your capex request has been approved<br>';
      emailBody += 'Here is a brief summary of capex request:<br><br>';

      emailBody += '<table role="presentation" border="1" cellspacing="0" style="width:100%;"><tr>';
      emailBody += '<th>Capex Request No.</th>';
      emailBody += '<th>Capex/Project Name</th>';
      emailBody += '<th>Priority</th>';
      emailBody += '<th>Currency</th>';
      emailBody += '<th align="right">Total Amount</th>';
      emailBody += '<th align="right">Forecasted Amount</th>';
      emailBody += '<th>Request Date</th>';
      emailBody += '<th>Request Status</th></tr>';


      emailBody += '<tr>';
      emailBody += '<td><a href="' + CPLDevCapexUtility::getCapexURL(_capexReqNo) + '" target="_blank">' + _capexReqNo + '</td>';
      //emailBody += '<td>' + _capexReqNo + '</td>';
      emailBody += '<td>' + cplCapexHeader.CapexProjectName + '</td>';
      emailBody += '<td>' + enum2Str(cplCapexHeader.Priority) + '</td>';
      emailBody += '<td>' + cplCapexHeader.Currency + '</td>';
      emailBody += '<td align="right">' + num2Str(cplCapexHeader.TotalAmount(), 0, 2, DecimalSeparator::Dot, ThousandSeparator::Comma) + '</td>';
      emailBody += '<td align="right">' + num2Str(cplCapexHeader.ForecastedAmount, 0, 2, DecimalSeparator::Dot, ThousandSeparator::Comma) + '</td>';
      emailBody += '<td>' + date2Str(cplCapexHeader.RequestDate,321,DateDay::Digits2,DateSeparator::Hyphen, DateMonth::Digits2,DateSeparator::Hyphen,DateYear::Digits4) + '</td>';
      emailBody += '<td>' + enum2Str(cplCapexHeader.CPLCapexWorkflowStatusEnum) + '</td></tr></table>';

      emailBody += '<br><br>Thanks.<br>';
      emailBody += '</body></html>';


      messageBuilder.setSubject(strFmt("%1 Capex has approved ", _capexReqNo));
      messageBuilder.setBody(emailBody,true);
      SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(messageBuilder.getMessage());
    }

  }

    public static void sendEmailToCreaterForCapexChangeStatus(UserId	_usrId, CPLDevCapexRequestNo _capexReqNo, str csStatus,PurchId _purchid = null)
    //SIT3-104-To add Auto-created Purchase order number in mail-[PavanKini]03March2023 starts here--->
  {
    str                 emailBody = '';
    SysEmailTable       sysEmailTable;
    CPLDevCapexHeader   cplCapexHeader;
    SysEmailParameters  sysEmailParameters = SysEmailParameters::find();
  //  SysUserInfo         userInfo = SysUserInfo::find(_usrId, false);   //Manju Y
    UserInfo userInfo;
    select * from userInfo where userInfo.id==_usrId;
    var messageBuilder = new SysMailerMessageBuilder();

    select firstonly sysEmailTable;

    select firstonly cplCapexHeader where cplCapexHeader.CapexRequestNo == _capexReqNo;

   // if(userInfo.Email)
   if(userInfo.networkAlias)
    {
      messageBuilder.setFrom(sysEmailParameters.SMTPUserName);
     // messageBuilder.addTo(userInfo.Email);
     messageBuilder.addTo(userInfo.networkAlias);//manju y
      //messageBuilder.addCc("cc@example.com");
      //messageBuilder.addBcc("bcc@example.com");

      emailBody = '<html>';
      emailBody = '<head><style>table, th, td{border: 1px solid black;border-collapse: collapse;}</style></head>';
      emailBody = '<html><body>';
      emailBody += '<p1>Hi ' + CPLDevCapexUtility::getUserName(_usrId) + '</p><br>';
      if(csStatus == 'ChangeRequest')
      {
        emailBody += 'This is to inform you that your capex request has Change Request<br>';
      }
      else
      {
        emailBody += strFmt('This is to inform you that your capex request has been %1<br>', csStatus);
      }
      
      emailBody += 'Here is a brief summary of capex request:<br><br>';

      emailBody += '<table role="presentation" border="1" cellspacing="0" style="width:100%;"><tr>';
      emailBody += '<th>Capex Request No.</th>';
      emailBody += '<th>Capex/Project Name</th>';
      emailBody += '<th>Priority</th>';
      emailBody += '<th>Currency</th>';
      emailBody += '<th align="right">Total Amount</th>';
      emailBody += '<th align="right">Forecasted Amount</th>';
      emailBody += '<th>Request Date</th>';
     
     //SIT3-104-To add Auto-created Purchase order number in mail-[PavanKini]03March2023 starts here--->
      if(csStatus =="approved" && _purchid)  //[ManjuY]   added MV validation
      {
        emailBody += '<th>Request Status</th>';
        emailBody += '<th>Purchase Order No</th></tr>';
      }
      else
      {
        emailBody += '<th>Request Status</th></tr>';
      }
      //SIT3-104-To add Auto-created Purchase order number in mail-[PavanKini]03March2023 ends here--->

      emailBody += '<tr>';
      emailBody += '<td><a href="' + CPLDevCapexUtility::getCapexURL(_capexReqNo) + '" target="_blank">' + _capexReqNo + '</td>';
      //emailBody += '<td>' + _capexReqNo + '</td>';
      emailBody += '<td>' + cplCapexHeader.CapexProjectName + '</td>';
      emailBody += '<td>' + enum2Str(cplCapexHeader.Priority) + '</td>';
      emailBody += '<td>' + cplCapexHeader.Currency + '</td>';
      emailBody += '<td align="right">' + num2Str(cplCapexHeader.TotalAmount(), 0, 2, DecimalSeparator::Dot, ThousandSeparator::Comma) + '</td>';
      emailBody += '<td align="right">' + num2Str(cplCapexHeader.ForecastedAmount, 0, 2, DecimalSeparator::Dot, ThousandSeparator::Comma) + '</td>';
      emailBody += '<td>' + date2Str(cplCapexHeader.RequestDate,321,DateDay::Digits2,DateSeparator::Hyphen, DateMonth::Digits2,DateSeparator::Hyphen,DateYear::Digits4) + '</td>';
    
      //SIT3-104-To add Auto-created Purchase order number in mail-[PavanKini]03March2023 starts here-->
      if(csStatus == "approved" && _purchid)    //[ManjuY]   added MV validation
      {
        emailBody += '<td>' + csStatus + '</td>';
        emailBody += '<td>' + _purchid + '</td></tr></table>';
      }
      else
      {
        emailBody += '<td>' + csStatus + '</td></tr></table>';
      }
      //todo
      //SIT3-104-To add Auto-created Purchase order number in mail-[PavanKini]03March2023 ends here--->

      emailBody += '<br><br>Thanks.<br>';
      emailBody += '</body></html>';

      //SIT-106-Capex Approved email for both single and multiple vendor PDF attachment- PavanKini 06-March-2023
      if(csStatus =="approved")
      {
          //------------------------------RptGenerate-----------------------------------------------------

          Filename fileName = _capexReqNo + ".pdf";
          SrsReportRunController              controller = new SrsReportRunController();
          CPLDevCapexSingleVendorContract     dataContract1 = new CPLDevCapexSingleVendorContract();
          SRSPrintDestinationSettings         settings;
          Array                               arrayFiles;
          System.Byte[]                       reportBytes = new System.Byte[0]();
          SRSProxy                            srsProxy;
          SRSReportRunService                 srsReportRunService = new SrsReportRunService();
          Microsoft.Dynamics.AX.Framework.Reporting.Shared.ReportingService.ParameterValue[] parameterValueArray;
          Map                                 reportParametersMap;
          SRSReportExecutionInfo              executionInfo = new SRSReportExecutionInfo();

          if(cplCapexHeader.ForKnownVendor == NoYes::Yes)
          {
            controller.parmReportName(ssrsReportStr(CPLDevCaexSiingleVendorReport, Report));
          }
          else
          {
            controller.parmReportName(ssrsReportStr(CPLDevCaexSiingleVendorReport, CapexMVReport));
          }
          controller.parmShowDialog(false);
          //controller.parmExecutionMode(SysOperationExecutionMode::ScheduledBatch);
          //controller.parmInBatch(true);

          dataContract1 = controller.parmReportContract().parmRdpContract() as CPLDevCapexSingleVendorContract ;
          dataContract1.parmCPLDevCapexRequestNo(_capexReqNo); //_capexReqNo

          controller.parmLoadFromSysLastValue(false);
          // Provide printer settings
          settings = controller.parmReportContract().parmPrintSettings();
          settings.printMediumType(SRSPrintMediumType::File);
          settings.fileName(fileName);
          settings.fileFormat(SRSReportFileFormat::PDF);

          // Below is a part of code responsible for rendering the report
          controller.parmReportContract().parmReportServerConfig(SRSConfiguration::getDefaultServerConfiguration());
          controller.parmReportContract().parmReportExecutionInfo(executionInfo);
 
          srsReportRunService.getReportDataContract(controller.parmreportcontract().parmReportName());
          srsReportRunService.preRunReport(controller.parmreportcontract());
          reportParametersMap = srsReportRunService.createParamMapFromContract(controller.parmReportContract());
          parameterValueArray = SrsReportRunUtil::getParameterValueArray(reportParametersMap);
 
          srsProxy = SRSProxy::constructWithConfiguration(controller.parmReportContract().parmReportServerConfig());
          // Actual rendering to byte array
          reportBytes = srsproxy.renderReportToByteArray(controller.parmreportcontract().parmreportpath(),parameterValueArray,settings.fileFormat(),settings.deviceinfo());
 
          // You can also convert the report Bytes into an xpp BinData object if needed
          container binData;
          Binary binaryData;
          System.IO.MemoryStream mstream = new System.IO.MemoryStream(reportBytes);
          binaryData = Binary::constructFromMemoryStream(mstream);
          if(binaryData)
          {
            binData = binaryData.getContainer();
          }
 
          System.Byte[] binData1;
          System.IO.Stream stream1;
 
          // Turn the Bytes into a stream
          for(int i = 0; i < conLen(binData); i++)
          {
            binData1 = conPeek(binData,i+1);
            stream1 = new System.IO.MemoryStream(binData1);
          }

          messageBuilder.addAttachment(stream1, fileName);

      }

        //-----------------------------RptGenerateEnd----------------------------------------------------
      //SIT-106-Capex Approved email for both single and multiple vendor PDF attachment- PavanKini 06-March-2023
      messageBuilder.setSubject(strFmt("%1 Capex has %2 ", _capexReqNo, csStatus));
      messageBuilder.setBody(emailBody,true);

    
      SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(messageBuilder.getMessage());
    }

  }

    public static void sendEmailToApprovarForCapexApproval(UserId	_usrId, CPLDevCapexRequestNo _capexReqNo, System.IO.Stream _stream = null)
    {
      str                 emailBody = '';
      SysEmailTable       sysEmailTable;
      CPLDevCapexHeader   cplCapexHeader;
      SysEmailParameters  sysEmailParameters = SysEmailParameters::find();
     // SysUserInfo         userInfo = SysUserInfo::find(_usrId, false);
      UserInfo userInfo;
      select * from userInfo where userInfo.id ==_usrId;          //manjuy
      var messageBuilder = new SysMailerMessageBuilder();
      //select firstonly sysEmailTable;
      select firstonly cplCapexHeader where cplCapexHeader.CapexRequestNo == _capexReqNo;
      URL attachmentUrl = CPLDevCapexUtility::getAttachmentURL(cplCapexHeader.RecId, cplCapexHeader.DataAreaId);
      

      changecompany(cplCapexHeader.DataAreaId)
      {
     // if(userInfo.Email)
     if(userInfo.networkAlias)
      {
        messageBuilder.setFrom(sysEmailParameters.SMTPUserName);
        //messageBuilder.addTo(userInfo.Email);
        messageBuilder.addTo(userInfo.networkAlias);  //manjuY
        //messageBuilder.addCc("cc@example.com");
        //messageBuilder.addBcc("bcc@example.com");

        
        emailBody = '<html>';
        emailBody += '<head><style>table, th, td{border: 1px solid black;border-collapse: collapse;}</style></head>';
        emailBody += '<html><body>';
        emailBody += '<p1>Hi ' + CPLDevCapexUtility::getUserName(_usrId) + '</p><br>';  //hcmWorker.name()
        emailBody += CPLDevCapexUtility::getUserName(cplCapexHeader.CreatedBy) + ' has sent you capex request for review and approval.<br><br>';  //hcmWorkerCreator.name()
        emailBody += 'Here is a brief summary of capex request:<br><br>';

        emailBody += '<table role="presentation" border="1" cellspacing="0" style="width:100%;"><tr>';
        emailBody += '<th>Capex Request No.</th>';
        emailBody += '<th>Capex/Project Name</th>';
        emailBody += '<th>Priority</th>';
        emailBody += '<th>Currency</th>';
        emailBody += '<th align="right">Total Amount</th>';
        emailBody += '<th align="right">Forecasted Amount</th>';
        emailBody += '<th>Request Date</th>';
        emailBody += '<th>Request Status</th></tr>';


        emailBody += '<tr>';
        emailBody += '<td><a href="' + CPLDevCapexUtility::getCapexURL(_capexReqNo) + '" target="_blank">' + _capexReqNo + '</td>';
        //emailBody += '<td>' + _capexReqNo + '</td>';
        emailBody += '<td>' + cplCapexHeader.CapexProjectName + '</td>';
        emailBody += '<td>' + enum2Str(cplCapexHeader.Priority) + '</td>';
        emailBody += '<td>' + cplCapexHeader.Currency + '</td>';
        emailBody += '<td align="right">' + num2Str(cplCapexHeader.TotalAmount(), 0, 2, DecimalSeparator::Dot, ThousandSeparator::Comma) + '</td>';
        emailBody += '<td align="right">' + num2Str(cplCapexHeader.ForecastedAmount, 0, 2, DecimalSeparator::Dot, ThousandSeparator::Comma) + '</td>';
        emailBody += '<td>' + date2Str(cplCapexHeader.RequestDate,321,DateDay::Digits2,DateSeparator::Hyphen, DateMonth::Digits2,DateSeparator::Hyphen,DateYear::Digits4) + '</td>';
        
        if(cplCapexHeader.CPLCapexWorkflowStatusEnum == CPLCapexWorkflowStatusEnum::Created || cplCapexHeader.CPLCapexWorkflowStatusEnum == CPLCapexWorkflowStatusEnum::Submitted)
        {
          emailBody += '<td>Submitted</td></tr></table>';
        }
        else
        {
          emailBody += '<td>' + enum2Str(cplCapexHeader.CPLCapexWorkflowStatusEnum) + '</td></tr></table>';
        }
        
        if(attachmentUrl != '')
        {
          emailBody += '<br><br>Please find below attachment url:';
          emailBody += '<br><a href="' + attachmentUrl + '" target="_blank">' + attachmentUrl + '</a>';
        }

        emailBody += '<br><br>Please help with your decision on approval/rejection/on-hold to proceed with the request.';
        emailBody += '<br><br>Thanks.<br>';
        emailBody += '</body></html>';
        //Capex Approval reminder email set Subject Line added by [Manju Y]
        if(cplCapexHeader.ReminderDate == today() && cplCapexHeader.CPLCapexWorkflowStatusEnum==CPLCapexWorkflowStatusEnum::Submitted)
        {
          messageBuilder.setSubject(strFmt("REMINDER: %1 Capex for review and approval ", _capexReqNo));
        }
        else
        {
          messageBuilder.setSubject(strFmt("%1 Capex for review and approval ", _capexReqNo));
        }
        //messageBuilder.setSubject(strFmt("%1 Capex for review and approval ", _capexReqNo));
        messageBuilder.setBody(emailBody,true);


        //------------------------------RptGenerate-----------------------------------------------------

        Filename fileName = _capexReqNo + ".pdf";
        SrsReportRunController              controller = new SrsReportRunController();
        CPLDevCapexSingleVendorContract     dataContract1 = new CPLDevCapexSingleVendorContract();
        SRSPrintDestinationSettings         settings;
        Array                               arrayFiles;
        System.Byte[]                       reportBytes = new System.Byte[0]();
        SRSProxy                            srsProxy;
        SRSReportRunService                 srsReportRunService = new SrsReportRunService();
        Microsoft.Dynamics.AX.Framework.Reporting.Shared.ReportingService.ParameterValue[] parameterValueArray;
        Map                                 reportParametersMap;
        SRSReportExecutionInfo              executionInfo = new SRSReportExecutionInfo();

        if(cplCapexHeader.ForKnownVendor == NoYes::Yes)
        {
          controller.parmReportName(ssrsReportStr(CPLDevCaexSiingleVendorReport, Report));
        }
        else
        {
          controller.parmReportName(ssrsReportStr(CPLDevCaexSiingleVendorReport, CapexMVReport));
        }
        controller.parmShowDialog(false);
        //controller.parmExecutionMode(SysOperationExecutionMode::ScheduledBatch);
        //controller.parmInBatch(true);

        dataContract1 = controller.parmReportContract().parmRdpContract() as CPLDevCapexSingleVendorContract ;
        dataContract1.parmCPLDevCapexRequestNo(_capexReqNo); //_capexReqNo

        controller.parmLoadFromSysLastValue(false);
        // Provide printer settings
        settings = controller.parmReportContract().parmPrintSettings();
        settings.printMediumType(SRSPrintMediumType::File);
        settings.fileName(fileName);
        settings.fileFormat(SRSReportFileFormat::PDF);

        // Below is a part of code responsible for rendering the report
        controller.parmReportContract().parmReportServerConfig(SRSConfiguration::getDefaultServerConfiguration());
        controller.parmReportContract().parmReportExecutionInfo(executionInfo);
 
        srsReportRunService.getReportDataContract(controller.parmreportcontract().parmReportName());
        srsReportRunService.preRunReport(controller.parmreportcontract());
        reportParametersMap = srsReportRunService.createParamMapFromContract(controller.parmReportContract());
        parameterValueArray = SrsReportRunUtil::getParameterValueArray(reportParametersMap);
 
        srsProxy = SRSProxy::constructWithConfiguration(controller.parmReportContract().parmReportServerConfig());
        // Actual rendering to byte array
        reportBytes = srsproxy.renderReportToByteArray(controller.parmreportcontract().parmreportpath(),parameterValueArray,settings.fileFormat(),settings.deviceinfo());
 
        // You can also convert the report Bytes into an xpp BinData object if needed
        container binData;
        Binary binaryData;
        System.IO.MemoryStream mstream = new System.IO.MemoryStream(reportBytes);
        binaryData = Binary::constructFromMemoryStream(mstream);
        if(binaryData)
        {
          binData = binaryData.getContainer();
        }
 
        System.Byte[] binData1;
        System.IO.Stream stream1;
 
        // Turn the Bytes into a stream
        for(int i = 0; i < conLen(binData); i++)
        {
          binData1 = conPeek(binData,i+1);
          stream1 = new System.IO.MemoryStream(binData1);
        }
        //-----------------------------RptGenerateEnd----------------------------------------------------

        messageBuilder.addAttachment(stream1, fileName);

        SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(messageBuilder.getMessage());
      }

    }
    }

    public static void sendEmailToApprovarForCapexWorkflowApproval(CPLDevCapexRequestNo _capexReqNo)
  {
    WorkflowTable           workflowTable;
    WorkflowVersionTable    workflowVersionTable;
    WorkflowElementTable    workflowElementTable;
    WorkflowStepTable       workflowStepTable;
    WorkflowAssignmentTable workflowAssignmentTable;
    System.IO.Stream        streamAttachment;
    container               conUser;
    int                     conPos;

    select workflowAssignmentTable
      join workflowStepTable
      where workflowStepTable.RecId == workflowAssignmentTable.workflowStepTable
      join workflowElementTable
      where workflowElementTable.ElementId == workflowStepTable.ElementId
      join workflowVersionTable
      where workflowVersionTable.ConfigurationId == workflowElementTable.ConfigurationId
      && workflowVersionTable.Enabled == NoYes::Yes
      join workflowTable
      where workflowTable.RecId == workflowVersionTable.workflowTable
      && workflowTable.DocumentTableName == "CPLDevCapexHeader"
      && workflowTable.TemplateName == 'CPLDevCapexWFType';
    if(workflowAssignmentTable.UserValue != '')
    {
      conUser = str2con(workflowAssignmentTable.UserValue, ";");
      if(conLen(conUser) > 0)
      {
        for(conPos=1; conPos <= conlen(conUser); conPos++)
        {
            CPLDevCapexUtility::sendEmailToApprovarForCapexApproval(conPeek(conUser, conPos),_capexReqNo, streamAttachment);
        }
      } 
    }
    else if(workflowAssignmentTable.ParticipantTokenName !='')  //added by Manju Y [fetch users from group]
    {
      UserGroupList groupList;
      while select groupList where groupList.groupId==workflowAssignmentTable.ParticipantTokenName
      {
          CPLDevCapexUtility::sendEmailToApprovarForCapexApproval(groupList.userId, _capexReqNo, streamAttachment);
      }
    }
  }

    private static Name getUserName(UserId _userId)
  {
    UserInfo usrInfoLoc;
    select firstonly1 usrInfoLoc where usrInfoLoc.id == _userId;
    return usrInfoLoc.name;
  }

    public static str getCapexURL(CPLDevCapexRequestNo _requestNo)
  {

    try
    {
      // gets the generator instance
      var generator     = new Microsoft.Dynamics.AX.Framework.Utilities.UrlHelper.UrlGenerator();
      //var currentHost   = new System.Uri(UrlUtility::getUrl());

      IApplicationEnvironment env = EnvironmentFactory::GetApplicationEnvironment();
      str currentUrl = env.Infrastructure.HostUrl;
      System.Uri currentHost = new System.Uri(currentUrl);

      generator.HostUrl = currentHost.GetLeftPart(System.UriPartial::Authority);
      generator.Company = curext();
      generator.MenuItemName = 'CPLDevCapexSummMI';
      generator.Partition = getCurrentPartition();

      // repeat this segment for each datasource to filter
      var requestQueryParameterCollection = generator.RequestQueryParameterCollection;
      requestQueryParameterCollection.AddRequestQueryParameter('CPLDevCapexHeader', 'CapexRequestNo', _requestNo);

      //System.Uri retURI = generator.GenerateFullUrl().AbsoluteUri;

      // to get the encoded URI, use the following code
      return generator.GenerateFullUrl().AbsoluteUri;
    }
    catch(Exception::CLRError)
    {
      System.Exception ex = CLRInterop::getLastException();
      info(ex.Message);
      return '';
    }

  }

    public static URL getAttachmentURL(RefRecId _recId, DataAreaId _dataArea)
  {
    DocuRef     docuRef;
    DocuType    docuType;

    select  docuRef
          order by docuRef.createddatetime desc
          where docuRef.RefTableId == tableName2Id('CPLDevCapexHeader') //_common.TableId
          && docuRef.RefRecId      == _recId //_common.RecId
          && docuRef.RefCompanyId  == _dataArea //_common.DataAreaId
      exists join DocuType
          where DocuType.TypeId    == docuRef.TypeId
          && DocuType.TypeGroup    == DocuTypeGroup::URL;

    return docuRef.url();
  }

}