/////////////////////////////////////////////////////////// // ClientList.cs // Implementation of Class ClientList // CSLA type: Read only collection // Created on: 07-Jun-2004 8:41:14 AM // Object design: Joyce // Coded: Sept. 23rd 2004 /////////////////////////////////////////////////////////// using System; using System.Data; using GZTW.Data; using CSLA.Data; using CSLA; using System.Threading; using CSLA.Security; using System.Collections.Generic; namespace GZTW.AyaNova.BLL { #pragma warning disable 1591 /// /// Read only list of objects representing objects. /// /// [Serializable] public class ClientList : ReadOnlyCollectionBase { #region Data structure /// /// Properties /// [Serializable] public struct ClientListInfo { internal GridNameValueCellItem mClient; internal GridNameValueCellItem mHeadOffice; internal GridNameValueCellItem mClientGroup; internal GridNameValueCellItem mDispatchZone; internal GridNameValueCellItem mRegion; //CONTACT FIELDS internal string mContact; internal string mEmail; internal string mPhone1; internal string mPhone2; internal string mPhone3; internal string mPhone4; internal string mPhone5; internal string mAccountNumber; internal string mDeliveryAddress; internal string mCity; internal string mStateProv; internal string mCountry; internal string mPostal; internal bool mActive; internal string mWebAddress; internal GridNameValueCellItem mWorkorder; internal SmartDate mServiceDate; internal bool mBillHeadOffice; internal bool mUsesBanking; //case 53 used internally and useful on grid display as well internal bool mSendNotifications; internal GridNameValueCellItem mContract; internal SmartDate mContractExpires; internal string mLatitude; internal string mLongitude; internal string mCountryCode; internal decimal mHoursBalance; internal decimal mIncidentsBalance; internal decimal mCurrencyBalance; [SqlColumnNameAttribute("aClient.aName", "aClient.aID"), Display(DisplayType.Button,RootObjectType=RootObjectTypes.Client)] public GridNameValueCellItem LT_O_Client { get { return mClient; } } [SqlColumnNameAttribute("aHeadOffice.aName","aHeadOffice.aID"), Display(DisplayType.Button, RootObjectType = RootObjectTypes.HeadOffice, ShowInLite = false)] public GridNameValueCellItem LT_O_HeadOffice { get { return mHeadOffice; } } [SqlColumnNameAttribute("aRegion.aName","aRegion.aID"), Display(DisplayType.Button, RootObjectType = RootObjectTypes.Region, ShowInLite = false)] public GridNameValueCellItem LT_O_Region { get { return mRegion; } } //CONTACT FIELDS [Display(DisplayType.Text)] public string LT_Client_Label_Contact {get{return mContact;}} [Display(DisplayType.URL_Email)] public string LT_Client_Label_Email { get { return mEmail; } } [Display(DisplayType.Text)] public string LT_Client_Label_Phone1 { get { return mPhone1; } } [Display(DisplayType.Text)] public string LT_Client_Label_Phone2 { get { return mPhone2; } } [Display(DisplayType.Text)] public string LT_Client_Label_Phone3 { get { return mPhone3; } } [Display(DisplayType.Text)] public string LT_Client_Label_Phone4 { get { return mPhone4; } } [Display(DisplayType.Text)] public string LT_Client_Label_Phone5 { get { return mPhone5; } } [Display(DisplayType.Text)] public string LT_Client_Label_AccountNumber { get { return mAccountNumber; } } [SqlColumnNameAttribute("aClientGroup.aName","aClientGroup.aID"), Display(DisplayType.Button, RootObjectType = RootObjectTypes.ClientGroup, ShowInLite = false)] public GridNameValueCellItem LT_O_ClientGroup { get { return mClientGroup; } } [SqlColumnNameAttribute("aDispatchZone.aName","aDispatchZone.aID"), Display(DisplayType.Button, RootObjectType = RootObjectTypes.DispatchZone, ShowInLite = false)] public GridNameValueCellItem LT_O_DispatchZone { get { return mDispatchZone; } } [Display(DisplayType.Text)] public string LT_Address_Label_DeliveryAddress { get { return mDeliveryAddress; } } [Display(DisplayType.Text)] public string LT_Address_Label_City { get { return mCity; } } [Display(DisplayType.Text)] public string LT_Address_Label_StateProv { get { return mStateProv; } } [Display(DisplayType.Text)] public string LT_Address_Label_Country { get { return mCountry; } } [Display(DisplayType.Text)] public string LT_Address_Label_Postal { get { return mPostal; } } [Display(DisplayType.TrueFalse)] public bool LT_Client_Label_Active { get { return mActive; } } [Display(DisplayType.URL_Web)] public string LT_Client_Label_WebAddress { get { return mWebAddress; } } [SqlColumnNameAttribute("aWorkorderService.aServiceNumber","aClient.aLastWorkorderID"), Display(DisplayType.Button, RootObjectType = RootObjectTypes.Workorder, CompareAs=CompareType.StringToInt32)] public GridNameValueCellItem LT_UI_Label_LastWorkorder { get { return mWorkorder; } } [SqlColumnNameAttribute("aClient.aLastServiceDate"), Display(DisplayType.DateTime)] public object LT_UI_Label_LastServiceDate { get { return mServiceDate.DBValue; } } [Display(DisplayType.TrueFalse, ShowInLite = false)] public bool LT_Client_Label_UsesBanking { get { return mUsesBanking; } } //case 53 [SqlColumnNameAttribute("aClient.aSendNotifications"), Display(DisplayType.TrueFalse, ShowInLite = false)] public bool LT_Client_Label_Notification { get { return mSendNotifications; } } [Display(DisplayType.TrueFalse, ShowInLite = false)] public bool LT_Client_Label_BillHeadOffice { get { return this.mBillHeadOffice; } } [SqlColumnNameAttribute("aContract.aName","aClient.aContractID"), Display(DisplayType.Button, RootObjectType = RootObjectTypes.Contract, ShowInLite = false)] public GridNameValueCellItem LT_O_Contract { get { return mContract; } } [SqlColumnNameAttribute("aClient.aContractExpires"), Display(DisplayType.DateTime, ShowInLite = false)] public object LT_Client_Label_ContractExpires { get { return mContractExpires.DBValue; } } [Display(DisplayType.GeoCoordinate)] public string LT_Address_Label_Latitude { get { return mLatitude; } } [Display(DisplayType.GeoCoordinate)] public string LT_Address_Label_Longitude { get { return mLongitude; } } [Display(DisplayType.Text)] public string LT_Address_Label_CountryCode { get { return mCountryCode; } } [SqlColumnNameAttribute("HOURSBAL"), Display(DisplayType.DecimalNumber, ShowInLite = false)] public decimal LT_ServiceBank_Label_HoursBalance { get { return mHoursBalance; } } [SqlColumnNameAttribute("INCIDENTSBAL"), Display(DisplayType.DecimalNumber, ShowInLite = false)] public decimal LT_ServiceBank_Label_IncidentsBalance { get { return mIncidentsBalance; } } [SqlColumnNameAttribute("CURRENCYBAL"), Display(DisplayType.Currency, ShowInLite = false)] public decimal LT_ServiceBank_Label_CurrencyBalance { get { return mCurrencyBalance; } } //======================================================================= /// /// /// /// public bool Equals(ClientListInfo obj) { return this.mClient.Value.Equals(obj.mClient.Value); } }//end ClientListInfo #endregion #region Constructor protected ClientList() { // AllowSort=false; // AllowFind=true; // AllowEdit=false; // AllowNew=false; // AllowRemove=false; } #endregion #region Business properties and methods /// /// Get item by index /// /// public ClientListInfo this[int Item] { get { return (ClientListInfo) List[Item]; } } /// /// Returns display text that matches passed in itemid value /// /// public string this[Guid ItemID]{ get { foreach (ClientListInfo child in List) { if(child.mClient.Value==ItemID) return child.ToString(); } return "Missing: "+ItemID.ToString(); } } #endregion #region contains /// /// Check if item in collection /// /// public bool Contains(ClientListInfo obj) { foreach (ClientListInfo child in List) { if(child.Equals(obj)) return true; } return false; } #endregion #region Reporting and shared UI editor helpers /// /// Returns the report key which is a property of /// reports used to link all reports that can be used /// with a particular data source. /// public static string ReportKey { get { return "ClientList"; } } /// /// Returns the Detailed report key /// which is used to determine which reports and objects /// will be used for detailed reports /// /// If empty string then indicates there is no detailed report object or reports /// public static string DetailedReportKey { get { return ClientListDetailed.ReportKey; } } /// /// Base object that this list is reporting on /// used by shared UI editor to instantiate new objects /// when user selects new in UI elements that display this list /// /// (I.E. when user clicks on new in a read only list grid, this is the object type created) /// public static RootObjectTypes BaseObjectType { get { return RootObjectTypes.Client; } } /// /// Locale key so that generic list editor /// UI code knows what title to give the list in a /// grid /// public string LocaleKey { get { return "Client.Label.List"; } } /// /// The Type of the struct used to store list records /// Used to fetch the custom display attributes of the fields /// contained within the record to modify the grid display accordingly /// /// public static Type ListRecordType { get { return typeof(ClientListInfo); } } /// /// Field that contains the ID of the objects /// that are the basis of this list. /// /// Used for compiling an ID list for reporting from user /// selections in a grid. /// public static string IDField { get { return "LT_O_Client"; } } /// /// Same as IDField but for detailed reports /// public static string IDFieldDetailed { get { return IDField; } } #endregion #region Static methods /// /// Internal method used by list factory /// /// /// /// /// internal static ClientList Get(string Filter, int MaxRecords, List IDList) { return (ClientList)DataPortal.Fetch(new Criteria(Filter, IDList, MaxRecords)); } /// /// Takes an xml column list and where criteria /// and returns a list filtered and sorted accordingly /// /// Use AyaNova UI to easily build xmlCriteria and Ctrl-Alt-g keyboard command to display it for use in your code /// list of objects public static ClientList GetListByCriteria(string xmlCriteria) { return (ClientList) DataPortal.Fetch(new Criteria(xmlCriteria,null,-1)); } /// /// Takes a single ID and returns a "list" of one object /// /// ID of Client object /// list of one object public static ClientList GetListForSingleItem(Guid ClientID) { //Case 556 List l = new List(); l.Add(ClientID); return GetListFromIDList(l); } /// /// Get list by items indicated in IDList /// /// Generic list of Guid's /// list of objects public static ClientList GetListFromIDList(List IDList) { //case 556 //Handle empty list if (IDList.Count == 0) return new ClientList(); return (ClientList)DataPortal.Fetch(new Criteria("", IDList, -1)); } /// /// Return an empty list /// used for initializing grid /// /// public static ClientList GetEmptyList() { return new ClientList(); } #endregion #region DAL DATA ACCESS /// /// protected override void DataPortal_Fetch(object Criteria) { Criteria crit = (Criteria)Criteria; SafeDataReader dr = null; using (IDbConnection connection = DBUtil.DB.GetConnection()) { connection.Open(); //case 1748 //IDbTransaction tr = connection.BeginTransaction(); try { DBCommandWrapper cm = null; if(crit.IDList!=null) { //Case 556 System.Text.StringBuilder sbIN = new System.Text.StringBuilder(); sbIN.Append(" AND (aClient.aID in ("); foreach (Guid gItem in crit.IDList) { sbIN.Append("'"); sbIN.Append("{"); sbIN.Append(gItem.ToString().ToUpperInvariant()); sbIN.Append("}"); sbIN.Append("',"); } sbIN.Length = sbIN.Length - 1; sbIN.Append(")) "); cm = DBUtil.DB.GetSqlStringCommandWrapper( "SELECT ACLIENT.aID, ACLIENT.aName, ACLIENT.aModified, " + " ACLIENT.AACTIVE, ACLIENT.aUsesBanking, ACLIENT.aSendNotifications, " + " ACLIENT.aBillHeadOffice, ACLIENT.aWebAddress, " + " ACLIENT.aDispatchZoneID, ACLIENT.aClientGroupID, " + " ACLIENT.aLastWorkorderID, " + " ACLIENT.ACONTACT, ACLIENT.AEMAIL, ACLIENT.APHONE1, ACLIENT.APHONE2, ACLIENT.APHONE3, ACLIENT.APHONE4, ACLIENT.APHONE5, " + " ACLIENT.aLastServiceDate, (SELECT TOP 1 aSBANK.aHoursBalance " + "FROM aServiceBank aSBANK WHERE aSBANK.AAPPLIESTOROOTOBJECTID " + "= ACLIENT.aID ORDER " + "BY aSBANK.aCreated DESC) AS HOURSBAL, (SELECT TOP 1 aSBANK.aIncidentsBalance " + "FROM aServiceBank aSBANK WHERE " + "aSBANK.AAPPLIESTOROOTOBJECTID = ACLIENT.aID ORDER " + "BY aSBANK.aCreated DESC) AS INCIDENTSBAL, (SELECT " + "TOP 1 aSBANK.aCurrencyBalance FROM aServiceBank aSBANK " + "WHERE aSBANK.AAPPLIESTOROOTOBJECTID = ACLIENT.aID " + "ORDER BY aSBANK.aCreated DESC) AS CURRENCYBAL, " + " ACLIENT.AACCOUNTNUMBER, " + " aHeadOffice.aName AS aHeadOfficeName, " + " aHeadOffice.aID AS aHeadOfficeID, " + " aDispatchZone.aName AS aDispatchZoneName, ACLIENT.aRegionID, " + " aRegion.aName AS aRegionName, " + " aClientGroup.aName AS aClientGroupName, AADDRESS.aDeliveryAddress, " + " AADDRESS.aCity, AADDRESS.aStateProv, " + " AADDRESS.aCountry, AADDRESS.aPostal, " + " AADDRESS.AADDRESSTYPE, AADDRESS.aLongitude, " + " AADDRESS.aLatitude, aWorkorderService.aServiceNumber, " + " ACLIENT.aContractID, " + " aContract.aName AS aContractName, ACLIENT.aContractExpires, " + " AADDRESS.aCountryCode " + "FROM aClient ACLIENT LEFT OUTER JOIN aContract " + "ON ACLIENT.aContractID = aContract.aID " + "LEFT OUTER JOIN aHeadOffice ON aHeadOffice.aID " + "= ACLIENT.aHeadOfficeID LEFT OUTER " + "JOIN aWorkorderService ON ACLIENT.aLastWorkorderID " + "= aWorkorderService.aWorkorderID LEFT " + "OUTER JOIN AADDRESS ON AADDRESS.aRootObjectID " + "= ACLIENT.aID LEFT OUTER JOIN aRegion " + "ON ACLIENT.aRegionID = aRegion.aID LEFT " + "OUTER JOIN aClientGroup ON ACLIENT.aClientGroupID " + "= aClientGroup.aID LEFT OUTER JOIN aDispatchZone " + "ON ACLIENT.aDispatchZoneID = aDispatchZone.aID " + "WHERE (AADDRESS.AADDRESSTYPE IS NULL OR AADDRESS.AADDRESSTYPE = 2) " + sbIN.ToString() + " ORDER BY ACLIENT.ANAME "); } else { string sCurrencySelect= " (SELECT TOP 1 aSBANK.aCurrencyBalance FROM aServiceBank aSBANK " + "WHERE aSBANK.AAPPLIESTOROOTOBJECTID = ACLIENT.aID " + "ORDER BY aSBANK.aCreated DESC) "; string sIncidentsSelect= " (SELECT TOP 1 aSBANK.aIncidentsBalance FROM aServiceBank aSBANK " + "WHERE aSBANK.AAPPLIESTOROOTOBJECTID = ACLIENT.aID " + "ORDER BY aSBANK.aCreated DESC) "; string sHoursSelect= " (SELECT TOP 1 aSBANK.aHoursBalance FROM aServiceBank aSBANK " + "WHERE aSBANK.AAPPLIESTOROOTOBJECTID = ACLIENT.aID " + "ORDER BY aSBANK.aCreated DESC) "; string where=AyaBizUtils.GetGridColumnCriteria(crit.CriteriaXML,false); where = where.Replace("CURRENCYBAL", sCurrencySelect); where = where.Replace("INCIDENTSBAL", sIncidentsSelect); where = where.Replace("HOURSBAL", sHoursSelect); string order=AyaBizUtils.GetGridSortOrderColumns(crit.CriteriaXML); //case 1184 //this was *hammering* performance and turns out to be unnecessary //as both MSSQL and Firebird will accept the aliases in the ORDER BY clause instead //of the full subquery. //NOTE that neither accepts the alias in the WHERE clause though //order=order.Replace("CURRENCYBAL",sCurrencySelect); //order=order.Replace("INCIDENTSBAL",sIncidentsSelect); //order=order.Replace("HOURSBAL",sHoursSelect); order=order.Replace("aClient.","ACLIENT."); string q = "SELECT ~MAXRECS~ ACLIENT.aID, ACLIENT.aName, ACLIENT.aModified, " + " ACLIENT.AACTIVE, ACLIENT.aUsesBanking, ACLIENT.aSendNotifications, " + " ACLIENT.aBillHeadOffice, ACLIENT.aWebAddress, " + " ACLIENT.aDispatchZoneID, ACLIENT.aClientGroupID, " + " ACLIENT.aLastWorkorderID, " + " ACLIENT.ACONTACT, ACLIENT.AEMAIL, ACLIENT.APHONE1, ACLIENT.APHONE2, ACLIENT.APHONE3, ACLIENT.APHONE4, ACLIENT.APHONE5, " + " ACLIENT.aLastServiceDate, (SELECT TOP 1 aSBANK.aHoursBalance " + "FROM aServiceBank aSBANK WHERE aSBANK.AAPPLIESTOROOTOBJECTID " + "= ACLIENT.aID ORDER " + "BY aSBANK.aCreated DESC) AS HOURSBAL, (SELECT TOP 1 aSBANK.aIncidentsBalance " + "FROM aServiceBank aSBANK WHERE " + "aSBANK.AAPPLIESTOROOTOBJECTID = ACLIENT.aID ORDER " + "BY aSBANK.aCreated DESC) AS INCIDENTSBAL, (SELECT " + "TOP 1 aSBANK.aCurrencyBalance FROM aServiceBank aSBANK " + "WHERE aSBANK.AAPPLIESTOROOTOBJECTID = ACLIENT.aID " + "ORDER BY aSBANK.aCreated DESC) AS CURRENCYBAL, " + " ACLIENT.AACCOUNTNUMBER, " + " aHeadOffice.aName AS aHeadOfficeName, " + " aHeadOffice.aID AS aHeadOfficeID, " + " aDispatchZone.aName AS aDispatchZoneName, ACLIENT.aRegionID, " + " aRegion.aName AS aRegionName, " + " aClientGroup.aName AS aClientGroupName, AADDRESS.aDeliveryAddress, " + " AADDRESS.aCity, AADDRESS.aStateProv, " + " AADDRESS.aCountry, AADDRESS.aPostal, " + " AADDRESS.AADDRESSTYPE, AADDRESS.aLongitude, " + " AADDRESS.aLatitude, aWorkorderService.aServiceNumber, " + " ACLIENT.aContractID, " + " aContract.aName AS aContractName, ACLIENT.aContractExpires, " + " AADDRESS.aCountryCode " + "FROM aClient LEFT OUTER JOIN aContract " + "ON ACLIENT.aContractID = aContract.aID " + "LEFT OUTER JOIN aHeadOffice ON aHeadOffice.aID " + "= ACLIENT.aHeadOfficeID LEFT OUTER " + "JOIN aWorkorderService ON ACLIENT.aLastWorkorderID " + "= aWorkorderService.aWorkorderID LEFT " + "OUTER JOIN AADDRESS ON AADDRESS.aRootObjectID " + "= ACLIENT.aID LEFT OUTER JOIN aRegion " + "ON ACLIENT.aRegionID = aRegion.aID LEFT " + "OUTER JOIN aClientGroup ON ACLIENT.aClientGroupID " + "= aClientGroup.aID LEFT OUTER JOIN aDispatchZone " + "ON ACLIENT.aDispatchZoneID = aDispatchZone.aID " + "WHERE (AADDRESS.AADDRESSTYPE IS NULL OR AADDRESS.AADDRESSTYPE = 2) \r\n "; //Can't use regular addregion because of subqueries so just insert it here q = q+DBUtil.RegionAClientClause;//case 58 q = q + where + " \r\n "; q=q+order; if (crit.MaxRecords > 0) q = q.Replace("~MAXRECS~", "TOP " + crit.MaxRecords.ToString()); else q = q.Replace("~MAXRECS~", ""); cm = DBUtil.DB.GetSqlStringCommandWrapper(q); } cm.AddInParameter("@TRUE",DbType.Boolean,true); dr=new SafeDataReader(DBUtil.DB.ExecuteReader(cm/*case 1748,tr*/)); while (dr.Read()) { ClientListInfo info=new ClientListInfo(); info.mClient=new GridNameValueCellItem( dr.GetGuid("aID"), dr.GetString("aName"), RootObjectTypes.Client); info.mHeadOffice=new GridNameValueCellItem( dr.GetGuid("aHeadOfficeID"), dr.GetString("aHeadOfficeName"), RootObjectTypes.HeadOffice); info.mDispatchZone = new GridNameValueCellItem( dr.GetGuid("aDispatchZoneID"), dr.GetString("aDispatchZoneName"), RootObjectTypes.DispatchZone); info.mClientGroup = new GridNameValueCellItem( dr.GetGuid("aClientGroupID"), dr.GetString("aClientGroupName"), RootObjectTypes.ClientGroup); info.mRegion = new GridNameValueCellItem( dr.GetGuid("aRegionID"), dr.GetString("aRegionName"), RootObjectTypes.Region); info.mWorkorder=new GridNameValueCellItem( dr.GetGuid("aLastWorkorderID"), dr.GetInt32("aServiceNumber")==0?"":dr.GetInt32("aServiceNumber").ToString(), RootObjectTypes.Workorder); info.mServiceDate=DBUtil.ToLocal(dr.GetSmartDate("aLastServiceDate")); info.mContact = dr.GetString("ACONTACT"); info.mEmail = dr.GetString("AEMAIL"); info.mPhone1 = dr.GetString("APHONE1");//.Replace('\t','~'); info.mPhone2 = dr.GetString("APHONE2"); info.mPhone3 = dr.GetString("APHONE3"); info.mPhone4 = dr.GetString("APHONE4"); info.mPhone5 = dr.GetString("APHONE5"); info.mAccountNumber=dr.GetString("AACCOUNTNUMBER"); info.mDeliveryAddress=dr.GetString("aDeliveryAddress"); info.mCity=dr.GetString("aCity"); info.mStateProv=dr.GetString("aStateProv"); info.mCountry=dr.GetString("aCountry"); info.mPostal=dr.GetString("aPostal"); info.mActive=dr.GetBoolean("AACTIVE"); info.mWebAddress=dr.GetString("aWebAddress"); info.mUsesBanking=dr.GetBoolean("aUsesBanking"); info.mSendNotifications = dr.GetBoolean("aSendNotifications"); info.mBillHeadOffice=dr.GetBoolean("aBillHeadOffice"); info.mContract = new GridNameValueCellItem( dr.GetGuid("aContractID"), dr.GetString("aContractName"), RootObjectTypes.Contract); info.mContractExpires=DBUtil.ToLocal(dr.GetSmartDate("aContractExpires")); //no need to call if lat/lon = 0 which is likely very often decimal dLat = dr.GetDecimal("aLatitude"); info.mLatitude=dLat!=0?Address.LatitudeToString(dLat):""; decimal dLon = dr.GetDecimal("aLongitude"); info.mLongitude=dLon!=0?Address.LongitudeToString(dLon):""; info.mCountryCode=dr.GetString("aCountryCode"); info.mHoursBalance=dr.GetDecimal("HOURSBAL"); info.mIncidentsBalance=dr.GetDecimal("INCIDENTSBAL"); info.mCurrencyBalance=dr.GetDecimal("CURRENCYBAL"); InnerList.Add(info); } } finally { if(dr!=null) dr.Close(); //tr.Rollback(); } } } #endregion #region criteria /// /// Criteria for identifying existing object /// [Serializable] private class Criteria { public List IDList; public string CriteriaXML; public int MaxRecords; public Criteria(string _CriteriaXML, List _IDList, int _MaxRecords) { CriteriaXML = _CriteriaXML; IDList = _IDList; MaxRecords = _MaxRecords; } } #endregion }//end ClientList #pragma warning restore 1591 }//end namespace GZTW.AyaNova.BLL