Update Lang Version to 12 ...
Fix and Complete XCategory and XSubCategory Services and Service Implementations ...
This commit is contained in:
@@ -1,15 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using xCategoryService.Models.Dtos;
|
||||
using xCategoryService.Models.Entities;
|
||||
using xCategoryService.Providers.Dtos;
|
||||
using xIdentityModels.Models;
|
||||
using xModels.Dtos;
|
||||
using xPushService.Interfaces;
|
||||
|
||||
namespace xCategoryService.Interfaces
|
||||
{
|
||||
public interface IXCategoryProvider : IXBaseProvided<XCategory, XCategoryDto, int, XCategoryDtoHub>
|
||||
{
|
||||
/// <summary>
|
||||
/// Check Has Specified Locale or not ...
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="language"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> HasLocale(
|
||||
int id,
|
||||
string language,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Load an Item by all of it's Related Translations ...
|
||||
/// </summary>
|
||||
@@ -65,11 +83,67 @@ namespace xCategoryService.Interfaces
|
||||
/// <param name="userInfo"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<XCategoryResourceDto> RefereshResource(
|
||||
Task<XCategoryResourceDto> Referesh(
|
||||
XCategoryResourceDto resource,
|
||||
string connectionId = null,
|
||||
XUserClaimsInfoDto userInfo = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Get All Resources ...
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<XCategoryResourceDto>> GetAllResources(
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Find One Resource ...
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<XCategoryResourceDto> FindOne(
|
||||
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Find Many Resource ...
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<XCategoryResourceDto>> FindMany(
|
||||
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
||||
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> orderBuilder = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve Resources by Query Pattern ...
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="orderBuilder"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<XQueryResult<XCategoryResourceDto>> QueryResources(
|
||||
XQuery query = null,
|
||||
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
||||
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> orderBuilder = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Get All Resources as Async Enumerable ...
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
IAsyncEnumerable<XCategoryResourceDto> GetAllResourcesAsAsyncEnumerable(
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,149 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using xCategoryService.Models.Dtos;
|
||||
using xCategoryService.Models.Entities;
|
||||
using xCategoryService.Providers.Dtos;
|
||||
using xIdentityModels.Models;
|
||||
using xModels.Dtos;
|
||||
using xPushService.Interfaces;
|
||||
|
||||
namespace xCategoryService.Interfaces
|
||||
{
|
||||
public interface IXSubCategoryProvider : IXBaseProvided<XSubCategory, XSubCategoryDto, int, XSubCategoryDtoHub>
|
||||
{ }
|
||||
{
|
||||
/// <summary>
|
||||
/// Check Has Specified Locale or not ...
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="language"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> HasLocale(
|
||||
int id,
|
||||
string language,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Load an Item by all of it's Related Translations ...
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<XSubCategoryResourceDto> GetResource(
|
||||
int id,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <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>
|
||||
Task<XSubCategoryResourceDto> Add(
|
||||
XSubCategoryDto item,
|
||||
string langauge = null,
|
||||
string connectionId = null,
|
||||
XUserClaimsInfoDto userInfo = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <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>
|
||||
Task<XSubCategoryResourceDto> Update(
|
||||
int id,
|
||||
XSubCategoryDto item,
|
||||
string language = null,
|
||||
string connectionId = null,
|
||||
XUserClaimsInfoDto userInfo = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Referesh a Resource ...
|
||||
/// </summary>
|
||||
/// <param name="resource"></param>
|
||||
/// <param name="connectionId"></param>
|
||||
/// <param name="userInfo"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<XSubCategoryResourceDto> Referesh(
|
||||
XSubCategoryResourceDto resource,
|
||||
string connectionId = null,
|
||||
XUserClaimsInfoDto userInfo = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Get All Resources ...
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<XSubCategoryResourceDto>> GetAllResources(
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Find One Resource ...
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<XSubCategoryResourceDto> FindOne(
|
||||
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Find Many Resource ...
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<XSubCategoryResourceDto>> FindMany(
|
||||
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
||||
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve Resources by Query Pattern ...
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="orderBuilder"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<XQueryResult<XSubCategoryResourceDto>> QueryResources(
|
||||
XQuery query = null,
|
||||
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
||||
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Get All Resources as Async Enumerable ...
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
IAsyncEnumerable<XSubCategoryResourceDto> GetAllResourcesAsAsyncEnumerable(
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using xCategoryService.Models.Dtos;
|
||||
using xModels.Base;
|
||||
using xModels.Dtos;
|
||||
|
||||
namespace xCategoryService.Providers.Dtos
|
||||
{
|
||||
public class XSubCategoryResourceDto : XBaseDto
|
||||
{
|
||||
public XSubCategoryDto Item { get; set; }
|
||||
public XResourceDto Titles { get; set; }
|
||||
public XResourceDto Descriptions { get; set; }
|
||||
}
|
||||
}
|
||||
+494
-19
@@ -1,4 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using xCategoryService.Interfaces;
|
||||
@@ -11,8 +15,10 @@ using xCommons.Extensions;
|
||||
using xExceptions.Constants;
|
||||
using xIdentityModels.Models;
|
||||
using xModels.Dtos;
|
||||
using xDataService.Extensions;
|
||||
using xPushService.Constants;
|
||||
using xPushService.Providers;
|
||||
using xDataService.Configuration;
|
||||
|
||||
namespace xCategoryService.Providers
|
||||
{
|
||||
@@ -20,12 +26,14 @@ namespace xCategoryService.Providers
|
||||
{
|
||||
private readonly IXCategoryServiceProvider provider;
|
||||
private readonly XAppConfiguration appConfiguration;
|
||||
private readonly XDataServiceConfiguration dataServiceConfiguration;
|
||||
private readonly IXCategoryTitleResourceProvider titleResourceProvider;
|
||||
private readonly IXCategoryDescriptionResourceProvider descriptionResourceProvider;
|
||||
|
||||
public XCategoryProvider(
|
||||
XAppConfiguration appConfiguration,
|
||||
IXCategoryServiceProvider provider,
|
||||
XDataServiceConfiguration dataServiceConfiguration,
|
||||
IXCategoryTitleResourceProvider titleResourceProvider,
|
||||
IXCategoryDescriptionResourceProvider descriptionResourceProvider
|
||||
) : base(
|
||||
@@ -37,9 +45,12 @@ namespace xCategoryService.Providers
|
||||
this.provider = provider;
|
||||
this.appConfiguration = appConfiguration;
|
||||
this.titleResourceProvider = titleResourceProvider;
|
||||
this.dataServiceConfiguration = dataServiceConfiguration;
|
||||
this.descriptionResourceProvider = descriptionResourceProvider;
|
||||
}
|
||||
|
||||
//
|
||||
#region Overrides ...
|
||||
public override bool IsOwned(
|
||||
XCategoryDto item,
|
||||
XUserClaimsInfoDto userInfo
|
||||
@@ -55,9 +66,12 @@ namespace xCategoryService.Providers
|
||||
{
|
||||
return !item.IsNullOrDefault();
|
||||
}
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Actions ...
|
||||
/// <summary>
|
||||
/// Check a Category Has Specified Locale or not ...
|
||||
/// Check Has Specified Locale or not ...
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="language"></param>
|
||||
@@ -91,9 +105,6 @@ namespace xCategoryService.Providers
|
||||
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));
|
||||
|
||||
@@ -113,7 +124,7 @@ namespace xCategoryService.Providers
|
||||
)
|
||||
{
|
||||
//
|
||||
var category = await Get(
|
||||
var item = await Get(
|
||||
id: id,
|
||||
includeBuilder: null,
|
||||
cancellationToken: cancellationToken
|
||||
@@ -130,7 +141,7 @@ namespace xCategoryService.Providers
|
||||
//
|
||||
var result = new XCategoryResourceDto
|
||||
{
|
||||
Item = category,
|
||||
Item = item,
|
||||
Titles = titleResource,
|
||||
Descriptions = descriptionResource
|
||||
};
|
||||
@@ -140,7 +151,7 @@ namespace xCategoryService.Providers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add Category Item for Specified Language ...
|
||||
/// Add an Item for Specified Language ...
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <param name="langauge"></param>
|
||||
@@ -171,6 +182,14 @@ namespace xCategoryService.Providers
|
||||
XException.InvalidArgs.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
// Check Permission ...
|
||||
isValid = HasPermision(userInfo);
|
||||
if (!isValid)
|
||||
{
|
||||
XException.NotAllowed.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
var id = -1;
|
||||
try
|
||||
@@ -271,7 +290,7 @@ namespace xCategoryService.Providers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update a Category Item for Specified Language ...
|
||||
/// Update an Item for Specified Language ...
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="item"></param>
|
||||
@@ -337,10 +356,10 @@ namespace xCategoryService.Providers
|
||||
isValid =
|
||||
!dto.IsNullOrDefault() &&
|
||||
!userInfo.IsNullOrDefault() &&
|
||||
IsOwned(
|
||||
(IsOwned(
|
||||
item: dto,
|
||||
userInfo: userInfo
|
||||
);
|
||||
) || HasPermision(userInfo));
|
||||
if (!isValid)
|
||||
{
|
||||
XException.NotAllowed.Throw();
|
||||
@@ -364,7 +383,7 @@ namespace xCategoryService.Providers
|
||||
.ForEach(tl =>
|
||||
{
|
||||
//
|
||||
if (tl.Language.Equals(language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
if (tl.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
//
|
||||
titleUpdated = true;
|
||||
@@ -379,7 +398,7 @@ namespace xCategoryService.Providers
|
||||
.ForEach(dl =>
|
||||
{
|
||||
//
|
||||
if (dl.Language.Equals(language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
if (dl.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
//
|
||||
descriptionUpdated = true;
|
||||
@@ -396,7 +415,7 @@ namespace xCategoryService.Providers
|
||||
}
|
||||
|
||||
//
|
||||
resource = await RefereshResource(
|
||||
resource = await Referesh(
|
||||
resource: resource,
|
||||
userInfo: userInfo,
|
||||
connectionId: connectionId,
|
||||
@@ -415,7 +434,7 @@ namespace xCategoryService.Providers
|
||||
/// <param name="userInfo"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<XCategoryResourceDto> RefereshResource(
|
||||
public async Task<XCategoryResourceDto> Referesh(
|
||||
XCategoryResourceDto resource,
|
||||
string connectionId = null,
|
||||
XUserClaimsInfoDto userInfo = null,
|
||||
@@ -425,20 +444,29 @@ namespace xCategoryService.Providers
|
||||
//
|
||||
// Validate Args ...
|
||||
var isValid =
|
||||
!resource.IsNull() &&
|
||||
!resource.Item.IsNullOrDefault();
|
||||
!resource.IsNull();
|
||||
if (!isValid)
|
||||
{
|
||||
XException.InvalidArgs.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
// Check Permission ...
|
||||
isValid = HasPermision(userInfo);
|
||||
if (!isValid)
|
||||
{
|
||||
XException.NotAllowed.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
var id = -1;
|
||||
XCategoryResourceDto result = null;
|
||||
|
||||
//
|
||||
// Check Item Exists ...
|
||||
XCategoryDto dto =
|
||||
!resource.Item.Id.IsValidIntId()
|
||||
(resource.Item.IsNullOrDefault() ||
|
||||
!resource.Item.Id.IsValidIntId())
|
||||
? null
|
||||
: await Get(
|
||||
id: resource.Item.Id,
|
||||
@@ -451,20 +479,215 @@ namespace xCategoryService.Providers
|
||||
// Do Referesh Based on Existance ...
|
||||
var isNew =
|
||||
!isExists &&
|
||||
!resource.Item.Id.IsValidIntId();
|
||||
(resource.Item.IsNullOrDefault() ||
|
||||
!resource.Item.Id.IsValidIntId());
|
||||
if (isNew)
|
||||
{
|
||||
//
|
||||
// Add ...
|
||||
// In this Senario, for Add a Category by Providing Resource
|
||||
// the item must clean, either Title and Description, and tge Locales Provided by Resource
|
||||
// ust Contains Values ...
|
||||
// the Add Starts by Titles and only Items Add Which has Titles, since Title is Mandatory
|
||||
// and Description is Optional ...
|
||||
isValid =
|
||||
//
|
||||
// Resource ...
|
||||
(resource.Item.IsNullOrDefault() ||
|
||||
(!resource.Item.Id.IsValidIntId() &&
|
||||
resource.Item.Title.IsNullOrEmpty() &&
|
||||
resource.Item.Description.IsNullOrEmpty())) &&
|
||||
//
|
||||
// Titles ...
|
||||
!resource.Titles.IsNullOrDefault() &&
|
||||
resource.Titles.Locales.HasChild();
|
||||
if (!isValid)
|
||||
{
|
||||
XException.InvalidArgs.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
// Add Temp Category ...
|
||||
var unique = Guid.NewGuid();
|
||||
var temp = new XCategoryDto
|
||||
{
|
||||
Title = $"TmpT_{unique}",
|
||||
Description = $"TmpD_{unique}",
|
||||
};
|
||||
temp = await provider.AddAsync(
|
||||
item: temp,
|
||||
saveChanges: true,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
isValid =
|
||||
!temp.IsNullOrDefault() &&
|
||||
temp.Id.IsValidIntId();
|
||||
if (!isValid)
|
||||
{
|
||||
XException.ActionFailed.Throw();
|
||||
}
|
||||
id = temp.Id;
|
||||
|
||||
//
|
||||
// Update Title and Description ...
|
||||
var titleResource = titleResourceProvider.GetResourceTitle(id);
|
||||
var descriptionResource = descriptionResourceProvider.GetResourceTitle(id);
|
||||
temp.Title = titleResource;
|
||||
temp.Description = descriptionResource;
|
||||
temp = await provider.UpdateAsync(
|
||||
id: id,
|
||||
item: temp,
|
||||
saveChanges: true,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
|
||||
//
|
||||
// Loop through Titles ...
|
||||
foreach (var locale in resource.Titles.Locales)
|
||||
{
|
||||
//
|
||||
// Add Or Update Locale ...
|
||||
await titleResourceProvider.AddOrUpdateLocale(
|
||||
locale: locale,
|
||||
identifier: id,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
var desLocale = resource.Descriptions.Locales.FirstOrDefault(
|
||||
dl =>
|
||||
dl.Language == locale.Language);
|
||||
if (!desLocale.IsNullOrDefault())
|
||||
{
|
||||
//
|
||||
// Add Descriptions ...
|
||||
await descriptionResourceProvider.AddOrUpdateLocale(
|
||||
identifier: id,
|
||||
locale: locale,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isExists)
|
||||
{
|
||||
//
|
||||
// Re State ...
|
||||
id = resource.Item.Id;
|
||||
|
||||
//
|
||||
// Try to Refresh Resource State ...
|
||||
|
||||
//
|
||||
#region Remove ...
|
||||
//
|
||||
// Titles ...
|
||||
var removeTitles = result.Titles.Locales.Where(
|
||||
l => !resource.Titles.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
);
|
||||
foreach (var locale in removeTitles)
|
||||
{
|
||||
//
|
||||
await titleResourceProvider.RemoveLocale(
|
||||
identifier: id,
|
||||
connectionId: null,
|
||||
language: locale.Language,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Descriptions ...
|
||||
var removeDescriptions = result.Descriptions.Locales.Where(
|
||||
l => !resource.Descriptions.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
);
|
||||
foreach (var locale in removeDescriptions)
|
||||
{
|
||||
//
|
||||
await descriptionResourceProvider.RemoveLocale(
|
||||
identifier: id,
|
||||
connectionId: null,
|
||||
language: locale.Language,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Update ...
|
||||
//
|
||||
// Titles ...
|
||||
var updateTitles = result.Titles.Locales.Where(
|
||||
l => resource.Titles.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
);
|
||||
foreach (var locale in updateTitles)
|
||||
{
|
||||
//
|
||||
await titleResourceProvider.AddOrUpdateLocale(
|
||||
identifier: id,
|
||||
locale: locale,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Descriptions ...
|
||||
var updateDescriptions = result.Descriptions.Locales.Where(
|
||||
l => resource.Descriptions.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
);
|
||||
foreach (var locale in updateDescriptions)
|
||||
{
|
||||
//
|
||||
await descriptionResourceProvider.AddOrUpdateLocale(
|
||||
identifier: id,
|
||||
locale: locale,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region New ...
|
||||
//
|
||||
// Titles ...
|
||||
var newTitles = resource.Titles.Locales.Where(
|
||||
l => !result.Titles.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
);
|
||||
foreach (var locale in newTitles)
|
||||
{
|
||||
//
|
||||
await titleResourceProvider.AddOrUpdateLocale(
|
||||
identifier: id,
|
||||
locale: locale,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Descriptions ...
|
||||
var newDescriptions = resource.Descriptions.Locales.Where(
|
||||
l => !result.Descriptions.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
);
|
||||
foreach (var locale in newDescriptions)
|
||||
{
|
||||
//
|
||||
await descriptionResourceProvider.AddOrUpdateLocale(
|
||||
identifier: id,
|
||||
locale: locale,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Action ...
|
||||
isValid = id.IsValidIntId();
|
||||
if (!isValid)
|
||||
{
|
||||
@@ -473,13 +696,265 @@ namespace xCategoryService.Providers
|
||||
|
||||
//
|
||||
// Get Result ...
|
||||
var result = await GetResource(
|
||||
result = await GetResource(
|
||||
id: id,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
isValid = !result.IsNullOrDefault();
|
||||
|
||||
//
|
||||
// Send Notification ...
|
||||
if (isValid)
|
||||
{
|
||||
//
|
||||
await provider.SendPush(
|
||||
connectionId: connectionId,
|
||||
cancellationToken: cancellationToken,
|
||||
payLoad: result.ToJSON(camelCase: true),
|
||||
action: isNew
|
||||
? XBaseEntityHubAction.Add.GetStringValue()
|
||||
: XBaseEntityHubAction.Update.GetStringValue()
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get All Resources as Async Enumerable ...
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async IAsyncEnumerable<XCategoryResourceDto> GetAllResourcesAsAsyncEnumerable(
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
var enumerable = provider.GetAllAsAsyncEnumerable(
|
||||
includeBuilder: null,
|
||||
ignoreSoftDeleteds: true,
|
||||
cancellationToken: cancellationToken,
|
||||
orderBuilder: x => x.OrderBy(y => y.Id)
|
||||
);
|
||||
|
||||
//
|
||||
await foreach (var dto in enumerable)
|
||||
{
|
||||
//
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
//
|
||||
var resource = await GetResource(
|
||||
id: dto.Id,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
yield return resource;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get All Resources ...
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<XCategoryResourceDto>> GetAllResources(
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
var result = new List<XCategoryResourceDto>();
|
||||
|
||||
//
|
||||
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
|
||||
await foreach (var item in enumerable)
|
||||
{
|
||||
//
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
result.Add(item);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find One Resource ...
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<XCategoryResourceDto> FindOne(
|
||||
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
var isApproved = false;
|
||||
XCategoryResourceDto result = null;
|
||||
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
|
||||
await foreach (var item in enumerable)
|
||||
{
|
||||
//
|
||||
// Check Cancellation Token ...
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Predicate Condition ...
|
||||
isApproved = predicate.Compile()(item);
|
||||
if (isApproved)
|
||||
{
|
||||
//
|
||||
result = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find Many Resource ...
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<XCategoryResourceDto>> FindMany(
|
||||
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
||||
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> orderBuilder = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
var isApproved = false;
|
||||
var result = new List<XCategoryResourceDto>();
|
||||
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
|
||||
await foreach (var item in enumerable)
|
||||
{
|
||||
//
|
||||
// Check Cancellation Token ...
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Predicate Condition ...
|
||||
isApproved = predicate.Compile()(item);
|
||||
if (isApproved)
|
||||
{
|
||||
result.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Apply Order ...
|
||||
if (!orderBuilder.IsNull())
|
||||
{
|
||||
//
|
||||
result =
|
||||
orderBuilder(result.AsQueryable())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve Resources by Query Pattern ...
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="orderBuilder"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<XQueryResult<XCategoryResourceDto>> QueryResources(
|
||||
XQuery query = null,
|
||||
Expression<Func<XCategoryResourceDto, bool>> predicate = null,
|
||||
Func<IQueryable<XCategoryResourceDto>, IOrderedQueryable<XCategoryResourceDto>> orderBuilder = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
// Normalize Query ...
|
||||
query = query.NormalizeQuery(dataServiceConfiguration);
|
||||
|
||||
//
|
||||
var items = await FindMany(
|
||||
predicate: predicate,
|
||||
orderBuilder: orderBuilder,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
var totalItemsCount = items.Count();
|
||||
|
||||
//
|
||||
// Apply Filter ...
|
||||
if (!query.Filter.IsNullOrEmpty())
|
||||
{
|
||||
//
|
||||
items = items
|
||||
.ApplyFilter(query.Filter);
|
||||
}
|
||||
int filteredItemsCount = items.Count();
|
||||
|
||||
//
|
||||
// Count Pages ...
|
||||
var totalPagesCount = query.CountPages(totalItemsCount);
|
||||
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
||||
|
||||
//
|
||||
// Apply Paging and Sorting ...
|
||||
if (totalItemsCount > 0 &&
|
||||
filteredItemsCount > 0)
|
||||
{
|
||||
//
|
||||
// Apply Sorting ...
|
||||
items = items
|
||||
.ToList()
|
||||
.ApplySorting(
|
||||
query.SortBy,
|
||||
query.IsAscending
|
||||
);
|
||||
|
||||
//
|
||||
// Apply Paging ...
|
||||
items = items
|
||||
.ToList()
|
||||
.ApplyPaging(
|
||||
query.Page,
|
||||
query.PageSize
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Result ...
|
||||
var result = new XQueryResult<XCategoryResourceDto>
|
||||
{
|
||||
Page = query.Page,
|
||||
Items = [.. items],
|
||||
PageSize = query.PageSize,
|
||||
TotalPages = totalPagesCount,
|
||||
TotalItems = totalItemsCount,
|
||||
TotalFilteredPages = filteredPagesCount,
|
||||
TotalFilteredItems = filteredItemsCount
|
||||
};
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Runtime.CompilerServices;
|
||||
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 xDataService.Configuration;
|
||||
using xExceptions.Constants;
|
||||
using xIdentityModels.Models;
|
||||
using xModels.Dtos;
|
||||
using xDataService.Extensions;
|
||||
using xPushService.Constants;
|
||||
using xPushService.Providers;
|
||||
|
||||
namespace xCategoryService.Providers
|
||||
{
|
||||
public class XSubCategoryProvider : XBaseProvided<XSubCategory, XSubCategoryDto, int, XSubCategoryDtoHub>, IXSubCategoryProvider
|
||||
{
|
||||
private readonly XAppConfiguration appConfiguration;
|
||||
private readonly IXSubCategoryServiceProvider provider;
|
||||
private readonly XDataServiceConfiguration dataServiceConfiguration;
|
||||
private readonly IXSubCategoryTitleResourceProvider titleResourceProvider;
|
||||
private readonly IXSubCategoryDescriptionResourceProvider descriptionResourceProvider;
|
||||
|
||||
public XSubCategoryProvider(
|
||||
IXSubCategoryServiceProvider provider
|
||||
XAppConfiguration appConfiguration,
|
||||
IXSubCategoryServiceProvider provider,
|
||||
XDataServiceConfiguration dataServiceConfiguration,
|
||||
IXSubCategoryTitleResourceProvider titleResourceProvider,
|
||||
IXSubCategoryDescriptionResourceProvider descriptionResourceProvider
|
||||
) : base(
|
||||
provider,
|
||||
permittedRoles: new string[] { }
|
||||
)
|
||||
{ }
|
||||
{
|
||||
this.appConfiguration = appConfiguration;
|
||||
this.provider = provider;
|
||||
this.dataServiceConfiguration = dataServiceConfiguration;
|
||||
this.titleResourceProvider = titleResourceProvider;
|
||||
this.descriptionResourceProvider = descriptionResourceProvider;
|
||||
}
|
||||
|
||||
//
|
||||
#region Overrides ...
|
||||
public override bool IsOwned(
|
||||
XSubCategoryDto item,
|
||||
XUserClaimsInfoDto userInfo
|
||||
@@ -34,5 +65,895 @@ namespace xCategoryService.Providers
|
||||
{
|
||||
return !item.IsNullOrDefault();
|
||||
}
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Actions ...
|
||||
/// <summary>
|
||||
/// Check 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));
|
||||
|
||||
//
|
||||
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<XSubCategoryResourceDto> GetResource(
|
||||
int id,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
var item = 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 XSubCategoryResourceDto
|
||||
{
|
||||
Item = item,
|
||||
Titles = titleResource,
|
||||
Descriptions = descriptionResource
|
||||
};
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an 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<XSubCategoryResourceDto> Add(
|
||||
XSubCategoryDto 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();
|
||||
}
|
||||
|
||||
//
|
||||
// Check Permission ...
|
||||
isValid = HasPermision(userInfo);
|
||||
if (!isValid)
|
||||
{
|
||||
XException.NotAllowed.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 an 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<XSubCategoryResourceDto> Update(
|
||||
int id,
|
||||
XSubCategoryDto 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
|
||||
) || HasPermision(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, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
//
|
||||
titleUpdated = true;
|
||||
tl.Value = item.Title;
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// Update Description ...
|
||||
resource.Descriptions.Locales
|
||||
.ToList()
|
||||
.ForEach(dl =>
|
||||
{
|
||||
//
|
||||
if (dl.Language.Equals(language, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
//
|
||||
descriptionUpdated = true;
|
||||
dl.Value = item.Description;
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// Validate Title and Description Updated ...
|
||||
isValid = titleUpdated && descriptionUpdated;
|
||||
if (!isValid)
|
||||
{
|
||||
XException.ActionFailed.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
resource = await Referesh(
|
||||
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<XSubCategoryResourceDto> Referesh(
|
||||
XSubCategoryResourceDto resource,
|
||||
string connectionId = null,
|
||||
XUserClaimsInfoDto userInfo = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
// Validate Args ...
|
||||
var isValid =
|
||||
!resource.IsNull();
|
||||
if (!isValid)
|
||||
{
|
||||
XException.InvalidArgs.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
// Check Permission ...
|
||||
isValid = HasPermision(userInfo);
|
||||
if (!isValid)
|
||||
{
|
||||
XException.NotAllowed.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
var id = -1;
|
||||
XSubCategoryResourceDto result = null;
|
||||
|
||||
//
|
||||
// Check Item Exists ...
|
||||
XSubCategoryDto dto =
|
||||
(resource.Item.IsNullOrDefault() ||
|
||||
!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.IsNullOrDefault() ||
|
||||
!resource.Item.Id.IsValidIntId());
|
||||
if (isNew)
|
||||
{
|
||||
//
|
||||
// Add ...
|
||||
// In this Senario, for Add a Category by Providing Resource
|
||||
// the item must clean, either Title and Description, and tge Locales Provided by Resource
|
||||
// ust Contains Values ...
|
||||
// the Add Starts by Titles and only Items Add Which has Titles, since Title is Mandatory
|
||||
// and Description is Optional ...
|
||||
isValid =
|
||||
//
|
||||
// Resource ...
|
||||
(resource.Item.IsNullOrDefault() ||
|
||||
(!resource.Item.Id.IsValidIntId() &&
|
||||
resource.Item.Title.IsNullOrEmpty() &&
|
||||
resource.Item.Description.IsNullOrEmpty())) &&
|
||||
//
|
||||
// Titles ...
|
||||
!resource.Titles.IsNullOrDefault() &&
|
||||
resource.Titles.Locales.HasChild();
|
||||
if (!isValid)
|
||||
{
|
||||
XException.InvalidArgs.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
// Add Temp Category ...
|
||||
var unique = Guid.NewGuid();
|
||||
var temp = new XSubCategoryDto
|
||||
{
|
||||
Title = $"TmpT_{unique}",
|
||||
Description = $"TmpD_{unique}",
|
||||
};
|
||||
temp = await provider.AddAsync(
|
||||
item: temp,
|
||||
saveChanges: true,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
isValid =
|
||||
!temp.IsNullOrDefault() &&
|
||||
temp.Id.IsValidIntId();
|
||||
if (!isValid)
|
||||
{
|
||||
XException.ActionFailed.Throw();
|
||||
}
|
||||
id = temp.Id;
|
||||
|
||||
//
|
||||
// Update Title and Description ...
|
||||
var titleResource = titleResourceProvider.GetResourceTitle(id);
|
||||
var descriptionResource = descriptionResourceProvider.GetResourceTitle(id);
|
||||
temp.Title = titleResource;
|
||||
temp.Description = descriptionResource;
|
||||
temp = await provider.UpdateAsync(
|
||||
id: id,
|
||||
item: temp,
|
||||
saveChanges: true,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
|
||||
//
|
||||
// Loop through Titles ...
|
||||
foreach (var locale in resource.Titles.Locales)
|
||||
{
|
||||
//
|
||||
// Add Or Update Locale ...
|
||||
await titleResourceProvider.AddOrUpdateLocale(
|
||||
locale: locale,
|
||||
identifier: id,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
var desLocale = resource.Descriptions.Locales.FirstOrDefault(
|
||||
dl =>
|
||||
dl.Language == locale.Language);
|
||||
if (!desLocale.IsNullOrDefault())
|
||||
{
|
||||
//
|
||||
// Add Descriptions ...
|
||||
await descriptionResourceProvider.AddOrUpdateLocale(
|
||||
identifier: id,
|
||||
locale: locale,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isExists)
|
||||
{
|
||||
//
|
||||
// Re State ...
|
||||
id = resource.Item.Id;
|
||||
|
||||
//
|
||||
// Try to Refresh Resource State ...
|
||||
|
||||
//
|
||||
#region Remove ...
|
||||
//
|
||||
// Titles ...
|
||||
var removeTitles = result.Titles.Locales.Where(
|
||||
l => !resource.Titles.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
);
|
||||
foreach (var locale in removeTitles)
|
||||
{
|
||||
//
|
||||
await titleResourceProvider.RemoveLocale(
|
||||
identifier: id,
|
||||
connectionId: null,
|
||||
language: locale.Language,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Descriptions ...
|
||||
var removeDescriptions = result.Descriptions.Locales.Where(
|
||||
l => !resource.Descriptions.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
);
|
||||
foreach (var locale in removeDescriptions)
|
||||
{
|
||||
//
|
||||
await descriptionResourceProvider.RemoveLocale(
|
||||
identifier: id,
|
||||
connectionId: null,
|
||||
language: locale.Language,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region Update ...
|
||||
//
|
||||
// Titles ...
|
||||
var updateTitles = result.Titles.Locales.Where(
|
||||
l => resource.Titles.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
);
|
||||
foreach (var locale in updateTitles)
|
||||
{
|
||||
//
|
||||
await titleResourceProvider.AddOrUpdateLocale(
|
||||
identifier: id,
|
||||
locale: locale,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Descriptions ...
|
||||
var updateDescriptions = result.Descriptions.Locales.Where(
|
||||
l => resource.Descriptions.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
);
|
||||
foreach (var locale in updateDescriptions)
|
||||
{
|
||||
//
|
||||
await descriptionResourceProvider.AddOrUpdateLocale(
|
||||
identifier: id,
|
||||
locale: locale,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
|
||||
//
|
||||
#region New ...
|
||||
//
|
||||
// Titles ...
|
||||
var newTitles = resource.Titles.Locales.Where(
|
||||
l => !result.Titles.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
);
|
||||
foreach (var locale in newTitles)
|
||||
{
|
||||
//
|
||||
await titleResourceProvider.AddOrUpdateLocale(
|
||||
identifier: id,
|
||||
locale: locale,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Descriptions ...
|
||||
var newDescriptions = resource.Descriptions.Locales.Where(
|
||||
l => !result.Descriptions.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
);
|
||||
foreach (var locale in newDescriptions)
|
||||
{
|
||||
//
|
||||
await descriptionResourceProvider.AddOrUpdateLocale(
|
||||
identifier: id,
|
||||
locale: locale,
|
||||
connectionId: null,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
//
|
||||
// Validate Action ...
|
||||
isValid = id.IsValidIntId();
|
||||
if (!isValid)
|
||||
{
|
||||
XException.ActionFailed.Throw();
|
||||
}
|
||||
|
||||
//
|
||||
// Get Result ...
|
||||
result = await GetResource(
|
||||
id: id,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
isValid = !result.IsNullOrDefault();
|
||||
|
||||
//
|
||||
// Send Notification ...
|
||||
if (isValid)
|
||||
{
|
||||
//
|
||||
await provider.SendPush(
|
||||
connectionId: connectionId,
|
||||
cancellationToken: cancellationToken,
|
||||
payLoad: result.ToJSON(camelCase: true),
|
||||
action: isNew
|
||||
? XBaseEntityHubAction.Add.GetStringValue()
|
||||
: XBaseEntityHubAction.Update.GetStringValue()
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get All Resources as Async Enumerable ...
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async IAsyncEnumerable<XSubCategoryResourceDto> GetAllResourcesAsAsyncEnumerable(
|
||||
[EnumeratorCancellation] CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
var enumerable = provider.GetAllAsAsyncEnumerable(
|
||||
includeBuilder: null,
|
||||
ignoreSoftDeleteds: true,
|
||||
cancellationToken: cancellationToken,
|
||||
orderBuilder: x => x.OrderBy(y => y.Id)
|
||||
);
|
||||
|
||||
//
|
||||
await foreach (var dto in enumerable)
|
||||
{
|
||||
//
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
//
|
||||
var resource = await GetResource(
|
||||
id: dto.Id,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
yield return resource;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get All Resources ...
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<XSubCategoryResourceDto>> GetAllResources(
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
var result = new List<XSubCategoryResourceDto>();
|
||||
|
||||
//
|
||||
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
|
||||
await foreach (var item in enumerable)
|
||||
{
|
||||
//
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
result.Add(item);
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find One Resource ...
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<XSubCategoryResourceDto> FindOne(
|
||||
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
var isApproved = false;
|
||||
XSubCategoryResourceDto result = null;
|
||||
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
|
||||
await foreach (var item in enumerable)
|
||||
{
|
||||
//
|
||||
// Check Cancellation Token ...
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Predicate Condition ...
|
||||
isApproved = predicate.Compile()(item);
|
||||
if (isApproved)
|
||||
{
|
||||
//
|
||||
result = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find Many Resource ...
|
||||
/// </summary>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<XSubCategoryResourceDto>> FindMany(
|
||||
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
||||
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
var isApproved = false;
|
||||
var result = new List<XSubCategoryResourceDto>();
|
||||
var enumerable = GetAllResourcesAsAsyncEnumerable(cancellationToken);
|
||||
await foreach (var item in enumerable)
|
||||
{
|
||||
//
|
||||
// Check Cancellation Token ...
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect Predicate Condition ...
|
||||
isApproved = predicate.Compile()(item);
|
||||
if (isApproved)
|
||||
{
|
||||
result.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Apply Order ...
|
||||
if (!orderBuilder.IsNull())
|
||||
{
|
||||
//
|
||||
result =
|
||||
orderBuilder(result.AsQueryable())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve Resources by Query Pattern ...
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="predicate"></param>
|
||||
/// <param name="orderBuilder"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<XQueryResult<XSubCategoryResourceDto>> QueryResources(
|
||||
XQuery query = null,
|
||||
Expression<Func<XSubCategoryResourceDto, bool>> predicate = null,
|
||||
Func<IQueryable<XSubCategoryResourceDto>, IOrderedQueryable<XSubCategoryResourceDto>> orderBuilder = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//
|
||||
// Normalize Query ...
|
||||
query = query.NormalizeQuery(dataServiceConfiguration);
|
||||
|
||||
//
|
||||
var items = await FindMany(
|
||||
predicate: predicate,
|
||||
orderBuilder: orderBuilder,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
var totalItemsCount = items.Count();
|
||||
|
||||
//
|
||||
// Apply Filter ...
|
||||
if (!query.Filter.IsNullOrEmpty())
|
||||
{
|
||||
//
|
||||
items = items
|
||||
.ApplyFilter(query.Filter);
|
||||
}
|
||||
int filteredItemsCount = items.Count();
|
||||
|
||||
//
|
||||
// Count Pages ...
|
||||
var totalPagesCount = query.CountPages(totalItemsCount);
|
||||
var filteredPagesCount = query.CountPages(filteredItemsCount);
|
||||
|
||||
//
|
||||
// Apply Paging and Sorting ...
|
||||
if (totalItemsCount > 0 &&
|
||||
filteredItemsCount > 0)
|
||||
{
|
||||
//
|
||||
// Apply Sorting ...
|
||||
items = items
|
||||
.ToList()
|
||||
.ApplySorting(
|
||||
query.SortBy,
|
||||
query.IsAscending
|
||||
);
|
||||
|
||||
//
|
||||
// Apply Paging ...
|
||||
items = items
|
||||
.ToList()
|
||||
.ApplyPaging(
|
||||
query.Page,
|
||||
query.PageSize
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Prepare Result ...
|
||||
var result = new XQueryResult<XSubCategoryResourceDto>
|
||||
{
|
||||
Page = query.Page,
|
||||
Items = [.. items],
|
||||
PageSize = query.PageSize,
|
||||
TotalPages = totalPagesCount,
|
||||
TotalItems = totalItemsCount,
|
||||
TotalFilteredPages = filteredPagesCount,
|
||||
TotalFilteredItems = filteredItemsCount
|
||||
};
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
<!-- Runtime Definition -->
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<PackageId>xDashboard.xCategoryService</PackageId>
|
||||
<Version>1.0.0</Version>
|
||||
<LangVersion>12.0</LangVersion>
|
||||
<Authors>Hadi Khazaee Asl</Authors>
|
||||
<Company>SaherElm IT Center</Company>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<PackageId>xDashboard.xCategoryService</PackageId>
|
||||
|
||||
<Description>
|
||||
it is a Part of xDashboard on SaherElm IT Center which provides Category Futures ...
|
||||
</Description>
|
||||
|
||||
Reference in New Issue
Block a user