Tuesday, March 20, 2018

X++ code to upload/Save a file in Azure location in D365


using Microsoft.Dynamics.ApplicationPlatform.Services.Instrumentation;
using Microsoft.DynamicsOnline.Infrastructure.Components.SharedServiceUnitStorage;
using Microsoft.Dynamics.AX.Framework.FileManagement;
public class AzureStorage
{
str docfiletype;
    Microsoft.Dynamics.AX.Framework.FileManagement.IDocumentStorageProvider storageProvider; 
    public void uploadfile(Filename _Filename,Filename _filePath)
    {
        guid fileGuid = newGuid();
        str fileId;
        str downloadUrl;
        System.IO.Stream    _stream;
        str fileNameAZ = strFmt('%1/%2', fileId, _fileName);//filename = Filename.Xlsx
        fileId = guid2str(fileGuid);
        _stream = File::UseFileFromURL(_filePath);//filepath = C://Temp//Filename.Xlsx
        var blobInfo = new SharedServiceUnitStorageData();
        blobInfo.Id = fileId;
        blobInfo.Category = "StorageFolder";//Folder name
        blobInfo.Name = fileNameAZ;
        blobInfo.Accessibility = Accessibility::Private;
        blobInfo.Retention = Retention::Permanent;       
        if (_stream.CanSeek)
        {
            _stream.Seek(0, System.IO.SeekOrigin::Begin);
        }
        var blobStorageService = new SharedServiceUnitStorage(SharedServiceUnitStorage::GetDefaultStorageContext());
        blobStorageService.UploadData(blobInfo, _stream);
        var uploadedBlobInfo = blobStorageService.GetData(fileId, "StorageFolder", BlobUrlPermission::Read, System.TimeSpan::FromDays(30));
//Time span for keeping the file at azure location.
        downloadUrl =uploadedBlobInfo.BlobLink;
    }
}

X++ code to create attachment of a file in D365


using Microsoft.Dynamics.ApplicationPlatform.Services.Instrumentation;
using Microsoft.DynamicsOnline.Infrastructure.Components.SharedServiceUnitStorage;
using Microsoft.Dynamics.AX.Framework.FileManagement;
public class AttachFile
{
str docfiletype;
Microsoft.Dynamics.AX.Framework.FileManagement.IDocumentStorageProvider storageProvider;
    public  boolean createAttachment(TableId tableId, RefRecId _refFieldId,Filename _Filename,Filename _filePath)
    {
        boolean                     ret = false;
        DocuRef     docuref;
        str downloadUrl;
        System.IO.Stream    _stream;
        _stream = File::UseFileFromURL(_filePath);
        str _contentType = System.Web.MimeMapping::GetMimeMapping(_filePath);
        DocuType fileType = DocuType::find(DocuType::typeFile());
        storageProvider = Docu::GetStorageProvider(fileType, true, curUserId());

        if(storageProvider)
        {
            str uniqueFileName = storageProvider.GenerateUniqueName(_Filename);
            str fileNameWithoutExtension = System.IO.Path::GetFileNameWithoutExtension(_filePath);
            str fileExtension = Docu::GetFileExtension(uniqueFileName);
  
            if(Docu::validateExtension(fileExtension))
            {
                guid FileId = newGuid();
                DocuValue docValue;
                docValue.Name = fileNameWithoutExtension;
                docValue.FileId = FileId;
                docValue.FileName = uniqueFileName;
                docValue.FileType = fileExtension;
                docValue.OriginalFileName = _Filename;
                docValue.Type = DocuValueType::Others;
                docValue.StorageProviderId = storageProvider.ProviderId;
                DocumentLocation 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();
                        //info(docValue.AccessInformation);
                    }

                    if (docValue.validateWrite())
                    {
                       
                        docValue.insert();
                        DocuUploadResult DocuUploadResult =  new DocuUploadResult(_fileName, _contentType, false, "", newGuid());
                        DocuUploadResult.fileId(FileId);
                        docuref = DocuUploadResult.createDocuRef(tableId,_refFieldId,DocuType::typeFile());
                        if(docuref)
                        {
                            ret =  true;
                        }
                        else
                        {
                            ret =  false;
                        }


                    }
                }
            }

        }

X++ code to read the attached file in D365


using Microsoft.Dynamics.ApplicationPlatform.Services.Instrumentation;
using Microsoft.DynamicsOnline.Infrastructure.Components.SharedServiceUnitStorage;
using Microsoft.Dynamics.AX.Framework.FileManagement;
public class ReadAzureBlobStorage
{
    str docfiletype;
    Microsoft.Dynamics.AX.Framework.FileManagement.IDocumentStorageProvider storageProvider;
    Public void readfromAzureBlob(DocuRef _docuRef)
    {
        AsciiStreamIo file;
        container record;
        str downloadUrl;
        if (_docuRef.isValueAttached())
        {
            var docuValueloc = _docuRef.docuValue();
            downloadUrl = docuValueloc.Path;

            if (!downloadUrl || docuValueloc.Type == DocuValueType::Others)
            {
                str accessToken = DocumentManagement::createAccessToken(_docuRef);
                downloadUrl = Microsoft.Dynamics.AX.Framework.FileManagement.URLBuilderUtilities::GetDownloadUrl(docuValueloc.FileId, accessToken);
            }
            var docContents = storageProvider.GetFile(docuValueloc.createLocation());
            file = AsciiStreamIo::constructForRead(docContents.Content);//File::UseFileFromURL(downloadUrl));
         
        }
       
        if (file)
        {
            if (file.status())
            {
                throw error("@SYS52680");
            }
            file.inFieldDelimiter(',');
            file.inRecordDelimiter('\r\n');
           
        }
      
        while (!file.status())
        {
            record = file.read();
          
            if (conLen(record))
            {
                info(strFmt("%1 - %2",conPeek(record,1),conPeek(record,2)));
            }
        }

    }
}

Monday, March 19, 2018

X++ code to send mail code in D365

System.IO.Stream workbookStream = new System.IO.MemoryStream(); 
SysMailerSMTP   mailer = new SysMailerSMTP();
SysMailerMessageBuilder builder = new SysMailerMessageBuilder();
SysEmailParameters parameters = SysEmailParameters::find();
FileIOPermission fileIOPermission;
InteropPermission interopPerm;
Notes content;          


Filepath = c:/temp/"filename"
System.IO.Stream filestream = File::UseFileFromURL(Filepath );
   
builder.setFrom(SysEmailParameters::find().SMTPUserName);
builder.addTo("Test@test.com");
builder.addAttachment(filestream,"Bookings.csv");
builder.setSubject("Ax_Daily Shipment report");
builder.setbody(content );
content ="";
content = content + strfmt("\n<p dir=ltr align=left>Hello, </p> ");
content = content + strfmt("\n<p dir=ltr align=left>XXXXXXX : %1 </p> ","");
content = content + strfmt("\n<p dir=ltr align=left>YYYYYY: %1 </p> ", "");
content =  content + strfmt('\n<p dir=ltr align=left></p>');
content =  content + strfmt('\n<p dir=ltr align=left></p>');
// builder.setBody("Please take a look at the attachment having shipping date changed");
SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(builder.getMessage());

Export to csv file in D365

fileUploadTemporaryStorageResult result;
AsciiStreamIo filecreate;
System.IO.StreamWriter StreamWriter;
Filename    localfilename , pathname;
System.IO.Stream stream;
TransDate           fromDate;
TransDate           toDate;
FilePath        pathfile;
FilenameSave path;
CommaStreamIo io;
Container Con;
FileIOPermission fileIOPermission;
InteropPermission interopPerm;
str bookingdetails;
;
super();
interopPerm = new InteropPermission(InteropKind::ClrInterop);
interopPerm.assert();
path = "Folder path" +"xxxx.csv";
fileIOPermission = new FileIOPermission(path, "r");
fileIOPermission.assert();
filecreate = AsciiStreamIo::constructForWrite();
con = conins(con,1,"SO Date");
con = conins(con,2,"Order Type");
con = conins(con,3,"Order Status");
con = conins(con,4,"SO Number");
con = conins(con,5,"Bill To");
bookingdetails = con2Str(con,",");
filecreate.write(bookingdetails);
filecreate.Dispose();
CodeAccessPermission::revertAssert();
this.Sendmail();
System.IO.File::Delete(path);

Export to Excel in D365

#AviFiles
SysOperationProgress progress1 = new SysOperationProgress();
int             row=1;
int             startrow;
int             col;
COM                 Crange;
COM                 CBorders;
COM                 CBorder;
;
DocuFileSaveResult saveResult = DocuFileSave::promptForSaveLocation("@ApplicationPlatform:OfficeDefaultWorkbookFileName", "xlsx", null, this.caption());
System.IO.Stream workbookStream = new System.IO.MemoryStream();  
System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
saveResult.parmOpenParameters('web=1');
saveResult.parmOpenInNewWindow(false);
using (var package = new OfficeOpenXml.ExcelPackage(memoryStream))
{
     var sheet = package.get_Workbook().get_Worksheets();
     var worksheet = sheet.Add("First sheet");
     var cells = worksheet.get_Cells();
     OfficeOpenXml.Style.ExcelStyle style = cells.get_Item(row,1).get_style();
     OfficeOpenXml.Style.ExcelFont font = style.Font;
     OfficeOpenXml.Style.ExcelColor color = font.Color;
 cell = Cells.get_item(row,2);cell.set_Value("Entry Date");
            cellStyle = Cells.get_item(row, 2).get_style();
            style = cells.style;font  = style.font;color = font.color;
            color.SetColor(System.Drawing.Color::FromArgb(190,0,0));
     font.Size = 20;
     row++;
     Col = 1;
     cell = Cells.get_item(row,col);cell.set_Value(date2str(salesline.dlvdate,213,2,4,2,4,2));//j:10 line 1
     col++;
     package.save();
}
memoryStream.Seek(0, System.IO.SeekOrigin::Begin);
DocuFileSave::processSaveResult(memoryStream, saveResult);

Friday, March 16, 2018

Delete a model in Dynamics 365



1.    Model belongs to its own package 
(For example: An extension package with no other models in the package):
a.      Stop the following services: The AOS web service and the Batch Management Service
b.     Delete the package folder C:\AOSService\PackagesLocalDirectory\<your model>
c.      Restart the services from step 1
d.     If Visual Studio is running, refresh your models (Visual Studio > Dynamics 365 > Model management > Refresh models)
e.      In Visual Studio, perform a full database synchronization (Visual Studio > Dynamics 365 > Synchronize database...)

2.    Model belongs to a package with multiple models 
(For example, <your model> overlays Application Suite):
a.      Stop the following services: The AOS web service and the Batch Management Service
b.     Delete the model folder C:\AOSService\PackagesLocalDirectory<PackageName>\<your model> (In this example PackageName=ApplicationSuite)
c.      Restart the services from step 1
d.     In Visual Studio, refresh your models (Visual Studio > Dynamics 365 > Model management > Refresh models)
e.      In Visual Studio, build the package that the deleted models belonged to (Visual Studio > Dynamics 365 > Build models...)
f.       In Visual Studio, perform a full database synchronization (Visual Studio > Dynamics 365 > Synchronize database...)

Disable non AD user in AX


    xAxaptaUserManager axUsrMgr;
    xAxaptaUserDetails axUsrDet;
    UserInfo userInfo;
    UserInfo userInfoUpdate;
    str userID;
    str domainName;
    str userSid;
    userAccountType accountType;  
    ;
    axUsrMgr = new xAxaptaUserManager();
    while select userInfo where userInfo.enable == true
    {
        userID = userInfo.networkAlias;
        domainName = userInfo.networkDomain;
        accountType = userInfo.accountType;
        try
        {
            axUsrDet = axUsrMgr.getSIDFromName(userID, domainName, accountType);
        }
        catch(Exception::Error)
        {
           ttsBegin;
            select forUpdate userInfoUpdate
                where userInfoUpdate.id == userInfo.id;  
            userInfoUpdate.enable = false;
            userInfoUpdate.doUpdate();
            ttsCommit;  
        }
    }

Error on DAX 365 VM Admin provisioning tool can't stop DynamicsAXBatch service


Admin User Provisioning Tool 

Error: can’t stop DynamicsAxBatch.

Solution 1:
restart IIS through cmd prompt

Or 
Solution 2:
->Go to the Services,
-> Find service with the name: Microsoft Dynamics 365 Unified Operations: Batch Management Service
-> Stop it.
-> Now try to register account with the admin provisioning tool

Kill services through CMD PROMPT

-> Click the Start menu
-> Click Run or in the search bar type services.msc
-> Press Enter
-> Look for the service and check the Properties and identify its service name.
-> open a command prompt. Type: sc queryex [servicename].
-> Press Enter
-> Identify the PID
-> Incommand prompt type: taskkill /f /pid [pid number]
-> Press Enter

Send mail in D365

            System.IO.Stream workbookStream = new System.IO.MemoryStream();
            SysMailerSMTP   mailer = new SysMailerSMTP();
            SysMailerMessageBuilder builder = new SysMailerMessageBuilder();
            SysEmailParameters parameters = SysEmailParameters::find();
            Notes content;
             ;
       
            if (parameters.SMTPRelayServerName)
            {
                mailer.SMTPRelayServer(parameters.SMTPRelayServerName,
                               parameters.SMTPPortNumber,
                               parameters.SMTPUserName,
                               SysEmailParameters::password(),
                               parameters.SMTPUseNTLM);
            }
            else
            {
                    warning("@ApplicationFoundation:EmailProviderSMTPServerNotFound");
            }
            content ="";
            content = content + strfmt("\n<p dir=ltr align=left>Hello, </p> ");
            content = content + strfmt("\n<p dir=ltr align=left>XXXXXXX : %1 </p> ","");
            content = content + strfmt("\n<p dir=ltr align=left>YYYYYY: %1 </p> ", "");
            content =  content + strfmt('\n<p dir=ltr align=left></p>');
            content =  content + strfmt('\n<p dir=ltr align=left></p>');
         
            builder.setFrom(SysEmailParameters::find().SMTPUserName);
            builder.addTo("test@test.com");
            //builder.addAttachment(workbookStream,path);
            builder.setSubject(strfmt("AAAA" , ""));
            builder.setBody(content);
            SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(builder.getMessage());

Tuesday, March 13, 2018

Creating work order through code


SalesLine                       salesLineLocal;
    InventMovement                  inventMovement;
    WMSOrder                        wmsOrder;
    WMSOrderCreate                  orderCreate;
    WMSOrderTrans                   wmsOrderTrans;
    SalesTable                      salesTableLocal;
    WMSShipment                     wmsShipment;
    WMSPickingRoute                 wmsPickingRoute;
    WMSPickingRouteLink          wmsPickingRouteLink;
 
    salesTableLocal = SalesTable::find('SO-101328');
    wmsShipment.clear();
    wmsPickingRoute.clear();
    wmsShipment.initTypeOrderPick();
    wmsShipment.insert();
    wmsPickingRoute.initTypeOrderPick(wmsShipment, wmsExpeditionStatus::Activated,wmsPickRequestTable::construct(salesTableLocal), '', true);
    wmsPickingRoute.ActivationDateTime = DateTimeUtil::utcNow();
    wmsPickingRoute.insert();
    wmsPickingRouteLink.initFromSalesTable(salesTableLocal);
    wmsPickingRouteLink.initFromWMSPickingRoute(wmsPickingRoute);
    wmsPickingRouteLink.insert();

    // Creating records for each salesline

    while select salesLineLocal where salesLineLocal.SalesId == salesTableLocal.SalesId
    {
        // Inventory Movement object is required to create new           SalesPickingList lines
        inventMovement = InventMovement::construct(salesLineLocal);
        orderCreate = WMSOrderCreate::newMovement(inventMovement, 3);
        orderCreate.parmMustBeWMSOrderControlled(true);
        orderCreate.parmQty(3);
        orderCreate.parmRecalculateMaxQtyForValidation(false);
        orderCreate.parmMaxCWQty(3);
        orderCreate.parmMaxQty(3);
        orderCreate.run();
        wmsOrder = orderCreate.parmWMSOrder();
        wmsOrder.updateShipment(wmsShipment, 3, wmsPickingRoute.PickingRouteID, false);
        // Updating status to activated
        while select forupdate wmsOrderTrans
            where wmsOrderTrans.inventTransId ==  salesLineLocal.inventTransId
               && wmsOrderTrans.expeditionStatus == WMSExpeditionStatus::Registered
        {
            ttsBegin;
            wmsOrderTrans.expeditionStatus = WMSExpeditionStatus::Activated;
            wmsOrderTrans.update();
            ttsCommit;

        }

    }

Movement journal picking list post with qty spliting for updating serial number


    Inventtrans                         inventTrans,inventTransCopy,inventTransLocal,inventTransUpdate;
    InventTransOrigin                   inventTransOrigin;
    inventjournaltrans                  inventjournaltrans;
    EcoResProductDimensionGroupProduct  erpdgp;
    EcoResProductDimensionGroup         erpdg;
    int                                 rowCount,i;
    TmpInventTransWMS                   tmpInventTransWMS;
    InventMovement                      InventMovement;
    InventTransOrigin                   InventTransOriginLoc;
    inventTransWMS_Pick                 inventTransWMS_Pick;
    Query                               inventTransQuery;
    QueryBuildDataSource                QueryBuildDataSource;
    InventTable                         inventtable;

    System.String                       netString = "Net string.";
    System.Exception                    netExcepn;

    while select inventjournaltrans where inventjournaltrans.JournalId == "00434"
    {
        erpdgp=EcoResProductDimensionGroupProduct::findByProduct(Inventtable::find(inventjournaltrans.ItemID).Product);
     
        if ( erpdg.Name == "SN" )
        {

            inventTransOrigin =     InventTransOrigin::findByInventTransId(inventjournaltrans.InventTransId, false);
            inventTrans = InventTrans::findByInventTransOrigin(inventTransOrigin.RecId, false);
            rowCount = real2int(abs(inventTrans.Qty));
            for (i = 1; i < rowCount; i++)
            {
                inventTrans = InventTrans::findByInventTransOrigin(inventTransOrigin.RecId, false);
                inventTrans.updateSplit(-1);
            }
        }
        else
            continue;

    }
    inventjournaltrans.clear();
    while select inventjournaltrans where inventjournaltrans.JournalId == "00434"
    {
        select inventTransOriginloc where inventTransOriginloc.InventTransId == inventjournaltrans.InventTransId;
        // start loop on <inventTrans> to get each item line
        while select inventTransUpdate where inventTransUpdate.InventTransOrigin == inventTransOriginloc.RecId
        {
            inventTransQuery                = new Query();
            QueryBuildDataSource            = inventTransQuery.addDataSource(tableNum(InventTrans));
            InventTransOrigin               = InventTransorigin::findByInventTransId(inventTransOriginloc.InventTransId);
            QueryBuildDataSource.addRange(fieldNum(InventTrans,RecId)).value(int642str(inventTransUpdate.recid));
            delete_from tmpInventTransWMS;
            tmpInventTransWMS.clear();
            inventTransWMS_Pick             = InventTransWMS_Pick::newStandard(tmpInventTransWMS,inventTransQuery);
            tmpInventTransWMS.initFromInventTrans(inventTransUpdate);
            tmpInventTransWMS.initFromInventTransOrigin(InventTransOriginloc);
            tmpInventTransWMS.InventQty     = 1;//inventTransUpdate.Qty;
            //tmpInventTransWMS.InventDimId   = _InventDimId;
            inventTransWMS_Pick.writeTmpInventTransWMS(tmpInventTransWMS);
            inventTransWMS_Pick.updateInvent();
        }
    }