Skip to content

Instantly share code, notes, and snippets.

@diegodfsd
Last active January 18, 2019 14:40
Show Gist options
  • Save diegodfsd/53c87874a0e76b1e245dd1e648cdc2a0 to your computer and use it in GitHub Desktop.
Save diegodfsd/53c87874a0e76b1e245dd1e648cdc2a0 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Xgen.Common.Extensions;
using Xgen.Common.Utils;
using Xgen.Domain.Common;
using Xgen.Domain.Common.Exceptions;
using Xgen.Domain.Model.Social.Events;
using Xgen.Domain.Model.Social.Exceptions;
namespace Xgen.Domain.Model.Social
{
public class Meeting : Entity<Meeting>, IAggregateRoot, ISociable, ILoggable
{
#region Private Members
private readonly ICollection<MeetingAttendee> _attendees = new Collection<MeetingAttendee>();
private readonly ICollection<MeetingAccessGroup> _groups = new Collection<MeetingAccessGroup>();
#endregion
#region Properties
public int TenantId { get; protected set; }
public string Title { get; protected set; }
public string Summary { get; protected set; }
public string Description { get; protected set; }
public string Slug { get; protected set; }
public MeetingType Type { get; protected set; }
public string Location { get; protected set; }
public string Image { get; protected set; }
public DateTime StartsOn { get; protected set; }
public bool IsPublic { get; protected set; }
public ObjectId ObjectId { get; protected set; }
public ObjectType ObjectType => ObjectType.Event;
public bool CommentsRequiresApproval { get; protected set; }
public bool CommentsAllowed { get; protected set; }
public bool LikesAllowed { get; protected set; }
public MeetingStatus Status { get; protected set; }
public MeetingUser PublishedBy { get; protected set; }
public DateTime? PublishedAt { get; protected set; }
public Period ScheduledPublicationDate { get; protected set; }
public virtual ICollection<MeetingAttendee> Attendees => _attendees;
public virtual ICollection<MeetingAccessGroup> Groups => _groups;
public int TotalParticipants { get; protected set; }
public Quantity TotalComments => Quantity.Get(AmountComments);
public Quantity TotalLikes => Quantity.Get(AmountLikes);
public ApplicationModules ModuleName => ApplicationModules.Social;
public string EntityName => "Evento";
//Criadas propriedades privadas porque o EF não estava aceitando
//que o mapeamento tenha duas propriedades Quantity
private int AmountComments { get; set; }
private int AmountLikes { get; set; }
#endregion
#region Constructors
/// <summary>
/// EF
/// </summary>
protected Meeting()
{
ObjectId = ObjectId.Create();
Status = MeetingStatus.Inactive;
}
private Meeting(int tenantId, string title, string description, MeetingType type, DateTime startsOn, string location, string summary = null, string image = null,
bool isPublic = true, bool commentsRequiresApproval = false, bool commentsAllowed = true, bool likesAllowed = true, Period scheduledPublicationDate = null, MeetingStatus status = MeetingStatus.Inactive)
: this()
{
Ensure.Arg.NotEmpty(title, nameof(title));
Ensure.Arg.NotEmpty(description, nameof(description));
Ensure.Arg.NotEmpty(location, nameof(location));
TenantId = tenantId;
Title = title;
Summary = summary;
Description = description;
Slug = title.Slugify();
Type = type;
Status = status;
StartsOn = startsOn;
Location = location;
Image = image;
IsPublic = isPublic;
CommentsRequiresApproval = commentsRequiresApproval;
CommentsAllowed = commentsAllowed;
LikesAllowed = likesAllowed;
ScheduledPublicationDate = scheduledPublicationDate ?? Period.Empty;
}
#endregion
#region Factory
public static Meeting Create(int tenantId, string title, string description, MeetingType type, DateTime startsOn, string location, string summary = null, string image = null,
bool isPublic = true, bool commentsRequiresApproval = false, bool commentsAllowed = true, bool likesAllowed = true, Period scheduledPublicationDate = null)
{
var @event = new Meeting(tenantId, title, description, type, startsOn, location, summary, image, isPublic,
commentsRequiresApproval, commentsAllowed, likesAllowed, scheduledPublicationDate);
return @event;
}
#endregion
#region Public Methods
public void ChangeDefinition(string title, string description, MeetingType type, DateTime startsOn, string location, string summary = null)
{
Ensure.Arg.NotEmpty(title, nameof(title));
Ensure.Arg.NotEmpty(description, nameof(description));
Ensure.Arg.NotEmpty(location, nameof(location));
Title = title;
Slug = title.Slugify();
Description = description;
Type = type;
StartsOn = startsOn;
Location = location;
Summary = summary;
}
public void ChangeImage(string image)
{
Image = image;
}
public void MakePublic()
{
Ensure.Not<CannotBecomeAPublicEventAsThereAreGroupsException>(!IsPublic && Groups.Any());
IsPublic = true;
}
public void MakePrivate()
{
Ensure.Not<CannotBecomeAPrivateEventAsThereAreParticipantsException>(IsPublic && Attendees.Any());
IsPublic = false;
}
public void SchedulePublicationFor(Period period)
{
ScheduledPublicationDate = period ?? Period.Empty;
}
public void AllowComments(bool allow, bool requiresApproval)
{
CommentsAllowed = allow;
CommentsRequiresApproval = requiresApproval;
}
public void AllowLikes(bool allow)
{
LikesAllowed = allow;
}
public void Cancel()
{
Ensure.Not<CannotChangeStatusOfADeletedEntityException>(Status == MeetingStatus.Deleted);
Status = MeetingStatus.Canceled;
}
public void Delete()
{
Status = MeetingStatus.Deleted;
}
public void Inactive()
{
Ensure.Not<CannotChangeStatusOfADeletedEntityException>(Status == MeetingStatus.Deleted);
Status = MeetingStatus.Inactive;
}
public void Publish(MeetingUser publisher)
{
Ensure.Not<CannotChangeStatusOfADeletedEntityException>(Status == MeetingStatus.Deleted);
if (Status != MeetingStatus.Active)
{
PublishedBy = publisher;
PublishedAt = DateTime.Now;
Status = MeetingStatus.Active;
}
}
/// <summary>
/// Add an user from attendees list
/// </summary>
/// <param name="user">An <see cref="MeetingUser"/> instance</param>
public void AddAttendee(MeetingUser user)
{
Ensure.Arg.NotNull(user, nameof(user));
Ensure.Not<OnlyAuthorizedUsersCanRegisterInAPrivateEventException>(!IsPublic && !Groups.Any(user.HasATeam));
if (!_attendees.Any(_ => _.User.Equals(user)))
{
_attendees.Add(new MeetingAttendee(user, this));
RaiseEvent(new AddedMeetingAttendeeEvent(ObjectId));
}
}
/// <summary>
/// Remove an user from attendees list
/// </summary>
/// <param name="user">An <see cref="MeetingUser"/> instance</param>
/// <returns>Returns success or failure</returns>
public MeetingAttendee RemoveAttendee(MeetingUser user)
{
Ensure.Arg.NotNull(user, nameof(user));
var attendee = _attendees.FirstOrDefault(_ => _.User.Equals(user));
if (attendee.IsNotNull())
{
RaiseEvent(new RemovedMeetingAttendeeEvent(ObjectId));
_attendees.Remove(attendee);
return attendee;
}
return default(MeetingAttendee);
}
public void GrantAccessTo(MeetingAccessGroup @group)
{
Ensure.Arg.NotNull(@group, nameof(@group));
Ensure.Not<OnlyPrivateMeetingCanHaveGroupsException>(IsPublic);
if (!_groups.Any(@group.Equals))
_groups.Add(@group);
}
public bool RevokeAccessTo(MeetingAccessGroup @group)
{
Ensure.Arg.NotNull(@group, nameof(@group));
return _groups.Any(@group.Equals) && _groups.Remove(@group);
}
public void FixSlug(string sufix, bool titleWasChanged)
{
if (sufix.IsNotEmpty() && titleWasChanged)
{
Slug = $"{Slug}-{sufix}";
}
}
#endregion
#region Internal Methods
internal void UpdateNumberOfAttendees(int count)
{
TotalParticipants = count;
}
internal void SetTotalComments(Quantity quantity)
{
if (quantity < 0)
throw new ValueShouldBeAPositiveValueException();
AmountComments = quantity;
}
internal void SetTotalLikes(Quantity quantity)
{
if (quantity < 0)
throw new ValueShouldBeAPositiveValueException();
AmountLikes = quantity;
}
#endregion
#region Comparison Methods
public override int GetIdentityHashCode()
{
return Slug.GetHashCode();
}
public override bool SameIdentityAs(Meeting other)
{
return other != null && Slug.Equals(other.Slug);
}
public override string ToString()
{
return $"{Title}, {Type}";
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment