using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using GZTW.AyaNova.BLL; using System.Reflection; using System.Collections.Generic; using System.ComponentModel; using Telerik.Web.UI; using System.Drawing; using GZTW.CustomWebControls; public partial class GenericList : BaseThemePage { #region page events SecurityLevelTypes _Rights = SecurityLevelTypes.NoAccess; protected void Page_Load(object sender, EventArgs e) { //TODO: need to add rights for whatever list object is being retrieved if (Util.CurrentUser.IsClientOrHeadOfficeAccount) { Util.Denied(Context); } if (!IsPostBack) { Session.Remove("GenericListSource"); Util.Localize(Page); GenerateColumns(); string DataSourceObjectName = Util.GetBizObjectLocaleKey(mDataSource); if (DataSourceObjectName == "ClientNoteType.Label.List") _Rights = (SecurityLevelTypes)AyaBizUtils.Right(RootObjectTypes.Client); else if (DataSourceObjectName == "UnitModelCategory.Label.List") _Rights = (SecurityLevelTypes)AyaBizUtils.Right(RootObjectTypes.UnitModel); else _Rights = (SecurityLevelTypes)AyaBizUtils.Right("Object." + DataSourceObjectName.Substring(0, DataSourceObjectName.IndexOf("."))); if (_Rights == SecurityLevelTypes.ReadOnly) { Util.SetReadOnly(this); } if (_Rights == SecurityLevelTypes.NoAccess) Util.Denied(Context); } } #endregion page events #region cache private object mDataSource=null; protected object DataSource { get { if (mDataSource != null) return mDataSource; //try to fetch it from the session mDataSource = Session["GenericListSource"]; if (mDataSource == null) { //not in the session, so fetch and put in session now string collection = Request.QueryString["o"]; if (string.IsNullOrEmpty(collection)) throw new ApplicationException("GenericList - Object collection type parameter missing"); mDataSource = EditableCollectionFactory.Get(collection); Session["GenericListSource"] = mDataSource; } return mDataSource; } } #endregion #region Display protected void Grid_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e) { Grid.DataSource = DataSource; } protected void Grid_ItemDataBound(object sender, Telerik.Web.UI.GridItemEventArgs e) { //Process fields in Data row... if (e.Item is GridDataItem) { Telerik.Web.UI.GridColumn ColorPicker = Grid.MasterTableView.Columns.FindByUniqueName("COLORCOLUMN"); Telerik.Web.UI.GridColumn RegionPicker = Grid.MasterTableView.Columns.FindByUniqueName("RegionID"); Hashtable newValues = Util.GridExtractValues(e.Item); string selectedRegionID = ""; if (newValues.ContainsKey("RegionID")) selectedRegionID = newValues["RegionID"].ToString(); string selectedColor=""; //get the currently selected color //in the biz object if (ColorPicker.Visible) { if (newValues.ContainsKey("ARGB")) selectedColor = newValues["ARGB"].ToString(); else selectedColor = newValues["Color"].ToString(); } if (e.Item.IsInEditMode) { if (selectedColor != "") { AyColorPicker cp = e.Item.FindControl("cp") as AyColorPicker; cp.SetPreselectedColor("________", int.Parse(selectedColor)); } Telerik.Web.UI.RadComboBox cb = e.Item.FindControl("cbregion") as Telerik.Web.UI.RadComboBox; bindgridcombo(RegionList, cb, selectedRegionID); } else { if (selectedColor != "") { Color c = Color.FromArgb(int.Parse(selectedColor)); Label l = e.Item.FindControl("lblColor") as Label; l.Text = "________"; l.BackColor = c; } Label l2 = e.Item.FindControl("lblregion") as Label; l2.Text = DisplayValueByID(RegionList, selectedRegionID); } } } private string DisplayValueByID(DataTable dt, string SelectedID) { if (string.IsNullOrEmpty(SelectedID)) return ""; foreach (DataRow dr in dt.Rows) { if (dr["Value"].ToString() == SelectedID) return dr["Display"].ToString(); } return ""; } private void bindgridcombo(DataTable dt, Telerik.Web.UI.RadComboBox cb, string selectedID) { cb.DataSource = dt; cb.DataValueField = "Value"; cb.DataTextField = "Display"; cb.DataBind(); if (!string.IsNullOrEmpty(selectedID)) cb.SelectedValue = selectedID; } private DataTable _RegionList = null; private DataTable RegionList { get { if (_RegionList == null) { _RegionList = Util.GetDataBiz("Region", Guid.Empty, false, Guid.Empty, null, true); } return _RegionList; } } #region Generate columns / setup grid private void GenerateColumns() { Telerik.Web.UI.GridColumn ColorPicker = Grid.MasterTableView.Columns.FindByUniqueName("COLORCOLUMN"); ColorPicker.Visible = false; Telerik.Web.UI.GridColumn RegionPicker = Grid.MasterTableView.Columns.FindByUniqueName("RegionID"); RegionPicker.Visible = false; object o = DataSource; if (o == null) throw new ApplicationException("GenericList: Datasource=null"); string DataSourceObjectName = Request.QueryString["o"].ToString() + ".Label.List"; lblGridTitle.Text = Util.LocaleText(DataSourceObjectName); FillReportList(DataSourceObjectName); SecurityLevelTypes _Rights = SecurityLevelTypes.NoAccess; if (DataSourceObjectName == "ContactTitle.Label.List") _Rights = (SecurityLevelTypes)AyaBizUtils.Right(RootObjectTypes.Client); else if (DataSourceObjectName == "ClientNoteType.Label.List") _Rights = (SecurityLevelTypes)AyaBizUtils.Right(RootObjectTypes.Client); else if (DataSourceObjectName == "UnitModelCategory.Label.List") _Rights = (SecurityLevelTypes)AyaBizUtils.Right(RootObjectTypes.UnitModel); else _Rights = (SecurityLevelTypes)AyaBizUtils.Right("Object." + DataSourceObjectName.Substring(0, DataSourceObjectName.IndexOf("."))); if (_Rights < SecurityLevelTypes.ReadWrite) { Grid.MasterTableView.Columns[0].Visible = false; ////add the edit column //Telerik.Web.UI.GridEditCommandColumn c = new Telerik.Web.UI.GridEditCommandColumn(); //Grid.MasterTableView.Columns.Add(c); //c.UniqueName = "EditColumn"; //c.EditImageUrl = "~/Graphics/Edit16.png"; //c.EditText = ""; //c.UpdateImageUrl = "~/Graphics/OK16.png"; //c.UpdateText=""; //c.CancelImageUrl="~/Graphics/Cancel16.png"; //c.CancelText=""; //c.ButtonType = Telerik.Web.UI.GridButtonColumnType.ImageButton; //c.HeaderStyle.Width = System.Web.UI.WebControls.Unit.Pixel(16); } //Fields from the editable business object that don't need to be rendered in an editable grid //Note that these are fields that are not flagged with the Browseable(false) attribute as they //do sometimes need to be displayed. //Browseable false are handled separately. List donotrender = new List(); donotrender.Add("Modified"); donotrender.Add("Modifier"); donotrender.Add("Created"); donotrender.Add("Creator"); donotrender.Add("RootObjectID"); donotrender.Add("RootObjectType"); //case 1955 if (DataSourceObjectName == "PartWarehouse.Label.List") donotrender.Add("DefaultWarehouseID"); //Inspect the public properties in the business collection object //find the businesbase derived object //iterate it's properties and generate grid columns accordingly foreach (PropertyInfo fi in o.GetType().GetProperties()) { if (fi.PropertyType.IsPublic && fi.PropertyType.BaseType == typeof(CSLA.BusinessBase)) { foreach (PropertyInfo pi in fi.PropertyType.GetProperties()) { // Confirm that the property is browsable. // many internal properties of business objects are //flagged browsable(false) and because they could //change in future it's safer to use reflection this way //rather than just adding those property names to the donotrender //list BrowsableAttribute[] browsables = (BrowsableAttribute[])pi.GetCustomAttributes(typeof(BrowsableAttribute), false); if (browsables.Length > 0 && !browsables[0].Browsable) { continue; } if (!donotrender.Contains(pi.Name)) { if (pi.PropertyType == typeof(bool)) { Telerik.Web.UI.GridCheckBoxColumn c = new GridCheckBoxColumn(); Grid.MasterTableView.Columns.Add(c); c.HeaderText = pi.Name; c.DataField = pi.Name; c.DataType = typeof(bool); } else { Telerik.Web.UI.GridBoundColumn c = new Telerik.Web.UI.GridBoundColumn(); Grid.MasterTableView.Columns.Add(c); c.HeaderText = pi.Name; c.DataField = pi.Name; if (pi.PropertyType == typeof(System.Object)) c.DataType = typeof(DateTime); else c.DataType = pi.PropertyType; if (pi.Name == "ID") c.Display = false; if (pi.Name == "Color" || pi.Name == "ARGB") { ColorPicker.Visible = true; ColorPicker.HeaderText = Util.LocaleText("Priority.Label.Color"); c.Display = false; } if (pi.Name == "RegionID") { c.Display = false;//case 1050 RegionPicker.Visible = true; } } } } if (_Rights > SecurityLevelTypes.ReadWrite) { //add the delete column Telerik.Web.UI.GridButtonColumn c = new Telerik.Web.UI.GridButtonColumn(); Grid.MasterTableView.Columns.Add(c); c.UniqueName = "DeleteColumn"; c.ImageUrl = "~/Graphics/Delete16.png"; c.Text = ""; c.CommandName = "Delete"; c.ButtonType = Telerik.Web.UI.GridButtonColumnType.ImageButton; c.HeaderStyle.Width = System.Web.UI.WebControls.Unit.Pixel(16); } //Localize the grid columns and set the layout Util.GridInitEditable(DataSourceObjectName, Grid, Request.QueryString["o"].ToString()); //split now because there could be more than one variation //of the same property type, i.e. more than one type of indexer (string, int etc) //which would result in adding all the same columns again return; } } } #endregion #endregion display #region Editing #region GetObjectByID /// /// Fetch the actual object from the collection with the ID specified /// /// /// private object GetObjectByID(Guid currentid) { //o is a reference to the currently being edited object if found object o = null; //1st find the specific object by iterating over the ilist and //comparing ID's IList il = (IList)DataSource; for (int i = 0; i < il.Count; i++) { object otemp = il[i]; System.Reflection.PropertyInfo pi = otemp.GetType().GetProperty("ID"); if (pi == null) throw new ApplicationException("GenericList->UpdateCurrentRowFromGrid - Can't retrieve ID property"); Guid g = (Guid)pi.GetValue(otemp, null); if (g == currentid) { //We've found our object o = otemp; break; } } if (o == null) throw new ApplicationException("GenericList->GetObjectFromDataSource - Couldn't find the object id in the datasource being edited"); return o; } #endregion private void DeleteCurrentRowFromGrid(GridCommandEventArgs e) { Hashtable newValues = Util.GridExtractValues(e.Item); Guid currentid = new Guid(newValues["ID"].ToString()); AyColorPicker cp = e.Item.FindControl("cp") as AyColorPicker; //1st get the object being edited from the datasource object o = GetObjectByID(currentid); //2nd delete it DataSource.GetType().GetMethod("Remove", new Type[] { typeof(Guid) }).Invoke(DataSource, new object[] { currentid }); //3rd save the collection, report errors if unsavable if (((CSLA.BusinessCollectionBase)DataSource).IsSavable) { SetErrors("", false); try { mDataSource = ((CSLA.BusinessCollectionBase)DataSource).Save(); } catch (Exception ex) { //User tried to delete a record with active relationships //so bail out to protect stuff SetErrors(Util.ReportSQLError(ex),false); e.Canceled = true; //undelete item mDataSource = null; Session.Remove("GenericListSource"); } } else { SetErrors(((CSLA.BusinessBase)o).BrokenRulesText, true); foreach (TableCell tc in e.Item.Cells) tc.BackColor = Color.Red; e.Canceled = true; } } /// ///takes the values in the current grid item and copies them /// to the current workorder item /// /// private bool UpdateCurrentRowFromGrid(GridCommandEventArgs e) { Hashtable newValues = Util.GridExtractValues(e.Item); Guid currentid = new Guid(newValues["ID"].ToString()); AyColorPicker cp = e.Item.FindControl("cp") as AyColorPicker; Telerik.Web.UI.RadComboBox cbregion = (Telerik.Web.UI.RadComboBox)e.Item.FindControl("cbregion"); // wi.WorkorderStatusID = new Guid(cbstat.SelectedValue); //1st get the object being edited from the datasource object o = GetObjectByID(currentid); //2nd we have our object, now set it's values via reflection from the values in the grid row //iterate over newvalues hashtable to get properties to set foreach (DictionaryEntry d in newValues) { switch (d.Key.ToString()) { case "ID": break; case "ARGB": SetPropertyValue(o, "ARGB", int.Parse(cp.SelectedValue)); break; case "Color": SetPropertyValue(o, "Color", int.Parse(cp.SelectedValue)); break; case "RegionID": SetPropertyValue(o, "RegionID", new Guid(cbregion.SelectedValue)); break; default: SetPropertyValue(o, d.Key.ToString(), d.Value); break; } } //3rd save now, we can't wait for the user to save in the same way as in winform ayanova //which is when they exit the form because we can't trap that so do an immediate save //Save collection here to catch errors early and ensure //that if user closes page the changes are saved if (((CSLA.BusinessCollectionBase)DataSource).IsSavable) { SetErrors("",false); mDataSource = ((CSLA.BusinessCollectionBase)DataSource).Save(); return true; } else { SetErrors(((CSLA.BusinessBase)o).BrokenRulesText,true); foreach (TableCell tc in e.Item.Cells) tc.BackColor = Color.Red; e.Canceled = true; return false; } } private void SetPropertyValue(object o, string propname, object newvalue) { System.Reflection.PropertyInfo p = o.GetType().GetProperty(propname); if (p == null) throw new ApplicationException("GenericList->SetPropertyValue - Can't retrieve property"); //Changetype below will barf on empty strings because they are //considered null and so we need to make them empty strings instead //this might need to be extended for other types or modified in the heart of //the Util.GridExtractValues method if (newvalue == null) { if (p.PropertyType == typeof(string)) { newvalue = ""; } } p.SetValue(o, System.Convert.ChangeType(newvalue, p.PropertyType), null); } protected void Grid_ItemCommand(object source, GridCommandEventArgs e) { switch (e.CommandName) { case RadGrid.UpdateCommandName: { UpdateCurrentRowFromGrid(e); } break; case RadGrid.InitInsertCommandName: { //slightly different from the method used when you are working with //a typed object, since this is generic //the new object to pass to insert item is created //by using reflection to invoke the Add method of the business object //collection (specifying the Add that takes no parameters). //In each of the business object collections this page will process //there is an add method that adds a new object to the collection and //returns it e.Item.OwnerTableView.InsertItem(DataSource.GetType().GetMethod("Add",new Type[0]).Invoke(DataSource, null)); } break; case RadGrid.PerformInsertCommandName: { UpdateCurrentRowFromGrid(e); } break; case RadGrid.DeleteCommandName: { DeleteCurrentRowFromGrid(e); } break; case RadGrid.CancelCommandName: { //If a user selects cancel and it's a new inserted item //then remove it if (e.Item is Telerik.Web.UI.GridDataInsertItem) { DeleteCurrentRowFromGrid(e); } } break; } } #endregion editing #region Error display public void SetErrors(string sErrors, bool IsBrokenRules) { if (sErrors == "") { this.divError.Visible = false; } else { this.divError.Visible = true; if (IsBrokenRules) this.phErrors.Controls.Add(new LiteralControl(Util.BrokenRuleCollectionLocalizer(sErrors).Replace("\r\n", "
"))); else this.phErrors.Controls.Add(new LiteralControl(sErrors)); } } #endregion error display #region Reporting and main menu private void FillReportList(string DataSourceObjectName) { if (AyaBizUtils.Right("Object.Report") < (int)SecurityLevelTypes.ReadOnly) { mnu.Visible = false; } else { mnu.Visible = true; Util.ReportFillList(mnu.Items[0], DataSourceObjectName, ""); } } protected void mnu_ItemClick(object sender, Telerik.Web.UI.RadMenuEventArgs e) { if (e.Item.Value.StartsWith("PRINT")) { doPrint(e.Item.Value); return; } } private void doPrint(string report) { string[] s = report.Split(','); if (s[0] == "PRINTDETAILED") { //There are no detailed reports for these sub grids } else { string DataSourceObjectName = Request.QueryString["o"].ToString() + ".Label.List"; Util.Report(Page, s[1], DataSourceObjectName, DataSource); } } #endregion }