Skip to content

Commit b3fd673

Browse files
authored
Implementing store owner settings management (#695)
* feat: add store settings management for store owners - Add SettingController to Grand.Web.Store with GeneralCommon, Catalog, Customer, Sales, Media (no file manager), Content actions - Create views and partials for all settings pages in Store area
1 parent d0af8c3 commit b3fd673

56 files changed

Lines changed: 6137 additions & 33 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/Business/Grand.Business.Checkout/Services/Orders/MerchandiseReturnService.cs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,20 @@ public virtual async Task<IPagedList<MerchandiseReturn>> SearchMerchandiseReturn
117117
/// <summary>
118118
/// Gets all merchandise return actions
119119
/// </summary>
120+
/// <param name="storeId">Store identifier; empty to load all entries</param>
120121
/// <returns>Merchandise return actions</returns>
121-
public virtual async Task<IList<MerchandiseReturnAction>> GetAllMerchandiseReturnActions()
122+
public virtual async Task<IList<MerchandiseReturnAction>> GetAllMerchandiseReturnActions(string storeId = "")
122123
{
123-
return await _cacheBase.GetAsync(CacheKey.MERCHANDISE_RETURN_ACTIONS_ALL_KEY, async () =>
124+
var key = string.Format(CacheKey.MERCHANDISE_RETURN_ACTIONS_ALL_KEY, storeId);
125+
return await _cacheBase.GetAsync(key, async () =>
124126
{
125-
var query = from rra in _merchandiseReturnActionRepository.Table
127+
IQueryable<MerchandiseReturnAction> query = from rra in _merchandiseReturnActionRepository.Table
126128
orderby rra.DisplayOrder
127129
select rra;
128-
return await Task.FromResult(query.ToList());
130+
if (!string.IsNullOrEmpty(storeId))
131+
query = query.Where(x => !x.LimitedToStores || x.Stores.Contains(storeId));
132+
var actions = query.ToList();
133+
return await Task.FromResult(actions);
129134
});
130135
}
131136

@@ -203,7 +208,7 @@ public virtual async Task InsertMerchandiseReturnAction(MerchandiseReturnAction
203208
await _mediator.EntityInserted(merchandiseReturnAction);
204209

205210
//clear cache
206-
await _cacheBase.RemoveByPrefix(CacheKey.MERCHANDISE_RETURN_ACTIONS_ALL_KEY);
211+
await _cacheBase.RemoveByPrefix(CacheKey.MERCHANDISE_RETURN_ACTIONS_PATTERN_KEY);
207212
}
208213

209214
/// <summary>
@@ -220,7 +225,7 @@ public virtual async Task UpdateMerchandiseReturnAction(MerchandiseReturnAction
220225
await _mediator.EntityUpdated(merchandiseReturnAction);
221226

222227
//clear cache
223-
await _cacheBase.RemoveByPrefix(CacheKey.MERCHANDISE_RETURN_ACTIONS_ALL_KEY);
228+
await _cacheBase.RemoveByPrefix(CacheKey.MERCHANDISE_RETURN_ACTIONS_PATTERN_KEY);
224229
}
225230

226231
/// <summary>
@@ -235,6 +240,9 @@ public virtual async Task DeleteMerchandiseReturnAction(MerchandiseReturnAction
235240

236241
//event notification
237242
await _mediator.EntityDeleted(merchandiseReturnAction);
243+
244+
//clear cache
245+
await _cacheBase.RemoveByPrefix(CacheKey.MERCHANDISE_RETURN_ACTIONS_PATTERN_KEY);
238246
}
239247

240248
/// <summary>
@@ -251,21 +259,26 @@ public virtual async Task DeleteMerchandiseReturnReason(MerchandiseReturnReason
251259
await _mediator.EntityDeleted(merchandiseReturnReason);
252260

253261
//clear cache
254-
await _cacheBase.RemoveByPrefix(CacheKey.MERCHANDISE_RETURN_REASONS_ALL_KEY);
262+
await _cacheBase.RemoveByPrefix(CacheKey.MERCHANDISE_RETURN_REASONS_PATTERN_KEY);
255263
}
256264

257265
/// <summary>
258266
/// Gets all merchandise return reasons
259267
/// </summary>
268+
/// <param name="storeId">Store identifier; empty to load all entries</param>
260269
/// <returns>Merchandise return reasons</returns>
261-
public virtual async Task<IList<MerchandiseReturnReason>> GetAllMerchandiseReturnReasons()
270+
public virtual async Task<IList<MerchandiseReturnReason>> GetAllMerchandiseReturnReasons(string storeId = "")
262271
{
263-
return await _cacheBase.GetAsync(CacheKey.MERCHANDISE_RETURN_REASONS_ALL_KEY, async () =>
272+
var key = string.Format(CacheKey.MERCHANDISE_RETURN_REASONS_ALL_KEY, storeId);
273+
return await _cacheBase.GetAsync(key, async () =>
264274
{
265-
var query = from rra in _merchandiseReturnReasonRepository.Table
275+
IQueryable<MerchandiseReturnReason> query = from rra in _merchandiseReturnReasonRepository.Table
266276
orderby rra.DisplayOrder
267277
select rra;
268-
return await Task.FromResult(query.ToList());
278+
if (!string.IsNullOrEmpty(storeId))
279+
query = query.Where(x => !x.LimitedToStores || x.Stores.Contains(storeId));
280+
var reasons = query.ToList();
281+
return await Task.FromResult(reasons);
269282
});
270283
}
271284

@@ -293,7 +306,7 @@ public virtual async Task InsertMerchandiseReturnReason(MerchandiseReturnReason
293306
await _mediator.EntityInserted(merchandiseReturnReason);
294307

295308
//clear cache
296-
await _cacheBase.RemoveByPrefix(CacheKey.MERCHANDISE_RETURN_REASONS_ALL_KEY);
309+
await _cacheBase.RemoveByPrefix(CacheKey.MERCHANDISE_RETURN_REASONS_PATTERN_KEY);
297310
}
298311

299312
/// <summary>
@@ -310,7 +323,7 @@ public virtual async Task UpdateMerchandiseReturnReason(MerchandiseReturnReason
310323
await _mediator.EntityUpdated(merchandiseReturnReason);
311324

312325
//clear cache
313-
await _cacheBase.RemoveByPrefix(CacheKey.MERCHANDISE_RETURN_REASONS_ALL_KEY);
326+
await _cacheBase.RemoveByPrefix(CacheKey.MERCHANDISE_RETURN_REASONS_PATTERN_KEY);
314327
}
315328

316329
#region Merchandise return notes

src/Business/Grand.Business.Core/Interfaces/Checkout/Orders/IMerchandiseReturnService.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ Task<IPagedList<MerchandiseReturn>> SearchMerchandiseReturns(string storeId = ""
6262
/// <summary>
6363
/// Gets all merchandise return actions
6464
/// </summary>
65+
/// <param name="storeId">Store identifier; empty to load all entries</param>
6566
/// <returns>Merchandise return actions</returns>
66-
Task<IList<MerchandiseReturnAction>> GetAllMerchandiseReturnActions();
67+
Task<IList<MerchandiseReturnAction>> GetAllMerchandiseReturnActions(string storeId = "");
6768

6869
/// <summary>
6970
/// Gets a merchandise return action
@@ -93,8 +94,9 @@ Task<IPagedList<MerchandiseReturn>> SearchMerchandiseReturns(string storeId = ""
9394
/// <summary>
9495
/// Gets all merchandise return reasons
9596
/// </summary>
97+
/// <param name="storeId">Store identifier; empty to load all entries</param>
9698
/// <returns>Merchandise return reasons</returns>
97-
Task<IList<MerchandiseReturnReason>> GetAllMerchandiseReturnReasons();
99+
Task<IList<MerchandiseReturnReason>> GetAllMerchandiseReturnReasons(string storeId = "");
98100

99101
/// <summary>
100102
/// Gets a merchandise return reasons

src/Core/Grand.Domain/Orders/MerchandiseReturnAction.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using Grand.Domain.Localization;
2+
using Grand.Domain.Stores;
23

34
namespace Grand.Domain.Orders;
45

56
/// <summary>
67
/// Represents a merchandise return action
78
/// </summary>
8-
public class MerchandiseReturnAction : BaseEntity, ITranslationEntity
9+
public class MerchandiseReturnAction : BaseEntity, ITranslationEntity, IStoreLinkEntity
910
{
1011
/// <summary>
1112
/// Gets or sets the name
@@ -21,4 +22,14 @@ public class MerchandiseReturnAction : BaseEntity, ITranslationEntity
2122
/// Gets or sets the collection of locales
2223
/// </summary>
2324
public IList<TranslationEntity> Locales { get; set; } = new List<TranslationEntity>();
25+
26+
/// <summary>
27+
/// Gets or sets a value indicating whether the entity is limited/restricted to certain stores
28+
/// </summary>
29+
public bool LimitedToStores { get; set; }
30+
31+
/// <summary>
32+
/// Gets or sets the stores
33+
/// </summary>
34+
public IList<string> Stores { get; set; } = new List<string>();
2435
}

src/Core/Grand.Domain/Orders/MerchandiseReturnReason.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using Grand.Domain.Localization;
2+
using Grand.Domain.Stores;
23

34
namespace Grand.Domain.Orders;
45

56
/// <summary>
67
/// Represents a merchandise return reason
78
/// </summary>
8-
public class MerchandiseReturnReason : BaseEntity, ITranslationEntity
9+
public class MerchandiseReturnReason : BaseEntity, ITranslationEntity, IStoreLinkEntity
910
{
1011
/// <summary>
1112
/// Gets or sets the name
@@ -21,4 +22,14 @@ public class MerchandiseReturnReason : BaseEntity, ITranslationEntity
2122
/// Gets or sets the collection of locales
2223
/// </summary>
2324
public IList<TranslationEntity> Locales { get; set; } = new List<TranslationEntity>();
25+
26+
/// <summary>
27+
/// Gets or sets a value indicating whether the entity is limited/restricted to certain stores
28+
/// </summary>
29+
public bool LimitedToStores { get; set; }
30+
31+
/// <summary>
32+
/// Gets or sets the stores
33+
/// </summary>
34+
public IList<string> Stores { get; set; } = new List<string>();
2435
}

src/Core/Grand.Infrastructure/Caching/Constants/MerchandiseReturnCacheKey.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,22 @@
33
public static partial class CacheKey
44
{
55
/// <summary>
6-
/// Key for all merchandise return reason
6+
/// Key for all merchandise return reasons. {0} - store ID
77
/// </summary>
8-
public static string MERCHANDISE_RETURN_REASONS_ALL_KEY => "Grand.merchandisereturn.reasons.all";
8+
public static string MERCHANDISE_RETURN_REASONS_ALL_KEY => "Grand.merchandisereturn.reasons.all-{0}";
99

1010
/// <summary>
11-
/// Key for all merchandise return actions
11+
/// Key pattern to clear merchandise return reasons cache
1212
/// </summary>
13-
public static string MERCHANDISE_RETURN_ACTIONS_ALL_KEY => "Grand.merchandisereturn.actions.all";
13+
public static string MERCHANDISE_RETURN_REASONS_PATTERN_KEY => "Grand.merchandisereturn.reasons";
14+
15+
/// <summary>
16+
/// Key for all merchandise return actions. {0} - store ID
17+
/// </summary>
18+
public static string MERCHANDISE_RETURN_ACTIONS_ALL_KEY => "Grand.merchandisereturn.actions.all-{0}";
19+
20+
/// <summary>
21+
/// Key pattern to clear merchandise return actions cache
22+
/// </summary>
23+
public static string MERCHANDISE_RETURN_ACTIONS_PATTERN_KEY => "Grand.merchandisereturn.actions";
1424
}

src/Modules/Grand.Module.Installer/Utilities/StandardAdminSiteMap.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,7 @@ public static class StandardAdminSiteMap
967967
new() {
968968
SystemName = "Vendor settings",
969969
ResourceName = "Admin.Settings.Vendor",
970+
PermissionNames = new List<string> { PermissionSystemName.System },
970971
ControllerName = "Setting",
971972
ActionName = "Vendor",
972973
DisplayOrder = 6,
@@ -975,6 +976,7 @@ public static class StandardAdminSiteMap
975976
new() {
976977
SystemName = "Push notifications settings",
977978
ResourceName = "Admin.Settings.PushNotifications",
979+
PermissionNames = new List<string> { PermissionSystemName.System },
978980
ControllerName = "Setting",
979981
ActionName = "PushNotifications",
980982
DisplayOrder = 7,
@@ -983,6 +985,7 @@ public static class StandardAdminSiteMap
983985
new() {
984986
SystemName = "Admin search settings",
985987
ResourceName = "Admin.Settings.AdminSearch",
988+
PermissionNames = new List<string> { PermissionSystemName.System },
986989
ControllerName = "Setting",
987990
ActionName = "AdminSearch",
988991
DisplayOrder = 8,
@@ -991,6 +994,7 @@ public static class StandardAdminSiteMap
991994
new() {
992995
SystemName = "System settings",
993996
ResourceName = "Admin.Settings.System",
997+
PermissionNames = new List<string> { PermissionSystemName.System },
994998
ControllerName = "Setting",
995999
ActionName = "SystemSetting",
9961000
DisplayOrder = 9,
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using Grand.Data;
2+
using Grand.Domain.Admin;
3+
using Grand.Domain.Permissions;
4+
using Grand.Infrastructure.Migrations;
5+
using Microsoft.Extensions.DependencyInjection;
6+
using Microsoft.Extensions.Logging;
7+
8+
namespace Grand.Module.Migration.Migrations._2._4;
9+
10+
public class MigrationUpdateAdminSiteMap : IMigration
11+
{
12+
public int Priority => 1;
13+
public DbVersion Version => new(2, 4);
14+
public Guid Identity => new("B7C3D8E2-F1A4-4B9E-8C62-197E3F5A4D21");
15+
public string Name => "Update standard admin site map - restrict Vendor, Push notifications, Admin search, System settings to System permission";
16+
17+
/// <summary>
18+
/// Upgrade process
19+
/// </summary>
20+
/// <param name="serviceProvider"></param>
21+
/// <returns></returns>
22+
public bool UpgradeProcess(IServiceProvider serviceProvider)
23+
{
24+
var repository = serviceProvider.GetRequiredService<IRepository<AdminSiteMap>>();
25+
var logService = serviceProvider.GetRequiredService<ILogger<MigrationUpdateAdminSiteMap>>();
26+
27+
try
28+
{
29+
var sitemapSettings = repository.Table.FirstOrDefault(x => x.SystemName == "Settings");
30+
if (sitemapSettings == null) return true;
31+
32+
var adminOnlyItems = new[] {
33+
"Vendor settings",
34+
"Push notifications settings",
35+
"Admin search settings",
36+
"System settings"
37+
};
38+
39+
foreach (var itemName in adminOnlyItems)
40+
{
41+
var item = sitemapSettings.ChildNodes.FirstOrDefault(x => x.SystemName == itemName);
42+
if (item != null && !item.PermissionNames.Contains(PermissionSystemName.System))
43+
item.PermissionNames.Add(PermissionSystemName.System);
44+
}
45+
46+
repository.Update(sitemapSettings);
47+
}
48+
catch (InvalidOperationException ex)
49+
{
50+
logService.LogError(ex, "UpgradeProcess - UpdateAdminSiteMap (2.4)");
51+
}
52+
53+
return true;
54+
}
55+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
Name: Refund,
33
DisplayOrder: 1,
4+
LimitedToStores: false,
45
Id: ObjectId_1
56
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
Name: Defective,
33
DisplayOrder: 1,
4+
LimitedToStores: false,
45
Id: ObjectId_1
56
}

src/Web/Grand.Web.Admin/Areas/Admin/Views/Setting/Partials/CreateOrUpdate.MerchandiseReturnAction.cshtml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,12 @@
4040
<span asp-validation-for="DisplayOrder"></span>
4141
</div>
4242
</div>
43+
<div class="form-group">
44+
<admin-label asp-for="Stores"/>
45+
<div class="col-md-9 col-sm-9">
46+
<admin-input asp-for="Stores"/>
47+
<span asp-validation-for="Stores"></span>
48+
</div>
49+
</div>
4350
</div>
4451
</div>

0 commit comments

Comments
 (0)