Files
xCategoryService/Providers/XCategoryProvider.cs
T
2026-06-10 09:31:49 +03:30

485 lines
15 KiB
C#

using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using xCategoryService.Interfaces;
using xCategoryService.Interfaces.Dtos;
using xCategoryService.Models.Dtos;
using xCategoryService.Models.Entities;
using xCategoryService.Providers.Dtos;
using xCommons.Configurations;
using xCommons.Extensions;
using xExceptions.Constants;
using xIdentityModels.Models;
using xModels.Dtos;
using xPushService.Constants;
using xPushService.Providers;
namespace xCategoryService.Providers
{
public class XCategoryProvider : XBaseProvided<XCategory, XCategoryDto, int, XCategoryDtoHub>, IXCategoryProvider
{
private readonly IXCategoryServiceProvider provider;
private readonly XAppConfiguration appConfiguration;
private readonly IXCategoryTitleResourceProvider titleResourceProvider;
private readonly IXCategoryDescriptionResourceProvider descriptionResourceProvider;
public XCategoryProvider(
XAppConfiguration appConfiguration,
IXCategoryServiceProvider provider,
IXCategoryTitleResourceProvider titleResourceProvider,
IXCategoryDescriptionResourceProvider descriptionResourceProvider
) : base(
provider,
permittedRoles: new string[] { }
)
{
//
this.provider = provider;
this.appConfiguration = appConfiguration;
this.titleResourceProvider = titleResourceProvider;
this.descriptionResourceProvider = descriptionResourceProvider;
}
public override bool IsOwned(
XCategoryDto item,
XUserClaimsInfoDto userInfo
)
{
return !item.IsNullOrDefault();
}
public override bool IsOwned(
XCategory item,
XUserClaimsInfoDto userInfo
)
{
return !item.IsNullOrDefault();
}
/// <summary>
/// Check a Category Has Specified Locale or not ...
/// </summary>
/// <param name="id"></param>
/// <param name="language"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<bool> HasLocale(
int id,
string language,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
var isValid =
id.IsValidIntId() &&
!language.IsNullOrEmpty();
if (isValid)
{
XException.InvalidArgs.Throw();
}
//
// Retrieve Resource ...
var resource = await GetResource(
id: id,
cancellationToken: cancellationToken
);
//
// Check Result ...
var result =
!resource.IsNullOrDefault() &&
resource.Titles.Locales
.Any(x => x.Language
.Equals(language, System.StringComparison.InvariantCultureIgnoreCase)) &&
resource.Descriptions.Locales
.Any(x => x.Language
.Equals(language, System.StringComparison.InvariantCultureIgnoreCase));
//
return result;
}
/// <summary>
/// Load an Item by all of it's Related Translations ...
/// </summary>
/// <param name="id"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XCategoryResourceDto> GetResource(
int id,
CancellationToken cancellationToken = default
)
{
//
var category = await Get(
id: id,
includeBuilder: null,
cancellationToken: cancellationToken
);
var titleResource = await titleResourceProvider.GetResource(
identifier: id,
cancellationToken: cancellationToken
);
var descriptionResource = await titleResourceProvider.GetResource(
identifier: id,
cancellationToken: cancellationToken
);
//
var result = new XCategoryResourceDto
{
Item = category,
Titles = titleResource,
Descriptions = descriptionResource
};
//
return result;
}
/// <summary>
/// Add Category Item for Specified Language ...
/// </summary>
/// <param name="item"></param>
/// <param name="langauge"></param>
/// <param name="connectionId"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XCategoryResourceDto> Add(
XCategoryDto item,
string langauge = null,
string connectionId = null,
XUserClaimsInfoDto userInfo = null,
CancellationToken cancellationToken = default
)
{
//
// Normalize ...
langauge =
!langauge.IsNullOrEmpty()
? langauge
: appConfiguration.DefaultLanguage;
//
// Validate ...
var isValid = !item.IsNullOrDefault();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
var id = -1;
try
{
//
var title = item.Title;
var description = item.Description;
//
// Add Item Pure for ID Generating ...
item = await base.Add(
item: item,
userInfo: userInfo,
connectionId: null, // Since here We dont want notification ...
cancellationToken: cancellationToken
);
isValid = !item.IsNullOrDefault();
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
id = item.Id;
var titleResource = await titleResourceProvider
.AddOrUpdateLocale(
identifier: id,
locale: new XLocaleResourceDto
{
Value = title,
Language = langauge
},
connectionId: connectionId,
cancellationToken: cancellationToken
);
var descriptionResource = await descriptionResourceProvider
.AddOrUpdateLocale(
identifier: id,
locale: new XLocaleResourceDto
{
Value = description,
Language = langauge
},
connectionId: connectionId,
cancellationToken: cancellationToken
);
//
// Update Category Dto ...
item.Title = titleResource.Resource;
item.Description = descriptionResource.Resource;
item = await base.Update(
id: id,
item: item,
userInfo: userInfo,
connectionId: null,
cancellationToken: cancellationToken
);
}
catch
{
XException.InvalidArgs.Throw();
}
//
// Validate Id ...
isValid = id.IsValidIntId();
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
// Retrieve Category Resourv=ce ...
var result = await GetResource(
id: id,
cancellationToken: cancellationToken
);
//
// Sending Push Notification ...
isValid =
isValid &&
!result.IsNullOrDefault();
if (isValid)
{
//
await provider.SendPush(
connectionId: connectionId,
cancellationToken: cancellationToken,
payLoad: result.ToJSON(camelCase: true),
action: XBaseEntityHubAction.Add.GetStringValue()
);
}
//
return result;
}
/// <summary>
/// Update a Category Item for Specified Language ...
/// </summary>
/// <param name="id"></param>
/// <param name="item"></param>
/// <param name="language"></param>
/// <param name="connectionId"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XCategoryResourceDto> Update(
int id,
XCategoryDto item,
string language = null,
string connectionId = null,
XUserClaimsInfoDto userInfo = null,
CancellationToken cancellationToken = default
)
{
//
// Validate ...
var isValid =
id.IsValidIntId() &&
!item.IsNullOrDefault() &&
!language.IsNullOrEmpty() &&
!item.Title.IsNullOrEmpty();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
// Check Category Exists ...
isValid = await IsExists(
id: id,
cancellationToken: cancellationToken
);
if (!isValid)
{
XException.NotFound.Throw();
}
//
// Check Locale Exists ...
isValid = await HasLocale(
id: id,
language: language,
cancellationToken: cancellationToken
);
if (!isValid)
{
XException.NotFound.Throw();
}
//
// Retrieve Category Dto for Validate Owining ...
var dto = await Get(
id: id,
includeBuilder: null,
cancellationToken: cancellationToken
);
//
// Check Permission ...
isValid =
!dto.IsNullOrDefault() &&
!userInfo.IsNullOrDefault() &&
IsOwned(
item: dto,
userInfo: userInfo
);
if (!isValid)
{
XException.NotAllowed.Throw();
}
//
// Retrieve Exists Item Resource ...
var resource = await GetResource(
id: id,
cancellationToken: cancellationToken
);
//
var titleUpdated = false;
var descriptionUpdated = false;
//
// Update Title ...
resource.Titles.Locales
.ToList()
.ForEach(tl =>
{
//
if (tl.Language.Equals(language, System.StringComparison.InvariantCultureIgnoreCase))
{
//
titleUpdated = true;
tl.Value = item.Title;
}
});
//
// Update Description ...
resource.Descriptions.Locales
.ToList()
.ForEach(dl =>
{
//
if (dl.Language.Equals(language, System.StringComparison.InvariantCultureIgnoreCase))
{
//
descriptionUpdated = true;
dl.Value = item.Description;
}
});
//
// Validate Title and Description Updated ...
isValid = titleUpdated && descriptionUpdated;
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
resource = await RefereshResource(
resource: resource,
userInfo: userInfo,
connectionId: connectionId,
cancellationToken: cancellationToken
);
//
return resource;
}
/// <summary>
/// Referesh a Resource ...
/// </summary>
/// <param name="resource"></param>
/// <param name="connectionId"></param>
/// <param name="userInfo"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<XCategoryResourceDto> RefereshResource(
XCategoryResourceDto resource,
string connectionId = null,
XUserClaimsInfoDto userInfo = null,
CancellationToken cancellationToken = default
)
{
//
// Validate Args ...
var isValid =
!resource.IsNull() &&
!resource.Item.IsNullOrDefault();
if (!isValid)
{
XException.InvalidArgs.Throw();
}
//
var id = -1;
//
// Check Item Exists ...
XCategoryDto dto =
!resource.Item.Id.IsValidIntId()
? null
: await Get(
id: resource.Item.Id,
includeBuilder: null,
cancellationToken: cancellationToken
);
var isExists = !dto.IsNullOrDefault();
//
// Do Referesh Based on Existance ...
var isNew =
!isExists &&
!resource.Item.Id.IsValidIntId();
if (isNew)
{
//
// Add ...
}
else if (isExists)
{
//
// Re State ...
id = resource.Item.Id;
}
//
isValid = id.IsValidIntId();
if (!isValid)
{
XException.ActionFailed.Throw();
}
//
// Get Result ...
var result = await GetResource(
id: id,
cancellationToken: cancellationToken
);
//
return result;
}
}
}