public static OrderResult SubmitCustomerOrder(string contractId, OrderItem[] orderItems, KeyValueBunch extraArgs)
        {
            //
            Contract contract = ContractSystem.ContractController.GetContract(contractId);

            // Impersonate
            ContractSystem.ContractController.ImpersonateAsContractReseller(contract);
            //
            OrderResult oResult = new OrderResult();
            // check account
            SecurityResult sResult = StorehouseController.CheckAccountActive();

            //
            if (!sResult.Success)
            {
                //
                oResult.Succeed = false;
                //
                oResult.ResultCode = sResult.ResultCode;
                //
                return(oResult);
            }
            // check order items not empty
            if (orderItems == null || orderItems.Length == 0)
            {
                //
                oResult.Succeed = false;
                //
                oResult.ResultCode = EMPTY_ORDER_ITEMS_CODE;
                //
                return(oResult);
            }
            //
            ES.TaskManager.StartTask("Storefront", "SUBMIT_CUSTOMER_ORDER");

            //
            try
            {
                string currency = StorehouseController.GetBaseCurrency(contract.ResellerId);
                // ordered services
                List <int> orderedSvcs = new List <int>();
                // build services to be ordered
                for (int i = 0; i < orderItems.Length; i++)
                {
                    //
                    OrderItem orderItem = orderItems[i];
                    //
                    int orderedSvcId = 0;
                    //
                    orderItem.ParentSvcId = (orderItem.ParentIndex > -1) ? orderedSvcs[orderItem.ParentIndex] : orderItem.ParentSvcId;
                    // load svc type
                    ProductType svcType = StorehouseController.GetProductType(orderItem.TypeId);
                    //
                    IServiceProvisioning controller = (IServiceProvisioning)Activator.CreateInstance(
                        Type.GetType(svcType.ProvisioningController));
                    // add service
                    orderedSvcId = controller.AddServiceInfo(contractId, currency, orderItem);
                    // check service controller result
                    if (orderedSvcId < 1)
                    {
                        // ROLLBACK HERE
                        StorehouseController.BulkServiceDelete(contractId, orderedSvcs.ToArray());
                        oResult.Succeed    = false;
                        oResult.ResultCode = orderedSvcId;
                        return(oResult);
                        // EXIT
                    }
                    //
                    orderedSvcs.Add(orderedSvcId);
                }
                // build invoice lines
                List <InvoiceItem> invoiceLines = InvoiceController.CalculateInvoiceLinesForServices(orderedSvcs);
                //
                int resultCode = InvoiceController.AddInvoice(contractId, invoiceLines, extraArgs);
                // ERROR
                if (resultCode < 1)
                {
                    // ROLLBACK HERE
                    StorehouseController.BulkServiceDelete(contractId, orderedSvcs.ToArray());
                    oResult.Succeed    = false;
                    oResult.ResultCode = resultCode;
                    return(oResult);
                }
                //
                oResult.OrderInvoice = resultCode;
                //
                oResult.Succeed = true;
            }
            catch (Exception ex)
            {
                //
                oResult.ResultCode = -1;
                //
                oResult.Succeed = false;
                //
                ES.TaskManager.WriteError(ex);
            }
            finally
            {
                //
                ES.TaskManager.CompleteTask();
            }
            //
            return(oResult);
        }
        public void InvoiceActiveServices()
        {
            DateTime dateTimeNow = DateTime.Now;
            // load store settings
            StoreSettings settings = StorehouseController.GetStoreSettings(SecurityContext.User.UserId,
                                                                           StoreSettings.SYSTEM_SETTINGS);
            //
            int threshold = Convert.ToInt32(settings["SvcInvoiceThreshold"]);
            // get expiring services today
            List <Service> services = ServiceController.GetServicesToInvoice(SecurityContext.User.UserId,
                                                                             dateTimeNow, threshold);
            // group services by users
            Dictionary <string, List <int> > usersServices = new Dictionary <string, List <int> >();

            // iterate
            foreach (Service service in services)
            {
                if (!usersServices.ContainsKey(service.ContractId))
                {
                    usersServices.Add(service.ContractId, new List <int>());
                }

                usersServices[service.ContractId].Add(service.ServiceId);
            }
            // generate invoice per contract
            foreach (string contractId in usersServices.Keys)
            {
                try
                {
                    TaskManager.Write("Creating invoice");
                    // TRACE
                    Contract        contract = ContractSystem.ContractController.GetContract(contractId);
                    ContractAccount account  = ContractSystem.ContractController.GetContractAccountSettings(contractId);
                    TaskManager.WriteParameter("ContractID", contractId);
                    TaskManager.WriteParameter("Username", account[ContractAccount.USERNAME]);
                    //
                    List <int> userSvcs = usersServices[contractId];
                    // build invoice items
                    List <InvoiceItem> invoiceLines = InvoiceController.CalculateInvoiceLinesForServices(userSvcs);
                    //
                    int resultCode = InvoiceController.AddInvoice(contractId, invoiceLines, null);
                    //
                    if (resultCode < 1)
                    {
                        TaskManager.WriteParameter("ResultCode", resultCode);
                        continue;
                    }
                    //
                    if (ServiceController.SetUsageRecordsClosed(userSvcs.ToArray()) != 0)
                    {
                        TaskManager.WriteWarning("Unable to close usage records automatically");
                    }
                    // TRACE
                    TaskManager.WriteParameter("InvoiceID", resultCode);
                    TaskManager.Write("Succeed");
                }
                catch (Exception ex)
                {
                    TaskManager.WriteError(ex);
                }
            }
        }