public int TypeToggle(int lidId)
        {
            var origineelLid = _ledenRepo.ByID(lidId);
            Lid nieuwLid     = null;

            Gav.Check(origineelLid);

            try
            {
                nieuwLid = _ledenMgr.TypeToggle(origineelLid);
            }
            catch (FoutNummerException ex)
            {
                // Dit is misschien wat kort door de bocht:
                throw FaultExceptionHelper.FoutNummer(ex.FoutNummer, ex.Message);
            }

#if KIPDORP
            using (var tx = new TransactionScope())
            {
#endif
            _ledenRepo.Delete(origineelLid);
            _ledenSync.TypeUpdaten(nieuwLid);
            _ledenSync.AfdelingenUpdaten(nieuwLid);
            _ledenRepo.SaveChanges();
#if KIPDORP
            tx.Complete();
        }
#endif
            return(nieuwLid.ID);
        }
        public void FunctiesVervangen(int lidId, IEnumerable <int> functieIds)
        {
            var lid = _ledenRepo.ByID(lidId);

            if (_autorisatieMgr.PermissiesOphalen(lid) != Permissies.Bewerken)
            {
                throw FaultExceptionHelper.GeenGav();
            }

            var functies = _functiesRepo.ByIDs(functieIds);

            // TODO: optimaliseren. Tien tegen 1 zijn al die functies aan dezelfde groep gekoppeld.
            // (Als ze al gekoppeld zijn, want de nationale functies hebben geen gekoppelde groep.)
            // In dat geval volstaat het om 1 check te doen, ipv een check per functie.
            // TIP: controleer GAV-schap functies.SelectMany(fn=>fn.Groep).Distinct().

            if (functies.Any(functie => !_autorisatieMgr.PermissiesOphalen(functie).HasFlag(Permissies.Lezen)))
            {
                throw FaultExceptionHelper.GeenGav();
            }

            try
            {
                _functiesMgr.Vervangen(lid, functies);
            }
            catch (FoutNummerException ex)
            {
                switch (ex.FoutNummer)
                {
                case FoutNummer.GroepsWerkJaarNietBeschikbaar:
                case FoutNummer.FunctieNietVanGroep:
                case FoutNummer.FunctieNietBeschikbaar:
                case FoutNummer.LidTypeVerkeerd:
                case FoutNummer.EMailVerplicht:
                case FoutNummer.ContactMoetNieuwsBriefKrijgen:
                    // Deze exceptions verwachten we; we sturen een foutnummerfault
                    throw FaultExceptionHelper.FoutNummer(ex.FoutNummer, ex.Message);

                default:
                    // Onverwachte exception gooien we opnieuw op.
                    throw;
                }
            }

#if KIPDORP
            using (var tx = new TransactionScope())
            {
#endif
            _ledenRepo.SaveChanges();
            _ledenSync.FunctiesUpdaten(lid);
#if KIPDORP
            tx.Complete();
        }
#endif
        }
        public LidInfo LidInfoOphalen(int lidID)
        {
            var lid = _ledenRepo.ByID(lidID);

            Gav.Check(lid);
            if (lid.NonActief)
            {
                FaultExceptionHelper.FoutNummer(FoutNummer.LidUitgeschreven, Resources.LidInactief);
            }
            return(_mappingHelper.Map <Lid, LidInfo>(lid));
        }
        public PersoonInfo PersoonOphalen(int lidID)
        {
            var lid = _ledenRepo.ByID(lidID);

            Gav.Check(lid);
            if (lid.NonActief)
            {
                FaultExceptionHelper.FoutNummer(FoutNummer.LidUitgeschreven, Resources.LidInactief);
            }
            return(_mappingHelper.Map <GelieerdePersoon, PersoonInfo>(lid.GelieerdePersoon));
        }
        public void RechtenToekennen(int gelieerdePersoonId, GebruikersRecht gebruikersRecht)
        {
            var gelieerdePersoon = _gelieerdePersonenRepo.ByID(gelieerdePersoonId);

            Gav.Check(gelieerdePersoon);

            if (gebruikersRecht == null)
            {
                // Als er geen gebruikersrechten meegegeven zijn, dan geven we de gelieerde persoon
                // rechten 'geen' op zijn eigen groep.
                gebruikersRecht = new GebruikersRecht();
            }

            var p = gelieerdePersoon.Persoon;

            if (p.AdNummer == null)
            {
                throw FaultExceptionHelper.FoutNummer(FoutNummer.AdNummerVerplicht,
                                                      Resources.AdNummerVerplicht);
            }
            if (string.IsNullOrEmpty(_gelieerdePersonenMgr.ContactEmail(gelieerdePersoon)))
            {
                throw FaultExceptionHelper.FoutNummer(FoutNummer.EMailVerplicht, Resources.EmailOntbreekt);
            }

            _gebruikersRechtenMgr.ToekennenOfWijzigen(gelieerdePersoon.Persoon, gelieerdePersoon.Groep,
                                                      gebruikersRecht.PersoonsPermissies, gebruikersRecht.GroepsPermissies, gebruikersRecht.AfdelingsPermissies,
                                                      gebruikersRecht.IedereenPermissies);


#if KIPDORP
            using (var tx = new TransactionScope())
            {
#endif
            _rechtenRepo.SaveChanges();

            // Zoekt de gegeven gebruiker in active directory. Maakt die gebruiker aan als die nog
            // niet bestaat. En voegt hem/haar toe aan de groep GapGebruikers.

            ServiceHelper.CallService <IAdService, string>(
                svc =>
                svc.GapLoginAanvragen(p.AdNummer.Value, p.VoorNaam, p.Naam,
                                      _gelieerdePersonenMgr.ContactEmail(gelieerdePersoon)));
#if KIPDORP
            tx.Complete();
        }
#endif
        }
        public GebruikersDetail DetailsOphalen(int adNummer, bool aanMaken)
        {
            int?mijnAdNummer = _authenticatieMgr.AdNummerGet();

            if (mijnAdNummer == null)
            {
                throw FaultExceptionHelper.FoutNummer(FoutNummer.KoppelingLoginPersoonOntbreekt, String.Format(
                                                          Resources.KoppelingLoginPersoonOntbreekt,
                                                          _authenticatieMgr.GebruikersNaamGet(),
                                                          mijnAdNummer));
            }
            var persoon = (from p in _personenRepo.Select()
                           where p.AdNummer == adNummer
                           select p).FirstOrDefault();
            var ik = (from p in _personenRepo.Select()
                      where p.AdNummer == mijnAdNummer
                      select p).FirstOrDefault();

            if (persoon == null && aanMaken)
            {
                // We gaan de persoon registreren. Als hij nog niet bestond, had hij nog geen rechten.
                // TODO: gegevens ophalen uit Civi, ipv leeg te laten (zie #5612).
                persoon = new Persoon
                {
                    // FIXME: stub-naam is niet zo goed. Misschien login erin verwerken?
                    VoorNaam = adNummer.ToString(),
                    Naam     = "AD-nummer",
                    AdNummer = mijnAdNummer,
                    Geslacht = GeslachtsType.Onbekend,
                };
                _personenRepo.Add(persoon);
                _personenRepo.SaveChanges();
            }

            // Controleer gebruikersrechten. Ik test ook op AD-nummer, want als ik mezelf net heb
            // aangemaakt loopt het anders fout.
            if (adNummer != mijnAdNummer && !_autorisatieMgr.MagLezen(ik, persoon))
            {
                throw FaultExceptionHelper.GeenGav();
            }

            return(_mappingHelper.Map <Persoon, GebruikersDetail>(persoon));
        }
        public int LoonVerliesVerzekeren(int lidId)
        {
            PersoonsVerzekering persoonsVerzekering;
            var lid = _ledenRepo.ByID(lidId);

            Gav.Check(lid);

            if (lid.GroepsWerkJaar.Groep.StopDatum != null && lid.GroepsWerkJaar.Groep.StopDatum < DateTime.Now)
            {
                throw FaultExceptionHelper.FoutNummer(FoutNummer.GroepInactief, Resources.GroepInactief);
            }

            var verzekeringstype = (from g in _verzekerRepo.Select() where g.ID == (int)Verzekering.LoonVerlies select g).First();

            try
            {
                persoonsVerzekering = _verzekeringenMgr.Verzekeren(lid, verzekeringstype, DateTime.Today,
                                                                   _groepsWerkJarenMgr.EindDatum(lid.GroepsWerkJaar));
            }
            catch (FoutNummerException ex)
            {
                throw FaultExceptionHelper.FoutNummer(ex.FoutNummer, ex.Message);
            }
            catch (BlokkerendeObjectenException <PersoonsVerzekering> )
            {
                // TODO: beter faultcontract. (VerzekeringsInfo?)
                throw FaultExceptionHelper.BestaatAl("Verzekering");
            }

#if KIPDORP
            using (var tx = new TransactionScope())
            {
#endif
            _verzekeringenSync.Bewaren(persoonsVerzekering, lid.GroepsWerkJaar);
            _ledenRepo.SaveChanges();
#if KIPDORP
            tx.Complete();
        }
#endif
            return(lid.GelieerdePersoon.ID);
        }
        public void AfdelingenVervangenBulk(IList <int> lidIds, IList <int> afdelingsJaarIds)
        {
            // Dit is een beetje een rare functie. Als er meerdere leden zijn, en meerdere afdelingen, dan moeten
            // die leden allemaal kindleden zijn van hetzelfde groepswerkjaar. Anders gaat het mis.

            // TODO: een en ander verhuizen naar workers.

            var leden = _ledenRepo.ByIDs(lidIds);
            List <AfdelingsJaar> afdelingsJaren;

            if (afdelingsJaarIds.Any())
            {
                var gwjs = (from l in leden select l.GroepsWerkJaar).Distinct().ToList();
                if (gwjs.Count() != 1)
                {
                    // Er zijn groepswerkjaren meegegeven. Een afdelingsjaar is steeds gekoppeld
                    // aan precies 1 groepswerkjaar.
                    // De leden komen uit meer dan 1 groepswerkjaar. Het afdelingsjaar kan dus
                    // nooit gekoppeld zijn aan het groepswerkjaar van elk lid.
                    // (pigeon hole principle)
                    throw FaultExceptionHelper.FoutNummer(FoutNummer.AfdelingNietVanGroep,
                                                          Resources.OngelidgeAfdelingVoorLid);
                }
                afdelingsJaren = (from aj in gwjs.First().AfdelingsJaar
                                  where afdelingsJaarIds.Contains(aj.ID)
                                  select aj).ToList();

                if (afdelingsJaarIds.Count != afdelingsJaren.Count)
                {
                    // Niet alle afdelingsjaren zijn gevonden in het groepswerkjaar van de leden.
                    throw FaultExceptionHelper.FoutNummer(FoutNummer.AfdelingNietVanGroep,
                                                          Resources.OngelidgeAfdelingVoorLid);
                }
            }
            else
            {
                afdelingsJaren = new List <AfdelingsJaar>();
            }

            if (!_autorisatieMgr.IsGav(leden))
            {
                throw FaultExceptionHelper.GeenGav();
            }

            foreach (var lid in leden)
            {
                try
                {
                    _ledenMgr.AfdelingsJarenVervangen(lid, afdelingsJaren);
                }
                catch (FoutNummerException ex)
                {
                    if (ex.FoutNummer == FoutNummer.AlgemeneKindFout)
                    {
                        throw FaultExceptionHelper.FoutNummer(FoutNummer.AfdelingKindVerplicht, Resources.KindInEenAfdelingsJaar);
                    }
                    else
                    {
                        throw;
                    }
                }
            }

#if KIPDORP
            using (var tx = new TransactionScope())
            {
#endif
            foreach (var l in leden)
            {
                _ledenSync.AfdelingenUpdaten(l);
            }
            _ledenRepo.SaveChanges();
#if KIPDORP
            tx.Complete();
        }
#endif
        }
        public void Uitschrijven(IList <int> gelieerdePersoonIDs, out string foutBerichten)
        {
            // Deze code is tamelijk rommelig; gebruik ze niet als referentie-implementatie
            // (Ik ben er ook niet van overtuigd of het werken met 'foutBerichten' wel in orde is.)
            var teVerwijderen    = new List <Lid>();
            var stopDatumBewaren = new List <Lid>();

            var foutBerichtenBuilder = new StringBuilder();

            var gelieerdePersonen = _gelieerdePersonenRepo.ByIDs(gelieerdePersoonIDs);

            if (!_autorisatieMgr.IsGav(gelieerdePersonen) || gelieerdePersoonIDs.Count() != gelieerdePersonen.Count)
            {
                throw FaultExceptionHelper.GeenGav();
            }

            var groepen = (from gp in gelieerdePersonen select gp.Groep).Distinct();

            foreach (var g in groepen)
            {
                if (g.StopDatum != null && g.StopDatum < DateTime.Now)
                {
                    throw FaultExceptionHelper.FoutNummer(FoutNummer.GroepInactief, Resources.GroepInactief);
                }

                var gwj = _groepenMgr.HuidigWerkJaar(g);

                // Handel per groep de uitschrijvingen af, zodat we per groep kunnen
                // controleren of de persoon wel ingeschreven is in het recentste groepswerkjaar.

                Groep g1 = g;
                foreach (var gp in gelieerdePersonen.Where(gp => Equals(gp.Groep, g1)))
                {
                    var lid = gp.Lid.FirstOrDefault(e => e.GroepsWerkJaar.ID == gwj.ID);

                    if (lid == null)
                    {
                        foutBerichtenBuilder.AppendLine(String.Format(Resources.IsNogNietIngeschreven,
                                                                      gp.Persoon.VolledigeNaam));
                        continue;
                    }
                    if (lid.NonActief)
                    {
                        foutBerichtenBuilder.AppendLine(String.Format(Resources.IsAlUitgeschreven,
                                                                      gp.Persoon.VolledigeNaam));
                        continue;
                    }

                    lid.UitschrijfDatum = DateTime.Now;
                    lid.Functie.Clear();

                    if (lid.EindeInstapPeriode > lid.UitschrijfDatum || lid.Niveau > Niveau.Groep)
                    {
                        teVerwijderen.Add(lid);
                    }
                    else
                    {
                        stopDatumBewaren.Add(lid);
                    }
                }
            }

            foutBerichten = foutBerichtenBuilder.ToString();

#if KIPDORP
            using (var tx = new TransactionScope())
            {
#endif
            _gelieerdePersonenRepo.SaveChanges();
            foreach (var l in teVerwijderen)
            {
                _ledenSync.Verwijderen(l);
            }
            foreach (var l in stopDatumBewaren)
            {
                _ledenSync.Bewaren(l);
            }
#if KIPDORP
            tx.Complete();
        }
#endif
        }