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

893 lines
27 KiB
C#

///////////////////////////////////////////////////////////
// PurchaseOrderReceipt.cs
// Implementation of Class PurchaseOrderReceipt
// CSLA type: Editable Root
// Created on: 17-Nov-2004
// Object design: Joyce & John
// Coded: John 17-Nov-2004
///////////////////////////////////////////////////////////
using System;
using System.Data;
using CSLA.Data;
using GZTW.Data;
using CSLA;
using System.Threading;
using CSLA.Security;
using System.Collections;
using System.Collections.Generic;
namespace GZTW.AyaNova.BLL
{
/// <summary>
/// This is a write once only object.
/// Once saved initially it can never be edited again
/// as it affects many other objects and must follow standard business practices for inventory control.
/// Corrections must be made through an inventory adjustment as per standard practices.
/// </summary>
[Serializable]
public class PurchaseOrderReceipt : BusinessBase
{
#region Attributes
private bool bReadOnly;
private Guid mID;
private SmartDate mCreated;
private SmartDate mModified;
private Guid mCreator;
private Guid mModifier;
private SmartDate mReceivedDate;
private Guid mVendorID;
private PurchaseOrderReceiptItems mItems;
private string mText1 = "";
private string mText2 = "";
#endregion
#region Constructor
/// <summary>
/// Private constructor to prevent direct instantiation
/// </summary>
private PurchaseOrderReceipt()
{
//Set to read / write initially so that properties
//can be set
bReadOnly=false;
//New ID
mID = Guid.NewGuid();
mItems=PurchaseOrderReceiptItems.NewItems();
mReceivedDate = new SmartDate(DBUtil.CurrentWorkingDateTime);
//Set record history to defaults
mCreated = new SmartDate(DBUtil.CurrentWorkingDateTime);
mModified=new SmartDate();
mCreator=Guid.Empty;
mModifier=Guid.Empty;
}
#endregion
#region Business properties
/// <summary>
/// Purchase order items child collection
/// </summary>
public PurchaseOrderReceiptItems Items
{
get
{
return mItems;
}
}
/// <summary>
/// Get internal id number Read only property because it's set internally, not
/// externally
/// </summary>
public Guid ID
{
get
{
return mID;
}
}
/// <summary>
/// Get created date
///
///
/// </summary>
public string Created
{
get
{
return mCreated.ToString();
}
}
/// <summary>
/// Get modified date
///
///
/// </summary>
public string Modified
{
get
{
return mModified.ToString();
}
}
/// <summary>
/// Get user record ID of person who created this record
///
///
/// </summary>
public Guid Creator
{
get
{
return mCreator;
}
}
/// <summary>
/// Get user ID of person who modified this record
///
///
/// </summary>
public Guid Modifier
{
get
{
return mModifier;
}
}
/// <summary>
/// Date items received
/// </summary>
public object ReceivedDate
{
get
{
return mReceivedDate.DBValue;
}
set
{
if(bReadOnly)
ThrowSetError();
else
{
if (!AyaBizUtils.SmartDateEquals(mReceivedDate, value)) //Case 298
{
mReceivedDate.DBValue = value;
BrokenRules.Assert("ReceivedDateRequired",
"Error.Object.RequiredFieldEmpty,PurchaseOrderReceipt.Label.ReceivedDate",
"ReceivedDate",mReceivedDate.IsEmpty);
MarkDirty();
}
}
}
}
/// <summary>
///
/// </summary>
public Guid VendorID
{
get
{
return mVendorID;
}
set
{
if(bReadOnly)
ThrowSetError();
else
{
if(mVendorID!=value)
{
mVendorID = value;
MarkDirty();
}
}
}
}
/// <summary>
/// Copy all line items from po indicated into
/// items collection of this receiving
/// </summary>
/// <param name="PurchaseOrderID"></param>
public void AddContentsOfPurchaseOrder(Guid PurchaseOrderID)
{
if(PurchaseOrderID==Guid.Empty)
return;
PurchaseOrder p = PurchaseOrder.GetItem(PurchaseOrderID);
if(p.OrderItems.Count<1)
return;
if(p.Status!=PurchaseOrderStatus.OpenOrdered && p.Status!=PurchaseOrderStatus.OpenPartialReceived)
{
return;
}
foreach(PurchaseOrderItem poi in p.OrderItems)
{
//Only add items that are not already there
//and not already fully received and not for some obscure
//reason ordered as quantity zero and not closed already
//just a safety, probably won't matter in practice but
//who knows what yahoo will be using this function
if(!Items.ContainsPurchaseOrderItem(poi.ID) && !(poi.QuantityOrdered==0) && !(poi.Closed) && !(poi.QuantityOrdered==poi.QuantityReceived))
{
PurchaseOrderReceiptItem i =Items.Add(this);
i.PurchaseOrderID=p.ID;
i.PartID=poi.PartID;
i.PurchaseOrderItemID=poi.ID;
i.QuantityReceived=poi.QuantityOrdered-poi.QuantityReceived;
i.ReceiptCost=poi.PurchaseOrderCost;
//i.mQuantityOrdered=poi.QuantityOrdered;
//i.mPurchaseOrderCost=poi.PurchaseOrderCost;
//i.mWorkorderNumber=poi.WorkorderNumber;
i.PartWarehouseID=poi.PartWarehouseID;
//i.mPOReferenceNumber=p.ReferenceNumber;
//i.mPurchaseTaxCodeID=poi.PurchaseTaxCodeID;
//i.mWorkorderItemPartRequestID=poi.WorkorderItemPartRequestID;
//i.mPartRequestedByID=poi.PartRequestedByID;
//i.mOrderedDate=p.sdOrderedDate;
//i.mExpectedReceiveDate=p.sdExpectedReceiveDate;
}
}
}
//Case 640
/// <summary>
/// A List of Guid's of Part Warehouses selected
/// anywhere in this work order.
///
/// </summary>
/// <returns></returns>
public System.Collections.Generic.List<Guid> ListOfPartWarehousesSelected()
{
System.Collections.Generic.List<Guid> l = new System.Collections.Generic.List<Guid>();
foreach (PurchaseOrderReceiptItem p in this.Items)
{
if (!l.Contains(p.PartWarehouseID))
l.Add(p.PartWarehouseID);
}
return l;
}
/// <summary>
/// Optional first text field
/// </summary>
public string Text1
{
get
{ return mText1; }
set
{
if (bReadOnly)
ThrowSetError();
else
{
if (mText1 != value)
{
mText1 = value;
BrokenRules.Assert("Text1Length",
"Error.Object.FieldLengthExceeded255,PurchaseOrderReceipt.Label.Text1",
"Text1", value.Length > 255);
MarkDirty();
}
}
}
}
/// <summary>
/// Optional second text field
/// </summary>
public string Text2
{
get
{ return mText2; }
set
{
if (bReadOnly)
ThrowSetError();
else
{
if (mText2 != value)
{
mText2 = value;
BrokenRules.Assert("Text2Length",
"Error.Object.FieldLengthExceeded255,PurchaseOrderReceipt.Label.Text2",
"Text2", value.Length > 255);
MarkDirty();
}
}
}
}
/// <summary>
/// Throw an error when a read only user
/// tries to set a property
/// (this should normally never be called unless someone is using the developer api since the UI
/// should prevent it from happening initially)
/// </summary>
private void ThrowSetError()
{
throw new System.Security.SecurityException
(
string.Format
(
LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToChange"),
LocalizedTextTable.GetLocalizedTextDirect("O.PurchaseOrderReceipt")
)
);
}
#endregion
#region System.object overrides
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "PurchaseOrderReceipt" + mID.ToString();
}
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(Object obj)
{
if ( obj == null || GetType ( ) != obj.GetType ( ) ) return false;
PurchaseOrderReceipt c=(PurchaseOrderReceipt)obj;
return mID==c.mID;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
return ("PurchaseOrderReceipt"+mID).GetHashCode();
}
#endregion
#region Static methods
/// <summary>
/// Create new PurchaseOrderReceipt
/// </summary>
/// <returns>PurchaseOrderReceipt</returns>
public static PurchaseOrderReceipt NewItem()
{
PurchaseOrderReceipt c;
if(AyaBizUtils.Right("Object.PurchaseOrder")>(int)SecurityLevelTypes.ReadOnly)
{
c = new PurchaseOrderReceipt();
return c;
}
else
throw new System.Security.SecurityException(
string.Format(
LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToCreate"),
LocalizedTextTable.GetLocalizedTextDirect("O.PurchaseOrderReceipt")));
}
/// <summary>
/// Fetch existing PurchaseOrderReceipt
/// </summary>
/// <returns>PurchaseOrderReceipt</returns>
/// <param name="_ID">PurchaseOrderReceipt Guid</param>
public static PurchaseOrderReceipt GetItem(Guid _ID)
{
if(AyaBizUtils.Right("Object.PurchaseOrder")>(int)SecurityLevelTypes.NoAccess)
return (PurchaseOrderReceipt)DataPortal.Fetch(new Criteria(_ID));
else
throw new System.Security.SecurityException(
string.Format(
LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToRetrieve"),
LocalizedTextTable.GetLocalizedTextDirect("O.PurchaseOrderReceipt")));
}
#endregion
#region DAL DATA ACCESS
#region Fetch
///
/// <param name="Criteria"></param>
protected override void DataPortal_Fetch(object Criteria)
{
//set to false to load items initially
bReadOnly=false;
Criteria crit = (Criteria)Criteria;
SafeDataReader dr = null;
try
{
dr=DBUtil.GetReaderFromSQLString("SELECT * FROM aPurchaseOrderReceipt WHERE aID=@ID;",crit.ID);
if(!dr.Read())
DBUtil.ThrowFetchError("PurchaseOrderReceipt ID: " + crit.ID.ToString());
//Standard fields
mID=dr.GetGuid("aID");
mCreated=DBUtil.ToLocal(dr.GetSmartDate("aCreated"));
mModified=DBUtil.ToLocal(dr.GetSmartDate("aModified"));
mCreator=dr.GetGuid("aCreator");
mModifier=dr.GetGuid("aModifier");
//PurchaseOrderReceipt fields
mReceivedDate=DBUtil.ToLocal(dr.GetSmartDate("aReceivedDate"));
mVendorID=dr.GetGuid("aVendorID");
mText1 = dr.GetString("aText1");
mText2 = dr.GetString("aText2");
if(dr!=null) dr.Close();
//Fetch child collection
dr=DBUtil.GetReaderFromSQLString(
"SELECT * FROM aPurchaseOrderReceiptItem " +
"WHERE (aPurchaseOrderReceiptItem.aPurchaseOrderReceiptID " +
"= @ID)"
,crit.ID);
mItems=PurchaseOrderReceiptItems.GetItems(dr);
if(dr!=null) dr.Close();
}
finally
{
if(dr!=null) dr.Close();
}
MarkOld();
//as this is a write once object it's always read only
//when fetched from DB
bReadOnly=true;
}
#endregion fetch
#region Update
/// <summary>
/// Called by DataPortal to add data into the database
/// </summary>
protected override void DataPortal_Update()
{
//unchangeable add only:
if(!IsNew)
throw new System.ApplicationException
(
string.Format
(
LocalizedTextTable.GetLocalizedTextDirect("Error.Object.NotChangeable"),
LocalizedTextTable.GetLocalizedTextDirect("O.PurchaseOrderReceipt")
)
);
if(IsDeleted)
throw new System.ApplicationException
(
string.Format
(
LocalizedTextTable.GetLocalizedTextDirect("Error.Object.NotDeleteable"),
LocalizedTextTable.GetLocalizedTextDirect("O.PurchaseOrderReceipt")
)
);
#region Add
//get modification time temporarily, if update succeeds then
//set to this time
System.DateTime dtModified = DBUtil.CurrentWorkingDateTime;
//Since this is an add-only object there is only the insert to deal with
DBCommandWrapper cm = DBUtil.GetCommandFromSQL(
"INSERT INTO aPurchaseOrderReceipt (aID, aVendorID, aReceivedDate, " +
"aCreated,aModified,aCreator,aModifier,aText1, aText2) VALUES (@ID,@VendorID, " +
"@ReceivedDate,@Created,@Modified,@CurrentUserID,@CurrentUserID,@Text1,@Text2)"
);
cm.AddInParameter("@ID",DbType.Guid,mID);
cm.AddInParameter("@ReceivedDate",DbType.DateTime,DBUtil.ToUTC(mReceivedDate).DBValue);
cm.AddInParameter("@VendorID",DbType.Guid,mVendorID);
//case 78
cm.AddInParameter("@Text1", DbType.String, mText1);
cm.AddInParameter("@Text2", DbType.String, mText2);
//Standard fields
cm.AddInParameter("@CurrentUserID",DbType.Guid, CurrentUserID);
cm.AddInParameter("@Created",DbType.DateTime, DBUtil.ToUTC(mCreated).DBValue);
cm.AddInParameter("@Modified",DbType.DateTime, DBUtil.ToUTC(dtModified));
using (IDbConnection connection = DBUtil.DB.GetConnection())
{
connection.Open();
//Use a serializeable isolation level as this affects inventory
//and must have full integrity throughout the transaction
IDbTransaction transaction = connection.BeginTransaction(System.Data.IsolationLevel.Serializable);
try
{
DBUtil.DB.ExecuteNonQuery(cm, transaction);
//Update child collection
mItems.Update(this,transaction);
#region Update other objects affected
foreach(PurchaseOrderReceiptItem i in mItems)
{
//poreceiptitem has a rule to disallow negative or
//zero received amounts, but let's be on the safe side anyway
//in case someone fucked with the database itself
//Case 823: this is a bug because users can receive less than one
//if(i.QuantityReceived<1) continue;
if (i.QuantityReceived < 0 || i.QuantityReceived==0) continue;
//get the current inventory values for later updating
PartByWarehouseInventoryValuesFetcher invent=
PartByWarehouseInventoryValuesFetcher.GetItem(
i.PartID,i.PartWarehouseID,transaction
);
Guid PartRequestID=Guid.Empty;
decimal POItemQuantityReceived=0;
decimal POItemQuantityOrdered=0;
#region Update the corresponding purchase order item
//Get the current received balance
SafeDataReader dr = DBUtil.GetReaderFromSQLString(
"SELECT aQuantityReceived, aQuantityOrdered, aWorkorderItemPartRequestID " +
"FROM aPurchaseOrderItem WHERE aID=@ID",
i.PurchaseOrderItemID,transaction
);
if(!dr.Read())
DBUtil.ThrowFetchError("PurchaseOrderReceipt.Update fetching received balance for po ID: " + i.PurchaseOrderItemID.ToString());
POItemQuantityReceived=dr.GetDecimal("aQuantityReceived");
POItemQuantityOrdered=dr.GetDecimal("aQuantityOrdered");
PartRequestID=dr.GetGuid("aWorkorderItemPartRequestID");
//case 1086
i.mPartRequestID = PartRequestID;
dr.Close();
//Update the Purchase order item current received balance
POItemQuantityReceived+=i.QuantityReceived;
DBCommandWrapper cmUpdatePOItem=DBUtil.GetCommandFromSQL(
"UPDATE aPurchaseOrderItem SET " +
"aQuantityReceived=@QuantityReceived, aClosed=@Closed, " +
"aModifier=@CurrentUserID, aModified=@Modified " +
"WHERE aID=@ID"
);
cmUpdatePOItem.AddInParameter("@ID",DbType.Guid,i.PurchaseOrderItemID);
cmUpdatePOItem.AddInParameter("@QuantityReceived",DbType.Decimal,POItemQuantityReceived);
cmUpdatePOItem.AddInParameter("@Closed",DbType.Boolean,POItemQuantityReceived==POItemQuantityOrdered);
cmUpdatePOItem.AddInParameter("@CurrentUserID",DbType.Guid, CurrentUserID);
cmUpdatePOItem.AddInParameter("@Modified",DbType.DateTime, DBUtil.ToUTC(dtModified));
DBUtil.DB.ExecuteNonQuery(cmUpdatePOItem, transaction);
#endregion
#region Update the Partbywarehouseinventory
//Update...
DBCommandWrapper cmUpdateInventory = null;
//is it a workorder item part request
//initiated po item?
if(PartRequestID!=Guid.Empty) //Yes
{
cmUpdateInventory = DBUtil.GetCommandFromSQL(
"UPDATE aPartByWarehouseInventory SET " +
"aQtyOnOrderCommitted=@NewQtyOnOrderCommitted, " +
"aQuantityOnHand=@NewOnHandQuantity, " +
"aModifier=@CurrentUserID, aModified=@Modified " +
"WHERE (aPartID = @PartID) AND (aPartWarehouseID " +
"= @PartWarehouseID)"
);
cmUpdateInventory.AddInParameter("@NewQtyOnOrderCommitted",DbType.Decimal,invent.QtyOnOrderCommitted-i.QuantityReceived);
}
else
{
cmUpdateInventory = DBUtil.GetCommandFromSQL(
"UPDATE aPartByWarehouseInventory SET aQuantityOnOrder=@NewOnOrderQuantity, " +
"aQuantityOnHand=@NewOnHandQuantity, " +
"aModifier=@CurrentUserID, aModified=@Modified " +
"WHERE (aPartID = @PartID) AND (aPartWarehouseID " +
"= @PartWarehouseID)"
);
cmUpdateInventory.AddInParameter("@NewOnOrderQuantity",DbType.Decimal,invent.QuantityOnOrder-i.QuantityReceived);
}
cmUpdateInventory.AddInParameter("@PartID",DbType.Guid,i.PartID);
cmUpdateInventory.AddInParameter("@PartWarehouseID",DbType.Guid,i.PartWarehouseID);
cmUpdateInventory.AddInParameter("@CurrentUserID",DbType.Guid, CurrentUserID);
cmUpdateInventory.AddInParameter("@Modified",DbType.DateTime, DBUtil.ToUTC(dtModified));
cmUpdateInventory.AddInParameter("@NewOnHandQuantity",DbType.Decimal,invent.QuantityOnHand+i.QuantityReceived);
DBUtil.DB.ExecuteNonQuery(cmUpdateInventory, transaction);
#endregion
#region Update the WorkorderItemPartRequest if applicable
if(PartRequestID!=Guid.Empty) //Yes
{
WorkorderItemPartRequest.ProcessPartsReceived(PartRequestID,i.QuantityReceived,transaction);
}
#endregion
}
#endregion
#region Update purchase order status
ArrayList al=Items.UniquePurchaseOrderGuids;
for(int x=0;x<al.Count;x++)
{
//fetch all workorder items for the indicated workorder that
//are NOT closed
DBCommandWrapper cmGetPO = DBUtil.DB.GetSqlStringCommandWrapper(
"SELECT aPurchaseOrder.aStatus, aPurchaseOrderItem.aClosed " +
"FROM aPurchaseOrder INNER JOIN " +
"aPurchaseOrderItem ON aPurchaseOrder.aID = " +
"aPurchaseOrderItem.aPurchaseOrderID WHERE (aPurchaseOrderItem.aPurchaseOrderID " +
"= @ID) " +
"AND (aPurchaseOrderItem.aClosed = @False)"
);
cmGetPO.AddInParameter("@ID",DbType.Guid,(Guid)al[x]);
cmGetPO.AddInParameter("@False",DbType.Boolean,false);
SafeDataReader dr = new SafeDataReader(DBUtil.DB.ExecuteReader(cmGetPO,transaction));
//Update the status
DBCommandWrapper cmUpdatePOStatus = DBUtil.GetCommandFromSQL(
"UPDATE aPurchaseOrder SET " +
"aStatus=@NewStatus, " +
"aModifier=@CurrentUserID, aModified=@Modified " +
"WHERE aID=@ID"
);
cmUpdatePOStatus.AddInParameter("@CurrentUserID",DbType.Guid, CurrentUserID);
cmUpdatePOStatus.AddInParameter("@Modified",DbType.DateTime, DBUtil.ToUTC(dtModified));
cmUpdatePOStatus.AddInParameter("@ID",DbType.Guid,(Guid)al[x]);
if(!dr.Read())
{
dr.Close();
//nothing?
//that means that there are no non-closed items
//in other words it's fully received so indicate the status as so
cmUpdatePOStatus.AddInParameter("@NewStatus",DbType.Int16,(int)PurchaseOrderStatus.ClosedFullReceived);
DBUtil.DB.ExecuteNonQuery(cmUpdatePOStatus, transaction);
}
else
{
//It's not fully received yet, but is it's status needing to be updated?
if((PurchaseOrderStatus)dr.GetInt16("aStatus")<PurchaseOrderStatus.OpenPartialReceived)
{
dr.Close();
//Yes, it's lower status than partial received which means we need to update it to
//partial received status
cmUpdatePOStatus.AddInParameter("@NewStatus",DbType.Int16,(int)PurchaseOrderStatus.OpenPartialReceived);
DBUtil.DB.ExecuteNonQuery(cmUpdatePOStatus, transaction);
}
else
dr.Close();
}
}
#endregion
MarkOld();//db is now synched with object
// Commit the transaction
transaction.Commit();
}
catch
{
// Rollback transaction
transaction.Rollback();
throw;
}
finally
{
connection.Close();
}
//Successful update so
//change modification time to match
this.mModified.Date=dtModified;
//case 1086
#region Add parts to workorder if there is a request on the po that was received
//It's just been successfully saved and is only saved if it's new
//so iterate the poitems and generate workorder item parts if any were requested and received
foreach (PurchaseOrderReceiptItem i in mItems)
{
if (i.QuantityReceived < 0 || i.QuantityReceived == 0) continue;
if (i.mPartRequestID != Guid.Empty) //Yes
{
Workorder w = Workorder.GetWorkorderByRelativeNoMRU(RootObjectTypes.WorkorderItemPartRequest, i.mPartRequestID);
if (w != null)
{
Guid woitemid= w.GetWorkorderItemIDFromDescendant(RootObjectTypes.WorkorderItemPartRequest, i.mPartRequestID);
if (woitemid != Guid.Empty)
{
WorkorderItem wi = w.WorkorderItems[woitemid];
if (wi != null)
{
//case 1802 shuffled the below around a bit to record discount
//so that it can be applied to received part
decimal dOriginalDiscount = 0;
PartPickList partinfo = PartPickList.GetOnePart(i.PartID);
//get record of ordered part for discount and to then remove later
Guid wipdeleteid = Guid.Empty;
foreach (WorkorderItemPart wipdelete in wi.Parts)
{
if (wipdelete.Quantity == 0 && wipdelete.PartID == i.PartID && !wipdelete.Used)
{
//case 1381 - exception: don't delete if the price or description of the original part was edited
//i.e. not the same as the partinfo variable
if (wipdelete.Price == partinfo[0].Retail && string.IsNullOrEmpty(wipdelete.Description))
{
//this is the one to remove
wipdeleteid = wipdelete.ID;
dOriginalDiscount = wipdelete.Discount;
}
break;
}
}
WorkorderItemPart wip = wi.Parts.Add(wi);
wip.PartID = i.PartID;
wip.PartWarehouseID = i.PartWarehouseID;
wip.Quantity = i.QuantityReceived;
wip.Cost = partinfo[0].Cost;
wip.Price = partinfo[0].Retail;
//case 1802
wip.Discount = dOriginalDiscount;
//set the serial number if serialized
if (partinfo[0].TrackSerialNumber)
{
wip.PartSerialID = i.SerialNumbers[0].ID;
}
w=(Workorder)w.Save();
//saved ok, now remove the original empty woitempart record
if (wipdeleteid != Guid.Empty)
{
wi.Parts.Remove(wipdeleteid);
w.Save();
}
}
}
}
}
}
#endregion add parts to workorder
}
#endregion
}
#endregion update
#endregion
#region Override IsValid / IsDirty
//Override base class version if there are child objects
/// <summary>
/// True if no broken business rules
/// </summary>
public override bool IsValid
{
get
{
return base.IsValid && mItems.IsValid && mItems.GrandChildIsValid() ;
}
}
/// <summary>
/// True if there are pending edits unsaved
/// </summary>
public override bool IsDirty
{
get
{
return base.IsDirty || mItems.IsDirty || mItems.GrandChildIsDirty() ;
}
}
#endregion
#region criteria
/// <summary>
/// Criteria for identifying existing object
/// </summary>
[Serializable]
private class Criteria
{
public Guid ID;
public Criteria(Guid _ID)
{
ID=_ID;
}
}
#endregion
}//end PurchaseOrderReceipt
}//end namespace GZTW.AyaNova.BLL