/////////////////////////////////////////////////////////// // RatePickList.cs // Implementation of Class RatePickList // CSLA type: Read only collection // Created on: 23-Dec-2004 // Object design: John // Coded: 23-Dec-2004 /////////////////////////////////////////////////////////// using System; using System.Data; using GZTW.Data; using CSLA.Data; using CSLA; using System.Collections.Generic; namespace GZTW.AyaNova.BLL { /// /// Lightweight read only list of objects representing objects. /// For user selection and internal use by other business objects. /// /// [Serializable] public class RatePickList : ReadOnlyCollectionBase { #region Data structure #pragma warning disable 1591 /// /// /// [Serializable] public struct RatePickListInfo { internal Guid mID; internal string mName; internal bool mActive; internal RateTypes mRateType; internal decimal mCharge; internal decimal mCost; //False if not active *or* //limited to a subset of rates (i.e. contract with contract rates only true) internal bool mSelectable; internal string mUnitNameSingle; internal string mUnitNamePlural; internal Guid mRateUnitChargeDescriptionID; //Case 109 internal string mAccountNumber; public string AccountNumber { get { return mAccountNumber; } } public string UnitNameSingle {get{return mUnitNameSingle;}} public string UnitNamePlural {get{return mUnitNamePlural;}} //Public properties public Guid ID {get{return mID;}} public string Name {get{return mName;}} public RateTypes RateType {get{return mRateType;}} public bool Active {get{return mActive;}} public decimal Charge {get{return mCharge;}} public decimal Cost { get { return mCost; } } /// /// True if this rate is active and allowed under /// current contract if any (Contract.ContractRatesOnly) /// public bool Selectable {get{return mSelectable;}} internal bool mIsContract; public bool IsContract {get{return mIsContract;}} public Guid RateUnitChargeDescriptionID {get{return mRateUnitChargeDescriptionID;}} //case 632 internal string mDescription; public string Description { get { return mDescription; } } internal Guid mRegionID;//case 58 public Guid RegionID { get { return mRegionID; } } //case 1477 internal string mClientGroupName; public string ClientGroupName { get { return mClientGroupName; } } /// /// /// /// public bool Equals(RatePickListInfo obj) { return this.mID.Equals(obj.mID); } }//end RatePickListInfo #pragma warning restore 1591 #endregion #region Constructor /// /// /// protected RatePickList() { // AllowSort=false; // AllowFind=true; // AllowEdit=false; // AllowNew=false; // AllowRemove=false; } #endregion #region Business properties and methods /// /// Get item by index /// /// public RatePickListInfo this[int Item] { get { return (RatePickListInfo) List[Item]; } } /// /// Returns RatePickListInfo item that matches passed in itemid value /// /// public RatePickListInfo this[Guid ItemID] { get { //case 1975 if (ItemID == Guid.Empty) return new RatePickListInfo(); foreach (RatePickListInfo child in List) { if(child.mID==ItemID) return child; } throw new ArgumentException("RatePickList: ID not found:\r\n"+ItemID.ToString()); } } /// /// Get a list of all duplicate names in this list /// public System.Collections.Generic.List DuplicateNames { get { System.Collections.Generic.List dupes = new System.Collections.Generic.List(); System.Collections.Generic.List all = new System.Collections.Generic.List(); foreach (RatePickListInfo i in List) { if (all.Contains(i.Name)) { dupes.Add(i.Name); } else { all.Add(i.Name); } } return dupes; } } #endregion #region contains /// /// Check if item in collection /// /// public bool Contains(RatePickListInfo obj) { foreach (RatePickListInfo child in List) { if(child.Equals(obj)) return true; } return false; } /// /// Check if item in collection /// /// public bool Contains(Guid ID) { foreach (RatePickListInfo child in List) { if(child.ID.Equals(ID)) return true; } return false; } #endregion #region Static methods /// /// Get all Rates /// Only Active rates that are not contract rates will /// be flagged as Selectable=true; /// /// /// list of objects public static RatePickList GetList(bool Regional)//case 58 { return (RatePickList)DataPortal.Fetch(new Criteria(string.Empty, Guid.Empty, false, Regional, Guid.Empty)); } /// /// Get all Rates and if contract forces a subset of rates /// then it flags all rates not in the forced contract rates /// as Selectable=false. /// /// /// Note that if a contract does not *force* contract rates only then the returned /// list will flag as selectable all active contract rates if there are any plus all active regular rates /// /// /// In other words you can use this regardless of the status of the contract /// /// Id of contract that might affect rates returned /// A list of all rates with selectable set according to contract public static RatePickList GetListWithContract(Guid ContractID) { return (RatePickList)DataPortal.Fetch(new Criteria(string.Empty, ContractID, false, false, Guid.Empty)); } /// /// Get all Rates and flag Active ones as Selectable=true regardless of whether they are contract only or not /// This is used in scenarios where it's valid to see and select any rate /// it should never be used in conjunction with another object's rate setting /// where a contract with contract rates only is in effect. /// /// list of objects public static RatePickList GetListAllActiveRates() { return (RatePickList)DataPortal.Fetch(new Criteria(string.Empty, Guid.Empty, true, true, Guid.Empty)); } /// /// Get one specific rate only but with all the pick list info /// /// A list of objects /// This sample shows how to use the GetListOfOneSpecificUnit method to fetch a single rates info. /// /// //Fetching a list of one rate means we can access the first item in the list /// //using array notation: /// RatePickListInfo i=RatePickList.GetListOfOneSpecificRate(MyRateID)[0]; /// //now can access all the properties of this single RatePickListInfo item: /// string RateName=i.Name; /// decimal RateCharge=i.Charge; /// //etc etc /// /// /// list of objects public static RatePickList GetListOfOneSpecificRate(Guid RateID) { return (RatePickList)DataPortal.Fetch(new Criteria(string.Empty, Guid.Empty, false, false, RateID)); } /// /// Given a workorder ID fetches a list of valid rates for that workorder /// taking into account contract status /// /// /// public static RatePickList GetListForWorkorder(Guid WorkorderID) {//added for ri case 1975 return GetListForWorkorder(string.Empty, WorkorderID); } /// /// Given a workorder ID fetches a list of valid rates for that workorder /// taking into account contract status /// /// string to match /// /// public static RatePickList GetListForWorkorder(string searchTerm, Guid WorkorderID) {//added for ri case 1975 Workorder w=Workorder.GetItemNoMRU(WorkorderID); if (w.ContractResolved() == null) return GetList(searchTerm, true); else return GetListWithContract(searchTerm, w.ContractIDResolved()); } /// /// Get all Rates by search term /// Only Active rates that are not contract rates will /// be flagged as Selectable=true; /// /// /// string to match /// /// list of objects public static RatePickList GetList(string searchTerm, bool Regional)//case 1975 { return (RatePickList)DataPortal.Fetch(new Criteria(searchTerm, Guid.Empty, false, Regional, Guid.Empty)); } /// /// Get all Rates filtered by search terms /// /// If contract forces a subset of rates /// then it flags all rates not in the forced contract rates /// as Selectable=false. /// /// /// Note that if a contract does not *force* contract rates only then the returned /// list will flag as selectable all active contract rates if there are any plus all active regular rates /// /// /// In other words you can use this regardless of the status of the contract /// /// string to match /// Id of contract that might affect rates returned /// A list of all rates with selectable set according to contract public static RatePickList GetListWithContract(string searchTerm, Guid ContractID)//case 1975 { return (RatePickList)DataPortal.Fetch(new Criteria(searchTerm, ContractID, false, false, Guid.Empty)); } /// /// Check all items for duplicate names /// /// List of duplicate names public static System.Collections.Generic.List DuplicateNameCheck() { return GetList(false).DuplicateNames; } #endregion #region DAL DATA ACCESS /// /// protected override void DataPortal_Fetch(object Criteria) { Criteria crit = (Criteria)Criteria; SafeDataReader dr = null; try { Contract c=null; if(crit.ContractID!=Guid.Empty) c=Contract.GetItemNoMRU(crit.ContractID); //case 1097 List rateidlist = new List(); string q =//************************************************************ "SELECT aRate.aName, aContractRate.aContractID, " + " aRate.aID, aRate.AACTIVE, aRate.aCharge, aRate.aCost, aRate.aRegionID, " + " aRate.aRateType, aRate.aContractRate,aRate.aRateUnitChargeDescriptionID, " + " aRateUnitChargeDescription.aName AS aUnitName, " + " aRateUnitChargeDescription.aNamePlural AS " + "aUnitNamePlural, " + //Case 109 "ARATE.AACCOUNTNUMBER, " + //case 1477 "ACLIENTGROUP.ANAME AS ACLIENTGROUPNAME, " + //Case 632 "ARATE.ADESCRIPTION " + "FROM aRate LEFT OUTER JOIN aRateUnitChargeDescription " + "ON aRate.aRateUnitChargeDescriptionID " + "= aRateUnitChargeDescription.aID " + "LEFT OUTER JOIN aContractRate ON aRate.aID " + "= aContractRate.aRateID " + //case 1477 "LEFT OUTER JOIN aClientGroup ON aRate.aClientGroupID " + "= aClientGroup.aID "; //************************************************************ string likeTerm = string.Empty; if (!string.IsNullOrEmpty(crit.SearchTerm))//case 1975 { likeTerm = " (LOWER(aRate.aName) LIKE '%" + crit.SearchTerm + "%')" + " OR (LOWER(ARATE.AACCOUNTNUMBER) LIKE '%" + crit.SearchTerm + "%')"; if(crit.SpecificRate != Guid.Empty) likeTerm = " AND " + likeTerm; else likeTerm = " WHERE " + likeTerm; } if (crit.SpecificRate != Guid.Empty) { //Get all the rates and flag em as selectable or not depending on //criteria object's settings dr = DBUtil.GetReaderFromSQLString(q + " WHERE (aRate.aID = @ID)" + likeTerm , crit.SpecificRate); } else { //Get all the rates and flag em as selectable or not depending on //criteria object's settings dr = DBUtil.GetReaderFromSQLString(q+likeTerm); } //case 1300 bool bCurrentUserIsInDefaultRegion = User.CurrentUserIsInDefaultRegion; Guid myRegion = User.CurrentUserRegionID; while(dr.Read()) { //******************************************* RatePickListInfo info=new RatePickListInfo(); info.mID=dr.GetGuid("aID"); info.mName=dr.GetString("aName"); info.mRateType=(RateTypes)dr.GetInt16("aRateType"); info.mActive=dr.GetBoolean("AACTIVE"); info.mCharge=dr.GetDecimal("aCharge"); info.mCost = dr.GetDecimal("aCost"); info.mUnitNamePlural=dr.GetString("aUnitNamePlural"); info.mUnitNameSingle=dr.GetString("aUnitName"); info.mIsContract=dr.GetBoolean("aContractRate"); info.mRateUnitChargeDescriptionID=dr.GetGuid("aRateUnitChargeDescriptionID"); //Case 109 info.mAccountNumber = dr.GetString("AACCOUNTNUMBER"); //case 632 info.mDescription = dr.GetString("ADESCRIPTION"); info.mRegionID = dr.GetGuid("aRegionID");//case 58 //case 1477 info.mClientGroupName = dr.GetString("ACLIENTGROUPNAME"); //case 58 //if (crit.Regional) //{ // //theory is that users outside current region should just be inactive so they don't show in // //workorders unless preselected but will then be grayed out. // if (!AyaBizUtils.InYourRegion(info.mRegionID)) // info.mActive = false; //} //case 1300 same effect as above but without triggering db calls to get user region if (crit.Regional) if (!bCurrentUserIsInDefaultRegion) if (info.mRegionID != Region.DefaultRegionID && info.mRegionID != myRegion) info.mActive = false; //default is same as active unless //with further refinement depending upon //contract status info.mSelectable=info.mActive; //Now check the criteria and flag the rate as selectable or not //accordingly: //Force all rates? if(crit.ForceAllActiveRates==true) { //Yup, so add this item and jump out of this iteration //of the while loop and go on to the next record //case 1127 if (!rateidlist.Contains(info.ID)) { InnerList.Add(info); rateidlist.Add(info.ID); } continue; } //Is a contract involved? if(c!=null) { //Contract rates only? if(c!=null && c.ContractRatesOnly) { //Yes, so if it's not a contract rate then it's not selectable if (!info.mIsContract) info.mSelectable = false; else { //Ok, it's a contract rate, but is it *our* contract rate? if (dr.GetGuid("aContractID") != crit.ContractID) info.mSelectable = false; } } else { //it's a contract, but both this contract's rates and non-contract rates are allowed //so if it's a non contract rate then selectable is left equal to Active //no further Processing required. //however if it's a contract rate then make sure it's *this* contract's rate //Is it a contract rate? if(info.mIsContract) { //It's not selectable if it's not *our* contract rate if(dr.GetGuid("aContractID")!=crit.ContractID) info.mSelectable=false; } } } else { //Nope, no contract is involved so //the only remaining choice is all NON contract rates, //so if it's a contract rate then it's not selectable if(info.mIsContract) info.mSelectable=false; } //case 1125: case 1097 to eliminate dupes caused a side effect //that results in a valid and selectable contract rate being added //as not selectable because a prior dupe for another contract didn't match the contract id //so was added previously but as not selectable //need to ensure that a new dupe that is selectable overrides and old one that was not selectable if (rateidlist.Contains(info.ID)) { //check to see if the current rate is selectable, if it is then kick out the old one and //put this one in. if (info.Selectable) { int nDupeIndex = -1; //replace the one in the list already foreach (RatePickListInfo dupe in InnerList) { if (dupe.ID == info.ID) { nDupeIndex = InnerList.IndexOf(dupe); break; } } if (nDupeIndex != -1) { InnerList.RemoveAt(nDupeIndex); rateidlist.Remove(info.ID); } } } //case 1097 - don't add rate if it's already in the list if (!rateidlist.Contains(info.ID)) { InnerList.Add(info); rateidlist.Add(info.ID); } //******************************************* } } finally { if(dr!=null) dr.Close(); } } #endregion #region criteria /// /// Criteria for identifying existing object /// [Serializable] private class Criteria { public Guid ContractID; public bool ForceAllActiveRates; public bool Regional; public Guid SpecificRate; public string SearchTerm;//case 1975 public Criteria(string _searchTerm, Guid _ContractID, bool _ForceAllActiveRates, bool _Regional, Guid _SpecificRate) { ContractID=_ContractID; ForceAllActiveRates=_ForceAllActiveRates; Regional = _Regional; SpecificRate = _SpecificRate; SearchTerm = _searchTerm; } } #endregion }//end RatePickList }//end namespace GZTW.AyaNova.BLL