/////////////////////////////////////////////////////////// // User.cs // Implementation of Class User // CSLA type: Editable Root // Created on: 07-Jun-2004 8:41:40 AM // Object design: Joyce // Coded: John 07/02/2004 // Last updated: John 07/05/2004 // /////////////////////////////////////////////////////////// using System; using System.Data; using CSLA.Data; using CSLA; using System.Threading; using CSLA.Security; using System.Text; using System.Security.Cryptography; using GZTW.Data; using System.Collections; using System.ComponentModel; namespace GZTW.AyaNova.BLL { /// /// User - anyone with access to AyaNova /// [Serializable] public class User : BusinessBase { #region Attributes private bool bReadOnly; private Guid mID; private SmartDate mCreated; private SmartDate mModified; private bool mActive; private Guid mCreator; private Guid mModifier; private string mFirstName=null; private string mLastName=null; private string mInitials=null; private string mEmployeeNumber=""; private AssignedDocs mDocs; private string mNotes=""; private UserTypes mUserType; private Guid mDispatchZoneID; private string mEmailAddress=""; private string mPhone1=""; private string mPhone2=""; private string mPageAddress=""; private int mPageMaxText; private Guid mVendorID; private Guid mRegionID; private UserCertificationAssignments mUserCertification; private UserSkillAssignments mUserSkill; private bool mSubContractor; private Guid mMemberOfGroup; private Guid mDefaultWarehouseID; private Guid mDefaultServiceTemplateID; //private Guid mDefaultQuoteTemplate; //private Guid mDefaultPurchaseOrderTemplate; private string mDefaultLanguage="English"; private string mtempPassword=""; private string mtempLogin=""; private string mPassword=""; private string mLogin=""; //Custom fields private string mCustom1=""; private string mCustom2=""; private string mCustom3=""; private string mCustom4=""; private string mCustom5=""; private string mCustom6=""; private string mCustom7=""; private string mCustom8=""; private string mCustom9=""; private string mCustom0=""; //Post creation fields private int mScheduleBackColor; //Last viewed form private string mLastView=""; //If usertype = client or head office then this needs to be set accordingly private Guid mClientID; private Guid mHeadOfficeID; //case 527 private Guid mLastSchedGroupID; //Workaround to allow loading the administrator //account fields through properties to test rules //as props normally read only for admin account //set to true by fetch and false at the end of fetch //this allows a load from db but still prevents user //from modifying fields for admin later private bool mFetching=false; //License affecting cache of original values private bool wasActive=false; private bool wasScheduleableUser=false; //case 1219 private SmartDate mLastSchedStartDate; private SmartDate mLastSchedStopDate; private int mLastSchedView; //case 1163 private decimal? mTimeZoneOffset; //case 1553 private int mMainGridLastRowCount; private bool mScheduleLastViewOpenOnly; private string mScheduleLastGraphicalPrintSettings; //case 1937 internal bool mCheckFollowUps = false; #endregion #region Constructor /// /// Private constructor to prevent direct instantiation /// responsible for setting object default values /// private User() { //Set to read / write initially so that properties //can be set bReadOnly=false; //New user ID mID = Guid.NewGuid(); //Defaults for items that are mandatory //set here to "pre-break" the rules collection mActive=true; mUserType=0; FirstName=""; Initials=""; LastName=""; mtempPassword=""; mtempLogin=""; mPassword=""; mLogin=""; mUserCertification=UserCertificationAssignments.NewItems(); mUserSkill=UserSkillAssignments.NewItems(); //Built-in "Default" region mRegionID=Region.DefaultRegionID;//case 58 //Built-in Default warehouse mDefaultWarehouseID=PartWarehouse.DefaultWarehouseID; //case 527 default last schedule group view mLastSchedGroupID = ScheduleableUserGroup.AllUsersGroupID; //Set record history to defaults mCreated = new SmartDate(DBUtil.CurrentWorkingDateTime); mModified=new SmartDate(); mCreator=Guid.Empty; mModifier=Guid.Empty; mDocs=AssignedDocs.NewItems(); //Default to transparent schedule background colour mScheduleBackColor=0; //Pre-break group membership MemberOfGroup=Guid.NewGuid(); MemberOfGroup=Guid.Empty; BrokenRules.Assert("PasswordRequired","Error.Object.RequiredFieldEmpty,User.Label.Password","Password",true); BrokenRules.Assert("LoginRequired","Error.Object.RequiredFieldEmpty,User.Label.Login","Login",true); this.mUserType=UserTypes.NonSchedulable; //Case 851 this.mDefaultLanguage = AyaBizUtils.GlobalSettings.DefaultLanguage; //case 1219 //case 1163 mTimeZoneOffset = null; //case 1219 mLastSchedStartDate = new SmartDate(); mLastSchedStopDate = new SmartDate(); mLastSchedView = 0; //case 1553 mMainGridLastRowCount = 100; mScheduleLastViewOpenOnly = true; mScheduleLastGraphicalPrintSettings = ""; } #endregion #region Business properties /// /// Set the MD5 hashes for the password and login /// /// private void SetHashes() { //TODO: FIPS SHA256 shaM = new SHA256Managed(); UTF8Encoding enc = new UTF8Encoding(); mLogin=BitConverter.ToString(shaM.ComputeHash(enc.GetBytes(mtempLogin))).Replace("-", ""); //Use the login as a "salt" for the password so that //when users look in the database at the user records two people with identical //passwords won't show the same hash value mPassword=BitConverter.ToString(shaM.ComputeHash(enc.GetBytes(mtempLogin + mtempPassword))).Replace("-", ""); } /// /// Login account /// public string Login { set { if(!mFetching && bReadOnly) ThrowSetError(); else { if(mtempLogin!=value) { mtempLogin = value; BrokenRules.Assert("LoginRequired","Error.Object.RequiredFieldEmpty,User.Label.Login","Login",value.Length==0); MarkDirty(); //Set the hash values for login and password SetHashes(); } } } } /// /// Login password /// public string Password { set { if(!mFetching && bReadOnly) ThrowSetError(); else { if(mtempPassword!=value) { mtempPassword = value; BrokenRules.Assert("PasswordRequired","Error.Object.RequiredFieldEmpty,User.Label.Password","Password",value.Length==0); MarkDirty(); //Set the hash values for login and password SetHashes(); } } } } /// /// Default language to present to user. /// Corresponds to the Locale field in the /// LocalizedText table in AyaNova database /// public string DefaultLanguage { get { return mDefaultLanguage; } set { if(!mFetching && bReadOnly) ThrowSetError(); else { if(mDefaultLanguage!=value) { mDefaultLanguage = value; BrokenRules.Assert("DefaultLanguageRequired","Error.Object.RequiredFieldEmpty,Common.Label.DefaultLanguage","DefaultLanguage",value.Length==0); MarkDirty(); } } } } ///// ///// Guid of default Purchase order template to use on new work orders ///// Note that this may be overriden by similar option in other objects ///// (depending on situation) ///// //public Guid DefaultPurchaseOrderTemplate //{ // get // { // return mDefaultPurchaseOrderTemplate; // } // set // { // if(SetPropertyNotAllowed) // ThrowSetError(); // else // { // if(mDefaultPurchaseOrderTemplate!=value) // { // mDefaultPurchaseOrderTemplate = value; // MarkDirty(); // } // } // } //} ///// ///// Guid of default WorkorderQuote template to use on new work orders ///// Note that this may be overriden by similar option in other objects ///// (depending on situation) ///// ///// //public Guid DefaultQuoteTemplate //{ // get // { // return mDefaultQuoteTemplate; // } // set // { // if(SetPropertyNotAllowed) // ThrowSetError(); // else // { // if(mDefaultQuoteTemplate!=value) // { // mDefaultQuoteTemplate = value; // MarkDirty(); // } // } // } //} /// /// Guid of default work order template to use on new work orders /// Note that this may be overriden by similar option in other objects /// (depending on situation) /// public Guid DefaultServiceTemplateID { get { return mDefaultServiceTemplateID; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mDefaultServiceTemplateID!=value) { mDefaultServiceTemplateID = value; MarkDirty(); } } } } /// /// Type of user. /// This property can affect license consumption, use with care /// or you may lockout all users of AyaNova. /// /// [System.ComponentModel.TypeConverter(typeof(EnumDescConverter))] public UserTypes UserType { get { return mUserType; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mUserType!=value) { //Don't allow to go from non scheduleable if there are any scheduled workorder items because //it would damage the history BrokenRules.Assert("UserType","User.Label.MustBeScheduleable","UserType",(mUserType==UserTypes.Schedulable) && (ScheduledUserCount(this.mID,false)>0)); mUserType = value; BrokenRules.Assert("UserTypeInvalid","Error.Object.FieldValueNotBetween,User.Label.UserType,1,7","UserType",((int)value<1 || (int)value>6)); bool bOutOfLicenses=OutOfLicenses; BrokenRules.Assert("ActiveLicense","Error.Security.UserCapacity","Active",bOutOfLicenses); BrokenRules.Assert("UserTypeLicense","Error.Security.UserCapacity","UserType",bOutOfLicenses); //Case 850 BrokenRules.Assert("ClientIDInvalid", "Error.Object.RequiredFieldEmpty,O.Client", "ClientID", (mUserType== UserTypes.Client && mClientID==Guid.Empty)); BrokenRules.Assert("HeadOfficeIDInvalid", "Error.Object.RequiredFieldEmpty,O.HeadOffice", "HeadOfficeID", (mUserType == UserTypes.HeadOffice && mHeadOfficeID == Guid.Empty)); MarkDirty(); } } } } /// /// Get /set active status of user /// If active = true then user is selectable for workorders if a tech or can log in /// etc /// If active = false then user in not selectable, but history can be viewed /// public bool Active { get { return mActive; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mActive!=value) { //case 1937 if (mActive = true && !this.IsNew) { //an existing user who was previously active is now not active so check followups //on save mCheckFollowUps = true; } mActive = value; bool bOutOfLicenses=OutOfLicenses; BrokenRules.Assert("ActiveLicense","Error.Security.UserCapacity","Active",bOutOfLicenses); BrokenRules.Assert("UserTypeLicense","Error.Security.UserCapacity","UserType",bOutOfLicenses); //close active / inactive scheduleable user license count loophole BrokenRules.Assert("Scheduled","User.Label.MustBeActive","Active",(value==false) && (ScheduledUserCount(this.mID,true)>0)); MarkDirty(); } } } } /// /// If usertype is a client login then this is the ID of thier client record ID /// otherwise is empty /// public Guid ClientID { get { return mClientID; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mClientID!=value) { mClientID = value; BrokenRules.Assert("ClientIDInvalid", "Error.Object.RequiredFieldEmpty,O.Client", "ClientID", (mUserType == UserTypes.Client && mClientID == Guid.Empty)); MarkDirty(); } } } } /// /// If usertype is a HeadOffice login then this is the ID of thier HeadOffice record ID /// otherwise is empty /// public Guid HeadOfficeID { get { return mHeadOfficeID; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mHeadOfficeID!=value) { mHeadOfficeID = value; BrokenRules.Assert("HeadOfficeIDInvalid", "Error.Object.RequiredFieldEmpty,O.HeadOffice", "HeadOfficeID", (mUserType == UserTypes.HeadOffice && mHeadOfficeID == Guid.Empty)); MarkDirty(); } } } } /// /// Security group Guid this user is a member of /// public Guid MemberOfGroup { get { return mMemberOfGroup; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mMemberOfGroup!=value) { mMemberOfGroup = value; BrokenRules.Assert("SecurityGroupInvalid","Error.Object.RequiredFieldEmpty,O.SecurityGroup","MemberOfGroup",value==Guid.Empty); MarkDirty(); } } } } /// /// Date record created /// /// public string Created { get { return mCreated.ToString(); } } /// /// Last record modification date /// /// public string Modified { get { return mModified.ToString(); } } /// /// User record ID of person who created this record /// /// public Guid Creator { get { return mCreator; } } /// /// User ID of person who modified this record /// /// public Guid Modifier { get { return mModifier; } } /// /// Users unique identifier (used internally) /// Read only /// public Guid ID { get { return mID; } } /// /// Users first (given) name /// public string FirstName { get { return mFirstName; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mFirstName!=value) { mFirstName = value; BrokenRules.Assert("FirstNameRequired","Error.Object.RequiredFieldEmpty,User.Label.FirstName","FirstName",value.Length==0); BrokenRules.Assert("FirstNameLength", "Error.Object.FieldLengthExceeded255,User.Label.FirstName","FirstName",value.Length>255); MarkDirty(); } } } } /// /// Users last (family) name /// public string LastName { get { return mLastName; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mLastName!=value) { mLastName = value; BrokenRules.Assert("LastNameRequired","Error.Object.RequiredFieldEmpty,User.Label.LastName","LastName",value.Length==0); BrokenRules.Assert("LastNameLength", "Error.Object.FieldLengthExceeded255,User.Label.LastName","LastName",value.Length>255); MarkDirty(); } } } } /// /// Initials to idientify user /// used in places where a full name can't be fit /// public string Initials { get { return mInitials; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mInitials!=value) { mInitials = value; BrokenRules.Assert("InitialsRequired","Error.Object.RequiredFieldEmpty,User.Label.Initials","Initials",value.Length==0); BrokenRules.Assert("InitialsLength", "Error.Object.FieldLengthExceeded255,User.Label.Initials","Initials",value.Length>255); MarkDirty(); } } } } /// /// May be used for accounting /// Some businesses may use employee number for lists rather than the first and /// last name - need to be able to have manager set which is desired. /// public string EmployeeNumber { get { return mEmployeeNumber; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mEmployeeNumber!=value) { mEmployeeNumber = value; BrokenRules.Assert("EmployeeNumberLength", "Error.Object.FieldLengthExceeded255,User.Label.EmployeeNumber","EmployeeNumber",value.Length>255); MarkDirty(); } } } } /// /// Email address for sending text messages /// public string PageAddress { get { return mPageAddress; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mPageAddress!=value) { mPageAddress = value; BrokenRules.Assert("PageAddressLength", "Error.Object.FieldLengthExceeded255,User.Label.PageAddress","PageAddress",value.Length>255); MarkDirty(); } } } } /// /// Maximum number of text in a single message this pager can handle /// public int PageMaxText { get { return mPageMaxText; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mPageMaxText!=value) { mPageMaxText = value; MarkDirty(); } } } } /// /// Users primary contact phone number /// public string Phone1 { get { return mPhone1; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mPhone1!=value) { mPhone1 = value; BrokenRules.Assert("Phone1Length", "Error.Object.FieldLengthExceeded255,User.Label.Phone1","Phone1",value.Length>255); MarkDirty(); } } } } /// /// Users second / alternative phone /// public string Phone2 { get { return mPhone2; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mPhone2!=value) { mPhone2 = value; BrokenRules.Assert("Phone2Length", "Error.Object.FieldLengthExceeded255,User.Label.Phone2","Phone2",value.Length>255); MarkDirty(); } } } } /// /// Users email address /// public string EmailAddress { get { return mEmailAddress; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mEmailAddress!=value) { mEmailAddress = value; BrokenRules.Assert("EmailAddressLength", "Error.Object.FieldLengthExceeded255,User.Label.EmailAddress","EmailAddress",value.Length>255); MarkDirty(); } } } } /// /// Collection of certifications this user posesses /// public UserCertificationAssignments UserCertifications { get { if( mID==User.AdministratorID || IsGenerator) return null; return mUserCertification; } } /// /// Collection of skills assigned to user /// public UserSkillAssignments UserSkills { get { if( mID==User.AdministratorID || IsGenerator) return null; return mUserSkill; } } /// /// Notes /// public string Notes { get { return mNotes; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mNotes!=value) { mNotes = value; MarkDirty(); } } } } /// /// If user is a subcontractor, than this field would contain ID of vendor that is /// specified as a SubContractor /// public Guid VendorID { get { return mVendorID; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mVendorID!=value) { mVendorID = value; MarkDirty(); } } } } /// /// Collection of assigned documents assigned to this user /// public AssignedDocs Docs { get { if( mID==User.AdministratorID || IsGenerator) return null; return mDocs; } } /// /// Region GUID that user is assigned to. /// public Guid RegionID { get { return mRegionID; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mRegionID!=value) { mRegionID = value; BrokenRules.Assert("RegionIDInvalid","Error.Object.RequiredFieldEmpty,O.Region","RegionID",value==Guid.Empty); MarkDirty(); } } } } /// /// Dispatch zone GUID /// public Guid DispatchZoneID { get { return mDispatchZoneID; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mDispatchZoneID!=value) { mDispatchZoneID = value; MarkDirty(); } } } } /// /// If true, than scheduleable user is a subcontractor /// /// public bool SubContractor { get { return mSubContractor; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mSubContractor!=value) { mSubContractor = value; MarkDirty(); } } } } /// /// Default warehouse for this user to select parts from /// public Guid DefaultWarehouseID { get { return mDefaultWarehouseID; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mDefaultWarehouseID!=value) { mDefaultWarehouseID = value; BrokenRules.Assert( "DefaultWarehouseIDInvalid", "Error.Object.RequiredFieldEmpty,O.PartWarehouse", "DefaultWarehouseID", value==Guid.Empty && this.mUserType==UserTypes.Schedulable); MarkDirty(); } } } } #region CUSTOM FIELDS //CUSTOM FIELDS /// /// Custom1 /// public string Custom1 { get { return mCustom1; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mCustom1!=value) { mCustom1 = value; BrokenRules.Assert("Custom1Length", "Error.Object.FieldLengthExceeded500,User.Label.Custom1","Custom1",value.Length>500); MarkDirty(); } } } } /// /// Custom2 /// public string Custom2 { get { return mCustom2; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mCustom2!=value) { mCustom2 = value; BrokenRules.Assert("Custom2Length", "Error.Object.FieldLengthExceeded500,User.Label.Custom2","Custom2",value.Length>500); MarkDirty(); } } } } /// /// Custom3 /// public string Custom3 { get { return mCustom3; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mCustom3!=value) { mCustom3 = value; BrokenRules.Assert("Custom3Length", "Error.Object.FieldLengthExceeded500,User.Label.Custom3","Custom3",value.Length>500); MarkDirty(); } } } } /// /// Custom4 /// public string Custom4 { get { return mCustom4; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mCustom4!=value) { mCustom4 = value; BrokenRules.Assert("Custom4Length", "Error.Object.FieldLengthExceeded500,User.Label.Custom4","Custom4",value.Length>500); MarkDirty(); } } } } /// /// Custom5 /// public string Custom5 { get { return mCustom5; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mCustom5!=value) { mCustom5 = value; BrokenRules.Assert("Custom5Length", "Error.Object.FieldLengthExceeded500,User.Label.Custom5","Custom5",value.Length>500); MarkDirty(); } } } } /// /// Custom6 /// public string Custom6 { get { return mCustom6; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mCustom6!=value) { mCustom6 = value; BrokenRules.Assert("Custom6Length", "Error.Object.FieldLengthExceeded500,User.Label.Custom6","Custom6",value.Length>500); MarkDirty(); } } } } /// /// Custom7 /// public string Custom7 { get { return mCustom7; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mCustom7!=value) { mCustom7 = value; BrokenRules.Assert("Custom7Length", "Error.Object.FieldLengthExceeded500,User.Label.Custom7","Custom7",value.Length>500); MarkDirty(); } } } } /// /// Custom8 /// public string Custom8 { get { return mCustom8; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mCustom8!=value) { mCustom8 = value; BrokenRules.Assert("Custom8Length", "Error.Object.FieldLengthExceeded500,User.Label.Custom8","Custom8",value.Length>500); MarkDirty(); } } } } /// /// Custom9 /// public string Custom9 { get { return mCustom9; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mCustom9!=value) { mCustom9 = value; BrokenRules.Assert("Custom9Length", "Error.Object.FieldLengthExceeded500,User.Label.Custom9","Custom9",value.Length>500); MarkDirty(); } } } } /// /// Custom0 /// public string Custom0 { get { return mCustom0; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mCustom0!=value) { mCustom0 = value; BrokenRules.Assert("Custom0Length", "Error.Object.FieldLengthExceeded500,User.Label.Custom0","Custom0",value.Length>500); MarkDirty(); } } } } #endregion /// /// Selected color is used for background /// behind users' schedule in calendar displays /// public int ScheduleBackColor { get { return mScheduleBackColor; } set { if(SetPropertyNotAllowed) ThrowSetError(); else { if(mScheduleBackColor!=value) { mScheduleBackColor = value; MarkDirty(); } } } } /// /// Return name in selected format /// /// /// public string Name(ScheduleableUserNameDisplayFormats Format) { //Is region name required? string sRegionName = ""; if (Format > ScheduleableUserNameDisplayFormats.EmployeeNumberInitials) { sRegionName = NameFetcher.GetItem("REGION", "NAME", mRegionID).RecordName; } switch(Format) { case ScheduleableUserNameDisplayFormats.LastFirst: return AyaBizUtils.SS("",mLastName,", ") + mFirstName; //break; case ScheduleableUserNameDisplayFormats.FirstLast: return AyaBizUtils.SS("",mFirstName," ") + mLastName ; //break; case ScheduleableUserNameDisplayFormats.Initials: return AyaBizUtils.SS("",mInitials,"") ; //break; case ScheduleableUserNameDisplayFormats.EmployeeNumberFirstLast: return AyaBizUtils.SS("",mEmployeeNumber," - ") + AyaBizUtils.SS("",mFirstName," ") + mLastName ; //break; case ScheduleableUserNameDisplayFormats.EmployeeNumberInitials: return AyaBizUtils.SS("",this.mEmployeeNumber," - ") + this.mInitials ; //case 1446 case ScheduleableUserNameDisplayFormats.LastFirstRegion: return AyaBizUtils.SS("", mLastName, ", ") + mFirstName + AyaBizUtils.SS(" - ",sRegionName,"") ; case ScheduleableUserNameDisplayFormats.FirstLastRegion: return AyaBizUtils.SS("", mFirstName, " ") + mLastName + AyaBizUtils.SS(" - ", sRegionName, ""); case ScheduleableUserNameDisplayFormats.RegionLastFirst: return AyaBizUtils.SS("", sRegionName, " - ") + AyaBizUtils.SS("", mLastName, ", ") + mFirstName; case ScheduleableUserNameDisplayFormats.RegionFirstLast: return AyaBizUtils.SS("", sRegionName, " - ") + AyaBizUtils.SS("", mFirstName, " ") + mLastName; } return "NO FORMAT SPECIFIED"; } /// /// LastView - key of last view (form) user /// was viewing when they last closed the program. /// /// This is used to ensure they start with the same view /// they had before. /// /// If this is blank or invalid then the UI will start with the /// first view they have rights to see. /// public string LastView { get { return mLastView; } set { //Deliberately no check for read only here, app needs to be able to update user's last view if(mLastView!=value) { mLastView = value; BrokenRules.Assert("mLastView", "Error.Object.FieldLengthExceeded255,User.Label.LastView","LastView",value.Length>255); MarkDirty(); } } } /// /// Last scheduleable user group that was being viewed in the schedule form /// so it can be re-instituted on startup again /// public Guid LastSchedGroupID { get { return mLastSchedGroupID; } set { if (mLastSchedGroupID != value) { mLastSchedGroupID = value; MarkDirty(); } } } /// /// Last Start date of range that was being viewed in the schedule form /// so it can be re-instituted on startup again /// public SmartDate LastSchedStartDate//case 1219 { get { return mLastSchedStartDate; } set { if (mLastSchedStartDate != value) { mLastSchedStartDate = value; MarkDirty(); } } } /// /// Last Stop date of range that was being viewed in the schedule form /// so it can be re-instituted on startup again /// public SmartDate LastSchedStopDate//case 1219 { get { return mLastSchedStopDate; } set { if (mLastSchedStopDate != value) { mLastSchedStopDate = value; MarkDirty(); } } } /// /// Last view type last being used in the schedule form /// so it can be re-instituted on startup again /// /// 0=day view, 1=week, 2=month, 3=workweek, 4=timeline /// public int LastSchedView//case 1219 { get { return mLastSchedView; } set { if (mLastSchedView != value) { mLastSchedView = value; MarkDirty(); } } } /// /// Override time zone by this value. /// /// All dates and times are stored in the database in UTC format. /// This setting overrides the normal process of converting during load and save /// data using the time zone of the machine this code is running on. /// /// Set null to use normal process /// /// public decimal? TimeZoneOffset { get { return mTimeZoneOffset; } set { if (!mFetching && bReadOnly) ThrowSetError(); else { if (mTimeZoneOffset != value) { mTimeZoneOffset = value; MarkDirty(); } } } } /// /// Saved settings from last schedule form graphical print /// public string ScheduleLastGraphicalPrintSettings//case 1553 { get { return mScheduleLastGraphicalPrintSettings; } set { //Deliberately no check for read only here, app needs to be able to update user's last view if (mScheduleLastGraphicalPrintSettings != value) { mScheduleLastGraphicalPrintSettings = value; MarkDirty(); } } } /// /// Last row count selected in main grid form /// public int MainGridLastRowCount//case 1553 { get { return mMainGridLastRowCount; } set { if (mMainGridLastRowCount != value) { mMainGridLastRowCount = value; MarkDirty(); } } } /// /// Open schedule form showing open only (or false=open/closed) based on last user selection /// public bool ScheduleLastViewOpenOnly//case 1553 { get { return this.mScheduleLastViewOpenOnly; } set { if (mScheduleLastViewOpenOnly != value) { mScheduleLastViewOpenOnly = value; MarkDirty(); } } } /// /// Used internally here to /// weed out attempts to set properties when read only /// or administrator or a utility account /// private bool SetPropertyNotAllowed { get { //always allowed to set when fetching if(mFetching) return false; if(bReadOnly || (!mFetching && mID==User.AdministratorID) || (!mFetching && IsGenerator)) return true; return false; } } /// /// Indicator if user is Built-in Administrator account /// /// (Administrator user properties are almost all read only /// check this before attempting to set) /// public bool IsAdministrator { get { if( mID==User.AdministratorID) return true; return false; } } /// /// Indicator if user is a Notification server account /// /// (Notification server user properties are almost all read only /// check this before attempting to set) /// public bool IsGenerator { get { if( this.mUserType==UserTypes.Utility) return true; return false; } } /// /// User is scheduleable /// public bool IsScheduleable { get { if (this.mUserType == UserTypes.Schedulable) return true; return false; } } private bool OutOfLicenses { //This is a test which will set a broken rule if it's not possible to save //a user due to it exceeding the license count //it's called by the active and usertype properties get { //case 1172 if (mID == User.LiteUserID) return false; //See if this record could be saved within //the current license //used by ui to prevent an exception when //a user violates a license //this code is identical to that in Update below if(this.mUserType==UserTypes.Schedulable && this.mActive) { //If it's a new user or was previously not affecing a license //then we need to check if(IsNew || (this.wasActive==false || this.wasScheduleableUser==false)) { if(ScheduleableUserCountFetcher.GetItem()+1 > AyaBizUtils.GlobalX.ScheduleableUsers) return true; else return false; } } return false; } } //Added:9-Nov-2006 for wbi login redirection /// /// True if user is client or headoffice user type /// public bool IsClientOrHeadOfficeAccount { get { if (UserType == UserTypes.Client || UserType == UserTypes.HeadOffice) return true; return false; } } //Added:9-Nov-2006 for wbi login redirection /// /// True if user is client login /// public bool IsClientAccount { get { if (UserType == UserTypes.Client) return true; return false; } } //Added:9-Nov-2006 for wbi login redirection /// /// True if user is client login /// public bool IsHeadOfficeAccount { get { if (UserType == UserTypes.HeadOffice) return true; return false; } } /// /// IF user is a head office or client account this is the RootObjectType and ID for that account /// If neither then this will return RootObjectTypes.Nothing and guid.empty instead /// public TypeAndID OrganizationTypeAndID { get { if (IsClientAccount) return new TypeAndID(RootObjectTypes.Client, mClientID); if (IsHeadOfficeAccount) return new TypeAndID(RootObjectTypes.HeadOffice, mHeadOfficeID); return new TypeAndID(RootObjectTypes.Nothing, Guid.Empty); } } /// /// Flag - indicates if current user can open the wiki page for this object /// This check is a little different since a user can always have rights to /// their own wikipage even if they don't have rights to user objects in general. /// /// This is cached for the lifetime of this object /// public bool CanWiki//case 73 { get//bugbug: what if a user opens a users wiki who is not their own? { if (!bCanWiki.HasValue) { bCanWiki = WikiPage.ShowWikiLink(RootObjectTypes.User, mID); } return bCanWiki.Value; } } //cache the result in case the UI calls this repeatedly private bool? bCanWiki = null; /// /// 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.User") ) ); } #endregion #region System.object overrides /// /// /// /// public override string ToString() { return "User" + mID.ToString(); } /// /// /// /// /// public override bool Equals(Object obj) { if ( obj == null || GetType ( ) != obj.GetType ( ) ) return false; User c=(User)obj; return mID==c.mID; } /// /// /// /// public override int GetHashCode() { return ("User" +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.User")<(int)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 aRegionID, aCreated, aModified, aCreator, aModifier, aFirstName, " + " aLastName, aInitials, aEmailAddress, aEmployeeNumber, " + " aNotes, aPhone1, aPhone2, aPageAddress, aLanguage, " + " aCustom1, aCustom2, aCustom3, aCustom4, aCustom5, " + " aCustom6, aCustom7, aCustom8, aCustom9, aCustom0 FROM " + "aUser WHERE (aID = @ID)",ID); if(!dr.Read()) return new SearchResult();//DBUtil.ThrowFetchError("SearchResult for UserID: " + ID.ToString()); if (!AyaBizUtils.InYourRegion(dr.GetGuid("aRegionID"))) return new SearchResult();//case 58 sr.Description=dr.GetString("aLastName") + ", " + dr.GetString("aFirstName"); sb.Append(sr.Description); sb.Append(" "); sb.Append(dr.GetString("aInitials")); sb.Append(" "); sb.Append(dr.GetString("aEmailAddress")); sb.Append(" "); sb.Append(dr.GetString("aEmployeeNumber")); sb.Append(" "); sb.Append(dr.GetString("aNotes")); sb.Append(" "); sb.Append(dr.GetString("aPhone1")); sb.Append(" "); sb.Append(dr.GetString("aPhone2")); sb.Append(" "); sb.Append(dr.GetString("aPageAddress")); sb.Append(" "); sb.Append(dr.GetString("aLanguage")); sb.Append(" "); sb.Append(dr.GetString("aCustom0")); sb.Append(" "); sb.Append(dr.GetString("aCustom1")); sb.Append(" "); sb.Append(dr.GetString("aCustom2")); sb.Append(" "); sb.Append(dr.GetString("aCustom3")); sb.Append(" "); sb.Append(dr.GetString("aCustom4")); sb.Append(" "); sb.Append(dr.GetString("aCustom5")); sb.Append(" "); sb.Append(dr.GetString("aCustom6")); sb.Append(" "); sb.Append(dr.GetString("aCustom7")); sb.Append(" "); sb.Append(dr.GetString("aCustom8")); sb.Append(" "); sb.Append(dr.GetString("aCustom9")); 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.User; return sr; } #endregion #region Static methods /// /// Guid of built in Administrator account /// public static Guid AdministratorID { get { return new Guid("{2ECC77FC-69E2-4A7E-B88D-BD0ECAF36AED}"); } } //case 1172 /// /// Guid of built in AyaNova Lite single user account /// public static Guid LiteUserID { get { return new Guid("{0A6AF710-366D-4ca8-BBC7-FCC75F0D1BD3}"); } } /// /// return true if current logged in user is *the* default AyaNova Manager account /// public static bool IsAdmin { get { BusinessPrincipal p = ((BusinessPrincipal)Thread.CurrentPrincipal); if(!p.Identity.IsAuthenticated) return false; return p.ID==User.AdministratorID; } } /// /// Returns current logged in user's UserType property /// public static UserTypes CurrentUserType {//added for case 1283 get { return UserTypeFetcher.UserType(CurrentThreadUserID); } } /// /// Returns true if current logged in user is a head office or client account /// public static bool CurrentUserIsACustomer { get { return (CurrentUserType == UserTypes.Client || CurrentUserType == UserTypes.HeadOffice); } } /// /// Returns true if current logged in user is an Administrator type account /// public static bool CurrentUserIsAnAdministrator { get { return (CurrentUserType == UserTypes.Administrator); } } /// /// Returns true if current logged in user is a /// type of user account that is supported by /// the AyaNova RI interface /// public static bool CurrentUserTypeSupportedInRI {//added for case 1975 get { UserTypes uType=UserTypeFetcher.UserType(CurrentThreadUserID); switch (uType) { case UserTypes.Administrator: case UserTypes.NonSchedulable: case UserTypes.Schedulable: return true; default: return false; } } } /// /// Current logged in User's ID /// public static Guid CurrentThreadUserID { get { return((BusinessPrincipal)Thread.CurrentPrincipal).ID; } } /// /// Return name in selected format /// /// /// /// /// /// /// /// public static string NameFormatter(string First, string Last, string Initials, string EmployeeNumber, string RegionName, ScheduleableUserNameDisplayFormats Format) { switch(Format) { case ScheduleableUserNameDisplayFormats.LastFirst: return AyaBizUtils.SS("",Last,", ") + First; //break; case ScheduleableUserNameDisplayFormats.FirstLast: return AyaBizUtils.SS("",First," ") + Last; //break; case ScheduleableUserNameDisplayFormats.Initials: return AyaBizUtils.SS("",Initials,"") ; //break; case ScheduleableUserNameDisplayFormats.EmployeeNumberFirstLast: return AyaBizUtils.SS("",EmployeeNumber," - ") + AyaBizUtils.SS("",First," ") + Last; //break; case ScheduleableUserNameDisplayFormats.EmployeeNumberInitials: return AyaBizUtils.SS("",EmployeeNumber," - ") + Initials; //case 1446 case ScheduleableUserNameDisplayFormats.LastFirstRegion: return AyaBizUtils.SS("", Last, ", ") + First + AyaBizUtils.SS(" - ", RegionName, ""); case ScheduleableUserNameDisplayFormats.FirstLastRegion: return AyaBizUtils.SS("", First, " ") + Last + AyaBizUtils.SS(" - ", RegionName, ""); case ScheduleableUserNameDisplayFormats.RegionLastFirst: return AyaBizUtils.SS("", RegionName, " - ") + AyaBizUtils.SS("", Last, ", ") + First; case ScheduleableUserNameDisplayFormats.RegionFirstLast: return AyaBizUtils.SS("", RegionName, " - ") + AyaBizUtils.SS("", First, " ") + Last; default: return AyaBizUtils.SS("",Last,", ") + First; } //return "NO FORMAT SPECIFIED"; } /// /// Create new user /// public static User NewItem() { if(AyaBizUtils.Right("Object.User")>(int)SecurityLevelTypes.ReadOnly) return new User(); else throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToCreate"), LocalizedTextTable.GetLocalizedTextDirect("O.User"))); } //case 1172 /// /// Create new lite user if it doesn't exist already /// internal static void CreateLiteUser() { //check if there already is one if (UserList.GetListForSingleItem(LiteUserID).Count > 0) return; User l = new User(); l.mID = LiteUserID; l.FirstName = "Lite"; l.LastName = "User"; l.UserType = UserTypes.Schedulable; l.Initials = "usr"; l.Login = "user"; l.Password = "user"; l.MemberOfGroup = new Guid("{FF0DE42A-0EA0-429B-9643-64355703E8D1}");//default security group l.Save(); return; } /// /// Fetch existing user /// /// Client Guid public static User GetItem(Guid _ID) { if (_ID == AyaBizUtils.NewObjectGuid) return NewItem(); //They always have to be able to retrieve their own user object //to login so this is a bit different here: if(User.CurrentThreadUserID == _ID || AyaBizUtils.Right("Object.User")>(int)SecurityLevelTypes.NoAccess) { User u=(User)DataPortal.Fetch(new Criteria(_ID)); //Get access rights level u.bReadOnly=AyaBizUtils.Right("Object.User")<(int)SecurityLevelTypes.ReadWrite; return u; //return (User)DataPortal.Fetch(new Criteria(_ID)); } else throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToRetrieve"), LocalizedTextTable.GetLocalizedTextDirect("O.User"))); } /// /// Delete user /// /// User GUID public static void DeleteItem(Guid _ID) { //case 1172 - can't delete any users if lite license //case 1136 moved 1172 change here as logic was faulty in if statement below which included it if (AyaBizUtils.Lite) return; if(_ID != User.AdministratorID && AyaBizUtils.Right("Object.User")>(int)SecurityLevelTypes.ReadWrite) { DataPortal.Delete(new Criteria(_ID)); //also delete notification subscriptions when above completes without //exception NotifySubscriber.DeleteItem(_ID); } else throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToDelete"), LocalizedTextTable.GetLocalizedTextDirect("O.User"))); } /// /// Used to quickly retrieve a user's language setting /// /// /// User ID /// Users language setting string public static string GetUserLanguage(Guid UserID) { return NameFetcher.GetItem("aUser","aLanguage",UserID).RecordName; } //case 1415 /// /// Used to quickly retrieve a users's time zone offset value /// (for notification processing) /// /// /// public static double GetUserTimeZoneOffset(Guid UserID) { try { object o = DBUtil.GetScalarFromSQLString("SELECT ATIMEZONEOFFSET FROM AUSER WHERE aID=@ID", UserID); double d= System.Convert.ToDouble(o); if (d == 9999)//9999 is the default empty record return 0; else return d; } catch { return 0; } } /// /// Used to fetch the administrators locale. /// Used internally in updates when a locale is required /// for general updates not user specific as the default locale /// public static string AdminUserLocale { get { return GetUserLanguage(AdministratorID); } } /// /// Current logged in user's locale setting /// public static string CurrentUserLanguage { get{return GetUserLanguage(CurrentThreadUserID);} } //case 58 /// /// Current logged in user's ID /// public static Guid CurrentUserRegionID { get { return UserRegionIDFetcher.UserRegion(CurrentThreadUserID); } } //case 58 /// /// True if current user is not in a specific but in default region /// public static bool CurrentUserIsInDefaultRegion { get { return UserRegionIDFetcher.UserRegion(CurrentThreadUserID)==Region.DefaultRegionID; } } //case 36 /// /// Current logged in user's ID /// public static Guid CurrentUserSecurityGroupID { get { return UserSecurityGroupIDFetcher.UserSecurityGroup(CurrentThreadUserID); } } /// /// Remove all automatically and user selected layout preferences for UI for indicated user /// /// public static void ClearUILayoutSettings(Guid _UserID) { ClearLayout.Clear(_UserID); } /// /// How many times the user indicated appears /// on a workorder item scheduled user record /// /// Scheduleable user /// Only count when on open workorder /// Count of workorder item scheduled user records for user public static long ScheduledUserCount(Guid _UserID, bool OpenWorkordersOnly) { //Case 504 return ScheduledUserCountFetcher.ScheduledCount(_UserID, OpenWorkordersOnly); } #endregion #region Shared Notification Message Processor internal static NotifyMessage GetNotificationMessage(NotifyMessageRequestData d) { if (d.EventType == 1) return new NotifyMessage("predefined", "predefined"); return null; } #endregion #region DAL Data Access #region fetch /// /// protected override void DataPortal_Fetch(object Criteria) { //set to false to load items initially bReadOnly=false; mFetching=true; Criteria crit = (Criteria)Criteria; SafeDataReader dr = null; try { dr=DBUtil.GetReaderFromSQLString("SELECT * FROM aUser WHERE aID=@ID;",crit.ID); if(!dr.Read()) DBUtil.ThrowFetchError("User ID: " + crit.ID.ToString()); mID=dr.GetGuid("aID"); mCreated=DBUtil.ToLocal(dr.GetSmartDate("aCreated")); mModified=DBUtil.ToLocal(dr.GetSmartDate("aModified")); this.wasActive=false; //mActive=true; mActive=dr.GetBoolean("AACTIVE"); //used for license checking on save this.wasActive=mActive; mCreator=dr.GetGuid("aCreator"); mModifier=dr.GetGuid("aModifier"); //Ruled items FirstName=dr.GetString("aFirstName"); LastName=dr.GetString("aLastName"); Initials=dr.GetString("aInitials"); mEmailAddress=dr.GetString("aEmailAddress"); mEmployeeNumber=dr.GetString("aEmployeeNumber"); mNotes=dr.GetString("aNotes"); mUserType=(UserTypes)dr.GetInt16("aUserType"); this.wasScheduleableUser=false; if(mUserType==UserTypes.Schedulable) this.wasScheduleableUser=true; mDispatchZoneID=dr.GetGuid("aDispatchZoneID"); mPhone1=dr.GetString("aPhone1"); mPhone2=dr.GetString("aPhone2"); mPageAddress=dr.GetString("aPageAddress"); mPageMaxText=dr.GetInt16("aPageMaxText"); //Unbreak RegionID=dr.GetGuid("aRegionID"); mVendorID=dr.GetGuid("aVendorID"); mSubContractor=dr.GetBoolean("aSubContractor"); //Unbreak MemberOfGroup=dr.GetGuid("aMemberOfGroup"); //Unbreak DefaultWarehouseID=dr.GetGuid("aWarehouseID"); //case 2104 added in schema 46 if (AyaBizUtils.GlobalX.DBSchemaVersion > 45) { mDefaultServiceTemplateID = dr.GetGuid("ADEFAULTSERVICETEMPLATEID"); } //mDefaultServiceTemplateID=dr.GetGuid("aDefaultServiceTemplateID"); //mDefaultQuoteTemplate=dr.GetGuid("aQuoteTemplate"); //mDefaultPurchaseOrderTemplate=dr.GetGuid("aPurchaseOrderTemplate"); //Unbreak DefaultLanguage=dr.GetString("aLanguage"); //Fetch login and password values mPassword=dr.GetString("aPassword"); mLogin=dr.GetString("aLogin"); //Custom fields mCustom1=dr.GetString("aCustom1"); mCustom2=dr.GetString("aCustom2"); mCustom3=dr.GetString("aCustom3"); mCustom4=dr.GetString("aCustom4"); mCustom5=dr.GetString("aCustom5"); mCustom6=dr.GetString("aCustom6"); mCustom7=dr.GetString("aCustom7"); mCustom8=dr.GetString("aCustom8"); mCustom9=dr.GetString("aCustom9"); mCustom0=dr.GetString("aCustom0"); mScheduleBackColor=dr.GetInt32("aScheduleBackColor"); mLastView=dr.GetString("aLastView"); mClientID=dr.GetGuid("aClientID"); mHeadOfficeID=dr.GetGuid("aHeadOfficeID"); //case 2104 added in schema 44 if (AyaBizUtils.GlobalX.DBSchemaVersion > 43) { mLastSchedGroupID = dr.GetGuid("ALASTSCHEDGROUPID"); } //case 2100 added in schema 90 if (AyaBizUtils.GlobalX.DBSchemaVersion > 89) { //case 1219 mLastSchedView = dr.GetInt16("ALASTSCHEDVIEW"); mLastSchedStartDate = DBUtil.ToLocal(dr.GetSmartDate("ALASTSCHEDSTARTDATE")); mLastSchedStopDate = DBUtil.ToLocal(dr.GetSmartDate("ALASTSCHEDSTOPDATE")); } //case 2100 added in schema 91 if (AyaBizUtils.GlobalX.DBSchemaVersion > 90) { //case 1163 mTimeZoneOffset = dr.GetDecimal("ATIMEZONEOFFSET"); } else { mTimeZoneOffset = 9999m; } //9999 is used in db to indicate no selection / empty if (mTimeZoneOffset == 9999m) mTimeZoneOffset = null; //case 2099 added in schema 108 if (AyaBizUtils.GlobalX.DBSchemaVersion > 107) { //case 1553 mMainGridLastRowCount = dr.GetInt32("AMAINGRIDLASTROWCOUNT"); //case 2099, also these two in same schema update mScheduleLastViewOpenOnly = dr.GetBoolean("ASCHEDULELASTVIEWOPENONLY"); mScheduleLastGraphicalPrintSettings = dr.GetString("ASCHEDULELASTPRINTSETTINGS"); } if (mMainGridLastRowCount == 0) mMainGridLastRowCount = 100; //Turn off pre-broken rules from constructor //Constructor breaks required rules for these fields so that //on new records user must fill them in, however when we load a record //then they should not be broken or the object will always be dirty //and will try to save with a blank password / login if it's unset BrokenRules.Assert("LoginRequired","",false); BrokenRules.Assert("PasswordRequired","",false); /* * Load child collection objects */ if(dr!=null) dr.Close(); //User educational certifications dr=DBUtil.GetReaderFromSQLString("SELECT * FROM aUserCertificationAssigned WHERE aUserID=@ID;",crit.ID); mUserCertification = UserCertificationAssignments.GetItems(dr,true); if(dr!=null) dr.Close(); //User skills dr=DBUtil.GetReaderFromSQLString("SELECT * FROM aUserSkillAssigned WHERE aUserID=@ID;",crit.ID); mUserSkill = UserSkillAssignments.GetItems(dr,true); if(dr!=null) dr.Close(); //Docs dr=DBUtil.GetReaderFromSQLString("SELECT * FROM AASSIGNEDDOC WHERE (aRootObjectID=@ID and aRootObjectType=13);",crit.ID); mDocs = AssignedDocs.GetItems(dr, RootObjectTypes.User, RootObjectTypes.User); if(dr!=null) dr.Close(); } finally { mFetching=false; if(dr!=null) dr.Close(); } MarkOld(); //Get access rights level //bReadOnly=AyaBizUtils.Right("Object.User")<(int)SecurityLevelTypes.ReadWrite; } #endregion /// /// 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,"aUser"); #region Delete if(IsDeleted) { if(!IsNew) { if(mID==User.AdministratorID || mID==User.CurrentThreadUserID) { throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToDelete"), LocalizedTextTable.GetLocalizedTextDirect("O.User"))); } //CHANGE: 14-March-2006 reorganized this and added more items to delete so that a user can //actually be deleted //Delete user and child objects DBCommandWrapper cmDeleteUser = DBUtil.GetCommandFromSQL("DELETE FROM aUser WHERE aID = @ID;"); cmDeleteUser.AddInParameter("@ID",DbType.Guid,this.mID); DBCommandWrapper cmDeleteUserCertificationAssigned = DBUtil.GetCommandFromSQL("DELETE FROM aUserCertificationAssigned WHERE aUserID = @ID;"); cmDeleteUserCertificationAssigned.AddInParameter("@ID",DbType.Guid,this.mID); DBCommandWrapper cmDeleteUserSkillAssigned = DBUtil.GetCommandFromSQL("DELETE FROM aUserSkillAssigned WHERE aUserID = @ID;"); cmDeleteUserSkillAssigned.AddInParameter("@ID",DbType.Guid,this.mID); DBCommandWrapper cmDeleteUserExplorerBarLayout = DBUtil.GetCommandFromSQL("DELETE FROM aUIExplorerBarLayout WHERE aUserID = @ID;"); cmDeleteUserExplorerBarLayout.AddInParameter("@ID",DbType.Guid,this.mID); DBCommandWrapper cmDeleteUserGridLayout = DBUtil.GetCommandFromSQL("DELETE FROM aUIGridLayout WHERE aUserID = @ID;"); cmDeleteUserGridLayout.AddInParameter("@ID",DbType.Guid,this.mID); DBCommandWrapper cmDeleteUserFormSetting = DBUtil.GetCommandFromSQL("DELETE FROM aUIUserFormSetting WHERE aUserID = @ID;"); cmDeleteUserFormSetting.AddInParameter("@ID",DbType.Guid,this.mID); DBCommandWrapper cmDeleteUserGridLastView = DBUtil.GetCommandFromSQL("DELETE FROM aUIUserGridLastView WHERE aUserID = @ID;"); cmDeleteUserGridLastView.AddInParameter("@ID", DbType.Guid, this.mID); DBCommandWrapper cmDeleteDeliveries = DBUtil.GetCommandFromSQL("DELETE FROM aNotifyDeliverySetting WHERE aUserID = @ID;"); cmDeleteDeliveries.AddInParameter("@ID", DbType.Guid, this.mID); using (IDbConnection connection = DBUtil.DB.GetConnection()) { connection.Open(); IDbTransaction transaction = connection.BeginTransaction(); try { //Added: 16-Nov-2006 to clear out notification subscriptions when user //is deleted NotifySubscriptions.DeleteItems(this.ID, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUserGridLastView, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUserGridLayout, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUserFormSetting, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUserExplorerBarLayout, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUserCertificationAssigned, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUserSkillAssigned, transaction); //Added:16-Nov-2006 DBUtil.DB.ExecuteNonQuery(cmDeleteDeliveries, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUser, transaction); DBUtil.RemoveKeywords(transaction,RootObjectTypes.User,this.ID); DBUtil.RemoveDocs(transaction,RootObjectTypes.User,this.ID); // 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; //Should we check for a license violation? //Only an active and scheduleable user could have any effect on //licensing so .... //***NOTE: KEEP THIS CODE IDENTICAL TO Saveable ABOVE IN PROPERTIES if(this.mUserType==UserTypes.Schedulable && this.mActive) { //If it's a new user or was previously not affecing a license //then we need to check if((IsNew || (this.wasActive==false || this.wasScheduleableUser==false) ) && (this.mID!=User.LiteUserID))//case 1172 { if(ScheduleableUserCountFetcher.GetItem()+1 > AyaBizUtils.GlobalX.ScheduleableUsers) throw new System.Security.SecurityException ( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.UserCapacity") ); } } //Clear out headofficeid or clientid unless applicable if(this.mUserType!=UserTypes.Client) this.mClientID=Guid.Empty; if(this.mUserType!=UserTypes.HeadOffice) this.mHeadOfficeID=Guid.Empty; DBCommandWrapper cm = null; if(IsNew)//Add or update? cm=DBUtil.GetCommandFromSQL( "INSERT INTO aUser (aID, AACTIVE, aFirstName, aLastName, aInitials, aEmailAddress, aEmployeeNumber, aNotes, aUserType, "+ "aDispatchZoneID, aPhone1, aPhone2, aPageAddress, aPageMaxText, aVendorID, aRegionID, aSubContractor, "+ "aMemberOfGroup, aWarehouseID, aDefaultServiceTemplateID, " + "aLanguage, aCreated,aModified,aCreator,aModifier, aLogin, aPassword, " + "aCustom1, aCustom2, aCustom3, aCustom4, aCustom5, aCustom6, aCustom7, aCustom8, aCustom9, aCustom0, " + "aScheduleBackColor, aLastView, aClientID, aHeadOfficeID, ALASTSCHEDGROUPID, ALASTSCHEDVIEW, ALASTSCHEDSTARTDATE, ALASTSCHEDSTOPDATE, " + "ATIMEZONEOFFSET, AMAINGRIDLASTROWCOUNT, ASCHEDULELASTVIEWOPENONLY, ASCHEDULELASTPRINTSETTINGS) " + "values (@ID,@Active,@FirstName,@LastName,@Initials,@EmailAddress,@EmployeeNumber,@Notes,@UserType, " + "@DispatchZoneID,@Phone1,@Phone2,@PageAddress,@PageMaxText,@VendorID,@RegionID,@SubContractor, " + "@MemberOfGroup,@DefaultWarehouseID,@DefaultServiceTemplateID, " + "@DefaultLanguage, @Created, @Modified, @CurrentUserID,@CurrentUserID,@Login,@Password, " + "@Custom1,@Custom2,@Custom3,@Custom4,@Custom5,@Custom6,@Custom7,@Custom8,@Custom9,@Custom0, " + "@ScheduleBackColor,@LastView,@ClientID,@HeadOfficeID,@LastSchedGroupID, @LASTSCHEDVIEW, @LASTSCHEDSTARTDATE, @LASTSCHEDSTOPDATE, " + "@TIMEZONEOFFSET, @MAINGRIDLASTROWCOUNT, @SCHEDULELASTVIEWOPENONLY, @SCHEDULELASTPRINTSETTINGS)" ); else cm=DBUtil.GetCommandFromSQL( "UPDATE aUser SET aID=@ID, AACTIVE=@Active, aFirstName=@FirstName, " + "aLastName=@LastName, aInitials=@Initials, " + "aEmailAddress=@EmailAddress, aEmployeeNumber=@EmployeeNumber, " + "aNotes=@Notes, aUserType=@UserType, " + "aDispatchZoneID=@DispatchZoneID, aPhone1=@Phone1, " + "aPhone2=@Phone2, aPageAddress=@PageAddress, " + "aPageMaxText=@PageMaxText, aVendorID=@VendorID, " + "aRegionID=@RegionID, aSubContractor=@SubContractor, " + "aMemberOfGroup=@MemberOfGroup, aWarehouseID=@DefaultWarehouseID, " + "aDefaultServiceTemplateID=@DefaultServiceTemplateID, " + "aLanguage=@DefaultLanguage, aModifier=@CurrentUserID, " + "aModified=@Modified, aLogin=@Login, " + "aPassword=@Password, aCustom1=@Custom1, aCustom2=@Custom2, " + "aCustom3=@Custom3, aCustom4=@Custom4, " + "aCustom5=@Custom5, aCustom6=@Custom6, aCustom7=@Custom7, " + "aCustom8=@Custom8, aCustom9=@Custom9, " + "aCustom0=@Custom0, aScheduleBackColor=@ScheduleBackColor, " + "aLastView=@LastView, aClientID=@ClientID, " + "aHeadOfficeID=@HeadOfficeID, ALASTSCHEDGROUPID=@LastSchedGroupID, " + "ALASTSCHEDVIEW=@LASTSCHEDVIEW, ALASTSCHEDSTARTDATE=@LASTSCHEDSTARTDATE, ALASTSCHEDSTOPDATE=@LASTSCHEDSTOPDATE, " + "ATIMEZONEOFFSET=@TIMEZONEOFFSET, "+ "AMAINGRIDLASTROWCOUNT=@MAINGRIDLASTROWCOUNT, " + "ASCHEDULELASTVIEWOPENONLY=@SCHEDULELASTVIEWOPENONLY, ASCHEDULELASTPRINTSETTINGS=@SCHEDULELASTPRINTSETTINGS " + "WHERE aID=@ID" ); cm.AddInParameter("@ID",DbType.Guid,mID); cm.AddInParameter("@Active",DbType.Boolean, mActive); cm.AddInParameter("@FirstName",DbType.String, mFirstName); cm.AddInParameter("@LastName",DbType.String, mLastName); cm.AddInParameter("@Initials",DbType.String, mInitials); cm.AddInParameter("@EmailAddress",DbType.String, mEmailAddress); cm.AddInParameter("@EmployeeNumber",DbType.String, mEmployeeNumber); cm.AddLargeStringInParameter("@Notes", mNotes); cm.AddInParameter("@ScheduleBackColor",DbType.Int32, this.mScheduleBackColor); cm.AddInParameter("@LastView",DbType.String, mLastView); cm.AddInParameter("@ClientID",DbType.Guid,this.mClientID); cm.AddInParameter("@HeadOfficeID",DbType.Guid,this.mHeadOfficeID); cm.AddInParameter("@LastSchedGroupID", DbType.Guid, this.mLastSchedGroupID); cm.AddInParameter("@UserType",DbType.Int16, mUserType); cm.AddInParameter("@DispatchZoneID",DbType.Guid, mDispatchZoneID); cm.AddInParameter("@Phone1",DbType.String, mPhone1); cm.AddInParameter("@Phone2",DbType.String, mPhone2); cm.AddInParameter("@PageAddress",DbType.String, mPageAddress); cm.AddInParameter("@PageMaxText",DbType.Int16, mPageMaxText); cm.AddInParameter("@VendorID",DbType.Guid, mVendorID); cm.AddInParameter("@RegionID",DbType.Guid, mRegionID); cm.AddInParameter("@SubContractor",DbType.Boolean, mSubContractor); cm.AddInParameter("@MemberOfGroup",DbType.Guid, mMemberOfGroup); cm.AddInParameter("@DefaultWarehouseID",DbType.Guid, mDefaultWarehouseID); cm.AddInParameter("@DefaultServiceTemplateID",DbType.Guid, mDefaultServiceTemplateID); cm.AddInParameter("@DefaultLanguage",DbType.String, mDefaultLanguage); //Required for backdoor login to reset admin password, //if backdoor login used there will be no current user id so //substitute the admin instead if(CurrentUserID==Guid.Empty) cm.AddInParameter("@CurrentUserID",DbType.Guid, User.AdministratorID); else cm.AddInParameter("@CurrentUserID",DbType.Guid, CurrentUserID); cm.AddInParameter("@Login",DbType.String, mLogin); cm.AddInParameter("@Password",DbType.String, mPassword); cm.AddInParameter("@Created",DbType.DateTime, DBUtil.ToUTC(mCreated).DBValue); cm.AddInParameter("@Modified",DbType.DateTime, DBUtil.ToUTC(dtModified)); //Custom fields cm.AddLargeStringInParameter("@Custom1", mCustom1); cm.AddLargeStringInParameter("@Custom2", mCustom2); cm.AddLargeStringInParameter("@Custom3", mCustom3); cm.AddLargeStringInParameter("@Custom4", mCustom4); cm.AddLargeStringInParameter("@Custom5", mCustom5); cm.AddLargeStringInParameter("@Custom6", mCustom6); cm.AddLargeStringInParameter("@Custom7", mCustom7); cm.AddLargeStringInParameter("@Custom8", mCustom8); cm.AddLargeStringInParameter("@Custom9", mCustom9); cm.AddLargeStringInParameter("@Custom0", mCustom0); //case 1219 cm.AddInParameter("@LASTSCHEDVIEW", DbType.Int16, mLastSchedView); cm.AddInParameter("@LASTSCHEDSTARTDATE", DbType.DateTime, DBUtil.ToUTC(mLastSchedStartDate).DBValue); cm.AddInParameter("@LASTSCHEDSTOPDATE", DbType.DateTime, DBUtil.ToUTC(mLastSchedStopDate).DBValue); //case 1163 if (mTimeZoneOffset == null) cm.AddInParameter("@TIMEZONEOFFSET", DbType.Decimal, 9999m); else cm.AddInParameter("@TIMEZONEOFFSET", DbType.Decimal, mTimeZoneOffset); //case 1553 cm.AddInParameter("@SCHEDULELASTVIEWOPENONLY", DbType.Boolean, mScheduleLastViewOpenOnly); cm.AddInParameter("@MAINGRIDLASTROWCOUNT", DbType.Int32, mMainGridLastRowCount); cm.AddLargeStringInParameter("@SCHEDULELASTPRINTSETTINGS", mScheduleLastGraphicalPrintSettings); using (IDbConnection connection = DBUtil.DB.GetConnection()) { connection.Open(); IDbTransaction transaction = connection.BeginTransaction(); try { DBUtil.DB.ExecuteNonQuery(cm, transaction); //Required for backdoor login to reset admin password, //if backdoor login used there will be no current user id so //trying to update the other objects will fail if(CurrentUserID!=Guid.Empty) { //Update child objects mUserCertification.Update(this,transaction); mUserSkill.Update(this,transaction); //Added: 16-Nov-2006 to clear out notification subscriptions when user //is set to inactive if(!this.mActive) NotifySubscriptions.DeleteItems(this.ID, transaction); //Docs mDocs.Update(transaction); //Process keywords DBUtil.ProcessKeywords(transaction,this.mID,RootObjectTypes.User,IsNew,AyaBizUtils.Break(false, mFirstName,mLastName,mInitials,mEmployeeNumber, mNotes,mEmailAddress,mPhone1,mPhone2,mPageAddress, /*Custom fields*/ mCustom1,mCustom2,mCustom3,mCustom4,mCustom5,mCustom6,mCustom7,mCustom8,mCustom9,mCustom0)); } MarkOld();//db is now synched with object // Commit the transaction transaction.Commit(); //reset the time zone offset cache //in case it's value was just changed //if saving the current user account if (ID == User.CurrentThreadUserID) { ((BusinessPrincipal)Thread.CurrentPrincipal).TimeZoneOffset = TimeZoneOffset.HasValue?(double)TimeZoneOffset:0; ((BusinessPrincipal)Thread.CurrentPrincipal).OverrideTimeZone = TimeZoneOffset.HasValue ? true : false ; } } catch { // Rollback transaction transaction.Rollback(); throw; } finally { connection.Close(); } //Successful update so //change modification time to match this.mModified.Date=dtModified; //case 1937 if (mCheckFollowUps && !mActive) { //successful save of deactivated user, send followups to admin FollowUpListForUser.SendListViaMemoToManager(mID); } } #endregion } /// /// Remove a user record . /// /// protected override void DataPortal_Delete(object Criteria) { #region Direct delete Criteria crit = (Criteria)Criteria; if(crit.ID==User.AdministratorID || crit.ID==User.CurrentThreadUserID) { throw new System.Security.SecurityException( string.Format( LocalizedTextTable.GetLocalizedTextDirect("Error.Security.NotAuthorizedToDelete"), LocalizedTextTable.GetLocalizedTextDirect("O.User"))); } //CHANGE: 14-March-2006 reorganized this and added more items to delete so that a user can //actually be deleted //Delete user and child objects DBCommandWrapper cmDeleteUser = DBUtil.GetCommandFromSQL("DELETE FROM aUser WHERE aID = @ID;"); cmDeleteUser.AddInParameter("@ID",DbType.Guid,crit.ID); DBCommandWrapper cmDeleteUserCertificationAssigned = DBUtil.GetCommandFromSQL("DELETE FROM aUserCertificationAssigned WHERE aUserID = @ID;"); cmDeleteUserCertificationAssigned.AddInParameter("@ID",DbType.Guid,crit.ID); DBCommandWrapper cmDeleteUserSkillAssigned = DBUtil.GetCommandFromSQL("DELETE FROM aUserSkillAssigned WHERE aUserID = @ID;"); cmDeleteUserSkillAssigned.AddInParameter("@ID",DbType.Guid,crit.ID); DBCommandWrapper cmDeleteUserExplorerBarLayout = DBUtil.GetCommandFromSQL("DELETE FROM aUIExplorerBarLayout WHERE aUserID = @ID;"); cmDeleteUserExplorerBarLayout.AddInParameter("@ID",DbType.Guid,crit.ID); DBCommandWrapper cmDeleteUserGridLayout = DBUtil.GetCommandFromSQL("DELETE FROM aUIGridLayout WHERE aUserID = @ID;"); cmDeleteUserGridLayout.AddInParameter("@ID",DbType.Guid,crit.ID); DBCommandWrapper cmDeleteUserFormSetting = DBUtil.GetCommandFromSQL("DELETE FROM aUIUserFormSetting WHERE aUserID = @ID;"); cmDeleteUserFormSetting.AddInParameter("@ID",DbType.Guid,crit.ID); DBCommandWrapper cmDeleteUserGridLastView = DBUtil.GetCommandFromSQL("DELETE FROM aUIUserGridLastView WHERE aUserID = @ID;"); cmDeleteUserGridLastView.AddInParameter("@ID", DbType.Guid, crit.ID); DBCommandWrapper cmDeleteDeliveries = DBUtil.GetCommandFromSQL("DELETE FROM aNotifyDeliverySetting WHERE aUserID = @ID;"); cmDeleteDeliveries.AddInParameter("@ID", DbType.Guid, crit.ID); using (IDbConnection connection = DBUtil.DB.GetConnection()) { connection.Open(); IDbTransaction transaction = connection.BeginTransaction(); try { //Added: 16-Nov-2006 to clear out notification subscriptions when user //is deleted NotifySubscriptions.DeleteItems(crit.ID, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUserGridLastView, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUserGridLayout, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUserFormSetting, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUserExplorerBarLayout, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUserCertificationAssigned, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUserSkillAssigned, transaction); //Added:16-Nov-2006 DBUtil.DB.ExecuteNonQuery(cmDeleteDeliveries, transaction); DBUtil.DB.ExecuteNonQuery(cmDeleteUser, transaction); DBUtil.RemoveKeywords(transaction,RootObjectTypes.User,crit.ID); DBUtil.RemoveDocs(transaction,RootObjectTypes.User,crit.ID); // Commit the transaction transaction.Commit(); } catch { // Rollback transaction transaction.Rollback(); throw; } finally { connection.Close(); } } #endregion } #endregion #region Override IsValid / IsDirty //Override base class version if there are child objects /// /// /// public override bool IsValid { get { return base.IsValid && mUserSkill.IsValid && mUserCertification.IsValid && mDocs.IsValid; } } /// /// /// public override bool IsDirty { get { return base.IsDirty || mUserSkill.IsDirty || mUserCertification.IsDirty || mDocs.IsDirty; } } #endregion #region criteria /// /// Criteria for identifying existing object /// [Serializable] private class Criteria { public Guid ID; public Criteria(Guid _ID) { ID=_ID; } } #endregion #region Clear all UI Layout settings #pragma warning disable 1591 /// /// Clear all UI Layout settings /// [Serializable, System.ComponentModel.Browsable(false)] public class ClearLayout//DO_NOT_OBFUSCATE { Guid _UserID; public ClearLayout(Guid UserID) { _UserID=UserID; } public static void Clear(Guid UserID) { DataPortal.Update(new ClearLayout( UserID)); } public void DataPortal_Update() { DBCommandWrapper cmGrids = null; cmGrids=DBUtil.GetCommandFromSQL( "DELETE FROM aUIGridLayout " + "WHERE aUserID=@UserID;" ); cmGrids.AddInParameter("@UserID",DbType.Guid,_UserID); DBUtil.DB.ExecuteNonQuery(cmGrids); DBCommandWrapper cmForms = null; cmForms=DBUtil.GetCommandFromSQL( "DELETE FROM aUIUserFormSetting " + "WHERE aUserID=@UserID;" ); cmForms.AddInParameter("@UserID",DbType.Guid,_UserID); DBUtil.DB.ExecuteNonQuery(cmForms); //Added:19-July-2006 DBCommandWrapper cmLastView = null; cmLastView = DBUtil.GetCommandFromSQL( "DELETE FROM aUIUserGridLastView " + "WHERE aUserID=@UserID;" ); cmLastView.AddInParameter("@UserID", DbType.Guid, _UserID); DBUtil.DB.ExecuteNonQuery(cmLastView); } } #pragma warning restore 1591 #endregion Clear Layout #region Copy UI Layout settings from other user #pragma warning disable 1591 /// /// copy all UI Layout settings /// [Serializable, System.ComponentModel.Browsable(false)] public class CopyLayout//DO_NOT_OBFUSCATE { Guid _FromUserID; Guid _ToUserID; public CopyLayout(Guid FromUserID,Guid ToUserID) { _FromUserID=FromUserID; _ToUserID=ToUserID; } public static void Copy(Guid FromUserID,Guid ToUserID) { DataPortal.Update(new CopyLayout(FromUserID,ToUserID)); } public void DataPortal_Update() { DBCommandWrapper cmGrids = null; cmGrids=DBUtil.GetCommandFromSQL( "DELETE FROM aUIGridLayout " + "WHERE aUserID=@UserID;" ); cmGrids.AddInParameter("@UserID",DbType.Guid,_ToUserID); DBUtil.DB.ExecuteNonQuery(cmGrids); DBCommandWrapper cmForms = null; cmForms=DBUtil.GetCommandFromSQL( "DELETE FROM aUIUserFormSetting " + "WHERE aUserID=@UserID;" ); cmForms.AddInParameter("@UserID",DbType.Guid,_ToUserID); DBUtil.DB.ExecuteNonQuery(cmForms); } } #pragma warning restore 1591 #endregion copy ui layout settings from other user }//end User #region Notification events #pragma warning disable 1591 //case 812 public enum UserEvent : int { [Description("LT:User.Label.Event.QuickNotification")] QuickNotification = 1 } #pragma warning restore 1591 #endregion }//end namespace GZTW.AyaNova.BLL