changeset 133:6f1041301797

Se agregan los estados Cancelado y Descartado con las acciones Cancelar, Reagendar, Descartar, Reproponer, según ticket 146. Falta solucionar problema con flujo, ver más información en el ticket de assembla. http://www.assembla.com/spaces/altnet-hispano/tickets/146-implementar-estado-descartar-y-cancelar-de-eventos
author alabra
date Sun, 10 Jul 2011 23:59:19 -0400
parents 45be716763c3
children a4ef6874ec81
files Agendas/trunk/src/Agendas.Domain/Agenda.cs Agendas/trunk/src/Agendas.Domain/Agendas.Domain.csproj Agendas/trunk/src/Agendas.Domain/Evento.cs Agendas/trunk/src/Agendas.Domain/EventoAgendadoState.cs Agendas/trunk/src/Agendas.Domain/EventoCanceladoState.cs Agendas/trunk/src/Agendas.Domain/EventoDescartadoState.cs Agendas/trunk/src/Agendas.Domain/EventoPropuestoState.cs Agendas/trunk/src/Agendas.Domain/Track.cs Agendas/trunk/src/Agendas.Tests/AgendarTests.cs Agendas/trunk/src/Agendas.Tests/Workflows/Workflow.cs Agendas/trunk/src/Agendas.Tests/Workflows/WorkflowTests.cs Agendas/trunk/src/Agendas.Web/Controllers/EventoController.cs Agendas/trunk/src/Agendas.Web/Models/EventoModel.cs Agendas/trunk/src/Agendas.Web/Views/Evento/Index.cshtml
diffstat 14 files changed, 553 insertions(+), 132 deletions(-) [+]
line wrap: on
line diff
--- a/Agendas/trunk/src/Agendas.Domain/Agenda.cs	Sun Jul 10 23:55:56 2011 -0400
+++ b/Agendas/trunk/src/Agendas.Domain/Agenda.cs	Sun Jul 10 23:59:19 2011 -0400
@@ -152,5 +152,57 @@
 			_personaRepository.Save(persona);
 			return persona;
 		}
+
+        public Resultado Cancelar(Guid eventoId)
+	    {
+            Evento evento = GetEvento(eventoId);
+
+            evento.Cancelar();
+
+            Notify(evento);
+
+            _eventosRepository.Save(evento);
+
+            return new Resultado(true);
+	    }
+
+	    public Resultado Descartar(Guid eventoId)
+	    {
+            Evento evento = GetEvento(eventoId);
+
+            evento.Descartar();
+
+            Notify(evento);
+
+            _eventosRepository.Save(evento);
+
+            return new Resultado(true);
+	    }
+
+	    public Resultado ReProponer(Guid eventoId)
+	    {
+            Evento evento = GetEvento(eventoId);
+
+            evento.ReProponer();
+
+            Notify(evento);
+
+            _eventosRepository.Save(evento);
+
+            return new Resultado(true);
+	    }
+
+	    public Resultado ReAgendar(Guid eventoId)
+	    {
+            Evento evento = GetEvento(eventoId);
+
+            evento.ReAgendar();
+
+            Notify(evento);
+
+            _eventosRepository.Save(evento);
+
+            return new Resultado(true);
+	    }
 	}
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Domain/Agendas.Domain.csproj	Sun Jul 10 23:55:56 2011 -0400
+++ b/Agendas/trunk/src/Agendas.Domain/Agendas.Domain.csproj	Sun Jul 10 23:59:19 2011 -0400
@@ -41,7 +41,9 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="EventoAgendadoState.cs" />
+    <Compile Include="EventoCanceladoState.cs" />
     <Compile Include="EventoConfirmadoState.cs" />
+    <Compile Include="EventoDescartadoState.cs" />
     <Compile Include="EventoNullState.cs" />
     <Compile Include="EventoPropuestoState.cs" />
     <Compile Include="EventoPublicadoState.cs" />
--- a/Agendas/trunk/src/Agendas.Domain/Evento.cs	Sun Jul 10 23:55:56 2011 -0400
+++ b/Agendas/trunk/src/Agendas.Domain/Evento.cs	Sun Jul 10 23:59:19 2011 -0400
@@ -54,37 +54,41 @@
 			get { return _tracks; }
 		}
 
-    /// <summary>
-    /// Estado del evento en formato string (para persistencia a DB)
-    /// </summary>
-	  public virtual string Estado
-	  {
-      get
-      {
-        if (_eventoState != null)
-          return _eventoState.GetDescripcion();
+	    /// <summary>
+	    /// Estado del evento en formato string (para persistencia a DB)
+	    /// </summary>
+	    public virtual string Estado
+	    {
+	        get
+	        {
+	            if (_eventoState != null)
+	                return _eventoState.GetDescripcion();
 
-        return string.Empty;
-      }
-	    set
-      {
-        if (value != Estado)
-        {
-          if (EventoPropuestoState.GetInstance().GetDescripcion().Equals(value))
-            _eventoState = EventoPropuestoState.GetInstance();
-          else if (EventoAgendadoState.GetInstance().GetDescripcion().Equals(value))
-            _eventoState = EventoAgendadoState.GetInstance();
-          else if (EventoConfirmadoState.GetInstance().GetDescripcion().Equals(value))
-            _eventoState = EventoConfirmadoState.GetInstance();
-          else if (EventoPublicadoState.GetInstance().GetDescripcion().Equals(value))
-            _eventoState = EventoPublicadoState.GetInstance();
-          else
-            throw new InvalidStateException(value);
-        }
-      }
-	  }
+	            return string.Empty;
+	        }
+	        set
+	        {
+	            if (value != Estado)
+	            {
+                    if (EventoPropuestoState.GetInstance().GetDescripcion().Equals(value))
+                        _eventoState = EventoPropuestoState.GetInstance();
+                    else if (EventoAgendadoState.GetInstance().GetDescripcion().Equals(value))
+                        _eventoState = EventoAgendadoState.GetInstance();
+                    else if (EventoConfirmadoState.GetInstance().GetDescripcion().Equals(value))
+                        _eventoState = EventoConfirmadoState.GetInstance();
+                    else if (EventoPublicadoState.GetInstance().GetDescripcion().Equals(value))
+                        _eventoState = EventoPublicadoState.GetInstance();
+                    else if (EventoCanceladoState.GetInstance().GetDescripcion().Equals(value))
+                        _eventoState = EventoCanceladoState.GetInstance();
+                    else if (EventoDescartadoState.GetInstance().GetDescripcion().Equals(value))
+                        _eventoState = EventoDescartadoState.GetInstance();
+                    else
+                        throw new InvalidStateException(value);
+	            }
+	        }
+	    }
 
-	  private EventoState _eventoState;
+	    private EventoState _eventoState;
 
 	  /// <summary>
     /// Obtiene una instancia de la clase que representa el estado del evento
@@ -112,40 +116,40 @@
 
 		#region Acciones sobre el evento
 
-	  /// <summary>
-	  /// Propone un evento
-	  /// </summary>
-	  /// <param name="titulo">Título del evento propuesto</param>
-	  /// <param name="persona">Ponente para evento propuesto</param>
-	  /// <param name="urlInvitacion">Url con la invitación realizada por el ponente</param>
-	  /// <param name="tipo">Tipo del evento</param>
-	  /// <returns></returns>
-	  public static Evento Proponer(string titulo, Persona persona, string urlInvitacion, TipoEvento tipo)
+	    /// <summary>
+	    /// Propone un evento
+	    /// </summary>
+	    /// <param name="titulo">Título del evento propuesto</param>
+	    /// <param name="persona">Ponente para evento propuesto</param>
+	    /// <param name="urlInvitacion">Url con la invitación realizada por el ponente</param>
+	    /// <param name="tipo">Tipo del evento</param>
+	    /// <returns></returns>
+	    public static Evento Proponer(string titulo, Persona persona, string urlInvitacion, TipoEvento tipo)
 		{
 			var evento = new Evento {Titulo = titulo, Ponente = persona, UrlInvitacion = urlInvitacion, Tipo = tipo};
-      evento.GetEstado().Promover(evento, Accion.Proponer);
+            evento.GetEstado().Promover(evento, Accion.Proponer);
 
 			return evento;
 		}
 
-	  /// <summary>
-	  /// Agenda un evento que no estaba propuesto
-	  /// </summary>
-	  /// <param name="titulo">Título del evento a agendar</param>
-	  /// <param name="persona">Ponente para el evento</param>
-	  /// <param name="fecha">Fecha de realización del evento</param>
-	  /// <param name="urlInvitacion">Url con la invitación realizada por el ponente</param>
-    /// <param name="tipo">Tipo del evento</param>
-    /// <returns></returns>
-	  public static Evento Agendar(string titulo, Persona persona, DateTime fecha, string urlInvitacion, TipoEvento tipo)
-	  {
-	    var evento = new Evento {Titulo = titulo, Tipo = tipo};
-      evento.Agendar(persona, fecha, urlInvitacion);
+	    /// <summary>
+	    /// Agenda un evento que no estaba propuesto
+	    /// </summary>
+	    /// <param name="titulo">Título del evento a agendar</param>
+	    /// <param name="persona">Ponente para el evento</param>
+	    /// <param name="fecha">Fecha de realización del evento</param>
+	    /// <param name="urlInvitacion">Url con la invitación realizada por el ponente</param>
+        /// <param name="tipo">Tipo del evento</param>
+        /// <returns></returns>
+        public static Evento Agendar(string titulo, Persona persona, DateTime fecha, string urlInvitacion, TipoEvento tipo)
+        {
+	        var evento = new Evento {Titulo = titulo, Tipo = tipo};
+	        evento.Agendar(persona, fecha, urlInvitacion);
 
-			return evento;
-		}
+	        return evento;
+        }
 
-		/// <summary>
+	    /// <summary>
 		/// Agenda el evento actual
 		/// </summary>
 		/// <param name="persona">Ponente para el evento</param>
@@ -156,7 +160,7 @@
 			Ponente = persona;
 			Fecha = fecha;
 			UrlInvitacion = urlInvitacion;
-      this.GetEstado().Promover(this, Accion.Agendar);
+            this.GetEstado().Promover(this, Accion.Agendar);
 		}
 
 		public virtual void Actualizar(Persona persona, DateTime? fecha, string urlInvitacion)
@@ -168,25 +172,44 @@
 			AddTrack(new Track(this, Accion.Modificar));
 		}
 
-		public virtual void CambiarTitulo(string titulo)
+        public virtual void CambiarTitulo(string titulo)
+        {
+            Titulo = titulo;
+            AddTrack(new Track(this, Accion.CambiarTitulo));
+        }
+
+	    public virtual void Confirmar()
 		{
-			Titulo = titulo;
-			AddTrack(new Track(this, Accion.CambiarTitulo));
+            this.GetEstado().Promover(this, Accion.Confirmar);
+		}
+
+        public virtual void Publicar(short numeroOrden, string urlWiki)
+        {
+            this.NumeroOrden = numeroOrden;
+            this.UrlWiki = urlWiki;
+            this.GetEstado().Promover(this, Accion.Publicar);
 		}
 
-		public virtual void Confirmar()
-		{
-      this.GetEstado().Promover(this, Accion.Confirmar);
-		}
+        public virtual void Cancelar()
+        {
+            GetEstado().Promover(this, Accion.Cancelar);
+        }
+
+        public virtual void Descartar()
+        {
+            GetEstado().Promover(this, Accion.Descartar);
+        }
 
-    public virtual void Publicar(short numeroOrden, string urlWiki)
-    {
-      this.NumeroOrden = numeroOrden;
-      this.UrlWiki = urlWiki;
-      this.GetEstado().Promover(this, Accion.Publicar);
-		}
+        public virtual void ReProponer()
+        {
+            GetEstado().Promover(this, Accion.ReProponer);
+        }
 
-		#endregion
+        public virtual void ReAgendar()
+        {
+            GetEstado().Promover(this, Accion.ReAgendar);
+        }
+	    #endregion
 
 		protected internal virtual void AddTrack(Track track)
 		{
@@ -194,9 +217,9 @@
 			_tracks.Add(track);
 		}
 
-		public virtual IEnumerable<Track> GetTrackNews()
-		{
-			return _newTracks;
-		}
+        public virtual IEnumerable<Track> GetTrackNews()
+        {
+            return _newTracks;
+        }
 	}
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Domain/EventoAgendadoState.cs	Sun Jul 10 23:55:56 2011 -0400
+++ b/Agendas/trunk/src/Agendas.Domain/EventoAgendadoState.cs	Sun Jul 10 23:59:19 2011 -0400
@@ -19,15 +19,19 @@
 
     public override void Promover(Evento evento, Accion accion)
     {
-      switch (accion)
-      {
-        case Accion.Confirmar:
-          evento.SetEstado(EventoConfirmadoState.GetInstance());
-          evento.AddTrack(new Track(evento, Accion.Confirmar));
-          break;
-        default:
-          throw new AccionNoSoportadaException(this.GetType(), accion);
-      }
+        switch (accion)
+        {
+            case Accion.Confirmar:
+                evento.SetEstado(EventoConfirmadoState.GetInstance());
+                evento.AddTrack(new Track(evento, Accion.Confirmar));
+                break;
+            case Accion.Cancelar:
+                evento.SetEstado(EventoCanceladoState.GetInstance());
+                evento.AddTrack(new Track(evento, Accion.Cancelar));
+                break;
+            default:
+                throw new AccionNoSoportadaException(this.GetType(), accion);
+        }
     }
 
     public override string GetDescripcion()
@@ -37,7 +41,7 @@
 
   	public override bool PuedePromover(Accion accion)
   	{
-		return accion == Accion.Confirmar;
+		return accion == Accion.Confirmar || accion == Accion.Cancelar;
   	}
   }
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Agendas/trunk/src/Agendas.Domain/EventoCanceladoState.cs	Sun Jul 10 23:59:19 2011 -0400
@@ -0,0 +1,51 @@
+using AltNetHispano.Agendas.Domain.Exceptions;
+
+namespace AltNetHispano.Agendas.Domain
+{
+    public class EventoCanceladoState : EventoState
+    {
+        private EventoCanceladoState()
+        {
+        }
+
+        private static readonly EventoState _instance = new EventoCanceladoState();
+
+        public static EventoState GetInstance()
+        {
+            return _instance;
+        }
+
+        private const string Descripcion = "Cancelado";
+
+        public override void Promover(Evento evento, Accion accion)
+        {
+            switch (accion)
+            {
+                case Accion.Descartar:
+                    evento.SetEstado(EventoDescartadoState.GetInstance());
+                    evento.AddTrack(new Track(evento, Accion.Descartar));
+                    break;
+                case Accion.ReAgendar:
+                    evento.SetEstado(EventoAgendadoState.GetInstance());
+                    evento.AddTrack(new Track(evento, Accion.ReAgendar));
+                    break;
+                case Accion.ReProponer:
+                    evento.SetEstado(EventoPropuestoState.GetInstance());
+                    evento.AddTrack(new Track(evento, Accion.ReProponer));
+                    break;
+                default:
+                    throw new AccionNoSoportadaException(this.GetType(), accion);
+            }
+        }
+
+        public override string GetDescripcion()
+        {
+            return Descripcion;
+        }
+
+        public override bool PuedePromover(Accion accion)
+        {
+            return accion == Accion.Descartar || accion == Accion.ReAgendar || accion == Accion.ReProponer;
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Agendas/trunk/src/Agendas.Domain/EventoDescartadoState.cs	Sun Jul 10 23:59:19 2011 -0400
@@ -0,0 +1,35 @@
+using AltNetHispano.Agendas.Domain.Exceptions;
+
+namespace AltNetHispano.Agendas.Domain
+{
+    public class EventoDescartadoState : EventoState
+    {
+        private EventoDescartadoState()
+        {
+        }
+
+        private static readonly EventoState _instance = new EventoDescartadoState();
+
+        public static EventoState GetInstance()
+        {
+            return _instance;
+        }
+
+        private const string Descripcion = "Descartado";
+
+        public override void Promover(Evento evento, Accion accion)
+        {
+            throw new AccionNoSoportadaException(this.GetType(), accion);
+        }
+
+        public override string GetDescripcion()
+        {
+            return Descripcion;
+        }
+
+        public override bool PuedePromover(Accion accion)
+        {
+            return false;
+        }
+    }
+}
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Domain/EventoPropuestoState.cs	Sun Jul 10 23:55:56 2011 -0400
+++ b/Agendas/trunk/src/Agendas.Domain/EventoPropuestoState.cs	Sun Jul 10 23:59:19 2011 -0400
@@ -19,15 +19,19 @@
 
     public override void Promover(Evento evento, Accion accion)
     {
-      switch (accion)
-      {
-        case Accion.Agendar:
-          evento.SetEstado(EventoAgendadoState.GetInstance());
-          evento.AddTrack(new Track(evento, Accion.Agendar));
-          break;
-        default:
-          throw new AccionNoSoportadaException(this.GetType(), accion);
-      }
+        switch (accion)
+        {
+            case Accion.Agendar:
+                evento.SetEstado(EventoAgendadoState.GetInstance());
+                evento.AddTrack(new Track(evento, Accion.Agendar));
+                break;
+            case Accion.Descartar:
+                evento.SetEstado(EventoDescartadoState.GetInstance());
+                evento.AddTrack(new Track(evento, Accion.Descartar));
+                break;
+            default:
+                throw new AccionNoSoportadaException(this.GetType(), accion);
+        }
     }
 
     public override string GetDescripcion()
@@ -37,7 +41,7 @@
 
   	public override bool PuedePromover(Accion accion)
   	{
-  		return accion == Accion.Agendar;
+  		return accion == Accion.Agendar || accion == Accion.Descartar;
   	}
   }
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Domain/Track.cs	Sun Jul 10 23:55:56 2011 -0400
+++ b/Agendas/trunk/src/Agendas.Domain/Track.cs	Sun Jul 10 23:59:19 2011 -0400
@@ -37,14 +37,17 @@
 		}
 	}
 
-	public enum Accion
-	{
-		Proponer = 1,
-		Agendar = 2,
-		Modificar = 3,
-		CambiarTitulo = 4,
-		Publicar = 5,
-		Confirmar = 6
-	}
-
+    public enum Accion
+    {
+        Proponer = 1,
+        Agendar = 2,
+        Modificar = 3,
+        CambiarTitulo = 4,
+        Publicar = 5,
+        Confirmar = 6,
+        Cancelar = 7,
+        Descartar = 8,
+        ReAgendar = 9,
+        ReProponer = 10
+    }
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Tests/AgendarTests.cs	Sun Jul 10 23:55:56 2011 -0400
+++ b/Agendas/trunk/src/Agendas.Tests/AgendarTests.cs	Sun Jul 10 23:59:19 2011 -0400
@@ -234,7 +234,42 @@
 			Assert.That(evento.GetTrackNews().Count(t => t.Accion == Accion.Agendar) == 1);
 		}
 
-		[Test]
+        [Test]
+        public void Al_cancelar_un_evento_debe_quedar_con_estado_EventoCanceladoState_y_debe_generar_el_track_correspondiente()
+        {
+            var publicador1 = new Mock<IPublicador>();
+
+            var agenda = new Agenda(publicador1.Object, DefaultEventoRepository, DefaultPersonaRepository);
+            agenda.Agendar("Html 5", "jjmontes", DateTime.MinValue, urlInvitacion, TipoEvento.Van);
+
+            var evento = DefaultEventoRepository.GetActivos().Single(e => e.Titulo == "Html 5");
+
+            agenda.Cancelar(evento.Id);
+
+            Assert.IsInstanceOf(typeof(EventoCanceladoState), evento.GetEstado());
+            Assert.That(evento.GetTrackNews().Count(t => t.Accion == Accion.Cancelar) == 1);
+            Assert.AreEqual(EventoCanceladoState.GetInstance().GetDescripcion(), evento.Estado);
+        }
+
+        [Test]
+        public void Al_descartar_un_evento_debe_quedar_con_estado_EventoDescartadoState_y_debe_generar_el_track_correspondiente()
+        {
+            var publicador1 = new Mock<IPublicador>();
+
+            var agenda = new Agenda(publicador1.Object, DefaultEventoRepository, DefaultPersonaRepository);
+            agenda.Agendar("Html 5", "jjmontes", DateTime.MinValue, urlInvitacion, TipoEvento.Van);
+
+            var evento = DefaultEventoRepository.GetActivos().Single(e => e.Titulo == "Html 5");
+
+            agenda.Cancelar(evento.Id);
+            agenda.Descartar(evento.Id);
+
+            Assert.IsInstanceOf(typeof(EventoDescartadoState), evento.GetEstado());
+            Assert.That(evento.GetTrackNews().Count(t => t.Accion == Accion.Descartar) == 1);
+            Assert.AreEqual(EventoDescartadoState.GetInstance().GetDescripcion(), evento.Estado);
+        }
+	    
+        [Test]
 		public void Al_confirmar_un_evento_debe_quedar_con_estado_EventoConfirmadoState_y_debe_generar_el_track_correspondiente()
 		{
 			var publicador1 = new Mock<IPublicador>();
--- a/Agendas/trunk/src/Agendas.Tests/Workflows/Workflow.cs	Sun Jul 10 23:55:56 2011 -0400
+++ b/Agendas/trunk/src/Agendas.Tests/Workflows/Workflow.cs	Sun Jul 10 23:59:19 2011 -0400
@@ -39,5 +39,29 @@
 			var resultado = _agenda.Publicar(eventoId, 0, string.Empty);
 			Assert.IsTrue(resultado.Succeful);
 		}
+
+	    public void Cancelar(Guid eventoId)
+	    {
+	        var resultado = _agenda.Cancelar(eventoId);
+            Assert.IsTrue(resultado.Succeful);
+	    }
+
+	    public void Descartar(Guid eventoId)
+	    {
+            var resultado = _agenda.Descartar(eventoId);
+            Assert.IsTrue(resultado.Succeful);
+	    }
+
+	    public void ReProponer(Guid eventoId)
+	    {
+	        var resultado = _agenda.ReProponer(eventoId);
+            Assert.IsTrue(resultado.Succeful);
+	    }
+
+        public void ReAgendar(Guid eventoId)
+        {
+            var resultado = _agenda.ReAgendar(eventoId);
+            Assert.IsTrue(resultado.Succeful);
+        }
 	}
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Tests/Workflows/WorkflowTests.cs	Sun Jul 10 23:55:56 2011 -0400
+++ b/Agendas/trunk/src/Agendas.Tests/Workflows/WorkflowTests.cs	Sun Jul 10 23:59:19 2011 -0400
@@ -35,8 +35,124 @@
 
 			_publicador.Verify(p => p.Publicar(It.IsAny<IEnumerable<Track>>()), Times.Exactly(2));
 		}
+        [Test]
+        public void Proponer_agendar_y_cancelar()
+        {
+            _workflow.Proponer();
 
-		[Test]
+            _workflow.Agendar();
+
+            var evento = DefaultEventoRepository.GetActivos().SingleOrDefault();
+            Assert.IsNotNull(evento);
+
+            _workflow.Cancelar(evento.Id);
+
+            _publicador.Verify(p=>p.Publicar(It.IsAny<IEnumerable<Track>>()), Times.Exactly(3));
+        }
+
+        [Test]
+        public void Proponer_agendar_cancelar_y_reagendar()
+        {
+            _workflow.Proponer();
+
+            _workflow.Agendar();
+
+            var evento = DefaultEventoRepository.GetActivos().SingleOrDefault();
+            Assert.IsNotNull(evento);
+
+            _workflow.Cancelar(evento.Id);
+
+            _workflow.ReAgendar(evento.Id);
+
+            _publicador.Verify(p => p.Publicar(It.IsAny<IEnumerable<Track>>()), Times.Exactly(4));
+        }
+
+        [Test, Explicit("Se esta discutiendo este problema en http://www.assembla.com/spaces/altnet-hispano/messages/768408")]
+        public void Proponer_agendar_cancelar_reproponer_agendar_y_confirmar()
+        {
+            _workflow.Proponer();
+
+            _workflow.Agendar();
+
+            var evento = DefaultEventoRepository.GetActivos().SingleOrDefault();
+            Assert.IsNotNull(evento);
+
+            _workflow.Cancelar(evento.Id);
+
+            _workflow.ReProponer(evento.Id);
+
+            _workflow.Agendar();
+
+            _workflow.Confirmar(evento.Id);
+
+            _publicador.Verify(p => p.Publicar(It.IsAny<IEnumerable<Track>>()), Times.Exactly(6));
+        }
+
+        [Test]
+        public void Proponer_agendar_cancelar_reagendar_y_confirmar()
+        {
+            _workflow.Proponer();
+
+            _workflow.Agendar();
+
+            var evento = DefaultEventoRepository.GetActivos().SingleOrDefault();
+            Assert.IsNotNull(evento);
+
+            _workflow.Cancelar(evento.Id);
+
+            _workflow.ReAgendar(evento.Id);
+
+            _workflow.Confirmar(evento.Id);
+
+            _publicador.Verify(p => p.Publicar(It.IsAny<IEnumerable<Track>>()), Times.Exactly(5));
+        }
+
+	    [Test]
+        public void Proponer_agendar_cancelar_y_reproponer()
+        {
+            _workflow.Proponer();
+
+            _workflow.Agendar();
+
+            var evento = DefaultEventoRepository.GetActivos().SingleOrDefault();
+            Assert.IsNotNull(evento);
+
+            _workflow.Cancelar(evento.Id);
+
+            _workflow.ReProponer(evento.Id);
+
+            _publicador.Verify(p => p.Publicar(It.IsAny<IEnumerable<Track>>()), Times.Exactly(4));
+        }
+
+        [Test]
+        public void Proponer_y_descartar()
+        {
+            _workflow.Proponer();
+            var evento = DefaultEventoRepository.GetActivos().SingleOrDefault();
+            Assert.IsNotNull(evento);
+
+            _workflow.Descartar(evento.Id);
+            _publicador.Verify(p => p.Publicar(It.IsAny<IEnumerable<Track>>()), Times.Exactly(2));
+        }
+
+	    [Test]
+        public void Proponer_agendar_cancelar_y_descartar()
+        {
+            _workflow.Proponer();
+
+            _workflow.Agendar();
+
+            var evento = DefaultEventoRepository.GetActivos().SingleOrDefault();
+            Assert.IsNotNull(evento);
+
+            _workflow.Cancelar(evento.Id);
+
+            _workflow.Descartar(evento.Id);
+
+            _publicador.Verify(p => p.Publicar(It.IsAny<IEnumerable<Track>>()), Times.Exactly(4));
+        }
+
+	    [Test]
 		public void Proponer_agendar_y_confirmar()
 		{
 			_workflow.Proponer();
--- a/Agendas/trunk/src/Agendas.Web/Controllers/EventoController.cs	Sun Jul 10 23:55:56 2011 -0400
+++ b/Agendas/trunk/src/Agendas.Web/Controllers/EventoController.cs	Sun Jul 10 23:59:19 2011 -0400
@@ -26,7 +26,11 @@
 			            		                         		PuedeAgendar = e.GetEstado().PuedePromover(Accion.Agendar),
 			            		                         		PuedeModificar = e.GetEstado().PuedePromover(Accion.Modificar),
 			            		                         		PuedeConfirmar = e.GetEstado().PuedePromover(Accion.Confirmar),
-			            		                         		PuedePublicar = e.GetEstado().PuedePromover(Accion.Publicar)
+			            		                         		PuedePublicar = e.GetEstado().PuedePromover(Accion.Publicar),
+                                                                PuedeCancelar = e.GetEstado().PuedePromover(Accion.Cancelar),
+                                                                PuedeDescartar = e.GetEstado().PuedePromover(Accion.Descartar),
+                                                                PuedeReAgendar = e.GetEstado().PuedePromover(Accion.ReAgendar),
+                                                                PuedeReProponer = e.GetEstado().PuedePromover(Accion.ReProponer)
 			            		                         	}
 			            	};
 			return View(model);
@@ -35,7 +39,8 @@
 		[Authorize]
 		public ActionResult Nuevo()
 		{
-			return View(new EventoNewModel());
+		    var eventoModel = new EventoNewModel {Fecha = DateTime.Now};
+		    return View(eventoModel);
 		}
 
 		[HttpPost]
@@ -171,6 +176,45 @@
 			}
 			return View(model);
 		}
+        
+        [Authorize]
+	    public ActionResult Cancelar(string id)
+	    {
+            var agenda = AgendaFactory.GetAgenda();
+            agenda.Cancelar(new Guid(id));
 
+            this.AddNotification("Evento cancelado");
+            return RedirectToAction("Index");
+	    }
+
+        [Authorize]
+	    public ActionResult Descartar(string id)
+	    {
+            var agenda = AgendaFactory.GetAgenda();
+            agenda.Descartar(new Guid(id));
+
+            this.AddNotification("Evento descartado");
+            return RedirectToAction("Index");
+	    }
+
+        [Authorize]
+	    public ActionResult ReAgendar(string id)
+	    {
+            var agenda = AgendaFactory.GetAgenda();
+            agenda.ReAgendar(new Guid(id));
+
+            this.AddNotification("Evento re-agendado");
+            return RedirectToAction("Index");
+	    }
+
+        [Authorize]
+	    public ActionResult ReProponer(string id)
+	    {
+            var agenda = AgendaFactory.GetAgenda();
+            agenda.ReProponer(new Guid(id));
+
+            this.AddNotification("Evento re-propuesto");
+            return RedirectToAction("Index");
+	    }
 	}
 }
--- a/Agendas/trunk/src/Agendas.Web/Models/EventoModel.cs	Sun Jul 10 23:55:56 2011 -0400
+++ b/Agendas/trunk/src/Agendas.Web/Models/EventoModel.cs	Sun Jul 10 23:59:19 2011 -0400
@@ -89,5 +89,9 @@
 		public bool PuedeModificar { get; set; }
 		public bool PuedeConfirmar { get; set; }
 		public bool PuedePublicar { get; set; }
+        public bool PuedeCancelar { get; set; }
+        public bool PuedeDescartar { get; set; }
+        public bool PuedeReAgendar { get; set; }
+        public bool PuedeReProponer { get; set; }
 	}
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Web/Views/Evento/Index.cshtml	Sun Jul 10 23:55:56 2011 -0400
+++ b/Agendas/trunk/src/Agendas.Web/Views/Evento/Index.cshtml	Sun Jul 10 23:59:19 2011 -0400
@@ -15,30 +15,54 @@
     <tbody>
         @foreach (var item in Model.ProximosEventos)
         {
-        <tr>
-            <td>@item.Fecha</td>
-            <td>@item.Titulo</td>
-            <td>@item.Estado</td>
-            <td>
-				@if (item.PuedeAgendar)
-	{
-					@Html.ActionLink("Agendar", "Agendar", "Evento", new { id = item.Id }, null)
-	}
-				@if (item.PuedeModificar)
-	{
-					@Html.ActionLink("Modificar", "Modificar", new { id = item.Id })
-	}
-				@if (item.PuedeConfirmar)
-	{
-					@Html.ActionLink("Confirmar", "Confirmar", new { id = item.Id })
-	}
-				@if (item.PuedePublicar)
-	{
-					@Html.ActionLink("Publicar", "Publicar", new { id = item.Id })
-	}
-			</td>
-        </tr>
-		}
+            <tr>
+                <td>@item.Fecha</td>
+                <td>@item.Titulo</td>
+                <td>@item.Estado</td>
+                <td>
+                    @if (item.PuedeAgendar)
+                    {
+                        @Html.ActionLink("Agendar", "Agendar", "Evento", new {id = item.Id}, null)
+                        <span>&nbsp;</span>
+                    }
+                    @if (item.PuedeModificar)
+                    {
+                        @Html.ActionLink("Modificar", "Modificar", new { id = item.Id })
+                        <span>&nbsp;</span>
+                    }
+                    @if (item.PuedeConfirmar)
+                    {
+                        @Html.ActionLink("Confirmar", "Confirmar", new { id = item.Id })
+                        <span>&nbsp;</span>
+                    }
+                    @if (item.PuedePublicar)
+                    {
+                        @Html.ActionLink("Publicar", "Publicar", new { id = item.Id })
+                        <span>&nbsp;</span>
+                    }
+                    @if (item.PuedeCancelar)
+                    {
+                        @Html.ActionLink("Cancelar", "Cancelar", new { id = item.Id })
+                        <span>&nbsp;</span>
+                    }
+                    @if (item.PuedeDescartar)
+                    {
+                        @Html.ActionLink("Descartar", "Descartar", new { id = item.Id })
+                        <span>&nbsp;</span>
+                    }
+                    @if (item.PuedeReAgendar)
+                    {
+                        @Html.ActionLink("Re-Agendar", "ReAgendar", new { id = item.Id })
+                        <span>&nbsp;</span>
+                    }
+                    @if (item.PuedeReProponer)
+                    {
+                        @Html.ActionLink("Re-Proponer", "ReProponer", new { id = item.Id })
+                        <span>&nbsp;</span>
+                    }
+                </td>
+            </tr>
+        }
     </tbody>
 </table>