/////////////////////////////////////////////////////////// // WorkorderPreventiveMaintenance.cs // Implementation of Class WorkorderPreventiveMaintenance // CSLA type: Editable Child // Created on: 17-Nov-2005 // Object design: Joyce / John // Coded: John 17-Nov-2005 /////////////////////////////////////////////////////////// using System; using System.Data; using CSLA.Data; using CSLA; using System.Threading; using CSLA.Security; using GZTW.Data; namespace GZTW.AyaNova.BLL { /// /// Preventive maintenance header component of a object of PreventiveMaintenance /// A workorder that is used to generate service work orders /// on a schedule. /// [Serializable] public class WorkorderPreventiveMaintenance : BusinessBase { #region Attributes private bool bReadOnly; private SmartDate mCreated; private Guid mCreator; private SmartDate mModified; private Guid mModifier; private Guid mID; private int mPreventiveMaintenanceNumber; private Guid mWorkorderStatusID; private Guid mWorkorderID; private AyaDayOfWeek mDayOfTheWeek; private SmartDate mStopGeneratingDate; private bool mActive; private int mGenerateSpan; private int mThresholdSpan; private SmartDate mNextServiceDate; private AyaUnitsOfTime mGenerateSpanUnit; private AyaUnitsOfTime mThresholdSpanUnit; private SmartDate mGenerateDate; #endregion #region Constructor private WorkorderPreventiveMaintenance() { //Set to read / write initially so that properties //can be set bReadOnly = false; //Child object MarkAsChild(); //New ID mID = Guid.NewGuid(); //important this be set to zero to indicate not set yet //so sql server sp can set by using incremental value mPreventiveMaintenanceNumber = 0; //mRangeStartDate=new SmartDate(); mStopGeneratingDate = new SmartDate(); //Set record history to defaults mCreated = new SmartDate(DBUtil.CurrentWorkingDateTime); mModified = new SmartDate(); mCreator = Guid.Empty; mModifier = Guid.Empty; mDayOfTheWeek = AyaDayOfWeek.AnyDayOfWeek; mActive = true; mGenerateSpan = 1; mGenerateSpanUnit = AyaUnitsOfTime.Months; mNextServiceDate = new SmartDate(DBUtil.CurrentWorkingDateTime.AddMonths(1)); mThresholdSpan = 7; mThresholdSpanUnit = AyaUnitsOfTime.Days; //ensure there is a default so it doesn't crash on save //if user using api and doesn't set anything this.SetGenerateDate(); } #endregion #region BusinessProperties //---Common properties /// /// Initial created date of this object /// public string Created { get { return mCreated.ToString(); } } /// /// User ID of who initially created this object /// public Guid Creator { get { return mCreator; } } /// /// Last modified date of this object /// public string Modified { get { return mModified.ToString(); } } /// /// User ID of who last modified this object /// public Guid Modifier { get { return mModifier; } } /// /// Unique ID of this object /// public Guid ID { get { return mID; } } //---WorkorderPreventiveMaintenance specific properties /// /// Incremental number from sql server /// public int PreventiveMaintenanceNumber { get { return mPreventiveMaintenanceNumber; } set { if (bReadOnly) ThrowSetError(); else { if (mPreventiveMaintenanceNumber != value) { mPreventiveMaintenanceNumber = value; MarkDirty(); } } } } /// /// ID of Status the service workorder will set to when generated /// public Guid WorkorderStatusID { get { return mWorkorderStatusID; } set { if (mWorkorderStatusID != value) { mWorkorderStatusID = value; MarkDirty(); } } } /// /// ID of root object this belongs to (workorder) /// public Guid WorkorderID { get { return mWorkorderID; } // set // { // if(mWorkorderID!=value) // { // mWorkorderID = value; // MarkDirty(); // // } // } } /// /// Desired day of the week to force service to /// /// public AyaDayOfWeek DayOfTheWeek { get { return mDayOfTheWeek; } set { if (bReadOnly) ThrowSetError(); else { if (mDayOfTheWeek != value) { mDayOfTheWeek = value; MarkDirty(); } } } } internal DateTime dtStopGeneratingDate { get { return mStopGeneratingDate.Date; } } /// /// Date that generator will stop Processing this PM /// (expiry date) /// After this date it will flip to inactive and /// remain for the user to delete or reactivate /// public object StopGeneratingDate { get { return mStopGeneratingDate.DBValue; } set { if (bReadOnly) ThrowSetError(); else { if (!AyaBizUtils.SmartDateEquals(mStopGeneratingDate, value)) //Case 298 { mStopGeneratingDate.DBValue = value; MarkDirty(); } } } } //******************* /// /// True=included in pm and makes workorders etc /// False=on hold, not used, not included in automatic pm stuff /// public bool Active { get { return mActive; } set { //Changed: 02-June-2006 was not checking if generator //and throwing a security exception when the generator //was setting to inactive automatically when it's stop generating //date came up if (!AyaBizUtils.IsGenerator && bReadOnly) ThrowSetError(); else { if (mActive != value) { mActive = value; MarkDirty(); } } } } /// /// Span of GenerateSpanUnits of time between workorder /// generations (for time based pm's) /// public int GenerateSpan { get { return mGenerateSpan; } set { if (bReadOnly) ThrowSetError(); else { if (mGenerateSpan != value) { mGenerateSpan = value; BrokenRules.Assert( "GenerateSpanInvalid", "Error.Object.RequiredFieldEmpty,WorkorderPreventiveMaintenance.Label.GenerateSpan", "GenerateSpan", value < 1); MarkDirty(); } } } } /// /// How far in advance to generate the workorder /// /// This is the number of ThresholdSpanUnits of time in advance of /// NextServiceDate to generate the service workorder. /// /// For example, if this value is 5, the ThresholdSpanUnits is Days /// and the NextServiceDate is March 12 then the workorder will be generated /// on March 7th, 5 days in advance of the service date. /// public int ThresholdSpan { get { return mThresholdSpan; } set { if (bReadOnly) ThrowSetError(); else { if (mThresholdSpan != value) { mThresholdSpan = value; BrokenRules.Assert( "ThresholdSpanInvalid", "Error.Object.RequiredFieldEmpty,WorkorderPreventiveMaintenance.Label.ThresholdSpan", "ThresholdSpan", value < 1); SetGenerateDate(); MarkDirty(); } } } } /// /// Date of next PM service. /// This will be the date used for the ServiceDate field /// in the service workorder. /// /// This value is originally set when the PM is first created and /// is then carried forward automatically when a service workorder is created off /// this PM, as well all other dates within the PM workorder are also carried forward /// relative to this date. This ensures that a scheduled tech for example one day after /// service date (follow up) still gets created one day after the new service date. /// /// /// The service workorder will be generated /// on or in advance of this date depending on the settings /// in the threshold fields. /// public object NextServiceDate { get { return mNextServiceDate.DBValue; } set { if (bReadOnly) ThrowSetError(); else { if (!AyaBizUtils.SmartDateEquals(mNextServiceDate, value)) //Case 298 { mNextServiceDate.DBValue = value; BrokenRules.Assert( "NextServiceDateInvalid", "Error.Object.RequiredFieldEmpty,WorkorderPreventiveMaintenance.Label.NextServiceDate", "NextServiceDate", mNextServiceDate.IsEmpty); SetGenerateDate(); MarkDirty(); } } } } internal DateTime dtNextServiceDate { get { return mNextServiceDate.Date; } set { if (mNextServiceDate.Date != value) { mNextServiceDate.Date = value; SetGenerateDate(); MarkDirty(); } } } /// /// A unit of time used in conjunction with the value of /// GenerateSpan to determine the frequency of PM service. /// (I.E. if this is set to AyaUnitsOfTime.Months and /// GenerateSpan is set to 6 then a service workorder will be generated /// every 6 months) /// public AyaUnitsOfTime GenerateSpanUnit { get { return mGenerateSpanUnit; } set { if (bReadOnly) ThrowSetError(); else { if (mGenerateSpanUnit != value) { mGenerateSpanUnit = value; SetGenerateDate(); MarkDirty(); } } } } /// /// A unit of time used in conjunction with the value of /// ThresholdSpan to determine how far in advance of the /// NextServiceDate to generate a service workorder /// public AyaUnitsOfTime ThresholdSpanUnit { get { return mThresholdSpanUnit; } set { if (bReadOnly) ThrowSetError(); else { if (mThresholdSpanUnit != value) { mThresholdSpanUnit = value; SetGenerateDate(); MarkDirty(); } } } } /// /// Calculate generate date based on service date and /// threshold span and unit /// internal void SetGenerateDate() { if (this.mNextServiceDate.IsEmpty) return; if (this.mThresholdSpan == 0) { this.mGenerateDate = this.mNextServiceDate; MarkDirty(); return; } mGenerateDate = new SmartDate(Workorder.GetDateFromSpanAndUnit(mNextServiceDate.Date, this.mThresholdSpanUnit, -mThresholdSpan)); MarkDirty(); } //********************** /// /// 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) /// private void ThrowSetError() { throw new System.Security.SecurityException ( string.Format ( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToChange"), LocalizedTextTable.GetLocalizedTextDirect("O.WorkorderPreventiveMaintenance") ) ); } #endregion #region System.object overrides /// /// /// /// public override string ToString() { return "WorkorderPreventiveMaintenance" + mID.ToString(); } /// /// /// /// /// public override bool Equals(Object obj) { if (obj == null || GetType() != obj.GetType()) return false; WorkorderPreventiveMaintenance c = (WorkorderPreventiveMaintenance)obj; return mID == c.mID; } /// /// /// /// public override int GetHashCode() { return ("WorkorderPreventiveMaintenance" + mID).GetHashCode(); } #endregion #region Searching /// /// Returns a search result object based on search terms /// for the ID specified /// /// /// /// public static SearchResult GetSearchResult(Guid ID, string[] searchTerms) { //case 1387 if (Workorder.RightsToWorkorder(WorkorderIDFetcher.GetWorkorderByRelative(RootObjectTypes.WorkorderPreventiveMaintenance, ID)) < SecurityLevelTypes.ReadOnly) return new SearchResult(); SearchResult sr = new SearchResult(); System.Text.StringBuilder sb = new System.Text.StringBuilder(); SafeDataReader dr = null; try { dr = DBUtil.GetReaderFromSQLString( "SELECT AWORKORDERPREVENTIVEMAINTENANCE.AID,ACLIENT.AREGIONID AS ACLIENTREGION, ACLIENT.ANAME AS ACLIENTNAME, " + "AWORKORDERPREVENTIVEMAINTENANCE.ACREATOR, AWORKORDERPREVENTIVEMAINTENANCE.AMODIFIER, " + " AWORKORDERPREVENTIVEMAINTENANCE.ACREATED, " + "AWORKORDERPREVENTIVEMAINTENANCE.AMODIFIED, AWORKORDERPREVENTIVEMAINTENANCE.APREVENTIVEMAINTENANCENUMBER " + " FROM ACLIENT " + "INNER JOIN AWORKORDER ON ACLIENT.AID = AWORKORDER.ACLIENTID " + "RIGHT OUTER JOIN AWORKORDERPREVENTIVEMAINTENANCE ON AWORKORDER.AID " + "= AWORKORDERPREVENTIVEMAINTENANCE.AWORKORDERID " + "WHERE (AWORKORDERPREVENTIVEMAINTENANCE.AID=@ID)" , ID); if (!dr.Read()) return new SearchResult(); if (!AyaBizUtils.InYourRegion(dr.GetGuid("ACLIENTREGION"))) return new SearchResult();//case 58 //Case 88 sr.Description = LocalizedTextTable.GetLocalizedTextDirect("O.WorkorderPreventiveMaintenance") + " " + dr.GetInt32("APREVENTIVEMAINTENANCENUMBER").ToString() + " " + dr.GetString("ACLIENTNAME"); //sb.Append(dr.GetString("aIntroduction")); sr.Created = DBUtil.ToLocal(dr.GetSmartDate("aCreated")); sr.Modified = DBUtil.ToLocal(dr.GetSmartDate("aModified")); sr.Creator = dr.GetGuid("aCreator"); sr.Modifier = dr.GetGuid("aModifier"); } finally { if (dr != null) dr.Close(); } //Formulate results ExtractAndRank er = new ExtractAndRank(); er.Process(sb.ToString().Trim(), searchTerms); sr.Extract = er.Extract; sr.Rank = er.Ranking; sr.AncestorRootObjectID = ID; sr.AncestorRootObjectType = RootObjectTypes.WorkorderQuote; return sr; } #endregion #region Static methods /// /// Create item /// /// Parent ID /// New Item internal static WorkorderPreventiveMaintenance NewItem(Workorder obj) { //case 1387 no need to check rights here because parent workorder object now checks correct rights by type //if(AyaBizUtils.IsGenerator || AyaBizUtils.Right("Object.WorkorderPreventiveMaintenance")>(int)SecurityLevelTypes.ReadOnly) //{ WorkorderPreventiveMaintenance child = new WorkorderPreventiveMaintenance(); child.mWorkorderID = obj.ID; return child; //} //else // throw new System.Security.SecurityException( // string.Format( // LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToCreate"), // LocalizedTextTable.GetLocalizedTextDirect("O.WorkorderPreventiveMaintenance"))); } /// /// Retrieve item /// /// Data reader /// item from database internal static WorkorderPreventiveMaintenance GetItem(SafeDataReader dr) { //case 1387 no need to check rights here because parent workorder object now checks correct rights by type //if(AyaBizUtils.Right("Object.WorkorderPreventiveMaintenance")>(int)SecurityLevelTypes.NoAccess) //{ WorkorderPreventiveMaintenance child = new WorkorderPreventiveMaintenance(); child.Fetch(dr); return child; //} //else // throw new System.Security.SecurityException( // string.Format( // LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToRetrieve"), // LocalizedTextTable.GetLocalizedTextDirect("O.WorkorderPreventiveMaintenance"))); } #endregion #region DAL DATA ACCESS #region Fetch /// /// Fetch from db /// /// private void Fetch(SafeDataReader dr) { //Standard items mCreated = DBUtil.ToLocal(dr.GetSmartDate("aCreated")); mCreator = dr.GetGuid("aCreator"); mModified = DBUtil.ToLocal(dr.GetSmartDate("aModified")); mModifier = dr.GetGuid("aModifier"); mID = dr.GetGuid("aID"); mWorkorderStatusID = dr.GetGuid("aWorkorderStatusID"); mWorkorderID = dr.GetGuid("aWorkorderID"); mDayOfTheWeek = (AyaDayOfWeek)dr.GetInt16("aDayOfTheWeek"); mStopGeneratingDate = DBUtil.ToLocal(dr.GetSmartDate("aStopGeneratingDate")); this.mNextServiceDate = DBUtil.ToLocal(dr.GetSmartDate("aNextServiceDate")); this.mGenerateDate = DBUtil.ToLocal(dr.GetSmartDate("aGenerateDate")); mActive = dr.GetBoolean("AACTIVE"); mGenerateSpan = dr.GetInt32("aGenerateSpan"); this.mPreventiveMaintenanceNumber = dr.GetInt32("aPreventiveMaintenanceNumber"); //GenerateSpanUnit this.mGenerateSpanUnit = (AyaUnitsOfTime)dr.GetInt16("aGenerateSpanUnit"); //ThresholdSpan this.mThresholdSpan = dr.GetInt32("aThresholdSpan"); //ThresholdSpanUnit this.mThresholdSpanUnit = (AyaUnitsOfTime)dr.GetInt16("aThresholdSpanUnit"); //Get access rights level bReadOnly = AyaBizUtils.Right("Object.WorkorderPreventiveMaintenance") < (int)SecurityLevelTypes.ReadWrite; MarkOld(); } #endregion #region Add / Update /// /// Persist object to database /// /// Parent object /// Parents transaction object internal void Update(Workorder 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, "aWorkorderPreventiveMaintenance", tr);//case 1960 #region Delete if (IsDeleted) { if (!IsNew) { DBCommandWrapper cmDelete = DBUtil.GetCommandFromSQL("DELETE FROM aWorkorderPreventiveMaintenance 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? if (this.mPreventiveMaintenanceNumber != 0)//importing? { DBUtil.AllowIdentityInsert();//Tell database to allow inserts into the identity field cm = DBUtil.GetCommandFromSQL( "INSERT INTO aWorkorderPreventiveMaintenance ( " + "aID,aWorkorderID, " + "aCreator,aModifier, " + "aCreated,aModified, " + "aWorkorderStatusID, aStopGeneratingDate, " + "aDayOfTheWeek, AACTIVE, " + "aNextServicedate, " + "aGenerateSpan, aGenerateSpanUnit, aGenerateDate, " + "aThresholdSpan, aThresholdSpanUnit, aPreventiveMaintenanceNumber) " + "VALUES ( " + "@ID, @WorkorderID, " + "@CurrentUserID, @CurrentUserID, " + "@Created,@Modified, " + "@WorkorderStatusID, @StopGeneratingDate, " + "@DayOfTheWeek, @Active, " + "@NextServicedate, " + "@GenerateSpan, @GenerateSpanUnit, @GenerateDate, " + "@ThresholdSpan, @ThresholdSpanUnit, @PreventiveMaintenanceNumber)" ); //add service number parameter cm.AddInParameter("@PreventiveMaintenanceNumber", DbType.Int32, this.mPreventiveMaintenanceNumber); } else { cm = DBUtil.GetCommandFromSQL( "INSERT INTO aWorkorderPreventiveMaintenance ( " + "aID,aWorkorderID, " + "aCreator,aModifier, " + "aCreated,aModified, " + "aWorkorderStatusID, aStopGeneratingDate, " + "aDayOfTheWeek, AACTIVE, " + "aNextServicedate, " + "aGenerateSpan, aGenerateSpanUnit, aGenerateDate, " + "aThresholdSpan, aThresholdSpanUnit) " + "VALUES ( " + "@ID, @WorkorderID, " + "@CurrentUserID, @CurrentUserID, " + "@Created,@Modified, " + "@WorkorderStatusID, @StopGeneratingDate, " + "@DayOfTheWeek, @Active, " + "@NextServicedate, " + "@GenerateSpan, @GenerateSpanUnit, @GenerateDate, " + "@ThresholdSpan, @ThresholdSpanUnit)" ); } else cm = DBUtil.GetCommandFromSQL( "UPDATE aWorkorderPreventiveMaintenance SET " + "aWorkorderID=@WorkorderID, " + "aModifier=@CurrentUserID, " + "aModified=@Modified, " + "aWorkorderStatusID=@WorkorderStatusID, aStopGeneratingDate=@StopGeneratingDate, " + "aDayOfTheWeek=@DayOfTheWeek, AACTIVE=@Active, " + "aNextServicedate=@NextServicedate, " + "aGenerateSpan=@GenerateSpan, aGenerateSpanUnit=@GenerateSpanUnit, aGenerateDate=@GenerateDate, " + "aThresholdSpan=@ThresholdSpan, aThresholdSpanUnit=@ThresholdSpanUnit " + "WHERE aID=@ID"); //WorkorderPreventiveMaintenance specific parameters cm.AddInParameter("@ID", DbType.Guid, mID); cm.AddInParameter("@WorkorderID", DbType.Guid, mWorkorderID); cm.AddInParameter("@WorkorderStatusID", DbType.Guid, mWorkorderStatusID); cm.AddInParameter("@StopGeneratingDate", DbType.DateTime, DBUtil.ToUTC(mStopGeneratingDate).DBValue); cm.AddInParameter("@DayOfTheWeek", DbType.Int16, (int)mDayOfTheWeek); cm.AddInParameter("@Active", DbType.Boolean, mActive); cm.AddInParameter("@NextServiceDate", DbType.DateTime, DBUtil.ToUTC(mNextServiceDate).DBValue); cm.AddInParameter("@GenerateSpan", DbType.Int32, mGenerateSpan); cm.AddInParameter("@GenerateSpanUnit", DbType.Int16, (int)mGenerateSpanUnit); cm.AddInParameter("@ThresholdSpan", DbType.Int32, mThresholdSpan); cm.AddInParameter("@ThresholdSpanUnit", DbType.Int16, (int)mThresholdSpanUnit); cm.AddInParameter("@GenerateDate", DbType.DateTime, DBUtil.ToUTC(mGenerateDate).DBValue); //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); //Get new DB generated identity value if (IsNew) this.mPreventiveMaintenanceNumber = DBUtil.GetIdentity("aPreventiveMaintenanceNumber", "aWorkorderPreventiveMaintenance", this.mID, tr); MarkOld();//db is now synched with object //Successful update so //change modification time to match this.mModified.Date = dtModified; #endregion } #endregion #endregion }//end WorkorderPreventiveMaintenance }//end namespace GZTW.AyaNova.BLL