Exemple #1
0
        public void ChangeShipvia(string shipvia)
        {
            Microsoft.Win32.RegistryKey SageKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\ODBC\ODBC.INI\SOTAMAS90");
            string InitPath = SageKey.GetValue("Directory") + @"\Home";
            object retVal;

            // Open Initial PVX object
            using (DispatchObject pvx = new DispatchObject("ProvideX.Script"))
            {
                // Set MAS90 Path
                pvx.InvokeMethod("Init", InitPath);

                // Set up my Session connection
                using (DispatchObject oSS = new DispatchObject(pvx.InvokeMethod("NewObject", "SY_Session")))
                {
                    // Set Username and password
                    // Set Company, and set the date
                    // Basic setup for the oSS object
                    oSS.InvokeMethod("nSetUser", Username, Password);
                    oSS.InvokeMethod("nLogon");
                    oSS.InvokeMethod("nSetCompany", Company);
                    oSS.InvokeMethod("nSetDate", "S/O", DateTime.Today.ToString("yyyyMMdd"));
                    oSS.InvokeMethod("nSetModule", "A/R");

                    // Set task ID to oSS
                    int TaskID = (int)oSS.InvokeMethod("nLookupTask", "SO_SalesOrder_ui");
                    retVal = oSS.InvokeMethod("nSetProgram", TaskID);

                    // SafeProcess just checks the last error message value and prints it to
                    // the debug output. In the future, I will have it post this to an error log
                    SafeProcess(oSS.InvokeMethod("nSetProgram", TaskID), oSS);

                    // Loop through the orders
                    // This saves time over opening the oSS and PVX object over and over again
                    foreach (SalesOrder salesorder in this.SalesOrders())
                    {
                        Debug.WriteLine(">>Changing " + salesorder.SalesOrderNo + "<<");
                        // Open object for sales order
                        using (DispatchObject so_order = new DispatchObject(pvx.InvokeMethod("NewObject", "SO_SalesOrder_bus", oSS.GetObject())))
                        {
                            SafeProcess(so_order.InvokeMethod("nSetKey", salesorder.SalesOrderNo), so_order);

                            SafeProcess(so_order.InvokeMethod("nSetValue", "ShipVia$", shipvia), so_order);

                            retVal = so_order.InvokeMethod("nWrite");
                            if ((int)retVal != 1)
                            {
                                Debug.WriteLine(so_order.GetProperty("sLastErrorMsg"));
                            }
                        }

                        Debug.WriteLine("<<End Changing Sales Order<<");
                    }
                }
            }
        }
Exemple #2
0
        private static int SafeProcess(object Method, DispatchObject Object)
        {
            object retVal;

            retVal = Method;
            if ((int)retVal != 1)
            {
                Debug.WriteLine(Object.GetProperty("sLastErrorMsg"));
            }

            return((int)retVal);
        }
Exemple #3
0
            public static SageObject Process(object Method, DispatchObject Object)
            {
                object retVal;
                string ErrorMessage = string.Empty;

                retVal = Method;

                if ((int)retVal != 1)
                {
                    ErrorMessage = Object.GetProperty("sLastErrorMsg").ToString();
                    if (SageError != null)
                    {
                        SageError(ErrorMessage);
                    }
                }

                return(new SageObject(ErrorMessage, (int)retVal));
            }
Exemple #4
0
        public static bool CanConnectToSage()
        {
            bool result = false;

            Microsoft.Win32.RegistryKey SageKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\ODBC\ODBC.INI\SOTAMAS90");
            string InitPath = SageKey.GetValue("Directory") + @"\Home";

            DispatchObject Test_PVX = null;
            DispatchObject Test_OSS = null;

            try
            {
                // If these objects fail, we need to manually clean them up
                // wrapping them in a using does not clean dispose them
                Test_PVX = new DispatchObject("ProvideX.Script");
                Test_PVX.InvokeMethod("Init", InitPath);
                Test_OSS = new DispatchObject(Test_PVX.InvokeMethod("NewObject", "SY_Session"));
                // If we get this far, the connection to Sage was a success
                result = true;
            }
            catch (System.Reflection.TargetInvocationException)
            {
                // We can't connect to Sage 100. Let the user know this.
                // We are going to return
            }
            finally
            {
                /*
                 * We have to force these objects to dispose
                 */

                if (Test_PVX != null)
                {
                    Test_PVX.Dispose();
                }

                if (Test_OSS != null)
                {
                    Test_OSS.Dispose();
                }
            }
            return(result);
        }
Exemple #5
0
        public static List <Company> CompanyList()
        {
            List <Company> Companies = new List <Company>();

            Microsoft.Win32.RegistryKey SageKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\ODBC\ODBC.INI\SOTAMAS90");
            string InitPath = SageKey.GetValue("Directory") + @"\Home";
            object retVal   = new object();

            // See if we can make a connection to Sage
            if (Core.CanConnectToSage() == false)
            {
                // We can't connect to Sage 100
                return(null);
            }

            // Open Initial PVX object
            using (DispatchObject pvx = new DispatchObject("ProvideX.Script"))
            {
                pvx.InvokeMethod("Init", InitPath);

                // Set up my Session connection
                using (DispatchObject oSS = new DispatchObject(pvx.InvokeMethod("NewObject", "SY_Session")))
                {
                    // Split on chr 138 - Š
                    string[] CompanyList = oSS.GetProperty("sCompanyList").ToString().Split(new char[] { 'Š' }, StringSplitOptions.RemoveEmptyEntries);

                    foreach (string company in CompanyList)
                    {
                        Companies.Add(
                            new Company(
                                company.Split(new string[] { "  " }, StringSplitOptions.None)[0],
                                company.Split(new string[] { "  " }, StringSplitOptions.None)[1].Replace(")", "").Replace("(", "")));
                    }
                }
            }

            return(Companies);
        }
Exemple #6
0
        public static string SalesOrders(IDispatchObject busObject, ISessionService session, Record record)
        {
            string _command  = "";
            string _method   = "";
            string _value    = "";
            string _variable = "";

            void SetLogParams(string method, string command, string variable, string value)
            {
                _method   = method;
                _command  = command;
                _variable = variable;
                _value    = value;
            }

            string GetErrorMessage()
            {
                var sessionError = session.GetError();

                return
                    ($"Error: {sessionError}, Method: {_method}, Command: {_command}, Variable: {_variable}, Value: {_value}");
            }

            Dictionary <string, object> recordObject;

            string[] keyColumnsObject = Metadata.Metadata.GetKeys(busObject, session);

            // convert record json into object
            try
            {
                recordObject = JsonConvert.DeserializeObject <Dictionary <string, object> >(record.DataJson);
            }
            catch (Exception e)
            {
                Logger.Error(e, e.Message);
                throw;
            }

            // set key column value to enable editing of record
            try
            {
                SetLogParams("InsertSingleRecord", "nGetNextSalesOrderNo", "", "");
                var data = new object[] { "" };
                busObject.InvokeMethodByRef("nGetNextSalesOrderNo", data);
                var keyValue = data[0].ToString();
                var key      = keyColumnsObject[0];

                SetLogParams("InsertSingleRecord", "nSetKey", key, keyValue);
                busObject.InvokeMethod("nSetKey", keyValue);

                // remove key column as it is already set
                recordObject.Remove(key);
            }
            catch (Exception e)
            {
                var error = GetErrorMessage();
                Logger.Error(e, "Error inserting single record");
                Logger.Error(e, e.Message);
                Logger.Error(e, error);
                return(error);
            }

            // set and validate all required properties
            var recordKey = "ARDivisionNo$";

            if (recordObject.ContainsKey(recordKey))
            {
                var recordValue = recordObject[recordKey];
                if (recordValue != null)
                {
                    try
                    {
                        SetLogParams("InsertSingleRecord", "nSetValue", recordKey, recordValue.ToString());
                        busObject.InvokeMethod("nSetValue", recordKey, recordValue.ToString());
                        recordObject.Remove(recordKey);
                    }
                    catch (Exception e)
                    {
                        var error = GetErrorMessage();
                        Logger.Error(e, "Error inserting single record");
                        Logger.Error(e, e.Message);
                        Logger.Error(e, error);
                        return(error);
                    }
                }
                else
                {
                    return($"{recordKey} was null");
                }
            }
            else
            {
                return($"{recordKey} must be set");
            }

            recordKey = "CustomerNo$";
            if (recordObject.ContainsKey(recordKey))
            {
                var recordValue = recordObject[recordKey];
                if (recordValue != null)
                {
                    try
                    {
                        SetLogParams("InsertSingleRecord", "nSetValue", recordKey, recordValue.ToString());
                        busObject.InvokeMethod("nSetValue", recordKey, recordValue.ToString());
                        recordObject.Remove(recordKey);
                    }
                    catch (Exception e)
                    {
                        var error = GetErrorMessage();
                        Logger.Error(e, "Error inserting single record");
                        Logger.Error(e, e.Message);
                        Logger.Error(e, error);
                        return(error);
                    }
                }
                else
                {
                    return($"{recordKey} was null");
                }
            }
            else
            {
                return($"{recordKey} must be set");
            }

            recordKey = "LineItems";
            if (recordObject.ContainsKey(recordKey))
            {
                var recordValue = recordObject[recordKey];
                if (recordValue != null)
                {
                    try
                    {
                        var linesBusObject = new DispatchObject(busObject.GetProperty("oLines"));
                        var lineItems      = JsonConvert.DeserializeObject <List <LineItem> >(JsonConvert.SerializeObject(recordValue));

                        foreach (var lineItem in lineItems)
                        {
                            SetLogParams("InsertSingleRecord", "nSetValue", recordKey, lineItem.ItemCode);
                            linesBusObject.InvokeMethod("nAddLine");
                            linesBusObject.InvokeMethod("nSetValue", "ItemCode$", lineItem.ItemCode);
                            linesBusObject.InvokeMethod("nSetValue", "QuantityOrdered", lineItem.QuantityOrdered.ToString());
                        }

                        recordObject.Remove(recordKey);
                    }
                    catch (Exception e)
                    {
                        var error = GetErrorMessage();
                        Logger.Error(e, "Error inserting single record");
                        Logger.Error(e, e.Message);
                        Logger.Error(e, error);
                        return(error);
                    }
                }
                else
                {
                    return($"{recordKey} was null");
                }
            }
            else
            {
                return($"{recordKey} must be set");
            }

            // write out all other columns
            try
            {
                foreach (var col in recordObject)
                {
                    if (col.Value != null)
                    {
                        SetLogParams("InsertSingleRecord", "nSetValue", col.Key, col.Value.ToString());
                        busObject.InvokeMethod("nSetValue", col.Key, col.Value.ToString());
                    }
                }

                SetLogParams("InsertSingleRecord", "nWrite", "", "");
                busObject.InvokeMethod("nWrite");
            }
            catch (Exception e)
            {
                var error = GetErrorMessage();
                Logger.Error(e, "Error inserting single record");
                Logger.Error(e, e.Message);
                Logger.Error(e, error);
                return(error);
            }

            return("");
        }
Exemple #7
0
        public static void Copy(
            Core.Company Company, Core.Credentials Credentials,
            string SourceCode, string DestinationCode,
            bool CopyItemVendor = true, bool CopyAliasItems = true, bool UpdateBillofMaterials = false)
        {
            // Grab init path from the registry
            Microsoft.Win32.RegistryKey SageKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\ODBC\ODBC.INI\SOTAMAS90");
            string InitPath = SageKey.GetValue("Directory") + @"\Home";
            object retVal   = new object();

            // See if we can make a connection to Sage
            if (Core.CanConnectToSage() == false)
            {
                // We can't connect to Sage 100
            }

            // Open Initial PVX object
            using (DispatchObject pvx = new DispatchObject("ProvideX.Script"))
            {
                // Set MAS90 Path
                pvx.InvokeMethod("Init", InitPath);

                // Set up my Session connection
                using (DispatchObject oSS = new DispatchObject(pvx.InvokeMethod("NewObject", "SY_Session")))
                {
                    // Set Username and password
                    // Set Company, and set the date
                    // Basic setup for the oSS object


                    if (Core.SageObject.Process(oSS.InvokeMethod("nSetCompany", Company.Code), oSS).ReturnCode == (int)Core.ReturnCode.Failed)
                    {
                        // I'm returning a null here to break anything
                        // that doesn't expect a null. This isn't something
                        // I should run into unless I'm using incorrect
                        // company codes.
                        return;
                    }

                    if (Core.SageObject.Process(oSS.InvokeMethod("nSetUser", Credentials.Username, Credentials.Password), oSS).ReturnCode == (int)Core.ReturnCode.Failed)
                    {
                        // Login Failure
                        // Check Username and Password
                        return;
                    }
                    oSS.InvokeMethod("nLogon");


                    oSS.InvokeMethod("nSetDate", "C/I", DateTime.Today.ToString("yyyyMMdd"));
                    oSS.InvokeMethod("nSetModule", "C/I");

                    // Set task ID to oSS
                    int TaskID = (int)oSS.InvokeMethod("nLookupTask", "CI_ItemCode_ui");
                    Core.SageObject.Process(oSS.InvokeMethod("nSetProgram", TaskID), oSS);

                    // Connect to ItemCode bus, create a new item, then copy from it
                    using (DispatchObject ci_item = new DispatchObject(pvx.InvokeMethod("NewObject", "CI_ItemCode_bus", oSS.GetObject())))
                    {
                        Core.SageObject.Process(ci_item.InvokeMethod("nSetKey", new object[] { DestinationCode }), ci_item);
                        Core.SageObject.Process(ci_item.InvokeMethod("nCopyFrom", new object[] { SourceCode }, true, true, true), ci_item);

                        if (Core.SageObject.Process(ci_item.InvokeMethod("nWrite"), ci_item).ReturnCode == (int)Core.ReturnCode.Failed)
                        {
                            return;
                        }
                    }

                    // If true, copy Bill of Materials
                    if (UpdateBillofMaterials)
                    {
                        oSS.InvokeMethod("nSetDate", "B/M", DateTime.Today.ToString("yyyyMMdd"));
                        oSS.InvokeMethod("nSetModule", "B/M");

                        TaskID = (int)oSS.InvokeMethod("nLookupTask", "BM_Bill_ui");
                        Core.SageObject.Process(oSS.InvokeMethod("nSetProgram", TaskID), oSS);

                        using (DispatchObject bm_bill = new DispatchObject(pvx.InvokeMethod("NewObject", "BM_Bill_bus", oSS.GetObject())))
                        {
                            Core.SageObject.Process(bm_bill.InvokeMethod("nSetValue", "BILLNO$", DestinationCode), bm_bill);
                            Core.SageObject.Process(bm_bill.InvokeMethod("nSetKey"), bm_bill);

                            Core.SageObject.Process(bm_bill.InvokeMethod("nSetCopyBillNo", new object[] { SourceCode, "" }), bm_bill);
                            Core.SageObject.Process(bm_bill.InvokeMethod("nCopyFrom"), bm_bill);
                            Core.SageObject.Process(bm_bill.InvokeMethod("nWrite"), bm_bill);
                        }
                    }
                }
            }
        }
Exemple #8
0
        public static List <string> List(Core.Company Company, Core.Credentials Credentials)
        {
            // NOT WORKING
            // NO IDEA WHY - RETURNS NOTHING :<
            List <string> result = new List <string>();

            // Grab init path from the registry
            Microsoft.Win32.RegistryKey SageKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\ODBC\ODBC.INI\SOTAMAS90");
            string InitPath = SageKey.GetValue("Directory") + @"\Home";
            object retVal   = new object();

            // See if we can make a connection to Sage
            if (Core.CanConnectToSage() == false)
            {
                // We can't connect to Sage 100
            }

            // Open Initial PVX object
            using (DispatchObject pvx = new DispatchObject("ProvideX.Script"))
            {
                pvx.InvokeMethod("Init", InitPath);

                // Set up my Session connection
                using (DispatchObject oSS = new DispatchObject(pvx.InvokeMethod("NewObject", "SY_Session")))
                {
                    if (Core.SageObject.Process(oSS.InvokeMethod("nSetCompany", Company.Code), oSS).ReturnCode == (int)Core.ReturnCode.Failed)
                    {
                        // I'm returning a null here to break anything
                        // that doesn't expect a null. This isn't something
                        // I should run into unless I'm using incorrect
                        // company codes.
                        return(result);
                    }

                    if (Core.SageObject.Process(oSS.InvokeMethod("nSetUser", Credentials.Username, Credentials.Password), oSS).ReturnCode == (int)Core.ReturnCode.Failed)
                    {
                        // Login Failure
                        // Check Username and Password
                        return(result);
                    }
                    oSS.InvokeMethod("nLogon");



                    /* PULLED WORKING CODE FROM OTHER PROJECT
                     * oSS.InvokeMethod("nSetDate", "A/R", DateTime.Today.ToString("yyyyMMdd"));
                     * oSS.InvokeMethod("nSetModule", "A/R");
                     *
                     * int TaskID = (int)oSS.InvokeMethod("nLookupTask", "AR_Customer_ui");
                     * Core.SageObject.Process(oSS.InvokeMethod("nSetProgram", TaskID), oSS);
                     *
                     * using (DispatchObject ar_customer = new DispatchObject(pvx.InvokeMethod("NewObject", "AR_Customer_svc", oSS.GetObject())))
                     * {
                     *  String columns = "CustomerName$";
                     *  String keys = "CustomerNo$";
                     *  String returnFields = "CustomerNo$";
                     *  String returnAccountKeys = "CustomerNo$";
                     *  String whereClause = "";
                     *
                     *  Object[] getResultSetParams = new Object[] { columns, keys, returnFields, returnAccountKeys, whereClause, "", "" };
                     *
                     *  object retTest = ar_customer.InvokeMethodByRef("nGetResultSets", getResultSetParams);
                     *
                     * }
                     *
                     */

                    oSS.InvokeMethod("nSetDate", "C/I", DateTime.Today.ToString("yyyyMMdd"));
                    oSS.InvokeMethod("nSetModule", "C/I");

                    using (DispatchObject ci_item = new DispatchObject(pvx.InvokeMethod("NewObject", "CI_ItemCode_svc", oSS.GetObject())))
                    {
                        String columns           = "ItemCode$";
                        String keys              = "ItemCode$";
                        String returnFields      = "";
                        String returnAccountKeys = "";
                        String whereClause       = "";

                        Object[] getResultSetParams = new Object[] { columns, keys, returnFields, returnAccountKeys, whereClause, "", "" };

                        //"ItemCode$", "ItemCode$", TestString, "ItemType$=" + (char)34 + "1" + (char)34 + " AND UseInSO$=" + (char)34 + "Y" + (char)34, "", "")
                        Core.SageObject.Process(ci_item.InvokeMethod("nGetResultSets", getResultSetParams), ci_item);
                    }

                    return(result);
                }
            }
        }
Exemple #9
0
        public List <Invoice> Invoice()
        {
            List <Invoice> invoices = new List <Invoice>();

            Microsoft.Win32.RegistryKey SageKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\ODBC\ODBC.INI\SOTAMAS90");
            string InitPath = SageKey.GetValue("Directory") + @"\Home";
            object retVal;

            // Open Initial PVX object
            using (DispatchObject pvx = new DispatchObject("ProvideX.Script"))
            {
                // Set MAS90 Path
                pvx.InvokeMethod("Init", InitPath);

                // Set up my Session connection
                using (DispatchObject oSS = new DispatchObject(pvx.InvokeMethod("NewObject", "SY_Session")))
                {
                    // Set Username and password
                    // Set Company, and set the date
                    // Basic setup for the oSS object
                    oSS.InvokeMethod("nSetUser", Username, Password);
                    oSS.InvokeMethod("nLogon");
                    oSS.InvokeMethod("nSetCompany", Company);
                    oSS.InvokeMethod("nSetDate", "S/O", DateTime.Today.ToString("yyyyMMdd"));
                    oSS.InvokeMethod("nSetModule", "A/R");

                    // Set task ID to oSS
                    int TaskID = (int)oSS.InvokeMethod("nLookupTask", "SO_Invoice_ui");
                    retVal = oSS.InvokeMethod("nSetProgram", TaskID);

                    SafeProcess(oSS.InvokeMethod("nSetProgram", TaskID), oSS);

                    using (DispatchObject so_invoice = new DispatchObject(pvx.InvokeMethod("NewObject", "SO_Invoice_bus", oSS.GetObject())))
                    {
                        object[] batchnum = new object[] { BatchNo, "N", BatchDescription };

                        if (BatchNo == "")
                        {
                            SafeProcess(so_invoice.InvokeMethodByRef("nSelectNewBatch", batchnum), so_invoice);
                            BatchNo = (string)batchnum[0];
                        }
                        else
                        {
                            SafeProcess(so_invoice.InvokeMethod("nSelectBatch", BatchNo), so_invoice);
                        }

                        foreach (SalesOrder order in SalesOrders())
                        {
                            string   InvoiceNumber  = string.Empty;
                            object[] nextInvoiceNum = new object[] { "OrderNo$" };
                            SafeProcess(so_invoice.InvokeMethodByRef("nGetNextInvoiceNo", nextInvoiceNum), so_invoice);

                            InvoiceNumber = (string)nextInvoiceNum[0];

                            SafeProcess(so_invoice.InvokeMethod("nSetKey", InvoiceNumber), so_invoice);

                            SafeProcess(so_invoice.InvokeMethod("nsetvalue", "SalesOrderNo$", order.SalesOrderNo), so_invoice);

                            //SafeProcess(so_invoice.InvokeMethod("nsetvalue", "ShipWeight$", "13.37"), so_invoice);

                            using (DispatchObject so_line = new DispatchObject(so_invoice.GetProperty("oLines")))
                            {
                                SafeProcess(so_line.InvokeMethod("nCopyLinesFromSalesOrder", order.SalesOrderNo, "Y"), so_line);
                                //retVal = so_line.InvokeMethod("nCopyLinesFromSalesOrder", SalesOrderNo, "Y");

                                SafeProcess(so_line.InvokeMethod("nMoveFirst"), so_line);

                                string ItemType = string.Empty;

                                object[] getValueParam3 = new object[] { "ItemType$", "" };

                                SafeProcess(so_line.InvokeMethodByRef("nGetValue", getValueParam3), so_line);


                                int EOF        = (int)so_line.GetProperty("nEOF");
                                int ShippedQty = 0;

                                do
                                {
                                    int      orderquantity = 0;
                                    object[] orderedQty    = new object[] { "QuantityOrdered", orderquantity };

                                    SafeProcess(so_line.InvokeMethodByRef("nGetValue", orderedQty), so_line);
                                    ShippedQty = (int)orderedQty[1];

                                    //object[] getValueParam2 = new object[] { "ItemCodeDesc$", "" };
                                    // Read Into the object
                                    //SafeProcess(so_line.InvokeMethodByRef("nGetValue", getValueParam2), so_line);

                                    SafeProcess(so_line.InvokeMethod("nsetvalue", "QuantityShipped", ShippedQty), so_line);

                                    SafeProcess(so_line.InvokeMethod("nWrite"), so_line);

                                    SafeProcess(so_line.InvokeMethod("nMoveNext"), so_line);

                                    EOF = (int)so_line.GetProperty("nEOF");
                                } while (EOF != 1);

                                SafeProcess(so_invoice.InvokeMethod("nsetvalue", "FreightAmt", order.Freight), so_invoice);
                                SafeProcess(so_invoice.InvokeMethod("nsetvalue", "NumberofPackages", order.TrackingNumbers.Count()), so_invoice);

                                SafeProcess(so_invoice.InvokeMethod("nWrite"), so_invoice);

                                invoices.Add(new Invoice(InvoiceNumber));
                                Debug.WriteLine("Invoice Created: " + InvoiceNumber);
                            }
                        }
                    }
                }
            }

            return(invoices);
        }
Exemple #10
0
        public List <SalesOrder> Post()
        {
            // Grab init path from the registry
            Microsoft.Win32.RegistryKey SageKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\ODBC\ODBC.INI\SOTAMAS90");
            string InitPath = SageKey.GetValue("Directory") + @"\Home";
            object retVal   = new object();

            // See if we can make a connection to Sage
            if (Core.CanConnectToSage() == false)
            {
                // We can't connect to Sage 100
                // Return null to hopefully break things
                return(null);
            }

            // Open Initial PVX object
            using (DispatchObject pvx = new DispatchObject("ProvideX.Script"))
            {
                // Set MAS90 Path
                pvx.InvokeMethod("Init", InitPath);

                // Set up my Session connection
                using (DispatchObject oSS = new DispatchObject(pvx.InvokeMethod("NewObject", "SY_Session")))
                {
                    // Set Username and password
                    // Set Company, and set the date
                    // Basic setup for the oSS object


                    if (Core.SageObject.Process(oSS.InvokeMethod("nSetCompany", Company), oSS).ReturnCode == (int)Core.ReturnCode.Failed)
                    {
                        // I'm returning a null here to break anything
                        // that doesn't expect a null. This isn't something
                        // I should run into unless I'm using incorrect
                        // company codes.
                        return(null);
                    }

                    if (Core.SageObject.Process(oSS.InvokeMethod("nSetUser", Username, Password), oSS).ReturnCode == (int)Core.ReturnCode.Failed)
                    {
                        // Login Failure
                        // Check Username and Password
                        return(null);
                    }
                    oSS.InvokeMethod("nLogon");


                    oSS.InvokeMethod("nSetDate", "S/O", DateTime.Today.ToString("yyyyMMdd"));
                    oSS.InvokeMethod("nSetModule", "A/R");

                    // Set task ID to oSS
                    int TaskID = (int)oSS.InvokeMethod("nLookupTask", "SO_SalesOrder_ui");
                    Core.SageObject.Process(oSS.InvokeMethod("nSetProgram", TaskID), oSS);

                    // Loop through the orders
                    // This saves time over opening the oSS and PVX object over and over again
                    foreach (SalesOrder Order in _salesorders)
                    {
                        if (StatusChanged != null)
                        {
                            StatusChanged(Status.Working, _salesorders.Count(), (_salesorders.FindIndex(a => a == Order) + 1));
                        }

                        // Open object for sales order
                        using (DispatchObject so_order = new DispatchObject(pvx.InvokeMethod("NewObject", "SO_SalesOrder_bus", oSS.GetObject())))
                        {
                            // Get the next salesorder number.
                            object[] oNextSalesOrder = new object[] { "" };
                            Core.SageObject.Process(so_order.InvokeMethodByRef("nGetNextSalesOrderNo", oNextSalesOrder), so_order);
                            Core.SageObject.Process(so_order.InvokeMethod("nSetKey", oNextSalesOrder), so_order);
                            // Update the order objerct to the correct number
                            Order.SalesOrderNo = (string)oNextSalesOrder[0];

                            // Set Customer name and the ARDivision. We always use 00 as the ARDivision
                            Core.SageObject.Process(so_order.InvokeMethod("nSetValue", "ARDivisionNo$", "00"), so_order);

                            if (Core.SageObject.Process(so_order.InvokeMethod("nSetValue", "CustomerNo$", Order.CustomerNo), so_order).ReturnCode == (int)Core.ReturnCode.Failed)
                            {
                                // Could not set this CustomerNo
                                // We'll see if any of the other orders
                                // can process
                                continue;
                            }

                            Core.SageObject.Process(so_order.InvokeMethod("nSetValue", "OrderDate$", Order.OrderDate.ToString("yyyyMMdd")), so_order);
                            Core.SageObject.Process(so_order.InvokeMethod("nSetValue", "ShipExpireDate$", Order.RequiredDate.ToString("yyyyMMdd")), so_order);

                            if (Order.StoreNo != string.Empty)
                            {
                                Core.SageObject.Process(so_order.InvokeMethod("nSetValue", "ShipToCode$", Order.StoreNo), so_order);
                            }

                            if (Order.ShipToZipcode != string.Empty)
                            {
                                Core.SageObject.Process(so_order.InvokeMethod("nSetValue", "ShipToZipcode$", Order.ShipToZipcode), so_order);
                            }

                            if (Order.ShipToName != string.Empty)
                            {
                                Core.SageObject.Process(so_order.InvokeMethod("nSetValue", "ShipToName$", Order.ShipToName), so_order);
                            }

                            if (Order.ShipToAddress1 != string.Empty)
                            {
                                Core.SageObject.Process(so_order.InvokeMethod("nSetValue", "ShipToAddress1$", Order.ShipToAddress1), so_order);
                            }

                            // We want this to override the address in sage, if this is blank
                            Core.SageObject.Process(so_order.InvokeMethod("nSetValue", "ShipToAddress2$", Order.ShipToAddress2), so_order);


                            if (Core.SageObject.Process(so_order.InvokeMethod("nSetValue", "CustomerPONo$", Order.CustomerPONo), so_order).ReturnCode == (int)Core.ReturnCode.SuccessWithError)
                            {
                                // We could trap duplicate PO#s here. The Error Message is:
                                // This customer PO number already exists on one or more sales orders or invoices.
                            }

                            // Eventually move GiftHeader to Comment
                            Core.SageObject.Process(so_order.InvokeMethod("nSetValue", "Comment$", Order.GiftHeader), so_order);

                            // Loop through each lineitem in the order
                            foreach (LineItem Line in Order.LineItems())
                            {
                                // Open object for Line item
                                using (DispatchObject so_line = new DispatchObject(so_order.GetProperty("oLines")))
                                {
                                    Core.SageObject.Process(so_line.InvokeMethod("nAddLine"), so_line);
                                    // Set Item Code
                                    if (Core.SageObject.Process(so_line.InvokeMethod("nSetValue", "ItemCode$", Line.ItemCode), so_line).ReturnCode == (int)Core.ReturnCode.Failed)
                                    {
                                        // Line failed to post. We are going to
                                        // continue to see if any of the lines post.
                                        continue;
                                    }

                                    // Set Quantity
                                    Core.SageObject.Process(so_line.InvokeMethod("nSetValue", "QuantityOrdered", Line.Quantity), so_line);
                                    // Set Monogram
                                    // I only ever need 1000 characters,
                                    // So I always use UDF_PERSONALIZE1

                                    Core.SageObject.Process(so_line.InvokeMethod("nSetValue", "UDF_PERSONALIZE1$", Line.Monogram), so_line);
                                    // Set GiftMessage
                                    Core.SageObject.Process(so_line.InvokeMethod("nSetValue", "UDF_GIFTMESSAGE$", Order.GiftMessage), so_line);

                                    //Set LineKey
                                    object[] oLineKey = new object[] { "LineKey", "" };
                                    Core.SageObject.Process(so_line.InvokeMethodByRef("nGetValue", oLineKey), so_line);
                                    Line.LineKey = oLineKey[1].ToString();

                                    // Set Shipvia
                                    if (Order.Shipvia != string.Empty)
                                    {
                                        Core.SageObject.Process(so_order.InvokeMethod("nSetValue", "ShipVia$", Order.Shipvia), so_order);
                                    }
                                    // Set Descriptions
                                    if (Line.Description != string.Empty)
                                    {
                                        string Description = string.Empty;
                                        // Read Create an object to hold the response
                                        object[] oDescription = new object[] { "ItemCodeDesc$", "" };

                                        // Read Into the object
                                        Core.SageObject.Process(so_line.InvokeMethodByRef("nGetValue", oDescription), so_line);

                                        // Retreive our description
                                        Description = oDescription[1].ToString();

                                        // Append the custom Description text and write the record
                                        Description = Description + Environment.NewLine + Line.Description;
                                        Core.SageObject.Process(so_line.InvokeMethod("nSetValue", "ItemCodeDesc$", Description), so_line);
                                    }

                                    if (Core.SageObject.Process(so_line.InvokeMethod("nWrite"), so_line).ReturnCode == (int)Core.ReturnCode.Failed)
                                    {
                                        continue;
                                    }
                                }
                            }

                            if (Core.SageObject.Process(so_order.InvokeMethod("nWrite"), so_order).ReturnCode == (int)Core.ReturnCode.Failed)
                            {
                                // Order failed to post
                                // Clear the SalesOrderNo because it is not valid.
                                Order.SalesOrderNo = "";
                            }
                            else
                            {
                                if (OrderPosted != null)
                                {
                                    OrderPosted(Order);
                                }
                            }
                        }
                    }

                    if (Completed != null)
                    {
                        Completed(_salesorders);
                    }
                    if (StatusChanged != null)
                    {
                        StatusChanged(Status.Completed, 0, 0);
                    }
                }
            }

            return(_salesorders);
        }