/// <summary>
        /// Main execution function for SaleFlowExecutor
        /// </summary>
        /// <param name="inputData"></param>
        /// <returns></returns>
        private object executorFxn(object inputData)
        {
            if (inputData == null)
            {
                inputData = suspendedState;
            }
            SaleFlowState inputState = (SaleFlowState)inputData;

            switch (inputState)
            {
            case SaleFlowState.ItemSearch:
                if (GlobalDataAccessor.Instance.DesktopSession.ActiveRetail == null)
                {
                    GlobalDataAccessor.Instance.DesktopSession.Sales.Add(new SaleVO());
                    GlobalDataAccessor.Instance.DesktopSession.DescribeItemPawnItemIndex = -1;
                }
                //ItemSearch itemSearchFrm = new ItemSearch();
                if (GlobalDataAccessor.Instance.DesktopSession.HistorySession.HasFormName("ItemSearch"))
                {
                    GlobalDataAccessor.Instance.DesktopSession.HistorySession.VisibleForm("ItemSearch");
                }
                else
                {
                    ShowForm itemSearchBlk = CommonAppBlocks.Instance.CreateItemSearchShowBlock(this.parentForm, this.itemSearchFormNavAction);
                    if (!itemSearchBlk.execute())
                    {
                        throw new ApplicationException("Cannot execute Item Search block");
                    }
                }

                break;

            case SaleFlowState.DescribeMerchandise:
                ShowForm describeMerchBlk = CommonAppBlocks.Instance.DescribeMerchandiseBlock(this.parentForm, this.describeMerchFormAction);
                if (!describeMerchBlk.execute())
                {
                    throw new ApplicationException("Cannot execute Describe Merchandise block");
                }

                break;

            case SaleFlowState.DescribeItem:
                ShowForm describeItemBlk = CommonAppBlocks.Instance.DescribeItemBlock(this.parentForm, this.describeItemFormAction);
                if (!describeItemBlk.execute())
                {
                    throw new ApplicationException("Cannot execute Describe Item Block");
                }
                break;

            case SaleFlowState.LookupCustomer:

                ShowForm lookupCustBlk = CommonAppBlocks.Instance.CreateLookupCustomerShowBlock(this.parentForm, this.lookupCustFormNavAction);
                if (!lookupCustBlk.execute())
                {
                    throw new ApplicationException("Cannot execute LookupCustomer block");
                }

                break;

            case SaleFlowState.LookupCustomerResults:
                ShowForm lookupCustResBlk = CommonAppBlocks.Instance.CreateLookupCustomerResultsBlock(this.parentForm, this.lookupCustResultsFormNavAction);
                if (!lookupCustResBlk.execute())
                {
                    throw new ApplicationException("Cannot execute LookupCustomerResults block");
                }
                break;

            case SaleFlowState.LookupVendorResults:
                ShowForm lookupVendResBlk = CommonAppBlocks.Instance.CreateLookupVendorResultsBlock(this.parentForm, this.lookupVendResultsFormNavAction);
                if (!lookupVendResBlk.execute())
                {
                    throw new ApplicationException("Cannot execute LookupVendorResults block");
                }
                break;

            case SaleFlowState.AddCustomer:
                if (GlobalDataAccessor.Instance.DesktopSession.HistorySession.Trigger.Equals(Commons.TriggerTypes.NEWPAWNLOAN, StringComparison.OrdinalIgnoreCase))
                {
                    ShowForm manageCustBlk = CommonAppBlocks.Instance.CreateManagePawnApplicationBlock(this.parentForm, this.managePawnAppFormNavAction);
                    if (!manageCustBlk.execute())
                    {
                        throw new ApplicationException("Cannot execute Manage Pawn Application block");
                    }
                }
                else
                {
                    ShowForm createCustBlk = CommonAppBlocks.Instance.CreateCreateCustomerBlock(this.parentForm, this.createCustomerFormNavAction);
                    if (!createCustBlk.execute())
                    {
                        throw new ApplicationException("Cannot execute CreateCustomer block");
                    }
                }
                break;

            case SaleFlowState.AddVendor:

                ShowForm createVendBlk = CommonAppBlocks.Instance.CreateCreateVendorBlock(this.parentForm, this.createVendFormNavAction);
                if (!createVendBlk.execute())
                {
                    throw new ApplicationException("Cannot execute Create Vendor block");
                }
                break;

            case SaleFlowState.ExistingCustomer:
                ShowForm existCustBlk = CommonAppBlocks.Instance.CreateExistingCustomerBlock(this.parentForm, this.existCustomerFormNavAction);
                if (!existCustBlk.execute())
                {
                    throw new ApplicationException("Cannot execute ExistingCustomer block");
                }
                break;

            case SaleFlowState.ManagePawnApplication:
                ShowForm managePawnAppBlk = CommonAppBlocks.Instance.CreateManagePawnApplicationBlock(this.parentForm, this.managePawnAppFormNavAction);
                if (!managePawnAppBlk.execute())
                {
                    throw new ApplicationException("Cannot execute ManagePawnApplication block");
                }
                break;

            case SaleFlowState.ViewCustomerInformation:
                ShowForm viewCustInfoBlk = CommonAppBlocks.Instance.ViewCustomerInfoShowBlock(this.parentForm, this.viewCustInfoFormNavAction);
                if (!viewCustInfoBlk.execute())
                {
                    throw new ApplicationException("Cannot execute View Customer Information block");
                }

                break;

            case SaleFlowState.ViewReadOnlyCustomerInformation:
                ShowForm viewCustInfoReadOnlyBlk = CommonAppBlocks.Instance.ViewCustomerInfoShowBlock(this.parentForm, this.viewCustInfoFormNavAction);
                if (!viewCustInfoReadOnlyBlk.execute())
                {
                    throw new ApplicationException("Cannot execute View customer information Read Only block");
                }
                ((ViewCustomerInformation)viewCustInfoReadOnlyBlk.ClassForm).ShowReadOnly = true;
                break;

            case SaleFlowState.TenderIn:
                if (this.tenderInComplete)
                {
                    GlobalDataAccessor.Instance.DesktopSession.HistorySession.Desktop();
                    if (GlobalDataAccessor.Instance.DesktopSession.ActiveRetail.LoanStatus == ProductStatus.LAY)
                    {
                        GlobalDataAccessor.Instance.DesktopSession.showProcessTender(ProcessTenderProcedures.ProcessTenderMode.LAYAWAY);
                    }
                    else
                    {
                        ProcessTenderController pCntrl = ProcessTenderController.Instance;
                        //Perform the process tender process
                        bool success = pCntrl.ExecuteProcessTender(ProcessTenderProcedures.ProcessTenderMode.RETAILSALE);
                        if (success)
                        {
                            ReceiptConfirmation rcptConf = new ReceiptConfirmation();
                            rcptConf.ShowDialog();
                        }
                        else
                        {
                            goto case SaleFlowState.CancelFlow;
                        }
                    }

                    goto case SaleFlowState.CancelFlow;
                }
                else
                {
                    if (GlobalDataAccessor.Instance.DesktopSession.HistorySession.Lookup("TenderIn"))
                    {
                        GlobalDataAccessor.Instance.DesktopSession.HistorySession.VisibleForm("TenderIn");
                    }
                    else
                    {
                        ShowForm tenderInBlk = CommonAppBlocks.Instance.TenderInShowBlock(this.parentForm, this.TenderInFormAction);
                        if (!tenderInBlk.execute())
                        {
                            throw new ApplicationException("Cannot execute Tender In block");
                        }
                    }
                }

                break;

            case SaleFlowState.CancelFlow:
                GlobalDataAccessor.Instance.DesktopSession.ClearCustomerList();
                GlobalDataAccessor.Instance.DesktopSession.ClearLoggedInUser();
                GlobalDataAccessor.Instance.DesktopSession.ClearSessionData();
                if (this.endStateNotifier != null)
                {
                    this.endStateNotifier.execute();
                }
                break;

            case SaleFlowState.ExitFlow:
                break;

            default:
                throw new ApplicationException("Invalid sale flow state");
            }

            return(true);
        }
        private void TenderInFormAction(object sender, object data)
        {
            if (sender == null || data == null)
            {
                throw new ApplicationException("Tender In form navigation action handler received invalid data");
            }
            NavBox   tenderNavBox = (NavBox)sender;
            TenderIn tenderForm   = (TenderIn)data;

            NavBox.NavAction action = tenderNavBox.Action;
            if (action == NavBox.NavAction.BACKANDSUBMIT)
            {
                GlobalDataAccessor.Instance.DesktopSession.HistorySession.Back();
                action = NavBox.NavAction.SUBMIT;
            }

            switch (action)
            {
            case NavBox.NavAction.SUBMIT:
                if (tenderNavBox.IsCustom)
                {
                    string custDet = tenderNavBox.CustomDetail;
                    if (custDet.Equals("ProcessTender"))
                    {
                        GlobalDataAccessor.Instance.DesktopSession.HistorySession.Desktop();
                        if (GlobalDataAccessor.Instance.DesktopSession.ActiveRetail.LoanStatus == ProductStatus.LAY)
                        {
                            GlobalDataAccessor.Instance.DesktopSession.showProcessTender(ProcessTenderProcedures.ProcessTenderMode.LAYAWAY);
                        }
                        else
                        {
                            var pCntrl = ProcessTenderController.Instance;
                            //Perform the process tender process
                            bool success = pCntrl.ExecuteProcessTender(ProcessTenderProcedures.ProcessTenderMode.RETAILSALE);
                            if (success)
                            {
                                ReceiptConfirmation rcptConf = new ReceiptConfirmation();
                                rcptConf.ShowDialog();
                            }
                            else
                            {
                                this.nextState = SaleFlowState.CancelFlow;
                            }
                        }
                        this.nextState = SaleFlowState.CancelFlow;
                    }
                    else if (custDet.Equals("LookupCustomer"))
                    {
                        this.tenderInComplete = true;
                        this.nextState        = SaleFlowState.LookupCustomer;
                    }
                    else
                    {
                        this.nextState = SaleFlowState.CancelFlow;
                    }
                }
                else
                {
                    GlobalDataAccessor.Instance.DesktopSession.CompleteSale    = false;
                    GlobalDataAccessor.Instance.DesktopSession.CompleteLayaway = false;
                    this.nextState = SaleFlowState.ItemSearch;
                }
                break;

            case NavBox.NavAction.HIDEANDSHOW:
                tenderForm.Hide();
                if (tenderNavBox.IsCustom)
                {
                    string custDet = tenderNavBox.CustomDetail;
                    this.nextState = custDet.Equals("LookupCustomer") ? SaleFlowState.LookupCustomer : SaleFlowState.CancelFlow;
                }
                break;

            case NavBox.NavAction.CANCEL:
                this.nextState = SaleFlowState.CancelFlow;
                break;

            default:
                throw new ApplicationException("" + action + " is not a valid state for Tender In");
            }
            this.executeNextState();
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ProcessTender_Load(object sender, EventArgs e)
        {
            ProcessTenderController pCntrl = ProcessTenderController.Instance;

            //Perform the process tender process
            this.loanTicketGroup.Visible = true;
            this.success = pCntrl.ExecuteProcessTender(procTendMode);
            this.Update();
            switch (this.procTendMode)
            {
            case ProcessTenderProcedures.ProcessTenderMode.NEWLOAN:
                if (!this.success ||
                    CollectionUtilities.isEmpty(pCntrl.TicketFiles))
                {
                    MessageBox.Show(
                        "New loan process tender failed.  \n" +
                        "Please call Shop System Support.  \n" +
                        "The loan number is: " + ProcessTenderController.Instance.TicketNumber,
                        "Application Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Stop);
                    GlobalDataAccessor.Instance.DesktopSession.ClearPawnLoan();
                    NewDesktop nDesk =
                        (NewDesktop)GlobalDataAccessor.Instance.DesktopSession.HistorySession.Desktop();
                    nDesk.handleEndFlow(null);
                }
                else
                {
                    this.okButton.Enabled = true;
                    //Update the labels
                    this.setProcessTenderDetails(
                        GlobalDataAccessor.Instance.DesktopSession.ActiveCustomer.FirstName,
                        GlobalDataAccessor.Instance.DesktopSession.ActiveCustomer.LastName,
                        String.Format("{0:C}", GlobalDataAccessor.Instance.DesktopSession.ActivePawnLoan.Amount));

                    //Update the list box
                    for (int cnt = 1;
                         cnt <= ProcessTenderController.Instance.TicketFiles.Count;
                         ++cnt)
                    {
                        string s = ProcessTenderController.Instance.TicketFiles[cnt - 1];
                        if (string.IsNullOrEmpty(s))
                        {
                            continue;
                        }
                        string ticketDesc = "Loan #" +
                                            ProcessTenderController.Instance.TicketNumber + "[" +
                                            cnt + "]";
                        this.loanDocListView.Items.Add(new ListViewItem(ticketDesc, 0));
                    }
                    this.loanDocListView.Update();
                    this.Update();
                }
                break;

            case ProcessTenderProcedures.ProcessTenderMode.SERVICELOAN:

                if (!this.success)
                {
                    MessageBox.Show(
                        "Servicing loan process failed.  \n" +
                        "Please call Shop System Support.  \n",
                        "Application Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Stop);
                    GlobalDataAccessor.Instance.DesktopSession.ClearPawnLoan();
                    NewDesktop nDesk =
                        (NewDesktop)GlobalDataAccessor.Instance.DesktopSession.HistorySession.Desktop();
                    nDesk.handleEndFlow(null);
                }
                else
                {
                    if (GlobalDataAccessor.Instance.DesktopSession.TotalServiceAmount > 0)
                    {
                        this.initialProcessTenderLabel.Text = "Received From Customer:";
                    }
                    else
                    {
                        this.initialProcessTenderLabel.Text = "Cash to Customer:";
                    }
                    this.okButton.Enabled = true;
                    this.setProcessTenderDetails(
                        GlobalDataAccessor.Instance.DesktopSession.ActiveCustomer.FirstName,
                        GlobalDataAccessor.Instance.DesktopSession.ActiveCustomer.LastName,
                        String.Format("{0:C}", GlobalDataAccessor.Instance.DesktopSession.TotalServiceAmount));
                    for (int cnt = 0;
                         cnt < ProcessTenderController.Instance.ProcessedTickets.Count;
                         cnt++)
                    {
                        var    ticketData = ProcessTenderController.Instance.ProcessedTickets[cnt];
                        string s          = ticketData.Right.ToString();
                        if (string.IsNullOrEmpty(s))
                        {
                            continue;
                        }
                        string ticketDesc = "Loan #" +
                                            ticketData.Left.ToString() + "[" +
                                            cnt + 1 + "]";
                        this.loanDocListView.Items.Add(new ListViewItem(ticketDesc, 0));
                    }
                    this.loanDocListView.Update();
                    this.Update();
                    //this.loanTicketGroup.Visible = false;
                    //this.loanDocListView.Visible = false;
                    //this.Update();
                }
                break;

            case ProcessTenderProcedures.ProcessTenderMode.VOIDLOAN:
                //Shouldn't be here for void loan
                break;

            case ProcessTenderProcedures.ProcessTenderMode.PURCHASE:
                if (!this.success)
                {
                    MessageBox.Show(
                        "Purchase process failed.  \n" +
                        "Please call Shop System Support.  \n",
                        "Application Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Stop);
                    GlobalDataAccessor.Instance.DesktopSession.ClearPawnLoan();
                    NewDesktop nDesk =
                        (NewDesktop)GlobalDataAccessor.Instance.DesktopSession.HistorySession.Desktop();
                    nDesk.handleEndFlow(null);
                }
                else
                {
                    this.okButton.Enabled = true;
                    this.setProcessTenderDetails(
                        GlobalDataAccessor.Instance.DesktopSession.ActiveCustomer.FirstName,
                        GlobalDataAccessor.Instance.DesktopSession.ActiveCustomer.LastName,
                        String.Format("{0:C}", GlobalDataAccessor.Instance.DesktopSession.ActivePurchase.Amount));
                    string ticketDesc = "Purchase #" +
                                        GlobalDataAccessor.Instance.DesktopSession.ActivePurchase.TicketNumber;
                    this.loanDocListView.Items.Add(new ListViewItem(ticketDesc, 0));
                    this.Update();
                }
                break;

            case ProcessTenderProcedures.ProcessTenderMode.VENDORPURCHASE:
                if (!this.success)
                {
                    MessageBox.Show(
                        "Purchase process failed.  \n" +
                        "Please call Shop System Support.  \n",
                        "Application Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Stop);
                    GlobalDataAccessor.Instance.DesktopSession.ClearPawnLoan();
                    NewDesktop nDesk =
                        (NewDesktop)GlobalDataAccessor.Instance.DesktopSession.HistorySession.Desktop();
                    nDesk.handleEndFlow(null);
                }
                else
                {
                    this.okButton.Enabled = true;
                    this.setProcessTenderDetails(
                        GlobalDataAccessor.Instance.DesktopSession.ActiveVendor.Name,
                        "",
                        String.Format("{0:C}", GlobalDataAccessor.Instance.DesktopSession.ActivePurchase.Amount));
                    string ticketDesc = "Vendor Purchase #" +
                                        GlobalDataAccessor.Instance.DesktopSession.ActivePurchase.TicketNumber;
                    this.loanDocListView.Items.Add(new ListViewItem(ticketDesc, 0));
                    this.Update();
                }
                break;

            case ProcessTenderProcedures.ProcessTenderMode.RETURNBUY:
                if (!this.success)
                {
                    MessageBox.Show(
                        "Purchase process failed.  \n" +
                        "Please call Shop System Support.  \n",
                        "Application Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Stop);
                    GlobalDataAccessor.Instance.DesktopSession.ClearPawnLoan();
                    NewDesktop nDesk =
                        (NewDesktop)GlobalDataAccessor.Instance.DesktopSession.HistorySession.Desktop();
                    nDesk.handleEndFlow(null);
                }
                else
                {
                    initialProcessTenderLabel.Text = "Received From Customer:";

                    this.okButton.Enabled = true;
                    this.setProcessTenderDetails(
                        GlobalDataAccessor.Instance.DesktopSession.ActiveCustomer.FirstName,
                        GlobalDataAccessor.Instance.DesktopSession.ActiveCustomer.LastName,
                        String.Format("{0:C}", (from item in GlobalDataAccessor.Instance.DesktopSession.ActivePurchase.Items
                                                select item.ItemAmount).Sum()));
                    string ticketDesc = "Return #" +
                                        GlobalDataAccessor.Instance.DesktopSession.ActivePurchase.TicketNumber;
                    this.loanDocListView.Items.Add(new ListViewItem(ticketDesc, 0));
                    this.Update();
                }
                break;

            case ProcessTenderProcedures.ProcessTenderMode.RETURNSALE:
                if (!this.success)
                {
                    MessageBox.Show(
                        "Refund process failed.  \n" +
                        "Please call Shop System Support.  \n",
                        "Application Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Stop);
                    GlobalDataAccessor.Instance.DesktopSession.ClearPawnLoan();
                    NewDesktop nDesk =
                        (NewDesktop)GlobalDataAccessor.Instance.DesktopSession.HistorySession.Desktop();
                    nDesk.handleEndFlow(null);
                }
                else
                {
                    this.okButton.Enabled = true;
                    this.setProcessTenderDetails(
                        string.IsNullOrEmpty(GlobalDataAccessor.Instance.DesktopSession.ActiveRetail.CustomerNumber) ?
                        GlobalDataAccessor.Instance.DesktopSession.ActiveRetail.EntityName :
                        GlobalDataAccessor.Instance.DesktopSession.ActiveRetail.CustomerNumber == "0" ?
                        GlobalDataAccessor.Instance.DesktopSession.ActiveCustomer.CustomerName :
                        GlobalDataAccessor.Instance.DesktopSession.ActiveRetail.EntityName,
                        "",
                        String.Format("{0:C}", GlobalDataAccessor.Instance.DesktopSession.ActiveRetail.TotalSaleAmount));
                    string ticketDesc = "Refund Ticket #" +
                                        GlobalDataAccessor.Instance.DesktopSession.ActiveRetail.TicketNumber;
                    this.loanDocListView.Items.Add(new ListViewItem(ticketDesc, 0));
                    this.Update();
                }
                break;

            case ProcessTenderProcedures.ProcessTenderMode.LAYAWAY:
                if (!this.success)
                {
                    MessageBox.Show(
                        "Layaway process failed.  \n" +
                        "Please call Shop System Support.  \n",
                        "Application Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Stop);
                    GlobalDataAccessor.Instance.DesktopSession.ClearPawnLoan();
                    NewDesktop nDesk =
                        (NewDesktop)GlobalDataAccessor.Instance.DesktopSession.HistorySession.Desktop();
                    nDesk.handleEndFlow(null);
                }
                else
                {
                    initialProcessTenderLabel.Text = "Received From Customer:";

                    this.okButton.Enabled = true;

                    this.setProcessTenderDetails(
                        GlobalDataAccessor.Instance.DesktopSession.ActiveCustomer.FirstName,
                        GlobalDataAccessor.Instance.DesktopSession.ActiveCustomer.LastName,
                        String.Format("{0:C}", GlobalDataAccessor.Instance.DesktopSession.ActiveLayaway.TotalSaleAmount));
                    string ticketDesc = "Layaway Ticket #" +
                                        GlobalDataAccessor.Instance.DesktopSession.ActiveLayaway.TicketNumber;
                    this.loanDocListView.Items.Add(new ListViewItem(ticketDesc, 0));
                    this.Update();
                }
                break;

            case ProcessTenderProcedures.ProcessTenderMode.LAYPAYMENT:
                if (!this.success)
                {
                    MessageBox.Show(
                        "Layaway payment process failed.  \n" +
                        "Please call Shop System Support.  \n",
                        "Application Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Stop);
                    GlobalDataAccessor.Instance.DesktopSession.ClearPawnLoan();
                    NewDesktop nDesk =
                        (NewDesktop)GlobalDataAccessor.Instance.DesktopSession.HistorySession.Desktop();
                    nDesk.handleEndFlow(null);
                }
                else
                {
                    initialProcessTenderLabel.Text = "Received From Customer:";

                    this.okButton.Enabled = true;
                    this.setProcessTenderDetails(
                        GlobalDataAccessor.Instance.DesktopSession.ActiveCustomer.FirstName,
                        GlobalDataAccessor.Instance.DesktopSession.ActiveCustomer.LastName,
                        String.Format("{0:C}", GlobalDataAccessor.Instance.DesktopSession.TotalServiceAmount));
                    this.loanTicketGroup.Visible = false;
                    this.Update();
                    ReceiptConfirmation rcptConf = new ReceiptConfirmation();
                    rcptConf.ShowDialog();
                    this.Close();
                }
                break;

            case ProcessTenderProcedures.ProcessTenderMode.LAYPAYMENTREF:
                if (!this.success)
                {
                    MessageBox.Show(
                        "Layaway payment refund process failed.  \n" +
                        "Please call Shop System Support.  \n",
                        "Application Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Stop);
                    GlobalDataAccessor.Instance.DesktopSession.ClearPawnLoan();
                    NewDesktop nDesk =
                        (NewDesktop)GlobalDataAccessor.Instance.DesktopSession.HistorySession.Desktop();
                    nDesk.handleEndFlow(null);
                }
                else
                {
                    decimal totalAmt = GlobalDataAccessor.Instance.DesktopSession.TenderAmounts.Sum(s => Utilities.GetDecimalValue(s, 0));

                    this.okButton.Enabled = true;
                    this.setProcessTenderDetails(
                        CashlinxDesktopSession.Instance.ActiveCustomer.FirstName,
                        CashlinxDesktopSession.Instance.ActiveCustomer.LastName,
                        String.Format("{0:C}", totalAmt));
                    this.loanTicketGroup.Visible = false;
                    this.Update();

                    DisbursementConfirmation rcptConf = new DisbursementConfirmation();
                    rcptConf.ShowDialog();
                    this.Close();
                }
                break;

            default:
                throw new ArgumentOutOfRangeException(this.procTendMode.ToString());
            }
        }