/////////////////////////////////////////////////////////// // 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; //case 3832 private bool mReplied; #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(); } } } } //case 3832 public bool Replied { get { return mViewed; } } /// /// 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, Guid __ID)//case 3832 for v8 migrate { if (__ID == new Guid("{BD608E8A-820C-46D1-9D81-4CCB6E71B213}")) return (Memo)DataPortal.Fetch(new Criteria(_ID)); else //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 //case 3832 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"); mReplied = dr.GetBoolean("aReplied"); } 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