From a853095e75dea334b6648628554458b7d47657f4 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 12 Jun 2026 23:51:14 +0330 Subject: [PATCH] last ... --- .../XCategoryProviderControllerBase.cs | 199 +++++++++ .../XSubCategoryProviderControllerBase.cs | 199 +++++++++ Interfaces/IXCategoryProvider.cs | 21 +- Interfaces/IXCategoryProviderController.cs | 18 +- Interfaces/IXSubCategoryProvider.cs | 21 +- Interfaces/IXSubCategoryProviderController.cs | 18 +- Providers/XCategoryProvider.cs | 382 ++++++++++++++---- Providers/XSubCategoryProvider.cs | 378 +++++++++++++---- xCategoryService.csproj | 7 + 9 files changed, 1065 insertions(+), 178 deletions(-) diff --git a/Controllers/XCategoryProviderControllerBase.cs b/Controllers/XCategoryProviderControllerBase.cs index 84bb36b..eb06136 100644 --- a/Controllers/XCategoryProviderControllerBase.cs +++ b/Controllers/XCategoryProviderControllerBase.cs @@ -45,6 +45,155 @@ namespace xCategoryService.Controllers this.provider = provider; } + // + #region Overrides ... + [NonAction] + [HttpGet("{id}")] + public override async Task> Get( + [FromRoute] int id, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + return await base.Get( + id: id, + useDefaultIncludes: useDefaultIncludes, + cancellationToken: cancellationToken + ); + } + + [NonAction] + [HttpGet("")] + public override async Task>> GetAll( + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + return await base.GetAll( + useDefaultOrders: useDefaultOrders, + cancellationToken: cancellationToken, + useDefaultIncludes: useDefaultIncludes + ); + } + + [NonAction] + [HttpGet("Find/One")] + public override async Task> FindOne( + [FromRoute] string query, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + return await base.FindOne( + query: query, + cancellationToken: cancellationToken, + useDefaultIncludes: useDefaultIncludes + ); + } + + [NonAction] + [HttpGet("Find/Many")] + public override async Task>> FindMany( + [FromRoute] string query, + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + return await base.FindMany( + query: query, + useDefaultOrders: useDefaultOrders, + cancellationToken: cancellationToken, + useDefaultIncludes: useDefaultIncludes + ); + } + + [NonAction] + [HttpGet("Query")] + public override async Task>> Query( + [FromQuery] XQuery query, + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + return await base.Query( + query: query, + useDefaultOrders: useDefaultOrders, + cancellationToken: cancellationToken, + useDefaultIncludes: useDefaultIncludes + ); + } + + [NonAction] + [HttpGet("Query/Owned")] + public override async Task>> QueryOwned( + [FromQuery] XQuery query, + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + return await base.QueryOwned( + query: query, + useDefaultOrders: useDefaultOrders, + cancellationToken: cancellationToken, + useDefaultIncludes: useDefaultIncludes + ); + } + + [NonAction] + [HttpPost("")] + public override async Task> Add( + [FromBody] XCategoryDto item, + CancellationToken cancellationToken = default + ) + { + // + return await base.Add( + item: item, + cancellationToken: cancellationToken + ); + } + + [NonAction] + [HttpPut("{id}")] + public override async Task> Update( + [FromRoute] int id, + [FromBody] XCategoryDto item, + CancellationToken cancellationToken = default + ) + { + // + return await base.Update( + id: id, + item: item, + cancellationToken: cancellationToken + ); + } + + [NonAction] + [HttpDelete("{id}")] + public override async Task> Remove( + [FromRoute] int id, + CancellationToken cancellationToken = default + ) + { + // + return await base.Remove( + id: id, + cancellationToken: cancellationToken + ); + } + #endregion + // #region Actions ... /// @@ -187,6 +336,56 @@ namespace xCategoryService.Controllers } } + /// + /// Remove Item for Specified Language ... + /// + /// + /// if null, Remove All + /// + /// + [HttpDelete("Resources/{id}")] + public virtual async Task> Remove( + [FromRoute] int id, + [FromQuery] string language = null, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid || + !id.IsValidIntId()) + { + XException.InvalidArgs.Throw(); + } + + // + // Reading Requirements ... + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + var result = await provider.Remove( + id: id, + language: language, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + /// /// Update a Category Item for Specified Language ... /// diff --git a/Controllers/XSubCategoryProviderControllerBase.cs b/Controllers/XSubCategoryProviderControllerBase.cs index 536d3be..10224a0 100644 --- a/Controllers/XSubCategoryProviderControllerBase.cs +++ b/Controllers/XSubCategoryProviderControllerBase.cs @@ -45,6 +45,155 @@ namespace xCategoryService.Controllers this.provider = provider; } + // + #region Overrides ... + [NonAction] + [HttpGet("{id}")] + public override async Task> Get( + [FromRoute] int id, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + return await base.Get( + id: id, + useDefaultIncludes: useDefaultIncludes, + cancellationToken: cancellationToken + ); + } + + [NonAction] + [HttpGet("")] + public override async Task>> GetAll( + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + return await base.GetAll( + useDefaultOrders: useDefaultOrders, + cancellationToken: cancellationToken, + useDefaultIncludes: useDefaultIncludes + ); + } + + [NonAction] + [HttpGet("Find/One")] + public override async Task> FindOne( + [FromRoute] string query, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + return await base.FindOne( + query: query, + cancellationToken: cancellationToken, + useDefaultIncludes: useDefaultIncludes + ); + } + + [NonAction] + [HttpGet("Find/Many")] + public override async Task>> FindMany( + [FromRoute] string query, + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + return await base.FindMany( + query: query, + useDefaultOrders: useDefaultOrders, + cancellationToken: cancellationToken, + useDefaultIncludes: useDefaultIncludes + ); + } + + [NonAction] + [HttpGet("Query")] + public override async Task>> Query( + [FromQuery] XQuery query, + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + return await base.Query( + query: query, + useDefaultOrders: useDefaultOrders, + cancellationToken: cancellationToken, + useDefaultIncludes: useDefaultIncludes + ); + } + + [NonAction] + [HttpGet("Query/Owned")] + public override async Task>> QueryOwned( + [FromQuery] XQuery query, + [FromQuery] bool useDefaultOrders = false, + [FromQuery] bool useDefaultIncludes = false, + CancellationToken cancellationToken = default + ) + { + // + return await base.QueryOwned( + query: query, + useDefaultOrders: useDefaultOrders, + cancellationToken: cancellationToken, + useDefaultIncludes: useDefaultIncludes + ); + } + + [NonAction] + [HttpPost("")] + public override async Task> Add( + [FromBody] XSubCategoryDto item, + CancellationToken cancellationToken = default + ) + { + // + return await base.Add( + item: item, + cancellationToken: cancellationToken + ); + } + + [NonAction] + [HttpPut("{id}")] + public override async Task> Update( + [FromRoute] int id, + [FromBody] XSubCategoryDto item, + CancellationToken cancellationToken = default + ) + { + // + return await base.Update( + id: id, + item: item, + cancellationToken: cancellationToken + ); + } + + [NonAction] + [HttpDelete("{id}")] + public override async Task> Remove( + [FromRoute] int id, + CancellationToken cancellationToken = default + ) + { + // + return await base.Remove( + id: id, + cancellationToken: cancellationToken + ); + } + #endregion + // #region Actions ... /// @@ -187,6 +336,56 @@ namespace xCategoryService.Controllers } } + /// + /// Remove Item for Specified Language ... + /// + /// + /// if null, Remove All + /// + /// + [HttpDelete("Resources/{id}")] + public virtual async Task> Remove( + [FromRoute] int id, + [FromQuery] string language = null, + CancellationToken cancellationToken = default + ) + { + // + try + { + // + // Validate ... + if (!ModelState.IsValid || + !id.IsValidIntId()) + { + XException.InvalidArgs.Throw(); + } + + // + // Reading Requirements ... + var userInfo = await GetUserInfo(); + var connectionId = GetConnectionId(); + + // + var result = await provider.Remove( + id: id, + language: language, + userInfo: userInfo, + connectionId: connectionId, + cancellationToken: cancellationToken + ); + + // + return Ok(result.ToDynamicObject()); + } + catch (Exception ex) + { + // + var result = GetExceptionActionResult(ex); + return result; + } + } + /// /// Update a Category Item for Specified Language ... /// diff --git a/Interfaces/IXCategoryProvider.cs b/Interfaces/IXCategoryProvider.cs index 4bbac01..686303f 100644 --- a/Interfaces/IXCategoryProvider.cs +++ b/Interfaces/IXCategoryProvider.cs @@ -40,7 +40,7 @@ namespace xCategoryService.Interfaces ); /// - /// Add Category Item for Specified Language ... + /// Add Item for Specified Language ... /// /// /// @@ -57,7 +57,24 @@ namespace xCategoryService.Interfaces ); /// - /// Update a Category Item for Specified Language ... + /// Remove Item for Specified Language ... + /// + /// + /// if null, Remove All + /// + /// + /// + /// + Task Remove( + int id, + string language = null, + string connectionId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ); + + /// + /// Update an Item for Specified Language ... /// /// /// diff --git a/Interfaces/IXCategoryProviderController.cs b/Interfaces/IXCategoryProviderController.cs index 6e37dfc..e85fc85 100644 --- a/Interfaces/IXCategoryProviderController.cs +++ b/Interfaces/IXCategoryProviderController.cs @@ -39,7 +39,7 @@ namespace xCategoryService.Interfaces ); /// - /// Add Category Item for Specified Language ... + /// Add Item for Specified Language ... /// /// /// @@ -53,7 +53,21 @@ namespace xCategoryService.Interfaces ); /// - /// Update a Category Item for Specified Language ... + /// Remove Item for Specified Language ... + /// + /// + /// if null, Remove All + /// + /// + [HttpDelete("Resources/{id}")] + Task> Remove( + [FromRoute] int id, + [FromQuery] string language = null, + CancellationToken cancellationToken = default + ); + + /// + /// Update an Item for Specified Language ... /// /// /// diff --git a/Interfaces/IXSubCategoryProvider.cs b/Interfaces/IXSubCategoryProvider.cs index 5cc7bbc..5cbdd48 100644 --- a/Interfaces/IXSubCategoryProvider.cs +++ b/Interfaces/IXSubCategoryProvider.cs @@ -40,7 +40,7 @@ namespace xCategoryService.Interfaces ); /// - /// Add Category Item for Specified Language ... + /// Add Item for Specified Language ... /// /// /// @@ -57,7 +57,24 @@ namespace xCategoryService.Interfaces ); /// - /// Update a Category Item for Specified Language ... + /// Remove Item for Specified Language ... + /// + /// + /// if null, Remove All + /// + /// + /// + /// + Task Remove( + int id, + string language = null, + string connectionId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ); + + /// + /// Update an Item for Specified Language ... /// /// /// diff --git a/Interfaces/IXSubCategoryProviderController.cs b/Interfaces/IXSubCategoryProviderController.cs index 77fabe0..4d568e6 100644 --- a/Interfaces/IXSubCategoryProviderController.cs +++ b/Interfaces/IXSubCategoryProviderController.cs @@ -39,7 +39,7 @@ namespace xCategoryService.Interfaces ); /// - /// Add Category Item for Specified Language ... + /// Add Item for Specified Language ... /// /// /// @@ -53,7 +53,21 @@ namespace xCategoryService.Interfaces ); /// - /// Update a Category Item for Specified Language ... + /// Remove Item for Specified Language ... + /// + /// + /// if null, Remove All + /// + /// + [HttpDelete("Resources/{id}")] + Task> Remove( + [FromRoute] int id, + [FromQuery] string language = null, + CancellationToken cancellationToken = default + ); + + /// + /// Update an Item for Specified Language ... /// /// /// diff --git a/Providers/XCategoryProvider.cs b/Providers/XCategoryProvider.cs index 29fdf12..1dbb481 100644 --- a/Providers/XCategoryProvider.cs +++ b/Providers/XCategoryProvider.cs @@ -88,7 +88,7 @@ namespace xCategoryService.Providers var isValid = id.IsValidIntId() && !language.IsNullOrEmpty(); - if (isValid) + if (!isValid) { XException.InvalidArgs.Throw(); } @@ -133,7 +133,7 @@ namespace xCategoryService.Providers identifier: id, cancellationToken: cancellationToken ); - var descriptionResource = await titleResourceProvider.GetResource( + var descriptionResource = await descriptionResourceProvider.GetResource( identifier: id, cancellationToken: cancellationToken ); @@ -289,6 +289,189 @@ namespace xCategoryService.Providers return result; } + /// + /// Remove Item for Specified Language ... + /// + /// + /// if null, Remove All + /// + /// + /// + /// + public async Task Remove( + int id, + string language = null, + string connectionId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ) + { + // + // Validate ... + var isValid = id.IsValidIntId(); + if (!isValid) + { + XException.InvalidArgs.Throw(); + } + + // + // Check Item Exists ... + isValid = await IsExists( + id: id, + cancellationToken: cancellationToken + ); + if (!isValid) + { + XException.NotFound.Throw(); + } + + // + // Validate Locale if Provided ... + isValid = + language.IsNullOrEmpty() || + await HasLocale( + id: id, + language: language, + cancellationToken: cancellationToken + ); + if (!isValid) + { + XException.NotFound.Throw(); + } + + // + var result = await GetResource( + id: id, + cancellationToken: cancellationToken + ); + if (language.IsNullOrEmpty()) + { + // + // Remove All ... + + // + // Titles ... + await titleResourceProvider.RemoveLocales( + identifier: id, + connectionId: null, + cancellationToken: cancellationToken + ); + + // + // Descriptions ... + await descriptionResourceProvider.RemoveLocales( + identifier: id, + connectionId: null, + cancellationToken: cancellationToken + ); + + // + // Remove Entity ... + await provider.RemoveAsync( + id: id, + softDelete: false, + saveChanges: true, + connectionId: null, + cancellationToken: cancellationToken + ); + + // + isValid = true; + result.Titles.Locales = []; + result.Descriptions.Locales = []; + } + else + { + // + // Remove Only One Locale, and if there is one, Remove all ... + + // + // Remove Title if Exists ... + isValid = await titleResourceProvider.HasLocale( + identifier: id, + language: language, + cancellationToken: cancellationToken + ); + if (isValid) + { + // + await titleResourceProvider.RemoveLocale( + identifier: id, + language: language, + connectionId: null, + cancellationToken: cancellationToken + ); + } + + // + // Remove Description if Exists ... + isValid = await descriptionResourceProvider.HasLocale( + identifier: id, + language: language, + cancellationToken: cancellationToken + ); + if (isValid) + { + // + await descriptionResourceProvider.RemoveLocale( + identifier: id, + language: language, + connectionId: null, + cancellationToken: cancellationToken + ); + } + + // + // Retrieve Resource ... + result = await GetResource( + id: id, + cancellationToken: cancellationToken + ); + + // + // Check Has Locales ... + isValid = result.Titles.Locales.HasChild(); + if (!isValid) + { + // + // Remove Item ... + await provider.RemoveAsync( + id: id, + softDelete: false, + saveChanges: true, + connectionId: null, + cancellationToken: cancellationToken + ); + + // + result.Titles.Locales = []; + result.Descriptions.Locales = []; + } + + // + isValid = true; + } + + // + if (isValid) + { + // + // Send Push ... + await provider.SendPush( + connectionId: connectionId, + cancellationToken: cancellationToken, + payLoad: result.ToJSON(camelCase: true), + action: + result.Titles.Locales.HasChild() + ? "DeleteLocale" + : XBaseEntityHubAction.Delete.GetStringValue() + ); + } + + // + return result; + } + /// /// Update an Item for Specified Language ... /// @@ -460,6 +643,7 @@ namespace xCategoryService.Providers // var id = -1; + var isDelete = false; XCategoryResourceDto result = null; // @@ -564,7 +748,7 @@ namespace xCategoryService.Providers // Add Descriptions ... await descriptionResourceProvider.AddOrUpdateLocale( identifier: id, - locale: locale, + locale: desLocale, connectionId: null, cancellationToken: cancellationToken ); @@ -581,109 +765,130 @@ namespace xCategoryService.Providers // 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) + // Check Delete ... + isDelete = !resource.Titles.Locales.HasChild(); + if (isDelete) { // - await titleResourceProvider.RemoveLocale( - identifier: id, + // Handle Delete ... + await Remove( + id: id, + language: null, + userInfo: userInfo, connectionId: null, - language: locale.Language, cancellationToken: cancellationToken ); } + else + { + // + // Handle Update ... - // - // 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 + #region Remove ... + // + // Titles ... + var removeTitles = result.Titles.Locales.Where( + l => !resource.Titles.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase)) ); - } - #endregion + foreach (var locale in removeTitles) + { + // + await titleResourceProvider.RemoveLocale( + identifier: id, + connectionId: null, + language: locale.Language, + cancellationToken: cancellationToken + ); + } - // - #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 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 - // - // 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 + #region Update ... + // + // Titles ... + var updateTitles = result.Titles.Locales.Where( + l => resource.Titles.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase)) ); - } - #endregion + foreach (var locale in updateTitles) + { + // + await titleResourceProvider.AddOrUpdateLocale( + identifier: id, + locale: locale, + connectionId: null, + cancellationToken: cancellationToken + ); + } - // - #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 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 - // - // 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 + #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 } - #endregion } // @@ -696,7 +901,10 @@ namespace xCategoryService.Providers // // Get Result ... - result = await GetResource( + result = + isDelete + ? resource + : await GetResource( id: id, cancellationToken: cancellationToken ); @@ -713,7 +921,9 @@ namespace xCategoryService.Providers payLoad: result.ToJSON(camelCase: true), action: isNew ? XBaseEntityHubAction.Add.GetStringValue() - : XBaseEntityHubAction.Update.GetStringValue() + : isDelete + ? XBaseEntityHubAction.Delete.GetStringValue() + : XBaseEntityHubAction.Update.GetStringValue() ); } diff --git a/Providers/XSubCategoryProvider.cs b/Providers/XSubCategoryProvider.cs index 13609a9..0ecee9d 100644 --- a/Providers/XSubCategoryProvider.cs +++ b/Providers/XSubCategoryProvider.cs @@ -87,7 +87,7 @@ namespace xCategoryService.Providers var isValid = id.IsValidIntId() && !language.IsNullOrEmpty(); - if (isValid) + if (!isValid) { XException.InvalidArgs.Throw(); } @@ -288,6 +288,189 @@ namespace xCategoryService.Providers return result; } + /// + /// Remove Item for Specified Language ... + /// + /// + /// if null, Remove All + /// + /// + /// + /// + public async Task Remove( + int id, + string language = null, + string connectionId = null, + XUserClaimsInfoDto userInfo = null, + CancellationToken cancellationToken = default + ) + { + // + // Validate ... + var isValid = id.IsValidIntId(); + if (!isValid) + { + XException.InvalidArgs.Throw(); + } + + // + // Check Item Exists ... + isValid = await IsExists( + id: id, + cancellationToken: cancellationToken + ); + if (!isValid) + { + XException.NotFound.Throw(); + } + + // + // Validate Locale if Provided ... + isValid = + language.IsNullOrEmpty() || + await HasLocale( + id: id, + language: language, + cancellationToken: cancellationToken + ); + if (!isValid) + { + XException.NotFound.Throw(); + } + + // + var result = await GetResource( + id: id, + cancellationToken: cancellationToken + ); + if (language.IsNullOrEmpty()) + { + // + // Remove All ... + + // + // Titles ... + await titleResourceProvider.RemoveLocales( + identifier: id, + connectionId: null, + cancellationToken: cancellationToken + ); + + // + // Descriptions ... + await descriptionResourceProvider.RemoveLocales( + identifier: id, + connectionId: null, + cancellationToken: cancellationToken + ); + + // + // Remove Entity ... + await provider.RemoveAsync( + id: id, + softDelete: false, + saveChanges: true, + connectionId: null, + cancellationToken: cancellationToken + ); + + // + isValid = true; + result.Titles.Locales = []; + result.Descriptions.Locales = []; + } + else + { + // + // Remove Only One Locale, and if there is one, Remove all ... + + // + // Remove Title if Exists ... + isValid = await titleResourceProvider.HasLocale( + identifier: id, + language: language, + cancellationToken: cancellationToken + ); + if (isValid) + { + // + await titleResourceProvider.RemoveLocale( + identifier: id, + language: language, + connectionId: null, + cancellationToken: cancellationToken + ); + } + + // + // Remove Description if Exists ... + isValid = await descriptionResourceProvider.HasLocale( + identifier: id, + language: language, + cancellationToken: cancellationToken + ); + if (isValid) + { + // + await descriptionResourceProvider.RemoveLocale( + identifier: id, + language: language, + connectionId: null, + cancellationToken: cancellationToken + ); + } + + // + // Retrieve Resource ... + result = await GetResource( + id: id, + cancellationToken: cancellationToken + ); + + // + // Check Has Locales ... + isValid = result.Titles.Locales.HasChild(); + if (!isValid) + { + // + // Remove Item ... + await provider.RemoveAsync( + id: id, + softDelete: false, + saveChanges: true, + connectionId: null, + cancellationToken: cancellationToken + ); + + // + result.Titles.Locales = []; + result.Descriptions.Locales = []; + } + + // + isValid = true; + } + + // + if (isValid) + { + // + // Send Push ... + await provider.SendPush( + connectionId: connectionId, + cancellationToken: cancellationToken, + payLoad: result.ToJSON(camelCase: true), + action: + result.Titles.Locales.HasChild() + ? "DeleteLocale" + : XBaseEntityHubAction.Delete.GetStringValue() + ); + } + + // + return result; + } + /// /// Update an Item for Specified Language ... /// @@ -459,6 +642,7 @@ namespace xCategoryService.Providers // var id = -1; + var isDelete = false; XSubCategoryResourceDto result = null; // @@ -580,109 +764,130 @@ namespace xCategoryService.Providers // 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) + // Check Delete ... + isDelete = !resource.Titles.Locales.HasChild(); + if (isDelete) { // - await titleResourceProvider.RemoveLocale( - identifier: id, + // Handle Delete ... + await Remove( + id: id, + language: null, + userInfo: userInfo, connectionId: null, - language: locale.Language, cancellationToken: cancellationToken ); } + else + { + // + // Handle Update ... - // - // 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 + #region Remove ... + // + // Titles ... + var removeTitles = result.Titles.Locales.Where( + l => !resource.Titles.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase)) ); - } - #endregion + foreach (var locale in removeTitles) + { + // + await titleResourceProvider.RemoveLocale( + identifier: id, + connectionId: null, + language: locale.Language, + cancellationToken: cancellationToken + ); + } - // - #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 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 - // - // 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 + #region Update ... + // + // Titles ... + var updateTitles = result.Titles.Locales.Where( + l => resource.Titles.Locales.Any(r => r.Language.Equals(l.Language, System.StringComparison.InvariantCultureIgnoreCase)) ); - } - #endregion + foreach (var locale in updateTitles) + { + // + await titleResourceProvider.AddOrUpdateLocale( + identifier: id, + locale: locale, + connectionId: null, + cancellationToken: cancellationToken + ); + } - // - #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 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 - // - // 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 + #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 } - #endregion } // @@ -695,7 +900,10 @@ namespace xCategoryService.Providers // // Get Result ... - result = await GetResource( + result = + isDelete + ? resource + : await GetResource( id: id, cancellationToken: cancellationToken ); @@ -712,7 +920,9 @@ namespace xCategoryService.Providers payLoad: result.ToJSON(camelCase: true), action: isNew ? XBaseEntityHubAction.Add.GetStringValue() - : XBaseEntityHubAction.Update.GetStringValue() + : isDelete + ? XBaseEntityHubAction.Delete.GetStringValue() + : XBaseEntityHubAction.Update.GetStringValue() ); } diff --git a/xCategoryService.csproj b/xCategoryService.csproj index d2fdf07..5823a7c 100644 --- a/xCategoryService.csproj +++ b/xCategoryService.csproj @@ -32,4 +32,11 @@ + + + true + true + $(NoWarn);1591 + +