public void ValidatieLidVoorstelZonderTelefoonNummer() { // Arrange // Ik maak een persoon, en een werkjaar met 2 afdelingen. Maar dat is hier // niet relevant. Wat wel van belang is, is dat de persoon te jong is om // lid te worden. We verwachten dat het maken van een lidvoorstel crasht. var gwj = new GroepsWerkJaar { WerkJaar = 2014, Groep = new ChiroGroep() }; // Werkjaar 2012-2013 var gp = new GelieerdePersoon { Persoon = new Persoon { GeboorteDatum = new DateTime(2000, 06, 21), Geslacht = GeslachtsType.Vrouw, }, Groep = gwj.Groep, PersoonsAdres = new PersoonsAdres(), Communicatie = new List <CommunicatieVorm>() // geen telefoonnummer }; gwj.AfdelingsJaar.Add(new AfdelingsJaar { ID = 1, GeboorteJaarVan = 1999, GeboorteJaarTot = 2000, Geslacht = GeslachtsType.Gemengd, OfficieleAfdeling = new OfficieleAfdeling() }); gwj.AfdelingsJaar.Add(new AfdelingsJaar { ID = 2, GeboorteJaarVan = 1997, GeboorteJaarTot = 1998, Geslacht = GeslachtsType.Gemengd, OfficieleAfdeling = new OfficieleAfdeling() }); var lidVoorstel = new LidVoorstel { GelieerdePersoon = gp, GroepsWerkJaar = gwj, AfdelingsJarenIrrelevant = true, LeidingMaken = false }; var target = new LidVoorstelValidator(); // Act var foutNummer = target.FoutNummer(lidVoorstel); // Assert Assert.AreEqual(FoutNummer.TelefoonNummerOntbreekt, foutNummer); }
public void ValidatieLidVoorstelKleutersTest() { // Arrange // Ik maak een persoon, en een werkjaar met 2 afdelingen. Maar dat is hier // niet relevant. Wat wel van belang is, is dat de persoon te jong is om // lid te worden. var gwj = new GroepsWerkJaar { WerkJaar = 2012, Groep = new ChiroGroep() }; // Werkjaar 2012-2013 var gp = new GelieerdePersoon { Persoon = new Persoon { GeboorteDatum = new DateTime(2010, 06, 21), // Geboren in 2010 Geslacht = GeslachtsType.Vrouw, }, Groep = gwj.Groep }; gwj.AfdelingsJaar.Add(new AfdelingsJaar { ID = 1, GeboorteJaarVan = 1999, GeboorteJaarTot = 2000, Geslacht = GeslachtsType.Gemengd, OfficieleAfdeling = new OfficieleAfdeling() }); gwj.AfdelingsJaar.Add(new AfdelingsJaar { ID = 2, GeboorteJaarVan = 1997, GeboorteJaarTot = 1998, Geslacht = GeslachtsType.Gemengd, OfficieleAfdeling = new OfficieleAfdeling() }); var lidVoorstel = new LidVoorstel { GelieerdePersoon = gp, GroepsWerkJaar = gwj, AfdelingsJarenIrrelevant = true, LeidingMaken = false }; var target = new LidVoorstelValidator(); // Act var foutNummer = target.FoutNummer(lidVoorstel); // Assert Assert.AreEqual(FoutNummer.LidTeJong, foutNummer); }
public void ValidatieLidVoorstelLeidingZonderEmail() { // Arrange // Ik maak een persoon, en een werkjaar met 2 afdelingen. Maar dat is hier // niet relevant. Wat wel van belang is, is dat de persoon te jong is om // lid te worden. We verwachten dat het maken van een lidvoorstel crasht. var gwj = new GroepsWerkJaar { WerkJaar = 2014, Groep = new ChiroGroep() }; // Werkjaar 2012-2013 var gp = new GelieerdePersoon { Persoon = new Persoon { GeboorteDatum = new DateTime(1995, 06, 21), Geslacht = GeslachtsType.Vrouw, }, Groep = gwj.Groep, PersoonsAdres = new PersoonsAdres(), Communicatie = new List <CommunicatieVorm> { // Enkel telefoonnummer; e-mailadres ontbreekt. new CommunicatieVorm { CommunicatieType = new CommunicatieType { ID = (int)CommunicatieTypeEnum.TelefoonNummer } } } }; var lidVoorstel = new LidVoorstel { GelieerdePersoon = gp, GroepsWerkJaar = gwj, AfdelingsJaren = new List <AfdelingsJaar>(), AfdelingsJarenIrrelevant = false, LeidingMaken = true }; var target = new LidVoorstelValidator(); // Act var foutNummer = target.FoutNummer(lidVoorstel); // Assert Assert.AreEqual(FoutNummer.EMailVerplicht, foutNummer); }
/// <summary> /// Schrijft een gelieerde persoon in, persisteert niet. Er mag nog geen lidobject (ook geen inactief) voor de /// gelieerde persoon bestaan. /// </summary> /// <param name="voorstelLid"> /// Voorstel voor de eigenschappen van het in te schrijven lid. /// </param> /// <param name="isJaarOvergang"> /// Geeft aan of het over de automatische jaarovergang gaat; relevant voor de /// probeerperiode /// </param> /// <returns> /// Het aangemaakte lid object /// </returns> public Lid NieuwInschrijven(LidVoorstel voorstelLid, bool isJaarOvergang) { var validator = new LidVoorstelValidator(); var gp = voorstelLid.GelieerdePersoon; var gwj = voorstelLid.GroepsWerkJaar; // We gaan ervan uit dat er een voorstel is. Je kunt het voorstel automatisch laten // genereren via InschrijvingVoorstellen. Debug.Assert(voorstelLid != null); var foutNummer = validator.FoutNummer(voorstelLid); if (foutNummer != null) { if (foutNummer.Value == FoutNummer.OnbekendGeslacht) { // Al de rest zit in client side validation, maar dit is een complex geval. Geslacht is verplicht, // maar als het niet ingevuld wordt, krijg je standaard 'Onbekend', waardoor het toch ingevuld is. throw new FoutNummerException(foutNummer.Value, Resources.GeslachtVerplicht); } else { throw new FoutNummerException(foutNummer.Value, Resources.LidProbleem); } } if (voorstelLid.AfdelingsJarenIrrelevant && !voorstelLid.LeidingMaken) { // Lid maken en zelf afdeling bepalen voorstelLid.AfdelingsJaren = InschrijvingVoorstellen(gp, gwj, false).AfdelingsJaren; if (!voorstelLid.AfdelingsJaren.Any()) { throw new FoutNummerException(FoutNummer.AfdelingNietBeschikbaar, Resources.GeenAfdelingVoorLeeftijd); } } Lid nieuwlid; if (voorstelLid.LeidingMaken) { nieuwlid = LeidingMaken(gp, gwj, isJaarOvergang, voorstelLid.AfdelingsJaren); } else { nieuwlid = KindMaken(gp, gwj, isJaarOvergang, voorstelLid.AfdelingsJaren.First()); } return(nieuwlid); }
public List <InschrijvingsVoorstel> Inschrijven(IList <InschrijvingsVerzoek> inschrijfInfo) { // TODO: Te veel nesting. Opkuis nodig. var probleemGevallen = new List <InschrijvingsVoorstel>(); var teSyncen = new List <Lid>(); var gelieerdePersonen = _gelieerdePersonenRepo.ByIDs(inschrijfInfo.Select(e => e.GelieerdePersoonID)); if (!_autorisatieMgr.IsGav(gelieerdePersonen) || inschrijfInfo.Count() != gelieerdePersonen.Count) { throw FaultExceptionHelper.GeenGav(); } // Mogelijk horen de gelieerde personen tot verschillende groepen. Dat kan, als de GAV GAV is van // al die groepen. Als hij geen GAV is van de IDs, dan werd er al een exception gethrowd natuurlijk. var groepen = (from gp in gelieerdePersonen select gp.Groep).Distinct(); foreach (var g in groepen) { bool groepInactief = g.StopDatum != null && g.StopDatum < DateTime.Now; // Per groep lid maken. // Zoek eerst recentste groepswerkjaar. var gwj = _groepenMgr.HuidigWerkJaar(g); foreach (var gp in gelieerdePersonen.Where(gelp => gelp.Groep.ID == g.ID).ToList()) { FoutNummer?foutNummer = groepInactief ? (FoutNummer?)FoutNummer.GroepInactief : null; var info = (from i in inschrijfInfo where i.GelieerdePersoonID == gp.ID select i).First(); if (foutNummer == null) { var lidVoorstel = new LidVoorstel { AfdelingsJaren = _afdelingsJaarRepo.ByIDs(info.AfdelingsJaarIDs), LeidingMaken = info.LeidingMaken, GelieerdePersoon = gp, GroepsWerkJaar = gwj }; // TODO: Dit is te veel business. Bekijken of een lid al ingeschreven is, moet in de workers gebeuren. // Behandel leden 1 voor 1 zodat een probleem met 1 lid niet verhindert dat de rest bewaard wordt. // Kijk of het lid al bestaat (eventueel niet-actief). In de meeste gevallen zal dit geen // resultaat opleveren. Als er toch al een lid is, worden persoon, voorkeursadres, officiele afdeling, // functies ook opgehaald, omdat een eventueel geheractiveerd lid opnieuw naar Kipadmin zal moeten. var l = gp.Lid.FirstOrDefault(ld => ld.GroepsWerkJaar.ID == gwj.ID); if (l != null) // al ingeschreven { if (l.UitschrijfDatum == null) { // Al ingeschreven als actief lid; we doen er verder niets mee. // (Behalve een foutcode meegeven) foutNummer = FoutNummer.LidWasAlIngeschreven; } else { l.UitschrijfDatum = null; l.NonActief = false; if (lidVoorstel.LeidingMaken != (l.Type == LidType.Leiding)) { // lidtype moet worden veranderd Lid nieuwLid = null; try { nieuwLid = _ledenMgr.TypeToggle(l); } catch (FoutNummerException ex) { foutNummer = ex.FoutNummer; } if (foutNummer == null) { // verwijder bestaande lid _ledenRepo.Delete(l); // bewaar nieuw lid (ander type) in l; wordt straks // toegevoegd aan 'te syncen', waardoor het zal worden // bewaard en gesynct. l = nieuwLid; } } try { _ledenMgr.AfdelingsJarenVervangen(l, lidVoorstel.AfdelingsJaren); } catch (FoutNummerException ex) { foutNummer = ex.FoutNummer; } if (foutNummer == null) { teSyncen.Add(l); } } } else // nieuw lid { try { l = _ledenMgr.NieuwInschrijven(lidVoorstel, false); l.GelieerdePersoon.Persoon.InSync = true; teSyncen.Add(l); } catch (BestaatAlException <Kind> ) { foutNummer = FoutNummer.LidWasAlIngeschreven; } catch (BestaatAlException <Leiding> ) { foutNummer = FoutNummer.LidWasAlIngeschreven; } catch (FoutNummerException ex) { foutNummer = ex.FoutNummer; } catch (GapException) { foutNummer = FoutNummer.AlgemeneLidFout; } } } if (foutNummer != null) { probleemGevallen.Add(new InschrijvingsVoorstel { GelieerdePersoonID = gp.ID, FoutNummer = foutNummer, VolledigeNaam = gp.Persoon.VolledigeNaam, AfdelingsJaarIDs = info.AfdelingsJaarIDs, AfdelingsJaarIrrelevant = info.AfdelingsJaarIrrelevant, LeidingMaken = info.LeidingMaken }); } } } #if KIPDORP using (var tx = new TransactionScope()) { #endif _ledenSync.Bewaren(teSyncen); _gelieerdePersonenRepo.SaveChanges(); #if KIPDORP tx.Complete(); } #endif return(probleemGevallen); }
/// <summary> /// Doet een voorstel voor de inschrijving van de gegeven gelieerdepersoon <paramref name="gp"/> in groepswerkjaar /// <paramref name="gwj"/> /// <para /> /// Als de persoon in een afdeling past, krijgt hij die afdeling. Als er meerdere passen, wordt er een gekozen. /// Als de persoon niet in een afdeling past, en <paramref name="leidingIndienMogelijk"/> <c>true</c> is, /// wordt hij leiding als hij oud genoeg is. /// Anders wordt een afdeling gekozen die het dichtst aanleunt bij de leeftijd van de persoon. /// Zijn er geen afdelingen, dan wordt een exception opgeworpen. /// </summary> /// <param name="gp"> /// De persoon om in te schrijven, gekoppeld met groep en persoon /// </param> /// <param name="gwj"> /// Het groepswerkjaar waarin moet worden ingeschreven, gekoppeld met afdelingsjaren /// </param> /// <param name="leidingIndienMogelijk">Als deze <c>true</c> is, dan stelt de method voor om een persoon /// leiding te maken als er geen geschikte afdeling is, en hij/zij oud genoeg is.</param> /// <returns> /// Voorstel tot inschrijving /// </returns> /// <remarks> /// Dit voorstel is een best effort. Het wordt hier niet gevalideerd; dat moet je elders doen. /// </remarks> public LidVoorstel InschrijvingVoorstellen(GelieerdePersoon gp, GroepsWerkJaar gwj, bool leidingIndienMogelijk) { var resultaat = new LidVoorstel { GelieerdePersoon = gp, GroepsWerkJaar = gwj }; if (!gp.GebDatumMetChiroLeefTijd.HasValue) { // Als we geen geboortedatum hebben, kunnen we niets doen, want het minste dat we willen is // valideren of de persoon wel oud genoeg is om leiding te kunnen worden. throw new FoutNummerException(FoutNummer.GeboorteDatumOntbreekt, Resources.GeboorteDatumOntbreekt); } // TODO: Bekijken of we 'AfdelingsJaarVoorstellen' niet kunnen hergebruiken. // Als we een geboortejaar hebben, kunnen we een afdeling voorstellen. var geboortejaar = gp.GebDatumMetChiroLeefTijd.Value.Year; // Bestaat er een afdeling waar de gelieerde persoon als kind in zou passen? // (Als er meerdere mogelijkheden zijn zullen we gewoon de eerste kiezen, maar we sorteren op // overenkomst geslacht) var mogelijkeAfdelingsJaren = gwj.AfdelingsJaar.Where(a => a.OfficieleAfdeling.ID != (int)NationaleAfdeling.Speciaal && geboortejaar <= a.GeboorteJaarTot && a.GeboorteJaarVan <= geboortejaar).OrderByDescending( a => (gp.Persoon.Geslacht & a.Geslacht)).ToArray(); if (mogelijkeAfdelingsJaren.Any()) { // Als we lid kunnen maken: doen. // Een lid heeft steeds maar 1 afdeling, vandaar: 'First'. resultaat.AfdelingsJaren = new List <AfdelingsJaar> { mogelijkeAfdelingsJaren.First() }; resultaat.LeidingMaken = false; } else if (leidingIndienMogelijk && KanLeidingWorden(gp, gwj)) { // Geen afdeling gevonden. Als oud genoeg om leiding te worden: OK resultaat.AfdelingsJarenIrrelevant = true; resultaat.LeidingMaken = true; } else { // Sorteer eerst aflopend op persoonsgeslacht|afdelingsgeslacht, zodat de // afdelingen met overeenkomstig geslacht eerst staan. Daarna sorteren we // op verschil geboortejaar-afdelingsgeboortejaar var geschiktsteAfdelingsjaar = gwj.AfdelingsJaar.OrderByDescending(a => (gp.Persoon.Geslacht & a.Geslacht)).ThenBy( aj => (Math.Abs(geboortejaar - aj.GeboorteJaarTot))).FirstOrDefault() ?? // als bovenstaande expressie null is, proberen we onderstaande. Onderstaande houdt // geen rekening met geslacht. gwj.AfdelingsJaar.OrderBy( aj => (Math.Abs(geboortejaar - aj.GeboorteJaarTot))).FirstOrDefault(); resultaat.AfdelingsJaren = new List <AfdelingsJaar> { geschiktsteAfdelingsjaar }; resultaat.LeidingMaken = false; } return(resultaat); }
/// <summary> /// Verandert het lidtype van <paramref name="origineelLid"/> van /// <c>Kind</c> naar <c>Leiding</c> of omgekeerd /// </summary> /// <param name="origineelLid">Lid waarvan type veranderd moet worden</param> /// <returns>Nieuw lid, met ander type</returns> /// <remarks>Het origineel lid moet door de caller zelf uit de repository verwijderd worden.</remarks> public Lid TypeToggle(Lid origineelLid) { if (origineelLid.GroepsWerkJaar.Groep.StopDatum != null && origineelLid.GroepsWerkJaar.Groep.StopDatum < DateTime.Now) { throw new FoutNummerException(FoutNummer.GroepInactief, Resources.GroepInactief); } DateTime?eindeInstap = origineelLid.EindeInstapPeriode; var nieuwNiveau = (origineelLid is Kind) ? Niveau.LeidingInGroep : Niveau.LidInGroep; var gelieerdePersoon = origineelLid.GelieerdePersoon; var groepsWerkJaar = origineelLid.GroepsWerkJaar; // Een bestaand object van type wisselen, is niet mogelijk (denk ik) // dus we verwijderen het bestaande lid, en maken een nieuw aan. // Zaken uit de repository verwijderen, kan moeilijk tot niet in de workers, // dus doen we het hier. if (!groepsWerkJaar.Groep.Niveau.HasFlag(Niveau.Groep)) { throw new FoutNummerException(FoutNummer.LidTypeVerkeerd, Resources.FoutiefLidTypeFunctie); } // Behoud bestaande functies die straks nog van // toepassing zijn, om opnieuw te kunnen toekennen. var teBewarenFuncties = (from f in origineelLid.Functie where f.Niveau.HasFlag(nieuwNiveau) select f).ToList(); // Koppel de bestaande functies en afdelingen los van het lid, en verwijder het bestaande lid. origineelLid.Functie.Clear(); if (origineelLid is Leiding) { (origineelLid as Leiding).AfdelingsJaar.Clear(); } gelieerdePersoon.Lid.Remove(origineelLid); groepsWerkJaar.Lid.Remove(origineelLid); var voorstelLid = new LidVoorstel { AfdelingsJarenIrrelevant = true, LeidingMaken = (nieuwNiveau == Niveau.LeidingInGroep), GelieerdePersoon = gelieerdePersoon, GroepsWerkJaar = groepsWerkJaar }; var nieuwLid = NieuwInschrijven(voorstelLid, false); nieuwLid.EindeInstapPeriode = eindeInstap; foreach (var f in teBewarenFuncties) { nieuwLid.Functie.Add(f); } return(nieuwLid); }