/////////////////////////////////////////////////////////// // Memo.cs // Implementation of Class Memo // CSLA type: Editable Root // Created on: 30-Aug-2004 // Object design: John // Coded: John 30-Aug-2004 /////////////////////////////////////////////////////////// using System; using System.Data; using CSLA.Data; using GZTW.Data; using CSLA; using System.Threading; using CSLA.Security; using System.ComponentModel; using System.Text; namespace GZTW.AyaNova.BLL { /// /// AyaNova Memo between AyaNova users. /// Used to create *new* Memo message only /// [Serializable] public class Memo : BusinessBase { #region Attributes private bool bReadOnly; private Guid mID; private SmartDate mCreated; private SmartDate mModified; private Guid mCreator; private Guid mModifier; private string mSubject=null; private string mMessage=""; private Guid mFromID; private Guid mToID; private bool mViewed; #endregion #region Constructor /// /// Private constructor to prevent direct instantiation /// private Memo() { //Set to read / write initially so that properties //can be set bReadOnly=false; //New ID mID = Guid.NewGuid(); Subject=""; Message=""; mViewed=false; this.mFromID=CurrentUserID; //Set record history to defaults mCreated = new SmartDate(DBUtil.CurrentWorkingDateTime); mModified=new SmartDate(); mCreator=Guid.Empty; mModifier=Guid.Empty; } #endregion #region Business properties /// /// Get internal id number Read only property because it's set internally, not /// externally /// public Guid ID { get { return mID; } } /// /// Get created date /// /// /// public string Created { get { return mCreated.ToString(); } } /// /// Set created date /// only used for importing /// old MAIL from AyaNova CE /// /// public SmartDate zInternal { set { if(bReadOnly) ThrowSetError(); else { if(mCreated!=value) { mCreated = value; MarkDirty(); } } } } /// /// Get modified date /// /// /// public string Modified { get { return mModified.ToString(); } } /// /// Get user record ID of person who created this record /// /// /// public Guid Creator { get { return mCreator; } } /// /// Get user ID of person who modified this record /// /// /// public Guid Modifier { get { return mModifier; } } /// /// Set/get Subject of item /// Required, can't be empty /// public string Subject { get { return mSubject; } set { if(bReadOnly) ThrowSetError(); else { if(mSubject!=value) { mSubject = value; BrokenRules.Assert("SubjectRequired", "Error.Object.RequiredFieldEmpty,Memo.Label.Subject", "Subject",value.Length==0); MarkDirty(); } } } } /// /// Set/get Subject of item /// /// public string Message { get { return mMessage; } set { if(bReadOnly) ThrowSetError(); else { if(mMessage!=value) { mMessage = value; MarkDirty(); } } } } /// /// From whom /// public Guid FromID { get { return mFromID; } set { if(bReadOnly) ThrowSetError(); else { if(mFromID!=value) { mFromID = value; MarkDirty(); } } } } /// /// To whom /// public Guid ToID { get { return mToID; } set { if(bReadOnly) ThrowSetError(); else { if(mToID!=value) { mToID = value; MarkDirty(); } } } } /// /// Viewed - user has read the message /// public bool Viewed { get { return mViewed; } set { if(bReadOnly) ThrowSetError(); else { if(mViewed!=value) { mViewed = value; 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.Memo") ) ); } #endregion #region System.Object overrides /// /// /// /// public override string ToString() { return "Memo" + mID.ToString(); } /// /// /// /// /// public override bool Equals(Object obj) { if ( obj == null || GetType ( ) != obj.GetType ( ) ) return false; Memo c=(Memo)obj; return mID==c.mID; } /// /// /// /// public override int GetHashCode() { return ("Memo" + 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) { if(AyaBizUtils.Right("Object.Memo")<(int)SecurityLevelTypes.ReadOnly) return new SearchResult(); Guid To=Guid.Empty; Guid From=Guid.Empty; SearchResult sr=new SearchResult(); System.Text.StringBuilder sb = new System.Text.StringBuilder(); SafeDataReader dr = null; try { dr=DBUtil.GetReaderFromSQLString( "SELECT aID, aCreated, aModified, aCreator, aModifier, aSubject, " + " aMessage, aFromID, aToID FROM aMemo WHERE (aID " + "= @ID)" ,ID); if(!dr.Read()) return new SearchResult();//DBUtil.ThrowFetchError("SearchResult for MemoID: " + ID.ToString()); sr.Description=dr.GetString("aSubject"); sb.Append(sr.Description); sb.Append(" "); sb.Append(dr.GetString("aMessage")); From=dr.GetGuid("aFromID"); To=dr.GetGuid("aToID"); 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(); } //Security..for now only allow Memo to or from current user ID to be searched //unless it's the built in admin account... if(!User.IsAdmin) { //If it's not for or from current user then bail if(User.CurrentThreadUserID != To && User.CurrentThreadUserID!=From) return new SearchResult(); } //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.Memo; return sr; } #endregion #region Static methods /// /// Get new object /// /// public static Memo NewItem() { if(AyaBizUtils.IsGenerator || AyaBizUtils.Right("Object.Memo")>(int)SecurityLevelTypes.ReadOnly) return new Memo(); else throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToCreate"), LocalizedTextTable.GetLocalizedTextDirect("O.Memo"))); } /// /// Memo Guid public static Memo GetItem(Guid _ID) { //Memo is write only, once it's sent you can't retrieve it again throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToRetrieve"), LocalizedTextTable.GetLocalizedTextDirect("O.Memo"))); } /// /// Delete Memo /// /// Memo GUID public static void DeleteItem(Guid _ID) { if(AyaBizUtils.Right("Object.Memo")>(int)SecurityLevelTypes.ReadWrite) DataPortal.Delete(new Criteria(_ID)); else throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToDelete"), LocalizedTextTable.GetLocalizedTextDirect("O.Memo"))); } /// /// Used by UI to flag a memo has having been read when it's displayed to the end user /// /// public static void FlagMessageRead(Guid _MemoID) { MemoFlagger.SetMemoFlags(_MemoID,true,false); } /// /// Used by the UI to flag a memo has having been replied to when end user creates a new memo and sends it /// based off an existing received memo /// /// public static void FlagMessageReplied(Guid _MemoID) { MemoFlagger.SetMemoFlags(_MemoID,false,true); } #endregion #region Shared Notification Message Processor internal static NotifyMessage GetNotificationMessage(NotifyMessageRequestData d) { //string Language=User.GetUserLanguage(MessageForUserID); MemoFetcher mf = MemoFetcher.GetItem(d.RootObjectID, d.Language); string sMessage = LocalizedTextTable.GetLocalizedTextDirect("O.Memo", d.Language); NotifyMessage nm=null; if (d.Format == NotifyDeliveryMessageFormats.Brief) { sMessage+="-" + mf.From + "-" + mf.Subject; if (d.MaxCharacters > 0 && sMessage.Length > d.MaxCharacters) nm = new NotifyMessage("", sMessage.Substring(0, d.MaxCharacters)); else nm=new NotifyMessage("", sMessage); } else { sMessage+="\r\n" + mf.Header + "\r\n\r\n" + mf.Message; nm=new NotifyMessage(mf.Subject,sMessage); } return nm; } #endregion #region DAL DATA ACCESS #region Fetch // /// // /// // 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 aMemo WHERE aID=@ID;",crit.ID); // if(!dr.Read()) // DBUtil.ThrowFetchError("Memo 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"); // // // //Memo fields // //Important: use property not internal field // //so that initial broken rule is unbroken on fetch // Subject=dr.GetString("aSubject"); // mMessage=dr.GetString("aMessage"); // mFromID=dr.GetGuid("aFromID"); // mToID=dr.GetGuid("aToID"); // mViewed=dr.GetBoolean("aViewed"); // // // } // finally // { // if(dr!=null) dr.Close(); // } // MarkOld(); // // // //Get access rights level // bReadOnly=AyaBizUtils.Right("Object.Memo")<(int)SecurityLevelTypes.ReadWrite; // } // #endregion fetch #region Update /// /// Called by DataPortal to delete/add/update data into the database /// protected override void DataPortal_Update() { //If not a new record, check if record was modified //by another user since original retrieval: if(!IsNew) DBUtil.CheckSafeToUpdate(this.mModified.Date,this.mID,"aMemo"); #region Delete if(IsDeleted) { throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToRetrieve"), LocalizedTextTable.GetLocalizedTextDirect("O.Memo"))); // if(!IsNew) // { // // // //Delete object and child objects // DBCommandWrapper cmDelete = DBUtil.GetCommandFromSQL("DELETE FROM aMemo WHERE aID = @ID;"); // cmDelete.AddInParameter("@ID",DbType.Guid,this.mID); // // // // using (IDbConnection connection = DBUtil.DB.GetConnection()) // { // connection.Open(); // IDbTransaction transaction = connection.BeginTransaction(); // // try // { // // DBUtil.DB.ExecuteNonQuery(cmDelete, transaction); // DBUtil.RemoveKeywords(transaction,RootObjectTypes.Memo,this.mID); // // // Commit the transaction // transaction.Commit(); // // } // catch // { // // Rollback transaction // transaction.Rollback(); // throw; // } // finally // { // connection.Close(); // } // } // // // //----------------------------- // } // 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 aMemo (aID, aSubject, aMessage, aFromID, aToID, aViewed, aReplied, aCreator,aModifier,aCreated, aModified) " + "VALUES (@ID,@Subject,@Message,@FromID,@ToID,@Viewed,@Replied,@CurrentUserID,@CurrentUserID,@Created,@Modified);" ); else cm=DBUtil.GetCommandFromSQL( "UPDATE aMemo SET aID=@ID, aSubject=@Subject, aMessage=@Message, " + "aFromID=@FromID, aToID=@ToID, aViewed=@Viewed, " + "aModifier=@CurrentUserID, aModified=@Modified " + "WHERE aID=@ID;" ); cm.AddInParameter("@ID",DbType.Guid,mID); cm.AddInParameter("@Subject", DbType.String, mSubject); cm.AddLargeStringInParameter("@Message", mMessage); cm.AddInParameter("@FromID", DbType.Guid, mFromID); cm.AddInParameter("@ToID",DbType.Guid, mToID); cm.AddInParameter("@Viewed", DbType.Boolean, mViewed); cm.AddInParameter("@Replied", DbType.Boolean, false); //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(); IDbTransaction transaction = connection.BeginTransaction(); try { DBUtil.DB.ExecuteNonQuery(cm, transaction); //Process keywords DBUtil.ProcessKeywords(transaction,this.mID,RootObjectTypes.Memo,IsNew,AyaBizUtils.Break(false, mSubject,mMessage)); 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; //Process events as necessary if(AyaBizUtils.GlobalSettings.UseNotification)//Case 509 { NotifyEvent.AddOrUpdateEvent(RootObjectTypes.Memo,this.mID,(int)MemoEvent.Created,this.mToID,new SmartDate(),Guid.Empty); } } #endregion } #endregion update #region Delete /// /// Remove a Memo record from the database /// /// protected override void DataPortal_Delete(object Criteria) { Criteria crit = (Criteria)Criteria; //Delete object DBCommandWrapper cmDelete = DBUtil.GetCommandFromSQL("DELETE FROM aMemo WHERE aID = @ID;"); cmDelete.AddInParameter("@ID",DbType.Guid,crit.ID); using (IDbConnection connection = DBUtil.DB.GetConnection()) { connection.Open(); IDbTransaction transaction = connection.BeginTransaction(); try { DBUtil.DB.ExecuteNonQuery(cmDelete, transaction); DBUtil.RemoveKeywords(transaction,RootObjectTypes.Memo,crit.ID); // Commit the transaction transaction.Commit(); } catch { // Rollback transaction transaction.Rollback(); throw; } finally { connection.Close(); } //Remove any events for this object if (AyaBizUtils.GlobalSettings.UseNotification)//Case 510 { NotifyEvent.RemoveAllEventsForObject(crit.ID); } } } #endregion delete #endregion #region Override IsValid / IsDirty //Override base class version if there are child objects /* public override bool IsValid { get { return base.IsValid && ChildItem.IsValid; } } public override bool IsDirty { get { return base.IsDirty || ChildItem.IsDirty; } } */ #endregion #region criteria /// /// Criteria for identifying existing object /// [Serializable] private class Criteria { public Guid ID; public Criteria(Guid _ID) { ID=_ID; } } #endregion #region Flag MessageReadReplied #pragma warning disable 1591 /// /// Update eMemo messages /// [Serializable, System.ComponentModel.Browsable(false)] public class MemoFlagger//DO_NOT_OBFUSCATE { bool _SetRead=false; bool _SetReplied=false; Guid _MemoID; public MemoFlagger(Guid MemoID, bool SetRead, bool SetReplied) { _MemoID=MemoID; _SetRead = SetRead; _SetReplied=SetReplied; } public static void SetMemoFlags(Guid MemoID, bool SetRead, bool SetReplied) { DataPortal.Update(new MemoFlagger( MemoID, SetRead, SetReplied)); } public void DataPortal_Update() { DBCommandWrapper cm = null; if(_SetRead) cm=DBUtil.GetCommandFromSQL( "UPDATE aMemo SET aViewed=@TRUE " + "WHERE aID=@ID;" ); if(_SetReplied) cm=DBUtil.GetCommandFromSQL( "UPDATE aMemo SET aReplied=@TRUE " + "WHERE aID=@ID;" ); cm.AddInParameter("@ID",DbType.Guid,_MemoID); cm.AddInParameter("@TRUE", DbType.Boolean, true); DBUtil.DB.ExecuteNonQuery(cm); } } #pragma warning restore 1591 #endregion memo flagger }//end Memo #region Notification events /// /// /// public enum MemoEvent : int { /// /// /// [Description("LT:Memo.Label.Event.Created")] Created=1 } #endregion }//end Subjectspace GZTW.AyaNova.BLL