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

885 lines
30 KiB
C#

///////////////////////////////////////////////////////////
// WorkorderItemPartRequest.cs
// Implementation of Class WorkorderItemPartRequest
// CSLA type: Editable Child
// Created on: 21-Feb-2005
// Object design: John
// Coded: John 21-Feb-2005
///////////////////////////////////////////////////////////
using System;
using System.Data;
using CSLA.Data;
using GZTW.Data;
using CSLA;
using System.Threading;
using CSLA.Security;
using System.ComponentModel;
namespace GZTW.AyaNova.BLL
{
/// <summary>
/// Part request object for <see cref="WorkorderItem"/> object's <see cref="WorkorderItemPartRequests"/> collection
/// </summary>
[Serializable]
public class WorkorderItemPartRequest : BusinessBase
{
#region Attributes
private bool bReadOnly;
private Guid mID;
private SmartDate mCreated;
private SmartDate mModified;
private Guid mCreator;
private Guid mModifier;
private Guid mWorkorderItemID;
private Guid mPartID;
/// <summary>
///
/// </summary>
private decimal mQuantity = 0;
/// <summary>
/// ID of purchase order item if part is OnOrder
/// </summary>
private Guid mPurchaseOrderItemID;
/// <summary>
/// Warehouse GUID
/// </summary>
private Guid mPartWarehouseID;
private decimal mReceived = 0;
//Read only helper fields
private SmartDate mOrderedDate = new SmartDate();
private SmartDate mExpectedReceiveDate = new SmartDate();
private int mPONumber = 0;
//case 227
private GridNameValueCellItem mPO = null;
#endregion
#region Constructor
/// <summary>
/// Private constructor to prevent direct instantiation
/// </summary>
private WorkorderItemPartRequest()
{
//Set to read / write initially so that properties
//can be set
bReadOnly = false;
//Child object
MarkAsChild();
//New ID
mID = Guid.NewGuid();
//Default warehouse
mPartWarehouseID = PartWarehouse.DefaultWarehouseID;
mPurchaseOrderItemID = Guid.Empty;
//Set record history to defaults
mCreated = new SmartDate(DBUtil.CurrentWorkingDateTime);
mModified = new SmartDate();
mCreator = Guid.Empty;
mModifier = Guid.Empty;
mOrderedDate = new SmartDate();
mExpectedReceiveDate = new SmartDate();
mPONumber = 0;
}
#endregion
#region Business properties
/// <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>
/// Guid ID of parent <see cref="WorkorderItem"/> object
/// </summary>
public Guid WorkorderItemID
{
get
{
return mWorkorderItemID;
}
set
{//TODO: Shouldn't this be read only?
//if so, this change will need to be made
//all over the place for Editable Child objects
//with parent ID values
if (bReadOnly)
ThrowSetError();
else
{
if (mWorkorderItemID != value)
{
mWorkorderItemID = value;
MarkDirty();
}
}
}
}
/// <summary>
/// <see cref="PartWarehouse"/> GUID
/// </summary>
public Guid PartWarehouseID
{
get
{
return mPartWarehouseID;
}
set
{
if (bReadOnly)
ThrowSetError();
else
{
if (mPartWarehouseID != value)
{
mPartWarehouseID = value;
MarkDirty();
}
}
}
}
/// <summary>
/// ID of <see cref="PurchaseOrderItem"/> if part is OnOrder
/// </summary>
public Guid PurchaseOrderItemID
{
get
{
return mPurchaseOrderItemID;
}
set
{
if (bReadOnly)
ThrowSetError();
else
{
if (mPurchaseOrderItemID != value)
{
mPurchaseOrderItemID = value;
MarkDirty();
}
}
}
}
/// <summary>
/// Flag to indicate if this WorkorderItemPartRequest
/// is on order.
/// (has a purchase order item ID and has less received than the quantity
/// requested)
/// </summary>
public bool OnOrder
{
get
{
//changed: 28-March-2006 from received <> quantity to
//received not less than quantity because people
//are finding a way to accidentally order more than required which
//was causing it to be stuck on order because 2 received is more than
//1 ordered
if (mPurchaseOrderItemID == Guid.Empty) return false;
if (this.mReceived < this.mQuantity) return true;
return false;
//return mPurchaseOrderItemID!=Guid.Empty && !(this.mReceived < this.mQuantity);
}
}
/// <summary>
/// Flag to indicate if this WorkorderItemPartRequest
/// has not yet been ordered
/// (has a quantity but no purchase order item ID)
/// </summary>
public bool Unordered//new for case 885
{
get
{
if (mQuantity > 0 && mPurchaseOrderItemID == Guid.Empty) return true;
return false;
}
}
/// <summary>
/// <see cref="Part"/> ID
/// </summary>
public Guid PartID
{
get
{
return mPartID;
}
set
{
if (bReadOnly)
ThrowSetError();
else
{
if (mPartID != value)
{
mPartID = value;
MarkDirty();
}
}
}
}
/// <summary>
/// Quantity of parts requested
/// </summary>
public decimal Quantity
{
get
{
return mQuantity;
}
set
{
if (bReadOnly)
ThrowSetError();
else
{
if (mQuantity != value)
{
mQuantity = value;
MarkDirty();
}
}
}
}
/// <summary>
/// Quantity of parts received to date against this request
/// </summary>
public decimal Received
{
get
{
return mReceived;
}
}
/// <summary>
/// Called by parent collection object
/// when called in turn by workorder object that is read only due to
/// security or closed or service completed
/// </summary>
/// <param name="RO">Either true or the rights allowed for the current user</param>
public void SetReadOnly(bool RO)
{
bReadOnly = RO;
}
//read only UI helper fields
/// <summary>
/// Read only UI helper field
/// </summary>
public object OrderedDate { get { return mOrderedDate.DBValue; } }
/// <summary>
/// Read only UI helper field
/// </summary>
public object ExpectedReceiveDate { get { return mExpectedReceiveDate.DBValue; } }
/// <summary>
/// Read only UI helper field
/// </summary>
public int PONumber { get { return mPONumber; } }
//case 227
/// <summary>
/// Read only UI helper field
/// </summary>
public GridNameValueCellItem PO { get { return mPO; } }
//case 1975
/// <summary>
/// Read only UI helper field
/// </summary>
public bool isDeletable
{
get
{
//first do we have the rights?
if (!(AyaBizUtils.Right("Object.WorkorderItemPart") > (int)SecurityLevelTypes.ReadWrite))
return false;//not enough rights no point checking further
//Does it have a po?
if (mPurchaseOrderItemID != Guid.Empty)
{
//has it been fully received?
if (mReceived < mQuantity)
return false;
//yup, deleteable
return true;
}
else
{
//we have the rights and there isn't a PO so go ahead
return true;
}
}
}
/// <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.WorkorderItemPartRequest")
)
);
}
#endregion
#region System.object overrides
/// <summary>
///
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "WorkorderItemPartRequest" + mID.ToString();
}
/// <summary>
///
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override bool Equals(Object obj)
{
if (obj == null || GetType() != obj.GetType()) return false;
WorkorderItemPartRequest c = (WorkorderItemPartRequest)obj;
return mID == c.mID;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public override int GetHashCode()
{
return ("WorkorderItemPartRequest" + mID).GetHashCode();
}
#endregion
#region Static methods
/// <summary>
/// Check for existance of a particular part request object
/// </summary>
/// <param name="WorkorderItemPartRequestID"></param>
/// <returns></returns>
public static bool Exists(Guid WorkorderItemPartRequestID)
{
return WorkorderItemPartRequestExistanceChecker.RequestExists(WorkorderItemPartRequestID);
}
/// <summary>
/// New item
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
internal static WorkorderItemPartRequest NewItem(WorkorderItem obj)
{
if ((obj.mHeaderRights > SecurityLevelTypes.ReadOnly) &&
(AyaBizUtils.Right("Object.WorkorderItemPart") > (int)SecurityLevelTypes.ReadOnly))
{
WorkorderItemPartRequest child = new WorkorderItemPartRequest();
child.mWorkorderItemID = obj.ID;
return child;
}
else
throw new System.Security.SecurityException(
string.Format(
LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToCreate"),
LocalizedTextTable.GetLocalizedTextDirect("O.WorkorderItemPartRequest")));
}
/// <summary>
/// Get Item
/// </summary>
/// <param name="dr"></param>
/// <param name="obj"></param>
/// <returns></returns>
internal static WorkorderItemPartRequest GetItem(SafeDataReader dr, WorkorderItem obj)
{
//case 1387
if ((obj.mHeaderRights > SecurityLevelTypes.NoAccess) &&
(AyaBizUtils.Right("Object.WorkorderItemPart") > (int)SecurityLevelTypes.NoAccess))
{
WorkorderItemPartRequest child = new WorkorderItemPartRequest();
child.Fetch(dr);
return child;
}
else
throw new System.Security.SecurityException(
string.Format(
LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToRetrieve"),
LocalizedTextTable.GetLocalizedTextDirect("O.WorkorderItemPartRequest")));
}
/// <summary>
/// Called by PurchaseOrderReceipt when parts are received against a request
/// this method ensures that the request record get's updated accordingly
/// notification is sent if subscribed to and finally creates a part record for the workorder
/// item ready for the tech
/// </summary>
/// <param name="WorkorderItemPartRequestID"></param>
/// <param name="QuantityReceived"></param>
/// <param name="tr"></param>
internal static void ProcessPartsReceived(Guid WorkorderItemPartRequestID,
decimal QuantityReceived, IDbTransaction tr)
{
ReceivePartsProcessor.Receive(WorkorderItemPartRequestID, QuantityReceived, tr);
}
#endregion
#region Shared Notification Message Processor
internal static NotifyMessage GetNotificationMessage(NotifyMessageRequestData d)
{
//string d.Language=User.GetUserLanguage(MessageForUserID);
WorkorderItemPartRequestNotificationDescriptionFetcher df = WorkorderItemPartRequestNotificationDescriptionFetcher.GetItem(d.RootObjectID);
string sEventDescription = "";
string sExtraInfo = "";
sEventDescription = LocalizedTextTable.GetLocalizedTextDirect("WorkorderItemPartRequest.Label.Event.PartsReceived", d.Language);
sExtraInfo = LocalizedTextTable.GetLocalizedTextDirect("O.Part", d.Language) + ": " + df.PartName + df.Received.ToString() + "/" + df.Requested.ToString();
string sMessage = sEventDescription;
string sSubject = sEventDescription;
NotifyMessage nm = null;
if (d.Format == NotifyDeliveryMessageFormats.Brief)
{
sMessage += " " + LocalizedTextTable.GetLocalizedTextDirect("WorkorderService.Label.ServiceNumber", d.Language) + " " + df.WorkorderNumber + " " + df.ClientName + " " + sExtraInfo;
if (d.MaxCharacters > 0 && sMessage.Length > d.MaxCharacters)
nm = new NotifyMessage("", sMessage.Substring(0, d.MaxCharacters));
else
nm = new NotifyMessage("", sMessage);
}
else
{
sSubject += ": " + LocalizedTextTable.GetLocalizedTextDirect("WorkorderService.Label.ServiceNumber", d.Language) + " " + df.WorkorderNumber;
sMessage += ": " + LocalizedTextTable.GetLocalizedTextDirect("WorkorderService.Label.ServiceNumber", d.Language) + " " + df.WorkorderNumber + "\r\n" +
LocalizedTextTable.GetLocalizedTextDirect("O.Client", d.Language) + ": " + df.ClientName + "\r\n" +
sExtraInfo;
nm = new NotifyMessage(sSubject, sMessage);
}
return nm;
}
#endregion
#region DAL DATA ACCESS
#region Fetch
/// <summary>
///
/// </summary>
/// <param name="dr"></param>
protected void Fetch(SafeDataReader dr)
{
//Standard fields
mCreated = DBUtil.ToLocal(dr.GetSmartDate("aCreated"));
mModified = DBUtil.ToLocal(dr.GetSmartDate("aModified"));
mCreator = dr.GetGuid("aCreator");
mModifier = dr.GetGuid("aModifier");
mID = dr.GetGuid("aID");
//WorkorderItemPartRequest fields
mWorkorderItemID = dr.GetGuid("aWorkorderItemID");
mPartID = dr.GetGuid("aPartID");
mPartWarehouseID = dr.GetGuid("aPartWarehouseID");
mPurchaseOrderItemID = dr.GetGuid("aPurchaseOrderItemID");
mQuantity = dr.GetDecimal("aQuantity");
mReceived = dr.GetDecimal("aReceived");
mOrderedDate = DBUtil.ToLocal(dr.GetSmartDate("aOrderedDate"));
mExpectedReceiveDate = DBUtil.ToLocal(dr.GetSmartDate("aExpectedReceiveDate"));
mPONumber = dr.GetInt32("aPONumber");
//case 227
mPO = new GridNameValueCellItem(dr.GetGuid("APURCHASEORDERID"), mPONumber.ToString(), RootObjectTypes.PurchaseOrder);
//Get access rights level
bReadOnly = AyaBizUtils.Right("Object.WorkorderItemPart") < (int)SecurityLevelTypes.ReadWrite;
MarkOld();
}
#endregion
#region Add / Update
/// <summary>
/// Update child
/// </summary>
/// <param name="obj"></param>
/// <param name="tr"></param>
internal void Update(WorkorderItem obj, IDbTransaction tr)
{
//No need to update if there is nothing changed
if (!this.IsDirty) return;
// If not a new record, check if record was modified
//by another user since original retrieval:
if (!IsNew)
DBUtil.CheckSafeToUpdateInsideTransaction(this.mModified.Date, this.mID, "aWorkorderItemPartRequest", tr);//case 1960
#region Delete
if (IsDeleted)
{
//If there are still outstanding parts on order this can't be removed
if (this.mPurchaseOrderItemID != Guid.Empty && this.mReceived < this.mQuantity)
{
throw new System.ApplicationException
(LocalizedTextTable.GetLocalizedTextDirect("WorkorderItemPartRequest.Error.NotDeleteableOnOrder"));
}
if (!IsNew)
{
if (this.mPurchaseOrderItemID != Guid.Empty)
{
//Case 396 - remove the link to the part request
//before it's deleted
//this code added to handle deleting a part request for
//an item that has been fully received already, something the
//other code around here did not do as it was only concerned with unreceived but on order
//items etc
DBCommandWrapper cmz = DBUtil.GetCommandFromSQL(
"UPDATE APURCHASEORDERITEM SET AWORKORDERITEMPARTREQUESTID=null " +
"WHERE AWORKORDERITEMPARTREQUESTID=@ID;");
cmz.AddInParameter("@ID", DbType.Guid, this.mID);
DBUtil.DB.ExecuteNonQuery(cmz, tr);
}
//Added: 17-Nov-2006 case 157
//added code to delete any purchase order items in existance for this workorder item part request
//this is safe to do outright because if we have made it to this point it's already confirmed there
//is nothing on order for this part request in the code immediately above here
DBCommandWrapper cmDeletepo = DBUtil.GetCommandFromSQL("DELETE FROM APURCHASEORDERITEM WHERE APURCHASEORDERITEM.AWORKORDERITEMPARTREQUESTID=@ID;");
cmDeletepo.AddInParameter("@ID", DbType.Guid, this.mID);
DBUtil.DB.ExecuteNonQuery(cmDeletepo, tr);
DBCommandWrapper cmDelete = DBUtil.GetCommandFromSQL("DELETE FROM aWorkorderItemPartRequest WHERE aID=@ID;");
cmDelete.AddInParameter("@ID", DbType.Guid, this.mID);
DBUtil.DB.ExecuteNonQuery(cmDelete, tr);
}
MarkNew();
return;
}
#endregion
#region Add / Update
//get modification time temporarily, if update succeeds then
//set to this time
System.DateTime dtModified = DBUtil.CurrentWorkingDateTime;
DBCommandWrapper cm = null;
if (IsNew)//Add or update?
cm = DBUtil.GetCommandFromSQL(
"INSERT INTO aWorkorderItemPartRequest (aWorkorderItemID, " +
"aID, aPartID, aQuantity, aReceived, aPurchaseOrderItemID, " +
"aPartWarehouseID, aCreated, aModified,aCreator,aModifier) VALUES (@WorkorderItemID, " +
"@ID,@PartID,@Quantity, @Received, @PurchaseOrderItemID, " +
"@PartWarehouseID,@Created,@Modified,@CurrentUserID,@CurrentUserID)"
);
else
cm = DBUtil.GetCommandFromSQL(
"UPDATE aWorkorderItemPartRequest SET aWorkorderItemID=@WorkorderItemID, " +
"aID=@ID, aPartID=@PartID, aQuantity=@Quantity, aReceived=@Received, " +
"aPurchaseOrderItemID=@PurchaseOrderItemID, " +
"aPartWarehouseID=@PartWarehouseID, aModifier=@CurrentUserID, " +
"aModified=@Modified WHERE aID=@ID"
);
//WorkorderItemPartRequest specific
cm.AddInParameter("@ID", DbType.Guid, mID);
cm.AddInParameter("@WorkorderItemID", DbType.Guid, mWorkorderItemID);
cm.AddInParameter("@PartID", DbType.Guid, mPartID);
cm.AddInParameter("@PartWarehouseID", DbType.Guid, mPartWarehouseID);
cm.AddInParameter("@PurchaseOrderItemID", DbType.Guid, mPurchaseOrderItemID);
cm.AddInParameter("@Quantity", DbType.Decimal, mQuantity);
cm.AddInParameter("@Received", DbType.Decimal, mReceived);
//standard parameters
cm.AddInParameter("@CurrentUserID", DbType.Guid, CurrentUserID);
cm.AddInParameter("@Created", DbType.DateTime, DBUtil.ToUTC(mCreated.Date));
cm.AddInParameter("@Modified", DbType.DateTime, DBUtil.ToUTC(dtModified));
DBUtil.DB.ExecuteNonQuery(cm, tr);
MarkOld();//db is now synched with object
//Successful update so
//change modification time to match
this.mModified.Date = dtModified;
#endregion
}
#endregion
#endregion
#region Inventory receipt Processing
#pragma warning disable 1591
/// <summary>
/// Handle receipt of inventory that fulfills
/// request
/// </summary>
[Serializable, System.ComponentModel.Browsable(false)]
public class ReceivePartsProcessor//DO_NOT_OBFUSCATE
{
Guid _WorkorderItemPartRequestID;
decimal _QuantityReceived;
IDbTransaction _tr;
public ReceivePartsProcessor(Guid WorkorderItemPartRequestID, decimal QuantityReceived, IDbTransaction tr)
{
_WorkorderItemPartRequestID = WorkorderItemPartRequestID;
_QuantityReceived = QuantityReceived;
_tr = tr;
}
public static void Receive(Guid WorkorderItemPartRequestID, decimal QuantityReceived, IDbTransaction tr)
{
DataPortal.Update(new ReceivePartsProcessor(WorkorderItemPartRequestID, QuantityReceived, tr));
}
public void DataPortal_Update()
{
#region Update the request record
//Get current balance, requestorid and workorderitem ID for Processing
SafeDataReader dr = DBUtil.GetReaderFromSQLString(
"SELECT aQuantity, aReceived, aWorkorderItemID, aCreator " +
"FROM aWorkorderItemPartRequest WHERE aID=@ID",
_WorkorderItemPartRequestID, _tr
);
if (!dr.Read())
DBUtil.ThrowFetchError("ReceivePartsProcessor.Update fetching part request balances for receiving. WorkorderItemPartRequestID: " + _WorkorderItemPartRequestID.ToString());
decimal NewReceivedQuantity = dr.GetDecimal("aReceived");
NewReceivedQuantity += _QuantityReceived;
decimal Ordered = dr.GetDecimal("aQuantity");
Guid WorkorderItemID = dr.GetGuid("aWorkorderItemID");
Guid RequestorID = dr.GetGuid("aCreator");
dr.Close();
//Update the current received value
DBCommandWrapper cmUpdateRequest = DBUtil.GetCommandFromSQL(
"UPDATE aWorkorderItemPartRequest SET aReceived=@Received, " +
"aModifier=@CurrentUserID, " +
"aModified=@Modified WHERE aID=@ID"
);
//WorkorderItemPartRequest specific
cmUpdateRequest.AddInParameter("@ID", DbType.Guid, _WorkorderItemPartRequestID);
cmUpdateRequest.AddInParameter("@Received", DbType.Decimal, NewReceivedQuantity);
//standard parameters
cmUpdateRequest.AddInParameter("@CurrentUserID", DbType.Guid, User.CurrentThreadUserID);
cmUpdateRequest.AddInParameter("@Modified", DbType.DateTime, DBUtil.ToUTC(DBUtil.CurrentWorkingDateTime));
DBUtil.DB.ExecuteNonQuery(cmUpdateRequest, _tr);
#endregion
#region Process Notification
//Process events as necessary
if (AyaBizUtils.GlobalSettings.UseNotification)//Case 510
{
//Notify requestor
NotifyEvent.AddOrUpdateEvent(RootObjectTypes.WorkorderItemPartRequest,
_WorkorderItemPartRequestID, (int)WorkorderItemPartRequestEvent.PartsReceived,
RequestorID, new SmartDate(), Guid.Empty);
//case 787
//get list of scheduled users on workorder item
//and process a notification for each one of them in addition
//to the requestor ID
dr = DBUtil.GetReaderFromSQLString(
"SELECT AUSERID FROM AWORKORDERITEMSCHEDULEDUSER WHERE AWORKORDERITEMID = @ID", WorkorderItemID);
System.Collections.ArrayList al = new System.Collections.ArrayList();
Guid g = Guid.Empty;
while (dr.Read())
{
g = dr.GetGuid("AUSERID");
if (!al.Contains(g) && g != Guid.Empty)
al.Add(g);
}
dr.Close();
foreach (object o in al)
{
NotifyEvent.AddOrUpdateEvent(RootObjectTypes.WorkorderItemPartRequest,
_WorkorderItemPartRequestID, (int)WorkorderItemPartRequestEvent.PartsReceived,
(Guid)o, new SmartDate(), Guid.Empty);
}
}
#endregion
}
}
#pragma warning restore 1591
#endregion Inventory receipt Processing
}//end WorkorderItemPartRequest
#region Notification events
#pragma warning disable 1591
public enum WorkorderItemPartRequestEvent : int
{
[Description("LT:WorkorderItemPartRequest.Label.Event.PartsReceived")]
PartsReceived = 1
}
#pragma warning restore 1591
#endregion
}//end namespace GZTW.AyaNova.BLL