diff --git a/Controllers/XCategoryProviderControllerBase.cs b/Controllers/XCategoryProviderControllerBase.cs index eb06136..72aed6f 100644 --- a/Controllers/XCategoryProviderControllerBase.cs +++ b/Controllers/XCategoryProviderControllerBase.cs @@ -336,6 +336,58 @@ namespace xCategoryService.Controllers } } + /// + /// Add Category Item for by It's Locales ... + /// + /// + /// + /// + [HttpPost("Resources/AddResource")] + public virtual async Task> AddResource( + [FromBody] XCategoryResourceDto item, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(item) + .AddNotNull(item.Titles) + .AddNotZeroChilds(item.Titles.Locales) + .ValidateGroupAsync(); + + // + // Reading Requirements ... + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + var result = await provider.AddResource( + item: item, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + /// /// Remove Item for Specified Language ... /// diff --git a/Controllers/XSubCategoryProviderControllerBase.cs b/Controllers/XSubCategoryProviderControllerBase.cs index 10224a0..c80cdbe 100644 --- a/Controllers/XSubCategoryProviderControllerBase.cs +++ b/Controllers/XSubCategoryProviderControllerBase.cs @@ -336,6 +336,58 @@ namespace xCategoryService.Controllers } } + /// + /// Add Item by it's Locales and Reference ... + /// + /// + /// + /// + [HttpPost("Resources/AddResource")] + public virtual async Task> AddResource( + [FromBody] XSubCategoryResourceDto item, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid) + { + XException.InvalidArgs.Throw(); + } + await ValidationProvider + .GroupValidationBuilder() + .AddNotNull(item) + .AddNotNull(item.Titles) + .AddNotZeroChilds(item.Titles.Locales) + .ValidateGroupAsync(); + + // + // Reading Requirements ... + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + var result = await provider.AddResource( + item: item, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + /// /// Remove Item for Specified Language ... /// diff --git a/DI/XDIHelperExtension.cs b/DI/XDIHelperExtension.cs index 4daa366..7c8e40d 100644 --- a/DI/XDIHelperExtension.cs +++ b/DI/XDIHelperExtension.cs @@ -75,7 +75,7 @@ namespace xCategoryService.DI ) { // - #region Using Hubs ... + #region Using Hubs ... // var pushHelper = new XPushServiceHelper(); @@ -86,8 +86,8 @@ namespace xCategoryService.DI // // SubCategory ... - // pushHelper.AddHub("subCategoryDto"); - // pushHelper.AddHub("subCategoryEntity"); + pushHelper.AddHub("subCategoryDto"); + pushHelper.AddHub("subCategoryEntity"); // app.UseXPushService(pushHelper); @@ -108,11 +108,11 @@ namespace xCategoryService.DI // Using XSubCategory Repository Descriptor ... if (!subCategoryDescriptor.IsNull()) { - // // - // app.UseXRepository( - // descriptor: subCategoryDescriptor, - // isDevelopmentEnvironment: isDevelopmentEnvironment - // ); + // + app.UseXRepository( + descriptor: subCategoryDescriptor, + isDevelopmentEnvironment: isDevelopmentEnvironment + ); } } @@ -323,7 +323,7 @@ namespace xCategoryService.DI // Provider ... services.Add( new ServiceDescriptor(typeof(IXSubCategoryProvider), typeof(XSubCategoryProvider), lifeTime) - ); + ); #endregion #endregion diff --git a/Interfaces/IXCategoryProvider.cs b/Interfaces/IXCategoryProvider.cs index fedcad1..5162291 100644 --- a/Interfaces/IXCategoryProvider.cs +++ b/Interfaces/IXCategoryProvider.cs @@ -56,6 +56,21 @@ namespace xCategoryService.Interfaces CancellationToken cancellationToken = default ); + /// + /// Add Item by It's Locales ... + /// + /// + /// + /// + /// + /// + Task AddResource( + XCategoryResourceDto item, + string connectionId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ); + /// /// Remove Item for Specified Language ... /// diff --git a/Interfaces/IXCategoryProviderController.cs b/Interfaces/IXCategoryProviderController.cs index e85fc85..8e92993 100644 --- a/Interfaces/IXCategoryProviderController.cs +++ b/Interfaces/IXCategoryProviderController.cs @@ -52,6 +52,18 @@ namespace xCategoryService.Interfaces CancellationToken cancellationToken = default ); + /// + /// Add Item by It's Locales ... + /// + /// + /// + /// + [HttpPost("Resources/AddResource")] + Task> AddResource( + [FromBody] XCategoryResourceDto item, + CancellationToken cancellationToken = default + ); + /// /// Remove Item for Specified Language ... /// diff --git a/Interfaces/IXSubCategoryProvider.cs b/Interfaces/IXSubCategoryProvider.cs index 5cbdd48..eba0784 100644 --- a/Interfaces/IXSubCategoryProvider.cs +++ b/Interfaces/IXSubCategoryProvider.cs @@ -56,6 +56,21 @@ namespace xCategoryService.Interfaces CancellationToken cancellationToken = default ); + /// + /// Add Item by it's Locales and Reference ... + /// + /// + /// + /// + /// + /// + Task AddResource( + XSubCategoryResourceDto item, + string connectionId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ); + /// /// Remove Item for Specified Language ... /// diff --git a/Interfaces/IXSubCategoryProviderController.cs b/Interfaces/IXSubCategoryProviderController.cs index 4d568e6..defae37 100644 --- a/Interfaces/IXSubCategoryProviderController.cs +++ b/Interfaces/IXSubCategoryProviderController.cs @@ -52,6 +52,18 @@ namespace xCategoryService.Interfaces CancellationToken cancellationToken = default ); + /// + /// Add Item by it's Locales and Reference ... + /// + /// + /// + /// + [HttpPost("Resources/AddResource")] + Task> AddResource( + [FromBody] XSubCategoryResourceDto item, + CancellationToken cancellationToken = default + ); + /// /// Remove Item for Specified Language ... /// diff --git a/Providers/XCategoryProvider.cs b/Providers/XCategoryProvider.cs index 43f3e42..a19b939 100644 --- a/Providers/XCategoryProvider.cs +++ b/Providers/XCategoryProvider.cs @@ -295,6 +295,179 @@ namespace xCategoryService.Providers return result; } + /// + /// Add Category by It's Locales ... + /// + /// + /// + /// + /// + /// + public async Task AddResource( + XCategoryResourceDto item, + string connectionId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ) + { + // + // Validate ... + var isValid = + !item.IsNullOrDefault() && + !item.Titles.IsNullOrDefault() && + item.Titles.Locales.HasChild() && + !item.Titles.Locales.Any(il => + il.Language.IsNullOrEmpty() || + il.Value.IsNullOrEmpty()); + if (!isValid) + { + XException.InvalidArgs.Throw(); + } + + // + // Normalize ... + if (item.Item.IsNullOrDefault()) + { + item.Item = new XCategoryDto(); + } + + // + // Check Permission ... + isValid = HasPermision(userInfo); + if (!isValid) + { + XException.NotAllowed.Throw(); + } + + // + var id = -1; + try + { + // + // Add Category for ID Generation ... + item.Item = await base.Add( + item: item.Item, + userInfo: userInfo, + connectionId: null, // Since here We dont want notification ... + cancellationToken: cancellationToken + ); + isValid = !item.Item.IsNullOrDefault(); + if (!isValid) + { + XException.ActionFailed.Throw(); + } + id = item.Item.Id; + + // + foreach (var il in item.Titles.Locales) + { + // + var title = il.Value; + var language = il.Language; + + // + var descriptionItem = + item.Descriptions.IsNullOrDefault() || + !item.Descriptions.Locales.HasChild() + ? null + : item.Descriptions.Locales + .FirstOrDefault(ides => + ides.Language + .Equals( + language, + StringComparison.InvariantCultureIgnoreCase)); + var description = + descriptionItem.IsNullOrDefault() + ? string.Empty + : descriptionItem.Value; + + // + // Try to Add Resources ... + var titleResource = await titleResourceProvider + .AddOrUpdateLocale( + identifier: id, + locale: new XLocaleResourceDto + { + Value = title, + Language = language + }, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + var descriptionResource = await descriptionResourceProvider + .AddOrUpdateLocale( + identifier: id, + locale: new XLocaleResourceDto + { + Value = description, + Language = language + }, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + // Update Category Dto if not ... + if (item.Item.Title.IsNullOrEmpty() || + !item.Item.Title + .Equals( + titleResource.Resource, + StringComparison.InvariantCultureIgnoreCase) + ) + { + // + item.Item.Title = titleResource.Resource; + item.Item.Description = descriptionResource.Resource; + item.Item = await base.Update( + id: id, + item: 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; + } + /// /// Remove Item for Specified Language ... /// diff --git a/Providers/XSubCategoryProvider.cs b/Providers/XSubCategoryProvider.cs index 1a97e9a..f952b49 100644 --- a/Providers/XSubCategoryProvider.cs +++ b/Providers/XSubCategoryProvider.cs @@ -135,7 +135,7 @@ namespace xCategoryService.Providers identifier: id, cancellationToken: cancellationToken ); - var descriptionResource = await titleResourceProvider.GetResource( + var descriptionResource = await descriptionResourceProvider.GetResource( identifier: id, cancellationToken: cancellationToken ); @@ -307,6 +307,207 @@ namespace xCategoryService.Providers return result; } + /// + /// Add Item by it's Locales and Reference ... + /// + /// + /// + /// + /// + /// + public async Task AddResource( + XSubCategoryResourceDto item, + string connectionId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ) + { + // + // Validate ... + var isValid = + !item.IsNullOrDefault() && + !item.Titles.IsNullOrDefault() && + item.Titles.Locales.HasChild() && + !item.Titles.Locales.Any(tl => + tl.Value.IsNullOrEmpty() || + tl.Language.IsNullOrEmpty()); + if (!isValid) + { + XException.InvalidArgs.Throw(); + } + + // + // Normalize ... + if (item.Item.IsNullOrDefault()) + { + item.Item = new XSubCategoryDto(); + } + + // + // Check Permission ... + isValid = HasPermision(userInfo); + if (!isValid) + { + XException.NotAllowed.Throw(); + } + + // + var id = -1; + try + { + // + // Handle Category Generation ... + if (!item.Category.IsNullOrDefault()) + { + // + // Handle Category ... + try + { + // Try to Add Category ... + item.Category = await categoryProvider.Refresh( + resource: item.Category, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + } + catch { } + } + + // + // Add SubCategory for ID Generation ... + item.Item = await base.Add( + item: item.Item, + userInfo: userInfo, + connectionId: null, // Since here We dont want notification ... + cancellationToken: cancellationToken + ); + isValid = !item.Item.IsNullOrDefault(); + if (!isValid) + { + XException.ActionFailed.Throw(); + } + id = item.Item.Id; + + // + foreach (var il in item.Titles.Locales) + { + // + var title = il.Value; + var language = il.Language; + + // + var descriptionItem = + item.Descriptions.IsNullOrDefault() || + !item.Descriptions.Locales.HasChild() + ? null + : item.Descriptions.Locales + .FirstOrDefault(ides => + ides.Language + .Equals( + language, + StringComparison.InvariantCultureIgnoreCase)); + var description = + descriptionItem.IsNullOrDefault() + ? string.Empty + : descriptionItem.Value; + + // + // Try to Add Resources ... + var titleResource = await titleResourceProvider + .AddOrUpdateLocale( + identifier: id, + locale: new XLocaleResourceDto + { + Value = title, + Language = language + }, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + var descriptionResource = await descriptionResourceProvider + .AddOrUpdateLocale( + identifier: id, + locale: new XLocaleResourceDto + { + Value = description, + Language = language + }, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + // Update Category Dto if not ... + if (item.Item.Title.IsNullOrEmpty() || + !item.Item.Title + .Equals( + titleResource.Resource, + StringComparison.InvariantCultureIgnoreCase) + ) + { + // + item.Item.Title = titleResource.Resource; + item.Item.Description = descriptionResource.Resource; + item.Item = await base.Update( + id: id, + item: item.Item, + userInfo: userInfo, + connectionId: null, + cancellationToken: cancellationToken + ); + } + } + } + catch + { + XException.InvalidArgs.Throw(); + } + + // + // Validate Id ... + isValid = id.IsValidIntId(); + if (!isValid) + { + XException.ActionFailed.Throw(); + } + + // + // Add Resource Reference to Category ... + isValid = await categoryProvider.AddReference( + providedForId: id, + connectionId: null, + model: item.Category.Item, + cancellationToken: cancellationToken + ); + + // + // 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; + } + /// /// Remove Item for Specified Language ... /// @@ -867,7 +1068,7 @@ namespace xCategoryService.Providers // // Descriptions ... var updateDescriptions = result.Descriptions.Locales.Where( - l => resource.Descriptions.Locales.Any(r => + l => resource.Descriptions.Locales.Any(r => r.Value .Equals(l.Value, StringComparison.InvariantCultureIgnoreCase) && r.Language