/////////////////////////////////////////////////////////// // Address.cs // Implementation of Class Address // CSLA type: Editable Child // Created on: 07-Jun-2004 8:41:13 AM // Object design: Joyce // Coded: John 30-Jun-2004 /////////////////////////////////////////////////////////// using System; using System.Data; using CSLA.Data; using CSLA; using System.Text.RegularExpressions; using System.Text; using System.Threading; using CSLA.Security; //test change for subversion testing using System.ComponentModel; using System.Globalization; using GZTW.Data; namespace GZTW.AyaNova.BLL { /// /// Address object - stores physical location or postal address /// This object used by , , and objects /// /// //[Serializable, TypeConverterAttribute(typeof(AddressConverter))]//case 3379, this seems to be not necessary and is interfering with json serialization? [Serializable] public class Address : BusinessBase { #region Attributes private bool bReadOnly; private AddressTypes mAddressType; private Guid mRootObjectID; private RootObjectTypes mRootObjectType; private Guid mCreator; private Guid mModifier; private SmartDate mCreated; private SmartDate mModified; private string mDeliveryAddress=""; private string mCity=""; private string mStateProv=""; private string mCountry=""; private string mPostal=""; private string mCountryCode=""; private decimal mLatitude; private decimal mLongitude; #endregion #region Constructor private Address() { //Child object MarkAsChild(); //Set to read / write initially so that properties //can be set bReadOnly=false; mRootObjectType=0; mRootObjectID=System.Guid.Empty; mLatitude=0; mLongitude=0; //Set record history to defaults mCreated = new SmartDate(DBUtil.CurrentWorkingDateTime); mModified=new SmartDate(); mCreator=Guid.Empty; mModifier=Guid.Empty; } #endregion #region Business properties /// /// The root object type this address applies to /// Valid settings are: /// Unit, HeadOffice, Vendor, Client /// Global or Region /// [Browsable(false)] public RootObjectTypes RootObjectType { get { return mRootObjectType; } set { if(bReadOnly) ThrowSetError(); else { if(mRootObjectType!=value) { mRootObjectType = value; BrokenRules.Assert("RootObjectTypeInValid", "Error.Object.FieldValueNotValid,Common.Label.RootObjectType", "RootObjectType", ((value!=RootObjectTypes.Unit)&&(value!=RootObjectTypes.HeadOffice)&& (value!=RootObjectTypes.Vendor)&&(value!=RootObjectTypes.Client)&& (value!=RootObjectTypes.Global)&&(value!=RootObjectTypes.Region))); MarkDirty(); } } } } /// /// ID of object this address belongs to /// [Browsable(false)] public Guid RootObjectID { get { return mRootObjectID; } set { if(bReadOnly) ThrowSetError(); else { if(mRootObjectID!=value) { mRootObjectID = value; BrokenRules.Assert("RootObjectIDRequired", "Error.Object.RequiredFieldEmpty,Common.Label.RootObject", "RootObjectID",value==System.Guid.Empty); MarkDirty(); } } } } /// /// Type of address (physical (deliver) or postal) /// [Browsable(false)] public AddressTypes AddressType { get { return mAddressType; } set { if(bReadOnly) ThrowSetError(); else { if(value!=AddressTypes.Unset/*<-Because we need to allow it to be set this way * for the constructor*/ && mAddressType!=value) { mAddressType = value; //A Unit can't have a mailing address BrokenRules.Assert("AddressTypeInValid", "Error.Object.FieldValueNotValid,Address.Label.IsMailAddress", "IsMailAddress", ((RootObjectType==RootObjectTypes.Unit)&&(value==AddressTypes.Postal))); //An address type *MUST* be set BrokenRules.Assert("AddressTypeEmpty", "Error.Object.RequiredFieldEmpty,Address.Label.AddressType","IsMailAddress",value==AddressTypes.Unset); MarkDirty(); } } } } /// /// /// [Browsable(false)] public Guid Creator { get { return mCreator; } } /// /// /// [Browsable(false)] public string Created { get { return mCreated.ToString(); } } /// /// /// [Browsable(false)] public Guid Modifier { get { return mModifier; } } /// /// /// [Browsable(false)] public string Modified { get { return mModified.ToString(); } } /// /// Get/set street address - maximum 255 char /// public string DeliveryAddress { get { return mDeliveryAddress; } set { if(bReadOnly) ThrowSetError(); else { if(mDeliveryAddress!=value) { mDeliveryAddress = value; BrokenRules.Assert("DeliveryAddressLength", "Error.Object.FieldLengthExceeded255,Address.Label.DeliveryAddress","DeliveryAddress",value.Length>255); MarkDirty(); } } } } /// /// Get/set city for this address - maximum 255 char - may have default /// entered by global/regional settings /// public string City { get { return mCity; } set { if(bReadOnly) ThrowSetError(); else { if(mCity!=value) { mCity = value; BrokenRules.Assert("CityLength", "Error.Object.FieldLengthExceeded255,Address.Label.City","City",value.Length>255); MarkDirty(); } } } } /// /// Get/set state or province for this address - maximum 255 char - may /// have default entered by global/regional settings /// public string StateProv { get { return mStateProv; } set { if(bReadOnly) ThrowSetError(); else { if(mStateProv!=value) { mStateProv = value; BrokenRules.Assert("StateProvLength", "Error.Object.FieldLengthExceeded255,Address.Label.StateProv","StateProv",value.Length>255); MarkDirty(); } } } } /// /// Get/set country for this address - maximum 255 char - may have default /// entered by global/regional settings /// public string Country { get { return mCountry; } set { if(bReadOnly) ThrowSetError(); else { if(mCountry!=value) { mCountry = value; if(mCountry!=null && mCountry!="") { //attempt to auto set the country code here //for english speakers switch(mCountry.ToLower()) { case "canada": mCountryCode="CA"; break; case "us": mCountryCode="US"; break; case "usa": mCountryCode="US"; break; case "united states": mCountryCode="US"; break; case "united states of america": mCountryCode="US"; break; case "america": mCountryCode="US"; break; case "australia": mCountryCode="AU"; break; case "hong kong": mCountryCode="HK"; break; case "china": mCountryCode="CN"; break; case "ireland": mCountryCode="IE"; break; case "india": mCountryCode="IN"; break; case "israel": mCountryCode="IL"; break; case "italy": mCountryCode="IT"; break; case "japan": mCountryCode="JP"; break; case "malta": mCountryCode="MT"; break; case "mexico": mCountryCode="MX"; break; case "new zealand": mCountryCode="NZ"; break; case "puerto rico": mCountryCode="PR"; break; case "singapore": mCountryCode="SG"; break; case "united kingdom": mCountryCode="UK"; break; case "uk": mCountryCode="UK"; break; case "scotland": mCountryCode="UK"; break; case "england": mCountryCode="UK"; break; } } BrokenRules.Assert("CountryLength", "Error.Object.FieldLengthExceeded255,Address.Label.Country","Country",value.Length>255); MarkDirty(); } } } } /// /// Get/set ISO country code for this country, maximum 2 characters /// required for all non-US address lookups /// public string CountryCode { get { return mCountryCode; } set { if(bReadOnly) ThrowSetError(); else { if(mCountryCode!=value) { mCountryCode = value; BrokenRules.Assert("CountryCodeLength", "Error.Object.FieldLengthExceeded,Address.Label.CountryCode,2","CountryCode",value.Length>2); MarkDirty(); } } } } /// /// Get/set postal code or zip code for this address - maximum 255 char /// public string Postal { get { return mPostal; } set { if(bReadOnly) ThrowSetError(); else { if(mPostal!=value) { mPostal = value; BrokenRules.Assert("PostalLength", "Error.Object.FieldLengthExceeded255,Address.Label.Postal","Postal",value.Length>255); MarkDirty(); } } } } /// /// Returns a valid MapQuest url for /// opening a map of address in a web page /// public string MapQuestURL { get { StringBuilder sb=new StringBuilder(); //sb.Append("http://www.mapquest.com/maps/map.adp?"); sb.Append(AyaBizUtils.SS("city=",MapQuestReplacement(this.mCity),"&")); sb.Append(AyaBizUtils.SS("state=",MapQuestReplacement(this.mStateProv),"&")); sb.Append(AyaBizUtils.SS("address=",MapQuestReplacement(this.mDeliveryAddress),"&")); sb.Append(AyaBizUtils.SS("zipcode=",MapQuestReplacement(this.mPostal),"&")); sb.Append(AyaBizUtils.SS("country=",MapQuestReplacement(this.mCountryCode),"&")); string s=sb.ToString(); if(s.StartsWith("&")) s=s.Remove(0,1); return "http://www.mapquest.com/maps/map.adp?" + s +"zoom=8&style=3"; } } /// /// makes replacements to any characters that might be /// in a source string so that they conform to mapquest url specs /// /// /// private string MapQuestReplacement(string source) { if(source==null || source=="") return ""; source=source.Replace("\r\n"," "); source=source.Replace("%","%%25"); source=source.Replace("&","%%26"); source=source.Replace("+","%%30"); return source.Replace(" ","+"); } /// /// Get complete address as single string for display /// following US / Canadian postal regulations recommendations: /// DELIVERY ADDRESS /// CITY/STATE/ZIP /// COUNTRY /// public string FullAddress { get { System.Text.StringBuilder sb = new System.Text.StringBuilder(); if(mDeliveryAddress!=null && mDeliveryAddress.Length>0) { sb.Append(mDeliveryAddress); sb.Append(" \r\n"); } if(mCity!=null && mCity.Length>0) { sb.Append(mCity); sb.Append(" "); } if(mStateProv!=null && mStateProv.Length>0) { sb.Append(mStateProv); sb.Append(" "); } if(mPostal!=null && mPostal.Length>0) { //Postal codes should have two spaces before them according to regs. sb.Append(" "); sb.Append(mPostal); sb.Append(" \r\n"); } if(mCountry!=null && mCountry.Length>0) { sb.Append(mCountry); } if(mAddressType==AddressTypes.Physical) { if(mLatitude!=0 || mLongitude!=0) { sb.Append(" \r\n"); sb.Append(LongitudeToString(mLongitude)); sb.Append(" "); sb.Append(LatitudeToString(mLatitude)); sb.Append(" \r\n"); } } return sb.ToString(); } } /// /// Longitude in decimal degrees /// public decimal Longitude { get { return mLongitude; } set { if(bReadOnly) ThrowSetError(); else { if(mLongitude!=value) { mLongitude = value; BrokenRules.Assert("LongitudeSetError", "Error.Object.FieldValueNotValid,Address.Label.Longitude","Longitude",mLongitude!=0 && ((mLongitude>180) || (mLongitude < -180))); MarkDirty(); } } } } /// /// Latitude in decimal degrees /// public decimal Latitude { get { return mLatitude; } set { if(bReadOnly) ThrowSetError(); else { if(mLatitude!=value) { mLatitude = value; BrokenRules.Assert("LatitudeSetError", "Error.Object.FieldValueNotValid,Address.Label.Latitude","Latitude",mLatitude !=0 && ((mLatitude>90) || (mLatitude < -90))); MarkDirty(); } } } } /// /// Longitude as text /// SET: parses most text formats of different styles co-ordinates /// /// GET: Returns text formatted as per global coordinate style setting /// public string LongitudeText { get { return LongitudeAsString(AyaBizUtils.GlobalSettings.CoordinateStyle,true); } set { if(bReadOnly) ThrowSetError(); else { string strValue=value; if(strValue==null) strValue=""; //If there is no negative or positive sign specified then //it's open to interpretation if(!strValue.StartsWith("-") && !strValue.StartsWith("+")) { //Time to interpret... //if the current value is zero then apply the global default chosen if(mLongitude==0) { if(AyaBizUtils.GlobalSettings.DefaultLongitude==LongitudeHemisphere.West) strValue="-" + strValue; } else {//otherwise use the same Hemisphere as the existing value if(mLongitude<0) strValue="-" + strValue; } } LongitudeFromString(strValue); MarkDirty(); } } } /// /// Latitude as text /// SET: parses most text formats of different styles co-ordinates /// GET: Returns text formatted as per global coordinate style setting /// /// public string LatitudeText { get { return LatitudeAsString(AyaBizUtils.GlobalSettings.CoordinateStyle,true); } set { if(bReadOnly) ThrowSetError(); else { string strValue=value; if(strValue==null) strValue=""; //If there is no negative or positive sign specified then //it's open to interpretation if(!strValue.StartsWith("-") && !strValue.StartsWith("+")) { //Time to interpret... //if the current value is zero then apply the global default chosen if(mLatitude==0) { if(AyaBizUtils.GlobalSettings.DefaultLatitude==LatitudeHemisphere.South) strValue="-" + strValue; } else {//otherwise use the same Hemisphere as the existing value if(mLatitude<0) strValue="-" + strValue; } } LatitudeFromString(strValue); MarkDirty(); } } } /// /// Get/Set the Hemisphere of the current Latitude coordinate /// (0 Latitude is always considered North for display purposes) /// public LatitudeHemisphere LatHemisphere { get { if(mLatitude<0) return LatitudeHemisphere.South; return LatitudeHemisphere.North; } set { if(bReadOnly) ThrowSetError(); else { if(mLatitude!=0 && value!=LatHemisphere) { mLatitude = -mLatitude; MarkDirty(); } } } } /// /// Get/Set the Hemisphere of the current Longitude coordinate /// (0 Longitude is always considered West for display purposes) /// public LongitudeHemisphere LongHemisphere { get { if(mLongitude<=0) return LongitudeHemisphere.West; return LongitudeHemisphere.East; } set { if(bReadOnly) ThrowSetError(); else { if(mLongitude!=0 && value!=LongHemisphere) { mLongitude = -mLongitude; MarkDirty(); } } } } #region various Coordinat display related methods /// /// Get Longitude as string /// No indication of East / West /// It is up to caller to check decimal value of /// Longitude separately to determine if required /// /// Format desired /// Return string with degrees and other symbols /// String representation of Longitude private string LongitudeAsString(CoordinateTypes CoOrdinateType,bool IncludeSeparatorCharacters) { string sReturn=""; //When not set should return zero if(mLongitude==0) return "0"; switch(CoOrdinateType) { case CoordinateTypes.DecimalDegrees: sReturn= System.Math.Abs(mLongitude).ToString(); break; case CoordinateTypes.DegreesDecimalMinutes: sReturn=DecimalDegreesToDMText(mLongitude, IncludeSeparatorCharacters); break; case CoordinateTypes.DegreesMinutesSeconds: sReturn= DecimalDegreesToDMSText(mLongitude, IncludeSeparatorCharacters); break; } return sReturn; } /// /// Get Latitude as string /// No indication of North / South /// It is up to caller to check decimal value of /// latitude separately to determine if required /// /// Format desired /// Return string with degrees and other symbols /// String representation of Latitude private string LatitudeAsString(CoordinateTypes CoOrdinateType,bool IncludeSeparatorCharacters) { string sReturn=""; //When not set should return zero if(mLatitude==0) return "0"; switch(CoOrdinateType) { case CoordinateTypes.DecimalDegrees: sReturn= System.Math.Abs(mLatitude).ToString(); break; case CoordinateTypes.DegreesDecimalMinutes: sReturn= DecimalDegreesToDMText(mLatitude, IncludeSeparatorCharacters); break; case CoordinateTypes.DegreesMinutesSeconds: sReturn= DecimalDegreesToDMSText(mLatitude, IncludeSeparatorCharacters); break; } return sReturn; } /// /// Get full Longitude as string using default format /// /// /// public static string LongitudeToString(decimal Longitude) { return LongitudeAsStringWithEastWestIndicator(Longitude,AyaBizUtils.GlobalSettings.CoordinateStyle,true); } /// /// Get Longitude as string in desired format /// /// /// Format desired /// Return string with degrees and other symbols /// decimal number representing longitude /// /// String representation of Longitude public static string LongitudeAsStringWithEastWestIndicator(decimal Longitude, CoordinateTypes CoOrdinateType,bool IncludeSeparatorCharacters) { string NEWS=""; string sReturn=""; //When not set should return empty string if(Longitude==0) return ""; //Negative longitudes are WEST of Greenwich if(Longitude<=0) NEWS=LocalizedTextTable.GetLocalizedTextDirect("UI.Label.West"); else NEWS=LocalizedTextTable.GetLocalizedTextDirect("UI.Label.East"); switch(CoOrdinateType) { case CoordinateTypes.DecimalDegrees: sReturn= NEWS + " " + System.Math.Abs(Longitude).ToString(); break; case CoordinateTypes.DegreesDecimalMinutes: sReturn= NEWS + " " + DecimalDegreesToDMText(Longitude, IncludeSeparatorCharacters); break; case CoordinateTypes.DegreesMinutesSeconds: sReturn= NEWS + " " + DecimalDegreesToDMSText(Longitude, IncludeSeparatorCharacters); break; } return sReturn; } /// /// Convert decimal Latitude to full string representation in default format /// /// /// public static string LatitudeToString(decimal Latitude) { return LatitudeAsStringWithNorthSouthIndicator(Latitude, AyaBizUtils.GlobalSettings.CoordinateStyle,true); } /// /// Get Latitude as string /// Includes localized North or South text prefix /// /// Format desired /// Return string with degrees and other symbols /// decimal type number representing latitude /// String representation of Latitude public static string LatitudeAsStringWithNorthSouthIndicator(decimal Latitude, CoordinateTypes CoOrdinateType,bool IncludeSeparatorCharacters) { string NEWS=""; string sReturn=""; //When not set should return empty string if(Latitude==0) return ""; //Negative Latitudes are SOUTH of the equator if(Latitude<0) NEWS=LocalizedTextTable.GetLocalizedTextDirect("UI.Label.South"); else NEWS=LocalizedTextTable.GetLocalizedTextDirect("UI.Label.North"); switch(CoOrdinateType) { case CoordinateTypes.DecimalDegrees: sReturn= NEWS + " " + System.Math.Abs(Latitude).ToString(); break; case CoordinateTypes.DegreesDecimalMinutes: sReturn= NEWS + " " + DecimalDegreesToDMText(Latitude,IncludeSeparatorCharacters); break; case CoordinateTypes.DegreesMinutesSeconds: sReturn= NEWS + " " + DecimalDegreesToDMSText(Latitude, IncludeSeparatorCharacters); break; } return sReturn; } /// /// Convert decimal degrees to String representation /// of Degrees minutes seconds /// Negative input is not converted to West or South, /// all input is returned as absolute value (with no sign) /// it is up to the caller to add the direction. /// /// /// /// static public string DecimalDegreesToDMSText(decimal DecimalDegrees, bool IncludeSeparatorCharacters) { /* * Degrees=Whole number portion of DecimalDegrees * Minutes = Whole number portion of (Decimal number portion of DecimalDegrees * 60) * Seconds = Minutes decimal portion times 60 * */ if(IncludeSeparatorCharacters) { return string.Format("{0}°{1}'{2}'", System.Math.Abs((int)DecimalDegrees),System.Math.Abs((int)((DecimalDegrees-(int)DecimalDegrees)*60)), (System.Math.Abs((((DecimalDegrees-(int)DecimalDegrees)*60)-(int)((DecimalDegrees-(int)DecimalDegrees)*60))*60)).ToString("F3")); } else { return string.Format("{0}{1}{2}", System.Math.Abs((int)DecimalDegrees),System.Math.Abs((int)((DecimalDegrees-(int)DecimalDegrees)*60)), (System.Math.Abs((((DecimalDegrees-(int)DecimalDegrees)*60)-(int)((DecimalDegrees-(int)DecimalDegrees)*60))*60)).ToString("F3")); } } /// /// Convert decimal degrees to String representation /// of Degrees minutes and decimal minutes (no seconds) /// Negative input is not converted to West or South, /// all input is returned as as absolute value (with no sign) /// it is up to the caller to add the direction. /// /// /// /// static public string DecimalDegreesToDMText(decimal DecimalDegrees, bool IncludeSeparatorCharacters) { /* * Degrees=Whole number portion of DecimalDegrees * Minutes.Decimal minutes = Decimal number portion of DecimalDegrees * 60 * */ if(IncludeSeparatorCharacters) { return string.Format("{0}°{1}'",System.Math.Abs((int)DecimalDegrees), System.Math.Abs(((DecimalDegrees-(int)DecimalDegrees)*60)).ToString("F3")); } else { return string.Format("{0}{1}",(System.Math.Abs((int)DecimalDegrees)).ToString("#00"), System.Math.Abs(((DecimalDegrees-(int)DecimalDegrees)*60)).ToString("00.000")); } } #endregion #region Various coordinate parsing and calc methods /// /// Set Longitude from string /// Expects a '-' sign for West longitudes /// any character other than a digit, decimal (period) or a - sign is /// ignored completely and not used in parsing /// /// /// Accepted types of co-ordinates are: /// Decimal degrees: "-49.3435" /// Degree decimal minutes: "49°22.456" /// Degrees Minutes Seconds Decimal seconds: "49° 22' 13.456''" /// /// Degree symbols are ignored and thus optional as well as minute ' or seconds '' symbols /// traditionally used. All that is important is that there is a space or non-numeric character /// between the groups of digits. /// /// If a single number is found it is assumed to be decimal degrees. /// If two separate numbers are found it is assumed to be Degree decimal minutes /// If three separate groups of numbers are found it is assumed to be Degress minutes seconds /// /// /// String indicating coordinate public void LongitudeFromString(string strLongitude) { try { mLongitude=StringToDecimalDegrees(strLongitude); BrokenRules.Assert("LongitudeSetError","LONGOK","Longitude",false); MarkDirty(); } catch(Exception ex) { mLongitude=0; BrokenRules.Assert("LongitudeSetError", "Error.Object.FieldValueNotValid,Address.Label.Longitude"+"\r\n"+ex.Message,"Longitude",true); MarkDirty(); } return; } /// /// Set Latitude from string /// Expects a '-' sign for South Latitudes /// any character other than a digit, decimal (period) or a - sign is /// ignored completely and not used in parsing /// /// Accepted types of co-ordinates are: /// Decimal degrees: "-49.3435" /// Degree decimal minutes: "49°22.456" /// Degrees Minutes Seconds Decimal seconds: "49° 22' 13.456''" /// /// Degree symbols are ignored and thus optional as well as minute ' or seconds '' symbols /// traditionally used. All that is important is that there is a space or non-numeric character /// between the groups of digits. /// /// If a single number is found it is assumed to be decimal degrees. /// If two separate numbers are found it is assumed to be Degree decimal minutes /// If three separate groups of numbers are found it is assumed to be Degress minutes seconds /// /// /// /// /// String indicating coordinate public void LatitudeFromString(string strLatitude) { try { mLatitude=StringToDecimalDegrees(strLatitude); BrokenRules.Assert("LatitudeSetError","LATOK","Latitude",false); MarkDirty(); } catch(Exception ex) { mLatitude=0; BrokenRules.Assert("LatitudeSetError", "Error.Object.FieldValueNotValid,Address.Label.Latitude"+"\r\n"+ex.Message,"Latitude",true); MarkDirty(); } return; } /// /// Parse a string coordinate and return a double coordinate value /// Negative symbol must be first character if a south latitude or /// a west longitude is input. All characters other than digits, /// decimal point (one only) and negative symbol are ignored. /// /// Accepted types of co-ordinates are: /// Decimal degrees: "-49.3435" /// Degree decimal minutes: "49°22.456" /// Degrees Minutes Seconds Decimal seconds: "49° 22' 13.456''" /// /// Degree symbols are ignored and thus optional as well as minute ' or seconds '' symbols /// traditionally used. All that is important is that there is a space or non-numeric character /// between the groups of digits. /// /// If a single number is found it is assumed to be decimal degrees. /// If two separate numbers are found it is assumed to be Degree decimal minutes /// If three separate groups of numbers are found it is assumed to be Degress minutes seconds /// /// If a null or empty string is the parameter then returns 0 /// /// /// Co-ordinate string /// Double coordinate value static public decimal StringToDecimalDegrees(string strCoordinate) { decimal dLong=0; if(strCoordinate==null || strCoordinate=="") return dLong; //Regular expression to extract numbers groups Regex regex = new Regex( @"[\d.]+", RegexOptions.IgnoreCase | RegexOptions.Compiled ); MatchCollection mc; //Parse string with regular expression mc = regex.Matches(strCoordinate); //Ensure there is at least 1 but less than 4 matches if(mc.Count<1 || mc.Count> 3) throw new System.FormatException("StringToDecimalDegrees:(" + strCoordinate +") INVALID INPUT"); //Parse out the degrees dLong=decimal.Parse(mc[0].Value); //If there are minutes, parse them out and add to the total if(mc.Count>1) dLong+=(decimal.Parse(mc[1].Value)/60); //If there are seconds, parse them out and add to the total if(mc.Count>2) dLong+=(decimal.Parse(mc[2].Value)/3600); //Preserve negative-icity if(strCoordinate[0]=='-') dLong=0-dLong; return dLong; } #endregion //Case 518 /// /// Address object is empty (not filled in)? /// public bool IsEmpty { get { if (string.IsNullOrEmpty(this.mDeliveryAddress.Trim()) && mLatitude==0 && mLongitude==0) return true; return false; } } /// /// 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.Address") ) ); } #endregion #region System.object overrides /// /// /// /// public override string ToString() { return "Address" + mRootObjectID.ToString()+mRootObjectType.ToString()+mAddressType.ToString(); } /// /// /// /// /// public override bool Equals(Object obj) { if ( obj == null || GetType ( ) != obj.GetType ( ) ) return false; Address c=(Address)obj; return ((mRootObjectID==c.RootObjectID) && (mRootObjectType==c.RootObjectType) && (mAddressType==c.AddressType)); } /// /// /// /// public override int GetHashCode() { return ("Address" + mRootObjectID.ToString()+mRootObjectType.ToString()+mAddressType.ToString()).GetHashCode(); } #endregion #region Static methods /// /// ID of the one and only Global object's address /// (since a global object has no ID itself, this value is /// used as the ID for it) /// public static Guid GlobalAddressID { get { return new Guid("{3A440D46-7C19-46f8-94BF-E9368DD16DED}"); } } /// /// Create new Address /// Parent MUST set RootObjectID, RootObjectType and IsMailAddress flag /// internal static Address NewItem() { return new Address(); } /// /// Get an address from passed in data reader /// this is GetItem code /// /// /// /// This sample shows how to call the GetZero method. /// /// class Address /// { /// static int GetItem(blah) /// { return GetZero(); } /// } /// /// internal static Address GetItem(SafeDataReader dr) { Address child = new Address(); child.Fetch(dr); //Get access rights level // (same as parent) child.bReadOnly=AyaBizUtils.Right(child.mRootObjectType)<(int)SecurityLevelTypes.ReadWrite; return child; } /// /// Delete address /// internal static void DeleteItem(AddressTypes _AddressType,Guid _RootObjectID,RootObjectTypes _RootObjectType) { DataPortal.Delete(new Criteria( _AddressType, _RootObjectID, _RootObjectType)); } /// /// copy the contents of one address to another address /// /// /// public static void Copy(Address FromAddress, Address ToAddress) { if(FromAddress==null || ToAddress==null) return; ToAddress.City=FromAddress.City; ToAddress.Country=FromAddress.Country; ToAddress.CountryCode=FromAddress.CountryCode; ToAddress.DeliveryAddress=FromAddress.DeliveryAddress; if(ToAddress.AddressType==AddressTypes.Physical && FromAddress.AddressType==AddressTypes.Physical) { ToAddress.Latitude=FromAddress.Latitude; ToAddress.Longitude=FromAddress.Longitude; } ToAddress.Postal=FromAddress.Postal; ToAddress.StateProv=FromAddress.StateProv; } #endregion #region DAL DATA ACCESS #region custom concurrency check private static void CheckSafeToUpdate(System.DateTime LastUpdated, RootObjectTypes RootObjectType, Guid RootObjectID, AddressTypes AddressType, IDbTransaction tr) { DBCommandWrapper dbCommandWrapper = DBUtil.DB.GetSqlStringCommandWrapper( "SELECT aModified, aModifier FROM AADDRESS WHERE (aRootObjectID " + "= @RootObjectID) AND " + "(aRootObjectType = @RootObjectType) AND (AADDRESSTYPE = @AddressType)" ); dbCommandWrapper.AddInParameter("@RootObjectID",DbType.Guid,RootObjectID); dbCommandWrapper.AddInParameter("@RootObjectType",DbType.Int16,(int)RootObjectType); dbCommandWrapper.AddInParameter("@AddressType",DbType.Int16,(int)AddressType); SafeDataReader r = new SafeDataReader(DBUtil.DB.ExecuteReader(dbCommandWrapper,tr)); if(r.Read()) { if(!DBUtil.DatesAreEqualish(DBUtil.ToUTC(LastUpdated),r.GetSmartDate("aModified").Date)) { Guid gModifier=r.GetGuid("aModifier"); r.Close(); dbCommandWrapper.Command.Parameters.Clear(); dbCommandWrapper.AddInParameter("@ID",DbType.Guid,gModifier); dbCommandWrapper.Command.CommandText="SELECT aFirstName, aLastName FROM aUser WHERE aID = @ID"; r=new SafeDataReader(DBUtil.DB.ExecuteReader(dbCommandWrapper)); if(r.Read()) { string sUser=r.GetString("aFirstName") + " " + r.GetString("aLastName"); r.Close(); throw new System.Exception(string.Format(LocalizedTextTable.GetLocalizedTextDirect("Error.DB.RecordModifiedExternally"),"Address",sUser)); } } else { //de nada r.Close(); return; } } //Added: 20-June-2006 r.Close(); } #endregion #region Update /// /// Update object to database /// /// RootOjbect type /// GUID of root object /// Address type (must be mail or physical) /// Parent object's transaction object internal void Update(RootObjectTypes RootObjectType, Guid RootObjectID, AddressTypes AddressType,IDbTransaction tr) { //No need to update if there is nothing changed if(!this.IsDirty) return; // If not a new record, check if record was modified //by another user since original retrieval: if(!IsNew)//call custom checksafetoupdate method for an address CheckSafeToUpdate(this.mModified.Date,RootObjectType,RootObjectID,AddressType,tr); #region Delete if(IsDeleted) { if(!IsNew) { DBCommandWrapper cmDelete = DBUtil.GetCommandFromSQL("DELETE FROM AADDRESS WHERE (aRootObjectID=@RootObjectID AND aRootObjectType=@RootObjectType and AADDRESSTYPE=@AddressType);"); cmDelete.AddInParameter("@RootObjectID",DbType.Guid,RootObjectID); cmDelete.AddInParameter("@RootObjectType",DbType.Int16,(int)RootObjectType); cmDelete.AddInParameter("@AddressType",DbType.Int16,(int)AddressType); DBUtil.DB.ExecuteNonQuery(cmDelete, tr); } MarkNew(); return; } #endregion #region Add / Update //get modification time temporarily, if update succeeds then //set to this time System.DateTime dtModified = DBUtil.CurrentWorkingDateTime; DBCommandWrapper cm = null; if(IsNew)//Add or update? cm=DBUtil.GetCommandFromSQL( "INSERT INTO AADDRESS (aRootObjectID,aRootObjectType, AADDRESSTYPE, aDeliveryAddress, aCity, aStateProv, " + "aCountry, aCountryCode, aPostal, aLatitude, aLongitude, aCreated,aModified,aCreator,aModifier) " + "VALUES (@RootObjectID,@RootObjectType,@AddressType,@DeliveryAddress,@City,@StateProv, " + "@Country,@CountryCode,@Postal,@Latitude,@Longitude,@Created, @Modified, @CurrentUserID,@CurrentUserID)" ); else cm=DBUtil.GetCommandFromSQL( "UPDATE AADDRESS SET aRootObjectID=@RootObjectID, aRootObjectType=@RootObjectType, " + "AADDRESSTYPE=@AddressType, " + "aDeliveryAddress=@DeliveryAddress, aCity=@City, " + "aStateProv=@StateProv, aCountry=@Country, " + "aCountryCode=@CountryCode, aPostal=@Postal, " + "aLatitude=@Latitude, aLongitude=@Longitude, aModifier=@CurrentUserID, " + "aModified=@Modified WHERE " + "(aRootObjectID=@RootObjectID AND aRootObjectType=@RootObjectType " + "AND AADDRESSTYPE=@AddressType)" ); cm.AddInParameter("@AddressType",DbType.Int16,(int)AddressType); cm.AddInParameter("@RootObjectID",DbType.Guid, RootObjectID); cm.AddInParameter("@RootObjectType",DbType.Int16, (int)RootObjectType); cm.AddInParameter("@CurrentUserID",DbType.Guid, CurrentUserID); cm.AddInParameter("@Created",DbType.DateTime, DBUtil.ToUTC(mCreated.Date)); cm.AddInParameter("@Modified",DbType.DateTime, DBUtil.ToUTC(dtModified)); cm.AddInParameter("@City",DbType.String,mCity); cm.AddInParameter("@Country",DbType.String, mCountry); cm.AddInParameter("@CountryCode",DbType.String, mCountryCode); cm.AddInParameter("@DeliveryAddress",DbType.String, mDeliveryAddress); cm.AddInParameter("@Latitude",DbType.Decimal, mLatitude); cm.AddInParameter("@Longitude",DbType.Decimal, mLongitude); cm.AddInParameter("@Postal",DbType.String, mPostal); cm.AddInParameter("@StateProv",DbType.String, mStateProv); DBUtil.DB.ExecuteNonQuery(cm, tr); MarkOld();//db is now synched with object //Successful update so //change modification time to match this.mModified.Date=dtModified; #endregion } #endregion #region Fetch /// /// Populate this object from the values in the datareader passed to it /// /// private void Fetch(SafeDataReader dr) { //Standard items mCreated=DBUtil.ToLocal(dr.GetSmartDate("aCreated")); mCreator=dr.GetGuid("aCreator"); mModified=DBUtil.ToLocal(dr.GetSmartDate("aModified")); mModifier=dr.GetGuid("aModifier"); //Address specific items mRootObjectID= dr.GetGuid("aRootObjectID"); mRootObjectType=(RootObjectTypes)dr.GetInt16("aRootObjectType"); mAddressType=(AddressTypes)dr.GetInt16("AADDRESSTYPE"); mCity=dr.GetString("aCity"); mCountry=dr.GetString("aCountry"); mCountryCode=dr.GetString("aCountryCode"); mDeliveryAddress=dr.GetString("aDeliveryAddress"); mLatitude=dr.GetDecimal("aLatitude"); mLongitude=dr.GetDecimal("aLongitude"); mPostal=dr.GetString("aPostal"); mStateProv=dr.GetString("aStateProv"); MarkOld(); } #endregion #endregion #region criteria /// /// Criteria for identifying existing object /// [Serializable] private class Criteria { public AddressTypes AddressType; public Guid RootObjectID; public RootObjectTypes RootObjectType; public Criteria(AddressTypes _AddressType,Guid _RootObjectID,RootObjectTypes _RootObjectType) { AddressType=_AddressType; RootObjectID=_RootObjectID; RootObjectType=_RootObjectType; } } #endregion }//end Address //case 3379, this seems to be not necessary and is interfering with json serialization? //#region Address Type converter ///// ///// Type converter for an Address object ///// only ToString is implemented ///// and displays a full address ///// //public class AddressConverter:ExpandableObjectConverter //{ // /// // /// True if address can be converted to desired type // /// // /// // /// // /// // public override bool CanConvertTo(ITypeDescriptorContext context,System.Type destinationType) // { // if (destinationType == typeof(GZTW.AyaNova.BLL.Address)) // return true; // return base.CanConvertTo(context, destinationType); // } // /// // /// Convert address to desired type // /// // /// // /// // /// // /// // /// // public override object ConvertTo(ITypeDescriptorContext context,CultureInfo culture, object value, System.Type destinationType) // { // if (destinationType == typeof(System.String) && // value is GZTW.AyaNova.BLL.Address) // { // GZTW.AyaNova.BLL.Address a = (GZTW.AyaNova.BLL.Address)value; // return a.FullAddress.Replace("\r\n"," "); // } // return base.ConvertTo(context, culture, value, destinationType); // } //} //#endregion }//end namespace GZTW.AyaNova.BLL