Custom service with mutli line Create a work order with multi line

 To day we have a requirement to create a API (Custom Service) that helps to create a multi-line and accept the parameter  for that below are the approcess we have taken we have condiser the list also 

1) create a  header contract class

2) Create a line contract class

3) create a line response class

4) Create a service class

5) Create a response class 

6) test class to test the custom service 


====================================================================


1) Create a header class


/// <summary>

/// Data contract for Related Work order header

/// </summary>

[DataContract]

Final class IHSRelatedWorkOrderHeaderContract

{

    EntAssetWorkOrderID     workOrderID;

    EntAssetWorkOrderTypeID workOrderType;

    Description             workOrderDescription;

    EntAssetServiceLevel    workOrderServiceLevel;

    EntAssetExpectedStart   workOrderExpectedStart;

    DataAreaId              dataAreaId;


    List    workorderLineList = new List(Types::Class);


    /// <summary>

    /// Parent workorder Id

    /// </summary>

    /// <param name = "_workOrderID">Parent work order ID</param>

    /// <returns></returns>

    [DataMember('ParentWorkorder')]

    public EntAssetWorkOrderID parmParentWorkOrderID(EntAssetWorkOrderID _workOrderID = workOrderID)

    {

        workOrderID = _workOrderID;

        return workOrderID;

    }


    /// <summary>

    /// header work order type

    /// </summary>

    /// <param name = "_workOrderType">New  work order Type</param>

    /// <returns></returns>

    [DataMember('WorkorderType')]

    public EntAssetWorkOrderTypeID parmWorkorderType(EntAssetWorkOrderTypeID _workOrderType = workOrderType)

    {

        workOrderType = _workOrderType;

        return workOrderType;

    }


    /// <summary>

    /// New  workorder Description

    /// </summary>

    /// <param name = "_workOrderDescription">New  work order Description</param>

    /// <returns></returns>

    [DataMember('Description')]

    public Description parmDescription(Description _workOrderDescription = workOrderDescription)

    {

        workOrderDescription = _workOrderDescription;

        return workOrderDescription;

    }


    /// <summary>

    /// New  workorder Service Level

    /// </summary>

    /// <param name = "_workOrderServiceLevel">New  work order Service Level</param>

    /// <returns></returns>

    [DataMember('ServiceLevel')]

    public EntAssetServiceLevel parmServiceLevel(EntAssetServiceLevel _workOrderServiceLevel = workOrderServiceLevel)

    {

        workOrderServiceLevel = _workOrderServiceLevel;

        return workOrderServiceLevel;

    }


    /// <summary>

    /// New  workorder Expected Start

    /// </summary>

    /// <param name = "_workOrderExpectedStart">New  work order Expected Start</param>

    /// <returns></returns>

    [DataMember('ExpectedStart')]

    public EntAssetExpectedStart parmExpectedStart(EntAssetExpectedStart _workOrderExpectedStart = workOrderExpectedStart)

    {

        workOrderExpectedStart = _workOrderExpectedStart;

        return workOrderExpectedStart;

    }


    /// <summary>

    /// Get/set list of  workorder lines

    /// </summary>

    /// <param name = "_workorderLineList">Lines list</param>

    /// <returns></returns>

        [DataMember('workorderLinesList'),

        AifCollectionType('_workorderLineList', Types::Class, classStr(IHSRelatedWorkOrderLineContract)),

        AifCollectionType('return', Types::Class, classStr(IHSRelatedWorkOrderLineContract))]

    public List parmWorkOrderLines(List _workorderLineList = workorderLineList)

    {

        workorderLineList = _workorderLineList;

        return workorderLineList;

    }


    [DataMember('Company')]

    public str parmDataAreaId(str _value = dataAreaId)

    {

        if (!prmIsDefault(_value))

        {

            dataAreaId = _value;

        }

        return dataAreaId;

    }


}

================================================================

2) Create a line contract 


/// <summary>

/// Data contract for Workorder Line

/// </summary>

[DataContract]

Final class IHSRelatedWorkOrderLineContract

{

    TradeLineNumber             workOrderLineNumber;

    EntAssetJobTypeID           maintenanceJobType ;

    EntAssetJobVariantID        maintenanceJobTypeVariant;

    EntAssetJobTradeID          maintenanceJobTypeTradeID;

    EntAssetObjectID            objectID;


    [DataMember('WorkOrderLineNumber')]

    public TradeLineNumber parmWorkOrderLineNumber(TradeLineNumber _workOrderLineNumber = workOrderLineNumber)

    {

        workOrderLineNumber = _workOrderLineNumber;

        return workOrderLineNumber;

    }


    [DataMember('MaintenanceJobType')]

    public EntAssetJobTypeID parmMaintenanceJobType(EntAssetJobTypeID _maintenanceJobType = maintenanceJobType)

    {

        maintenanceJobType = _maintenanceJobType;

        return maintenanceJobType;

    }


    [DataMember('MaintenanceJobTypeVariant')]

    public EntAssetJobVariantID parmMaintenanceJobTypeVariant(EntAssetJobVariantID _maintenanceJobTypeVariant = maintenanceJobTypeVariant)

    {

        maintenanceJobTypeVariant = _maintenanceJobTypeVariant;

        return maintenanceJobTypeVariant;

    }


    [DataMember('Trade')]

    public EntAssetJobVariantID parmMaintenanceJobTypeTradeID(EntAssetJobTradeID _maintenanceJobTypeTradeID = maintenanceJobTypeTradeID)

    {

        maintenanceJobTypeTradeID = _maintenanceJobTypeTradeID;

        return maintenanceJobTypeTradeID;

    }


    [DataMember('AssetID')]

    public EntAssetObjectID parmObjectID(EntAssetObjectID _objectID = objectID)

    {

        objectID = _objectID;

        return objectID;

    }


}


====================================================================


3) Create a line response class 


Final class IHSRelatedWorkOrderLineResponseContract

{

    TradeLineNumber workOrderLineNumber;

    str             message;

    str             status;


    

    [DataMember("WorkOrderLineNumber")]

    public TradeLineNumber parmWorkOrderLineNumber(TradeLineNumber _workOrderLineNumber = workOrderLineNumber)

    {

        workOrderLineNumber = _workOrderLineNumber;

        return workOrderLineNumber;

    }


    [DataMember("Status")]

    public str parmStatus(str _status = status)

    {

        status = _status;

        return status;

    }


    [DataMember("Message")]

    public str parmMessage(str _message = message)

    {

        message = _message;

        return message;

    }


    public void setFailed(str _message)

    {

        this.parmStatus("Failed");

        this.parmMessage(_message);

    }


    public void setSuccess(str _message = "success")

    {

        this.parmStatus("Success");

        this.parmMessage(_message);

    }


}


====================================================================


4) Create a service class 


/// <summary>

/// Service class for processing Related work order in one transaction

/// </summary>

Final class IHSRelatedWorkOrderService extends SysOperationServiceBase

{

    EntAssetWorkOrderTable          newWorkOrderTable;

    EntAssetWorkOrderLine           newWorkOrderLine;

    EntAssetWorkOrderTableRelation  workOrderTableRelation;

    EntAssetWorkOrderTable          oldWorkOrderTable;

    str                             errorMessage;


    boolean                     success;


    /// <summary>

    /// Insert the work order lines for the new work order

    /// </summary>

    /// <param name = "_headerContract">workorder  header contract (with lines)</param>

    /// <returns>Response for header and each line</returns>

    public IHSRelatedWorkOrderServiceResponseContract  insertWorkOrderHeaderLines(IHSRelatedWorkOrderHeaderContract  _headerContract)

    {

      

        ListEnumerator                              workOrderLineListEnumerator;

        IHSRelatedWorkOrderLineContract             workOrderLineContract;

        IHSRelatedWorkOrderServiceResponseContract  response = new IHSRelatedWorkOrderServiceResponseContract();

        

        boolean                                     ok = true, isModified;


            changecompany(_headerContract.parmDataAreaId(_headerContract.parmDataAreaId()))

            {

                try

                {

                    if(this.validateWorkOrderheader(_headerContract,response))

                    {

                        ttsBegin;

                        //Create work order header

                        this.createWorkOrderHeader(_headerContract);

                        // Get the work orderline list 

                        workOrderLineListEnumerator  = _headerContract.parmWorkOrderLines().getEnumerator();


                        while(workOrderLineListEnumerator.moveNext())

                        {

                            workOrderLineContract = workOrderLineListEnumerator.current();


                            if(workOrderLineContract)

                            {

                                //Create work order Line

                                this.createWorkOrderLine(workOrderLineContract);

                            }

                        }


                        workOrderLineListEnumerator.reset();

                        success = true;

                        response.parmOutput(response.sucessJsonFormat(IHSRelatedWorkOrderService::GetInfoLogMessages(), newWorkOrderTable.WorkOrderId, oldWorkOrderTable.WorkOrderId));

                        ttscommit;

                    }

                }


                catch(Exception::CLRError)

                {

                    success = false;

                //    errorMessage response.setFailed(AifUtil::getClrErrorMessage()); = 

                    response.parmOutput(response.FailedJsonFormat(response.parmMessage(AifUtil::getClrErrorMessage()), _headerContract.parmParentWorkOrderID()));


                }

                catch(Exception::Error)

                {

                    success = false;

                   // response.setFailed(IHSRelatedWorkOrderService::getErrorFromInfolog());

                   response.parmOutput(response.FailedJsonFormat(response.parmMessage(IHSRelatedWorkOrderService::GetInfoLogMessages()), _headerContract.parmParentWorkOrderID()));

                }


                return response;

            }

        }


        public void createWorkOrderHeader(IHSRelatedWorkOrderHeaderContract _headerContract)

        {

            NumberSeq   numberSeq;

            oldWorkOrderTable = EntAssetWorkOrderTable::find(_headerContract.parmParentWorkOrderID());


            numberSeq = NumberSeq::newGetNum(EntAssetParameters::numRefWorkOrderId(), true);

            newWorkOrderTable.WorkOrderID = numberSeq.num();


            newWorkOrderTable.initValue();

            newWorkOrderTable.initFromWorkOrderType(EntAssetWorkOrderType::findByWorkOrderTypeId(_headerContract.parmWorkorderType()).RecId);


            newWorkOrderTable.ParentWorkOrder = oldWorkOrderTable.RecId;

            newWorkOrderTable.Description     = _headerContract.parmDescription();

            newWorkOrderTable.ServiceLevel    = _headerContract.parmServiceLevel();


            if (newWorkOrderTable.ServiceLevel)

            {

                newWorkOrderTable.initFromServiceLevel(_headerContract.parmServiceLevel());

            }

            

            newWorkOrderTable.IHSCapexVendAccount = oldWorkOrderTable.IHSCapexVendAccount;

            newWorkOrderTable.IsLogistics     = oldWorkOrderTable.IsLogistics;


            // Create Work order header Asset movement tab.

            newWorkOrderTable.IHSTransferOrder  = oldWorkOrderTable.IHSTransferOrder;

            newWorkOrderTable.Department        = oldWorkOrderTable.Department;

            newWorkOrderTable.VendAccount       = oldWorkOrderTable.VendAccount;

            newWorkOrderTable.IHSTransferType   = oldWorkOrderTable.IHSTransferType;

          

            newWorkOrderTable.FromSite          = oldWorkOrderTable.FromSite;

            newWorkOrderTable.ToSite            = oldWorkOrderTable.ToSite;

            newWorkOrderTable.FromLocationId    = oldWorkOrderTable.FromLocationId;

            newWorkOrderTable.ToLocationId      = oldWorkOrderTable.ToLocationId;

            newWorkOrderTable.FromwMSLocationId = oldWorkOrderTable.FromwMSLocationId;

            newWorkOrderTable.TowMSLocationId   = oldWorkOrderTable.TowMSLocationId;


            newWorkOrderTable.IHSReasonName     = oldWorkOrderTable.IHSReasonName;

            newWorkOrderTable.IHSIsCounter      = oldWorkOrderTable.IHSIsCounter;

            newWorkOrderTable.IHSPurposeTypes   = oldWorkOrderTable.IHSPurposeTypes;

            newWorkOrderTable.IHSFromFunctionalLocation = oldWorkOrderTable.IHSFromFunctionalLocation;

            newWorkOrderTable.IHSToFunctionalLocation   = oldWorkOrderTable.IHSToFunctionalLocation;

            newWorkOrderTable.IHSStopGap             = oldWorkOrderTable.IHSStopGap;

            newWorkOrderTable.IHSIsMaterialMovement  = oldWorkOrderTable.IHSIsMaterialMovement;


            newWorkOrderTable.IHSMaterialMovementJobType    = oldWorkOrderTable.IHSMaterialMovementJobType;

            newWorkOrderTable.IHSMaterialMovementJobVariant = oldWorkOrderTable.IHSMaterialMovementJobVariant;

            newWorkOrderTable.IHSIsPerformWork       = oldWorkOrderTable.IHSIsPerformWork;

            newWorkOrderTable.IHSPerformWorkJobType  = oldWorkOrderTable.IHSPerformWorkJobType;

            newWorkOrderTable.IHSPerformWorkJobVariant  = oldWorkOrderTable.IHSPerformWorkJobVariant;

            newWorkOrderTable.IHSIsPerformQc         = oldWorkOrderTable.IHSIsPerformQc;

            newWorkOrderTable.IHSPerformQcJobType    = oldWorkOrderTable.IHSPerformQcJobType;

            newWorkOrderTable.IHSPerformQcJobVariant = oldWorkOrderTable.IHSPerformQcJobVariant;

            // End Work order header Asset movement tab.


            

            if (newWorkOrderTable.validateWrite())

            {

                newWorkOrderTable.insert();

    

                if (numberSeq)

                {

                    numberSeq.used();

                }

            }

            else

            {

                if (numberSeq)

                {

                    numberSeq.abort();

                }

    

                throw error(strfmt("@SYS4007721", tablePname(EntAssetWorkOrderTable)));

            }

           

        }


        /// <summary>

        /// Creates a work order line if asset and job type is set.

        /// </summary>

    protected void createWorkOrderLine(IHSRelatedWorkOrderLineContract _lineContract)

        {

            setPrefix("@EnterpriseAssetManagementAppSuite:EntAsset10");

            

            newWorkOrderLine.clear();

            newWorkOrderLine.initValue();

            newWorkOrderLine.initFromWorkOrderTable(newWorkOrderTable);

            newWorkOrderLine.Object     = EntAssetObjectTable::find(_lineContract.parmObjectID()).RecId;

            newWorkOrderLine.modifiedField(fieldNum(EntAssetWorkOrderLine, Object));


            newWorkOrderLine.jobType    = EntAssetJobType::find(_lineContract.parmMaintenanceJobType()).RecId;

            newWorkOrderLine.JobVariant = EntAssetJobVariant::findId(_lineContract.parmMaintenanceJobTypeVariant()).RecId;

            newWorkOrderLine.JobTrade   = EntAssetJobTrade::findId(_lineContract.parmMaintenanceJobTypeTradeID()).RecId;

            

            if (newWorkOrderLine.validateWrite())

            {

                newWorkOrderLine.insert();

               

            }

            else

            {

                throw error(strfmt("@SYS4007721", tablePname(EntAssetWorkOrderLine)));

               

            }

            

            newWorkOrderTable.reread();


            EntAssetWorkOrderLine   workOrderLineFrom;


            select workOrderLineFrom

                where workOrderLineFrom.WorkOrder == oldWorkOrderTable.RecId

                 && workOrderLineFrom.Object ==  newWorkOrderLine.Object;

    

            workOrderTableRelation.initValue();

            workOrderTableRelation.FromWorkOrder     = workOrderLineFrom.WorkOrder;

            workOrderTableRelation.FromWorkOrderLine = workOrderLineFrom.RecId;

            workOrderTableRelation.ToWorkOrder       = newWorkOrderTable.RecId;

            workOrderTableRelation.ToWorkOrderLine   = newWorkOrderLine.RecId;

    

            if (workOrderTableRelation.validateWrite())

            {

                workOrderTableRelation.insert();

            }

            else

            {

                throw error(strfmt("@SYS4007721", tablePname(EntAssetWorkOrderTableRelation)));

            }

        }


    public boolean validateWorkOrderheader(IHSRelatedWorkOrderHeaderContract _headerContract, IHSRelatedWorkOrderServiceResponseContract _response)

    {

        boolean ret = true;

        EntAssetWorkOrderTable  workOrderTablevalidate = EntAssetWorkOrderTable::find(_headerContract.parmParentWorkOrderID());


        if(_headerContract == null)

        {

           

            _response.parmOutput(_response.FailedJsonFormat( _response.parmMessage("Input contract is null"), _headerContract.parmParentWorkOrderID()));

            ret = false;

          //  return ret;

        }

            

        if(!EntAssetWorkOrderTable::exist(workOrderTablevalidate.RecId))

        {

          //  _response.setFailed(strFmt("Work order %1 does not exist", _headerContract.parmParentWorkOrderID()));

          _response.parmOutput(_response.FailedJsonFormat( _response.parmMessage(strFmt("Work order %1 does not exist", _headerContract.parmParentWorkOrderID())), _headerContract.parmParentWorkOrderID()));

            ret = false;

           // return response;

        }


        if(_headerContract.parmWorkOrderLines() == null || _headerContract.parmWorkOrderLines().empty())

        {

            

            _response.parmOutput(_response.FailedJsonFormat(_response.parmMessage("Input contract contains no lines"), _headerContract.parmParentWorkOrderID()));

            ret = false;

           // return response;

        }


        if(_headerContract.parmWorkorderType() == null)

        {

           

            _response.parmOutput(_response.FailedJsonFormat(_response.parmMessage("Work order type must be filled in."), _headerContract.parmParentWorkOrderID()));

            ret = false;

           // return response;

        }


        //return response;

        return ret;

    }


    static str GetInfoLogMessages()

    {

        SysInfologEnumerator    sysInfologEnumerator;

        SysInfologMessageStruct infoMessageStruct;

        str                     logMessage;

        const str NewLine       = '\n';


        sysInfologEnumerator = SysInfologEnumerator::newData(infolog.export());

    

        while (sysInfologEnumerator.moveNext())

        {

            int i = 1;


            if (logMessage)

            {

                logMessage += Newline;

            }


            infoMessageStruct = SysInfologMessageStruct::construct(sysInfologEnumerator.currentMessage());

        

            while (i <= infoMessageStruct.prefixDepth())

            {

                logMessage += infoMessageStruct.preFixTextElement(i) + '. ';

                i++;

            }


            logMessage += infoMessageStruct.message();

        }


        return logMessage;

    }


}


=========================================================================


5) Create a response class


/// <summary>

/// COntract class for Related WorkOrder header Service

/// </summary>

[DataContract]

Final class IHSRelatedWorkOrderServiceResponseContract

{

    EntAssetWorkOrderID     workOrderID;

    str         message;

    str         status;

    str         output;

    List        linesResponse = new List(Types::Class);

   

    [DataMember("WorkOrderID")]

    public EntAssetWorkOrderID parmWorkOrderID(EntAssetWorkOrderID _workOrderID = workOrderID)

    {

        workOrderID = _workOrderID;

        return workOrderID;

    }


    [DataMember("Status")]

    public str parmStatus(str _status = status)

    {

        status = _status;

        return status;

    }


    [DataMember("Message")]

    public str parmMessage(str _message = message)

    {

        message = _message;

        return message;

    }


    public void setFailed(str _message)

    {

        this.parmStatus("Failed");

        this.parmMessage(_message);

    }


    public void setSuccess(str _message = "success")

    {

        this.parmStatus("Success");

        this.parmMessage(_message);

    }


    public str parmOutput(str _output = output)

    {

        output = _output;

        return output;

    }


    public  str sucessJsonFormat(Notes _successMessage, EntAssetWorkOrderID _workorderId, EntAssetWorkOrderID _oldWorkOrderNumber)

    {

        System.IO.StringWriter          stringWriter;

        Newtonsoft.Json.JsonTextWriter  jsonWriter;

       

        stringWriter       = new System.IO.StringWriter();

        jsonWriter         = new Newtonsoft.Json.JsonTextWriter(stringWriter);


        jsonWriter.WriteStartArray();


        str sJSON = "";

        jsonWriter.WriteStartObject();

        jsonWriter.WritePropertyName("Status");

        jsonWriter.WriteValue("Success");

        jsonWriter.WritePropertyName("FromWO");

        jsonWriter.WriteValue(_oldWorkOrderNumber);

        jsonWriter.WritePropertyName("NewWO");

        jsonWriter.WriteValue(_workorderId);

        jsonWriter.WritePropertyName("Message");

        jsonWriter.WriteValue(strFmt("New work order created succesfully :%1", _workorderId));


        jsonWriter.WriteEndObject();

        jsonWriter.WriteEndArray();


        sJSON = stringWriter.ToString();


        return sJSON;

        // Info(strFmt("%1", stringWriter.ToString()));

    }


    public str FailedJsonFormat(Notes _failedMessage, EntAssetWorkOrderID _oldWorkOrderNumber)

    {

        System.IO.StringWriter          stringWriter;

        Newtonsoft.Json.JsonTextWriter  jsonWriter;

        

        stringWriter       = new System.IO.StringWriter();

        jsonWriter         = new Newtonsoft.Json.JsonTextWriter(stringWriter);


        jsonWriter.WriteStartArray();


        str sJSON = "";


        jsonWriter.WriteStartObject();

        jsonWriter.WritePropertyName("Status");

        jsonWriter.WriteValue("Failed");

        jsonWriter.WritePropertyName("FromWO");

        jsonWriter.WriteValue(_oldWorkOrderNumber);

        jsonWriter.WritePropertyName("ErrorMessage");

        jsonWriter.WriteValue(_failedMessage);


        jsonWriter.WriteEndObject();

        jsonWriter.WriteEndArray();


        sJSON = stringWriter.ToString();

           

        return sJSON;

    }


    /// <summary>

    /// Get/set list of  workorder lines

    /// </summary>

    /// <param name = "_workorderLineList">Lines list</param>

    /// <returns></returns>

    [DataMember("Lines"),

        AifCollectionType("_linesResponse", Types::Class, classStr(IHSRelatedWorkOrderLineResponseContract)),

        AifCollectionType("return", Types::Class, classStr(IHSRelatedWorkOrderLineResponseContract))]

    public List parmLines(List _linesResponse = linesResponse)

    {

        linesResponse = _linesResponse;

        return linesResponse;

    }


}



==================================================================================================



6) Create a Test job to check the web service 


internal final class IHSTestIHSRelatedWorkOrderServiceJob

{

    /// <summary>

    /// Class entry point. The system will call this method when a designated menu 

    /// is selected or when execution starts and this class is set as the startup class.

    /// </summary>

    /// <param name = "_args">The specified arguments.</param>

    public static void main(Args _args)

    {

        str output;

        int ticks;

        List    workorderLineList = new List(Types::Class);

        ;


        //  EntAssetWorkOrderTable    workOrderTable = EntAssetWorkOrderTable::find('NG04-00000087');

        // get the tickcount before the process starts

        ticks = winapi::getTickCount();

   

        // start the process

        sleep(2000); // simulate 2 seconds of processing

   

        IHSRelatedWorkOrderHeaderContract contract = new IHSRelatedWorkOrderHeaderContract();

        IHSRelatedWorkOrderLineContract contractLine = new IHSRelatedWorkOrderLineContract();

        IHSRelatedWorkOrderLineContract contractLine1 = new IHSRelatedWorkOrderLineContract();


      //  workorderLineList.addStart(contractLine);

        contractLine1.parmWorkOrderLineNumber(1);

        contractLine1.parmObjectID('Alter-0000005');

        contractLine1.parmMaintenanceJobType('Manage Disposal');

        workorderLineList.addEnd(contractLine1);


        contractLine.parmWorkOrderLineNumber(2);

        contractLine.parmObjectID('Alter-0000006');

        contractLine.parmMaintenanceJobType('Manage Disposal');

        workorderLineList.addEnd(contractLine);


        contract.parmParentWorkOrderID("NG04-00000741");

        contract.parmDataAreaId("NG04");

        contract.parmWorkorderType('Manage Disposal');

        contract.parmDescription('TestHeader');

        contract.parmServiceLevel(4);

        contract.parmWorkOrderLines(workorderLineList);


        IHSRelatedWorkOrderService service = new IHSRelatedWorkOrderService();

        IHSRelatedWorkOrderServiceResponseContract response = service.insertWorkOrderHeaderLines(contract);

        

        info(response.parmOutput());


        

        

        // compare tickcount

        ticks = winapi::getTickCount() - ticks;

   

        // display result

        info(strfmt('Number of ticks: %1', ticks));

    }


}






Comments

Popular posts from this blog

Customization on Sales invoice Report in D365 F&O

75) COC - Create a coc of the table modified method

46) D365 FO: SHAREPOINT FILE UPLOAD USING X++