private void InsertSingleEventOrder(DataEntities context, Olympiad_Info olympiad, EntryJson order,
                                            ParsedOrder parsedOrder, Dictionary <string, Fee> eventFees)
        {
            // Don't do this case yet
            if (parsedOrder.BookingSpaces != parsedOrder.Entrants.Count())
            {
                return;
            }

            List <ParsedOrder.Entrant> EntrantsToCreate = new List <ParsedOrder.Entrant>();

            var evt = context.Events.FirstOrDefault(x => x.Code == parsedOrder.EventCode &&
                                                    x.OlympiadId == olympiad.Id);

            // Bad event code
            if (evt == null)
            {
                return;
            }

            var feeExpected = 0m;

            foreach (var parsedEntrant in parsedOrder.Entrants)
            {
                var contestants = context.Contestants.Where(ContestantSelector(parsedEntrant));
                // Don't handle the case of people you can't verify yet
                if (contestants.Count() > 1)
                {
                    return;
                }
                else if (contestants.Count() == 0)
                {
                    EntrantsToCreate.Add(parsedEntrant);
                }

                if (parsedEntrant.DoB.HasValue && parsedEntrant.DoB.Value > olympiad.FirstDateOfBirthForJunior())
                {
                    feeExpected += eventFees[evt.Entry_Fee].Concession.Value;
                }
                else
                {
                    feeExpected += eventFees[evt.Entry_Fee].Adult.Value;
                }
            }

            if (feeExpected != parsedOrder.BookingPrice)
            {
                order.Notes = string.Format("Wrong fee, expected {0} found {1}; ", feeExpected, parsedOrder.BookingPrice);
                //context.SaveChanges();
                //return;
            }

            // All OK - can change entities now.
            if (order.Notes != null)
            {
                order.Notes = "";
            }

            order.Notes += "Assigned to contestant(s) ";
            CreateEntrants(context, EntrantsToCreate);
            foreach (var parsedEntrant in parsedOrder.Entrants)
            {
                var contestants = context.Contestants.Where(ContestantSelector(parsedEntrant));

                var thisPersonsFee = 0.0m;
                if (parsedEntrant.DoB.HasValue && parsedEntrant.DoB.Value > olympiad.FirstDateOfBirthForJunior())
                {
                    thisPersonsFee = eventFees[evt.Entry_Fee].Concession.Value;
                }
                else
                {
                    thisPersonsFee = eventFees[evt.Entry_Fee].Adult.Value;
                }

                var thisContestant = contestants.First();
                // All OK
                thisContestant.Payments.Add(new Payment()
                {
                    Banked         = 1,
                    MindSportsID   = contestants.First().Mind_Sport_ID,
                    OlympiadId     = olympiad.Id,
                    Payment_Method = "MSO Website",
                    Payment1       = thisPersonsFee,
                    Year           = olympiad.StartDate.Value.Year,
                    Received       = DateTime.Now
                });

                // Put the contestant into the right event
                var entrant = Entrant.NewEntrant(evt.EIN, evt.Code, olympiad.Id, thisContestant,
                                                 thisPersonsFee);
                thisContestant.Entrants.Add(entrant);

                // Update the order to avoid re-parsing
                order.ProcessedDate = DateTime.Now;
                order.Notes        += contestants.First().Mind_Sport_ID.ToString() + " ";
            }

            context.SaveChanges();
        }
        private ParsedOrder Parse(EntryJson order)
        {
            // This catches people who only enter day and month for dob - they come through as
            // the current year - and people who want to cause us headaches...
            var validDateCutoff = DateTime.Now.AddYears(-4);

            var text = order.JsonText;

            if (text.StartsWith("\""))
            {
                text = text.Substring(1, text.Length - 2)
                       .Replace("\\", "")
                       .Replace("\"event\"", "\"event_detail\""); // property name is reserved in C#
            }
            dynamic obj = JsonConvert.DeserializeObject(text);
            // One day it would be nice to have consistent JSON sent to me!
            var parsedOrder = new ParsedOrder();

            parsedOrder.BookingId = obj.booking_id.Value;
            parsedOrder.EventCode = obj.event_id.Value;
            // This is a special case...
            if (parsedOrder.EventCode == "divingchess")
            {
                parsedOrder.EventCode = "CHDV";
            }
            parsedOrder.BookingPrice  = (decimal)obj.booking_price.Value;
            parsedOrder.BookingSpaces = int.Parse(obj.booking_spaces.Value);
            parsedOrder.BookingStatus = int.Parse(obj.booking_status.Value.ToString());   // should be integer 1, sometimes string "1"
            foreach (var o2 in obj.attendees)
            {
                // o2.Name is the mysterious number in json
                foreach (var entrant in o2.Value)
                {
                    var parsedEntrant = new ParsedOrder.Entrant();
                    parsedEntrant.Title     = entrant.title.Value;
                    parsedEntrant.FirstName = TitleCase(entrant.first_name.Value);
                    parsedEntrant.LastName  = TitleCase(entrant.last_name.Value);
                    parsedEntrant.Country   = entrant.country_to_represent.Value;
                    parsedEntrant.DoB       = (entrant.date_of_birth != null) ?
                                              DateTime.Parse(entrant.date_of_birth.Value) : null;
                    if (parsedEntrant.DoB > validDateCutoff)
                    {
                        parsedEntrant.DoB = null;
                    }
                    parsedOrder.Entrants.Add(parsedEntrant);

                    // Override if necessary
                    if (order.ManualDoB != null)
                    {
                        parsedEntrant.DoB = order.ManualDoB;
                    }
                }
            }
            parsedOrder.Timestamp = obj.timestamp.Value;
            parsedOrder.EventId   = obj.event_detail.id.Value;
            parsedOrder.EventName = obj.event_detail.name.Value;
            //  MessageBox.Show(obj.attendees);

            /* \"attendees\":{\"31\":[{\"title\":\"Mr\",\"first_name\":\"Howard\",\"last_name\":\"Kenward\",
             * \"country_to_represent\":\"England\",\"date_of_birth\":\"1955-07-26\"}]},
             \"timestamp\":1466096898,\"event\":{\"id\":\"31\",\"name\":\"Trench\"}}" */

            if (parsedOrder.BookingSpaces != parsedOrder.Entrants.Count())
            {
                throw new ParsingFailureException(string.Format("Order {0} has wrong number of entrants", parsedOrder.BookingId));
            }

            return(parsedOrder);
        }
        private void InsertMaxFeeOrder(DataEntities context, Olympiad_Info olympiad, EntryJson order, ParsedOrder parsedOrder)
        {
            // Something wrong with the order
            if (parsedOrder.BookingSpaces != parsedOrder.Entrants.Count())
            {
                return;
            }
            List <ParsedOrder.Entrant> EntrantsToCreate = new List <ParsedOrder.Entrant>();

            var feeExpected = 0m;

            foreach (var parsedEntrant in parsedOrder.Entrants)
            {
                var contestants = context.Contestants.Where(ContestantSelector(parsedEntrant));
                // Don't handle the case of people you can't verify yet
                if (contestants.Count() > 1)
                {
                    return;
                }
                else if (contestants.Count() == 0)
                {
                    EntrantsToCreate.Add(parsedEntrant);
                }

                if (parsedEntrant.DoB != null && parsedEntrant.DoB > olympiad.FirstDateOfBirthForJunior())
                {
                    feeExpected += olympiad.MaxCon.Value;
                }
                else
                {
                    feeExpected += olympiad.MaxFee.Value;
                }
            }

            if (feeExpected != parsedOrder.BookingPrice)
            {
                order.Notes = string.Format("Wrong fee, expected {0} found {1}", feeExpected, parsedOrder.BookingPrice);
                context.SaveChanges();
                return;
            }

            // All OK - can change entities now.
            order.Notes = "Assigned to contestant(s) ";
            CreateEntrants(context, EntrantsToCreate);
            foreach (var parsedEntrant in parsedOrder.Entrants)
            {
                var contestants = context.Contestants.Where(ContestantSelector(parsedEntrant));

                var thisPersonsFee = 0.0m;
                if (parsedEntrant.DoB.HasValue && parsedEntrant.DoB.Value > olympiad.FirstDateOfBirthForJunior())
                {
                    thisPersonsFee = olympiad.MaxCon.Value;
                }
                else
                {
                    thisPersonsFee = olympiad.MaxFee.Value;
                }

                contestants.First().Payments.Add(new Payment()
                {
                    Banked         = 1,
                    MindSportsID   = contestants.First().Mind_Sport_ID,
                    OlympiadId     = olympiad.Id,
                    Payment_Method = "MSO Website",
                    Payment1       = thisPersonsFee,
                    Year           = olympiad.StartDate.Value.Year,
                    Received       = DateTime.Now
                });

                order.ProcessedDate = DateTime.Now;
                order.Notes        += contestants.First().Mind_Sport_ID.ToString() + " ";
            }
            context.SaveChanges();
        }