Tuesday, January 16, 2024

Generate CSV file and send as an attachment using X++

class UpdateEndOfLifeOnItemsService_Custom extends SysOperationServiceBase
{
    public void processOperation(UpdateEndOfLifeOnItemsContract_Custom _contract)
    {
        Query               orderQuery;
        QueryRun            queryRun;
    
        boolean             closeWSLItem;
        Str                 users;

        orderQuery      = _contract.getQuery();
        closeWSLItem    = _contract.parmCloseWSLItem();
        users           = _contract.parmUsers();

        queryRun        = new QueryRun(orderQuery);

        container userCon = str2con(users, SysAppUtilities_Custom::semiColon);

        System.Byte[]   byteArray;
        CommaStreamIo   io = CommaStreamIo::constructForWrite();
        io.outFieldDelimiter(SysAppUtilities_Custom::comma);
        io.outRecordDelimiter('\r\n');

        io.writeExp(['@MCR23630', '@SYS319915' , '@Custom:PLCStat']);

        Filename fileName = strFmt('@Custom:EOLUpdateFileName', DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()));

        fileName = fileName + ".csv";

        while (queryRun.Next())
        {
            ItemId      itemId = strMin();
            InventTable inventTableMaster = queryRun.get(tableNum(InventTable));

            itemId = inventTableMaster.ItemId;
           
            EcoResProductLifecycleStateId productLifecycleStateId;

            if (!this.OnhandQty(inventTableMaster) == 0)
            {
                PurchLine   purchLine;
                PurchTable  purchTable;

                select firstonly purchLine
                    where purchLine.ItemId == itemId
                        exists join purchTable
                            where purchTable.PurchId == purchLine.PurchId
                            && purchTable.PurchStatus == PurchStatus::Backorder;

                if (!purchLine)
                {
                    if (closeWSLItem)
                    {
                        productLifecycleStateId = EcoResProductLifecycleState::find("40_EOL_int").StateId;

                        SalesLine           salesLine;
                        InventTrans         inventTrans;
                        InventTransOrigin   inventTransOrigin;

                        select firstonly inventTrans
                            where inventTrans.ItemId == itemId
                            && inventTrans.StatusIssue == StatusIssue::ReservPhysical
                                join inventTransOrigin
                                    where inventTransOrigin.RecId == inventTrans.InventTransOrigin
                                    exists join salesLine
                                        where inventTransOrigin.InventTransId == salesLine.InventTransId;

                        if (!inventTrans)
                        {
                            UpdateEndOfLifeOnItemsService_Custom::updateSalesStopped(itemId);
                        }

                        UpdateEndOfLifeOnItemsService_Custom::updatePLCStatus(itemId, productLifecycleStateId);
                    }
                }

                io.writeExp([itemId, inventTableMaster.itemName(), productLifecycleStateId]);
            }
        }

        System.IO.Stream stream = iO.getStream();
        stream.Position = 0;

        System.IO.StreamReader reader = new System.IO.StreamReader(stream);
        str csv = reader.ReadToEnd();

        System.Text.Encoding encoding = System.Text.Encoding::get_UTF8();

        byteArray = encoding.GetBytes(csv);
        using(System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(byteArray))
        {
            this.sendEmailNotification(userCon, memoryStream, fileName);
        }

        info("@SYS9265");
    }

    public Qty OnhandQty(InventTable _inventtable)
    {
        Qty     availPhysical;
        CompanyInfo companyInfo;
        ItemId  item = _inventtable.ItemId;
        
        select firstonly companyInfo
            where companyInfo.IsMasterCompany_Custom ==  NoYes::Yes;

        changecompany(companyInfo.DataArea)
        {
            InventDim           inventDimLoc;
            InventDimParm       inventDimParm;
            InventTable         inventTableMaster = InventTable::find(item);
            InventLocationId    inventLocationId = inventTableMaster.InventItemSalesSetup().inventDimDefault().InventLocationId;
            InventLocation      inventLocation = InventLocation::find(inventLocationId);

            if (inventLocationId)
            {
                inventDimLoc.InventLocationId   = inventLocationId;
                inventDimLoc.InventSiteId       = inventLocation.InventSiteId;
                inventDimLoc                    =  InventDim::findOrCreate(inventDimLoc);

                inventDimParm.initFromInventDim(InventDim::find(inventDimLoc.inventDimId));

                return InventSum::findSum(item, inventDimLoc, inventDimParm).AvailPhysical;
            }
        }

        return 0;
    }

    /// <summary>
    /// Send emails notification about the base cost update to user/user group.
    /// </summary>
    /// <param name = "_notifyCon">
    /// Container which holds users to whom email notification to be sent.
    /// </param>
    /// <param name = "_messageBody">
    /// Contains information about the method of calculation to be send to user in email.
    /// </param>
    /// <returns>
    /// boolean true, if sends the notification of users successfully.
    /// </returns>
    public boolean sendEmailNotification(container _notifyCon, System.IO.MemoryStream _memoryStream, Filename _fileName)
    {
        UserInfo        sysUser;
        boolean         messageSent     = false;
        str             messageBody; 
        str             subject = strFmt('@Custom:EOLUpdateFileName', DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()));

        for (int i = 1; i <= conLen(_notifyCon); i++)
        {
            str notifyEmailsStr = conPeek(_notifyCon, i);

            select firstonly RecId, NetworkAlias from sysUser where sysUser.Id == notifyEmailsStr;
            
            if (sysUser.RecId && sysUser.NetworkAlias)
            {
                UpdateEndOfLifeOnItemsService_Custom::sendEmail(_fileName, subject, messageBody, _memoryStream, sysUser.NetworkAlias);

                messageSent = true;
            }
        }

        return messageSent;
    }

    public static void sendEmail(str _fileName,
                                 str _subject,
                                 str _body,
                                 System.IO.MemoryStream _memoryStream,
                                 Email _toEmail)
    {
        SysMailerMessageBuilder mailer = new SysMailerMessageBuilder();
        try
        {
            mailer.setSubject(_subject);

            mailer.setBody(_body);

            mailer.addTo(_toEmail);

            mailer.addAttachment(_memoryStream, _fileName);

            SysMailerFactory::sendNonInteractive(mailer.getMessage());

            Info("@SYS58551");
        }
        catch (Exception::CLRError)
        {
            System.Exception ex = ClrInterop::getLastException();
            if (ex != null)
            {
                ex = ex.get_InnerException();
                if (ex != null)
                {
                    error(ex.ToString());
                }
            }
        }
        catch (Exception::Error)
        {
            Error("@CustomASCS:ErrorOccurredFailedSendEmail");
        }
    }

    public static void updatePLCStatus(ItemId _itemId, EcoResProductLifecycleStateId _productLifecycleStateId)
    {
        InventTable inventTable;

        inventTable.skipDatabaseLog(true);
        inventTable.skipDataMethods(true);
        inventTable.skipBusinessEvents(true);
        inventTable.skipAosValidation(true);
        inventTable.skipEvents(true);

        update_recordset crosscompany inventTable
            setting ProductLifecycleStateId = _productLifecycleStateId
            where inventTable.ItemId == _itemId;
    }

    public static void updateSalesStopped(ItemId _itemId)
    {
        InventItemSalesSetup inventItemSalesSetup;

        inventItemSalesSetup.skipDatabaseLog(true);
        inventItemSalesSetup.skipDataMethods(true);
        inventItemSalesSetup.skipBusinessEvents(true);
        inventItemSalesSetup.skipAosValidation(true);
        inventItemSalesSetup.skipEvents(true);

        update_recordset crosscompany inventItemSalesSetup
            setting Stopped = true
            where inventItemSalesSetup.ItemId == _itemId
            && inventItemSalesSetup.InventDimId == InventDim::inventDimIdBlank()
            && inventItemSalesSetup.DataAreaId != SysAppUtilities_Custom::companyDSSE;
    }

}

No comments:

Post a Comment

Table browser URL in D365FO

Critical Thinking icon icon by Icons8