public ActionResult Aangemeld(InschrijvingModel model)
        {
            bool? isCheckSumValid;
            bool isJustPaid;
            model = CheckConfirmationParameters(out isCheckSumValid, out isJustPaid);

            if (model!=null && (model.DateConfirmationSend==null || isJustPaid)) {
                SendSubscriptionConfirmationMail(model);
            }

            // If the checksum was incorrect then throw an exception in order to be notified (via Health Monitoring) of possible hacking or problems.
            if (isCheckSumValid.HasValue && !isCheckSumValid.Value) {
                string trxId = Request.QueryString["trxid"];
                string ec = Request.QueryString["ec"];
                string error = Request.QueryString["error"];
                string status = Request.QueryString["status"];
                string sha1 = Request.QueryString["sha1"];
                throw new ArgumentException(string.Format("Er ging iets mis. Error in iDeal checksum (trxId: {0}, ec: {1}, error: {2}, status: {3}, sha1: {4}.", trxId, ec, error, status, sha1));
            }
            return View(model);
        }
        /// <summary>
        /// Stuurt een bevestigingsmail van inschrijving naar de gebruiker.
        /// Hiervoor wordt de nieuwsbrief template gebruikt.
        /// </summary>
        /// <param name="model"></param>
        private void SendSubscriptionConfirmationMail(InschrijvingModel model)
        {
            NewsletterViewModel newsletter = new NewsletterViewModel();
            newsletter.IncludeLoginLink = true;
            newsletter.Items = new List<NewsletterItemViewModel>();

            if (!model.DoForceSendConfirmationOfChange) {
                newsletter.IntroText = string.Format("Proficiat! Je hebt je zojuist aangemeld voor Hét Rondje Eilanden! ");
                if (!model.IsBetaald.HasValue || !model.IsBetaald.Value) {
                    newsletter.IntroText += "Je aanmelding wordt omgezet naar een inschrijving na betaling van het inschrijfgeld.";
                } else {
                    newsletter.IntroText += "Je hebt betaald en bent nu ingeschreven.";
                }
            } else {
                if (model.EmailBeforeUpdateIfAny!=model.Email) {
                    newsletter.IntroText = string.Format("Je bent aangemeld voor Hét Rondje Eilanden! Je hebt je e-mail adres gewijzigd, of iemand anders heeft zijn inschrijving naar jouw e-mail overgezet. Bevestig je inschrijving en dit e-mail adres via onderstaande link. ");
                } else {
                    newsletter.IntroText = string.Format("Hier een Flessenpost achtige mail omdat je je inschrijfgegevens hebt gewijzigd.");
                }
            }
            newsletter.IntroText += "<br/>Hieronder ter bevestiging nogmaals je inschrijfgegevens. Als er iets niet klopt graag direct zelf wijzigen door op de website in te loggen via de persoonlijke link hiernaast.";

            NewsletterItemViewModel item1 = new NewsletterItemViewModel();
            if (!model.DoForceSendConfirmationOfChange) {
                item1.Title = "You're in!";
                item1.SubTitle = "voor Hét Rondje Eilanden";
            } else {
                item1.Title = "Thanks for the update!";
                item1.SubTitle = "...change is the only constant :)";
            }
            item1.HeadingHtmlColour = "208900";
            item1.ImagePath = "News_2013.png";
            item1.IconImagePath = "News_TileEB.png";

            item1.Text = string.Format("");
            item1.Text += string.Format("<table>");
                item1.Text += string.Format("<tr><td></td></tr>");
                item1.Text += string.Format("<tr><th colspan=\"2\"><b>Inschrijfgegevens</b></th></tr>");

                item1.Text += string.Format("<tr><td>Naam</td><td>{0}</span></td></tr>", model.VolledigeNaamMetAanhef);
                item1.Text += string.Format("<tr><td>Geboortedatum</td><td>{0}</span></td></tr>", model.GeboorteDatum.HasValue ? model.GeboorteDatum.Value.ToShortDateString() : "-");
                item1.Text += string.Format("<tr><td>NTB Licentie</td><td>{0}</span></td></tr>", string.IsNullOrEmpty(model.LicentieNummer) ? " - " : model.LicentieNummer);
                item1.Text += string.Format("<tr><td>Persoonlijke MyLaps Chip</td><td>{0}</span></td></tr>", string.IsNullOrEmpty(model.MyLapsChipNummer) ? " - " : model.MyLapsChipNummer);

                item1.Text += string.Format("<tr><td></td></tr>");
                item1.Text += string.Format("<tr><th colspan=\"2\"><b>Persoonsgegevens</b></th></tr>");

                item1.Text += string.Format("<tr><td>Geslacht</td><td>{0}</span></td></tr>", model.Geslacht ?? "-");
                item1.Text += string.Format("<tr><td>Straat</td><td>{0}</span></td></tr>", model.Straat ?? "-");
                item1.Text += string.Format("<tr><td>Huisnummer</td><td>{0}</span></td></tr>", model.Huisnummer ?? "-");
                item1.Text += string.Format("<tr><td>Toevoeging</td><td>{0}</span></td></tr>", model.HuisnummerToevoeging ?? "-");
                item1.Text += string.Format("<tr><td>Postcode</td><td>{0}</span></td></tr>", model.Postcode ?? "-");
                item1.Text += string.Format("<tr><td>Woonplaats</td><td>{0}</span></td></tr>", model.Woonplaats?? "-");
                item1.Text += string.Format("<tr><td>Land</td><td>{0}</span></td></tr>", model.Land ?? "-");
                item1.Text += string.Format("<tr><td>E-mail adres</td><td>{0}</span></td></tr>", model.Email ?? "-");
                item1.Text += string.Format("<tr><td>Telefoon</td><td>{0}</span></td></tr>", model.Telefoon ?? "-");

                item1.Text += string.Format("<tr><td></td></tr>");
                item1.Text += string.Format("<tr><th colspan=\"2\"><b>Extra's</b></th></tr>");

                item1.Text += string.Format("<tr><td>Meeeten?</td><td>{0}</span></td></tr>", model.Food ? "Ja" : "Nee");
                item1.Text += string.Format("<tr><td>Kamperen</td><td>{0}</span></td></tr>", model.Camp ? "Interesse" : "Geen interesse");
                item1.Text += string.Format("<tr><td>Fiets stallen</td><td>{0}</span></td></tr>", model.Bike ? "Interesse" : "Geen interesse");
                item1.Text += string.Format("<tr><td>Finale</td><td>{0}</span></td></tr>", model.Finale=="W" ? "Ik ga ervoor!" : "Ik zie wel" );

                item1.Text += string.Format("<tr><td></td></tr>");
                item1.Text += string.Format("<tr><th colspan=\"2\"><b>Opmerkingen</b></th></tr>");

                item1.Text += string.Format("<tr><td>Opmerkingen</td><td>{0}</span></td></tr>", model.HebJeErZinIn ?? "-");
                item1.Text += string.Format("<tr><td>Opmerkingen voor speaker</td><td>{0}</span></td></tr>", model.OpmerkingenTbvSpeaker?? "-");
                item1.Text += string.Format("<tr><td>Opmerkingen voor organisatie</td><td>{0}</span></td></tr>", model.OpmerkingenAanOrganisatie ?? "-");

                item1.Text += string.Format("<tr><td></td></tr>");
                item1.Text += string.Format("<tr><th colspan=\"2\"><b>Inschrijfkosten</b></th></tr>");
                item1.Text += string.Format("<tr><td>Inschrijfgeld</td><td>{0}</span></td></tr>", model.BasisKosten.AsAmount() );
                item1.Text += string.Format("<tr><td>NTB Licentie</td><td>{0}</span></td></tr>", model.KostenNtbDagLicentie.AsAmount() );
                item1.Text += string.Format("<tr><td>MyLaps Chip</td><td>{0}</span></td></tr>", model.KostenChip.AsAmount());
                if (model.IsEarlyBird.HasValue && model.IsEarlyBird.Value) {
                    item1.Text += string.Format("<tr><td>Early Bird™ korting</td><td>{0}</span></td></tr>", model.EarlyBirdKorting.AsAmount());
                }
                item1.Text += string.Format("<tr><td>Avondeten</td><td>{0}</span></td></tr>", model.KostenEten.AsAmount());
                item1.Text += string.Format("<tr><td><b></b></td><td><span class=\"quotable\">------</span></td></tr>");
                item1.Text += string.Format("<tr><td><b>Totaal</b></td><td><span class=\"quotable\">{0}</span></td></tr>", model.InschrijfGeld.AsAmount());

                item1.Text += string.Format("<tr><td>Betaalwijze</td><td>{0}</span></td></tr>", model.Betaalwijze.Value.ToString());
                item1.Text += string.Format("<tr><td>Betaald?</td><td>{0}</span></td></tr>", model.DatumBetaald.HasValue ? model.DatumBetaald.Value.ToShortDateString() : "Nog niet");
                item1.Text += string.Format("<tr><td><b></b></td><td><span class=\"quotable\">------</span></td></tr>");
                item1.Text += string.Format("<tr><td><b>Totaal</b></td><td><span class=\"quotable\">{0}</span></td></tr>", model.InschrijfGeld.AsAmount());

                /*
                item1.Text += string.Format("<tr><td></td></tr>");
                item1.Text += string.Format("<tr><th colspan=\"2\"><b>Overmaken naar</b></th></tr>");

                item1.Text += string.Format("<tr><td>Bank rek nr</td><td><span class=\"quotable\">'1684.92.059'</span> (Rabobank)</td></tr>");
                item1.Text += string.Format("<tr><td>Ten name van </td><td><span class=\"quotable\">'Stichting Woelig Water'</span> (te Vinkeveen)</td></tr>");
                item1.Text += string.Format("<tr><td>Onder vermelding van</td><td><span class=\"quotable\">'H2RE {0}'</span></td></tr>", model.VolledigeNaam);
                */

                item1.Text += string.Format("</table></td></tr>");
                item1.Text += string.Format("</table>");

            newsletter.Items.Add(item1);

            SendPersonalNewsletterViewModel spnvm = new SendPersonalNewsletterViewModel();
            spnvm.IsEmail = true;
            spnvm.Newsletter = newsletter;

            MailMessage mm = new MailMessage();
            mm.From = new MailAddress(HreSettings.ReplyToAddress);
            mm.To.Add(new MailAddress(model.Email));

            // Send the confirmation mail to an appsetting defined admin email address for backup purposes.
            mm.Bcc.Add(new MailAddress(HreSettings.ConfirmationsCCAddress));

            if (!string.IsNullOrEmpty(model.OpmerkingenAanOrganisatie)) {
                mm.Bcc.Add(new MailAddress(HreSettings.MailAddressSecretary));
            }

            mm.Subject = model.DoForceSendConfirmationOfChange ?
                "Wijziging in inschrijfgegevens Hét Rondje Eilanden " + model.VolledigeNaam
                : "Aanmeldbevestiging deelname Hét Rondje Eilanden " + model.VolledigeNaam;

            mm.IsBodyHtml = true;
            spnvm.UserId = model.UserId;
            mm.Body = this.RenderNewsletterViewToString("../Newsletter/NewsletterTemplates/NewsletterTemplate", spnvm);
            EmailSender.SendEmail(mm, EmailCategory.SubscriptionConfirmation, model.ParticipationId, model.UserId);

            model.DateConfirmationSend = DateTime.Now;

            // Sla de entry nog een keer op, om ook de dateConfirmationSend op te slaan.
            // TODO BW 2013-03-01: Doe dit wat netter dan alles geheel twee keer opslaan.
            InschrijvingenRepository.SaveEntry(model, model.ExternalEventIdentifier, false, true);
        }
 public ActionResult UploadVolonteers()
 {
     InschrijvingModel model = new InschrijvingModel();
     return View(model);
 }
 public ActionResult UploadTest()
 {
     InschrijvingModel model = new InschrijvingModel();
     return View(model);
 }
        public ActionResult Index(InschrijvingenModel model)
        {
            if (model==null || model.SubmitAction!="Scrape") {
                if (model==null) {
                    model = new InschrijvingenModel();
                    return View(model);
                }

                if (model.SubmitAction=="Download") {
                    string filename = string.Format("HRE-{0}-{1}", DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString().Replace(":", ""));
                    MemoryStream ms = CreateExcelFile(filename, false);

                    // Return the memorystream.
                    if (ms != null) {
                        // Rewind the memory stream to the beginning.
                        ms.Seek(0, SeekOrigin.Begin);
                        return File(ms, @"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", filename + ".xlsx");
                    } else {
                        // No Excel file, show the main 'Inschrijvingen' page.
                        return RedirectToAction("Index");
                    }
                }
            }

            Initialise(AppConstants.MeedoenOverzicht);
            try {
                int maxNumberOfItemsToScrape = model.MaxNumberOfScrapedItems;
                if (maxNumberOfItemsToScrape==0) {
                    maxNumberOfItemsToScrape = int.MaxValue;
                }

                // 0. Inloggen (sessie ID krijgen).
                // Posten naar https://mijn.triathlonbond.nl/default.asp */
                string ntbInschrijvingenStartUrl = "https://mijn.triathlonbond.nl/default.asp";

                ConsoleWrite(string.Format("Logging in via post to: {0}", ntbInschrijvingenStartUrl));

                // In form InlogFormulier invullen input met Id 'Gebruikersnaam' = SWW en input met Id 'wachtwoord' '.
                string gebruikersnaam = HreSettings.NtbIUsername;
                string wachtwoord = HreSettings.NtbIPassword;
                // Creates the post data for the POST request (fiddler: gebruikersnaam=SWW&wachtwoord=18jan2012&Inloggen=True&tijdverschil=-60)
                string postData = ("gebruikersnaam=" + gebruikersnaam + "&wachtwoord="+ wachtwoord+"&Inloggen=True&tijdverschil=-60");

                // Create the POST request.
                HttpWebRequest loginRequest = (HttpWebRequest) WebRequest.Create(ntbInschrijvingenStartUrl);
                loginRequest.Method = "POST";

                loginRequest.KeepAlive = true;
                loginRequest.ContentType = "application/x-www-form-urlencoded";
                loginRequest.ContentLength = postData.Length;

                // POST the data.
                using (StreamWriter requestWriter = new StreamWriter(loginRequest.GetRequestStream())) {
                    requestWriter.Write(postData);
                }

                string framesetUrl;

                // Post the request and get the response back.
                using (HttpWebResponse response = (HttpWebResponse) loginRequest.GetResponse()) {

                    if (response.Cookies!=null && response.Cookies.Count>0) {
                        Cookies = response.Cookies;
                    }

                    // In het teruggegeven resultaat request heeft de URL dan een sessie code in de URL parameter 'SID'.
                    // https://mijn.triathlonbond.nl/_interface/frameset.asp?SID={20B12A29-FFA4-4606-B912-5928181C7D4D}
                    // Deze gebruik je in stap 2.

                    framesetUrl = HttpUtility.UrlDecode(response.ResponseUri.AbsoluteUri);
                    ConsoleWrite(string.Format("Frame set URL (to open for manual editing stuff): {0}", framesetUrl));
                    NtbISessionCode = HttpUtility.ParseQueryString(response.ResponseUri.Query, Encoding.UTF8).Get("SID");
                    ConsoleWrite(string.Format("Session ID: {0}", NtbISessionCode));
                    response.Close();
                }

                string currentEvenementNumber = model.EventNumber;

                string currentSerieNumber;
                switch (model.EventNumber) {
                    case SportsEventRepository.H2RE_EVENTNR:
                        currentSerieNumber = SportsEventRepository.H2RE_SERIENR;
                        break;
                    case SportsEventRepository.HRE_SERIENR:
                        currentSerieNumber = SportsEventRepository.HRE_SERIENR;
                        break;
                    case SportsEventRepository.H3RE_SERIENR:
                    default:
                        currentSerieNumber = SportsEventRepository.H3RE_SERIENR;
                        break;
                }
                // I. Overzichtscherm. Voorbeeld URL: https://mijn.triathlonbond.nl/evenementbeheer/inschrijvingen/inschrijvingen_serie_individueel.asp?SID={20B12A29-FFA4-4606-B912-5928181C7D4D}&Serie=4549
                // Create the GET request.
                string overviewUrl = "https://mijn.triathlonbond.nl/evenementbeheer/inschrijvingen/inschrijvingen_serie_individueel.asp?SID="
                    + NtbISessionCode + "&Serie=" + currentSerieNumber; // CurrentSerieNr;

                // Make a GET request and get the response back.
                // HtmlDocument overviewDoc = GetHtmlDocumentFromUrl(overviewUrl);
                HtmlDocument overviewDoc = new HtmlDocument();
                ConsoleWrite(string.Format("Getting Html document from: {0}", overviewUrl));

                HttpWebRequest overviewReq = (HttpWebRequest) WebRequest.Create(overviewUrl);
                if (Cookies!=null && Cookies.Count>0) {
                    overviewReq.CookieContainer.Add(Cookies);
                }
                overviewReq.KeepAlive = true;
                overviewReq.Method = "GET";
                overviewReq.Headers.Add("Authorization: Basic ZGNpOkFpR2g3YWVj");

                using (HttpWebResponse response = overviewReq.GetResponse() as HttpWebResponse) {
                    if (response.Cookies!=null && response.Cookies.Count>0) {
                        Cookies = response.Cookies;
                    }
                    NtbISessionCode = HttpUtility.ParseQueryString(response.ResponseUri.Query, Encoding.UTF8).Get("SID");

                    // Get the response stream
                    StreamReader reader = new StreamReader(response.GetResponseStream());
                    overviewDoc.Load(reader);
                    reader.Close();
                }

                ////////////////////////////// START Evenement screen.
                // Open the evenement once to do some stuff that's apparantly necesary before you can access the entry detail page (setting cookies or something?).
                string evenementUrl = string.Format("https://mijn.triathlonbond.nl/evenementbeheer/evenement.asp?SID={0}&Evenement={1}", NtbISessionCode, currentEvenementNumber);

                // Make a GET request and get the response back.
                // HtmlDocument overviewDoc = GetHtmlDocumentFromUrl(overviewUrl);
                HtmlDocument evenementDoc = new HtmlDocument();
                ConsoleWrite(string.Format("Getting Html document from: {0}", evenementUrl));

                HttpWebRequest evenementReq = (HttpWebRequest) WebRequest.Create(evenementUrl);
                if (Cookies!=null && Cookies.Count>0) {
                    evenementReq.CookieContainer.Add(Cookies);
                }
                evenementReq.KeepAlive = true;
                evenementReq.Method = "GET";

                using (HttpWebResponse response = evenementReq.GetResponse() as HttpWebResponse) {
                    if (response.Cookies!=null && response.Cookies.Count>0) {
                        Cookies = response.Cookies;
                    }

                    // Get the response stream
                    StreamReader reader = new StreamReader(response.GetResponseStream());
                    evenementDoc.Load(reader);
                    reader.Close();
                }

                ////////////////////////////// END evenement.

                // Filter op de 2e geneste <table> in de 2e <table> in de 2e <div> in de <body> van de <html>.
                // HtmlNodeCollection raceEntryRows = doc.DocumentNode.SelectSingleNode("//body").SelectNodes("div")[1].SelectNodes("table")[1].SelectNodes("table")[1].SelectNodes("tr");
                HtmlNodeCollection raceEntryRows = overviewDoc.DocumentNode.SelectNodes("/html/body/div[2]/table/tr[2]/td/table/tr");

                raceEntryRows.Remove(raceEntryRows.ElementAt(0));
                List<InschrijvingModel> raceEntries = new List<InschrijvingModel>(raceEntryRows.Count);

                int counter = 1;

                foreach (HtmlNode raceEntryRow in raceEntryRows) {
                    InschrijvingModel raceEntry = new InschrijvingModel();

                    raceEntry.DateFirstSynchronized = DateTime.Now;

                    // Pak binnen elke TR even van de 7e td de innerHtml. Dit is de inschrijfdatum; en wel in het volgende format: 3-7-2012 23:03:15.
                    string registrationsDateAsString = raceEntryRow.SelectSingleNode("./td[7]").InnerHtml;
                    raceEntry.RegistrationDate = DateTime.Parse(registrationsDateAsString, CultureInfo.CreateSpecificCulture("nl-NL")); // "dd-MM-yyyy hh:mm:ss"

                    // Daarin neem je de 2e tot en met laatste <tr> (1e is header) en daarin telkens de waarde van het 'onclick' attribuut en wel de waarde tussen de aanhalingstekens (') binnen de Open functie.
                    // bijvoorbeeld: Open('inschrijvingen_serie_detail_individueel.asp?SID={7D72F8DA-7E50-46AC-B22E-81A638FB3171}&Inschrijving=81836');
                    // Regex re = new Regex(@"\'(.*?)\'");
                    string onClickValue = raceEntryRow.Attributes["onclick"].Value;
                    string entryUrlPostfix = Regex.Match(onClickValue, @"\'(.*?)\'").ToString();
                    entryUrlPostfix = entryUrlPostfix.Substring(1, entryUrlPostfix.Length-2);

                    string externalInschrijvingsId = HttpUtility.ParseQueryString(entryUrlPostfix, Encoding.UTF8).Get("Inschrijving");
                    raceEntry.ExternalIdentifier = externalInschrijvingsId;

                    raceEntry.ExternalEventIdentifier = currentEvenementNumber;
                    raceEntry.ExternalEventSerieIdentifier = currentSerieNumber;

                    // Deze pagina open je voor alle rijen (GET request) door het achter de URL te plakken.
                    // Voorbeeld URL: https://mijn.triathlonbond.nl/evenementbeheer/inschrijvingen/inschrijvingen_serie_detail_individueel.asp?SID={7D72F8DA-7E50-46AC-B22E-81A638FB3171}&Inschrijving=94938
                    string entryUrl = "https://mijn.triathlonbond.nl/evenementbeheer/inschrijvingen/" + entryUrlPostfix;

                    ConsoleWrite(string.Format("Getting Html document for entry {0} of {1} from: {2}", counter, raceEntryRows.Count, entryUrl));

                    HtmlDocument entryDoc = new HtmlDocument();
                    HttpWebRequest entryReq = (HttpWebRequest) WebRequest.Create(entryUrl);
                    if (Cookies!=null && Cookies.Count>0) {
                        entryReq.CookieContainer.Add(Cookies);
                    }

                    entryReq.KeepAlive = true;
                    entryReq.Method = "GET";
                    // entryReq.Headers.Add("Authorization: Basic ZGNpOkFpR2g3YWVj");
                    loginRequest.Referer=overviewUrl;
                    // entryReq.Credentials = myCache;

                    using (HttpWebResponse response = entryReq.GetResponse() as HttpWebResponse) {
                        // Get the response stream
                        StreamReader reader = new StreamReader(response.GetResponseStream());
                        if (response.Cookies!=null && response.Cookies.Count>0) {
                            Cookies = response.Cookies;
                        }

                        entryDoc.Load(reader);
                        reader.Close();
                    }

                    // II. Skrape van elke pagina dan de gegevens zoals hieronder gegeven.
                    // Hieruit pak je de <table> uit de tweede <div> in de <body> van de <html>.
                    // Hieruit pak je de 3e tot en met de laatste <tr>.
                    HtmlNodeCollection raceEntryDetails = entryDoc.DocumentNode.SelectNodes("/html/body/div[2]/table/tr");

                    // A. Uit de 3e en 4e <tr>'s pak je telkens de content die staat tussen de tweede <td> en </td> en de vierde <td> en </td>. Dan krijg je achtereenvolgens:
                    // 1. Voornaam, Geboortedatum.
                    raceEntry.Voornaam = raceEntryDetails[2].SelectNodes("./td[2]").First().InnerText.TrimThisShit();
                    string geboorteDatum = raceEntryDetails[2].SelectNodes("./td[4]").First().InnerText.TrimThisShit();
                    raceEntry.GeboorteDatum = DateTime.Parse(geboorteDatum); // CultureInfo.CreateSpecificCulture("nl-NL")

                    // 2. Tussenvoegsel, Licentienummer.
                    raceEntry.Tussenvoegsel = raceEntryDetails[3].SelectNodes("./td[2]").First().InnerText.TrimThisShit();
                    raceEntry.LicentieNummer = raceEntryDetails[3].SelectNodes("./td[4]").First().InnerText.TrimThisShit();

                    // B. In de 5e <tr> pak je uit de tweede <td>
                    // 3. Achternaam.
                    raceEntry.Achternaam = raceEntryDetails[4].SelectSingleNode("./td[2]").InnerText.TrimThisShit();

                    // In de 3e <td> van deze zelfde 5e <tr> zit daarna een geneste <table> met optionele gegevens (id=optioneel) in de 2e tot en met 5e <tr>.
                    // Uit de <tr> pak je telkens de 2e <td> voor achtereenvolgens:
                    // 4. ChampionChip nummer.
                    raceEntry.MyLapsChipNummer = raceEntryDetails[4].SelectSingleNode("./td[3]/table/tr[2]/td[2]").InnerText.TrimThisShit();

                    // 5. Maat T-shirt
                    raceEntry.MaatTshirt = raceEntryDetails[4].SelectSingleNode("./td[3]/table/tr[3]/td[2]").InnerText.TrimThisShit();

                    // 6. Aanmelden Nieuwsbrief
                    raceEntry.Newsletter = raceEntryDetails[4].SelectSingleNode("./td[3]/table/tr[4]/td[2]").InnerText.TrimThisShit()=="Ja";

                    // 7. Interesse in overnachten na de wedstrijd
                    raceEntry.Camp = raceEntryDetails[4].SelectSingleNode("./td[3]/table/tr[5]/td[2]").InnerText.TrimThisShit()=="Ja";

                    // C. In de 10 <tr>'s van de zesde en tot en met de laatste - 16e - <tr> pak je telkens de content die staat tussen de 2e <td> en </td>. Dan krijg je achtereenvolgens:
                    // 8. Geslacht.
                    raceEntry.Geslacht = raceEntryDetails[5].SelectSingleNode("./td[2]").InnerText.TrimThisShit();

                    // 9. Straat en huisnummer (huisnummer gescheiden door &nbsp, spaties in straat zijn gewoon spaties).
                    string straatEnHuisnummer = raceEntryDetails[6].SelectSingleNode("./td[2]").InnerText.Trim();
                    const string straatEnHuisnummerSeperator = "&nbsp;";
                    int straatEnHuisnummerSeperatorIndex = straatEnHuisnummer.IndexOf(straatEnHuisnummerSeperator);
                    raceEntry.Straat = straatEnHuisnummer.Substring(0, straatEnHuisnummerSeperatorIndex);
                    string huisnummerEnToevoeging = straatEnHuisnummer.Substring(straatEnHuisnummerSeperatorIndex+straatEnHuisnummerSeperator.Length, straatEnHuisnummer.Length-(raceEntry.Straat.Length+straatEnHuisnummerSeperator.Length));
                    const string huisnummerEnToevoegingSeperator = "-";
                    int huisnummerEnToevoegingSeperatorIndex = huisnummerEnToevoeging.IndexOf(huisnummerEnToevoegingSeperator);
                    if (huisnummerEnToevoegingSeperatorIndex>0) {
                        raceEntry.Huisnummer = huisnummerEnToevoeging.Substring(0, huisnummerEnToevoegingSeperatorIndex);
                        raceEntry.HuisnummerToevoeging = huisnummerEnToevoeging.Substring(huisnummerEnToevoegingSeperatorIndex+huisnummerEnToevoegingSeperator.Length, huisnummerEnToevoeging.Length-(raceEntry.Huisnummer.Length+huisnummerEnToevoegingSeperator.Length));
                    } else {
                        raceEntry.Huisnummer = huisnummerEnToevoeging;
                        raceEntry.HuisnummerToevoeging = string.Empty;
                    }
                    // 10. Postcode.
                    raceEntry.Postcode = raceEntryDetails[7].SelectSingleNode("./td[2]").InnerText.TrimThisShit();

                    // 11. Woonplaats+.
                    raceEntry.Woonplaats = raceEntryDetails[8].SelectSingleNode("./td[2]").InnerText.TrimThisShit();

                    // 12. Land.
                    raceEntry.Land = raceEntryDetails[9].SelectSingleNode("./td[2]").InnerText.TrimThisShit();

                    // 13. Telefoon.
                    raceEntry.Telefoon = raceEntryDetails[10].SelectSingleNode("./td[2]").InnerText.TrimThisShit();

                    // 14. E-mail.
                    raceEntry.Email = raceEntryDetails[11].SelectSingleNode("./td[2]").InnerText.TrimThisShit();
                    raceEntry.UserName = raceEntry.Email;

                    // 15. Opmerkingen tbv speaker.
                    raceEntry.OpmerkingenTbvSpeaker = raceEntryDetails[12].SelectSingleNode("./td[2]").InnerText.TrimThisShit();

                    // 16. Opmerkingen aan organisatie.
                    raceEntry.OpmerkingenAanOrganisatie = raceEntryDetails[13].SelectSingleNode("./td[2]").InnerText.TrimThisShit();

                    // 17. Deelnamebedrag.
                    string deelnamebedragAsString = raceEntryDetails[14].SelectSingleNode("./td[2]").InnerText;
                    string deelnamebedragKaleString = deelnamebedragAsString.Replace("&euro;", "").Replace(",", "").TrimThisShit();
                    int deelnamebedragAsInt;
                    bool result = int.TryParse(deelnamebedragKaleString, out deelnamebedragAsInt);
                    if (result) {
                        raceEntry.InschrijfGeld = deelnamebedragAsInt;
                    }

                    // Save the entry (Determine if the entry aready exists using externalIdentifier and then update, otherwise insert).
                    InschrijvingenRepository.SaveEntry(raceEntry, currentEvenementNumber, true, model.OverrideLocallyUpdated);
                    raceEntries.Add(raceEntry);

                    if (counter>=maxNumberOfItemsToScrape) {
                        ConsoleWrite(string.Format("Stopping scraping after {0} entries.", counter));
                        break;
                    }
                    counter++;

                }

            } catch (WebException ex) {
                using (StreamReader reader = new StreamReader(ex.Response.GetResponseStream())) {
                    string str = reader.ReadToEnd();
                    ConsoleWrite(string.Format("Error! Response: {0}", str));
                }
            }

            return View("Index", model);
        }
        /// <summary>
        /// Load the screen with a model filled with the given external ID and the data from HRE 2012.
        /// </summary>
        /// <param name="externalId"></param>
        /// <returns></returns>
        // [RequiresSsl]
        public ActionResult IkDoeMee()
        {
            InschrijvingModel model = new InschrijvingModel();
            sportsevent currentEvent = SportsEventRepository.GetCurrentEvent();
            model.ExternalEventIdentifier = currentEvent.ExternalEventIdentifier;
            model.ExternalEventSerieIdentifier = currentEvent.ExternalEventSerieIdentifier;
            model.ExternalIdentifier = string.Empty;
            model.RegistrationDate = DateTime.MinValue;

            model.IsInschrijvingNieuweGebruiker = true;

            return View("Edit", model);
        }
        public ActionResult Edit(InschrijvingModel model)
        {
            Initialise(AppConstants.MeedoenOverzicht);

            // Run server side validations.
            if (model.HasLicentieNummer && (string.IsNullOrEmpty(model.LicentieNummer) || !Regex.IsMatch(model.LicentieNummer, @"^\d\d[LA]\d\d\d\d\d[MV]\d\d\d$"))) {
                ModelState.AddModelError("LicentieNummer", "Geef correct licentienummer (of zet licentie-icoon uit)");
            }

            // Check champion/mylaps chip nr, for instance 4R-YGF8T (green chip).
            if (model.HasMyLapsChipNummer) {
                if (string.IsNullOrEmpty(model.MyLapsChipNummer)) {
                    ModelState.AddModelError("MyLapsChipNummer", "Vul een correct chip nummer in (of zet dit icoon uit)");
                } else if (!CheckMyLapsChipNumber(model.MyLapsChipNummer)) {
                    ModelState.AddModelError("MyLapsChipNummer", "Geen geldig MyLaps chip nummer. Graag controleren!");
                }
            }

            if (model.Land=="NL" && !string.IsNullOrEmpty(model.Postcode) && !Regex.IsMatch(model.Postcode, @"^\d{4}\s*\w{2}$")) {
                ModelState.AddModelError("Postcode", "Geen geldige Nederlandse postcode!");
            }

            if (!string.IsNullOrEmpty(model.Email) && !Regex.IsMatch(model.Email, @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*")) {
                ModelState.AddModelError("Email", "Geen geldig e-mail adres!");
            }

            // Only check the payment if the subscription is new.
            if ((!model.IsBetaald.HasValue || !model.IsBetaald.Value)  && model.Betaalwijze != PaymentType.iDeal) {
                ModelState.AddModelError("PaymentType", "Alleen iDeal betaling mogelijk");
            }

            // Check final yes/no if the subsription is new.
            if (model.IsNewUser && string.IsNullOrEmpty(model.Finale)) {
                ModelState.AddModelError("PaymentType", "Geef aan of je de finale denkt mee te kunnen en willen doen.");
            }

            // Only check the payment if the subsription is new.
            if ((!model.IsBetaald.HasValue || !model.IsBetaald.Value) && string.IsNullOrEmpty(model.BankCode)) {
                ModelState.AddModelError("BankCode", "Selecteer bank voor iDeal betaling");
            }

            // Check birthday.
            if (!model.GeboorteDatum.HasValue) {
                ModelState.AddModelError("GeboorteDatum", "Geef je geboortedatum");
            } else {
                int currentYear = DateTime.Now.Year;
                int birthYear = model.GeboorteDatum.Value.Year;
                int minimumAge = HreSettings.MinimumLeeftijd;
                if (currentYear-birthYear<minimumAge) {
                    ModelState.AddModelError("GeboorteDatum", string.Format("Minimumleeftijd! Je moet 31 dec {0} minstens {1} zijn.", currentYear, minimumAge));
                }
            }

            // Subscrbe for the current event.
            string currentEventNr = SportsEventRepository.CurrentExternalEventIdentifier;

            // Controleer als het een nieuwe inschrijving betreft dat er nog geen deelnemer is met hetzelfde e-mail adres.
            LogonUserDal user = LogonUserDal.GetUserByUsername(model.Email);
            if ((model.IsInschrijvingNieuweGebruiker || (!model.IsInschrijvingNieuweGebruiker && model.Email!=model.EmailBeforeUpdateIfAny))
                    && user!=null && InschrijvingenRepository.GetInschrijving(user, currentEventNr)!=null) {
                ModelState.AddModelError("Email", "Er is al een deelnemer met dit e-mail adres ingeschreven. Elke deelnemer moet een eigen e-mail adres opgeven!");
            }

            // Store the race entry in the local database.
            if (ModelState.IsValid) {
                // Set the eventIdentifier to the event of 2014.
                // TODO BW 2013-02-10: Refactor "HRE" to prefix constant.
                model.ExternalIdentifier = "HRE" + model.ParticipationId;

                // Sla op!
                InschrijvingenRepository.SaveEntry(model, currentEventNr, false, true);

                // Stuur een bevestigingsmail bij wijziging indien gewenst
                // NB Het sturen van bevestigingsmail bij initiele aanmelding gebeurd pas na terugkomst uit Sisow dialoog.
                if (model.DoForceSendConfirmationOfChange) {
                    SendSubscriptionConfirmationMail(model);
                }

                // TODO BW 2013-02-04: Synchronize the data to NTB inschrijvingen.
                if (string.IsNullOrEmpty(model.ExternalIdentifier) || model.ExternalIdentifier.StartsWith("HRE")) {
                    // The data is not yet in NTB inschrijvingen, write it to a new form.
                } else {
                    // The entry is already in NTB inschr, load the edit page of it, edit the existing entry and save.
                }

                // TODO BW 2013-02-10: Set the model as updated and synchronized/scraped if it was written to NTB inschrijvingen.
                // model.DateUpdated=DateTime.Now;
                // model.DateLastScraped=model.DateUpdated;
                // if (!model.DateFirstSynchronized.HasValue) {
                //    model.DateFirstSynchronized=model.DateUpdated;
                // }

                if (model.IsInschrijvingNieuweGebruiker) {
                    string sisowUrl = model.SisowUrl;
                    // return RedirectToAction("Aangemeld", model);
                    return Redirect(sisowUrl);
                } else {
                    if (!model.IsBetaald.HasValue || !model.IsBetaald.Value) {
                        model.SisowReturnUrl = Url.Action("MijnRondjeEilanden", new { externalId=model.ExternalIdentifier, eventNr=model.ExternalEventIdentifier });
                        string sisowUrl = model.SisowUrl;
                        return Redirect(sisowUrl);
                    } else {
                        return RedirectToAction("MijnRondjeEilanden", new { externalId=model.ExternalIdentifier, eventNr=model.ExternalEventIdentifier });
                    }
                }
            }

            return View(model);
        }
        /// <summary>
        /// Save an entry.
        /// </summary>
        /// <param name="inschrijving"></param>
        /// <param name="eventNumber"></param>
        public static void SaveEntry(InschrijvingModel inschrijving, string eventNumber, bool isScrape, bool overrideLocallyUpdated = false)
        {
            // TODO BW 2013-02-6 Als een inschrijving wordt gesaved die is gescraped van NTB inschrijvingen, maar het e-mail adres is
            // inmiddels aangepast dan werkt onderstaande niet. De persoon wordt dan onder een nieuwe inschrijving gesaved en klapt er mogelijk uit op duplicate NTB licentie nummer..
            inschrijving.Email = inschrijving.Email.ToLower();

            bool isEmailGewijzigd = (!string.IsNullOrEmpty(inschrijving.EmailBeforeUpdateIfAny) && inschrijving.EmailBeforeUpdateIfAny!=inschrijving.Email);

            string gebruikersnaam = isEmailGewijzigd ? inschrijving.EmailBeforeUpdateIfAny : inschrijving.Email;

            // Create and/or retrieve the user (and the underlying ASP.NET membership user).
            LogonUserDal user = LogonUserDal.CreateOrRetrieveUser(gebruikersnaam, "", inschrijving.ExternalIdentifier);

            // Update the rest of the user data ONLY if:
            // - It is NOT being scraped for this save
            // - Or the raceEntry is first created
            // - OR it IS being scraped but was scraped before and was NOT updated after it was last scraped (e.g. DateUpdated<=DateLastScraped)
            // TODO: Update (and save) only if the information is newer; somehow...
            if (overrideLocallyUpdated || !isScrape || !user.DateOfBirth.HasValue ||
                    (!inschrijving.DateLastSynchronized.HasValue || (inschrijving.DateLastSynchronized.HasValue
                        && DateTime.Compare(inschrijving.DateUpdated, inschrijving.DateLastSynchronized.Value)<=0))) {
                user.DateOfBirth = inschrijving.GeboorteDatum;
                user.IsMailingListMember = inschrijving.Newsletter;

                if (user.EmailAddress != inschrijving.Email) {
                    // TODO BW 2013-07-28: A check has to be added that the new e-mail address does not exist yet (or is it already present?).
                    if (Membership.GetUser(inschrijving.Email)!=null) {
                        throw new ArgumentException(string.Format("Het e-mail adres is gewijzigd van {0} naar {1}, maar dit laatste e-mail adres is al gebruikt door een andere gebruiker.", user.EmailAddress, inschrijving.Email));
                    }

                    user.EmailAddress = inschrijving.Email;
                    // Set user status as unconfirmed, since the e-mail address is changed, and the new address is not confirmed yet.
                    user.Status = Business.LogonUserStatus.Undetermined;
                }
                user.UserName = inschrijving.Email;
                user.TelephoneNumber = inschrijving.Telefoon;

                user.NtbLicenseNumber = inschrijving.HasLicentieNummer ? inschrijving.LicentieNummer : null;

                user.IsActive = false;
                if (!string.IsNullOrEmpty(inschrijving.Geslacht)) {
                    user.Gender = inschrijving.Geslacht=="M";
                }

                // If the user has no address or the addres was updated later then the user then add an address.
                address address = user.PrimaryAddress;
                if (address==null) {
                    throw new ArgumentException("address is null. This should not occur. This code should be able to be deleted :P.");
                    // Create an address.
                    // address = new address();
                    // address.DateCreated = DateTime.Now;
                }
                address.DateUpdated = DateTime.Now;
                if (address.DateCreated==null || address.DateCreated==DateTime.MinValue) {
                    address.DateCreated = DateTime.Now;
                }
                address.City = inschrijving.Woonplaats;
                address.Street = inschrijving.Straat;
                address.Housenumber = inschrijving.Huisnummer;
                address.HouseNumberAddition = inschrijving.HuisnummerToevoeging;
                address.Country = inschrijving.Land;
                address.Firstname = inschrijving.Voornaam;
                address.Insertion = inschrijving.Tussenvoegsel;
                address.Lastname = inschrijving.Achternaam;
                address.PostalCode = inschrijving.Postcode;
                user.PrimaryAddress = address;
                user.Save();

                // Set the userId of the inschrijvingmodel, if not set before (for registration of completely new users).
                if (inschrijving.UserId==0) {
                    inschrijving.UserId=user.Id;
                }
                int eventId = SportsEventRepository.GetEvent(eventNumber).Id;

                // Create the sportsparticipation.
                sportseventparticipation participation = (from p in DB.sportseventparticipation where p.UserId==user.Id && p.SportsEventId ==  eventId select p).FirstOrDefault();

                if (participation==null) {
                    participation = new sportseventparticipation();
                    SportsEventDal sportsevent = SportsEventDal.GetByExternalId(eventNumber);
                    participation.SportsEventId = sportsevent.ID;
                    participation.EarlyBird = inschrijving.IsEarlyBird;
                }

                participation.DateUpdated = DateTime.Now;
                // If datecreated wasn't set (e.g. it is new) then set it identical to dateCreated.
                if (participation.DateCreated==DateTime.MinValue) {
                    participation.DateCreated=participation.DateUpdated;
                }

                participation.MyLapsChipIdentifier = inschrijving.HasMyLapsChipNummer ? inschrijving.MyLapsChipNummer : string.Empty;

                if (isScrape) {
                    participation.ExternalIdentifier=inschrijving.ExternalIdentifier;
                    if (!participation.DateFirstScraped.HasValue) {
                        participation.DateFirstScraped = participation.DateUpdated;
                    }
                    participation.DateLastScraped = participation.DateUpdated;
                    participation.DateRegistered=inschrijving.RegistrationDate;
                } else {
                    participation.ExternalIdentifier = inschrijving.ExternalIdentifier;
                    participation.DateRegistered = participation.DateUpdated;
                    participation.ParticipationAmountInEuroCents = inschrijving.InschrijfGeld;
                }

                // Initialiseer de virtuele datum voor orderen op de inschrijfdatum (door wijzigen kun je later de volgorde 'kunstmatig' wijzigen, maar dit is wel iets minder kunstmatig dan met de inschrijfdatum zelf :P).
                if (!participation.VirtualRegistrationDateForOrdering.HasValue) {
                    participation.VirtualRegistrationDateForOrdering = participation.DateRegistered;
                }

                participation.SportsEventId = (from sportsevent se in DB.sportsevent
                                                where se.ExternalEventIdentifier==eventNumber
                                                select se.Id).First();
                participation.UserId = user.Id;

                participation.SpeakerRemarks = inschrijving.OpmerkingenTbvSpeaker;
                participation.Camp = inschrijving.Camp;
                participation.Food = inschrijving.Food;
                participation.Bike = inschrijving.Bike;
                participation.WantsToDoFinal = inschrijving.Finale=="W";
                participation.TShirtSize = inschrijving.MaatTshirt;

                participation.ParticipationStatus = 1;
                participation.Notes = inschrijving.OpmerkingenAanOrganisatie;
                participation.NotesToAll = inschrijving.HebJeErZinIn;
                participation.DateConfirmationSend = inschrijving.DateConfirmationSend;

                participation.BankCode = inschrijving.BankCode;
                participation.PaymentType = (int?) inschrijving.Betaalwijze;

                if (participation.Id==0) {
                    DB.AddTosportseventparticipation(participation);
                }
                DB.SaveChanges();
                inschrijving.ParticipationId = participation.Id;
                inschrijving.RegistrationDate = participation.DateRegistered;
            }
        }
 public ActionResult Inschrijven(InschrijvingModel entryModel)
 {
     return View(entryModel);
 }