Browse Source

Multi-store, basic CRUD and authorization handlers.

pull/157/head
gdlcf88 4 years ago
parent
commit
7cb5fed279
  1. 2
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductDetails/ProductDetailAppService.cs
  2. 11
      modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductAppService.cs
  3. 7
      modules/EasyAbp.EShop.Stores/src/EasyAbp.EShop.Stores.Application.Shared/EasyAbp/EShop/Stores/Stores/MultiStoreAbstractKeyCrudAppService.cs
  4. 4
      modules/EasyAbp.EShop.Stores/src/EasyAbp.EShop.Stores.Application.Shared/EasyAbp/EShop/Stores/Stores/MultiStoreCrudAppService.cs
  5. 1
      plugins/Booking/src/EasyAbp.EShop.Orders.Booking.Application/EasyAbp.EShop.Orders.Booking.Application.csproj
  6. 153
      plugins/Booking/src/EasyAbp.EShop.Orders.Booking.Application/EasyAbp/EShop/Orders/Booking/Authorization/BookingOrderCreationAuthorizationHandler.cs
  7. 6
      plugins/Booking/src/EasyAbp.EShop.Orders.Booking.Application/EasyAbp/EShop/Orders/Booking/EShopOrdersBookingApplicationModule.cs
  8. 2
      plugins/Booking/src/EasyAbp.EShop.Orders.Booking.Application/EasyAbp/EShop/Orders/Booking/ObjectExtending/EShopOrdersPluginsBookingObjectExtensions.cs
  9. 1
      plugins/Booking/src/EasyAbp.EShop.Payments.Booking.Application/EasyAbp.EShop.Payments.Booking.Application.csproj
  10. 179
      plugins/Booking/src/EasyAbp.EShop.Payments.Booking.Application/EasyAbp/EShop/Payments/Booking/Authorization/BookingPaymentCreationAuthorizationHandler.cs
  11. 6
      plugins/Booking/src/EasyAbp.EShop.Payments.Booking.Application/EasyAbp/EShop/Payments/Booking/EShopPaymentsBookingApplicationModule.cs
  12. 4
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Orders/BookingOrderProperties.cs
  13. 10
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Orders/CreateOrderLineDtoExtensions.cs
  14. 10
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Orders/OrderLineExtensions.cs
  15. 2
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/Permissions/BookingPermissionDefinitionProvider.cs
  16. 2
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/Permissions/BookingPermissions.cs
  17. 5
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/Dtos/CreateProductAssetCategoryDto.cs
  18. 18
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/Dtos/GetProductAssetCategoryDto.cs
  19. 2
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/Dtos/ProductAssetCategoryDto.cs
  20. 3
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/IProductAssetCategoryAppService.cs
  21. 5
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssets/Dtos/CreateProductAssetDto.cs
  22. 18
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssets/Dtos/GetProductAssetDto.cs
  23. 2
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssets/Dtos/ProductAssetDto.cs
  24. 2
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssets/IProductAssetAppService.cs
  25. 3
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application/EasyAbp.EShop.Plugins.Booking.Application.csproj
  26. 4
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application/EasyAbp/EShop/Plugins/Booking/BookingApplicationAutoMapperProfile.cs
  27. 8
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application/EasyAbp/EShop/Plugins/Booking/EShopPluginsBookingApplicationModule.cs
  28. 152
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategoryAppService.cs
  29. 130
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application/EasyAbp/EShop/Plugins/Booking/ProductAssets/ProductAssetAppService.cs
  30. 3
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain.Shared/EasyAbp/EShop/Plugins/Booking/BookingErrorCodes.cs
  31. 5
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain.Shared/EasyAbp/EShop/Plugins/Booking/Localization/en.json
  32. 5
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain.Shared/EasyAbp/EShop/Plugins/Booking/Localization/zh-Hans.json
  33. 5
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain.Shared/EasyAbp/EShop/Plugins/Booking/Localization/zh-Hant.json
  34. 1
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp.EShop.Plugins.Booking.Domain.csproj
  35. 4
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/EShopPluginsBookingDomainModule.cs
  36. 6
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/IProductAssetCategoryRepository.cs
  37. 15
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory.cs
  38. 43
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetManager.cs
  39. 6
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/ProductAssets/IProductAssetRepository.cs
  40. 16
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/ProductAssets/ProductAsset.cs
  41. 43
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/ProductAssets/ProductAssetManager.cs
  42. 33
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategoryRepository.cs
  43. 38
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore/EasyAbp/EShop/Plugins/Booking/ProductAssets/ProductAssetRepository.cs
  44. 4
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore/EasyAbp/EShop/Plugins/Booking/StoreAssetCategories/StoreAssetCategoryEfCoreQuerableExtensions.cs
  45. 3
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.HttpApi/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategoryController.cs
  46. 2
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.HttpApi/EasyAbp/EShop/Plugins/Booking/ProductAssets/ProductAssetController.cs
  47. 12
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/EasyAbp.EShop.Plugins.Booking.Web.csproj
  48. 2
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/CreateModal.cshtml.cs
  49. 69
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/Index.cshtml
  50. 5
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/Index.cshtml.cs
  51. 5
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/ViewModels/CreateProductAssetCategoryViewModel.cs
  52. 19
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/ViewModels/ProductAssetCategoryListFilterViewModel.cs
  53. 13
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/index.js
  54. 2
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/CreateModal.cshtml.cs
  55. 69
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/Index.cshtml
  56. 5
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/Index.cshtml.cs
  57. 6
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/ViewModels/CreateProductAssetViewModel.cs
  58. 20
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/ViewModels/ProductAssetListFilterViewModel.cs
  59. 13
      plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/index.js
  60. 5416
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220603163430_AddedStoreIdInProductAssetAndProductAssetCategory.Designer.cs
  61. 38
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220603163430_AddedStoreIdInProductAssetAndProductAssetCategory.cs
  62. 6
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs

2
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductDetails/ProductDetailAppService.cs

@ -83,7 +83,7 @@ namespace EasyAbp.EShop.Products.ProductDetails
ProductsPermissions.Products.CrossStore);
}
MapToEntity(input, detail);
await MapToEntityAsync(input, detail);
await Repository.UpdateAsync(detail, autoSave: true);

11
modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductAppService.cs

@ -61,16 +61,9 @@ namespace EasyAbp.EShop.Products.Products
.WhereIf(!input.ShowUnpublished, x => x.IsPublished);
}
protected override Product MapToEntity(CreateUpdateProductDto createInput)
{
var product = base.MapToEntity(createInput);
return product;
}
public override async Task<ProductDto> CreateAsync(CreateUpdateProductDto input)
{
var product = MapToEntity(input);
var product = await MapToEntityAsync(input);
await CheckMultiStorePolicyAsync(product.StoreId, CreatePolicyName);
@ -111,7 +104,7 @@ namespace EasyAbp.EShop.Products.Products
CheckProductIsNotStatic(product);
MapToEntity(input, product);
await MapToEntityAsync(input, product);
await UpdateProductAttributesAsync(product, input);

7
modules/EasyAbp.EShop.Stores/src/EasyAbp.EShop.Stores.Application.Shared/EasyAbp/EShop/Stores/Stores/MultiStoreAbstractKeyCrudAppService.cs

@ -62,7 +62,7 @@ namespace EasyAbp.EShop.Stores.Stores
where TEntity : class, IEntity, IMultiStore
where TCreateInput : IMultiStore
{
protected virtual string CrossStorePolicyName { get; set; }
protected abstract string CrossStorePolicyName { get; set; }
protected MultiStoreAbstractKeyCrudAppService(IRepository<TEntity> repository)
: base(repository)
@ -82,7 +82,7 @@ namespace EasyAbp.EShop.Stores.Stores
{
await CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName);
var entity = MapToEntity(input);
var entity = await MapToEntityAsync(input);
TryToSetTenantId(entity);
@ -96,7 +96,7 @@ namespace EasyAbp.EShop.Stores.Stores
var entity = await GetEntityByIdAsync(id);
await CheckMultiStorePolicyAsync(entity.StoreId, UpdatePolicyName);
MapToEntity(input, entity);
await MapToEntityAsync(input, entity);
await Repository.UpdateAsync(entity, autoSave: true);
return await MapToGetOutputDtoAsync(entity);
@ -110,7 +110,6 @@ namespace EasyAbp.EShop.Stores.Stores
await DeleteByIdAsync(id);
}
protected virtual async Task CheckMultiStorePolicyAsync(Guid? storeId, string policyName, bool crossStoreAllowed = true)
{
if (crossStoreAllowed)

4
modules/EasyAbp.EShop.Stores/src/EasyAbp.EShop.Stores.Application.Shared/EasyAbp/EShop/Stores/Stores/MultiStoreCrudAppService.cs

@ -79,14 +79,14 @@ namespace EasyAbp.EShop.Stores.Stores
return await Repository.GetAsync(id);
}
protected override void MapToEntity(TUpdateInput updateInput, TEntity entity)
protected override Task MapToEntityAsync(TUpdateInput updateInput, TEntity entity)
{
if (updateInput is IEntityDto<TKey> entityDto)
{
entityDto.Id = entity.Id;
}
base.MapToEntity(updateInput, entity);
return base.MapToEntityAsync(updateInput, entity);
}
protected override IQueryable<TEntity> ApplyDefaultSorting(IQueryable<TEntity> query)

1
plugins/Booking/src/EasyAbp.EShop.Orders.Booking.Application/EasyAbp.EShop.Orders.Booking.Application.csproj

@ -8,6 +8,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\..\EasyAbp.BookingService\src\EasyAbp.BookingService.Application.Contracts\EasyAbp.BookingService.Application.Contracts.csproj" />
<ProjectReference Include="..\..\..\..\modules\EasyAbp.EShop.Orders\src\EasyAbp.EShop.Orders.Application\EasyAbp.EShop.Orders.Application.csproj" />
<ProjectReference Include="..\EasyAbp.EShop.Plugins.Booking.Application.Contracts\EasyAbp.EShop.Plugins.Booking.Application.Contracts.csproj" />
</ItemGroup>

153
plugins/Booking/src/EasyAbp.EShop.Orders.Booking.Application/EasyAbp/EShop/Orders/Booking/Authorization/BookingOrderCreationAuthorizationHandler.cs

@ -1,21 +1,45 @@
using System.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using EasyAbp.BookingService.AssetOccupancies;
using EasyAbp.BookingService.AssetOccupancies.Dtos;
using EasyAbp.BookingService.PeriodSchemes;
using EasyAbp.EShop.Orders.Orders;
using EasyAbp.EShop.Orders.Orders.Dtos;
using EasyAbp.EShop.Plugins.Booking.BookingProductGroupDefinitions;
using EasyAbp.EShop.Plugins.Booking.ProductAssetCategories;
using EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.Dtos;
using EasyAbp.EShop.Plugins.Booking.ProductAssets;
using EasyAbp.EShop.Plugins.Booking.ProductAssets.Dtos;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp;
namespace EasyAbp.EShop.Orders.Booking.Authorization
{
public class BookingOrderCreationAuthorizationHandler : OrderCreationAuthorizationHandler
{
private readonly IPeriodSchemeAppService _periodSchemeAppService;
private readonly IProductAssetAppService _productAssetAppService;
private readonly IProductAssetCategoryAppService _productAssetCategoryAppService;
private readonly IAssetOccupancyAppService _assetOccupancyAppService;
private readonly IBookingProductGroupDefinitionAppService _definitionAppService;
public BookingOrderCreationAuthorizationHandler(
IPeriodSchemeAppService periodSchemeAppService,
IProductAssetAppService productAssetAppService,
IProductAssetCategoryAppService productAssetCategoryAppService,
IAssetOccupancyAppService assetOccupancyAppService,
IBookingProductGroupDefinitionAppService definitionAppService)
{
_periodSchemeAppService = periodSchemeAppService;
_productAssetAppService = productAssetAppService;
_productAssetCategoryAppService = productAssetCategoryAppService;
_assetOccupancyAppService = assetOccupancyAppService;
_definitionAppService = definitionAppService;
}
protected override async Task HandleOrderCreationAsync(AuthorizationHandlerContext context,
OrderOperationAuthorizationRequirement requirement, OrderCreationResource resource)
{
@ -29,26 +53,133 @@ namespace EasyAbp.EShop.Orders.Booking.Authorization
return;
}
var models = new List<OccupyAssetInfoModel>();
var byCategoryModels = new List<OccupyAssetByCategoryInfoModel>();
foreach (var orderLine in bookingOrderLines)
{
if (!await IsPeriodInfoValidAsync(orderLine))
{
context.Fail();
return;
}
var assetId = orderLine.FindBookingAssetId();
var assetCategoryId = orderLine.FindBookingAssetCategoryId();
if (assetId is not null)
{
// Todo: Invoke IProductAssetAppService to check the mapping.
}
else
if (!await IsAssetInfoValidAsync(orderLine, resource))
{
context.Fail();
return;
}
var bookingDate =
Check.NotNull(orderLine.FindBookingDate(), BookingOrderProperties.OrderLineBookingDate)!.Value;
var bookingStartingTime = Check.NotNull(orderLine.FindBookingStartingTime(),
BookingOrderProperties.OrderLineBookingStartingTime)!.Value;
var bookingDuration = Check.NotNull(orderLine.FindBookingDuration(),
BookingOrderProperties.OrderLineBookingDuration)!.Value;
models.Add(new OccupyAssetInfoModel(
assetId.Value, bookingDate, bookingStartingTime, bookingDuration));
}
else if (assetCategoryId is not null)
{
var assetCategoryId = orderLine.FindBookingAssetCategoryId();
if (assetCategoryId is null)
if (!await IsAssetCategoryInfoValidAsync(orderLine, resource))
{
context.Fail();
return;
}
// Todo: Invoke IProductAssetCategoryAppService to check the mapping.
var bookingDate =
Check.NotNull(orderLine.FindBookingDate(), BookingOrderProperties.OrderLineBookingDate)!.Value;
var bookingStartingTime = Check.NotNull(orderLine.FindBookingStartingTime(),
BookingOrderProperties.OrderLineBookingStartingTime)!.Value;
var bookingDuration = Check.NotNull(orderLine.FindBookingDuration(),
BookingOrderProperties.OrderLineBookingDuration)!.Value;
byCategoryModels.Add(new OccupyAssetByCategoryInfoModel(
assetCategoryId.Value, bookingDate, bookingStartingTime, bookingDuration));
}
else
{
context.Fail();
return;
}
// Todo: Invoke IAssetOccupancyAppService (in EasyAbp.EShop.Plugins.Booking, not EasyAbp.BookingService) to check the booking info.
}
try
{
await _assetOccupancyAppService.CheckBulkCreateAsync(new BulkCreateAssetOccupancyDto
{
OccupierUserId = Check.NotNull(context.User.FindUserId(), "CurrentUserId"),
Models = models,
ByCategoryModels = byCategoryModels
});
}
catch
{
context.Fail();
return;
}
}
protected virtual async Task<bool> IsAssetInfoValidAsync(CreateOrderLineDto orderLine,
OrderCreationResource resource)
{
var productAsset = (await _productAssetAppService.GetListAsync(
new GetProductAssetDto
{
MaxResultCount = 1,
StoreId = resource.Input.StoreId,
ProductId = orderLine.ProductId,
ProductSkuId = orderLine.ProductSkuId,
AssetId = orderLine.FindBookingAssetId(),
PeriodSchemeId = orderLine.FindBookingPeriodSchemeId()
}
)).Items.FirstOrDefault();
return productAsset is not null;
}
protected virtual async Task<bool> IsAssetCategoryInfoValidAsync(CreateOrderLineDto orderLine,
OrderCreationResource resource)
{
var productAssetCategory = (await _productAssetCategoryAppService.GetListAsync(
new GetProductAssetCategoryDto
{
MaxResultCount = 1,
StoreId = resource.Input.StoreId,
ProductId = orderLine.ProductId,
ProductSkuId = orderLine.ProductSkuId,
AssetCategoryId = orderLine.FindBookingAssetCategoryId(),
PeriodSchemeId = orderLine.FindBookingPeriodSchemeId()
}
)).Items.FirstOrDefault();
return productAssetCategory is not null;
}
protected virtual async Task<bool> IsPeriodInfoValidAsync(CreateOrderLineDto orderLine)
{
var periodSchemeId = orderLine.FindBookingPeriodSchemeId();
var periodId = orderLine.FindBookingPeriodId();
if (periodSchemeId is null || periodId is null)
{
return false;
}
var periodScheme = await _periodSchemeAppService.GetAsync(periodSchemeId.Value);
var period = periodScheme.Periods.Find(x => x.Id == periodId);
return period is not null;
}
}
}
}

6
plugins/Booking/src/EasyAbp.EShop.Orders.Booking.Application/EasyAbp/EShop/Orders/Booking/EShopOrdersBookingApplicationModule.cs

@ -1,11 +1,13 @@
using EasyAbp.EShop.Orders.Booking.ObjectExtending;
using EasyAbp.BookingService;
using EasyAbp.EShop.Orders.Booking.ObjectExtending;
using Volo.Abp.Modularity;
namespace EasyAbp.EShop.Orders.Booking
{
[DependsOn(
typeof(EShopOrdersApplicationModule),
typeof(EShopOrdersApplicationContractsModule)
typeof(EShopOrdersApplicationContractsModule),
typeof(BookingServiceApplicationContractsModule)
)]
public class EShopOrdersBookingApplicationModule : AbpModule
{

2
plugins/Booking/src/EasyAbp.EShop.Orders.Booking.Application/EasyAbp/EShop/Orders/Booking/ObjectExtending/EShopOrdersPluginsBookingObjectExtensions.cs

@ -42,6 +42,8 @@ namespace EasyAbp.EShop.Orders.Booking.ObjectExtending
{
config.AddOrUpdateProperty<Guid?>(BookingOrderProperties.OrderLineBookingAssetId);
config.AddOrUpdateProperty<Guid?>(BookingOrderProperties.OrderLineBookingAssetCategoryId);
config.AddOrUpdateProperty<Guid?>(BookingOrderProperties.OrderLineBookingPeriodSchemeId);
config.AddOrUpdateProperty<Guid?>(BookingOrderProperties.OrderLineBookingPeriodId);
config.AddOrUpdateProperty<DateTime?>(BookingOrderProperties.OrderLineBookingDate);
config.AddOrUpdateProperty<TimeSpan?>(BookingOrderProperties.OrderLineBookingStartingTime);
config.AddOrUpdateProperty<TimeSpan?>(BookingOrderProperties.OrderLineBookingDuration);

1
plugins/Booking/src/EasyAbp.EShop.Payments.Booking.Application/EasyAbp.EShop.Payments.Booking.Application.csproj

@ -8,6 +8,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\..\EasyAbp.BookingService\src\EasyAbp.BookingService.Application.Contracts\EasyAbp.BookingService.Application.Contracts.csproj" />
<ProjectReference Include="..\..\..\..\modules\EasyAbp.EShop.Payments\src\EasyAbp.EShop.Payments.Application\EasyAbp.EShop.Payments.Application.csproj" />
<ProjectReference Include="..\EasyAbp.EShop.Plugins.Booking.Application.Contracts\EasyAbp.EShop.Plugins.Booking.Application.Contracts.csproj" />
</ItemGroup>

179
plugins/Booking/src/EasyAbp.EShop.Payments.Booking.Application/EasyAbp/EShop/Payments/Booking/Authorization/BookingPaymentCreationAuthorizationHandler.cs

@ -1,36 +1,187 @@
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using EasyAbp.BookingService.AssetOccupancies;
using EasyAbp.BookingService.AssetOccupancies.Dtos;
using EasyAbp.BookingService.PeriodSchemes;
using EasyAbp.EShop.Orders;
using EasyAbp.EShop.Orders.Orders.Dtos;
using EasyAbp.EShop.Payments.Payments;
using EasyAbp.EShop.Plugins.Booking.ProductAssetCategories;
using EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.Dtos;
using EasyAbp.EShop.Plugins.Booking.ProductAssets;
using EasyAbp.EShop.Plugins.Booking.ProductAssets.Dtos;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp;
namespace EasyAbp.EShop.Payments.Booking.Authorization
{
public class BookingPaymentCreationAuthorizationHandler : PaymentCreationAuthorizationHandler
{
public BookingPaymentCreationAuthorizationHandler()
private readonly IPeriodSchemeAppService _periodSchemeAppService;
private readonly IProductAssetAppService _productAssetAppService;
private readonly IProductAssetCategoryAppService _productAssetCategoryAppService;
private readonly IAssetOccupancyAppService _assetOccupancyAppService;
public BookingPaymentCreationAuthorizationHandler(
IPeriodSchemeAppService periodSchemeAppService,
IProductAssetAppService productAssetAppService,
IProductAssetCategoryAppService productAssetCategoryAppService,
IAssetOccupancyAppService assetOccupancyAppService)
{
_periodSchemeAppService = periodSchemeAppService;
_productAssetAppService = productAssetAppService;
_productAssetCategoryAppService = productAssetCategoryAppService;
_assetOccupancyAppService = assetOccupancyAppService;
}
protected override async Task HandlePaymentCreationAsync(AuthorizationHandlerContext context,
PaymentOperationAuthorizationRequirement requirement, PaymentCreationResource resource)
{
foreach (var order in resource.Orders)
{
foreach (var orderLine in order.OrderLines)
if (await IsBookingOrderValidAsync(context, order))
{
continue;
}
context.Fail();
return;
}
}
protected virtual async Task<bool> IsBookingOrderValidAsync(AuthorizationHandlerContext context, OrderDto order)
{
var bookingOrderLines = order.OrderLines.Where(x => x.FindBookingAssetId() is not null).ToList();
if (!bookingOrderLines.Any())
{
return true;
}
var models = new List<OccupyAssetInfoModel>();
var byCategoryModels = new List<OccupyAssetByCategoryInfoModel>();
foreach (var orderLine in bookingOrderLines)
{
if (!await IsPeriodInfoValidAsync(orderLine))
{
var assetId = orderLine.FindBookingAssetId();
if (assetId is null)
return false;
}
var assetId = orderLine.FindBookingAssetId();
var assetCategoryId = orderLine.FindBookingAssetCategoryId();
if (assetId is not null)
{
if (!await IsAssetInfoValidAsync(order, orderLine))
{
var assetCategoryId = orderLine.FindBookingAssetCategoryId();
if (assetCategoryId is null)
{
continue;
}
return false;
}
// Todo: Invoke IAssetOccupancyAppService (in EasyAbp.EShop.Plugins.Booking, not EasyAbp.BookingService) to check the booking info.
var bookingDate =
Check.NotNull(orderLine.FindBookingDate(), BookingOrderProperties.OrderLineBookingDate)!.Value;
var bookingStartingTime = Check.NotNull(orderLine.FindBookingStartingTime(),
BookingOrderProperties.OrderLineBookingStartingTime)!.Value;
var bookingDuration = Check.NotNull(orderLine.FindBookingDuration(),
BookingOrderProperties.OrderLineBookingDuration)!.Value;
models.Add(new OccupyAssetInfoModel(
assetId.Value, bookingDate, bookingStartingTime, bookingDuration));
}
else if (assetCategoryId is not null)
{
if (!await IsAssetCategoryInfoValidAsync(order, orderLine))
{
return false;
}
var bookingDate =
Check.NotNull(orderLine.FindBookingDate(), BookingOrderProperties.OrderLineBookingDate)!.Value;
var bookingStartingTime = Check.NotNull(orderLine.FindBookingStartingTime(),
BookingOrderProperties.OrderLineBookingStartingTime)!.Value;
var bookingDuration = Check.NotNull(orderLine.FindBookingDuration(),
BookingOrderProperties.OrderLineBookingDuration)!.Value;
byCategoryModels.Add(new OccupyAssetByCategoryInfoModel(
assetCategoryId.Value, bookingDate, bookingStartingTime, bookingDuration));
}
else
{
return false;
}
}
try
{
await _assetOccupancyAppService.CheckBulkCreateAsync(new BulkCreateAssetOccupancyDto
{
OccupierUserId = Check.NotNull(context.User.FindUserId(), "CurrentUserId"),
Models = models,
ByCategoryModels = byCategoryModels
});
}
catch
{
return false;
}
return true;
}
protected virtual async Task<bool> IsAssetInfoValidAsync(OrderDto order, OrderLineDto orderLine)
{
var productAsset = (await _productAssetAppService.GetListAsync(
new GetProductAssetDto
{
MaxResultCount = 1,
StoreId = order.StoreId,
ProductId = orderLine.ProductId,
ProductSkuId = orderLine.ProductSkuId,
AssetId = orderLine.FindBookingAssetId(),
PeriodSchemeId = orderLine.FindBookingPeriodSchemeId()
}
)).Items.FirstOrDefault();
return productAsset is not null;
}
protected virtual async Task<bool> IsAssetCategoryInfoValidAsync(OrderDto order, OrderLineDto orderLine)
{
var productAssetCategory = (await _productAssetCategoryAppService.GetListAsync(
new GetProductAssetCategoryDto
{
MaxResultCount = 1,
StoreId = order.StoreId,
ProductId = orderLine.ProductId,
ProductSkuId = orderLine.ProductSkuId,
AssetCategoryId = orderLine.FindBookingAssetCategoryId(),
PeriodSchemeId = orderLine.FindBookingPeriodSchemeId()
}
)).Items.FirstOrDefault();
return productAssetCategory is not null;
}
protected virtual async Task<bool> IsPeriodInfoValidAsync(OrderLineDto orderLine)
{
var periodSchemeId = orderLine.FindBookingPeriodSchemeId();
var periodId = orderLine.FindBookingPeriodId();
if (periodSchemeId is null || periodId is null)
{
return false;
}
var periodScheme = await _periodSchemeAppService.GetAsync(periodSchemeId.Value);
var period = periodScheme.Periods.Find(x => x.Id == periodId);
return period is not null;
}
}
}
}

6
plugins/Booking/src/EasyAbp.EShop.Payments.Booking.Application/EasyAbp/EShop/Payments/Booking/EShopPaymentsBookingApplicationModule.cs

@ -1,11 +1,13 @@
using EasyAbp.EShop.Plugins.Booking;
using EasyAbp.BookingService;
using EasyAbp.EShop.Plugins.Booking;
using Volo.Abp.Modularity;
namespace EasyAbp.EShop.Payments.Booking
{
[DependsOn(
typeof(EShopPaymentsApplicationModule),
typeof(EShopPluginsBookingApplicationContractsModule)
typeof(EShopPluginsBookingApplicationContractsModule),
typeof(BookingServiceApplicationContractsModule)
)]
public class EShopPaymentsBookingApplicationModule : AbpModule
{

4
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Orders/BookingOrderProperties.cs

@ -5,6 +5,10 @@ public class BookingOrderProperties
public const string OrderLineBookingAssetId = "BookingAssetId";
public const string OrderLineBookingAssetCategoryId = "BookingAssetCategoryId";
public const string OrderLineBookingPeriodSchemeId = "BookingPeriodSchemeId";
public const string OrderLineBookingPeriodId = "BookingPeriodId";
public const string OrderLineBookingDate = "BookingDate";

10
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Orders/CreateOrderLineDtoExtensions.cs

@ -16,6 +16,16 @@ public static class CreateOrderLineDtoExtensions
return orderLine.GetProperty<Guid?>(BookingOrderProperties.OrderLineBookingAssetCategoryId);
}
public static Guid? FindBookingPeriodSchemeId(this CreateOrderLineDto orderLine)
{
return orderLine.GetProperty<Guid?>(BookingOrderProperties.OrderLineBookingPeriodSchemeId);
}
public static Guid? FindBookingPeriodId(this CreateOrderLineDto orderLine)
{
return orderLine.GetProperty<Guid?>(BookingOrderProperties.OrderLineBookingPeriodId);
}
public static DateTime? FindBookingDate(this CreateOrderLineDto orderLine)
{
return orderLine.GetProperty<DateTime?>(BookingOrderProperties.OrderLineBookingDate);

10
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Orders/OrderLineExtensions.cs

@ -15,7 +15,17 @@ public static class OrderLineExtensions
{
return orderLine.GetProperty<Guid?>(BookingOrderProperties.OrderLineBookingAssetCategoryId);
}
public static Guid? FindBookingPeriodSchemeId(this IOrderLine orderLine)
{
return orderLine.GetProperty<Guid?>(BookingOrderProperties.OrderLineBookingPeriodSchemeId);
}
public static Guid? FindBookingPeriodId(this IOrderLine orderLine)
{
return orderLine.GetProperty<Guid?>(BookingOrderProperties.OrderLineBookingPeriodId);
}
public static DateTime? FindBookingDate(this IOrderLine orderLine)
{
return orderLine.GetProperty<DateTime?>(BookingOrderProperties.OrderLineBookingDate);

2
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/Permissions/BookingPermissionDefinitionProvider.cs

@ -11,11 +11,13 @@ public class BookingPermissionDefinitionProvider : PermissionDefinitionProvider
var myGroup = context.AddGroup(BookingPermissions.GroupName, L("Permission:Booking"));
var productAssetPermission = myGroup.AddPermission(BookingPermissions.ProductAsset.Default, L("Permission:ProductAsset"));
productAssetPermission.AddChild(BookingPermissions.ProductAsset.Manage, L("Permission:Manage"));
productAssetPermission.AddChild(BookingPermissions.ProductAsset.Create, L("Permission:Create"));
productAssetPermission.AddChild(BookingPermissions.ProductAsset.Update, L("Permission:Update"));
productAssetPermission.AddChild(BookingPermissions.ProductAsset.Delete, L("Permission:Delete"));
var productAssetCategoryPermission = myGroup.AddPermission(BookingPermissions.ProductAssetCategory.Default, L("Permission:ProductAssetCategory"));
productAssetCategoryPermission.AddChild(BookingPermissions.ProductAssetCategory.Manage, L("Permission:Manage"));
productAssetCategoryPermission.AddChild(BookingPermissions.ProductAssetCategory.Create, L("Permission:Create"));
productAssetCategoryPermission.AddChild(BookingPermissions.ProductAssetCategory.Update, L("Permission:Update"));
productAssetCategoryPermission.AddChild(BookingPermissions.ProductAssetCategory.Delete, L("Permission:Delete"));

2
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/Permissions/BookingPermissions.cs

@ -14,6 +14,7 @@ public class BookingPermissions
public class ProductAsset
{
public const string Default = GroupName + ".ProductAsset";
public const string Manage = Default + ".Manage";
public const string Update = Default + ".Update";
public const string Create = Default + ".Create";
public const string Delete = Default + ".Delete";
@ -22,6 +23,7 @@ public class BookingPermissions
public class ProductAssetCategory
{
public const string Default = GroupName + ".ProductAssetCategory";
public const string Manage = Default + ".Manage";
public const string Update = Default + ".Update";
public const string Create = Default + ".Create";
public const string Delete = Default + ".Delete";

5
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/Dtos/CreateProductAssetCategoryDto.cs

@ -1,12 +1,15 @@
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using EasyAbp.EShop.Stores.Stores;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.Dtos
{
[Serializable]
public class CreateProductAssetCategoryDto
public class CreateProductAssetCategoryDto : IMultiStore
{
public Guid StoreId { get; set; }
public Guid ProductId { get; set; }
public Guid ProductSkuId { get; set; }

18
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/Dtos/GetProductAssetCategoryDto.cs

@ -0,0 +1,18 @@
using System;
using Volo.Abp.Application.Dtos;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.Dtos;
[Serializable]
public class GetProductAssetCategoryDto : PagedAndSortedResultRequestDto
{
public Guid? StoreId { get; set; }
public Guid? ProductId { get; set; }
public Guid? ProductSkuId { get; set; }
public Guid? AssetCategoryId { get; set; }
public Guid? PeriodSchemeId { get; set; }
}

2
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/Dtos/ProductAssetCategoryDto.cs

@ -7,6 +7,8 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.Dtos
[Serializable]
public class ProductAssetCategoryDto : AuditedEntityDto<Guid>
{
public Guid StoreId { get; set; }
public Guid ProductId { get; set; }
public Guid ProductSkuId { get; set; }

3
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/IProductAssetCategoryAppService.cs

@ -1,7 +1,6 @@
using System;
using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.Dtos;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories
@ -10,7 +9,7 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories
ICrudAppService<
ProductAssetCategoryDto,
Guid,
PagedAndSortedResultRequestDto,
GetProductAssetCategoryDto,
CreateProductAssetCategoryDto,
UpdateProductAssetCategoryDto>
{

5
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssets/Dtos/CreateProductAssetDto.cs

@ -1,11 +1,14 @@
using System;
using System.ComponentModel.DataAnnotations;
using EasyAbp.EShop.Stores.Stores;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssets.Dtos
{
[Serializable]
public class CreateProductAssetDto
public class CreateProductAssetDto : IMultiStore
{
public Guid StoreId { get; set; }
public Guid ProductId { get; set; }
public Guid ProductSkuId { get; set; }

18
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssets/Dtos/GetProductAssetDto.cs

@ -0,0 +1,18 @@
using System;
using Volo.Abp.Application.Dtos;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssets.Dtos;
[Serializable]
public class GetProductAssetDto : PagedAndSortedResultRequestDto
{
public Guid? StoreId { get; set; }
public Guid? ProductId { get; set; }
public Guid? ProductSkuId { get; set; }
public Guid? AssetId { get; set; }
public Guid? PeriodSchemeId { get; set; }
}

2
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssets/Dtos/ProductAssetDto.cs

@ -7,6 +7,8 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssets.Dtos
[Serializable]
public class ProductAssetDto : AuditedEntityDto<Guid>
{
public Guid StoreId { get; set; }
public Guid ProductId { get; set; }
public Guid ProductSkuId { get; set; }

2
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application.Contracts/EasyAbp/EShop/Plugins/Booking/ProductAssets/IProductAssetAppService.cs

@ -10,7 +10,7 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssets
ICrudAppService<
ProductAssetDto,
Guid,
PagedAndSortedResultRequestDto,
GetProductAssetDto,
CreateProductAssetDto,
UpdateProductAssetDto>
{

3
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application/EasyAbp.EShop.Plugins.Booking.Application.csproj

@ -10,6 +10,9 @@
<ItemGroup>
<PackageReference Include="Volo.Abp.AutoMapper" Version="$(AbpVersion)" />
<PackageReference Include="Volo.Abp.Ddd.Application" Version="$(AbpVersion)" />
<ProjectReference Include="..\..\..\..\..\EasyAbp.BookingService\src\EasyAbp.BookingService.Application.Contracts\EasyAbp.BookingService.Application.Contracts.csproj" />
<ProjectReference Include="..\..\..\..\modules\EasyAbp.EShop.Products\src\EasyAbp.EShop.Products.Application.Contracts\EasyAbp.EShop.Products.Application.Contracts.csproj" />
<ProjectReference Include="..\..\..\..\modules\EasyAbp.EShop.Stores\src\EasyAbp.EShop.Stores.Application.Shared\EasyAbp.EShop.Stores.Application.Shared.csproj" />
<ProjectReference Include="..\EasyAbp.EShop.Plugins.Booking.Application.Contracts\EasyAbp.EShop.Plugins.Booking.Application.Contracts.csproj" />
<ProjectReference Include="..\EasyAbp.EShop.Plugins.Booking.Domain\EasyAbp.EShop.Plugins.Booking.Domain.csproj" />
</ItemGroup>

4
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application/EasyAbp/EShop/Plugins/Booking/BookingApplicationAutoMapperProfile.cs

@ -16,16 +16,12 @@ public class BookingApplicationAutoMapperProfile : Profile
* Alternatively, you can split your mapping configurations
* into multiple profile classes for a better organization. */
CreateMap<ProductAsset, ProductAssetDto>();
CreateMap<CreateProductAssetDto, ProductAsset>(MemberList.Source);
CreateMap<UpdateProductAssetDto, ProductAsset>(MemberList.Source);
CreateMap<ProductAssetPeriod, ProductAssetPeriodDto>();
CreateMap<CreateProductAssetPeriodDto, ProductAssetPeriod>(MemberList.Source);
CreateMap<UpdateProductAssetPeriodDto, ProductAssetPeriod>(MemberList.Source);
CreateMap<ProductAssetCategory, ProductAssetCategoryDto>();
CreateMap<CreateProductAssetCategoryDto, ProductAssetCategory>(MemberList.Source);
CreateMap<UpdateProductAssetCategoryDto, ProductAssetCategory>(MemberList.Source);
CreateMap<ProductAssetCategoryPeriod, ProductAssetCategoryPeriodDto>();
CreateMap<CreateProductAssetCategoryPeriodDto, ProductAssetCategoryPeriod>(MemberList.Source);

8
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application/EasyAbp/EShop/Plugins/Booking/EShopPluginsBookingApplicationModule.cs

@ -1,4 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using EasyAbp.BookingService;
using EasyAbp.EShop.Products;
using EasyAbp.EShop.Stores;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
using Volo.Abp.Application;
@ -6,8 +9,11 @@ using Volo.Abp.Application;
namespace EasyAbp.EShop.Plugins.Booking;
[DependsOn(
typeof(EShopStoresApplicationSharedModule),
typeof(EShopProductsApplicationContractsModule),
typeof(EShopPluginsBookingDomainModule),
typeof(EShopPluginsBookingApplicationContractsModule),
typeof(BookingServiceApplicationContractsModule),
typeof(AbpDddApplicationModule),
typeof(AbpAutoMapperModule)
)]

152
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategoryAppService.cs

@ -1,67 +1,173 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using EasyAbp.BookingService.AssetCategories;
using EasyAbp.BookingService.PeriodSchemes;
using EasyAbp.EShop.Plugins.Booking.Permissions;
using EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.Dtos;
using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Stores.Stores;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories
{
public class ProductAssetCategoryAppService : CrudAppService<ProductAssetCategory, ProductAssetCategoryDto, Guid, PagedAndSortedResultRequestDto, CreateProductAssetCategoryDto, UpdateProductAssetCategoryDto>,
public class ProductAssetCategoryAppService : MultiStoreCrudAppService<ProductAssetCategory, ProductAssetCategoryDto
, Guid, GetProductAssetCategoryDto, CreateProductAssetCategoryDto, UpdateProductAssetCategoryDto>,
IProductAssetCategoryAppService
{
protected override string CrossStorePolicyName { get; set; } = BookingPermissions.ProductAssetCategory.Manage;
protected override string GetPolicyName { get; set; } = BookingPermissions.ProductAssetCategory.Default;
protected override string GetListPolicyName { get; set; } = BookingPermissions.ProductAssetCategory.Default;
protected override string CreatePolicyName { get; set; } = BookingPermissions.ProductAssetCategory.Create;
protected override string UpdatePolicyName { get; set; } = BookingPermissions.ProductAssetCategory.Update;
protected override string DeletePolicyName { get; set; } = BookingPermissions.ProductAssetCategory.Delete;
private readonly IProductAppService _productAppService;
private readonly IPeriodSchemeAppService _periodSchemeAppService;
private readonly IAssetCategoryAppService _assetCategoryAppService;
private readonly IProductAssetCategoryRepository _repository;
private readonly ProductAssetCategoryManager _productAssetCategoryManager;
public ProductAssetCategoryAppService(IProductAssetCategoryRepository repository) : base(repository)
public ProductAssetCategoryAppService(
IProductAppService productAppService,
IPeriodSchemeAppService periodSchemeAppService,
IAssetCategoryAppService assetCategoryAppService,
IProductAssetCategoryRepository repository,
ProductAssetCategoryManager productAssetCategoryManager) : base(repository)
{
_productAppService = productAppService;
_periodSchemeAppService = periodSchemeAppService;
_assetCategoryAppService = assetCategoryAppService;
_repository = repository;
_productAssetCategoryManager = productAssetCategoryManager;
}
public virtual async Task<ProductAssetCategoryDto> CreatePeriodAsync(Guid productAssetCategoryId, CreateProductAssetCategoryPeriodDto input)
protected override async Task<IQueryable<ProductAssetCategory>> CreateFilteredQueryAsync(GetProductAssetCategoryDto input)
{
await CheckUpdatePolicyAsync();
return (await base.CreateFilteredQueryAsync(input))
.WhereIf(input.StoreId.HasValue, x => x.StoreId == input.StoreId)
.WhereIf(input.ProductId.HasValue, x => x.ProductId == input.ProductId)
.WhereIf(input.ProductSkuId.HasValue, x => x.ProductSkuId == input.ProductSkuId)
.WhereIf(input.AssetCategoryId.HasValue, x => x.AssetCategoryId == input.AssetCategoryId)
.WhereIf(input.PeriodSchemeId.HasValue, x => x.PeriodSchemeId == input.PeriodSchemeId);
}
public override async Task<PagedResultDto<ProductAssetCategoryDto>> GetListAsync(
GetProductAssetCategoryDto input)
{
await CheckMultiStorePolicyAsync(input.StoreId, GetListPolicyName);
var productAsset = await GetEntityByIdAsync(productAssetCategoryId);
var query = await CreateFilteredQueryAsync(input);
productAsset.AddPeriod(ObjectMapper.Map<CreateProductAssetCategoryPeriodDto, ProductAssetCategoryPeriod>(input));
var totalCount = await AsyncExecuter.CountAsync(query);
await _repository.UpdateAsync(productAsset, true);
query = ApplySorting(query, input);
query = ApplyPaging(query, input);
return await MapToGetOutputDtoAsync(productAsset);
var entities = await AsyncExecuter.ToListAsync(query);
var entityDtos = await MapToGetListOutputDtosAsync(entities);
return new PagedResultDto<ProductAssetCategoryDto>(
totalCount,
entityDtos
);
}
public virtual async Task<ProductAssetCategoryDto> UpdatePeriodAsync(Guid productAssetCategoryId, Guid periodId, UpdateProductAssetCategoryPeriodDto input)
public override async Task<ProductAssetCategoryDto> CreateAsync(CreateProductAssetCategoryDto input)
{
await CheckUpdatePolicyAsync();
var productAsset = await GetEntityByIdAsync(productAssetCategoryId);
await CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName);
await EnsureProductSkuExistAsync(input.StoreId, input.ProductId, input.ProductSkuId);
await EnsureAssetCategoryExistAsync(input.AssetCategoryId);
await EnsurePeriodSchemeExistAsync(input.PeriodSchemeId);
var entity = await MapToEntityAsync(input);
TryToSetTenantId(entity);
await Repository.InsertAsync(entity, autoSave: true);
return await MapToGetOutputDtoAsync(entity);
}
protected virtual async Task EnsureProductSkuExistAsync(Guid storeId, Guid productId, Guid productSkuId)
{
var product = await _productAppService.GetAsync(productId);
if (product.StoreId != storeId)
{
throw (new BusinessException(BookingErrorCodes.WrongStoreIdForProduct))
.WithData(nameof(storeId), storeId)
.WithData(nameof(productId), productId);
}
product.GetSkuById(productSkuId);
}
protected virtual async Task EnsureAssetCategoryExistAsync(Guid assetCategoryId)
{
await _assetCategoryAppService.GetAsync(assetCategoryId);
}
protected virtual async Task EnsurePeriodSchemeExistAsync(Guid periodSchemeId)
{
await _periodSchemeAppService.GetAsync(periodSchemeId);
}
protected override async Task<ProductAssetCategory> MapToEntityAsync(CreateProductAssetCategoryDto input)
{
return await _productAssetCategoryManager.CreateAsync(input.StoreId, input.ProductId, input.ProductSkuId,
input.AssetCategoryId, input.PeriodSchemeId, input.FromTime, input.ToTime, input.Price);
}
protected override async Task MapToEntityAsync(UpdateProductAssetCategoryDto input, ProductAssetCategory entity)
{
await _productAssetCategoryManager.UpdateAsync(entity, input.FromTime, input.ToTime, input.Price);
}
public virtual async Task<ProductAssetCategoryDto> CreatePeriodAsync(Guid productAssetCategoryId,
CreateProductAssetCategoryPeriodDto input)
{
var productAssetCategory = await GetEntityByIdAsync(productAssetCategoryId);
await CheckMultiStorePolicyAsync(productAssetCategory.StoreId, UpdatePolicyName);
productAssetCategory.AddPeriod(
ObjectMapper.Map<CreateProductAssetCategoryPeriodDto, ProductAssetCategoryPeriod>(input));
await _repository.UpdateAsync(productAssetCategory, true);
return await MapToGetOutputDtoAsync(productAssetCategory);
}
public virtual async Task<ProductAssetCategoryDto> UpdatePeriodAsync(Guid productAssetCategoryId, Guid periodId,
UpdateProductAssetCategoryPeriodDto input)
{
var productAssetCategory = await GetEntityByIdAsync(productAssetCategoryId);
await CheckMultiStorePolicyAsync(productAssetCategory.StoreId, UpdatePolicyName);
var productAssetCategoryPeriod = productAssetCategory.GetPeriod(periodId);
var productAssetCategoryPeriod = productAsset.GetPeriod(periodId);
ObjectMapper.Map(input, productAssetCategoryPeriod);
await _repository.UpdateAsync(productAsset, true);
await _repository.UpdateAsync(productAssetCategory, true);
return await MapToGetOutputDtoAsync(productAsset);
return await MapToGetOutputDtoAsync(productAssetCategory);
}
public virtual async Task<ProductAssetCategoryDto> DeletePeriodAsync(Guid productAssetCategoryId, Guid periodId)
{
await CheckUpdatePolicyAsync();
var productAsset = await GetEntityByIdAsync(productAssetCategoryId);
var productAssetCategory = await GetEntityByIdAsync(productAssetCategoryId);
await CheckMultiStorePolicyAsync(productAssetCategory.StoreId, UpdatePolicyName);
productAsset.RemovePeriod(periodId);
productAssetCategory.RemovePeriod(periodId);
await _repository.UpdateAsync(productAsset, true);
await _repository.UpdateAsync(productAssetCategory, true);
return await MapToGetOutputDtoAsync(productAsset);
return await MapToGetOutputDtoAsync(productAssetCategory);
}
}
}

130
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Application/EasyAbp/EShop/Plugins/Booking/ProductAssets/ProductAssetAppService.cs

@ -1,49 +1,155 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using EasyAbp.BookingService.Assets;
using EasyAbp.BookingService.PeriodSchemes;
using EasyAbp.EShop.Plugins.Booking.Permissions;
using EasyAbp.EShop.Plugins.Booking.ProductAssets.Dtos;
using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Stores.Stores;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssets
{
public class ProductAssetAppService : CrudAppService<ProductAsset, ProductAssetDto, Guid, PagedAndSortedResultRequestDto, CreateProductAssetDto, UpdateProductAssetDto>,
public class ProductAssetAppService : MultiStoreCrudAppService<ProductAsset, ProductAssetDto
, Guid, GetProductAssetDto, CreateProductAssetDto, UpdateProductAssetDto>,
IProductAssetAppService
{
protected override string CrossStorePolicyName { get; set; } = BookingPermissions.ProductAsset.Manage;
protected override string GetPolicyName { get; set; } = BookingPermissions.ProductAsset.Default;
protected override string GetListPolicyName { get; set; } = BookingPermissions.ProductAsset.Default;
protected override string CreatePolicyName { get; set; } = BookingPermissions.ProductAsset.Create;
protected override string UpdatePolicyName { get; set; } = BookingPermissions.ProductAsset.Update;
protected override string DeletePolicyName { get; set; } = BookingPermissions.ProductAsset.Delete;
private readonly IProductAppService _productAppService;
private readonly IPeriodSchemeAppService _periodSchemeAppService;
private readonly IAssetAppService _assetAppService;
private readonly IProductAssetRepository _repository;
private readonly ProductAssetManager _productAssetManager;
public ProductAssetAppService(IProductAssetRepository repository) : base(repository)
public ProductAssetAppService(
IProductAppService productAppService,
IPeriodSchemeAppService periodSchemeAppService,
IAssetAppService assetAppService,
IProductAssetRepository repository,
ProductAssetManager productAssetManager) : base(repository)
{
_productAppService = productAppService;
_periodSchemeAppService = periodSchemeAppService;
_assetAppService = assetAppService;
_repository = repository;
_productAssetManager = productAssetManager;
}
public virtual async Task<ProductAssetDto> CreatePeriodAsync(Guid productAssetId, CreateProductAssetPeriodDto input)
protected override async Task<IQueryable<ProductAsset>> CreateFilteredQueryAsync(GetProductAssetDto input)
{
await CheckUpdatePolicyAsync();
return (await base.CreateFilteredQueryAsync(input))
.WhereIf(input.StoreId.HasValue, x => x.StoreId == input.StoreId)
.WhereIf(input.ProductId.HasValue, x => x.ProductId == input.ProductId)
.WhereIf(input.ProductSkuId.HasValue, x => x.ProductSkuId == input.ProductSkuId)
.WhereIf(input.AssetId.HasValue, x => x.AssetId == input.AssetId)
.WhereIf(input.PeriodSchemeId.HasValue, x => x.PeriodSchemeId == input.PeriodSchemeId);
}
public override async Task<PagedResultDto<ProductAssetDto>> GetListAsync(
GetProductAssetDto input)
{
await CheckMultiStorePolicyAsync(input.StoreId, GetListPolicyName);
var query = await CreateFilteredQueryAsync(input);
var totalCount = await AsyncExecuter.CountAsync(query);
query = ApplySorting(query, input);
query = ApplyPaging(query, input);
var entities = await AsyncExecuter.ToListAsync(query);
var entityDtos = await MapToGetListOutputDtosAsync(entities);
return new PagedResultDto<ProductAssetDto>(
totalCount,
entityDtos
);
}
public override async Task<ProductAssetDto> CreateAsync(CreateProductAssetDto input)
{
await CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName);
await EnsureProductSkuExistAsync(input.StoreId, input.ProductId, input.ProductSkuId);
await EnsureAssetExistAsync(input.AssetId);
await EnsurePeriodSchemeExistAsync(input.PeriodSchemeId);
var entity = await MapToEntityAsync(input);
TryToSetTenantId(entity);
await Repository.InsertAsync(entity, autoSave: true);
return await MapToGetOutputDtoAsync(entity);
}
protected virtual async Task EnsureProductSkuExistAsync(Guid storeId, Guid productId, Guid productSkuId)
{
var product = await _productAppService.GetAsync(productId);
if (product.StoreId != storeId)
{
throw (new BusinessException(BookingErrorCodes.WrongStoreIdForProduct))
.WithData(nameof(storeId), storeId)
.WithData(nameof(productId), productId);
}
product.GetSkuById(productSkuId);
}
protected virtual async Task EnsureAssetExistAsync(Guid assetId)
{
await _assetAppService.GetAsync(assetId);
}
protected virtual async Task EnsurePeriodSchemeExistAsync(Guid periodSchemeId)
{
await _periodSchemeAppService.GetAsync(periodSchemeId);
}
protected override async Task<ProductAsset> MapToEntityAsync(CreateProductAssetDto input)
{
return await _productAssetManager.CreateAsync(input.StoreId, input.ProductId, input.ProductSkuId,
input.AssetId, input.PeriodSchemeId, input.FromTime, input.ToTime, input.Price);
}
protected override async Task MapToEntityAsync(UpdateProductAssetDto input, ProductAsset entity)
{
await _productAssetManager.UpdateAsync(entity, input.FromTime, input.ToTime, input.Price);
}
public virtual async Task<ProductAssetDto> CreatePeriodAsync(Guid productAssetId,
CreateProductAssetPeriodDto input)
{
var productAsset = await GetEntityByIdAsync(productAssetId);
productAsset.AddPeriod(ObjectMapper.Map<CreateProductAssetPeriodDto, ProductAssetPeriod>(input));
await CheckMultiStorePolicyAsync(productAsset.StoreId, UpdatePolicyName);
productAsset.AddPeriod(
ObjectMapper.Map<CreateProductAssetPeriodDto, ProductAssetPeriod>(input));
await _repository.UpdateAsync(productAsset, true);
return await MapToGetOutputDtoAsync(productAsset);
}
public virtual async Task<ProductAssetDto> UpdatePeriodAsync(Guid productAssetId, Guid periodId, UpdateProductAssetPeriodDto input)
public virtual async Task<ProductAssetDto> UpdatePeriodAsync(Guid productAssetId, Guid periodId,
UpdateProductAssetPeriodDto input)
{
await CheckUpdatePolicyAsync();
var productAsset = await GetEntityByIdAsync(productAssetId);
await CheckMultiStorePolicyAsync(productAsset.StoreId, UpdatePolicyName);
var productAssetPeriod = productAsset.GetPeriod(periodId);
ObjectMapper.Map(input, productAssetPeriod);
await _repository.UpdateAsync(productAsset, true);
@ -53,10 +159,10 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssets
public virtual async Task<ProductAssetDto> DeletePeriodAsync(Guid productAssetId, Guid periodId)
{
await CheckUpdatePolicyAsync();
var productAsset = await GetEntityByIdAsync(productAssetId);
await CheckMultiStorePolicyAsync(productAsset.StoreId, UpdatePolicyName);
productAsset.RemovePeriod(periodId);
await _repository.UpdateAsync(productAsset, true);

3
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain.Shared/EasyAbp/EShop/Plugins/Booking/BookingErrorCodes.cs

@ -4,4 +4,7 @@ public static class BookingErrorCodes
{
public const string PeriodNotFound = "EasyAbp.EShop.Plugins.Booking:PeriodNotFound";
public const string DuplicatePeriod = "EasyAbp.EShop.Plugins.Booking:DuplicatePeriod";
public const string ConflictingProductAsset = "EasyAbp.EShop.Plugins.Booking:ConflictingProductAsset";
public const string ConflictingProductAssetCategory = "EasyAbp.EShop.Plugins.Booking:ConflictingProductAssetCategory";
public const string WrongStoreIdForProduct = "EasyAbp.EShop.Plugins.Booking:WrongStoreIdForProduct";
}

5
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain.Shared/EasyAbp/EShop/Plugins/Booking/Localization/en.json

@ -8,6 +8,7 @@
"Permission:Delete": "Delete",
"Menu:ProductAsset": "Asset prices",
"ProductAsset": "Asset prices",
"ProductAssetStoreId": "Store ID",
"ProductAssetProductId": "Product ID",
"ProductAssetProductSkuId": "Product SKU ID",
"ProductAssetAssetId": "Asset ID",
@ -30,6 +31,7 @@
"Permission:ProductAssetCategory": "Asset category prices",
"Menu:ProductAssetCategory": "Asset category prices",
"ProductAssetCategory": "Asset category prices",
"ProductAssetCategoryStoreId": "Store ID",
"ProductAssetCategoryProductId": "Product ID",
"ProductAssetCategoryProductSkuId": "Product SKU ID",
"ProductAssetCategoryAssetCategoryId": "Asset Category ID",
@ -50,6 +52,9 @@
"ProductAssetCategoryPeriodDeletionConfirmationMessage": "Are you sure to delete the product asset category period {0}?",
"EasyAbp.EShop.Plugins.Booking:PeriodNotFound": "Period {id} not found.",
"EasyAbp.EShop.Plugins.Booking:DuplicatePeriod": "Period {id} exists.",
"EasyAbp.EShop.Plugins.Booking:ConflictingProductAsset": "Exist conflicting product asset mapping.",
"EasyAbp.EShop.Plugins.Booking:ConflictingProductAssetCategory": "Exist conflicting product asset category mapping.",
"EasyAbp.EShop.Plugins.Booking:WrongStoreIdForProduct": "Wrong StoreId {storeId} for product {productId}.",
"Permission:StoreAssetCategory": "Store assets",
"Menu:StoreAssetCategory": "Store assets",
"StoreAssetCategory": "Store assets",

5
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain.Shared/EasyAbp/EShop/Plugins/Booking/Localization/zh-Hans.json

@ -8,6 +8,7 @@
"Permission:Delete": "删除",
"Menu:ProductAsset": "资产价格",
"ProductAsset": "资产价格",
"ProductAssetStoreId": "店铺 ID",
"ProductAssetProductId": "产品 ID",
"ProductAssetProductSkuId": "产品 SKU ID",
"ProductAssetAssetId": "资产 ID",
@ -30,6 +31,7 @@
"Permission:ProductAssetCategory": "资产类目价格",
"Menu:ProductAssetCategory": "资产类目价格",
"ProductAssetCategory": "资产类目价格",
"ProductAssetCategoryStoreId": "店铺 ID",
"ProductAssetCategoryProductId": "产品 ID",
"ProductAssetCategoryProductSkuId": "产品 SKU ID",
"ProductAssetCategoryAssetCategoryId": "资产目录 ID",
@ -50,6 +52,9 @@
"ProductAssetCategoryPeriodDeletionConfirmationMessage": "确认删除资产类目时段价格 {0}?",
"EasyAbp.EShop.Plugins.Booking:PeriodNotFound": "时段 {id} 不存在。",
"EasyAbp.EShop.Plugins.Booking:DuplicatePeriod": "时段 {id} 已存在。",
"EasyAbp.EShop.Plugins.Booking:ConflictingProductAsset": "存在冲突的产品资产映射。",
"EasyAbp.EShop.Plugins.Booking:ConflictingProductAssetCategory": "存在冲突的产品资产映射。",
"EasyAbp.EShop.Plugins.Booking:WrongStoreIdForProduct": "错误的店铺 ID {storeId} 之于产品 {productId}。",
"Permission:StoreAssetCategory": "店铺资产",
"Menu:StoreAssetCategory": "店铺资产",
"StoreAssetCategory": "店铺资产",

5
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain.Shared/EasyAbp/EShop/Plugins/Booking/Localization/zh-Hant.json

@ -8,6 +8,7 @@
"Permission:Delete": "刪除",
"Menu:ProductAsset": "資產價格",
"ProductAsset": "資產價格",
"ProductAssetStoreId": "店鋪 ID",
"ProductAssetProductId": "產品 ID",
"ProductAssetProductSkuId": "產品 SKU ID",
"ProductAssetAssetId": "資產 ID",
@ -30,6 +31,7 @@
"Permission:ProductAssetCategory": "資產類目價格",
"Menu:ProductAssetCategory": "資產類目價格",
"ProductAssetCategory": "資產類目價格",
"ProductAssetCategoryStoreId": "店鋪 ID",
"ProductAssetCategoryProductId": "產品 ID",
"ProductAssetCategoryProductSkuId": "產品 SKU ID",
"ProductAssetCategoryAssetCategoryId": "資產目錄 ID",
@ -50,6 +52,9 @@
"ProductAssetCategoryPeriodDeletionConfirmationMessage": "確認刪除資產類目時段價格 {0}?",
"EasyAbp.EShop.Plugins.Booking:PeriodNotFound": "時段 {id} 不存在。",
"EasyAbp.EShop.Plugins.Booking:DuplicatePeriod": "時段 {id} 已存在。",
"EasyAbp.EShop.Plugins.Booking:ConflictingProductAsset": "存在衝突的產品資產映射。",
"EasyAbp.EShop.Plugins.Booking:ConflictingProductAssetCategory": "存在衝突的產品資產映射。",
"EasyAbp.EShop.Plugins.Booking:WrongStoreIdForProduct": "錯誤的店鋪 ID {storeId} 之於產品 {productId}。",
"Permission:StoreAssetCategory": "店鋪資產",
"Menu:StoreAssetCategory": "店鋪資產",
"StoreAssetCategory": "店鋪資產",

1
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp.EShop.Plugins.Booking.Domain.csproj

@ -9,6 +9,7 @@
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="$(AbpVersion)" />
<ProjectReference Include="..\..\..\..\modules\EasyAbp.EShop.Stores\src\EasyAbp.EShop.Stores.Domain.Shared\EasyAbp.EShop.Stores.Domain.Shared.csproj" />
<ProjectReference Include="..\EasyAbp.EShop.Plugins.Booking.Domain.Shared\EasyAbp.EShop.Plugins.Booking.Domain.Shared.csproj" />
</ItemGroup>

4
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/EShopPluginsBookingDomainModule.cs

@ -1,10 +1,12 @@
using Volo.Abp.Domain;
using EasyAbp.EShop.Stores;
using Volo.Abp.Domain;
using Volo.Abp.Modularity;
namespace EasyAbp.EShop.Plugins.Booking;
[DependsOn(
typeof(AbpDddDomainModule),
typeof(EShopStoresDomainSharedModule),
typeof(EShopPluginsBookingDomainSharedModule)
)]
public class EShopPluginsBookingDomainModule : AbpModule

6
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/IProductAssetCategoryRepository.cs

@ -1,9 +1,15 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories
{
public interface IProductAssetCategoryRepository : IRepository<ProductAssetCategory, Guid>
{
Task<ProductAssetCategory> FindEffectiveAsync(DateTime currentTime, Guid storeId, Guid productId,
Guid productSkuId, Guid assetCategoryId, Guid periodSchemeId);
Task<bool> ExistConflictAsync(Guid id, Guid storeId, Guid productId, Guid productSkuId, Guid assetCategoryId,
Guid periodSchemeId, DateTime fromTime);
}
}

15
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using EasyAbp.EShop.Plugins.Booking.Shared;
using EasyAbp.EShop.Stores.Stores;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
@ -12,10 +13,12 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories;
/// Set which SKU can use to book a specified asset category.
/// The matched <see cref="ProductAssetCategory"/> with the larger <see cref="FromTime"/> takes precedence.
/// </summary>
public class ProductAssetCategory : AuditedAggregateRoot<Guid>, IMultiTenant
public class ProductAssetCategory : AuditedAggregateRoot<Guid>, IMultiStore, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual Guid StoreId { get; protected set; }
public virtual Guid ProductId { get; protected set; }
public virtual Guid ProductSkuId { get; protected set; }
@ -53,6 +56,7 @@ public class ProductAssetCategory : AuditedAggregateRoot<Guid>, IMultiTenant
public ProductAssetCategory(
Guid id,
Guid? tenantId,
Guid storeId,
Guid productId,
Guid productSkuId,
Guid assetCategoryId,
@ -64,6 +68,7 @@ public class ProductAssetCategory : AuditedAggregateRoot<Guid>, IMultiTenant
) : base(id)
{
TenantId = tenantId;
StoreId = storeId;
ProductId = productId;
ProductSkuId = productSkuId;
AssetCategoryId = assetCategoryId;
@ -71,9 +76,17 @@ public class ProductAssetCategory : AuditedAggregateRoot<Guid>, IMultiTenant
FromTime = fromTime;
ToTime = toTime;
Price = price;
Periods = periods ?? new List<ProductAssetCategoryPeriod>();
}
internal void Update(DateTime fromTime, DateTime? toTime, decimal? price)
{
FromTime = fromTime;
ToTime = toTime;
Price = price;
}
public void AddPeriod(ProductAssetCategoryPeriod productAssetCategoryPeriod)
{
if (FindPeriod(productAssetCategoryPeriod.PeriodId) is not null)

43
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetManager.cs

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Services;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories;
public class ProductAssetCategoryManager : DomainService
{
private readonly IProductAssetCategoryRepository _repository;
public ProductAssetCategoryManager(IProductAssetCategoryRepository repository)
{
_repository = repository;
}
public virtual async Task<ProductAssetCategory> CreateAsync(Guid storeId, Guid productId, Guid productSkuId, Guid assetCategoryId,
Guid periodSchemeId, DateTime fromTime, DateTime? toTime, decimal? price)
{
var id = GuidGenerator.Create();
if (await _repository.ExistConflictAsync(
id, storeId, productId, productSkuId, assetCategoryId, periodSchemeId, fromTime))
{
throw new BusinessException(BookingErrorCodes.ConflictingProductAssetCategory);
}
return new ProductAssetCategory(GuidGenerator.Create(), CurrentTenant.Id, storeId, productId, productSkuId, assetCategoryId,
periodSchemeId, fromTime, toTime, price, new List<ProductAssetCategoryPeriod>());
}
public virtual async Task UpdateAsync(ProductAssetCategory entity, DateTime fromTime, DateTime? toTime, decimal? price)
{
if (await _repository.ExistConflictAsync(entity.Id, entity.StoreId, entity.ProductId, entity.ProductSkuId,
entity.AssetCategoryId, entity.PeriodSchemeId, fromTime))
{
throw new BusinessException(BookingErrorCodes.ConflictingProductAssetCategory);
}
entity.Update(fromTime, toTime, price);
}
}

6
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/ProductAssets/IProductAssetRepository.cs

@ -1,9 +1,15 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssets
{
public interface IProductAssetRepository : IRepository<ProductAsset, Guid>
{
Task<ProductAsset> FindEffectiveAsync(DateTime currentTime, Guid storeId, Guid productId, Guid productSkuId,
Guid assetId, Guid periodSchemeId);
Task<bool> ExistConflictAsync(Guid id, Guid storeId, Guid productId, Guid productSkuId, Guid assetId,
Guid periodSchemeId, DateTime fromTime);
}
}

16
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/ProductAssets/ProductAsset.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using EasyAbp.EShop.Plugins.Booking.ProductAssetCategories;
using EasyAbp.EShop.Plugins.Booking.Shared;
using EasyAbp.EShop.Stores.Stores;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
@ -14,10 +15,12 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssets;
/// The matched <see cref="ProductAsset"/> with the larger <see cref="FromTime"/> takes precedence.
/// Fall back to <see cref="ProductAssetCategory"/> if the booking asset has no matched <see cref="ProductAsset"/>.
/// </summary>
public class ProductAsset : AuditedAggregateRoot<Guid>, IMultiTenant
public class ProductAsset : AuditedAggregateRoot<Guid>, IMultiStore, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual Guid StoreId { get; protected set; }
public virtual Guid ProductId { get; protected set; }
public virtual Guid ProductSkuId { get; protected set; }
@ -52,9 +55,10 @@ public class ProductAsset : AuditedAggregateRoot<Guid>, IMultiTenant
{
}
public ProductAsset(
internal ProductAsset(
Guid id,
Guid? tenantId,
Guid storeId,
Guid productId,
Guid productSkuId,
Guid assetId,
@ -66,6 +70,7 @@ public class ProductAsset : AuditedAggregateRoot<Guid>, IMultiTenant
) : base(id)
{
TenantId = tenantId;
StoreId = storeId;
ProductId = productId;
ProductSkuId = productSkuId;
AssetId = assetId;
@ -77,6 +82,13 @@ public class ProductAsset : AuditedAggregateRoot<Guid>, IMultiTenant
Periods = periods ?? new List<ProductAssetPeriod>();
}
internal void Update(DateTime fromTime, DateTime? toTime, decimal? price)
{
FromTime = fromTime;
ToTime = toTime;
Price = price;
}
public void AddPeriod(ProductAssetPeriod productAssetPeriod)
{
if (FindPeriod(productAssetPeriod.PeriodId) is not null)

43
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Domain/EasyAbp/EShop/Plugins/Booking/ProductAssets/ProductAssetManager.cs

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Services;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssets;
public class ProductAssetManager : DomainService
{
private readonly IProductAssetRepository _repository;
public ProductAssetManager(IProductAssetRepository repository)
{
_repository = repository;
}
public virtual async Task<ProductAsset> CreateAsync(Guid storeId, Guid productId, Guid productSkuId, Guid assetId,
Guid periodSchemeId, DateTime fromTime, DateTime? toTime, decimal? price)
{
var id = GuidGenerator.Create();
if (await _repository.ExistConflictAsync(
id, storeId, productId, productSkuId, assetId, periodSchemeId, fromTime))
{
throw new BusinessException(BookingErrorCodes.ConflictingProductAsset);
}
return new ProductAsset(GuidGenerator.Create(), CurrentTenant.Id, storeId, productId, productSkuId, assetId,
periodSchemeId, fromTime, toTime, price, new List<ProductAssetPeriod>());
}
public virtual async Task UpdateAsync(ProductAsset entity, DateTime fromTime, DateTime? toTime, decimal? price)
{
if (await _repository.ExistConflictAsync(entity.Id, entity.StoreId, entity.ProductId, entity.ProductSkuId,
entity.AssetId, entity.PeriodSchemeId, fromTime))
{
throw new BusinessException(BookingErrorCodes.ConflictingProductAsset);
}
entity.Update(fromTime, toTime, price);
}
}

33
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategoryRepository.cs

@ -2,6 +2,7 @@ using System;
using System.Linq;
using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
@ -17,5 +18,37 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories
{
return (await GetQueryableAsync()).IncludeDetails();
}
public virtual async Task<ProductAssetCategory> FindEffectiveAsync(DateTime currentTime, Guid storeId,
Guid productId, Guid productSkuId, Guid assetCategoryId, Guid periodSchemeId)
{
return await (await GetQueryableAsync())
.Where(x =>
x.StoreId == storeId &&
x.ProductId == productId &&
x.ProductSkuId == productSkuId &&
x.AssetCategoryId == assetCategoryId &&
x.PeriodSchemeId == periodSchemeId
&& x.FromTime <= currentTime &&
(!x.ToTime.HasValue || x.ToTime.Value > currentTime))
.OrderByDescending(x => x.FromTime)
.FirstOrDefaultAsync();
}
public virtual async Task<bool> ExistConflictAsync(Guid id, Guid storeId, Guid productId, Guid productSkuId,
Guid assetCategoryId, Guid periodSchemeId, DateTime fromTime)
{
var conflict = await (await GetQueryableAsync())
.Where(x =>
x.StoreId == storeId &&
x.ProductId == productId &&
x.ProductSkuId == productSkuId &&
x.AssetCategoryId == assetCategoryId &&
x.PeriodSchemeId == periodSchemeId
&& x.FromTime == fromTime)
.FirstOrDefaultAsync();
return conflict is not null && conflict.Id != id;
}
}
}

38
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore/EasyAbp/EShop/Plugins/Booking/ProductAssets/ProductAssetRepository.cs

@ -2,12 +2,14 @@ using System;
using System.Linq;
using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssets
{
public class ProductAssetRepository : EfCoreRepository<IBookingDbContext, ProductAsset, Guid>, IProductAssetRepository
public class ProductAssetRepository : EfCoreRepository<IBookingDbContext, ProductAsset, Guid>,
IProductAssetRepository
{
public ProductAssetRepository(IDbContextProvider<IBookingDbContext> dbContextProvider) : base(dbContextProvider)
{
@ -17,5 +19,37 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssets
{
return (await GetQueryableAsync()).IncludeDetails();
}
public virtual async Task<ProductAsset> FindEffectiveAsync(DateTime currentTime, Guid storeId, Guid productId,
Guid productSkuId, Guid assetId, Guid periodSchemeId)
{
return await (await GetQueryableAsync())
.Where(x =>
x.StoreId == storeId &&
x.ProductId == productId &&
x.ProductSkuId == productSkuId &&
x.AssetId == assetId &&
x.PeriodSchemeId == periodSchemeId
&& x.FromTime <= currentTime &&
(!x.ToTime.HasValue || x.ToTime.Value > currentTime))
.OrderByDescending(x => x.FromTime)
.FirstOrDefaultAsync();
}
public virtual async Task<bool> ExistConflictAsync(Guid id, Guid storeId, Guid productId, Guid productSkuId,
Guid assetId, Guid periodSchemeId, DateTime fromTime)
{
var conflict = await (await GetQueryableAsync())
.Where(x =>
x.StoreId == storeId &&
x.ProductId == productId &&
x.ProductSkuId == productSkuId &&
x.AssetId == assetId &&
x.PeriodSchemeId == periodSchemeId
&& x.FromTime == fromTime)
.FirstOrDefaultAsync();
return conflict is not null && conflict.Id != id;
}
}
}
}

4
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore/EasyAbp/EShop/Plugins/Booking/StoreAssetCategories/StoreAssetCategoryEfCoreQuerableExtensions.cs

@ -12,9 +12,7 @@ namespace EasyAbp.EShop.Plugins.Booking.StoreAssetCategories
return queryable;
}
return queryable
// .Include(x => x.xxx) // TODO: AbpHelper generated
;
return queryable;
}
}
}

3
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.HttpApi/EasyAbp/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategoryController.cs

@ -4,7 +4,6 @@ using Volo.Abp.Application.Dtos;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories
{
@ -70,7 +69,7 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories
[HttpGet]
[Route("")]
public virtual Task<PagedResultDto<ProductAssetCategoryDto>> GetListAsync(PagedAndSortedResultRequestDto input)
public virtual Task<PagedResultDto<ProductAssetCategoryDto>> GetListAsync(GetProductAssetCategoryDto input)
{
return _service.GetListAsync(input);
}

2
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.HttpApi/EasyAbp/EShop/Plugins/Booking/ProductAssets/ProductAssetController.cs

@ -69,7 +69,7 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssets
[HttpGet]
[Route("")]
public virtual Task<PagedResultDto<ProductAssetDto>> GetListAsync(PagedAndSortedResultRequestDto input)
public virtual Task<PagedResultDto<ProductAssetDto>> GetListAsync(GetProductAssetDto input)
{
return _service.GetListAsync(input);
}

12
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/EasyAbp.EShop.Plugins.Booking.Web.csproj

@ -41,16 +41,4 @@
<Content Remove="wwwroot\**\*.*" />
</ItemGroup>
<ItemGroup>
<Folder Include="Pages\EShop\Plugins" />
</ItemGroup>
<ItemGroup>
<_ContentIncludedByDefault Remove="Pages\Booking\Index.cshtml" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="Pages\EShop\Plugins\Booking\Index.cshtml" />
</ItemGroup>
</Project>

2
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/CreateModal.cshtml.cs

@ -8,7 +8,7 @@ namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductA
{
public class CreateModalModel : BookingPageModel
{
[BindProperty]
[BindProperty(SupportsGet = true)]
public CreateProductAssetCategoryViewModel ViewModel { get; set; }
private readonly IProductAssetCategoryAppService _service;

69
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/Index.cshtml

@ -25,24 +25,51 @@
<abp-style src="/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/index.css"/>
}
<abp-card>
<abp-card-header>
<abp-row>
<abp-column size-md="_6">
<abp-card-title>@L["ProductAssetCategory"]</abp-card-title>
</abp-column>
<abp-column size-md="_6" class="text-end">
@if (await Authorization.IsGrantedAsync(BookingPermissions.ProductAssetCategory.Create))
{
<abp-button id="NewProductAssetCategoryButton"
text="@L["CreateProductAssetCategory"].Value"
icon="plus"
button-type="Primary" />
}
</abp-column>
</abp-row>
</abp-card-header>
<abp-card-body>
<abp-table striped-rows="true" id="ProductAssetCategoryTable" class="nowrap"/>
</abp-card-body>
</abp-card>
<script>
let storeId = '@Model.Filter.StoreId';
</script>
@if (Model.Filter.StoreId == null)
{
<abp-dynamic-form abp-model="Filter" data-ajaxForm="true" asp-page="Index">
<abp-card>
<abp-card-header>
<abp-row>
<abp-column size-md="_6">
<abp-card-title>@L["ProductAssetCategory"]</abp-card-title>
</abp-column>
</abp-row>
</abp-card-header>
<abp-card-body>
<abp-form-content></abp-form-content>
</abp-card-body>
<abp-modal-footer>
<abp-button id="enter-button" button-type="Primary" text="Enter"/>
</abp-modal-footer>
</abp-card>
</abp-dynamic-form>
}
else
{
<abp-card>
<abp-card-header>
<abp-row>
<abp-column size-md="_6">
<abp-card-title>@L["ProductAssetCategory"]</abp-card-title>
</abp-column>
<abp-column size-md="_6" class="text-end">
@if (await Authorization.IsGrantedAsync(BookingPermissions.ProductAssetCategory.Create))
{
<abp-button id="NewProductAssetCategoryButton"
text="@L["CreateProductAssetCategory"].Value"
icon="plus"
button-type="Primary"/>
}
</abp-column>
</abp-row>
</abp-card-header>
<abp-card-body>
<abp-table striped-rows="true" id="ProductAssetCategoryTable" class="nowrap"/>
</abp-card-body>
</abp-card>
}

5
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/Index.cshtml.cs

@ -1,9 +1,14 @@
using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory
{
public class IndexModel : BookingPageModel
{
[BindProperty(SupportsGet = true)]
public ProductAssetCategoryListFilterViewModel Filter { get; set; }
public virtual async Task OnGetAsync()
{
await Task.CompletedTask;

5
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/ViewModels/CreateProductAssetCategoryViewModel.cs

@ -1,10 +1,15 @@
using System;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory.ViewModels
{
public class CreateProductAssetCategoryViewModel
{
[HiddenInput]
[Display(Name = "ProductAssetCategoryStoreId")]
public Guid StoreId { get; set; }
[Display(Name = "ProductAssetCategoryProductId")]
public Guid ProductId { get; set; }

19
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/ViewModels/ProductAssetCategoryListFilterViewModel.cs

@ -0,0 +1,19 @@
using System;
using System.ComponentModel.DataAnnotations;
using EasyAbp.Abp.TagHelperPlus.EasySelector;
using EasyAbp.EShop.Stores;
namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory.ViewModels
{
public class ProductAssetCategoryListFilterViewModel
{
[EasySelector(
getListedDataSourceUrl: StoresConsts.GetStoreListedDataSourceUrl + "?onlyManageable=true",
getSingleDataSourceUrl: StoresConsts.GetStoreSingleDataSourceUrl,
keyPropertyName: "id",
textPropertyName: "name",
runScriptOnWindowLoad: true)]
[Display(Name = "ProductAssetCategoryStoreId")]
public Guid? StoreId { get; set; }
}
}

13
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/index.js

@ -14,7 +14,9 @@ $(function () {
autoWidth: false,
scrollCollapse: true,
order: [[0, "asc"]],
ajax: abp.libs.datatables.createAjax(service.getList),
ajax: abp.libs.datatables.createAjax(service.getList, function () {
return { storeId: storeId }
}),
columnDefs: [
{
rowAction: {
@ -91,6 +93,13 @@ $(function () {
$('#NewProductAssetCategoryButton').click(function (e) {
e.preventDefault();
createModal.open();
createModal.open({ storeId: storeId });
});
$('#enter-button').click(function (e) {
e.preventDefault();
var storeId = $('#Filter_StoreId').val();
document.location.href = document.location.origin + document.location.pathname + '?storeId=' + storeId;
})
});

2
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/CreateModal.cshtml.cs

@ -8,7 +8,7 @@ namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductA
{
public class CreateModalModel : BookingPageModel
{
[BindProperty]
[BindProperty(SupportsGet = true)]
public CreateProductAssetViewModel ViewModel { get; set; }
private readonly IProductAssetAppService _service;

69
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/Index.cshtml

@ -25,24 +25,51 @@
<abp-style src="/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/index.css"/>
}
<abp-card>
<abp-card-header>
<abp-row>
<abp-column size-md="_6">
<abp-card-title>@L["ProductAsset"]</abp-card-title>
</abp-column>
<abp-column size-md="_6" class="text-end">
@if (await Authorization.IsGrantedAsync(BookingPermissions.ProductAsset.Create))
{
<abp-button id="NewProductAssetButton"
text="@L["CreateProductAsset"].Value"
icon="plus"
button-type="Primary" />
}
</abp-column>
</abp-row>
</abp-card-header>
<abp-card-body>
<abp-table striped-rows="true" id="ProductAssetTable" class="nowrap"/>
</abp-card-body>
</abp-card>
<script>
let storeId = '@Model.Filter.StoreId';
</script>
@if (Model.Filter.StoreId == null)
{
<abp-dynamic-form abp-model="Filter" data-ajaxForm="true" asp-page="Index">
<abp-card>
<abp-card-header>
<abp-row>
<abp-column size-md="_6">
<abp-card-title>@L["ProductAsset"]</abp-card-title>
</abp-column>
</abp-row>
</abp-card-header>
<abp-card-body>
<abp-form-content></abp-form-content>
</abp-card-body>
<abp-modal-footer>
<abp-button id="enter-button" button-type="Primary" text="Enter"/>
</abp-modal-footer>
</abp-card>
</abp-dynamic-form>
}
else
{
<abp-card>
<abp-card-header>
<abp-row>
<abp-column size-md="_6">
<abp-card-title>@L["ProductAsset"]</abp-card-title>
</abp-column>
<abp-column size-md="_6" class="text-end">
@if (await Authorization.IsGrantedAsync(BookingPermissions.ProductAsset.Create))
{
<abp-button id="NewProductAssetButton"
text="@L["CreateProductAsset"].Value"
icon="plus"
button-type="Primary"/>
}
</abp-column>
</abp-row>
</abp-card-header>
<abp-card-body>
<abp-table striped-rows="true" id="ProductAssetTable" class="nowrap"/>
</abp-card-body>
</abp-card>
}

5
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/Index.cshtml.cs

@ -1,9 +1,14 @@
using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssets.ProductAsset.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssets.ProductAsset
{
public class IndexModel : BookingPageModel
{
[BindProperty(SupportsGet = true)]
public ProductAssetListFilterViewModel Filter { get; set; }
public virtual async Task OnGetAsync()
{
await Task.CompletedTask;

6
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/ViewModels/CreateProductAssetViewModel.cs

@ -1,11 +1,15 @@
using System;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssets.ProductAsset.ViewModels
{
public class CreateProductAssetViewModel
{
[HiddenInput]
[Display(Name = "ProductAssetStoreId")]
public Guid StoreId { get; set; }
[Display(Name = "ProductAssetProductId")]
public Guid ProductId { get; set; }

20
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/ViewModels/ProductAssetListFilterViewModel.cs

@ -0,0 +1,20 @@
using System;
using System.ComponentModel.DataAnnotations;
using EasyAbp.Abp.TagHelperPlus.EasySelector;
using EasyAbp.EShop.Products;
using EasyAbp.EShop.Stores;
namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssets.ProductAsset.ViewModels
{
public class ProductAssetListFilterViewModel
{
[EasySelector(
getListedDataSourceUrl: StoresConsts.GetStoreListedDataSourceUrl + "?onlyManageable=true",
getSingleDataSourceUrl: StoresConsts.GetStoreSingleDataSourceUrl,
keyPropertyName: "id",
textPropertyName: "name",
runScriptOnWindowLoad: true)]
[Display(Name = "ProductAssetStoreId")]
public Guid? StoreId { get; set; }
}
}

13
plugins/Booking/src/EasyAbp.EShop.Plugins.Booking.Web/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/index.js

@ -14,7 +14,9 @@ $(function () {
autoWidth: false,
scrollCollapse: true,
order: [[0, "asc"]],
ajax: abp.libs.datatables.createAjax(service.getList),
ajax: abp.libs.datatables.createAjax(service.getList, function () {
return { storeId: storeId }
}),
columnDefs: [
{
rowAction: {
@ -91,6 +93,13 @@ $(function () {
$('#NewProductAssetButton').click(function (e) {
e.preventDefault();
createModal.open();
createModal.open({ storeId: storeId });
});
$('#enter-button').click(function (e) {
e.preventDefault();
var storeId = $('#Filter_StoreId').val();
document.location.href = document.location.origin + document.location.pathname + '?storeId=' + storeId;
})
});

5416
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220603163430_AddedStoreIdInProductAssetAndProductAssetCategory.Designer.cs

File diff suppressed because it is too large

38
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20220603163430_AddedStoreIdInProductAssetAndProductAssetCategory.cs

@ -0,0 +1,38 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace EShopSample.Migrations
{
public partial class AddedStoreIdInProductAssetAndProductAssetCategory : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "StoreId",
table: "EasyAbpEShopPluginsBookingProductAssets",
type: "uniqueidentifier",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
migrationBuilder.AddColumn<Guid>(
name: "StoreId",
table: "EasyAbpEShopPluginsBookingProductAssetCategories",
type: "uniqueidentifier",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "StoreId",
table: "EasyAbpEShopPluginsBookingProductAssets");
migrationBuilder.DropColumn(
name: "StoreId",
table: "EasyAbpEShopPluginsBookingProductAssetCategories");
}
}
}

6
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs

@ -847,6 +847,9 @@ namespace EShopSample.Migrations
b.Property<Guid>("ProductSkuId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("StoreId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");
@ -931,6 +934,9 @@ namespace EShopSample.Migrations
b.Property<Guid>("ProductSkuId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("StoreId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier")
.HasColumnName("TenantId");

Loading…
Cancel
Save