diff --git a/src/Web/Grand.SharedUIResources/wwwroot/administration/build/css/custom-rtl.css b/src/Web/Grand.SharedUIResources/wwwroot/administration/build/css/custom-rtl.css index 1d943f991..28d0ff2e6 100644 --- a/src/Web/Grand.SharedUIResources/wwwroot/administration/build/css/custom-rtl.css +++ b/src/Web/Grand.SharedUIResources/wwwroot/administration/build/css/custom-rtl.css @@ -6986,7 +6986,6 @@ h2 { color: #f9f9f9; } [data-theme="dark"] .k-grid table a, [data-theme="dark"] .premium-list li span { - color: #A5D8FE; font-weight: 500; } [data-theme="dark"] .toggle a span { diff --git a/src/Web/Grand.SharedUIResources/wwwroot/administration/build/css/custom.css b/src/Web/Grand.SharedUIResources/wwwroot/administration/build/css/custom.css index 2d86c5d94..ab00b02d3 100644 --- a/src/Web/Grand.SharedUIResources/wwwroot/administration/build/css/custom.css +++ b/src/Web/Grand.SharedUIResources/wwwroot/administration/build/css/custom.css @@ -7094,7 +7094,6 @@ table.tableFixHead { color: #f9f9f9; } [data-theme="dark"] .k-grid table a, [data-theme="dark"] .premium-list li span { - color: #A5D8FE; font-weight: 500; } [data-theme="dark"] .toggle a span { diff --git a/src/Web/Grand.Web.Store/Areas/Store/Views/Currency/List.cshtml b/src/Web/Grand.Web.Store/Areas/Store/Views/Currency/List.cshtml new file mode 100644 index 000000000..5a658fb1f --- /dev/null +++ b/src/Web/Grand.Web.Store/Areas/Store/Views/Currency/List.cshtml @@ -0,0 +1,216 @@ +@inject AdminAreaSettings adminAreaSettings +@{ + ViewBag.Title = Loc["Admin.Configuration.Currencies"]; + Layout = Constants.LayoutStore; +} + +
+
+
+
+
+ + @Loc["Admin.Configuration.Currencies"] +
+
+
+
+
+
+
+
+ + diff --git a/src/Web/Grand.Web.Store/Controllers/CurrencyController.cs b/src/Web/Grand.Web.Store/Controllers/CurrencyController.cs new file mode 100644 index 000000000..3004601f1 --- /dev/null +++ b/src/Web/Grand.Web.Store/Controllers/CurrencyController.cs @@ -0,0 +1,164 @@ +using Grand.Business.Core.Interfaces.Common.Directory; +using Grand.Business.Core.Interfaces.Common.Localization; +using Grand.Business.Core.Interfaces.Common.Stores; +using Grand.Domain.Directory; +using Grand.Domain.Permissions; +using Grand.Infrastructure; +using Grand.Web.Common.DataSource; +using Grand.Web.Common.Security.Authorization; +using Grand.Web.Store.Models; +using Microsoft.AspNetCore.Mvc; + +namespace Grand.Web.Store.Controllers; + +[PermissionAuthorize(PermissionSystemName.Currencies)] +public class CurrencyController( + ICurrencyService currencyService, + CurrencySettings currencySettings, + ITranslationService translationService, + IStoreService storeService, + IContextAccessor contextAccessor) : BaseStoreController +{ + private string CurrentStoreId => contextAccessor.WorkContext.CurrentCustomer.StaffStoreId; + + public IActionResult Index() + { + return RedirectToAction("List"); + } + + [PermissionAuthorizeAction(PermissionActionName.List)] + public IActionResult List() + { + return View(); + } + + [HttpPost] + [PermissionAuthorizeAction(PermissionActionName.List)] + public async Task ListData() + { + var storeId = CurrentStoreId; + var primaryStoreCurrencyId = currencySettings.PrimaryStoreCurrencyId; + + var store = await storeService.GetStoreById(storeId); + var defaultCurrencyId = store?.DefaultCurrencyId; + + var currencies = await currencyService.GetAllCurrencies(showHidden: false); + + var items = currencies + .Select(c => new StoreCurrencyModel { + Id = c.Id, + Name = c.Name, + CurrencyCode = c.CurrencyCode, + Published = c.Published, + DisplayOrder = c.DisplayOrder, + LimitedToStores = c.LimitedToStores, + IsAssignedToCurrentStore = !c.LimitedToStores || c.Stores.Contains(storeId), + IsPrimaryStoreCurrency = c.Id == primaryStoreCurrencyId, + IsDefaultStoreCurrency = c.Id == defaultCurrencyId, + CanManage = c.LimitedToStores + }) + .ToList(); + + var gridModel = new DataSourceResult { + Data = items, + Total = items.Count + }; + + return Json(gridModel); + } + + [HttpPost] + [PermissionAuthorizeAction(PermissionActionName.Edit)] + public async Task AssignStore(string id) + { + var currency = await currencyService.GetCurrencyById(id); + if (currency == null) + return Json(new { success = false, message = translationService.GetResource("Admin.Configuration.Currencies.NotFound") }); + + if (!currency.LimitedToStores) + return Json(new { success = false, message = translationService.GetResource("Admin.Configuration.Currencies.CannotModifyGlobal") }); + + var storeId = CurrentStoreId; + if (!currency.Stores.Contains(storeId)) + { + currency.Stores.Add(storeId); + await currencyService.UpdateCurrency(currency); + } + + return Json(new { success = true }); + } + + [HttpPost] + [PermissionAuthorizeAction(PermissionActionName.Edit)] + public async Task UnassignStore(string id) + { + var currency = await currencyService.GetCurrencyById(id); + if (currency == null) + return Json(new { success = false, message = translationService.GetResource("Admin.Configuration.Currencies.NotFound") }); + + if (!currency.LimitedToStores) + return Json(new { success = false, message = translationService.GetResource("Admin.Configuration.Currencies.CannotModifyGlobal") }); + + if (currency.Id == currencySettings.PrimaryStoreCurrencyId) + return Json(new { success = false, message = translationService.GetResource("Admin.Configuration.Currencies.CantDeletePrimary") }); + + var storeId = CurrentStoreId; + + var store = await storeService.GetStoreById(storeId); + if (store?.DefaultCurrencyId == currency.Id) + return Json(new { success = false, message = translationService.GetResource("Admin.Configuration.Currencies.CantUnassignDefault") }); + + if (currency.Stores.Remove(storeId)) + await currencyService.UpdateCurrency(currency); + + return Json(new { success = true }); + } + + [HttpPost] + [PermissionAuthorizeAction(PermissionActionName.Edit)] + public async Task SetDefaultCurrency(string id) + { + var currency = await currencyService.GetCurrencyById(id); + if (currency == null) + return Json(new { success = false, message = translationService.GetResource("Admin.Configuration.Currencies.NotFound") }); + + if (!currency.Published) + return Json(new { success = false, message = translationService.GetResource("Admin.Configuration.Currencies.NotPublished") }); + + var storeId = CurrentStoreId; + + if (currency.LimitedToStores && !currency.Stores.Contains(storeId)) + return Json(new { success = false, message = translationService.GetResource("Admin.Configuration.Currencies.NotAssignedToStore") }); + + var store = await storeService.GetStoreById(storeId); + if (store == null) + return Json(new { success = false, message = translationService.GetResource("Admin.Configuration.Stores.NotFound") }); + + store.DefaultCurrencyId = currency.Id; + await storeService.UpdateStore(store); + + return Json(new { success = true }); + } + + [HttpPost] + [PermissionAuthorizeAction(PermissionActionName.Edit)] + public async Task UnsetDefaultCurrency(string id) + { + var currency = await currencyService.GetCurrencyById(id); + if (currency == null) + return Json(new { success = false, message = translationService.GetResource("Admin.Configuration.Currencies.NotFound") }); + + var storeId = CurrentStoreId; + var store = await storeService.GetStoreById(storeId); + if (store == null) + return Json(new { success = false, message = translationService.GetResource("Admin.Configuration.Stores.NotFound") }); + + if (store.DefaultCurrencyId != currency.Id) + return Json(new { success = false, message = translationService.GetResource("Admin.Configuration.Currencies.NotDefaultCurrency") }); + + store.DefaultCurrencyId = string.Empty; + await storeService.UpdateStore(store); + + return Json(new { success = true }); + } +} diff --git a/src/Web/Grand.Web.Store/Models/StoreCurrencyModel.cs b/src/Web/Grand.Web.Store/Models/StoreCurrencyModel.cs new file mode 100644 index 000000000..50e569202 --- /dev/null +++ b/src/Web/Grand.Web.Store/Models/StoreCurrencyModel.cs @@ -0,0 +1,15 @@ +namespace Grand.Web.Store.Models; + +public class StoreCurrencyModel +{ + public string Id { get; set; } + public string Name { get; set; } + public string CurrencyCode { get; set; } + public bool Published { get; set; } + public int DisplayOrder { get; set; } + public bool LimitedToStores { get; set; } + public bool IsAssignedToCurrentStore { get; set; } + public bool IsPrimaryStoreCurrency { get; set; } + public bool IsDefaultStoreCurrency { get; set; } + public bool CanManage { get; set; } +} diff --git a/src/Web/Grand.Web/App_Data/Resources/DefaultLanguage.xml b/src/Web/Grand.Web/App_Data/Resources/DefaultLanguage.xml index 527aba66d..94f18f262 100644 Binary files a/src/Web/Grand.Web/App_Data/Resources/DefaultLanguage.xml and b/src/Web/Grand.Web/App_Data/Resources/DefaultLanguage.xml differ