Files
2018-06-29 19:47:36 +00:00

624 lines
22 KiB
C#

///////////////////////////////////////////////////////////
// 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
{
/// <summary>
/// Lightweight read only list of <see cref="RatePickList.RatePickListInfo"/> objects representing <see cref="Rate"/> objects.
/// For user selection and internal use by other business objects.
/// <seealso cref="Rate"/>
/// </summary>
[Serializable]
public class RatePickList : ReadOnlyCollectionBase
{
#region Data structure
#pragma warning disable 1591
/// <summary>
///
/// </summary>
[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; } }
/// <summary>
/// True if this rate is active and allowed under
/// current contract if any (Contract.ContractRatesOnly)
/// </summary>
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; } }
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
public bool Equals(RatePickListInfo obj)
{
return this.mID.Equals(obj.mID);
}
}//end RatePickListInfo
#pragma warning restore 1591
#endregion
#region Constructor
/// <summary>
///
/// </summary>
protected RatePickList()
{
// AllowSort=false;
// AllowFind=true;
// AllowEdit=false;
// AllowNew=false;
// AllowRemove=false;
}
#endregion
#region Business properties and methods
/// <summary>
/// Get item by index
/// </summary>
/// <param name="Item"></param>
public RatePickListInfo this[int Item]
{
get
{
return (RatePickListInfo) List[Item];
}
}
/// <summary>
/// Returns RatePickListInfo item that matches passed in itemid value
/// </summary>
/// <param name="ItemID"></param>
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());
}
}
/// <summary>
/// Get a list of all duplicate names in this list
/// </summary>
public System.Collections.Generic.List<string> DuplicateNames
{
get
{
System.Collections.Generic.List<string> dupes = new System.Collections.Generic.List<string>();
System.Collections.Generic.List<string> all = new System.Collections.Generic.List<string>();
foreach (RatePickListInfo i in List)
{
if (all.Contains(i.Name))
{
dupes.Add(i.Name);
}
else
{
all.Add(i.Name);
}
}
return dupes;
}
}
#endregion
#region contains
/// <summary>
/// Check if item in collection
/// </summary>
/// <param name="obj"></param>
public bool Contains(RatePickListInfo obj)
{
foreach (RatePickListInfo child in List)
{
if(child.Equals(obj)) return true;
}
return false;
}
/// <summary>
/// Check if item in collection
/// </summary>
/// <param name="ID"></param>
public bool Contains(Guid ID)
{
foreach (RatePickListInfo child in List)
{
if(child.ID.Equals(ID)) return true;
}
return false;
}
#endregion
#region Static methods
/// <summary>
/// Get all Rates
/// Only Active rates that are not contract rates will
/// be flagged as Selectable=true;
///
/// </summary>
/// <returns>list of <see cref="RatePickList.RatePickListInfo"/> objects</returns>
public static RatePickList GetList(bool Regional)//case 58
{
return (RatePickList)DataPortal.Fetch(new Criteria(string.Empty, Guid.Empty, false, Regional, Guid.Empty));
}
/// <summary>
/// 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
/// </summary>
/// <param name="ContractID">Id of contract that might affect rates returned</param>
/// <returns>A list of all rates with selectable set according to contract</returns>
public static RatePickList GetListWithContract(Guid ContractID)
{
return (RatePickList)DataPortal.Fetch(new Criteria(string.Empty, ContractID, false, false, Guid.Empty));
}
/// <summary>
/// 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.
/// </summary>
/// <returns>list of <see cref="RatePickList.RatePickListInfo"/> objects</returns>
public static RatePickList GetListAllActiveRates()
{
return (RatePickList)DataPortal.Fetch(new Criteria(string.Empty, Guid.Empty, true, true, Guid.Empty));
}
/// <summary>
/// Get one specific rate only but with all the pick list info
/// </summary>
/// <returns>A list of <see cref="RatePickList.RatePickListInfo"/> objects</returns>
/// <example> This sample shows how to use the GetListOfOneSpecificUnit method to fetch a single rates info.
/// <code>
/// //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
/// </code>
/// </example>
/// <returns>list of <see cref="RatePickList.RatePickListInfo"/> objects</returns>
public static RatePickList GetListOfOneSpecificRate(Guid RateID)
{
return (RatePickList)DataPortal.Fetch(new Criteria(string.Empty, Guid.Empty, false, false, RateID));
}
/// <summary>
/// Given a workorder ID fetches a list of valid rates for that workorder
/// taking into account contract status
/// </summary>
/// <param name="WorkorderID"></param>
/// <returns></returns>
public static RatePickList GetListForWorkorder(Guid WorkorderID)
{//added for ri case 1975
return GetListForWorkorder(string.Empty, WorkorderID);
}
/// <summary>
/// Given a workorder ID fetches a list of valid rates for that workorder
/// taking into account contract status
/// </summary>
/// <param name="searchTerm">string to match</param>
/// <param name="WorkorderID"></param>
/// <returns></returns>
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());
}
/// <summary>
/// Get all Rates by search term
/// Only Active rates that are not contract rates will
/// be flagged as Selectable=true;
///
/// </summary>
/// <param name="searchTerm">string to match</param>
/// <param name="Regional"></param>
/// <returns>list of <see cref="RatePickList.RatePickListInfo"/> objects</returns>
public static RatePickList GetList(string searchTerm, bool Regional)//case 1975
{
return (RatePickList)DataPortal.Fetch(new Criteria(searchTerm, Guid.Empty, false, Regional, Guid.Empty));
}
/// <summary>
/// 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
/// </summary>
/// <param name="searchTerm">string to match</param>
/// <param name="ContractID">Id of contract that might affect rates returned</param>
/// <returns>A list of all rates with selectable set according to contract</returns>
public static RatePickList GetListWithContract(string searchTerm, Guid ContractID)//case 1975
{
return (RatePickList)DataPortal.Fetch(new Criteria(searchTerm, ContractID, false, false, Guid.Empty));
}
/// <summary>
/// Check all items for duplicate names
/// </summary>
/// <returns>List of duplicate names</returns>
public static System.Collections.Generic.List<string> DuplicateNameCheck()
{
return GetList(false).DuplicateNames;
}
#endregion
#region DAL DATA ACCESS
///
/// <param name="Criteria"></param>
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<Guid> rateidlist = new List<Guid>();
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
/// <summary>
/// Criteria for identifying existing object
/// </summary>
[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