Example #1
0
        private void Page_Load(object sender, System.EventArgs e)
        {
            litPageTitle.Text = L10n.Term("ProductTemplates.LBL_LIST_FORM_TITLE");
            try
            {
                DbProviderFactory dbf = DbProviderFactories.GetFactory();
                using (IDbConnection con = dbf.CreateConnection())
                {
                    string sSQL;
                    sSQL = "select *                       " + ControlChars.CrLf
                           + "  from vwPRODUCT_TEMPLATES_List" + ControlChars.CrLf
                           + " where 1 = 1                   " + ControlChars.CrLf;
                    using (IDbCommand cmd = con.CreateCommand())
                    {
                        cmd.CommandText = sSQL;
                        ctlSearch.SqlSearchClause(cmd);
#if DEBUG
                        Page.RegisterClientScriptBlock("SQLCode", Sql.ClientScriptBlock(cmd));
#endif
                        using (DbDataAdapter da = dbf.CreateDataAdapter())
                        {
                            ((IDbDataAdapter)da).SelectCommand = cmd;
                            using (DataTable dt = new DataTable())
                            {
                                da.Fill(dt);
                                foreach (DataRow row in dt.Rows)
                                {
                                    row["STATUS"]            = L10n.Term(".product_template_status_dom.", row["STATUS"]);
                                    row["COST_USDOLLAR"]     = C10n.ToCurrency(Sql.ToFloat(row["COST_USDOLLAR"]));
                                    row["LIST_USDOLLAR"]     = C10n.ToCurrency(Sql.ToFloat(row["LIST_USDOLLAR"]));
                                    row["DISCOUNT_USDOLLAR"] = C10n.ToCurrency(Sql.ToFloat(row["DISCOUNT_USDOLLAR"]));
                                }

                                vwMain             = dt.DefaultView;
                                grdMain.DataSource = vwMain;
                                if (!IsPostBack)
                                {
                                    grdMain.SortColumn = "NAME";
                                    grdMain.SortOrder  = "asc";
                                    grdMain.ApplySort();
                                    grdMain.DataBind();
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                SplendidError.SystemError(new StackTrace(true).GetFrame(0), ex.Message);
                lblError.Text = ex.Message;
            }
            if (!IsPostBack)
            {
                Page.DataBind();
            }
        }
        // 01/05/2007 Paul.  We need to update the totals before saving.
        public void UpdateTotals()
        {
            Double dSUBTOTAL = 0.0;
            Double dDISCOUNT = new DynamicControl(this, "DISCOUNT").FloatValue;
            Double dSHIPPING = new DynamicControl(this, "SHIPPING").FloatValue;
            Double dTAX      = 0.0;
            Double dTOTAL    = 0.0;
            double dTAX_RATE = 0.0;

            DataTable dtTAX_RATE = SplendidCache.TaxRates();

            if (!Sql.IsEmptyGuid(TAXRATE_ID.SelectedValue))
            {
                DataRow[] row = dtTAX_RATE.Select("ID = '" + TAXRATE_ID.SelectedValue + "'");
                if (row.Length == 1)
                {
                    dTAX_RATE = Sql.ToDouble(row[0]["VALUE"]) / 100;
                }
            }
            foreach (DataRow row in dtLineItems.Rows)
            {
                if (row.RowState != DataRowState.Deleted)
                {
                    // 08/11/2007 Paul.  Allow an item to be manually added.  Require either a product ID or a name.
                    if (!Sql.IsEmptyString(row["NAME"]) || !Sql.IsEmptyGuid(row["PRODUCT_TEMPLATE_ID"]))
                    {
                        string sLINE_ITEM_TYPE = Sql.ToString(row["LINE_ITEM_TYPE"]);
                        string sTAX_CLASS      = Sql.ToString(row["TAX_CLASS"]);
                        int    nQUANTITY       = Sql.ToInteger(row["QUANTITY"]);
                        Double dUNIT_PRICE     = Sql.ToDouble(row["UNIT_PRICE"]);
                        if (sLINE_ITEM_TYPE != "Comment")
                        {
                            dSUBTOTAL += dUNIT_PRICE * nQUANTITY;
                            if (sTAX_CLASS == "Taxable")
                            {
                                dTAX += dUNIT_PRICE * nQUANTITY * dTAX_RATE;
                            }
                        }
                    }
                }
            }
            dTOTAL        = dSUBTOTAL - dDISCOUNT + dTAX + dSHIPPING;
            SUBTOTAL.Text = Convert.ToDecimal(dSUBTOTAL).ToString("c");
            DISCOUNT.Text = Convert.ToDecimal(dDISCOUNT).ToString("0.00");
            SHIPPING.Text = Convert.ToDecimal(dSHIPPING).ToString("0.00");
            TAX.Text      = Convert.ToDecimal(dTAX).ToString("c");
            TOTAL.Text    = Convert.ToDecimal(dTOTAL).ToString("c");
            // 03/31/2007 Paul.  We are using UNIT_PRICE, so the value will need to be converted to USD before stored in hidden fields.
            DISCOUNT_USDOLLAR.Value = C10n.FromCurrency(Convert.ToDecimal(dDISCOUNT)).ToString("0.000");
            SHIPPING_USDOLLAR.Value = C10n.FromCurrency(Convert.ToDecimal(dSHIPPING)).ToString("0.000");
        }
        private void UpdateTotals()
        {
            Double dALLOCATED = 0.0;

            foreach (DataRow row in dtLineItems.Rows)
            {
                if (row.RowState != DataRowState.Deleted)
                {
                    Double dAMOUNT = Sql.ToDouble(row["AMOUNT"]);
                    dALLOCATED += dAMOUNT;
                }
            }
            ALLOCATED.Text           = Convert.ToDecimal(dALLOCATED).ToString("c");
            ALLOCATED_USDOLLAR.Value = C10n.FromCurrency(Convert.ToDecimal(dALLOCATED)).ToString("0.000");
        }
        protected void grdMain_RowUpdating(object sender, GridViewUpdateEventArgs e)
        {
            if (dtLineItems != null)
            {
                GridViewRow gr = grdMain.Rows[e.RowIndex];
                TextBox     txtINVOICE_NAME    = gr.FindControl("INVOICE_NAME") as TextBox;
                HiddenField txtINVOICE_ID      = gr.FindControl("INVOICE_ID") as HiddenField;
                TextBox     txtAMOUNT          = gr.FindControl("AMOUNT") as TextBox;
                HiddenField txtAMOUNT_USDOLLAR = gr.FindControl("AMOUNT_USDOLLAR") as HiddenField;

                DataRow row = dtLineItems.Rows[e.RowIndex];
                // 03/31/2007 Paul.  The US Dollar values are computed from the price and are only used when changing currencies.
                if (txtINVOICE_NAME != null)
                {
                    row["INVOICE_NAME"] = txtINVOICE_NAME.Text;
                }
                if (txtINVOICE_ID != null)
                {
                    row["INVOICE_ID"] = Sql.ToGuid(txtINVOICE_ID.Value);
                }
                if (txtAMOUNT != null)
                {
                    row["AMOUNT"] = Sql.ToDecimal(txtAMOUNT.Text);
                }

                row["AMOUNT_USDOLLAR"] = C10n.FromCurrency(Sql.ToDecimal(txtAMOUNT.Text));

                DataRow[] aCurrentRows = dtLineItems.Select(String.Empty, String.Empty, DataViewRowState.CurrentRows);
                // 03/30/2007 Paul.  Always allow editing of the last empty row. Add blank row if necessary.
                if (aCurrentRows.Length == 0 || !Sql.IsEmptyString(aCurrentRows[aCurrentRows.Length - 1]["INVOICE_NAME"]))
                {
                    DataRow rowNew = dtLineItems.NewRow();
                    dtLineItems.Rows.Add(rowNew);
                    aCurrentRows = dtLineItems.Select(String.Empty, String.Empty, DataViewRowState.CurrentRows);
                }

                ViewState["LineItems"] = dtLineItems;
                grdMain.DataSource     = dtLineItems;
                // 03/30/2007 Paul.  Make sure to use the last row of the current set, not the total rows of the table.  Some rows may be deleted.
                grdMain.EditIndex = aCurrentRows.Length - 1;
                grdMain.DataBind();
                UpdateTotals();
            }
        }
        public void CURRENCY_ID_Changed(object sender, System.EventArgs e)
        {
            // 03/31/2007 Paul.  When the currency changes, use the default exchange rate.
            Guid gCURRENCY_ID = Sql.ToGuid(CURRENCY_ID.SelectedValue);

            SetC10n(gCURRENCY_ID);
            EXCHANGE_RATE.Value = C10n.CONVERSION_RATE.ToString();

            foreach (DataRow row in dtLineItems.Rows)
            {
                if (row.RowState != DataRowState.Deleted)
                {
                    row["AMOUNT"] = C10n.ToCurrency(Sql.ToDecimal(row["AMOUNT_USDOLLAR"]));
                }
            }
            grdMain.DataBind();

            UpdateTotals();
        }
        protected void CURRENCY_ID_Changed(object sender, System.EventArgs e)
        {
            // 03/31/2007 Paul.  When the currency changes, use the default exchange rate.
            Guid gCURRENCY_ID = Sql.ToGuid(CURRENCY_ID.SelectedValue);

            SetC10n(gCURRENCY_ID);
            EXCHANGE_RATE.Text = C10n.CONVERSION_RATE.ToString();

            DISCOUNT.Text = C10n.ToCurrency(Sql.ToDecimal(DISCOUNT_USDOLLAR.Value)).ToString("0.00");
            SHIPPING.Text = C10n.ToCurrency(Sql.ToDecimal(SHIPPING_USDOLLAR.Value)).ToString("0.00");
            foreach (DataRow row in dtLineItems.Rows)
            {
                if (row.RowState != DataRowState.Deleted)
                {
                    row["COST_PRICE"]     = C10n.ToCurrency(Sql.ToDecimal(row["COST_USDOLLAR"]));
                    row["LIST_PRICE"]     = C10n.ToCurrency(Sql.ToDecimal(row["LIST_USDOLLAR"]));
                    row["UNIT_PRICE"]     = C10n.ToCurrency(Sql.ToDecimal(row["UNIT_USDOLLAR"]));
                    row["EXTENDED_PRICE"] = C10n.ToCurrency(Sql.ToDecimal(row["EXTENDED_USDOLLAR"]));
                }
            }
            grdMain.DataBind();

            UpdateTotals();
        }
        public void LoadLineItems(Guid gID, Guid gDuplicateID, IDbConnection con, IDataReader rdr)
        {
            if (!IsPostBack)
            {
                GetCurrencyControl();
                try
                {
                    // 03/15/2007 Paul.  Set the default currency to the current user currency.
                    CURRENCY_ID.SelectedValue = C10n.ID.ToString();
                    EXCHANGE_RATE.Value       = C10n.CONVERSION_RATE.ToString();
                }
                catch
                {
                }
                foreach (DataControlField col in grdMain.Columns)
                {
                    if (!Sql.IsEmptyString(col.HeaderText))
                    {
                        col.HeaderText = L10n.Term(col.HeaderText);
                    }
                    CommandField cf = col as CommandField;
                    if (cf != null)
                    {
                        cf.EditText   = L10n.Term(cf.EditText);
                        cf.DeleteText = L10n.Term(cf.DeleteText);
                        cf.UpdateText = L10n.Term(cf.UpdateText);
                        cf.CancelText = L10n.Term(cf.CancelText);
                    }
                }

                if ((!Sql.IsEmptyGuid(gID) || !Sql.IsEmptyGuid(gDuplicateID)) && (con != null) && (rdr != null))
                {
                    try
                    {
                        CURRENCY_ID.SelectedValue = Sql.ToString(rdr["CURRENCY_ID"]);
                        // 05/26/2007 Paul.  Make sure to update the exchange rate.
                        EXCHANGE_RATE.Value = C10n.CONVERSION_RATE.ToString();
                    }
                    catch
                    {
                    }
                    // 03/31/2007 Paul.  The exchange rate might be an old value.
                    float fEXCHANGE_RATE = Sql.ToFloat(rdr["EXCHANGE_RATE"]);
                    if (fEXCHANGE_RATE == 0.0f)
                    {
                        fEXCHANGE_RATE = 1.0f;
                    }
                    EXCHANGE_RATE.Value = fEXCHANGE_RATE.ToString();
                    if (CURRENCY_ID.Items.Count > 0)
                    {
                        // 03/31/2007 Paul.  Replace the user currency with the form currency, but use the old exchange rate.
                        Guid gCURRENCY_ID = Sql.ToGuid(CURRENCY_ID.SelectedValue);
                        SetC10n(gCURRENCY_ID, fEXCHANGE_RATE);
                        EXCHANGE_RATE.Value = C10n.CONVERSION_RATE.ToString();
                    }
                    // 05/26/2007 Paul.  ALLOCATED field is not returned, just TOTAL_ALLOCATED_USDOLLAR.
                    // Don't convert TOTAL_ALLOCATED_USDOLLAR in the hidden variable.
                    ALLOCATED.Text           = C10n.ToCurrency(Sql.ToDecimal(rdr["TOTAL_ALLOCATED_USDOLLAR"])).ToString("c");
                    ALLOCATED_USDOLLAR.Value = Sql.ToDecimal(rdr["TOTAL_ALLOCATED_USDOLLAR"]).ToString("0.00");
                    rdr.Close();

                    string sSQL;
                    sSQL = "select *                  " + ControlChars.CrLf
                           + "  from vwPAYMENTS_INVOICES" + ControlChars.CrLf
                           + " where 1 = 1              " + ControlChars.CrLf;
                    using (IDbCommand cmd = con.CreateCommand())
                    {
                        cmd.CommandText = sSQL;
                        Sql.AppendParameter(cmd, gID, "PAYMENT_ID", false);
                        cmd.CommandText += " order by DATE_MODIFIED asc" + ControlChars.CrLf;

                        if (bDebug)
                        {
                            RegisterClientScriptBlock("vwPAYMENTS_INVOICES", Sql.ClientScriptBlock(cmd));
                        }

                        DbProviderFactory dbf = DbProviderFactories.GetFactory();
                        using (DbDataAdapter da = dbf.CreateDataAdapter())
                        {
                            ((IDbDataAdapter)da).SelectCommand = cmd;
                            dtLineItems = new DataTable();
                            da.Fill(dtLineItems);

                            // 04/01/2007 Paul.  If we are duplicating a quote, then we must create new IDs for the line items.
                            // Otherwise, edits to the line items will change the old quote.
                            if (!Sql.IsEmptyGuid(gDuplicateID))
                            {
                                foreach (DataRow row in dtLineItems.Rows)
                                {
                                    row["ID"] = Guid.NewGuid();
                                }
                            }
                            // 03/27/2007 Paul.  Always add blank line to allow quick editing.
                            DataRow rowNew = dtLineItems.NewRow();
                            dtLineItems.Rows.Add(rowNew);

                            ViewState["LineItems"] = dtLineItems;
                            grdMain.DataSource     = dtLineItems;
                            // 03/27/2007 Paul.  Start with last line enabled for editing.
                            grdMain.EditIndex = dtLineItems.Rows.Count - 1;
                            grdMain.DataBind();
                        }
                    }
                }
                else
                {
                    dtLineItems = new DataTable();
                    DataColumn colID              = new DataColumn("ID", Type.GetType("System.Guid"));
                    DataColumn colINVOICE_NAME    = new DataColumn("INVOICE_NAME", Type.GetType("System.String"));
                    DataColumn colINVOICE_ID      = new DataColumn("INVOICE_ID", Type.GetType("System.Guid"));
                    DataColumn colAMOUNT          = new DataColumn("AMOUNT", Type.GetType("System.Decimal"));
                    DataColumn colAMOUNT_USDOLLAR = new DataColumn("AMOUNT_USDOLLAR", Type.GetType("System.Decimal"));
                    dtLineItems.Columns.Add(colID);
                    dtLineItems.Columns.Add(colINVOICE_NAME);
                    dtLineItems.Columns.Add(colINVOICE_ID);
                    dtLineItems.Columns.Add(colAMOUNT);
                    dtLineItems.Columns.Add(colAMOUNT_USDOLLAR);
                    // 03/27/2007 Paul.  Always add blank line to allow quick editing.
                    DataRow rowNew = null;

                    DbProviderFactory dbf = DbProviderFactories.GetFactory();
                    using (IDbConnection conInvoice = dbf.CreateConnection())
                    {
                        conInvoice.Open();
                        string sSQL;
                        sSQL = "select *              " + ControlChars.CrLf
                               + "  from vwINVOICES_Edit" + ControlChars.CrLf
                               + " where 1 = 1          " + ControlChars.CrLf;
                        using (IDbCommand cmd = conInvoice.CreateCommand())
                        {
                            cmd.CommandText = sSQL;
                            Guid gPARENT_ID = Sql.ToGuid(Request["PARENT_ID"]);
                            Sql.AppendParameter(cmd, gPARENT_ID, "ID", false);

                            if (bDebug)
                            {
                                RegisterClientScriptBlock("vwINVOICES_Edit", Sql.ClientScriptBlock(cmd));
                            }

                            using (IDataReader rdrInvoice = cmd.ExecuteReader(CommandBehavior.SingleRow))
                            {
                                if (rdrInvoice.Read())
                                {
                                    rowNew = dtLineItems.NewRow();
                                    rowNew["INVOICE_NAME"]    = Sql.ToString(rdrInvoice["NAME"]);
                                    rowNew["INVOICE_ID"]      = Sql.ToGuid(rdrInvoice["ID"]);
                                    rowNew["AMOUNT"]          = Sql.ToDecimal(rdrInvoice["AMOUNT_DUE"]);
                                    rowNew["AMOUNT_USDOLLAR"] = Sql.ToDecimal(rdrInvoice["AMOUNT_DUE_USDOLLAR"]);
                                    dtLineItems.Rows.Add(rowNew);
                                }
                            }
                        }
                    }
                    rowNew = dtLineItems.NewRow();
                    dtLineItems.Rows.Add(rowNew);

                    ViewState["LineItems"] = dtLineItems;
                    grdMain.DataSource     = dtLineItems;
                    // 02/03/2007 Paul.  Start with last line enabled for editing.
                    grdMain.EditIndex = dtLineItems.Rows.Count - 1;
                    grdMain.DataBind();

                    UpdateTotals();
                }
            }
        }
        protected void grdMain_RowUpdating(object sender, GridViewUpdateEventArgs e)
        {
            if (dtLineItems != null)
            {
                GridViewRow  gr = grdMain.Rows[e.RowIndex];
                HiddenField  txtLINE_ITEM_TYPE      = gr.FindControl("LINE_ITEM_TYPE") as HiddenField;
                TextBox      txtNAME                = gr.FindControl("NAME") as TextBox;
                TextBox      txtMFT_PART_NUM        = gr.FindControl("MFT_PART_NUM") as TextBox;
                HiddenField  txtVENDOR_PART_NUM     = gr.FindControl("VENDOR_PART_NUM") as HiddenField;
                HiddenField  txtPRODUCT_TEMPLATE_ID = gr.FindControl("PRODUCT_TEMPLATE_ID") as HiddenField;
                DropDownList lstTAX_CLASS           = gr.FindControl("TAX_CLASS") as DropDownList;
                TextBox      txtQUANTITY            = gr.FindControl("QUANTITY") as TextBox;
                TextBox      txtCOST_PRICE          = gr.FindControl("COST_PRICE") as TextBox;
                HiddenField  txtCOST_USDOLLAR       = gr.FindControl("COST_USDOLLAR") as HiddenField;
                TextBox      txtLIST_PRICE          = gr.FindControl("LIST_PRICE") as TextBox;
                HiddenField  txtLIST_USDOLLAR       = gr.FindControl("LIST_USDOLLAR") as HiddenField;
                TextBox      txtUNIT_PRICE          = gr.FindControl("UNIT_PRICE") as TextBox;
                HiddenField  txtUNIT_USDOLLAR       = gr.FindControl("UNIT_USDOLLAR") as HiddenField;
                TextBox      txtEXTENDED_PRICE      = gr.FindControl("EXTENDED_PRICE") as TextBox;
                HiddenField  txtEXTENDED_USDOLLAR   = gr.FindControl("EXTENDED_USDOLLAR") as HiddenField;
                TextBox      txtDESCRIPTION         = gr.FindControl("DESCRIPTION") as TextBox;

                //DataRow row = dtLineItems.Rows[e.RowIndex];
                // 12/07/2007 garf.  If there are deleted rows in the set, then the index will be wrong.  Make sure to use the current rowset.
                DataRow[] aCurrentRows = dtLineItems.Select(String.Empty, String.Empty, DataViewRowState.CurrentRows);
                DataRow   row          = aCurrentRows[e.RowIndex];
                // 03/30/2007 Paul.  The text controls are empty.  Use the Request object to read the data.
                if (txtLINE_ITEM_TYPE != null)
                {
                    row["LINE_ITEM_TYPE"] = txtLINE_ITEM_TYPE.Value;
                }
                if (txtDESCRIPTION != null)
                {
                    row["DESCRIPTION"] = txtDESCRIPTION.Text;
                }
                if (Sql.ToString(row["LINE_ITEM_TYPE"]) == "Comment")
                {
                    row["NAME"]                = DBNull.Value;
                    row["MFT_PART_NUM"]        = DBNull.Value;
                    row["VENDOR_PART_NUM"]     = DBNull.Value;
                    row["PRODUCT_TEMPLATE_ID"] = DBNull.Value;
                    row["TAX_CLASS"]           = DBNull.Value;
                    row["QUANTITY"]            = DBNull.Value;
                    row["COST_PRICE"]          = DBNull.Value;
                    row["COST_USDOLLAR"]       = DBNull.Value;
                    row["LIST_PRICE"]          = DBNull.Value;
                    row["LIST_USDOLLAR"]       = DBNull.Value;
                    row["UNIT_PRICE"]          = DBNull.Value;
                    row["UNIT_USDOLLAR"]       = DBNull.Value;
                    row["EXTENDED_PRICE"]      = DBNull.Value;
                    row["EXTENDED_USDOLLAR"]   = DBNull.Value;
                }
                else
                {
                    // 03/31/2007 Paul.  The US Dollar values are computed from the price and are only used when changing currencies.
                    if (txtNAME != null)
                    {
                        row["NAME"] = txtNAME.Text;
                    }
                    if (txtMFT_PART_NUM != null)
                    {
                        row["MFT_PART_NUM"] = txtMFT_PART_NUM.Text;
                    }
                    if (txtVENDOR_PART_NUM != null)
                    {
                        row["VENDOR_PART_NUM"] = txtVENDOR_PART_NUM.Value;
                    }
                    if (txtPRODUCT_TEMPLATE_ID != null)
                    {
                        row["PRODUCT_TEMPLATE_ID"] = Sql.ToGuid(txtPRODUCT_TEMPLATE_ID.Value);
                    }
                    if (lstTAX_CLASS != null)
                    {
                        row["TAX_CLASS"] = lstTAX_CLASS.SelectedValue;
                    }
                    if (txtQUANTITY != null)
                    {
                        row["QUANTITY"] = Sql.ToInteger(txtQUANTITY.Text);
                    }
                    if (txtCOST_PRICE != null)
                    {
                        row["COST_PRICE"] = Sql.ToDecimal(txtCOST_PRICE.Text);
                    }
                    if (txtLIST_PRICE != null)
                    {
                        row["LIST_PRICE"] = Sql.ToDecimal(txtLIST_PRICE.Text);
                    }
                    if (txtUNIT_PRICE != null)
                    {
                        row["UNIT_PRICE"] = Sql.ToDecimal(txtUNIT_PRICE.Text);
                    }

                    row["COST_USDOLLAR"]     = C10n.FromCurrency(Sql.ToDecimal(txtCOST_PRICE.Text));
                    row["LIST_USDOLLAR"]     = C10n.FromCurrency(Sql.ToDecimal(txtLIST_PRICE.Text));
                    row["UNIT_USDOLLAR"]     = C10n.FromCurrency(Sql.ToDecimal(txtUNIT_PRICE.Text));
                    row["EXTENDED_PRICE"]    = Sql.ToInteger(row["QUANTITY"]) * Sql.ToDecimal(row["UNIT_PRICE"]);
                    row["EXTENDED_USDOLLAR"] = C10n.FromCurrency(Sql.ToDecimal(row["EXTENDED_PRICE"]));
                }

                // 12/07/2007 Paul.  aCurrentRows is defined above.
                //DataRow[] aCurrentRows = dtLineItems.Select(String.Empty, String.Empty, DataViewRowState.CurrentRows);
                // 03/30/2007 Paul.  Always allow editing of the last empty row. Add blank row if necessary.
                // 08/11/2007 Paul.  Allow an item to be manually added.  Require either a product ID or a name.
                if (aCurrentRows.Length == 0 || !Sql.IsEmptyString(aCurrentRows[aCurrentRows.Length - 1]["NAME"]) || !Sql.IsEmptyGuid(aCurrentRows[aCurrentRows.Length - 1]["PRODUCT_TEMPLATE_ID"]))
                {
                    DataRow rowNew = dtLineItems.NewRow();
                    dtLineItems.Rows.Add(rowNew);
                    aCurrentRows = dtLineItems.Select(String.Empty, String.Empty, DataViewRowState.CurrentRows);
                }

                ViewState["LineItems"] = dtLineItems;
                grdMain.DataSource     = dtLineItems;
                // 03/30/2007 Paul.  Make sure to use the last row of the current set, not the total rows of the table.  Some rows may be deleted.
                grdMain.EditIndex = aCurrentRows.Length - 1;
                grdMain.DataBind();
                UpdateTotals();
            }
        }
        private void Page_Load(object sender, System.EventArgs e)
        {
            SetPageTitle(L10n.Term(".moduleList." + m_sMODULE));
            // 06/04/2006 Paul.  Visibility is already controlled by the ASPX page, but it is probably a good idea to skip the load.
            this.Visible = (SplendidCRM.Security.GetUserAccess(m_sMODULE, "edit") >= 0);
            if (!this.Visible)
            {
                return;
            }

            try
            {
                // 06/09/2006 Paul.  Remove data binding in the user controls.  Binding is required, but only do so in the ASPX pages.
                //Page.DataBind();
                gID = Sql.ToGuid(Request["ID"]);
                if (!IsPostBack)
                {
                    Guid gDuplicateID = Sql.ToGuid(Request["DuplicateID"]);
                    if (!Sql.IsEmptyGuid(gID) || !Sql.IsEmptyGuid(gDuplicateID))
                    {
                        DbProviderFactory dbf = DbProviderFactories.GetFactory();
                        using (IDbConnection con = dbf.CreateConnection())
                        {
                            string sSQL;
                            sSQL = "select *                   " + ControlChars.CrLf
                                   + "  from vwOPPORTUNITIES_Edit" + ControlChars.CrLf;
                            using (IDbCommand cmd = con.CreateCommand())
                            {
                                cmd.CommandText = sSQL;
                                // 11/24/2006 Paul.  Use new Security.Filter() function to apply Team and ACL security rules.
                                Security.Filter(cmd, m_sMODULE, "edit");
                                if (!Sql.IsEmptyGuid(gDuplicateID))
                                {
                                    Sql.AppendParameter(cmd, gDuplicateID, "ID", false);
                                    gID = Guid.Empty;
                                }
                                else
                                {
                                    Sql.AppendParameter(cmd, gID, "ID", false);
                                }
                                con.Open();

                                if (bDebug)
                                {
                                    RegisterClientScriptBlock("SQLCode", Sql.ClientScriptBlock(cmd));
                                }

                                using (IDataReader rdr = cmd.ExecuteReader(CommandBehavior.SingleRow))
                                {
                                    if (rdr.Read())
                                    {
                                        ctlModuleHeader.Title = Sql.ToString(rdr["NAME"]);
                                        SetPageTitle(L10n.Term(".moduleList." + m_sMODULE) + " - " + ctlModuleHeader.Title);
                                        Utils.UpdateTracker(Page, m_sMODULE, gID, ctlModuleHeader.Title);
                                        ViewState["ctlModuleHeader.Title"] = ctlModuleHeader.Title;

                                        this.AppendEditViewFields(m_sMODULE + ".EditView", tblMain, rdr);
                                    }
                                    else
                                    {
                                        // 11/25/2006 Paul.  If item is not visible, then don't allow save
                                        ctlEditButtons.DisableAll();
                                        ctlEditButtons.ErrorText = L10n.Term("ACL.LBL_NO_ACCESS");
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        this.AppendEditViewFields(m_sMODULE + ".EditView", tblMain, null);
                        // 04/28/2007 Paul.  If created from a Quote, then load quote values.
                        Guid gQUOTE_ID        = Sql.ToGuid(Request["QUOTE_ID"]);
                        DbProviderFactory dbf = DbProviderFactories.GetFactory();
                        using (IDbConnection con = dbf.CreateConnection())
                        {
                            string sSQL;
                            sSQL = "select *       " + ControlChars.CrLf
                                   + "  from vwQUOTES" + ControlChars.CrLf;
                            using (IDbCommand cmd = con.CreateCommand())
                            {
                                cmd.CommandText = sSQL;
                                // 11/24/2006 Paul.  Use new Security.Filter() function to apply Team and ACL security rules.
                                Security.Filter(cmd, m_sMODULE, "edit");
                                Sql.AppendParameter(cmd, gQUOTE_ID, "ID", false);
                                con.Open();

                                if (bDebug)
                                {
                                    RegisterClientScriptBlock("SQLCode", Sql.ClientScriptBlock(cmd));
                                }

                                using (IDataReader rdr = cmd.ExecuteReader(CommandBehavior.SingleRow))
                                {
                                    if (rdr.Read())
                                    {
                                        new DynamicControl(this, "ACCOUNT_ID").ID       = Sql.ToGuid(rdr["BILLING_ACCOUNT_ID"]);
                                        new DynamicControl(this, "ACCOUNT_NAME").Text   = Sql.ToString(rdr["BILLING_ACCOUNT_NAME"]);
                                        new DynamicControl(this, "AMOUNT").DecimalValue = C10n.ToCurrency(Sql.ToDecimal(rdr["TOTAL_USDOLLAR"]));
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    // 12/02/2005 Paul.  When validation fails, the header title does not retain its value.  Update manually.
                    ctlModuleHeader.Title = Sql.ToString(ViewState["ctlModuleHeader.Title"]);
                    SetPageTitle(L10n.Term(".moduleList." + m_sMODULE) + " - " + ctlModuleHeader.Title);
                }
            }
            catch (Exception ex)
            {
                SplendidError.SystemError(new StackTrace(true).GetFrame(0), ex);
                ctlEditButtons.ErrorText = ex.Message;
            }
        }