/////////////////////////////////////////////////////////// // Report.cs // Implementation of Class Report // CSLA type: Editable Root // Created on: 21-March-2005 // Object design: John // Coded: John 21-March-2005 /////////////////////////////////////////////////////////// using System; using System.Data; using CSLA.Data; using GZTW.Data; using CSLA; using System.Threading; using CSLA.Security; //using log4net; using System.IO; //using System.Collections; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization; namespace GZTW.AyaNova.BLL { #pragma warning disable 1591 /// /// Report /// [Serializable] public class Report : BusinessBase { // Create a logger for use in this class //private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); #region Attributes private bool bReadOnly; private Guid mID; private string mName=null; private SmartDate mCreated; private SmartDate mModified; private Guid mCreator; private Guid mModifier; private string mReportKey=null; private int mReportSize; private byte[] mReportContent; private bool mActive; //case 58 private Guid mRegionID; //case 36 private Guid mSecurityGroupID; #endregion #region Constructor /// /// Private constructor to prevent direct instantiation /// private Report() { ////case 1039 //log.Debug("Report()"); //Set to read / write initially so that properties //can be set bReadOnly=false; //New ID mID = Guid.NewGuid(); //pre-break the rule Name=""; ReportKey=""; mReportSize=0; mActive=true; //Set record history to defaults mCreated = new SmartDate(DBUtil.CurrentWorkingDateTime); mModified=new SmartDate(); mCreator=Guid.Empty; mModifier=Guid.Empty; //Built-in "Default" region mRegionID = Region.DefaultRegionID;//case 58 //All groups mSecurityGroupID = 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(); } } /// /// 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 name /// public string Name { get { return mName; } set { if(bReadOnly) ThrowSetError(); else { if(mName!=value) { mName = value; BrokenRules.Assert("NameRequired","Error.Object.RequiredFieldEmpty,Report.Label.Name","Name",value.Length==0); BrokenRules.Assert("NameLength", "Error.Object.FieldLengthExceeded255,Report.Label.Name","Name",value.Length>255); MarkDirty(); } } } } /// /// Set/get ReportKey /// public string ReportKey { get { return mReportKey; } set { if(bReadOnly) ThrowSetError(); else { if(mReportKey!=value) { mReportKey = value; BrokenRules.Assert("ReportKeyRequired","Error.Object.RequiredFieldEmpty,Report.Label.ReportKey","ReportKey",value.Length==0); BrokenRules.Assert("ReportKeyLength", "Error.Object.FieldLengthExceeded255,Report.Label.ReportKey","ReportKey",value.Length>255); MarkDirty(); } } } } /// /// Size of binary layout data content /// public int ReportSize { get { return mReportSize; } set { if(mReportSize!=value) { mReportSize=value; MarkDirty(); } } } /// /// /// /// public System.IO.MemoryStream GetReportContent() { ////case 1039 //log.Debug("GetReportContent()"); return new System.IO.MemoryStream(mReportContent); } public void SetReportContent(System.IO.MemoryStream mStream) { mStream.Position=0; byte[] bData=new byte[mStream.Length+1]; mStream.Read(bData,0,(int)mStream.Length); ReportSize=(int)mStream.Length; mReportContent=bData; MarkDirty(); } /// /// True=reports are visible in print menu /// False=reports are not shown in print menu /// public bool Active { get { return mActive; } set { if(mActive!=value) { mActive=value; MarkDirty(); } } } /// /// Limit to specific region or available to all regions using Region.DefaultRegionID /// public Guid RegionID { get { return mRegionID; } set { if (bReadOnly) ThrowSetError(); else { if (mRegionID != value) { mRegionID = value; BrokenRules.Assert("RegionIDRequired", "Error.Object.RequiredFieldEmpty,O.Region", "RegionID", value == Guid.Empty); MarkDirty(); } } } } /// /// Limit to specific SecurityGroup or available to all if guid.empty /// public Guid SecurityGroupID { get { return mSecurityGroupID; } set { if (bReadOnly) ThrowSetError(); else { if (mSecurityGroupID != value) { mSecurityGroupID = 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.Report") ) ); } #endregion #region System.Object overrides public override string ToString() { return "Report" + mID.ToString(); } /// /// public override bool Equals(Object obj) { if ( obj == null || GetType ( ) != obj.GetType ( ) ) return false; Report c=(Report)obj; return mID==c.mID; } public override int GetHashCode() { return ("Report"+mID).GetHashCode(); } #endregion #region Static methods /// /// True if current logged in user has sufficient /// rights to view reports /// (this does not necessarily indicate that they are allowed to edit them) /// public static bool UserCanViewReports { get { return (AyaBizUtils.Right("Object.Report") > (int)SecurityLevelTypes.NoAccess); } } /// /// Create new Report /// public static Report NewItem() { if(AyaBizUtils.Right("Object.Report")>(int)SecurityLevelTypes.ReadOnly) return new Report(); else throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToCreate"), LocalizedTextTable.GetLocalizedTextDirect("O.Report"))); } /// /// Fetch existing Report /// /// Client Guid public static Report GetItem(Guid _ID) { if(AyaBizUtils.Right("Object.Report")>(int)SecurityLevelTypes.NoAccess) return (Report)DataPortal.Fetch(new Criteria(_ID)); else throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToRetrieve"), LocalizedTextTable.GetLocalizedTextDirect("O.Report"))); } /// /// Delete Report (if clients assigned to this group, should be notified) /// /// Client GUID public static void DeleteItem(Guid _ID) { if(AyaBizUtils.Right("Object.Report")>(int)SecurityLevelTypes.ReadWrite) DataPortal.Delete(new Criteria(_ID)); else throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToDelete"), LocalizedTextTable.GetLocalizedTextDirect("O.Report"))); } /// /// Retrieve internal ID from name. /// /// /// Text value /// Guid ID value or Guid.Empty if no match public static Guid GetIDFromName(string Name) { return GuidFetcher.GetItem("AREPORT", "ANAME", Name); } #endregion #region Serialization /// /// Export layout to an AyaNova Transportable Report file (.AYR) at the path indicated /// /// Guid of existing report in database /// Full path (including file name) to export to. NOTE: By convention, all AyaNova report file names end in the extension .AYR public static void ExportLayout(Guid ReportID, string Path) { Report r=Report.GetItem(ReportID); ReportLayout rl=new ReportLayout(); rl.ID=r.ID; rl.Name=r.Name; rl.ReportContent=r.mReportContent; rl.ReportKey=r.ReportKey; rl.ReportSize=r.ReportSize; FileStream fs = new FileStream(Path, FileMode.Create); // Construct a BinaryFormatter and use it to serialize the data to the stream. BinaryFormatter formatter = new BinaryFormatter(); formatter.AssemblyFormat=System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; try { formatter.Serialize(fs, rl); } catch { //Console.WriteLine("Failed to serialize. Reason: " + e.Message); throw; } finally { fs.Close(); } } /// /// Import layout from an AyaNova Transportable Report file (.AYR) at the path indicated /// /// Full path (including file name) to import. NOTE: By convention, all AyaNova report file names end in the extension .AYR /// False if report with that ID already exists, true for any other result public static bool ImportLayout(string Path) { ReportLayout rl=null; FileStream fs = new FileStream(Path, FileMode.Open); try { // Construct a BinaryFormatter and use it to de-serialize the data from the stream. BinaryFormatter formatter = new BinaryFormatter(); formatter.AssemblyFormat=System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; rl=(ReportLayout)formatter.Deserialize(fs); } catch { //Console.WriteLine("Failed to serialize. Reason: " + e.Message); throw; } finally { fs.Close(); } //See if a report with that id already exists if(ReportExistanceChecker.ReportExists(rl.ID)) return false; Report r=Report.NewItem(); r.mID=rl.ID; r.mCreator=User.CurrentThreadUserID; r.mModifier=r.mCreator; r.mModified=r.mCreated; r.Name=rl.Name; r.mReportContent=rl.ReportContent; r.ReportKey=rl.ReportKey; r.mReportSize=rl.ReportSize; r.Save(); return true; } #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 aReport WHERE aID=@ID;",crit.ID); if(!dr.Read()) DBUtil.ThrowFetchError("Report 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"); //Report fields //Important: use property not internal field //so that initial broken rule is unbroken on fetch Name=dr.GetString("aName"); ReportKey=dr.GetString("aReportKey"); //case 58 mRegionID = dr.GetGuid("aRegionID"); //case 36 mSecurityGroupID = dr.GetGuid("ASECURITYGROUPID"); mActive=dr.GetBoolean("AACTIVE"); //Get the layout size mReportSize=dr.GetInt32("aReportSize"); //Get the number of bytes mReportContent=new Byte[mReportSize]; //retrieve the bytes dr.GetBytes("aReportContent",0,mReportContent,0,mReportContent.Length); } finally { if(dr!=null) dr.Close(); } MarkOld(); //Get access rights level bReadOnly=AyaBizUtils.Right("Object.Report")<(int)SecurityLevelTypes.ReadWrite; } #endregion #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,"aReport"); #region Delete if(IsDeleted) { if(!IsNew) { //Delete object DBCommandWrapper cmDelete = DBUtil.GetCommandFromSQL("DELETE FROM aReport 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); // 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 aReport (aID, aReportKey, aName, aReportSize, aReportContent, " + "AACTIVE, aCreated,aModified,aCreator,aModifier, aRegionID, ASECURITYGROUPID) " + "VALUES (@ID,@ReportKey,@Name,@ReportSize,@ReportContent," + "@Active,@Created,@Modified,@CurrentUserID,@CurrentUserID,@RegionID,@SecurityGroupID);" ); else cm=DBUtil.GetCommandFromSQL( "UPDATE aReport SET aID=@ID, aReportKey=@ReportKey, " + "aName=@Name, AACTIVE=@Active, aReportSize=@ReportSize, aReportContent=@ReportContent, " + "aModifier=@CurrentUserID, " + "aModified=@Modified, aRegionID=@RegionID, ASECURITYGROUPID=@SecurityGroupID WHERE aReport.aID=@ID" ); cm.AddInParameter("@ID",DbType.Guid,mID); cm.AddInParameter("@Name",DbType.String, mName); cm.AddInParameter("@RegionID", DbType.Guid, mRegionID);//case 58 cm.AddInParameter("@SecurityGroupID", DbType.Guid, mSecurityGroupID);//case 36 cm.AddInParameter("@Active",DbType.Boolean,mActive); cm.AddInParameter("@ReportKey",DbType.String, mReportKey); cm.AddInParameter("@ReportContent",DbType.Object,mReportContent); cm.AddInParameter("@ReportSize",DbType.Int32,mReportSize); //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); 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; } #endregion } #endregion #region Delete /// /// Remove a Report record from the database /// /// protected override void DataPortal_Delete(object Criteria) { Criteria crit = (Criteria)Criteria; //Delete object and child objects DBCommandWrapper cmDelete = DBUtil.GetCommandFromSQL("DELETE FROM aReport 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); // Commit the transaction transaction.Commit(); } catch { // Rollback transaction transaction.Rollback(); throw; } finally { connection.Close(); } } } #endregion delete #endregion dal data access #region Override IsValid / IsDirty //Override base class version if there are child objects public override bool IsValid { get { return base.IsValid; } } public override bool IsDirty { get { return base.IsDirty ; } } #endregion #region criteria /// /// Criteria for identifying existing object /// [Serializable] private class Criteria { public Guid ID; public Criteria(Guid _ID) { ID=_ID; } } #endregion }//end Task #pragma warning restore 1591 }//end namespace GZTW.AyaNova.BLL