<commit_before>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Transactions;

using Chiro.Cdf.Data;
using Chiro.Gap.Domain;
using Chiro.Gap.Orm;
using Chiro.Gap.Orm.DataInterfaces;
using Chiro.Gap.Orm.SyncInterfaces;
using Chiro.Gap.Workers.Exceptions;

namespace Chiro.Gap.Workers
{
	/// <summary>
	/// Businesslogica wat betreft uitstappen en bivakken
	/// </summary>
	public class UitstappenManager
	{
		private readonly IGroepsWerkJaarDao _groepsWerkJaarDao;
		private readonly IAutorisatieManager _autorisatieManager;
		private readonly IUitstappenDao _uitstappenDao;
		private readonly IBivakSync _sync;

		/// <summary>
		/// Constructor.  De parameters moeten 'ingevuld' via dependency inejction
		/// </summary>
		/// <param name="uitstappenDao"></param>
		/// <param name="groepsWerkJaarDao">Data access voor groepswerkjaren</param>
		/// <param name="autorisatieManager">Businesslogica voor autorisatie</param>
		/// <param name="sync">Proxy naar service om bivakaangiftes te syncen met Kipadmin</param>
		public UitstappenManager(
			IUitstappenDao uitstappenDao,
			IGroepsWerkJaarDao groepsWerkJaarDao,
			IAutorisatieManager autorisatieManager,
			IBivakSync sync)
		{
			_uitstappenDao = uitstappenDao;
			_groepsWerkJaarDao = groepsWerkJaarDao;
			_autorisatieManager = autorisatieManager;
			_sync = sync;
		}

		/// <summary>
		/// Koppelt een uitstap aan een groepswerkjaar.  Dit moet typisch
		/// enkel gebeuren bij een nieuwe uitstap.
		/// </summary>
		/// <param name="uitstap">Te koppelen uitstap</param>
		/// <param name="gwj">Te koppelen groepswerkjaar</param>
		/// <returns><paramref name="uitstap"/>, gekoppeld aan <paramref name="gwj"/>.</returns>
		public Uitstap Koppelen(Uitstap uitstap, GroepsWerkJaar gwj)
		{
			if (!_autorisatieManager.IsGavGroepsWerkJaar(gwj.ID) || !_autorisatieManager.IsGavUitstap(uitstap.ID))
			{
				throw new GeenGavException(Properties.Resources.GeenGav);
			}
			else if (uitstap.GroepsWerkJaar != null && uitstap.GroepsWerkJaar != gwj)
			{
				throw new BlokkerendeObjectenException<GroepsWerkJaar>(
					uitstap.GroepsWerkJaar,
					Properties.Resources.UitstapAlGekoppeld);
			}
			else if (!_groepsWerkJaarDao.IsRecentste(gwj.ID))
			{
				throw new FoutNummerException(FoutNummer.GroepsWerkJaarNietBeschikbaar, Properties.Resources.GroepsWerkJaarVoorbij);
			}
			else
			{
				uitstap.GroepsWerkJaar = gwj;
				gwj.Uitstap.Add(uitstap);
				return uitstap;
			}
		}

		/// <summary>
		/// Haalt de uitstap met gegeven <paramref name="uitstapID"/> op, inclusief
		/// het gekoppelde groepswerkjaar.
		/// </summary>
		/// <param name="uitstapID">ID op te halen uitstap</param>
		/// <param name="extras"></param>
		/// <returns>De uitstap, met daaraan gekoppeld het groepswerkjaar.</returns>
		public Uitstap Ophalen(int uitstapID, UitstapExtras extras)
		{
			var paths = new List<Expression<Func<Uitstap, object>>>();

			if (!_autorisatieManager.IsGavUitstap(uitstapID))
			{
				throw new GeenGavException(Properties.Resources.GeenGav);
			}
			else
			{
				if ((extras & UitstapExtras.Groep) == UitstapExtras.Groep)
				{
					paths.Add(u => u.GroepsWerkJaar.Groep);
				}
				else if ((extras & UitstapExtras.GroepsWerkJaar) == UitstapExtras.GroepsWerkJaar)
				{
					paths.Add(u => u.GroepsWerkJaar);
				}

				if ((extras & UitstapExtras.Deelnemers) == UitstapExtras.Deelnemers)
				{
					paths.Add(u => u.Deelnemer.First().GelieerdePersoon.Persoon.WithoutUpdate());
				}

				if ((extras & UitstapExtras.Contact) == UitstapExtras.Contact)
				{
					paths.Add(u => u.ContactDeelnemer.WithoutUpdate());
				}

				if ((extras & UitstapExtras.Plaats) != 0)
				{
					paths.Add(u => u.Plaats.Adres);
				}
				return _uitstappenDao.Ophalen(uitstapID, paths.ToArray());
			}
		}

		/// <summary>
		/// Bewaart de uitstap met het gekoppelde groepswerkjaar
		/// </summary>
		/// <param name="uitstap">Te bewaren uitstap</param>
		/// <param name="extras">Bepaalt de mee te bewaren koppelingen</param>
		/// <remarks>Groepswerkjaar wordt altijd mee bewaard</remarks>
		public Uitstap Bewaren(Uitstap uitstap, UitstapExtras extras)
		{
			var groep = uitstap.GroepsWerkJaar == null ? null : uitstap.GroepsWerkJaar.Groep;

			if (!_autorisatieManager.IsGavUitstap(uitstap.ID))
			{
				throw new GeenGavException(Properties.Resources.GeenGav);
			}
			else if (!_groepsWerkJaarDao.IsRecentste(uitstap.GroepsWerkJaar.ID))
			{
				throw new FoutNummerException(FoutNummer.GroepsWerkJaarNietBeschikbaar, Properties.Resources.GroepsWerkJaarVoorbij);
			}
			else
			{
				// Sowieso groepswerkjaar koppelen.

				Debug.Assert(uitstap.GroepsWerkJaar != null);
				var koppelingen = new List<Expression<Func<Uitstap, object>>> { u => u.GroepsWerkJaar.WithoutUpdate() };

				if ((extras & UitstapExtras.Plaats) != 0)
				{
					koppelingen.Add(u => u.Plaats);
				}
				if ((extras & UitstapExtras.Deelnemers) == UitstapExtras.Deelnemers)
				{
					koppelingen.Add(u => u.Deelnemer.First().GelieerdePersoon.WithoutUpdate());
				}
				if ((extras & UitstapExtras.Contact) == UitstapExtras.Contact)
				{
					koppelingen.Add(u => u.ContactDeelnemer.WithoutUpdate());
				}
#if KIPDORP
				using (var tx = new TransactionScope())
				{
#endif
					uitstap = _uitstappenDao.Bewaren(uitstap, koppelingen.ToArray());
					if (uitstap.IsBivak)
					{
						// De 'Bewaren' hierboven heeft tot gevolg dat de groep niet
						// meer gekoppeld is (wegens onderliggende beperkingen van
						// AttachObjectGraph).  Vandaar dat we voor het gemak
						// die groep hier opnieuw koppelen.

						uitstap.GroepsWerkJaar.Groep = groep;
						_sync.Bewaren(uitstap);
					}
					else
					{
						// Dit om op te vangen dat een bivak afgevinkt wordt als bivak.
						// TODO: betere manier bedenken

						_sync.Verwijderen(uitstap.ID);
					}
#if KIPDORP
					tx.Complete();
				}
#endif
				return uitstap;
			}
		}

		/// <summary>
		/// Haalt alle uitstappen van een gegeven groep op.<commit_msg>Refs #951. Plaats bivak naar Kipadmin.<commit_after>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Transactions;

using Chiro.Cdf.Data;
using Chiro.Gap.Domain;
using Chiro.Gap.Orm;
using Chiro.Gap.Orm.DataInterfaces;
using Chiro.Gap.Orm.SyncInterfaces;
using Chiro.Gap.Workers.Exceptions;

namespace Chiro.Gap.Workers
{
	/// <summary>
	/// Businesslogica wat betreft uitstappen en bivakken
	/// </summary>
	public class UitstappenManager
	{
		private readonly IGroepsWerkJaarDao _groepsWerkJaarDao;
		private readonly IAutorisatieManager _autorisatieManager;
		private readonly IUitstappenDao _uitstappenDao;
		private readonly IBivakSync _sync;

		/// <summary>
		/// Constructor.  De parameters moeten 'ingevuld' via dependency inejction
		/// </summary>
		/// <param name="uitstappenDao"></param>
		/// <param name="groepsWerkJaarDao">Data access voor groepswerkjaren</param>
		/// <param name="autorisatieManager">Businesslogica voor autorisatie</param>
		/// <param name="sync">Proxy naar service om bivakaangiftes te syncen met Kipadmin</param>
		public UitstappenManager(
			IUitstappenDao uitstappenDao,
			IGroepsWerkJaarDao groepsWerkJaarDao,
			IAutorisatieManager autorisatieManager,
			IBivakSync sync)
		{
			_uitstappenDao = uitstappenDao;
			_groepsWerkJaarDao = groepsWerkJaarDao;
			_autorisatieManager = autorisatieManager;
			_sync = sync;
		}

		/// <summary>
		/// Koppelt een uitstap aan een groepswerkjaar.  Dit moet typisch
		/// enkel gebeuren bij een nieuwe uitstap.
		/// </summary>
		/// <param name="uitstap">Te koppelen uitstap</param>
		/// <param name="gwj">Te koppelen groepswerkjaar</param>
		/// <returns><paramref name="uitstap"/>, gekoppeld aan <paramref name="gwj"/>.</returns>
		public Uitstap Koppelen(Uitstap uitstap, GroepsWerkJaar gwj)
		{
			if (!_autorisatieManager.IsGavGroepsWerkJaar(gwj.ID) || !_autorisatieManager.IsGavUitstap(uitstap.ID))
			{
				throw new GeenGavException(Properties.Resources.GeenGav);
			}
			else if (uitstap.GroepsWerkJaar != null && uitstap.GroepsWerkJaar != gwj)
			{
				throw new BlokkerendeObjectenException<GroepsWerkJaar>(
					uitstap.GroepsWerkJaar,
					Properties.Resources.UitstapAlGekoppeld);
			}
			else if (!_groepsWerkJaarDao.IsRecentste(gwj.ID))
			{
				throw new FoutNummerException(FoutNummer.GroepsWerkJaarNietBeschikbaar, Properties.Resources.GroepsWerkJaarVoorbij);
			}
			else
			{
				uitstap.GroepsWerkJaar = gwj;
				gwj.Uitstap.Add(uitstap);
				return uitstap;
			}
		}

		/// <summary>
		/// Haalt de uitstap met gegeven <paramref name="uitstapID"/> op, inclusief
		/// het gekoppelde groepswerkjaar.
		/// </summary>
		/// <param name="uitstapID">ID op te halen uitstap</param>
		/// <param name="extras"></param>
		/// <returns>De uitstap, met daaraan gekoppeld het groepswerkjaar.</returns>
		public Uitstap Ophalen(int uitstapID, UitstapExtras extras)
		{
			var paths = new List<Expression<Func<Uitstap, object>>>();

			if (!_autorisatieManager.IsGavUitstap(uitstapID))
			{
				throw new GeenGavException(Properties.Resources.GeenGav);
			}
			else
			{
				if ((extras & UitstapExtras.Groep) == UitstapExtras.Groep)
				{
					paths.Add(u => u.GroepsWerkJaar.Groep);
				}
				else if ((extras & UitstapExtras.GroepsWerkJaar) == UitstapExtras.GroepsWerkJaar)
				{
					paths.Add(u => u.GroepsWerkJaar);
				}

				if ((extras & UitstapExtras.Deelnemers) == UitstapExtras.Deelnemers)
				{
					paths.Add(u => u.Deelnemer.First().GelieerdePersoon.Persoon.WithoutUpdate());
				}

				if ((extras & UitstapExtras.Contact) == UitstapExtras.Contact)
				{
					paths.Add(u => u.ContactDeelnemer.WithoutUpdate());
				}

				if ((extras & UitstapExtras.Plaats) != 0)
				{
					paths.Add(u => u.Plaats.Adres);
				}
				return _uitstappenDao.Ophalen(uitstapID, paths.ToArray());
			}
		}

		/// <summary>
		/// Bewaart de uitstap met het gekoppelde groepswerkjaar
		/// </summary>
		/// <param name="uitstap">Te bewaren uitstap</param>
		/// <param name="extras">Bepaalt de mee te bewaren koppelingen</param>
		/// <remarks>Groepswerkjaar wordt altijd mee bewaard</remarks>
		public Uitstap Bewaren(Uitstap uitstap, UitstapExtras extras)
		{
			// kopieer eerst een aantal gekoppelde entiteiten (voor sync straks), want na het bewaren van 
			// het bivak zijn we die kwijt...

			var groep = uitstap.GroepsWerkJaar == null ? null : uitstap.GroepsWerkJaar.Groep;
			var plaats = uitstap.Plaats == null ? null : uitstap.Plaats;


			if (!_autorisatieManager.IsGavUitstap(uitstap.ID))
			{
				throw new GeenGavException(Properties.Resources.GeenGav);
			}
			else if (!_groepsWerkJaarDao.IsRecentste(uitstap.GroepsWerkJaar.ID))
			{
				throw new FoutNummerException(FoutNummer.GroepsWerkJaarNietBeschikbaar, Properties.Resources.GroepsWerkJaarVoorbij);
			}
			else
			{
				// Sowieso groepswerkjaar koppelen.

				Debug.Assert(uitstap.GroepsWerkJaar != null);
				var koppelingen = new List<Expression<Func<Uitstap, object>>> { u => u.GroepsWerkJaar.WithoutUpdate() };

				if ((extras & UitstapExtras.Plaats) != 0)
				{
					koppelingen.Add(u => u.Plaats);
				}
				if ((extras & UitstapExtras.Deelnemers) == UitstapExtras.Deelnemers)
				{
					koppelingen.Add(u => u.Deelnemer.First().GelieerdePersoon.WithoutUpdate());
				}
				if ((extras & UitstapExtras.Contact) == UitstapExtras.Contact)
				{
					koppelingen.Add(u => u.ContactDeelnemer.WithoutUpdate());
				}
#if KIPDORP
				using (var tx = new TransactionScope())
				{
#endif
					uitstap = _uitstappenDao.Bewaren(uitstap, koppelingen.ToArray());
					if (uitstap.IsBivak)
					{
						// De 'Bewaren' hierboven heeft tot gevolg dat de groep niet
						// meer gekoppeld is (wegens onderliggende beperkingen van
						// AttachObjectGraph).  Vandaar dat we voor het gemak
						// die groep hier opnieuw koppelen.
						// Idem voor plaats

						// Opgelet.  Dit is inconsistent gedrag van de software :-(

						uitstap.GroepsWerkJaar.Groep = groep;
						uitstap.Plaats = plaats;
						_sync.Bewaren(uitstap);
					}
					else
					{
						// Dit om op te vangen dat een bivak afgevinkt wordt als bivak.
						// TODO: betere manier bedenken

						_sync.Verwijderen(uitstap.ID);
					}
#if KIPDORP
					tx.Complete();
				}
#endif
				return uitstap;
			}
		}

		/// <summary>
		/// Haalt alle uitstappen van een gegeven groep op.
{'fraction_non_alphanumeric': 0.11909716663998719, 'fraction_numerical': 0.0005602689290859612, 'mean_word_length': 3.5059502344031737, 'pattern_counts': {'":': 0, '<': 97, '<?xml version=': 0, '>': 115, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2394166', 'n_tokens_mistral': 5635, 'n_tokens_neox': 4848, 'n_words': 861}