Files
ayanova7/source/bizobjects/AyaLib/GZTW.AyaNova.BLL/PartWarehouseInventoryList.cs
2018-06-29 19:47:36 +00:00

627 lines
23 KiB
C#

///////////////////////////////////////////////////////////
// PartWarehouseInventoryList.cs
// Implementation of Class PartWarehouseInventoryList
// CSLA type: Read only collection
// Created on: 03-Dec-2004
// Object design: John
// Coded: 03-Dec-2004
// Re-Coded: 28-Oct-2005
///////////////////////////////////////////////////////////
using System;
using System.Data;
using GZTW.Data;
using CSLA.Data;
using CSLA;
using System.ComponentModel;
using System.Collections.Generic;
namespace GZTW.AyaNova.BLL
{
#pragma warning disable 1591
/// <summary>
/// Read only list of <see cref="PartWarehouseInventoryList.PartWarehouseInventoryListInfo"/> objects representing the inventory status of all parts.
/// Used for reporting and grid listing.
/// </summary>
[Serializable]
public class PartWarehouseInventoryList : ReadOnlyCollectionBase, ITypedList
{
#region ITypedList
//Implementation of ITypedList to allow a grid to display a read only child collection
//within a read only collection
PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors)
{
if(listAccessors==null)//then return properties of this (the parent) collection
{
//This class this code is in is the implementation of the
//PartWarehouseInventoryList read only collection business object
return TypeDescriptor.GetProperties(typeof(PartWarehouseInventoryListInfo));
}
else if(listAccessors.Length==1)//then return the properties of a child object
{
//Return the properties of the struct inside the
//PartWarehouseInventoryList read only collection
if(listAccessors[0].Name=="LT_PartSerial_Label_List")
return TypeDescriptor.GetProperties(typeof(PartSerialPickList.PartSerialPickListInfo));
//add more here if there are more children or grandchildren
}
return null;
}
///
/// Not required for grid but must be implemented
///
///
///
string ITypedList.GetListName(PropertyDescriptor[] listAccessors)
{
return "";
}
#endregion
#region Data structure
/// <summary>
/// Properties
/// </summary>
[Serializable]
public struct PartWarehouseInventoryListInfo
{
internal Guid mID;
internal GridNameValueCellItem mPartWarehouseID;
internal GridNameValueCellItem mPartID;
internal decimal mQuantityOnHand;
internal decimal mQuantityOnOrder;
internal decimal mReorderQuantity;
internal decimal mMinStockLevel;
internal GridNameValueCellItem mPartCategory;
internal GridNameValueCellItem mPartAssembly;
//case 265
internal bool mPartActive;
//Case 177
internal decimal mCost;
internal decimal mRetail;
[SqlColumnNameAttribute("aPartAssembly.aName",
"aPartAssembly.aID"),
Display(DisplayType.Button, RootObjectType = RootObjectTypes.PartAssembly)]
public GridNameValueCellItem LT_O_PartAssembly {get{return mPartAssembly;}}
[SqlColumnNameAttribute("aPartCategory.aName",
"aPartCategory.aID"),
Display(DisplayType.Button, RootObjectType = RootObjectTypes.PartCategory)]
public GridNameValueCellItem LT_O_PartCategory {get{return mPartCategory;}}
internal PartSerialPickList mSerials;
/// <summary>
/// Serial numbers in <see cref="PartSerialPickList"/>
/// </summary>
[SqlColumnNameAttribute("grid"),Display(DisplayType.Text)]
public PartSerialPickList LT_PartSerial_Label_List {get{return mSerials;}}
[Display(DisplayType.Hidden)]
public Guid ID {get{return mID;}}
[SqlColumnNameAttribute("aPartWarehouse.aName",
"aPartByWarehouseInventory.aPartWarehouseID"),
Display(DisplayType.Button, RootObjectType = RootObjectTypes.PartWarehouse)]
public GridNameValueCellItem LT_O_PartWarehouse {get{return mPartWarehouseID;}}
[SqlColumnNameAttribute("aPart.aPartNumber",
"aPartByWarehouseInventory.aPartID"),
Display(DisplayType.Button, RootObjectType = RootObjectTypes.Part)]
public GridNameValueCellItem LT_O_Part {get{return mPartID;}}
[Display(DisplayType.DecimalNumber)]
public decimal LT_PartByWarehouseInventory_Label_QuantityOnHand {get{return mQuantityOnHand;}}
[Display(DisplayType.DecimalNumber)]
public decimal LT_PartByWarehouseInventory_Label_QuantityOnOrder {get{return mQuantityOnOrder;}}
[Display(DisplayType.DecimalNumber)]
public decimal LT_PartByWarehouseInventory_Label_MinStockLevel {get{return mMinStockLevel;}}
[SqlColumnNameAttribute("AREORDERQUANTITY"),Display(DisplayType.DecimalNumber)]
public decimal LT_PartByWarehouseInventory_Label_ReorderQuantity {get{return mReorderQuantity;}}
//Case 265
[Display(DisplayType.TrueFalse)]
public bool LT_Part_Label_Active { get { return mPartActive; } }
//Case 177
[Display(DisplayType.Currency)]
public decimal LT_Part_Label_Cost { get { return mCost; } }
[Display(DisplayType.Currency)]
public decimal LT_Part_Label_Retail { get { return mRetail; } }
//Case 58
internal GridNameValueCellItem mRegion;
[SqlColumnNameAttribute("aRegion.aName", "aRegion.aID"),
Display(DisplayType.Button, RootObjectType = RootObjectTypes.Region)]
public GridNameValueCellItem LT_O_Region
{
get
{
return mRegion;
}
}
//case 460
internal GridNameValueCellItem mWholeSalerID;
[SqlColumnNameAttribute("AVENDWHOLE.ANAME", "AVENDWHOLE.AID"),
Display(DisplayType.Button, RootObjectType = RootObjectTypes.Vendor)]
public GridNameValueCellItem LT_Part_Label_WholesalerID { get { return mWholeSalerID; } }
internal GridNameValueCellItem mAlternativeWholeSalerID;
[SqlColumnNameAttribute("AVENDALTWHOLE.ANAME", "AVENDALTWHOLE.AID"),
Display(DisplayType.Button, RootObjectType = RootObjectTypes.Vendor)]
public GridNameValueCellItem LT_Part_Label_AlternativeWholesalerID { get { return mAlternativeWholeSalerID; } }
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
public bool Equals(PartWarehouseInventoryListInfo obj)
{
return this.mID.Equals(obj.mID);
}
}//end PartWarehouseInventoryListInfo
#endregion
#region Constructor
protected PartWarehouseInventoryList()
{
// 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 PartWarehouseInventoryListInfo this[int Item]
{
get
{
return (PartWarehouseInventoryListInfo) List[Item];
}
}
/// <summary>
/// Returns display text that matches passed in itemid value
/// </summary>
/// <param name="ItemID"></param>
public string this[Guid ItemID]
{
get
{
foreach (PartWarehouseInventoryListInfo child in List)
{
if(child.mID==ItemID) return child.ToString();
}
return "Missing: "+ItemID.ToString();
}
}
#endregion
#region contains
/// <summary>
/// Check if item in collection
/// </summary>
/// <param name="obj"></param>
public bool Contains(PartWarehouseInventoryListInfo obj)
{
foreach (PartWarehouseInventoryListInfo child in List)
{
if(child.Equals(obj)) return true;
}
return false;
}
#endregion
#region Reporting and shared UI editor helpers
/// <summary>
/// Returns the report key which is a property of
/// reports used to link all reports that can be used
/// with a particular data source.
/// </summary>
public static string ReportKey
{
get
{
return "PartWarehouseInventoryList";
}
}
/// <summary>
/// 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
/// </summary>
public static string DetailedReportKey
{
get
{
return "";
}
}
/// <summary>
/// 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)
/// </summary>
public static RootObjectTypes BaseObjectType
{
get
{
return RootObjectTypes.PartByWarehouseInventory;
}
}
/// <summary>
/// Locale key so that generic list editor
/// UI code knows what title to give the list in a
/// grid
/// </summary>
public string LocaleKey
{
get
{
return "PartByWarehouseInventory.Label.List";
}
}
/// <summary>
/// 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
/// <see cref="DisplayAttribute"/>
/// </summary>
public static Type ListRecordType
{
get
{
return typeof(PartWarehouseInventoryListInfo);
}
}
/// <summary>
/// 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.
/// </summary>
public static string IDField
{
get
{
return "ID";
}
}
/// <summary>
/// Same as IDField but for detailed reports
/// </summary>
public static string IDFieldDetailed
{
get
{
return IDField;
}
}
#endregion
#region Static methods
/// <summary>
/// Internal method used by list factory
/// </summary>
internal static PartWarehouseInventoryList Get(string Filter, int MaxRecords, List<Guid> IDList)
{
return (PartWarehouseInventoryList)DataPortal.Fetch(new Criteria(Filter, IDList, MaxRecords));
}
/// <summary>
/// Get all PartByWarehouseInventory (filtered by crit)
/// </summary>
/// <param name="xmlCriteria">Use AyaNova UI to easily build xmlCriteria and Ctrl-Alt-g keyboard command to display it for use in your code</param>
/// <returns></returns>
public static PartWarehouseInventoryList GetList(string xmlCriteria)
{
return (PartWarehouseInventoryList) DataPortal.Fetch(new Criteria(xmlCriteria, null, -1));
}
/// <summary>
/// Takes a single ID and returns a "list" of one object
/// </summary>
/// <param name="PartByWarehouseInventoryID">ID of PartByWarehouseInventory object</param>
/// <returns></returns>
public static PartWarehouseInventoryList GetListForSingleItem(Guid PartByWarehouseInventoryID)
{
//Case 556
List<Guid> l = new List<Guid>();
l.Add(PartByWarehouseInventoryID);
return GetListFromIDList(l);
}
/// <summary>
/// Get list by items indicated in IDList
/// </summary>
/// <param name="IDList">Generic list of Guid's</param>
/// <returns></returns>
public static PartWarehouseInventoryList GetListFromIDList(List<Guid> IDList)
{
//case 556
//Handle empty list
if (IDList.Count == 0)
return new PartWarehouseInventoryList();
return (PartWarehouseInventoryList)DataPortal.Fetch(new Criteria("", IDList, -1));
}
/// <summary>
/// Return an empty list
/// used for initializing grid
/// </summary>
/// <returns></returns>
public static PartWarehouseInventoryList GetEmptyList()
{
return new PartWarehouseInventoryList();
}
#endregion
#region DAL DATA ACCESS
///
/// <param name="Criteria"></param>
protected override void DataPortal_Fetch(object Criteria)
{
Criteria crit = (Criteria)Criteria;
SafeDataReader dr = null;
try
{
//Workaround for sorting on the calculated column
string sSort=AyaBizUtils.GetGridSortOrderColumns(crit.CriteriaXML);
sSort=sSort.Replace("AREORDERQUANTITY","(aPartByWarehouseInventory.aMinStockLevel-(aPartByWarehouseInventory.aQuantityOnHand + aPartByWarehouseInventory.aQuantityOnOrder))");
//This is a funky workaround because AREORDERQUANTITY is based on a calculated value
//you can't filter on an alias even though you can sort on one wierd in MS SQL (In firebird you can't
// do either. AREORDERQUANTITY
//so when it's filtered, it's distinctive name is easy to replace with the filter calculation
//whereas when it's sorted it simply uses the alias so we replace here in case of filter"
//Also we display zero when a reorderqty is less than zero so there needs to be a
//hack to change a filter of =0 (as the user sees it) to <1
string sFilter=AyaBizUtils.GetGridColumnCriteria(crit.CriteriaXML,true);
if(sFilter.IndexOf("AREORDERQUANTITY =0") !=-1)
sFilter=sFilter.Replace("AREORDERQUANTITY =0","(aPartByWarehouseInventory.aMinStockLevel-(aPartByWarehouseInventory.aQuantityOnHand + aPartByWarehouseInventory.aQuantityOnOrder)) <1");
else if(sFilter.IndexOf("AREORDERQUANTITY <0") !=-1)
sFilter=sFilter.Replace("AREORDERQUANTITY <0","(aPartByWarehouseInventory.aMinStockLevel-(aPartByWarehouseInventory.aQuantityOnHand + aPartByWarehouseInventory.aQuantityOnOrder)) <1");
else
sFilter=sFilter.Replace("AREORDERQUANTITY","(aPartByWarehouseInventory.aMinStockLevel-(aPartByWarehouseInventory.aQuantityOnHand + aPartByWarehouseInventory.aQuantityOnOrder)) ");
string q =//************************************************************
"SELECT ~MAXRECS~ aPart.aPartNumber AS aPARTNUMBER, aPart.aName, aPart.aActive, " +//case 265 added apartactive
"aPart.aCost, aPart.aRetail, " + //case 177
" aPartByWarehouseInventory.aPartWarehouseID, " +
" aPartWarehouse.aName AS aPartWarehouseName, " +
" aPartWarehouse.aRegionID, aRegion.aName AS aRegionName, " + //case 58
" aPartByWarehouseInventory.aQuantityOnHand, " +
" aPartByWarehouseInventory.aQtyOnOrderCommitted, " +
" aPartByWarehouseInventory.aQuantityOnOrder, " +
" aPartByWarehouseInventory.aMinStockLevel, " +
"aPartByWarehouseInventory.aID, aPartByWarehouseInventory.aMinStockLevel " +
"- (aPartByWarehouseInventory.aQuantityOnHand " +
"+ aPartByWarehouseInventory.aQuantityOnOrder) " +
"AS AREORDERQUANTITY, " +
"aPartByWarehouseInventory.aPartID, aPart.aUPC, " +
" AVENDMAN.aName AS aMANUFACTURERNAME, aPartCategory.aName " +
"AS aPARTCATEGORYNAME, aPartCategory.aID " +
"AS aPartCategoryID, aPartAssembly.aName " +
"AS aPARTASSEMBLYNAME, aPartAssembly.aID " +
"AS aPartAssemblyID, " +
//case 460
"AVENDWHOLE.ANAME AS AVENDWHOLENAME, AVENDWHOLE.AID AS AVENDWHOLEID, " +
"AVENDALTWHOLE.ANAME AS AVENDALTWHOLENAME, AVENDALTWHOLE.AID AS AVENDALTWHOLEID " +
"FROM " +
" APARTBYWAREHOUSEINVENTORY " +
" LEFT OUTER JOIN APART ON (APARTBYWAREHOUSEINVENTORY.APARTID=APART.AID) " +
//case 460
" LEFT OUTER JOIN AVENDOR AVENDMAN ON (APART.AMANUFACTURERID=AVENDMAN.AID) " +
" LEFT OUTER JOIN AVENDOR AVENDWHOLE ON (APART.AWHOLESALERID=AVENDWHOLE.AID) " +
" LEFT OUTER JOIN AVENDOR AVENDALTWHOLE ON (APART.AALTERNATIVEWHOLESALERID=AVENDALTWHOLE.AID) " +
" LEFT OUTER JOIN APARTWAREHOUSE ON (APARTBYWAREHOUSEINVENTORY.APARTWAREHOUSEID=APARTWAREHOUSE.AID) " +
" LEFT OUTER JOIN aRegion ON APARTWAREHOUSE.aRegionID = aRegion.aID " + //Case 58
" LEFT OUTER JOIN APARTCATEGORY ON (APART.APARTCATEGORYID=APARTCATEGORY.AID) " +
" LEFT OUTER JOIN APARTASSEMBLY ON (APART.APARTASSEMBLYID=APARTASSEMBLY.AID) ";
//************************************************************
if (crit.IDList != null)
{
//Case 556
System.Text.StringBuilder sbIN = new System.Text.StringBuilder();
sbIN.Append(" WHERE (aPartByWarehouseInventory.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(")) ");
q = q.Replace("~MAXRECS~", "") + sbIN.ToString() + sSort;
}
else
{
//Case 566
if (string.IsNullOrEmpty(sFilter))
sFilter = " WHERE (AQUANTITYONHAND <> 0 OR AQUANTITYONORDER <> 0 OR AMINSTOCKLEVEL <> 0) ";
else
sFilter += " AND (AQUANTITYONHAND <> 0 OR AQUANTITYONORDER <> 0 OR AMINSTOCKLEVEL <> 0) ";
q = q + sFilter + sSort;
if (crit.MaxRecords > 0)
q = q.Replace("~MAXRECS~", "TOP " + crit.MaxRecords.ToString());
else
q = q.Replace("~MAXRECS~", "");
q = DBUtil.AddRegionFilter(q, "aPartWarehouse", "");//case 58
}
dr=DBUtil.GetReaderFromSQLString(q);
while(dr.Read())
{
//*******************************************
PartWarehouseInventoryListInfo info=new PartWarehouseInventoryListInfo();
info.mPartWarehouseID=new GridNameValueCellItem(
dr.GetGuid("aPartWarehouseID"),
dr.GetString("aPartWarehouseName"),
RootObjectTypes.PartWarehouse);
//Case 58
info.mRegion = new GridNameValueCellItem(
dr.GetGuid("aRegionID"),
dr.GetString("aRegionName"),
RootObjectTypes.Region);
info.mPartID=new GridNameValueCellItem(
dr.GetGuid("aPartID"),
Part.PartDisplayFormatter(dr.GetString("aName"),dr.GetString("aPARTNUMBER"),dr.GetString("aUPC"),
dr.GetString("aMANUFACTURERNAME"),dr.GetString("aPARTCATEGORYNAME"),dr.GetString("aPARTASSEMBLYNAME"),
AyaBizUtils.GlobalSettings.DefaultPartDisplayFormat),
RootObjectTypes.Part);
info.mPartCategory=new GridNameValueCellItem(
dr.GetGuid("aPartCategoryID"),
dr.GetString("aPartCategoryName"),
RootObjectTypes.PartCategory);
info.mPartAssembly=new GridNameValueCellItem(
dr.GetGuid("aPartAssemblyID"),
dr.GetString("aPartAssemblyName"),
RootObjectTypes.PartAssembly);
info.mQuantityOnHand=dr.GetDecimal("aQuantityOnHand");
info.mQuantityOnOrder=dr.GetDecimal("aQuantityOnOrder");
info.mMinStockLevel=dr.GetDecimal("aMinStockLevel");
//TODO: Why is this necessary, if I pull in the value from the query
//under firebird it's over by a factor of 10000
//haven't tested with mssql yet
//info.mReorderQuantity=dr.GetDecimal("AREORDERQUANTITY");
info.mReorderQuantity=info.mMinStockLevel-(info.mQuantityOnHand+info.mQuantityOnOrder);
if(info.mReorderQuantity<0) info.mReorderQuantity=0;
info.mID=dr.GetGuid("aID");
info.mSerials =PartSerialPickList.GetList(info.mPartID.Value,info.mPartWarehouseID.Value);
//case 265
info.mPartActive = dr.GetBoolean("AACTIVE");
//Case 177
info.mCost = dr.GetDecimal("aCost");
info.mRetail = dr.GetDecimal("aRetail");
//case 460
info.mWholeSalerID = new GridNameValueCellItem(
dr.GetGuid("AVENDWHOLEID"),
dr.GetString("AVENDWHOLENAME"),
RootObjectTypes.Vendor);
info.mAlternativeWholeSalerID = new GridNameValueCellItem(
dr.GetGuid("AVENDALTWHOLEID"),
dr.GetString("AVENDALTWHOLENAME"),
RootObjectTypes.Vendor);
InnerList.Add(info);
//*******************************************
}
}
finally
{
if(dr!=null) dr.Close();
}
}
#endregion
#region criteria
/// <summary>
/// Criteria for identifying existing object
/// </summary>
[Serializable]
private class Criteria
{
public List<Guid> IDList;
public string CriteriaXML;
public int MaxRecords;
public Criteria(string _CriteriaXML, List<Guid> _IDList, int _MaxRecords)
{
CriteriaXML = _CriteriaXML;
IDList = _IDList;
MaxRecords = _MaxRecords;
}
}
#endregion
}//end PartWarehouseInventoryList
#pragma warning restore 1591
}//end namespace GZTW.AyaNova.BLL