PageRenderTime 130ms CodeModel.GetById 30ms app.highlight 68ms RepoModel.GetById 22ms app.codeStats 0ms

/GolfSigma.Inventory/Model/TeeTime.cs

http://github.com/golfsigma/inventory-client
C# | 559 lines | 373 code | 87 blank | 99 comment | 47 complexity | 030f8879e376f33743d2900fbc7318f9 MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.Text;
  4using System.Runtime.Serialization;
  5using System.Xml.Serialization;
  6
  7using GolfSigma.Inventory.Extension;
  8
  9namespace GolfSigma.Inventory.Model
 10{
 11    #region Enumerations tied directed to TeeTime(s)
 12
 13    public enum FeeEnum : int
 14    {
 15        UnKnown = 0,
 16        Green = 1,
 17        Cart = 2,
 18        Booking = 3,
 19        Tax = 4,
 20        RackRate = 5
 21    }
 22
 23    public enum TeeTimeAttributeEnum : int
 24    {
 25        Holes18 = 0,
 26        Holes9 = 5,
 27        Holes27 = 10,
 28        Holes36 = 15,
 29        ResidentRestriction = 20,
 30        ResidentOnly = 25,
 31        GPSIncluded = 30,
 32        MembersOnly = 35,
 33        MemberDiscount = 40,
 34        PlayerCardDiscount = 45,
 35        PlayerCardOnly = 50,
 36        PracticeBalls = 55,
 37        SeniorDiscount = 60,
 38        SeniorOnly = 65,
 39        Twilight = 70,
 40        TaxIncluded = 75,
 41        Walking = 80,
 42        CartIncluded = 85,
 43        CaddieIncluded = 90,
 44        PullCartIncluded = 95,
 45        Replay = 100,
 46        Aerification = 105,
 47        MilitaryDiscount = 110,
 48        ShotgunStart = 115,
 49        CourseAlert = 120,
 50        FreeReplay = 125,
 51        OverSeeding = 130,
 52        BestRateGuarantee = 135,
 53        CartPathOnly = 140,
 54        PrePaidOnline = 145
 55    }
 56
 57    [Flags]
 58    public enum PlayerEnum : int
 59    {
 60        None = 0x0,
 61        Single = 0x1,
 62        Twosome = 0x2,
 63        Threesome = 0x4,
 64        Foursome = 0x8,
 65        All = Single | Twosome | Threesome | Foursome
 66    }
 67
 68    /// <summary>
 69    /// Currencies and their official names
 70    /// </summary>
 71    public enum CurrencyEnum
 72    {
 73        /// <summary>
 74        /// United States dollar
 75        /// </summary>
 76        USD = 0,
 77
 78        /// <summary>
 79        /// British Pound
 80        /// </summary>
 81        GBP = 5,
 82
 83        /// <summary>
 84        /// Canadian dollar
 85        /// </summary>
 86        CAD = 10,
 87
 88        /// <summary>
 89        /// Euro
 90        /// </summary>
 91        EUR = 15,
 92
 93        /// <summary>
 94        /// Australian dollar
 95        /// </summary>
 96        AUD = 20,
 97
 98        /// <summary>
 99        /// Japanese yen
100        /// </summary>
101        JPY = 25,
102
103        /// <summary>
104        /// Swiss Franc
105        /// </summary>
106        CHF = 30,
107
108        /// <summary>
109        /// Hong Kong Dollar
110        /// </summary>
111        HKD = 35,
112
113        /// <summary>
114        /// Mexican Peso
115        /// </summary>
116        MXN = 40
117    }
118
119    #endregion
120
121    [XmlRoot("TeeTime")]
122    public class TeeTime : IXmlSerializable
123    {
124        #region Ids
125
126        /// <summary>
127        /// Id of the tee-time. Id will be dropped on insert(s)
128        /// </summary>
129        public UInt64 TeeTimeId { get; set; }
130
131        /// <summary>
132        /// Website for the specific tee-time. 
133        /// </summary>
134        public UInt32 WebSiteId { get; set; }
135
136        /// <summary>
137        /// Course for the specific tee-time
138        /// </summary>
139        public UInt64 CourseId { get; set; }
140
141        #endregion
142
143        #region Time and Players
144
145        /// <summary>
146        /// Date and Time of the tee-time.
147        /// </summary>
148        public DateTime Time { get; set; }
149
150        /// <summary>
151        /// Number of players available for the current tee time. Use bitwise operators to determine the number
152        /// of players available.
153        /// </summary>
154        public PlayerEnum Players { get; set; }
155
156        /// <summary>
157        /// Miscellaneous data. Providers can store information used to regenerate lookups to their own tee-time ids etc.
158        /// </summary>
159        public string MiscData { get; set; }
160
161        #endregion
162
163        #region Fees
164
165        /// <summary>
166        /// Total searchType per player. Sum of GreenFee, CartFee, Tax and Booking Fee
167        /// </summary>
168        public float TotalPricePerPlayer { get; set; }
169
170        /// <summary>
171        /// Percentage of interval off the original green fee
172        /// </summary>
173        public double? Savings { get; set; }
174
175        /// <summary>
176        /// Detailed breakdown of fees for this tee-time
177        /// </summary>
178        public Dictionary<FeeEnum, float> Fees { get; set; }
179
180        /// <summary>
181        /// Currency of the fees and total price per player
182        /// </summary>
183        public CurrencyEnum Currency { get; set; }
184
185        #endregion
186
187        #region Dates
188
189        /// <summary>
190        /// DateTime of when this tee time was created. (UTC) (Item will be dropped on any insert or update.)
191        /// </summary>
192        public DateTime Created { get; set; }
193
194        /// <summary>
195        /// DateTime of when this tee-time was last updated. (UTC) (Item will be dropped on any insert or update.)
196        /// </summary>
197        public DateTime? Updated { get; set; }
198
199        /// <summary>
200        /// DateTime of when this tee-time was deleted. (UTC) (Item will be dropped on any insert or update.)
201        /// </summary>
202        public DateTime? Deleted { get; set; }
203
204        #endregion
205
206        #region Attributes
207
208        /// <summary>
209        /// Attributes for the given tee times. List of integers (comma separated when serialized) representing
210        /// all attributes that apply for the given tee time
211        /// </summary>
212        public List<TeeTimeAttributeEnum> Attributes { get; set; }
213
214        private int? _NumberOfHoles;
215        /// <summary>
216        /// The number of holes for this tee-time
217        /// ** ASSUME 18 HOLES!! **
218        /// </summary>
219        public int NumberOfHoles
220        {
221            get
222            {
223                if (_NumberOfHoles.HasValue)
224                    return _NumberOfHoles.Value;
225
226                if (this.Attributes == null || this.Attributes.Count < 1)
227                {
228                    _NumberOfHoles = 18;
229                }
230                else
231                {
232                    if (this.Attributes.Contains(TeeTimeAttributeEnum.Holes9))
233                        _NumberOfHoles = 9;
234                    else if (this.Attributes.Contains(TeeTimeAttributeEnum.Holes27))
235                        _NumberOfHoles = 27;
236                    else if (this.Attributes.Contains(TeeTimeAttributeEnum.Holes36))
237                        _NumberOfHoles = 36;
238                    else
239                        _NumberOfHoles = 18;
240                }
241
242                // Return the number of holes
243                return _NumberOfHoles.Value;
244            }
245        }
246
247        #endregion
248
249        #region IXmlSerializable Members
250
251        public System.Xml.Schema.XmlSchema GetSchema()
252        {
253            return null;
254        }
255
256        public void ReadXml(System.Xml.XmlReader reader)
257        {
258            // Check to see if we were provided an id
259            string teeTimeId = reader.GetAttribute("id");
260            if (!string.IsNullOrEmpty(teeTimeId))
261            {
262                UInt64 teeTimeIdParsed;
263                if (UInt64.TryParse(teeTimeId, out teeTimeIdParsed))
264                    TeeTimeId = teeTimeIdParsed;
265                else
266                    throw new FormatException();
267            }
268
269            bool breakRead = false;
270            while (breakRead == false)
271            {
272                reader.Read();
273                string localName = reader.LocalName;
274
275                string elementAsString = string.Empty;
276                elementAsString = reader.ReadString();
277
278                switch (localName)
279                {
280                    case "WebSiteId":
281                        UInt32? webSiteIdParsed = StringExtension.ToUInt32(elementAsString);
282                        if (!webSiteIdParsed.HasValue)
283                            throw new FormatException();
284                        else
285                            WebSiteId = webSiteIdParsed.Value;
286                        break;
287
288                    case "CourseId":
289                        UInt64? courseIdParsed = StringExtension.ToUInt64(elementAsString);
290                        if (!courseIdParsed.HasValue)
291                            throw new FormatException();
292                        else
293                            CourseId = courseIdParsed.Value;
294                        break;
295
296                    case "Players":
297                        int playersParsed = 0;
298                        if (!int.TryParse(elementAsString, out playersParsed))
299                            throw new FormatException();
300                        else
301                            Players = (PlayerEnum)playersParsed;
302                        if (Players == PlayerEnum.None)
303                            throw new FormatException();
304                        break;
305
306                    case "Time":
307                        DateTime timeParsed;
308                        if (!DateTime.TryParseExact(
309                            elementAsString,
310                            Extension.StringExtension.DateTimeFormatShort,
311                            System.Globalization.CultureInfo.InvariantCulture,
312                            System.Globalization.DateTimeStyles.AssumeLocal | System.Globalization.DateTimeStyles.AllowWhiteSpaces,
313                            out timeParsed))
314                            throw new FormatException();
315                        else
316                            Time = timeParsed;
317                        break;
318
319                    case "Created":
320                        DateTime createdParsed;
321                        if (!DateTime.TryParseExact(
322                            elementAsString,
323                            Extension.StringExtension.DateTimeFormatUTC,
324                            System.Globalization.CultureInfo.InvariantCulture,
325                            System.Globalization.DateTimeStyles.AssumeUniversal | System.Globalization.DateTimeStyles.AllowWhiteSpaces,
326                            out createdParsed))
327                            throw new FormatException();
328                        else
329                            Created = createdParsed;
330                        break;
331
332                    case "Deleted":
333                        DateTime deletedParsed;
334                        if (!DateTime.TryParseExact(
335                            elementAsString,
336                            Extension.StringExtension.DateTimeFormatUTC,
337                            System.Globalization.CultureInfo.InvariantCulture,
338                            System.Globalization.DateTimeStyles.AssumeUniversal | System.Globalization.DateTimeStyles.AllowWhiteSpaces,
339                            out deletedParsed))
340                            throw new FormatException();
341                        else
342                            Deleted = deletedParsed;
343                        break;
344
345                    case "Price":
346                        float priceParsed;
347                        if (float.TryParse(elementAsString, out priceParsed))
348                            TotalPricePerPlayer = priceParsed;
349                        else
350                            // Failed (anything lower than -1 is a failure)
351                            throw new FormatException();
352                        if (TotalPricePerPlayer < -1 || TotalPricePerPlayer > 1000)
353                            throw new FormatException();
354                        break;
355
356                    case "Currency":
357                        try
358                        {
359                            CurrencyEnum currencyParsed = (CurrencyEnum)Enum.Parse(
360                                typeof(CurrencyEnum),
361                                elementAsString,
362                                true);
363
364                            Currency = currencyParsed;
365                        }
366                        catch
367                        {
368                            throw new FormatException();
369                        }
370                        break;
371
372                    case "Savings":
373                        Double savingsParsed;
374                        if (double.TryParse(elementAsString, out savingsParsed))
375                            Savings = savingsParsed;
376                        else
377                            throw new FormatException();
378                        break;
379
380                    case "Fees":
381                        // Create a new list
382                        if (Fees == null)
383                            Fees = new Dictionary<FeeEnum, float>();
384
385                        while (reader.IsStartElement("Fee"))
386                        {
387                            string feeType = reader.GetAttribute("type");
388                            string feeValue = reader.GetAttribute("value");
389
390                            // Skip if we don't have a fee AND value
391                            if (string.IsNullOrEmpty(feeType) || string.IsNullOrEmpty(feeValue))
392                            {
393                                reader.Read();
394                                continue;
395                            }
396
397                            FeeEnum feeTypeParsed = FeeEnum.UnKnown;
398                            try
399                            {
400                                // Attempt to convert the feeType into an enum
401                                feeTypeParsed = (FeeEnum)Enum.Parse(typeof(FeeEnum), feeType);
402                            }
403                            catch
404                            {
405                                throw new FormatException();
406                            }
407
408                            // Attempt to parse the value
409                            float feeValueParsed;
410                            if (float.TryParse(feeValue, out feeValueParsed))
411                                Fees.Add(feeTypeParsed, feeValueParsed);
412                            else
413                                throw new FormatException();
414
415                            // Done reading this element
416                            reader.Read();
417                        }
418                        break;
419
420                    case "Attributes":
421                        // Make sure we have attributes
422                        if (!string.IsNullOrEmpty(elementAsString))
423                        {
424                            // Create a new list if it doesn't exist
425                            if (Attributes == null)
426                                Attributes = new List<TeeTimeAttributeEnum>();
427
428                            // Loop through each attribute and add it to the attribute list!
429                            foreach (var attr in elementAsString.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
430                            {
431                                try
432                                {
433                                    // Attempt to parse the attribute
434                                    TeeTimeAttributeEnum attrParsed =
435                                        (TeeTimeAttributeEnum)Enum.Parse(typeof(TeeTimeAttributeEnum), attr, true);
436
437                                    if (StringExtension.IsNumber(attrParsed.ToString(), false))
438                                    {
439                                        throw new FormatException();
440                                    }
441
442                                    // Add to the list
443                                    Attributes.Add(attrParsed);
444                                }
445                                catch
446                                {
447                                    throw new FormatException();
448                                }
449                            }
450                        }
451                        break;
452
453                    case "Misc":
454                        if (!string.IsNullOrEmpty(elementAsString))
455                            MiscData = elementAsString;
456                        break;
457
458                    case "TeeTime":
459                        // End reading this element
460                        reader.ReadEndElement();
461                        breakRead = true;
462                        break;
463
464                    // Do nothing on any other attribute
465                    default: break;
466                }
467            }
468        }
469
470        public void WriteXml(System.Xml.XmlWriter writer)
471        {
472            throw new NotImplementedException();
473        }
474
475        #endregion
476
477        #region Post Parameters
478
479        public Dictionary<string, string> GetPostParamters()
480        {
481            return GetPostParamters(default(int?));
482        }
483
484        public Dictionary<string, string> GetPostParamters(int? index)
485        {
486            string prefix = "teetime.";
487
488            // Create our result
489            Dictionary<string, string> result = new Dictionary<string, string>();
490
491            result.Add(StringExtension.Prefix("websiteid", prefix, index), WebSiteId.ToString());
492            result.Add(StringExtension.Prefix("courseid", prefix, index), CourseId.ToString());
493            result.Add(StringExtension.Prefix("time", prefix, index), Time.ToString(Extension.StringExtension.DateTimeFormatShort));
494            result.Add(StringExtension.Prefix("players", prefix, index), ((int)Players).ToString());
495            result.Add(StringExtension.Prefix("currency", prefix, index), Currency.ToString());
496
497            // Add our savings
498            if (Savings.HasValue)
499                result.Add(StringExtension.Prefix("savings", prefix, index), Savings.Value.ToString());
500
501            // Convert our attributes to filters
502            if (Attributes != null && Attributes.Count > 0)
503            {
504                StringBuilder sbAttributes = new StringBuilder();
505                foreach (var item in Attributes)
506                    sbAttributes.AppendFormat("{0},", ((int)item).ToString());
507
508                // Add without the trailing comma
509                result.Add(StringExtension.Prefix("attributes", prefix, index), sbAttributes.ToString(0, sbAttributes.Length - 1));
510            }
511
512            // Convert our fees
513            if (Fees != null && Fees.Count > 0)
514            {
515                string feePrefix = "fee.";
516                int i = 1;
517                foreach (var item in Fees)
518                {
519                    string keyPrefix = StringExtension.Prefix(StringExtension.Prefix("key", feePrefix, i), prefix, index);
520                    string valuePrefix = StringExtension.Prefix(StringExtension.Prefix("value", feePrefix, i), prefix, index);
521
522                    result.Add(keyPrefix, item.Key.ToString());
523                    result.Add(valuePrefix, item.Value.ToString());
524                    i++;
525                }
526            }
527
528            if (!string.IsNullOrEmpty(MiscData))
529                result.Add(StringExtension.Prefix("miscdata", prefix, index), MiscData);
530
531            // Return the params
532            return result;
533        }
534
535        #endregion
536
537        public TeeTime() { }
538        public TeeTime(TeeTime input) : this()
539        {
540            if (input == null)
541                return;
542
543            this.Attributes = input.Attributes;
544            this.CourseId = input.CourseId;
545            this.Created = input.Created;
546            this.Currency = input.Currency;
547            this.Deleted = input.Deleted;
548            this.Fees = input.Fees;
549            this.MiscData = input.MiscData;
550            this.Players = input.Players;
551            this.Savings = input.Savings;
552            this.TeeTimeId = input.TeeTimeId;
553            this.Time = input.Time;
554            this.TotalPricePerPlayer = input.TotalPricePerPlayer;
555            this.Updated = input.Updated;
556            this.WebSiteId = input.WebSiteId;
557        }
558    }
559}