Creating Sales Order through WebServices in E9

Hi people, I am trying to create a Sales Order through WebServices in E9.05.702. I was able to connect successfully. Here is my code so far:

private void button1_Click(object sender, EventArgs e)
 {
         try
         {
                Session objSession = null;
                objSession = new Session("manager", "manager", "AppServerDC://127.0.0.1:9431", Session.LicenseType.Default);"

                MessageBox.Show("Connection established successfully" + objSession.SessionID + " to Instance "+ objSession.CompanyName);

SalesOrder so = new SalesOrder(objSession.ConnectionPool);
SalesOrderDataSet ds = new SalesOrderDataSet();

//Here, I am stuck. Further implementation here.

System.Threading.Thread.Sleep(10000);
                ds.Dispose();
                objSession.Dispose();
                MessageBox.Show("Sesion has been disposed");
         }
catch (Exception error)
            {
                MessageBox.Show(error.Message);
                if (objSession != null)
                {
                    objSession.Dispose();
                    objSession = null;
                    MessageBox.Show("Sesion has been disposed");
                }
            }
}

The spot where I left a comment Further implementation I want to continue my developing. Here are my thoughts about the next step:

When I go ‘so.’ Intellisense in VS shows me a bunch of methods that I can use. As per ‘Create’ I can see:
image

None of them are going to work for me as there will be no Quotes, so I can’t do that. The idea here is to map all the necessary fields from XML document and submit them into E9.

There are some methods related to OrderHed, Dtl, etc. For example:

Should I be looking for those might be? Like GetNewOrderHed. It looks like it accepts an instance of SalesOrderDataSet but I can’t populate it with fields in order to send it to Epicor. I might be wrong here though.

Any ideas and thoughts would be very much appreciated.

Thank you,

Alex

Run a trace in Epicor. You will see the methods that are called. Yes, next step is GetNewOrderHed. You would update fields in the dataset.

1 Like

Hi @Jason_Woods. Thank you for your input. I have tried to run a TraceLog with (WriteDataSet option on) and I see what do you mean by methods that are called. However, I think I confused myself and confused everybody and here is why. The way I was connecting to Epicor is by grabbing necessary dlls and adding them to my project so I would have access to those and Intellisense. I actually need to connect to Epicor through WebServices first I suppose and then try to create Sales Order.

I updated my code so it would match the approach I need to take I guess.

private void button1_Click(object sender, EventArgs e)
{
 try {
       SalesOrderService.SalesOrderServiceSoapClient client = new SalesOrderService.SalesOrderServiceSoapClient();
                
       client.ClientCredentials.UserName.UserName = "manager";
       client.ClientCredentials.UserName.Password = "manager";
                
       SalesOrderService.SalesOrderDataSetType dss = new SalesOrderService.SalesOrderDataSetType();
       SalesOrderService.CallContextDataSetType callContextIn = new SalesOrderService.CallContextDataSetType();
       SalesOrderService.CallContextDataSetType callContextOut = new SalesOrderService.CallContextDataSetType();
       SalesOrderService.SalesOrderDataSetTypeOrderHed orderHedReq = new SalesOrderService.SalesOrderDataSetTypeOrderHed();

       orderHedReq.OrderNum = 10002;
       orderHedReq.CustNum = 1;
       var response = client.GetNewOrderHed("TEST", dss, callContextIn, out callContextOut);
       
}
}

This code fails on client.GetNewOrderHed call and returns the next error:
image

and I do not see how I can pass a security header in addition to UserName and Password.

What do you think?

Alex

P.S. Might be @josecgomez will have a clue what’s going on?

You need to read the web services guide available in EpicWeb

1 Like

Hey Jose,

Thank you for a pointer. I looked through that documentation. I found this example and tried to do a similar thing but for SalesOrder.

However, I do not have SalesOrderServiceWse or SalesOrderServiceClient class definitions in order to instantiate a proper proxy class. The only one I have is SalesOrderServiceSoapClient that more or less make sense and I’ve seen how it’s usually used to consume Web Services.

I also found this example:


As I can see, they do not use any Tokens in this one, but just Username and Password unless, they forgot to put a piece with Token code. This is kinda confusing. My question is where would I be able to find a proper proxy class to instantiate?

If you consume the WSLD as a Web Service Reference and not a “Service Reference” it will generate correctrly
You also have to use the WSE runtime, again all this is in the guide step by step.

Hi Jose,

By saying “You also have to use the WSE runtime” do you mean “Enable this project for Web Services Enhancements” or something else? The guide is showing that you need to go and select WSE Settings 3.0 button on a project file and then go and add a Web Reference. I was able to add Web Service in VS2017 without enabling WSE Settings in advance. Moreover, I do not even have that option when I right-click on a project file. Just wondering if I am missing a step here or it’s all good. Also, I verified that WSE Runtime is installed.

So, after I added WSDL as Web Service Reference I got SalesOrderService class generated for me. I followed all the steps from the guide and now I am having a problem with SetPolicy method it says that SalesOrderService doesn’t contain a definition of SetPolicy. Does it mean that I have to call SetPolicy method in a different way or might be using the wrong object?
Here is my updated code:

try
            {
                SalesOrderReferenceE9.SalesOrderService proxy = new SalesOrderReferenceE9.SalesOrderService();
                Trace.WriteLine("Line 1 -----------------");
                SalesOrderReferenceE9.SalesOrderDataSetType ds = new SalesOrderReferenceE9.SalesOrderDataSetType();
                Trace.WriteLine("Line 2 -----------------");
                SalesOrderReferenceE9.CallContextDataSetType callContextIn = new SalesOrderReferenceE9.CallContextDataSetType();
                Trace.WriteLine("Line 3 -----------------");
                SalesOrderReferenceE9.CallContextDataSetType callContextOut = new SalesOrderReferenceE9.CallContextDataSetType();
                Trace.WriteLine("Line 4 -----------------");
                
                UsernameOverTransportAssertion userNameAssertion = new UsernameOverTransportAssertion();
                Trace.WriteLine("Line 5 -----------------");
                userNameAssertion.UsernameTokenProvider = new UsernameTokenProvider("manager", "manager");
                Trace.WriteLine("Line 6 -----------------");

                Policy policy = new Policy();
                policy.Assertions.Add(userNameAssertion);
                Trace.WriteLine("Line 7 -----------------");
                proxy.SetPolicy(policy);
                
                
                Trace.WriteLine("Line 8 -----------------");
                SalesOrderReferenceE9.SalesOrderDataSetType soDataSet = proxy.GetNewOrderHed("TEST", ds, callContextIn, out callContextOut);
}

P.S. Should I be modifying my previous posts to keep this thread clear? or a new Reply is fine?

As stated in the guide you need to install and use
https://www.microsoft.com/en-us/download/details.aspx?id=14089

Because you are in 9
And when you add the Service you need to add it as a WebReference not a Service Reference (Advanced Options)

1 Like

Update. After pocking around I was able to bring SetPolicy to SalesOrderService class by changing the inherited class from System.Web.Services.Protocols.SoapHttpClientProtocol to Microsoft.Web.Services3.WebServicesClientProtocol. I guess the actual problem was that I got it right at first but then re-imported WSDL and forgot to change it again because re-importing will re-write your changes.

Thanks Jose, I am moving forward!=)

1 Like

Hey @josecgomez, I think I almost was able to post the entire order into Epicor but, it looks like it doesn’t want to process a Detail level information and returns me this error:

image

At this point, Header was populated successfully but, none of the Details. I think that it might be related to OrderNum on Detail level being passed as 0 but, I do not see how do I specify a Number of a new order that hasn’t been created yet. Unless I have to do two separate calls, one for Header and one for Detail which I did not find available methods to call. Here is how my code looks like:

SalesOrderDataSetType ds = new SalesOrderDataSetType();

SalesOrderDataSetTypeOrderHed soDSHed = new SalesOrderDataSetTypeOrderHed();

ds = soService.GetNewOrderHed("TEST", ds, callContextIn, out callContextOut);
soDSHed.Company = "TEST";
soDSHed.OrderNum = 0;
soDSHed.CustNum = 1;
soDSHed.CustomerCustID = "TEST";
soDSHed.ShipViaCode = "UPSG";
                
SalesOrderDataSetTypeOrderDtl soDSDtl = new SalesOrderDataSetTypeOrderDtl();
//ds = soService.GetNewOrderDtl("TEST", ds, 0, callContextIn, out callContextOut);//This guy is commented out as it won't accept 0 as OrderNum and would return an error that valid OrderNum is required.
soDSDtl.Company = "TEST";
soDSDtl.OrderNum = 0;
soDSDtl.OrderLine = 1;
soDSDtl.PartNum = "6.WD8";
soDSDtl.CustNum = 1;
soDSDtl.SellingQuantity = 2.0m;
                
ds.SalesOrderDataSet[0] = soDSHed;
Trace.WriteLine("Line 9 -----------------");
ds.SalesOrderDataSet[1] = soDSDtl;
Trace.WriteLine("Line 10 -----------------");

soService.SubmitNewOrder("TEST", ds, callContextIn, out callContextOut);

Trace.WriteLine("Line 11 -----------------");

I confirmed that all the information exists in Epicor and I can create a new order Header and Detail with all those values from UI.

Any thoughts or advice would be very much appreciated. Thank you.

GetNewOrderHed method only you able to insert header details. for line level you have to invoke anther method

Hi @surendrapal, for the line-level, apparently GetNewOrderDtl would be suitable but, it looks like I can’t call it as it expects a valid OrderNum as one of the parameters and at that time Order has not been created yet so there is no corresponding OrderNum that I can specify. Look at my code example, that method is commented out and there is a comment.

SalesOrderDataSetTypeOrderDtl soDSDtl = new SalesOrderDataSetTypeOrderDtl();
//ds = soService.GetNewOrderDtl("TEST", ds, 0, callContextIn, out callContextOut);//This guy is commented out as it won't accept 0 as OrderNum and would return an error that valid OrderNum is required.
soDSDtl.Company = "TEST";
soDSDtl.OrderNum = 0;
soDSDtl.OrderLine = 1;
soDSDtl.PartNum = "6.WD8";
soDSDtl.CustNum = 1;
soDSDtl.SellingQuantity = 2.0m;

once you save header detail you will have order number use that one.