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); ProductsPermissions.Products.CrossStore);
} }
MapToEntity(input, detail); await MapToEntityAsync(input, detail);
await Repository.UpdateAsync(detail, autoSave: true); 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); .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) public override async Task<ProductDto> CreateAsync(CreateUpdateProductDto input)
{ {
var product = MapToEntity(input); var product = await MapToEntityAsync(input);
await CheckMultiStorePolicyAsync(product.StoreId, CreatePolicyName); await CheckMultiStorePolicyAsync(product.StoreId, CreatePolicyName);
@ -111,7 +104,7 @@ namespace EasyAbp.EShop.Products.Products
CheckProductIsNotStatic(product); CheckProductIsNotStatic(product);
MapToEntity(input, product); await MapToEntityAsync(input, product);
await UpdateProductAttributesAsync(product, input); 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 TEntity : class, IEntity, IMultiStore
where TCreateInput : IMultiStore where TCreateInput : IMultiStore
{ {
protected virtual string CrossStorePolicyName { get; set; } protected abstract string CrossStorePolicyName { get; set; }
protected MultiStoreAbstractKeyCrudAppService(IRepository<TEntity> repository) protected MultiStoreAbstractKeyCrudAppService(IRepository<TEntity> repository)
: base(repository) : base(repository)
@ -82,7 +82,7 @@ namespace EasyAbp.EShop.Stores.Stores
{ {
await CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName); await CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName);
var entity = MapToEntity(input); var entity = await MapToEntityAsync(input);
TryToSetTenantId(entity); TryToSetTenantId(entity);
@ -96,7 +96,7 @@ namespace EasyAbp.EShop.Stores.Stores
var entity = await GetEntityByIdAsync(id); var entity = await GetEntityByIdAsync(id);
await CheckMultiStorePolicyAsync(entity.StoreId, UpdatePolicyName); await CheckMultiStorePolicyAsync(entity.StoreId, UpdatePolicyName);
MapToEntity(input, entity); await MapToEntityAsync(input, entity);
await Repository.UpdateAsync(entity, autoSave: true); await Repository.UpdateAsync(entity, autoSave: true);
return await MapToGetOutputDtoAsync(entity); return await MapToGetOutputDtoAsync(entity);
@ -110,7 +110,6 @@ namespace EasyAbp.EShop.Stores.Stores
await DeleteByIdAsync(id); await DeleteByIdAsync(id);
} }
protected virtual async Task CheckMultiStorePolicyAsync(Guid? storeId, string policyName, bool crossStoreAllowed = true) protected virtual async Task CheckMultiStorePolicyAsync(Guid? storeId, string policyName, bool crossStoreAllowed = true)
{ {
if (crossStoreAllowed) 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); 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) if (updateInput is IEntityDto<TKey> entityDto)
{ {
entityDto.Id = entity.Id; entityDto.Id = entity.Id;
} }
base.MapToEntity(updateInput, entity); return base.MapToEntityAsync(updateInput, entity);
} }
protected override IQueryable<TEntity> ApplyDefaultSorting(IQueryable<TEntity> query) 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> </PropertyGroup>
<ItemGroup> <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="..\..\..\..\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" /> <ProjectReference Include="..\EasyAbp.EShop.Plugins.Booking.Application.Contracts\EasyAbp.EShop.Plugins.Booking.Application.Contracts.csproj" />
</ItemGroup> </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 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;
using EasyAbp.EShop.Orders.Orders.Dtos;
using EasyAbp.EShop.Plugins.Booking.BookingProductGroupDefinitions; 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 Microsoft.AspNetCore.Authorization;
using Volo.Abp;
namespace EasyAbp.EShop.Orders.Booking.Authorization namespace EasyAbp.EShop.Orders.Booking.Authorization
{ {
public class BookingOrderCreationAuthorizationHandler : OrderCreationAuthorizationHandler public class BookingOrderCreationAuthorizationHandler : OrderCreationAuthorizationHandler
{ {
private readonly IPeriodSchemeAppService _periodSchemeAppService;
private readonly IProductAssetAppService _productAssetAppService;
private readonly IProductAssetCategoryAppService _productAssetCategoryAppService;
private readonly IAssetOccupancyAppService _assetOccupancyAppService;
private readonly IBookingProductGroupDefinitionAppService _definitionAppService; private readonly IBookingProductGroupDefinitionAppService _definitionAppService;
public BookingOrderCreationAuthorizationHandler( public BookingOrderCreationAuthorizationHandler(
IPeriodSchemeAppService periodSchemeAppService,
IProductAssetAppService productAssetAppService,
IProductAssetCategoryAppService productAssetCategoryAppService,
IAssetOccupancyAppService assetOccupancyAppService,
IBookingProductGroupDefinitionAppService definitionAppService) IBookingProductGroupDefinitionAppService definitionAppService)
{ {
_periodSchemeAppService = periodSchemeAppService;
_productAssetAppService = productAssetAppService;
_productAssetCategoryAppService = productAssetCategoryAppService;
_assetOccupancyAppService = assetOccupancyAppService;
_definitionAppService = definitionAppService; _definitionAppService = definitionAppService;
} }
protected override async Task HandleOrderCreationAsync(AuthorizationHandlerContext context, protected override async Task HandleOrderCreationAsync(AuthorizationHandlerContext context,
OrderOperationAuthorizationRequirement requirement, OrderCreationResource resource) OrderOperationAuthorizationRequirement requirement, OrderCreationResource resource)
{ {
@ -29,26 +53,133 @@ namespace EasyAbp.EShop.Orders.Booking.Authorization
return; return;
} }
var models = new List<OccupyAssetInfoModel>();
var byCategoryModels = new List<OccupyAssetByCategoryInfoModel>();
foreach (var orderLine in bookingOrderLines) foreach (var orderLine in bookingOrderLines)
{ {
if (!await IsPeriodInfoValidAsync(orderLine))
{
context.Fail();
return;
}
var assetId = orderLine.FindBookingAssetId(); var assetId = orderLine.FindBookingAssetId();
var assetCategoryId = orderLine.FindBookingAssetCategoryId();
if (assetId is not null) if (assetId is not null)
{ {
// Todo: Invoke IProductAssetAppService to check the mapping. if (!await IsAssetInfoValidAsync(orderLine, resource))
} {
else 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 (!await IsAssetCategoryInfoValidAsync(orderLine, resource))
if (assetCategoryId is null)
{ {
context.Fail(); context.Fail();
return; 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; using Volo.Abp.Modularity;
namespace EasyAbp.EShop.Orders.Booking namespace EasyAbp.EShop.Orders.Booking
{ {
[DependsOn( [DependsOn(
typeof(EShopOrdersApplicationModule), typeof(EShopOrdersApplicationModule),
typeof(EShopOrdersApplicationContractsModule) typeof(EShopOrdersApplicationContractsModule),
typeof(BookingServiceApplicationContractsModule)
)] )]
public class EShopOrdersBookingApplicationModule : AbpModule 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.OrderLineBookingAssetId);
config.AddOrUpdateProperty<Guid?>(BookingOrderProperties.OrderLineBookingAssetCategoryId); config.AddOrUpdateProperty<Guid?>(BookingOrderProperties.OrderLineBookingAssetCategoryId);
config.AddOrUpdateProperty<Guid?>(BookingOrderProperties.OrderLineBookingPeriodSchemeId);
config.AddOrUpdateProperty<Guid?>(BookingOrderProperties.OrderLineBookingPeriodId);
config.AddOrUpdateProperty<DateTime?>(BookingOrderProperties.OrderLineBookingDate); config.AddOrUpdateProperty<DateTime?>(BookingOrderProperties.OrderLineBookingDate);
config.AddOrUpdateProperty<TimeSpan?>(BookingOrderProperties.OrderLineBookingStartingTime); config.AddOrUpdateProperty<TimeSpan?>(BookingOrderProperties.OrderLineBookingStartingTime);
config.AddOrUpdateProperty<TimeSpan?>(BookingOrderProperties.OrderLineBookingDuration); 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> </PropertyGroup>
<ItemGroup> <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="..\..\..\..\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" /> <ProjectReference Include="..\EasyAbp.EShop.Plugins.Booking.Application.Contracts\EasyAbp.EShop.Plugins.Booking.Application.Contracts.csproj" />
</ItemGroup> </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;
using EasyAbp.EShop.Orders.Orders.Dtos;
using EasyAbp.EShop.Payments.Payments; 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 Microsoft.AspNetCore.Authorization;
using Volo.Abp;
namespace EasyAbp.EShop.Payments.Booking.Authorization namespace EasyAbp.EShop.Payments.Booking.Authorization
{ {
public class BookingPaymentCreationAuthorizationHandler : PaymentCreationAuthorizationHandler 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, protected override async Task HandlePaymentCreationAsync(AuthorizationHandlerContext context,
PaymentOperationAuthorizationRequirement requirement, PaymentCreationResource resource) PaymentOperationAuthorizationRequirement requirement, PaymentCreationResource resource)
{ {
foreach (var order in resource.Orders) 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(); return false;
if (assetId is null) }
var assetId = orderLine.FindBookingAssetId();
var assetCategoryId = orderLine.FindBookingAssetCategoryId();
if (assetId is not null)
{
if (!await IsAssetInfoValidAsync(order, orderLine))
{ {
var assetCategoryId = orderLine.FindBookingAssetCategoryId(); return false;
if (assetCategoryId is null)
{
continue;
}
} }
// 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; using Volo.Abp.Modularity;
namespace EasyAbp.EShop.Payments.Booking namespace EasyAbp.EShop.Payments.Booking
{ {
[DependsOn( [DependsOn(
typeof(EShopPaymentsApplicationModule), typeof(EShopPaymentsApplicationModule),
typeof(EShopPluginsBookingApplicationContractsModule) typeof(EShopPluginsBookingApplicationContractsModule),
typeof(BookingServiceApplicationContractsModule)
)] )]
public class EShopPaymentsBookingApplicationModule : AbpModule 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 OrderLineBookingAssetId = "BookingAssetId";
public const string OrderLineBookingAssetCategoryId = "BookingAssetCategoryId"; public const string OrderLineBookingAssetCategoryId = "BookingAssetCategoryId";
public const string OrderLineBookingPeriodSchemeId = "BookingPeriodSchemeId";
public const string OrderLineBookingPeriodId = "BookingPeriodId";
public const string OrderLineBookingDate = "BookingDate"; 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); 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) public static DateTime? FindBookingDate(this CreateOrderLineDto orderLine)
{ {
return orderLine.GetProperty<DateTime?>(BookingOrderProperties.OrderLineBookingDate); 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); 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) public static DateTime? FindBookingDate(this IOrderLine orderLine)
{ {
return orderLine.GetProperty<DateTime?>(BookingOrderProperties.OrderLineBookingDate); 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 myGroup = context.AddGroup(BookingPermissions.GroupName, L("Permission:Booking"));
var productAssetPermission = myGroup.AddPermission(BookingPermissions.ProductAsset.Default, L("Permission:ProductAsset")); 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.Create, L("Permission:Create"));
productAssetPermission.AddChild(BookingPermissions.ProductAsset.Update, L("Permission:Update")); productAssetPermission.AddChild(BookingPermissions.ProductAsset.Update, L("Permission:Update"));
productAssetPermission.AddChild(BookingPermissions.ProductAsset.Delete, L("Permission:Delete")); productAssetPermission.AddChild(BookingPermissions.ProductAsset.Delete, L("Permission:Delete"));
var productAssetCategoryPermission = myGroup.AddPermission(BookingPermissions.ProductAssetCategory.Default, L("Permission:ProductAssetCategory")); 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.Create, L("Permission:Create"));
productAssetCategoryPermission.AddChild(BookingPermissions.ProductAssetCategory.Update, L("Permission:Update")); productAssetCategoryPermission.AddChild(BookingPermissions.ProductAssetCategory.Update, L("Permission:Update"));
productAssetCategoryPermission.AddChild(BookingPermissions.ProductAssetCategory.Delete, L("Permission:Delete")); 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 class ProductAsset
{ {
public const string Default = GroupName + ".ProductAsset"; public const string Default = GroupName + ".ProductAsset";
public const string Manage = Default + ".Manage";
public const string Update = Default + ".Update"; public const string Update = Default + ".Update";
public const string Create = Default + ".Create"; public const string Create = Default + ".Create";
public const string Delete = Default + ".Delete"; public const string Delete = Default + ".Delete";
@ -22,6 +23,7 @@ public class BookingPermissions
public class ProductAssetCategory public class ProductAssetCategory
{ {
public const string Default = GroupName + ".ProductAssetCategory"; public const string Default = GroupName + ".ProductAssetCategory";
public const string Manage = Default + ".Manage";
public const string Update = Default + ".Update"; public const string Update = Default + ".Update";
public const string Create = Default + ".Create"; public const string Create = Default + ".Create";
public const string Delete = Default + ".Delete"; 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;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using EasyAbp.EShop.Stores.Stores;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.Dtos namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.Dtos
{ {
[Serializable] [Serializable]
public class CreateProductAssetCategoryDto public class CreateProductAssetCategoryDto : IMultiStore
{ {
public Guid StoreId { get; set; }
public Guid ProductId { get; set; } public Guid ProductId { get; set; }
public Guid ProductSkuId { 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] [Serializable]
public class ProductAssetCategoryDto : AuditedEntityDto<Guid> public class ProductAssetCategoryDto : AuditedEntityDto<Guid>
{ {
public Guid StoreId { get; set; }
public Guid ProductId { get; set; } public Guid ProductId { get; set; }
public Guid ProductSkuId { 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;
using System.Threading.Tasks; using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.Dtos; using EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.Dtos;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories
@ -10,7 +9,7 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories
ICrudAppService< ICrudAppService<
ProductAssetCategoryDto, ProductAssetCategoryDto,
Guid, Guid,
PagedAndSortedResultRequestDto, GetProductAssetCategoryDto,
CreateProductAssetCategoryDto, CreateProductAssetCategoryDto,
UpdateProductAssetCategoryDto> 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;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using EasyAbp.EShop.Stores.Stores;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssets.Dtos namespace EasyAbp.EShop.Plugins.Booking.ProductAssets.Dtos
{ {
[Serializable] [Serializable]
public class CreateProductAssetDto public class CreateProductAssetDto : IMultiStore
{ {
public Guid StoreId { get; set; }
public Guid ProductId { get; set; } public Guid ProductId { get; set; }
public Guid ProductSkuId { 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] [Serializable]
public class ProductAssetDto : AuditedEntityDto<Guid> public class ProductAssetDto : AuditedEntityDto<Guid>
{ {
public Guid StoreId { get; set; }
public Guid ProductId { get; set; } public Guid ProductId { get; set; }
public Guid ProductSkuId { 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< ICrudAppService<
ProductAssetDto, ProductAssetDto,
Guid, Guid,
PagedAndSortedResultRequestDto, GetProductAssetDto,
CreateProductAssetDto, CreateProductAssetDto,
UpdateProductAssetDto> UpdateProductAssetDto>
{ {

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

@ -10,6 +10,9 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.AutoMapper" Version="$(AbpVersion)" /> <PackageReference Include="Volo.Abp.AutoMapper" Version="$(AbpVersion)" />
<PackageReference Include="Volo.Abp.Ddd.Application" 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.Application.Contracts\EasyAbp.EShop.Plugins.Booking.Application.Contracts.csproj" />
<ProjectReference Include="..\EasyAbp.EShop.Plugins.Booking.Domain\EasyAbp.EShop.Plugins.Booking.Domain.csproj" /> <ProjectReference Include="..\EasyAbp.EShop.Plugins.Booking.Domain\EasyAbp.EShop.Plugins.Booking.Domain.csproj" />
</ItemGroup> </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 * Alternatively, you can split your mapping configurations
* into multiple profile classes for a better organization. */ * into multiple profile classes for a better organization. */
CreateMap<ProductAsset, ProductAssetDto>(); CreateMap<ProductAsset, ProductAssetDto>();
CreateMap<CreateProductAssetDto, ProductAsset>(MemberList.Source);
CreateMap<UpdateProductAssetDto, ProductAsset>(MemberList.Source);
CreateMap<ProductAssetPeriod, ProductAssetPeriodDto>(); CreateMap<ProductAssetPeriod, ProductAssetPeriodDto>();
CreateMap<CreateProductAssetPeriodDto, ProductAssetPeriod>(MemberList.Source); CreateMap<CreateProductAssetPeriodDto, ProductAssetPeriod>(MemberList.Source);
CreateMap<UpdateProductAssetPeriodDto, ProductAssetPeriod>(MemberList.Source); CreateMap<UpdateProductAssetPeriodDto, ProductAssetPeriod>(MemberList.Source);
CreateMap<ProductAssetCategory, ProductAssetCategoryDto>(); CreateMap<ProductAssetCategory, ProductAssetCategoryDto>();
CreateMap<CreateProductAssetCategoryDto, ProductAssetCategory>(MemberList.Source);
CreateMap<UpdateProductAssetCategoryDto, ProductAssetCategory>(MemberList.Source);
CreateMap<ProductAssetCategoryPeriod, ProductAssetCategoryPeriodDto>(); CreateMap<ProductAssetCategoryPeriod, ProductAssetCategoryPeriodDto>();
CreateMap<CreateProductAssetCategoryPeriodDto, ProductAssetCategoryPeriod>(MemberList.Source); 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.AutoMapper;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Application; using Volo.Abp.Application;
@ -6,8 +9,11 @@ using Volo.Abp.Application;
namespace EasyAbp.EShop.Plugins.Booking; namespace EasyAbp.EShop.Plugins.Booking;
[DependsOn( [DependsOn(
typeof(EShopStoresApplicationSharedModule),
typeof(EShopProductsApplicationContractsModule),
typeof(EShopPluginsBookingDomainModule), typeof(EShopPluginsBookingDomainModule),
typeof(EShopPluginsBookingApplicationContractsModule), typeof(EShopPluginsBookingApplicationContractsModule),
typeof(BookingServiceApplicationContractsModule),
typeof(AbpDddApplicationModule), typeof(AbpDddApplicationModule),
typeof(AbpAutoMapperModule) 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;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using EasyAbp.BookingService.AssetCategories;
using EasyAbp.BookingService.PeriodSchemes;
using EasyAbp.EShop.Plugins.Booking.Permissions; using EasyAbp.EShop.Plugins.Booking.Permissions;
using EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.Dtos; 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.Dtos;
using Volo.Abp.Application.Services;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories 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 IProductAssetCategoryAppService
{ {
protected override string CrossStorePolicyName { get; set; } = BookingPermissions.ProductAssetCategory.Manage;
protected override string GetPolicyName { get; set; } = BookingPermissions.ProductAssetCategory.Default; protected override string GetPolicyName { get; set; } = BookingPermissions.ProductAssetCategory.Default;
protected override string GetListPolicyName { 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 CreatePolicyName { get; set; } = BookingPermissions.ProductAssetCategory.Create;
protected override string UpdatePolicyName { get; set; } = BookingPermissions.ProductAssetCategory.Update; protected override string UpdatePolicyName { get; set; } = BookingPermissions.ProductAssetCategory.Update;
protected override string DeletePolicyName { get; set; } = BookingPermissions.ProductAssetCategory.Delete; 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 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; _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(); await CheckMultiStorePolicyAsync(input.StoreId, CreatePolicyName);
var productAsset = await GetEntityByIdAsync(productAssetCategoryId); 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); 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) public virtual async Task<ProductAssetCategoryDto> DeletePeriodAsync(Guid productAssetCategoryId, Guid periodId)
{ {
await CheckUpdatePolicyAsync(); var productAssetCategory = await GetEntityByIdAsync(productAssetCategoryId);
var productAsset = 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;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using EasyAbp.BookingService.Assets;
using EasyAbp.BookingService.PeriodSchemes;
using EasyAbp.EShop.Plugins.Booking.Permissions; using EasyAbp.EShop.Plugins.Booking.Permissions;
using EasyAbp.EShop.Plugins.Booking.ProductAssets.Dtos; 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.Dtos;
using Volo.Abp.Application.Services;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssets 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 IProductAssetAppService
{ {
protected override string CrossStorePolicyName { get; set; } = BookingPermissions.ProductAsset.Manage;
protected override string GetPolicyName { get; set; } = BookingPermissions.ProductAsset.Default; protected override string GetPolicyName { get; set; } = BookingPermissions.ProductAsset.Default;
protected override string GetListPolicyName { 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 CreatePolicyName { get; set; } = BookingPermissions.ProductAsset.Create;
protected override string UpdatePolicyName { get; set; } = BookingPermissions.ProductAsset.Update; protected override string UpdatePolicyName { get; set; } = BookingPermissions.ProductAsset.Update;
protected override string DeletePolicyName { get; set; } = BookingPermissions.ProductAsset.Delete; 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 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; _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); 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); await _repository.UpdateAsync(productAsset, true);
return await MapToGetOutputDtoAsync(productAsset); 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); var productAsset = await GetEntityByIdAsync(productAssetId);
await CheckMultiStorePolicyAsync(productAsset.StoreId, UpdatePolicyName);
var productAssetPeriod = productAsset.GetPeriod(periodId); var productAssetPeriod = productAsset.GetPeriod(periodId);
ObjectMapper.Map(input, productAssetPeriod); ObjectMapper.Map(input, productAssetPeriod);
await _repository.UpdateAsync(productAsset, true); 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) public virtual async Task<ProductAssetDto> DeletePeriodAsync(Guid productAssetId, Guid periodId)
{ {
await CheckUpdatePolicyAsync();
var productAsset = await GetEntityByIdAsync(productAssetId); var productAsset = await GetEntityByIdAsync(productAssetId);
await CheckMultiStorePolicyAsync(productAsset.StoreId, UpdatePolicyName);
productAsset.RemovePeriod(periodId); productAsset.RemovePeriod(periodId);
await _repository.UpdateAsync(productAsset, true); 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 PeriodNotFound = "EasyAbp.EShop.Plugins.Booking:PeriodNotFound";
public const string DuplicatePeriod = "EasyAbp.EShop.Plugins.Booking:DuplicatePeriod"; 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", "Permission:Delete": "Delete",
"Menu:ProductAsset": "Asset prices", "Menu:ProductAsset": "Asset prices",
"ProductAsset": "Asset prices", "ProductAsset": "Asset prices",
"ProductAssetStoreId": "Store ID",
"ProductAssetProductId": "Product ID", "ProductAssetProductId": "Product ID",
"ProductAssetProductSkuId": "Product SKU ID", "ProductAssetProductSkuId": "Product SKU ID",
"ProductAssetAssetId": "Asset ID", "ProductAssetAssetId": "Asset ID",
@ -30,6 +31,7 @@
"Permission:ProductAssetCategory": "Asset category prices", "Permission:ProductAssetCategory": "Asset category prices",
"Menu:ProductAssetCategory": "Asset category prices", "Menu:ProductAssetCategory": "Asset category prices",
"ProductAssetCategory": "Asset category prices", "ProductAssetCategory": "Asset category prices",
"ProductAssetCategoryStoreId": "Store ID",
"ProductAssetCategoryProductId": "Product ID", "ProductAssetCategoryProductId": "Product ID",
"ProductAssetCategoryProductSkuId": "Product SKU ID", "ProductAssetCategoryProductSkuId": "Product SKU ID",
"ProductAssetCategoryAssetCategoryId": "Asset Category ID", "ProductAssetCategoryAssetCategoryId": "Asset Category ID",
@ -50,6 +52,9 @@
"ProductAssetCategoryPeriodDeletionConfirmationMessage": "Are you sure to delete the product asset category period {0}?", "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:PeriodNotFound": "Period {id} not found.",
"EasyAbp.EShop.Plugins.Booking:DuplicatePeriod": "Period {id} exists.", "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", "Permission:StoreAssetCategory": "Store assets",
"Menu:StoreAssetCategory": "Store assets", "Menu:StoreAssetCategory": "Store assets",
"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": "删除", "Permission:Delete": "删除",
"Menu:ProductAsset": "资产价格", "Menu:ProductAsset": "资产价格",
"ProductAsset": "资产价格", "ProductAsset": "资产价格",
"ProductAssetStoreId": "店铺 ID",
"ProductAssetProductId": "产品 ID", "ProductAssetProductId": "产品 ID",
"ProductAssetProductSkuId": "产品 SKU ID", "ProductAssetProductSkuId": "产品 SKU ID",
"ProductAssetAssetId": "资产 ID", "ProductAssetAssetId": "资产 ID",
@ -30,6 +31,7 @@
"Permission:ProductAssetCategory": "资产类目价格", "Permission:ProductAssetCategory": "资产类目价格",
"Menu:ProductAssetCategory": "资产类目价格", "Menu:ProductAssetCategory": "资产类目价格",
"ProductAssetCategory": "资产类目价格", "ProductAssetCategory": "资产类目价格",
"ProductAssetCategoryStoreId": "店铺 ID",
"ProductAssetCategoryProductId": "产品 ID", "ProductAssetCategoryProductId": "产品 ID",
"ProductAssetCategoryProductSkuId": "产品 SKU ID", "ProductAssetCategoryProductSkuId": "产品 SKU ID",
"ProductAssetCategoryAssetCategoryId": "资产目录 ID", "ProductAssetCategoryAssetCategoryId": "资产目录 ID",
@ -50,6 +52,9 @@
"ProductAssetCategoryPeriodDeletionConfirmationMessage": "确认删除资产类目时段价格 {0}?", "ProductAssetCategoryPeriodDeletionConfirmationMessage": "确认删除资产类目时段价格 {0}?",
"EasyAbp.EShop.Plugins.Booking:PeriodNotFound": "时段 {id} 不存在。", "EasyAbp.EShop.Plugins.Booking:PeriodNotFound": "时段 {id} 不存在。",
"EasyAbp.EShop.Plugins.Booking:DuplicatePeriod": "时段 {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": "店铺资产", "Permission:StoreAssetCategory": "店铺资产",
"Menu:StoreAssetCategory": "店铺资产", "Menu:StoreAssetCategory": "店铺资产",
"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": "刪除", "Permission:Delete": "刪除",
"Menu:ProductAsset": "資產價格", "Menu:ProductAsset": "資產價格",
"ProductAsset": "資產價格", "ProductAsset": "資產價格",
"ProductAssetStoreId": "店鋪 ID",
"ProductAssetProductId": "產品 ID", "ProductAssetProductId": "產品 ID",
"ProductAssetProductSkuId": "產品 SKU ID", "ProductAssetProductSkuId": "產品 SKU ID",
"ProductAssetAssetId": "資產 ID", "ProductAssetAssetId": "資產 ID",
@ -30,6 +31,7 @@
"Permission:ProductAssetCategory": "資產類目價格", "Permission:ProductAssetCategory": "資產類目價格",
"Menu:ProductAssetCategory": "資產類目價格", "Menu:ProductAssetCategory": "資產類目價格",
"ProductAssetCategory": "資產類目價格", "ProductAssetCategory": "資產類目價格",
"ProductAssetCategoryStoreId": "店鋪 ID",
"ProductAssetCategoryProductId": "產品 ID", "ProductAssetCategoryProductId": "產品 ID",
"ProductAssetCategoryProductSkuId": "產品 SKU ID", "ProductAssetCategoryProductSkuId": "產品 SKU ID",
"ProductAssetCategoryAssetCategoryId": "資產目錄 ID", "ProductAssetCategoryAssetCategoryId": "資產目錄 ID",
@ -50,6 +52,9 @@
"ProductAssetCategoryPeriodDeletionConfirmationMessage": "確認刪除資產類目時段價格 {0}?", "ProductAssetCategoryPeriodDeletionConfirmationMessage": "確認刪除資產類目時段價格 {0}?",
"EasyAbp.EShop.Plugins.Booking:PeriodNotFound": "時段 {id} 不存在。", "EasyAbp.EShop.Plugins.Booking:PeriodNotFound": "時段 {id} 不存在。",
"EasyAbp.EShop.Plugins.Booking:DuplicatePeriod": "時段 {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": "店鋪資產", "Permission:StoreAssetCategory": "店鋪資產",
"Menu:StoreAssetCategory": "店鋪資產", "Menu:StoreAssetCategory": "店鋪資產",
"StoreAssetCategory": "店鋪資產", "StoreAssetCategory": "店鋪資產",

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

@ -9,6 +9,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="$(AbpVersion)" /> <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" /> <ProjectReference Include="..\EasyAbp.EShop.Plugins.Booking.Domain.Shared\EasyAbp.EShop.Plugins.Booking.Domain.Shared.csproj" />
</ItemGroup> </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; using Volo.Abp.Modularity;
namespace EasyAbp.EShop.Plugins.Booking; namespace EasyAbp.EShop.Plugins.Booking;
[DependsOn( [DependsOn(
typeof(AbpDddDomainModule), typeof(AbpDddDomainModule),
typeof(EShopStoresDomainSharedModule),
typeof(EShopPluginsBookingDomainSharedModule) typeof(EShopPluginsBookingDomainSharedModule)
)] )]
public class EShopPluginsBookingDomainModule : AbpModule 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;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories
{ {
public interface IProductAssetCategoryRepository : IRepository<ProductAssetCategory, Guid> 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.Collections.Generic;
using System.Linq; using System.Linq;
using EasyAbp.EShop.Plugins.Booking.Shared; using EasyAbp.EShop.Plugins.Booking.Shared;
using EasyAbp.EShop.Stores.Stores;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy; 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. /// Set which SKU can use to book a specified asset category.
/// The matched <see cref="ProductAssetCategory"/> with the larger <see cref="FromTime"/> takes precedence. /// The matched <see cref="ProductAssetCategory"/> with the larger <see cref="FromTime"/> takes precedence.
/// </summary> /// </summary>
public class ProductAssetCategory : AuditedAggregateRoot<Guid>, IMultiTenant public class ProductAssetCategory : AuditedAggregateRoot<Guid>, IMultiStore, IMultiTenant
{ {
public virtual Guid? TenantId { get; protected set; } public virtual Guid? TenantId { get; protected set; }
public virtual Guid StoreId { get; protected set; }
public virtual Guid ProductId { get; protected set; } public virtual Guid ProductId { get; protected set; }
public virtual Guid ProductSkuId { get; protected set; } public virtual Guid ProductSkuId { get; protected set; }
@ -53,6 +56,7 @@ public class ProductAssetCategory : AuditedAggregateRoot<Guid>, IMultiTenant
public ProductAssetCategory( public ProductAssetCategory(
Guid id, Guid id,
Guid? tenantId, Guid? tenantId,
Guid storeId,
Guid productId, Guid productId,
Guid productSkuId, Guid productSkuId,
Guid assetCategoryId, Guid assetCategoryId,
@ -64,6 +68,7 @@ public class ProductAssetCategory : AuditedAggregateRoot<Guid>, IMultiTenant
) : base(id) ) : base(id)
{ {
TenantId = tenantId; TenantId = tenantId;
StoreId = storeId;
ProductId = productId; ProductId = productId;
ProductSkuId = productSkuId; ProductSkuId = productSkuId;
AssetCategoryId = assetCategoryId; AssetCategoryId = assetCategoryId;
@ -71,9 +76,17 @@ public class ProductAssetCategory : AuditedAggregateRoot<Guid>, IMultiTenant
FromTime = fromTime; FromTime = fromTime;
ToTime = toTime; ToTime = toTime;
Price = price; Price = price;
Periods = periods ?? new List<ProductAssetCategoryPeriod>(); 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) public void AddPeriod(ProductAssetCategoryPeriod productAssetCategoryPeriod)
{ {
if (FindPeriod(productAssetCategoryPeriod.PeriodId) is not null) 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;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssets namespace EasyAbp.EShop.Plugins.Booking.ProductAssets
{ {
public interface IProductAssetRepository : IRepository<ProductAsset, Guid> 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 System.Linq;
using EasyAbp.EShop.Plugins.Booking.ProductAssetCategories; using EasyAbp.EShop.Plugins.Booking.ProductAssetCategories;
using EasyAbp.EShop.Plugins.Booking.Shared; using EasyAbp.EShop.Plugins.Booking.Shared;
using EasyAbp.EShop.Stores.Stores;
using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy; 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. /// 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"/>. /// Fall back to <see cref="ProductAssetCategory"/> if the booking asset has no matched <see cref="ProductAsset"/>.
/// </summary> /// </summary>
public class ProductAsset : AuditedAggregateRoot<Guid>, IMultiTenant public class ProductAsset : AuditedAggregateRoot<Guid>, IMultiStore, IMultiTenant
{ {
public virtual Guid? TenantId { get; protected set; } public virtual Guid? TenantId { get; protected set; }
public virtual Guid StoreId { get; protected set; }
public virtual Guid ProductId { get; protected set; } public virtual Guid ProductId { get; protected set; }
public virtual Guid ProductSkuId { 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 id,
Guid? tenantId, Guid? tenantId,
Guid storeId,
Guid productId, Guid productId,
Guid productSkuId, Guid productSkuId,
Guid assetId, Guid assetId,
@ -66,6 +70,7 @@ public class ProductAsset : AuditedAggregateRoot<Guid>, IMultiTenant
) : base(id) ) : base(id)
{ {
TenantId = tenantId; TenantId = tenantId;
StoreId = storeId;
ProductId = productId; ProductId = productId;
ProductSkuId = productSkuId; ProductSkuId = productSkuId;
AssetId = assetId; AssetId = assetId;
@ -77,6 +82,13 @@ public class ProductAsset : AuditedAggregateRoot<Guid>, IMultiTenant
Periods = periods ?? new List<ProductAssetPeriod>(); 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) public void AddPeriod(ProductAssetPeriod productAssetPeriod)
{ {
if (FindPeriod(productAssetPeriod.PeriodId) is not null) 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.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore; using EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
@ -17,5 +18,37 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories
{ {
return (await GetQueryableAsync()).IncludeDetails(); 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.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore; using EasyAbp.EShop.Plugins.Booking.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssets 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) public ProductAssetRepository(IDbContextProvider<IBookingDbContext> dbContextProvider) : base(dbContextProvider)
{ {
@ -17,5 +19,37 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssets
{ {
return (await GetQueryableAsync()).IncludeDetails(); 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;
} }
return queryable return queryable;
// .Include(x => x.xxx) // TODO: AbpHelper generated
;
} }
} }
} }

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 System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Application.Dtos;
namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories
{ {
@ -70,7 +69,7 @@ namespace EasyAbp.EShop.Plugins.Booking.ProductAssetCategories
[HttpGet] [HttpGet]
[Route("")] [Route("")]
public virtual Task<PagedResultDto<ProductAssetCategoryDto>> GetListAsync(PagedAndSortedResultRequestDto input) public virtual Task<PagedResultDto<ProductAssetCategoryDto>> GetListAsync(GetProductAssetCategoryDto input)
{ {
return _service.GetListAsync(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] [HttpGet]
[Route("")] [Route("")]
public virtual Task<PagedResultDto<ProductAssetDto>> GetListAsync(PagedAndSortedResultRequestDto input) public virtual Task<PagedResultDto<ProductAssetDto>> GetListAsync(GetProductAssetDto input)
{ {
return _service.GetListAsync(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\**\*.*" /> <Content Remove="wwwroot\**\*.*" />
</ItemGroup> </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> </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 public class CreateModalModel : BookingPageModel
{ {
[BindProperty] [BindProperty(SupportsGet = true)]
public CreateProductAssetCategoryViewModel ViewModel { get; set; } public CreateProductAssetCategoryViewModel ViewModel { get; set; }
private readonly IProductAssetCategoryAppService _service; 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-style src="/Pages/EShop/Plugins/Booking/ProductAssetCategories/ProductAssetCategory/index.css"/>
} }
<abp-card> <script>
<abp-card-header> let storeId = '@Model.Filter.StoreId';
<abp-row> </script>
<abp-column size-md="_6">
<abp-card-title>@L["ProductAssetCategory"]</abp-card-title> @if (Model.Filter.StoreId == null)
</abp-column> {
<abp-column size-md="_6" class="text-end"> <abp-dynamic-form abp-model="Filter" data-ajaxForm="true" asp-page="Index">
@if (await Authorization.IsGrantedAsync(BookingPermissions.ProductAssetCategory.Create)) <abp-card>
{ <abp-card-header>
<abp-button id="NewProductAssetCategoryButton" <abp-row>
text="@L["CreateProductAssetCategory"].Value" <abp-column size-md="_6">
icon="plus" <abp-card-title>@L["ProductAssetCategory"]</abp-card-title>
button-type="Primary" /> </abp-column>
} </abp-row>
</abp-column> </abp-card-header>
</abp-row> <abp-card-body>
</abp-card-header> <abp-form-content></abp-form-content>
<abp-card-body> </abp-card-body>
<abp-table striped-rows="true" id="ProductAssetCategoryTable" class="nowrap"/> <abp-modal-footer>
</abp-card-body> <abp-button id="enter-button" button-type="Primary" text="Enter"/>
</abp-card> </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 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 namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory
{ {
public class IndexModel : BookingPageModel public class IndexModel : BookingPageModel
{ {
[BindProperty(SupportsGet = true)]
public ProductAssetCategoryListFilterViewModel Filter { get; set; }
public virtual async Task OnGetAsync() public virtual async Task OnGetAsync()
{ {
await Task.CompletedTask; 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;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory.ViewModels namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory.ViewModels
{ {
public class CreateProductAssetCategoryViewModel public class CreateProductAssetCategoryViewModel
{ {
[HiddenInput]
[Display(Name = "ProductAssetCategoryStoreId")]
public Guid StoreId { get; set; }
[Display(Name = "ProductAssetCategoryProductId")] [Display(Name = "ProductAssetCategoryProductId")]
public Guid ProductId { get; set; } 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, autoWidth: false,
scrollCollapse: true, scrollCollapse: true,
order: [[0, "asc"]], order: [[0, "asc"]],
ajax: abp.libs.datatables.createAjax(service.getList), ajax: abp.libs.datatables.createAjax(service.getList, function () {
return { storeId: storeId }
}),
columnDefs: [ columnDefs: [
{ {
rowAction: { rowAction: {
@ -91,6 +93,13 @@ $(function () {
$('#NewProductAssetCategoryButton').click(function (e) { $('#NewProductAssetCategoryButton').click(function (e) {
e.preventDefault(); 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 public class CreateModalModel : BookingPageModel
{ {
[BindProperty] [BindProperty(SupportsGet = true)]
public CreateProductAssetViewModel ViewModel { get; set; } public CreateProductAssetViewModel ViewModel { get; set; }
private readonly IProductAssetAppService _service; 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-style src="/Pages/EShop/Plugins/Booking/ProductAssets/ProductAsset/index.css"/>
} }
<abp-card> <script>
<abp-card-header> let storeId = '@Model.Filter.StoreId';
<abp-row> </script>
<abp-column size-md="_6">
<abp-card-title>@L["ProductAsset"]</abp-card-title> @if (Model.Filter.StoreId == null)
</abp-column> {
<abp-column size-md="_6" class="text-end"> <abp-dynamic-form abp-model="Filter" data-ajaxForm="true" asp-page="Index">
@if (await Authorization.IsGrantedAsync(BookingPermissions.ProductAsset.Create)) <abp-card>
{ <abp-card-header>
<abp-button id="NewProductAssetButton" <abp-row>
text="@L["CreateProductAsset"].Value" <abp-column size-md="_6">
icon="plus" <abp-card-title>@L["ProductAsset"]</abp-card-title>
button-type="Primary" /> </abp-column>
} </abp-row>
</abp-column> </abp-card-header>
</abp-row> <abp-card-body>
</abp-card-header> <abp-form-content></abp-form-content>
<abp-card-body> </abp-card-body>
<abp-table striped-rows="true" id="ProductAssetTable" class="nowrap"/> <abp-modal-footer>
</abp-card-body> <abp-button id="enter-button" button-type="Primary" text="Enter"/>
</abp-card> </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 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 namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssets.ProductAsset
{ {
public class IndexModel : BookingPageModel public class IndexModel : BookingPageModel
{ {
[BindProperty(SupportsGet = true)]
public ProductAssetListFilterViewModel Filter { get; set; }
public virtual async Task OnGetAsync() public virtual async Task OnGetAsync()
{ {
await Task.CompletedTask; 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;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssets.ProductAsset.ViewModels namespace EasyAbp.EShop.Plugins.Booking.Web.Pages.EShop.Plugins.Booking.ProductAssets.ProductAsset.ViewModels
{ {
public class CreateProductAssetViewModel public class CreateProductAssetViewModel
{ {
[HiddenInput]
[Display(Name = "ProductAssetStoreId")]
public Guid StoreId { get; set; }
[Display(Name = "ProductAssetProductId")] [Display(Name = "ProductAssetProductId")]
public Guid ProductId { get; set; } 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, autoWidth: false,
scrollCollapse: true, scrollCollapse: true,
order: [[0, "asc"]], order: [[0, "asc"]],
ajax: abp.libs.datatables.createAjax(service.getList), ajax: abp.libs.datatables.createAjax(service.getList, function () {
return { storeId: storeId }
}),
columnDefs: [ columnDefs: [
{ {
rowAction: { rowAction: {
@ -91,6 +93,13 @@ $(function () {
$('#NewProductAssetButton').click(function (e) { $('#NewProductAssetButton').click(function (e) {
e.preventDefault(); 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") b.Property<Guid>("ProductSkuId")
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
b.Property<Guid>("StoreId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId") b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier") .HasColumnType("uniqueidentifier")
.HasColumnName("TenantId"); .HasColumnName("TenantId");
@ -931,6 +934,9 @@ namespace EShopSample.Migrations
b.Property<Guid>("ProductSkuId") b.Property<Guid>("ProductSkuId")
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
b.Property<Guid>("StoreId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId") b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier") .HasColumnType("uniqueidentifier")
.HasColumnName("TenantId"); .HasColumnName("TenantId");

Loading…
Cancel
Save