297 lines
12 KiB
C#
297 lines
12 KiB
C#
namespace Modules.Library.Domain.Entities.MediaContent.CommonProperties;
|
|
|
|
public class CommonProperties : ValueObject
|
|
{
|
|
private readonly List<NameItem> _names = [];
|
|
public IReadOnlyCollection<NameItem> Names => _names.AsReadOnly();
|
|
public MediaInfo? Preview { get; private set; }
|
|
|
|
private readonly List<Description> _descriptions = [];
|
|
public IReadOnlyCollection<Description> Descriptions => _descriptions.AsReadOnly();
|
|
|
|
private readonly List<GenreProportion> _genres = [];
|
|
public IReadOnlyCollection<GenreProportion> Genres => _genres.AsReadOnly();
|
|
|
|
private readonly List<MediaInfo> _relatedContent = [];
|
|
public IReadOnlyCollection<MediaInfo> RelatedContent => _relatedContent.AsReadOnly();
|
|
|
|
|
|
public DateTimeOffset? AnnouncementDate { get; private set; }
|
|
public DateTimeOffset? EstimatedReleaseDate { get; private set; }
|
|
public DateTimeOffset? ReleaseDate { get; private set; }
|
|
|
|
internal CommonProperties() { }
|
|
private CommonProperties(Models.CommonProperties commonProperties)
|
|
{
|
|
Preview = commonProperties.Preview != null
|
|
? new MediaInfo(commonProperties.Preview.ObjectId, commonProperties.Preview.Type, commonProperties.Preview.ContentType)
|
|
: null;
|
|
AnnouncementDate = commonProperties.AnnouncementDate;
|
|
EstimatedReleaseDate = commonProperties.EstimatedReleaseDate;
|
|
ReleaseDate = commonProperties.ReleaseDate;
|
|
_names.AddRange(commonProperties.Names.Select(NameItem.New));
|
|
_descriptions.AddRange(commonProperties.Descriptions.Select(Description.New));
|
|
_genres.AddRange(commonProperties.Genres.Select(GenreProportion.New));
|
|
_relatedContent.AddRange(commonProperties.RelatedContent.Select(q => new MediaInfo(q.ObjectId, q.Type, q.ContentType)));
|
|
}
|
|
|
|
internal CommonProperties(IEnumerable<NameItem> names)
|
|
{
|
|
foreach (var name in names)
|
|
{
|
|
AddName(name.Type, name.LanguageId, name.Value);
|
|
}
|
|
}
|
|
|
|
internal static CommonProperties New(Models.CommonProperties commonProperties) => new(commonProperties);
|
|
|
|
#region Name
|
|
public void AddName(NameType nameType, Guid languageId, string value)
|
|
{
|
|
switch (nameType)
|
|
{
|
|
case NameType.Original:
|
|
AddNameOriginal(languageId, value);
|
|
break;
|
|
case NameType.OriginalInAnotherLanguage:
|
|
AddNameOriginalInAnotherLanguage(languageId, value);
|
|
break;
|
|
case NameType.Translation:
|
|
AddNameTranslation(languageId, value);
|
|
break;
|
|
case NameType.Abbreviation:
|
|
AddNameAbbreviation(languageId, value);
|
|
break;
|
|
default:
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
private void AddNameOriginal(Guid languageId, string value)
|
|
{
|
|
if (_names.Any(q => q.Type == NameType.Original)) throw new Exception("Original name is already exist.");
|
|
var name = new NameItem(languageId, NameType.Original, value);
|
|
_names.Add(name);
|
|
}
|
|
|
|
private void AddNameOriginalInAnotherLanguage(Guid languageId, string value)
|
|
{
|
|
if (_names.FirstOrDefault(q => q.Type == NameType.Original)?.LanguageId == languageId)
|
|
throw new Exception("Language must not match original name language");
|
|
|
|
if (_names.Any(q => q.Type == NameType.OriginalInAnotherLanguage && q.LanguageId == languageId))
|
|
throw new Exception("Name in following language is already exist.");
|
|
|
|
var name = new NameItem(languageId, NameType.OriginalInAnotherLanguage, value);
|
|
_names.Add(name);
|
|
}
|
|
|
|
private void AddNameTranslation(Guid languageId, string value)
|
|
{
|
|
var name = new NameItem(languageId, NameType.Translation, value);
|
|
_names.Add(name);
|
|
}
|
|
|
|
private void AddNameAbbreviation(Guid languageId, string value)
|
|
{
|
|
var name = new NameItem(languageId, NameType.Abbreviation, value);
|
|
_names.Add(name);
|
|
}
|
|
|
|
public void RemoveName(NameItem nameItem)
|
|
{
|
|
var name = GetName(nameItem);
|
|
if (name.Type == NameType.Original) throw new Exception($"Unable to remove original name");
|
|
_names.Remove(name);
|
|
}
|
|
|
|
public void SetNameValue(NameItem nameItem, Guid? languageId, string? value)
|
|
{
|
|
var name = GetName(nameItem);
|
|
var newValue = value?.Trim();
|
|
if (string.IsNullOrWhiteSpace(newValue)) throw new ArgumentNullException(nameof(value));
|
|
if (nameItem.Type != NameType.Original && _names.Any(q => q.LanguageId == (languageId ?? nameItem.LanguageId) && q.Value == (newValue ?? nameItem.Value)))
|
|
throw new Exception("Name item with same language and same value is already exists");
|
|
else if (nameItem.Type == NameType.Original && languageId.HasValue && _names.Any(q => q.LanguageId == languageId && q.Type == NameType.OriginalInAnotherLanguage))
|
|
throw new Exception("Could not change original name language to one of \"original in another language\" item's one");
|
|
if (languageId.HasValue) name.SetLanguage(languageId.Value);
|
|
if (!string.IsNullOrWhiteSpace(newValue)) name.SetValue(newValue);
|
|
}
|
|
|
|
private NameItem GetName(NameItem name) => _names.FirstOrDefault(q => q == name) ??
|
|
throw new Exception($"Name with is not found");
|
|
#endregion
|
|
|
|
public void SetPreview(string objectId, MediaInfoType type, string contentType)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(objectId)) throw new ArgumentNullException(nameof(objectId));
|
|
Preview ??= new MediaInfo(objectId, type, contentType);
|
|
Preview.SetObjectId(objectId);
|
|
Preview.SetType(type);
|
|
Preview.SetContentType(contentType);
|
|
}
|
|
public void DeletePreview() => Preview = null;
|
|
|
|
#region Description
|
|
public void AddOriginalDescription(Guid languageId, string value)
|
|
{
|
|
if (_descriptions.Any(q => q.IsOriginal)) throw new Exception("Original description is already exist.");
|
|
var description = new Description(languageId, true, value);
|
|
_descriptions.Add(description);
|
|
}
|
|
|
|
public void AddNotOriginalDescription(Guid languageId, string value)
|
|
{
|
|
var description = new Description(languageId, false, value);
|
|
_descriptions.Add(description);
|
|
}
|
|
|
|
public void RemoveDescription(Description descriptionItem)
|
|
{
|
|
var description = GetDescription(descriptionItem);
|
|
if (description.IsOriginal) throw new Exception($"Unable to remove original description");
|
|
_descriptions.Remove(description); //TODO: valueobject convert
|
|
//description.SetDeleted();
|
|
}
|
|
|
|
public void SetDescriptionValue(Description descriptionItem, Guid? languageId, string? value)
|
|
{
|
|
var description = GetDescription(descriptionItem);
|
|
var newValue = value?.Trim();
|
|
if (string.IsNullOrWhiteSpace(newValue)) throw new ArgumentNullException(nameof(value));
|
|
if (!descriptionItem.IsOriginal && _descriptions.Any(q => q.LanguageId == (languageId ?? descriptionItem.LanguageId) && q.Value == (newValue ?? descriptionItem.Value)))
|
|
throw new Exception("Descriptoin item with with same value is already exists");
|
|
if (languageId.HasValue) descriptionItem.SetLanguage(languageId.Value);
|
|
if (!string.IsNullOrWhiteSpace(newValue)) descriptionItem.SetValue(newValue);
|
|
}
|
|
|
|
private Description GetDescription(Description description)
|
|
{
|
|
return _descriptions.FirstOrDefault(q => q == description) ??
|
|
throw new Exception($"Description is not found");
|
|
}
|
|
#endregion
|
|
|
|
#region Genre
|
|
public void AddGenre(Guid genreId, decimal? proportion = null)
|
|
{
|
|
if (_genres.Any(q => q.GenreId == genreId)) throw new Exception("Genre is already in the list");
|
|
var genreProportionItem = new GenreProportion(genreId, proportion);
|
|
_genres.Add(genreProportionItem);
|
|
if (proportion.HasValue) genreProportionItem.SetProportion(proportion);
|
|
}
|
|
|
|
public void SetGenreProportion(Guid genreId, decimal? value = null)
|
|
{
|
|
var genreProportion = GetGenreProportionItem(genreId);
|
|
genreProportion.SetProportion(value);
|
|
}
|
|
|
|
public void RemoveGenre(Guid genreId)
|
|
{
|
|
var genreProportion = GetGenreProportionItem(genreId);
|
|
_genres.Remove(genreProportion);
|
|
}
|
|
|
|
private GenreProportion GetGenreProportionItem(Guid genreId)
|
|
{
|
|
return _genres.FirstOrDefault(q => q.GenreId == genreId) ??
|
|
throw new Exception($"Genre proportion is not found");
|
|
}
|
|
/*
|
|
private GenreProportion GetGenreProportionItem(GenreProportion genreProportionItem)
|
|
{
|
|
return _genres.FirstOrDefault(q => q == genreProportionItem) ??
|
|
throw new Exception($"Genre proportion is not found");
|
|
}
|
|
*/
|
|
#endregion
|
|
|
|
#region RelatedContent
|
|
|
|
public void AddRelatedContent(string objectId, MediaInfoType type, string contentType)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(objectId)) throw new ArgumentNullException(nameof(objectId));
|
|
CheckIfCanAddOrEdit(objectId, type);
|
|
_relatedContent.Add(new MediaInfo(objectId, type, contentType));
|
|
}
|
|
|
|
public void EditRelatedContent(MediaInfo relatedContentItem, string? objectId, MediaInfoType? type, string? contentType)
|
|
{
|
|
var relatedContent = GetRelatedContent(relatedContentItem);
|
|
CheckIfCanAddOrEdit(objectId, type);
|
|
if (!string.IsNullOrWhiteSpace(objectId)) relatedContent.SetObjectId(objectId);
|
|
if (type.HasValue) relatedContent.SetType(type.Value);
|
|
if (!string.IsNullOrWhiteSpace(contentType)) relatedContent.SetContentType(contentType);
|
|
}
|
|
|
|
public void RemoveRelatedContent(MediaInfo relatedContentItem)
|
|
{
|
|
var relatedContent = GetRelatedContent(relatedContentItem);
|
|
_relatedContent.Remove(relatedContent); //TODO: valueobject convert
|
|
}
|
|
|
|
private void CheckIfCanAddOrEdit(string? objectId, MediaInfoType? type)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(objectId) && !type.HasValue) return;
|
|
var query = _relatedContent.AsQueryable();
|
|
if (!string.IsNullOrWhiteSpace(objectId)) query = query.Where(q => q.ObjectId == objectId);
|
|
if (type.HasValue) query = query.Where(q => q.Type == type);
|
|
if (query.Any()) throw new Exception("Related content with same url and same type is already exists");
|
|
}
|
|
|
|
|
|
private MediaInfo GetRelatedContent(MediaInfo relatedContentItem)
|
|
{
|
|
return _relatedContent.FirstOrDefault(q => q == relatedContentItem) ??
|
|
throw new Exception($"Related content is not found");
|
|
}
|
|
#endregion
|
|
|
|
|
|
public void SetAnnouncementDate(DateTimeOffset? value)
|
|
{
|
|
AnnouncementDate = value;
|
|
}
|
|
|
|
public void SetEstimatedReleaseDate(DateTimeOffset? value)
|
|
{
|
|
//if (value == default) throw new ArgumentNullException(nameof(value));
|
|
if (value.HasValue && value.Value == default) throw new ArgumentOutOfRangeException(nameof(value));
|
|
if (AnnouncementDate.HasValue && value <= AnnouncementDate.Value)
|
|
throw new Exception("Estimated release date can not be less or equal to announcement date");
|
|
EstimatedReleaseDate = value;
|
|
}
|
|
public void SetReleaseDate(DateTimeOffset? value)
|
|
{
|
|
if (value.HasValue && value.Value == default) throw new ArgumentOutOfRangeException(nameof(value));
|
|
if (AnnouncementDate.HasValue && value <= AnnouncementDate.Value)
|
|
throw new Exception("Release date can not be less or equal to announcement date");
|
|
ReleaseDate = value;
|
|
}
|
|
|
|
protected override IEnumerable<object?> GetEqualityComponents()
|
|
{
|
|
foreach (var name in _names)
|
|
{
|
|
yield return name;
|
|
}
|
|
yield return Preview;
|
|
foreach (var descriptions in _descriptions)
|
|
{
|
|
yield return descriptions;
|
|
}
|
|
foreach (var genre in _genres)
|
|
{
|
|
yield return genre;
|
|
}
|
|
foreach (var relatedContent in _relatedContent)
|
|
{
|
|
yield return relatedContent;
|
|
}
|
|
yield return AnnouncementDate;
|
|
yield return EstimatedReleaseDate;
|
|
yield return ReleaseDate;
|
|
}
|
|
}
|