view Agendas/trunk/src/Agendas.Domain/Agenda.cs @ 214:7d838e7d83b3

Se soluciona ticket 176. Se agrega validación para que no se pueda agendar otro evento con el mismo título, buscando los eventos que no estén en estado propuesto.
author alabra
date Wed, 24 Aug 2011 19:49:18 -0300
parents 1fead4596a98
children 8a8c35302b81
line wrap: on
line source

using System;
using System.Collections.Generic;
using System.Linq;
using AltNetHispano.Agendas.Domain.Exceptions;
using AltNetHispano.Agendas.Domain.Repositories;

namespace AltNetHispano.Agendas.Domain
{
    public class Agenda
    {
        private readonly IEventoRepository _eventosRepository;
        private readonly IPersonaRepository _personaRepository;
        //private readonly IPatrocinadorRepository _patrocinadorRepository;

        private readonly IPublicador _publicador;

        public Agenda(IPublicador publicador, IEventoRepository eventosRepository,
                      IPersonaRepository personaRepository)
        {
            _publicador = publicador;
            //_patrocinadorRepository = patrocinadorRepository;
            _personaRepository = personaRepository;
            _eventosRepository = eventosRepository;
        }

        public Evento GetEvento(Guid eventoId)
        {
            Evento evento = _eventosRepository.Get(eventoId);
            if (evento == null)
                throw new EventoNotFoundException(eventoId);
            return evento;
        }

        public IList<Evento> GetEventosActivos(EventoState state)
        {
            return _eventosRepository.GetByState(state) ?? new List<Evento>();
        }

        public IList<Evento> GetEventosActivos()
        {
            return _eventosRepository.GetActivos() ?? new List<Evento>();
        }

        public IEnumerable<Evento> GetHistorico()
        {
            return _eventosRepository.GetByState(EventoPublicadoState.GetInstance()) ?? new List<Evento>();
        }

        public EventoResultado ModificarEvento(Guid eventoId, string titulo, Guid ponenteId, DateTime? fechaInicio, DateTime? fechaTermino, string urlInvitacion)
        {
            Evento evento = GetEvento(eventoId);
            Persona persona = _personaRepository.Get(ponenteId);

            if (evento.Titulo != titulo)
                evento.CambiarTitulo(titulo);

            if (evento.FechaInicio == null && fechaInicio != null && evento.FechaTermino == null && fechaTermino != null)
                evento.Agendar(persona, fechaInicio, fechaTermino, urlInvitacion);
            else if (evento.FechaInicio != fechaInicio || evento.Ponente != persona || evento.UrlInvitacion != urlInvitacion ||
                    evento.FechaTermino != fechaTermino)
                evento.Actualizar(persona, fechaInicio, fechaTermino, urlInvitacion);

            Notify(evento);

			var warnings = evento.GetLogsNews().Where(l => !l.Successful);

			return new EventoResultado(true,"Evento modificado", warnings);
		}

		public EventoResultado ModificarPropuesta(Guid id, string titulo, Guid ponenteId, string urlInvitacion)
        {
            return ModificarEvento(id, titulo, ponenteId, null, null, urlInvitacion);
        }

		public EventoResultado Proponer(string titulo, Guid? ponenteId, string urlInvitacion, TipoEvento tipo)
        {
            Persona persona = null;
            if (ponenteId.HasValue)
                persona = _personaRepository.Get(ponenteId.Value);

            var evento = Evento.Proponer(titulo, persona, urlInvitacion, tipo);

            if (string.IsNullOrWhiteSpace(evento.Titulo))
                return new EventoResultado(false,"Debe indicar el título del evento", null);

            Notify(evento);

            _eventosRepository.Save(evento);

			var warnings = evento.GetLogsNews().Where(l => !l.Successful);

			return new EventoResultado(true,"Evento propuesto", warnings);
		}

		public EventoResultado Agendar(string titulo, Guid ponenteId, DateTime? fechaInicio, DateTime? fechaTermino, string urlInvitacion, TipoEvento tipo)
        {
            if (!fechaInicio.HasValue)
                return new EventoResultado(false, "Debe indicar la fecha", null);
            if (!fechaTermino.HasValue)
                return new EventoResultado(false, "Debe indicar la hora y duración", null);

            Persona persona = _personaRepository.Get(ponenteId);
            if (persona == null)
                return new EventoResultado(false, string.Format("No se encontró el ponente indicado ({0})", ponenteId), null);

		    var existeOtroEvento = _eventosRepository.GetNoPropuestoByTitulo(titulo);
            if (existeOtroEvento != null)
                return new EventoResultado(false,
                                           string.Format(
                                               "Ya existe un evento con el mismo título ({0}) del {1}, por favor ingrese otro.",
                                               titulo, existeOtroEvento.FechaInicio.Value.ToShortDateString()), null);

            Evento evento = _eventosRepository.GetPropuestaByTitulo(titulo);

			foreach (var e in _eventosRepository.GetActivos())
			{
				if (!e.Equals(evento) && fechaInicio <= e.FechaTermino && fechaTermino >= e.FechaInicio)
				{
					return new EventoResultado(false, string.Format("El evento que está intentando agendar entra en conflicto con '{0}'", e.Titulo), null);
				}
			}

			if (evento == null)
                evento = Evento.Agendar(titulo, persona, fechaInicio.Value, fechaTermino.Value, urlInvitacion, tipo);
            else
                evento.Agendar(persona, fechaInicio, fechaTermino, urlInvitacion);

			Notify(evento);

            _eventosRepository.Save(evento);

			var warnings = evento.GetLogsNews().Where(l => !l.Successful);

			return new EventoResultado(true, "Evento creado", warnings);
		}

		public EventoResultado Confirmar(Guid eventoId)
        {
            Evento evento = GetEvento(eventoId);

            evento.Confirmar();

            Notify(evento);

            _eventosRepository.Save(evento);

			var warnings = evento.GetLogsNews().Where(l => !l.Successful);

			return new EventoResultado(true, "Evento confirmado. Recuerde agendar los eventos en http://twuffer.com/ u otro servicio similar.", warnings);
        }

		public EventoResultado Publicar(Guid eventoId, short numeroOrden, string urlWiki, TimeSpan duracion)
        {
            if (numeroOrden <= 0)
                throw new ArgumentOutOfRangeException("numeroOrden");

            if (string.IsNullOrWhiteSpace(urlWiki))
                throw new ArgumentException("urlWiki");

			if (duracion.Hours.Equals(0) && duracion.Minutes.Equals(0))
				throw new ArgumentOutOfRangeException("duracion");

            Evento evento = GetEvento(eventoId);

            evento.Publicar(numeroOrden, urlWiki, duracion);

            Notify(evento);

            _eventosRepository.Save(evento);

			var warnings = evento.GetLogsNews().Where(l => !l.Successful);

			return new EventoResultado(true, "Evento publicado", warnings);
		}

		public EventoResultado Cancelar(Guid eventoId)
        {
            Evento evento = GetEvento(eventoId);

            evento.Cancelar();

            Notify(evento);

            _eventosRepository.Save(evento);

			var warnings = evento.GetLogsNews().Where(l => !l.Successful);

			return new EventoResultado(true,"Evento cancelado", warnings);
		}

		public EventoResultado Descartar(Guid eventoId)
        {
            Evento evento = GetEvento(eventoId);

            evento.Descartar();

            Notify(evento);

            _eventosRepository.Save(evento);

			var warnings = evento.GetLogsNews().Where(l => !l.Successful);

			return new EventoResultado(true, "Evento descartado", warnings);
		}

		public EventoResultado ReProponer(Guid eventoId)
        {
            Evento evento = GetEvento(eventoId);

            evento.ReProponer();

            Notify(evento);

            _eventosRepository.Save(evento);

			var warnings = evento.GetLogsNews().Where(l => !l.Successful);

			return new EventoResultado(true,"Evento re-prpuesto", warnings);
		}

		public EventoResultado ReAgendar(Guid eventoId)
        {
            Evento evento = GetEvento(eventoId);

            evento.ReAgendar();

            Notify(evento);

            _eventosRepository.Save(evento);

			var warnings = evento.GetLogsNews().Where(l => !l.Successful);

			return new EventoResultado(true,"Evento re-agendado", warnings);
		}

		//public void IndicarPatrocinadores(Guid eventoId, IEnumerable<Guid> patrocinadores)
		//{
		//    var evento = GetEvento(eventoId);

		//    var agregar = new List<Patrocinador>();
		//    var quitar = new List<Patrocinador>();

		//    foreach (var patrocinadorId in patrocinadores)
		//    {
		//        if (!evento.Patrocinadores.Any(p => p.Id == patrocinadorId))
		//        {
		//            var patrocinador = _patrocinadorRepository.Get(patrocinadorId);
		//            agregar.Add(patrocinador);
		//        }
		//    }

		//    foreach (var patrocinador in evento.Patrocinadores)
		//    {
		//        if (!patrocinadores.Any(p => p == patrocinador.Id))
		//            quitar.Add(patrocinador);
		//    }

		//    foreach (var patrocinador in agregar)
		//        evento.AddPatrocinador(patrocinador);

		//    foreach (var patrocinador in quitar)
		//        evento.RemovePatrocinador(patrocinador);
		//}

		private void Notify(Evento evento)
		{
			var tracks = evento.GetTrackNews();
			if (_publicador != null)
				_publicador.Publicar(tracks);
		}

		//TODO: este método ya no se debería usar
		public void RegistrarPonente(string nombre, string mail, string twitter, string blog)
		{
			var ponente = new Persona(nombre, mail, twitter, blog);
			_personaRepository.Save(ponente);
		}

	}
}