Creating an order

Discussions related to SoftPro Select Server development.

Moderator: Phil Barton

Post Reply
dn_garza
Posts: 25
Joined: Wed Jan 10, 2024 11:16 pm

Creating an order

Post by dn_garza »

I'm trying to create the most basic of orders as a starter. I've taken a few examples from the forum here but am running into a null exception error. Any thoughts?
nullExceptionNewOrder.png.png
nullExceptionNewOrder.png.png (36.25 KiB) Viewed 1560 times
BobRichards
Posts: 1377
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Creating an order

Post by BobRichards »

It appears that your call to get the IOrderStore service failed and `os` is null. Make sure you are using the service locator from SelectServer - not from a shell or standalone application environment. These are very different collections of services and the IOrderStore is only available from a server context.

Otherwise, please submit your code so I can advise. Put it in inside code blocks so the spacing is preserved.
DevForumCodeBlock.jpg
DevForumCodeBlock.jpg (1.02 KiB) Viewed 1502 times
Bob Richards, Senior Software Developer, SoftPro
dn_garza
Posts: 25
Joined: Wed Jan 10, 2024 11:16 pm

Re: Creating an order

Post by dn_garza »

'os' does not appear to be null and if I use os.OrderSaving to attach a method, the attached method works. 'NewOrder' seems to be the issue.

Code: Select all

using SoftPro.Accounting.Client;
using SoftPro.ClientModel;
using SoftPro.OrderTracking.Client;
using SoftPro.OrderTracking.Client.Orders;
using SoftPro.Select.Client;
using SoftPro.Select.Service;
using SoftPro.ServerModel;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.InteropServices;
using SoftPro.Select.Service.Runtime;
using SoftPro.Select.Client.Scheduler;
using SoftPro.Select.Client.Runtime;
using System.Linq;
using System.Net;

namespace XXXXXX
{
    [Guid("3c691408-fd01-45a2-9945-6831b0358c96")]
    partial class XXXXXX: Package
    {
        // This method is called when the package is loaded by the server.
        protected override void OnInitialize()
        {
           
            // Listen to the environment started event.
            ISelectServerEnvironment environment = GetService<ISelectServerEnvironment>();
            environment.Started += SelectServerEnvironment_Started;
        }

        // This method is called when the server is finished loading packages and services.
        private void SelectServerEnvironment_Started(object sender, System.EventArgs e)
        {
            // Get services here because they are guaranteed to be loaded.
            // Listen to the order saving event.

            IOrderStore os = GetService<IOrderStore>();
            if (os == null)
            {
                System.Diagnostics.Debug.WriteLine("os is null");
            } else
            {
            	//This is what I'm getting - os is not null
                System.Diagnostics.Debug.WriteLine("os is not null");
            }
            OrderCreationSpec spec = new OrderCreationSpec();
            spec.SettlementType = SettlementType.CDF;
            spec.BaseNumber = "Test-007";
            //Code breaks here
            IOrder order = os.NewOrder(spec);

            // Cast to dynamic to make order handling easier.
            dynamic o = (dynamic)order;

            // Set a property.
            o.Project = "New Deal";

            // Save the order in the database.
            os.ApplyChanges(order);

	    // if I uncomment the following line the OrderStore_OrderSaving method works
            //os.OrderSaving += OrderStore_OrderSaving;

            // Unhook this event as it is no longer needed.
            ISelectServerEnvironment environment = GetService<ISelectServerEnvironment>();
            environment.Started -= SelectServerEnvironment_Started;
            
        }

        // This method is called when an order is being saved.
        private void OrderStore_OrderSaving(object sender, OrderSavingEventArgs e)
        {
            // Get the order as a dynamic object to make programming easier.
            dynamic order = e.Order;
            string salesPrice = Convert.ToString(order.SalesContract.SalesPrice);
            System.Diagnostics.Debug.WriteLine("an order is saving");
            System.Diagnostics.Debug.WriteLine(salesPrice);
        }
    }
}
nullOrder.png
nullOrder.png (19.96 KiB) Viewed 1437 times
dn_garza
Posts: 25
Joined: Wed Jan 10, 2024 11:16 pm

Re: Creating an order

Post by dn_garza »

Hi Bob, have you had a chance to review this?
BobRichards
Posts: 1377
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Creating an order

Post by BobRichards »

Orders should typically be created in a shell or standalone package context like is demonstrated in the SDK in Standalone Application Development topic "Create an Order". This is because the user that is active in the server does not have all the information necessary to create an order. For instance, it does not have a user profile. In your code, the order creation failed because of the missing information.

You need to create a SelectServer session by passing in the credentials of an enabled User displayed in SPAdmin/Security/Users.
Bob Richards, Senior Software Developer, SoftPro
dn_garza
Posts: 25
Joined: Wed Jan 10, 2024 11:16 pm

Re: Creating an order

Post by dn_garza »

So if we want a server package to import orders from an outside source and map them to softpro on behalf of the client, we can only do so by using the SPAdmin's credentials?
BobRichards
Posts: 1377
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Creating an order

Post by BobRichards »

To CREATE an order, you must do it with user credentials. Most people have a fixed user set aside for this function. This allows the user to have whatever permissions are needed to create the order. You can also change the user's profile or just the order's ownership profile on-the-fly if desired.
Bob Richards, Senior Software Developer, SoftPro
dn_garza
Posts: 25
Joined: Wed Jan 10, 2024 11:16 pm

Re: Creating an order

Post by dn_garza »

Hi Bob,

In one post you wrote:

"Server packages run as the administrator. There is no way to change this.

The only way for a server package to impersonate a user is to create another SelectServer instance by logging in with the user credentials. This means the server must know the username/password for the user and it would consume a license for the duration of the session. This is not advised."

If the server package runs as the administrator, do I still need to create another SelectServer instance? And if not, is this simply an issue of the administrator not having the correct permissions? What permissions are required to create a new order programmatically? Also, in case I do need to create another SelectServer instance, since I have a local setup simply to test the creation of this package and a built in administrator user is available, how do I get the password for the Admin?

Thanks!
Post Reply