mirror of https://github.com/EasyAbp/EShop.git
101 changed files with 28389 additions and 67 deletions
@ -0,0 +1,10 @@ |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Products.Products.Dtos; |
|||
|
|||
namespace EasyAbp.EShop.Products.Products |
|||
{ |
|||
public interface IProductSkuDescriptionProvider |
|||
{ |
|||
Task<string> GenerateAsync(ProductDto productDto, ProductSkuDto productSkuDto); |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using System.Collections.ObjectModel; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Products.Products.Dtos; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Json; |
|||
|
|||
namespace EasyAbp.EShop.Products.Products |
|||
{ |
|||
public class ProductSkuDescriptionProvider : IProductSkuDescriptionProvider, ITransientDependency |
|||
{ |
|||
private readonly IJsonSerializer _jsonSerializer; |
|||
|
|||
public ProductSkuDescriptionProvider(IJsonSerializer jsonSerializer) |
|||
{ |
|||
_jsonSerializer = jsonSerializer; |
|||
} |
|||
|
|||
public virtual Task<string> GenerateAsync(ProductDto productDto, ProductSkuDto productSkuDto) |
|||
{ |
|||
var names = new Collection<string[]>(); |
|||
|
|||
foreach (var attributeOptionId in productSkuDto.AttributeOptionIds) |
|||
{ |
|||
names.Add(productDto.ProductAttributes.SelectMany( |
|||
attribute => attribute.ProductAttributeOptions.Where(option => option.Id == attributeOptionId), |
|||
(attribute, option) => new [] {attribute.DisplayName, option.DisplayName}).Single()); |
|||
} |
|||
|
|||
return Task.FromResult(_jsonSerializer.Serialize(names)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System; |
|||
using Volo.Abp; |
|||
|
|||
namespace EasyAbp.EShop.Products.ProductInventories |
|||
{ |
|||
public class InventoryInsufficientException : BusinessException |
|||
{ |
|||
public InventoryInsufficientException(Guid productId, Guid productSkuId, int quantity, int inventory) : base( |
|||
message: $"The inventory of the product {productId} (SKU: {productSkuId}) is insufficient, {quantity} are needed, but only {inventory}.") |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace EasyAbp.EShop.Products.ProductInventories |
|||
{ |
|||
public class ProductInventoryChangedEto : IMultiTenant |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
public Guid? TenantId { get; set; } |
|||
|
|||
public Guid ProductId { get; set; } |
|||
|
|||
public Guid ProductSkuId { get; set; } |
|||
|
|||
public int OriginalInventory { get; set; } |
|||
|
|||
public int NewInventory { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Data; |
|||
|
|||
namespace EasyAbp.EShop.Products.Products |
|||
{ |
|||
public interface IProduct : IHasExtraProperties |
|||
{ |
|||
Guid ProductTypeId { get; } |
|||
|
|||
Guid ProductDetailId { get; } |
|||
|
|||
string Code { get; } |
|||
|
|||
string DisplayName { get; } |
|||
|
|||
InventoryStrategy InventoryStrategy { get; } |
|||
|
|||
string MediaResources { get; } |
|||
|
|||
int DisplayOrder { get; } |
|||
|
|||
bool IsPublished { get; } |
|||
|
|||
bool IsStatic { get; } |
|||
|
|||
bool IsHidden { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace EasyAbp.EShop.Products.Products |
|||
{ |
|||
public interface IProductAttribute |
|||
{ |
|||
string DisplayName { get; } |
|||
|
|||
string Description { get; } |
|||
|
|||
int DisplayOrder { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
namespace EasyAbp.EShop.Products.Products |
|||
{ |
|||
public interface IProductAttributeOption |
|||
{ |
|||
string DisplayName { get; } |
|||
|
|||
string Description { get; } |
|||
|
|||
int DisplayOrder { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System; |
|||
|
|||
namespace EasyAbp.EShop.Products.Products |
|||
{ |
|||
public interface IProductSku |
|||
{ |
|||
string SerializedAttributeOptionIds { get; } |
|||
|
|||
string Code { get; } |
|||
|
|||
string Currency { get; } |
|||
|
|||
decimal? OriginalPrice { get; } |
|||
|
|||
decimal Price { get; } |
|||
|
|||
int Inventory { get; } |
|||
|
|||
int Sold { get; } |
|||
|
|||
int OrderMinQuantity { get; } |
|||
|
|||
int OrderMaxQuantity { get; } |
|||
|
|||
string MediaResources { get; } |
|||
|
|||
public Guid? ProductDetailId { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace EasyAbp.EShop.Products.Products |
|||
{ |
|||
public class ProductAttributeEto : IProductAttribute |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
public string DisplayName { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
|
|||
public int DisplayOrder { get; set; } |
|||
|
|||
public ICollection<ProductAttributeOptionEto> ProductAttributeOptions { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
|
|||
namespace EasyAbp.EShop.Products.Products |
|||
{ |
|||
public class ProductAttributeOptionEto : IProductAttributeOption |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
public string DisplayName { get; set; } |
|||
|
|||
public string Description { get; set; } |
|||
|
|||
public int DisplayOrder { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace EasyAbp.EShop.Products.Products |
|||
{ |
|||
public class ProductEto : IProduct |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
public Guid ProductTypeId { get; set; } |
|||
|
|||
public Guid ProductDetailId { get; set; } |
|||
|
|||
public string Code { get; set; } |
|||
|
|||
public string DisplayName { get; set; } |
|||
|
|||
public InventoryStrategy InventoryStrategy { get; set; } |
|||
|
|||
public string MediaResources { get; set; } |
|||
|
|||
public int DisplayOrder { get; set; } |
|||
|
|||
public bool IsPublished { get; set; } |
|||
|
|||
public bool IsStatic { get; set; } |
|||
|
|||
public bool IsHidden { get; set; } |
|||
|
|||
public Dictionary<string, object> ExtraProperties { get; set; } |
|||
|
|||
public ICollection<ProductAttributeEto> ProductAttributes { get; set; } |
|||
|
|||
public ICollection<ProductSkuEto> ProductSkus { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using System; |
|||
|
|||
namespace EasyAbp.EShop.Products.Products |
|||
{ |
|||
public class ProductSkuEto : IProductSku |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
public string SerializedAttributeOptionIds { get; set; } |
|||
|
|||
public string Code { get; set; } |
|||
|
|||
public string Currency { get; set; } |
|||
|
|||
public decimal? OriginalPrice { get; set; } |
|||
|
|||
public decimal Price { get; set; } |
|||
|
|||
public int Inventory { get; set; } |
|||
|
|||
public int Sold { get; set; } |
|||
|
|||
public int OrderMinQuantity { get; set; } |
|||
|
|||
public int OrderMaxQuantity { get; set; } |
|||
|
|||
public string MediaResources { get; set; } |
|||
|
|||
public Guid? ProductDetailId { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using AutoMapper; |
|||
using EasyAbp.EShop.Products.Products; |
|||
|
|||
namespace EasyAbp.EShop.Products |
|||
{ |
|||
public class ProductsDomainAutoMapperProfile : Profile |
|||
{ |
|||
public ProductsDomainAutoMapperProfile() |
|||
{ |
|||
/* You can configure your AutoMapper mapping configuration here. |
|||
* Alternatively, you can split your mapping configurations |
|||
* into multiple profile classes for a better organization. */ |
|||
CreateMap<Product, ProductEto>(); |
|||
CreateMap<ProductAttribute, ProductAttributeEto>(); |
|||
CreateMap<ProductAttributeOption, ProductAttributeOptionEto>(); |
|||
CreateMap<ProductSku, ProductSkuEto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos |
|||
{ |
|||
[Serializable] |
|||
public class BasketItemDto : AuditedEntityDto<Guid> |
|||
{ |
|||
public string BasketName { get; set; } |
|||
|
|||
public Guid UserId { get; set; } |
|||
|
|||
public Guid StoreId { get; set; } |
|||
|
|||
public Guid ProductId { get; set; } |
|||
|
|||
public Guid ProductSkuId { get; set; } |
|||
|
|||
public int Quantity { get; set; } |
|||
|
|||
public string MediaResources { get; set; } |
|||
|
|||
public string ProductName { get; set; } |
|||
|
|||
public string SkuDescription { get; set; } |
|||
|
|||
public string Currency { get; set; } |
|||
|
|||
public decimal UnitPrice { get; set; } |
|||
|
|||
public decimal TotalPrice { get; set; } |
|||
|
|||
public decimal TotalDiscount { get; set; } |
|||
|
|||
public int Inventory { get; set; } |
|||
|
|||
public bool IsInvalid { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel; |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos |
|||
{ |
|||
[Serializable] |
|||
public class CreateBasketItemDto : IValidatableObject |
|||
{ |
|||
public string BasketName { get; set; } = BasketsConsts.DefaultBasketName; |
|||
|
|||
/// <summary>
|
|||
/// Specify the basket item owner user ID. Use current user ID if this property is null.
|
|||
/// </summary>
|
|||
public Guid? UserId { get; set; } |
|||
|
|||
public Guid StoreId { get; set; } |
|||
|
|||
public Guid ProductId { get; set; } |
|||
|
|||
public Guid ProductSkuId { get; set; } |
|||
|
|||
public int Quantity { get; set; } |
|||
|
|||
public new IEnumerable<ValidationResult> Validate(ValidationContext validationContext) |
|||
{ |
|||
if (Quantity <= 0) |
|||
{ |
|||
yield return new ValidationResult( |
|||
"Quantity should be greater than 0.", |
|||
new[] { "Quantity" } |
|||
); |
|||
} |
|||
|
|||
if (BasketName.IsNullOrWhiteSpace()) |
|||
{ |
|||
yield return new ValidationResult( |
|||
"BasketName should not be empty.", |
|||
new[] { "BasketName" } |
|||
); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos |
|||
{ |
|||
public class GetBasketItemListDto : PagedAndSortedResultRequestDto |
|||
{ |
|||
[Required] |
|||
public string BasketName { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Specify the basket item owner user ID. Use current user ID if this property is null.
|
|||
/// </summary>
|
|||
public Guid? UserId { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos |
|||
{ |
|||
[Serializable] |
|||
public class UpdateBasketItemDto : IValidatableObject |
|||
{ |
|||
public int Quantity { get; set; } |
|||
|
|||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) |
|||
{ |
|||
if (Quantity <= 0) |
|||
{ |
|||
yield return new ValidationResult( |
|||
"Quantity should be greater than 0.", |
|||
new[] { "Quantity" } |
|||
); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems |
|||
{ |
|||
public interface IBasketItemAppService : |
|||
ICrudAppService< |
|||
BasketItemDto, |
|||
Guid, |
|||
GetBasketItemListDto, |
|||
CreateBasketItemDto, |
|||
UpdateBasketItemDto> |
|||
{ |
|||
Task DeleteInBulkAsync(IEnumerable<Guid> ids); |
|||
} |
|||
} |
|||
@ -0,0 +1,280 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Plugins.Baskets.Permissions; |
|||
using EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos; |
|||
using EasyAbp.EShop.Plugins.Baskets.ProductUpdates; |
|||
using EasyAbp.EShop.Products.ProductInventories; |
|||
using EasyAbp.EShop.Products.Products; |
|||
using EasyAbp.EShop.Products.Products.Dtos; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.Authorization; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems |
|||
{ |
|||
public class BasketItemAppService : CrudAppService<BasketItem, BasketItemDto, Guid, GetBasketItemListDto, CreateBasketItemDto, UpdateBasketItemDto>, |
|||
IBasketItemAppService |
|||
{ |
|||
protected override string GetPolicyName { get; set; } = BasketsPermissions.BasketItem.Default; |
|||
protected override string GetListPolicyName { get; set; } = BasketsPermissions.BasketItem.Default; |
|||
protected override string CreatePolicyName { get; set; } = BasketsPermissions.BasketItem.Create; |
|||
protected override string UpdatePolicyName { get; set; } = BasketsPermissions.BasketItem.Update; |
|||
protected override string DeletePolicyName { get; set; } = BasketsPermissions.BasketItem.Delete; |
|||
|
|||
private readonly IBasketItemRepository _repository; |
|||
private readonly IProductUpdateRepository _productUpdateRepository; |
|||
private readonly IProductAppService _productAppService; |
|||
private readonly IProductSkuDescriptionProvider _productSkuDescriptionProvider; |
|||
|
|||
public BasketItemAppService( |
|||
IBasketItemRepository repository, |
|||
IProductUpdateRepository productUpdateRepository, |
|||
IProductAppService productAppService, |
|||
IProductSkuDescriptionProvider productSkuDescriptionProvider) : base(repository) |
|||
{ |
|||
_repository = repository; |
|||
_productUpdateRepository = productUpdateRepository; |
|||
_productAppService = productAppService; |
|||
_productSkuDescriptionProvider = productSkuDescriptionProvider; |
|||
} |
|||
|
|||
public override async Task<BasketItemDto> GetAsync(Guid id) |
|||
{ |
|||
await CheckGetPolicyAsync(); |
|||
|
|||
var item = await GetEntityByIdAsync(id); |
|||
|
|||
if (item.UserId != CurrentUser.GetId() && !await IsCurrentUserManagerAsync()) |
|||
{ |
|||
throw new AbpAuthorizationException(); |
|||
} |
|||
|
|||
var productUpdate = await _productUpdateRepository.FindAsync(x => x.ProductSkuId == item.ProductSkuId); |
|||
|
|||
if (productUpdate != null) |
|||
{ |
|||
var itemUpdateTime = item.LastModificationTime ?? item.CreationTime; |
|||
var productUpdateTime = productUpdate.LastModificationTime ?? productUpdate.CreationTime; |
|||
|
|||
if (itemUpdateTime < productUpdateTime) |
|||
{ |
|||
var productDto = await _productAppService.GetAsync(item.ProductId, item.StoreId); |
|||
|
|||
await UpdateProductDataAsync(item.Quantity, item, productDto); |
|||
|
|||
await _repository.UpdateAsync(item, true); |
|||
} |
|||
} |
|||
|
|||
return MapToGetOutputDto(item); |
|||
} |
|||
|
|||
public override async Task<PagedResultDto<BasketItemDto>> GetListAsync(GetBasketItemListDto input) |
|||
{ |
|||
await CheckGetListPolicyAsync(); |
|||
|
|||
if (input.UserId != CurrentUser.GetId() && !await IsCurrentUserManagerAsync()) |
|||
{ |
|||
throw new AbpAuthorizationException(); |
|||
} |
|||
|
|||
var query = CreateFilteredQuery(input); |
|||
|
|||
var totalCount = await AsyncExecuter.CountAsync(query); |
|||
|
|||
query = ApplySorting(query, input); |
|||
query = ApplyPaging(query, input); |
|||
|
|||
var items = await AsyncExecuter.ToListAsync(query); |
|||
|
|||
var productSkuIds = items.Select(item => item.ProductSkuId).ToList(); |
|||
|
|||
var skuIdUpdateTimeDict = |
|||
(await _productUpdateRepository.GetListByProductSkuIdsAsync(productSkuIds)).ToDictionary( |
|||
x => x.ProductSkuId, x => x.LastModificationTime ?? x.CreationTime); |
|||
|
|||
var productDtoDict = new Dictionary<Guid, ProductDto>(); |
|||
|
|||
foreach (var item in items) |
|||
{ |
|||
if (!skuIdUpdateTimeDict.ContainsKey(item.ProductSkuId)) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
var itemUpdateTime = item.LastModificationTime ?? item.CreationTime; |
|||
var productUpdateTime = skuIdUpdateTimeDict[item.ProductSkuId]; |
|||
|
|||
if (itemUpdateTime >= productUpdateTime) |
|||
{ |
|||
continue; |
|||
} |
|||
|
|||
if (!productDtoDict.ContainsKey(item.ProductId)) |
|||
{ |
|||
// Todo: deleted product cause errors
|
|||
productDtoDict[item.ProductId] = |
|||
await _productAppService.GetAsync(item.ProductId, item.StoreId); |
|||
} |
|||
|
|||
await UpdateProductDataAsync(item.Quantity, item, productDtoDict[item.ProductId]); |
|||
|
|||
await _repository.UpdateAsync(item); |
|||
} |
|||
|
|||
return new PagedResultDto<BasketItemDto>( |
|||
totalCount, |
|||
items.Select(MapToGetListOutputDto).ToList() |
|||
); |
|||
} |
|||
|
|||
protected virtual async Task UpdateProductDataAsync(int quantity, BasketItem item, ProductDto productDto) |
|||
{ |
|||
item.SetIsInvalid(false); |
|||
|
|||
var productSkuDto = productDto.FindSkuById(item.ProductSkuId); |
|||
|
|||
if (productSkuDto == null) |
|||
{ |
|||
item.SetIsInvalid(true); |
|||
|
|||
return; |
|||
} |
|||
|
|||
if (productDto.InventoryStrategy != InventoryStrategy.NoNeed && quantity > productSkuDto.RealInventory) |
|||
{ |
|||
item.SetIsInvalid(true); |
|||
} |
|||
|
|||
item.UpdateProductData(quantity, new ProductDataModel |
|||
{ |
|||
MediaResources = productSkuDto.MediaResources ?? productDto.MediaResources, |
|||
ProductName = productDto.DisplayName, |
|||
SkuDescription = await _productSkuDescriptionProvider.GenerateAsync(productDto, productSkuDto), |
|||
Currency = productSkuDto.Currency, |
|||
UnitPrice = productSkuDto.DiscountedPrice, |
|||
TotalPrice = productSkuDto.DiscountedPrice * item.Quantity, |
|||
TotalDiscount = (productSkuDto.Price - productSkuDto.DiscountedPrice) * item.Quantity, |
|||
Inventory = productSkuDto.RealInventory |
|||
}); |
|||
|
|||
if (!productDto.IsPublished) |
|||
{ |
|||
item.SetIsInvalid(true); |
|||
} |
|||
} |
|||
|
|||
protected override IQueryable<BasketItem> CreateFilteredQuery(GetBasketItemListDto input) |
|||
{ |
|||
var userId = input.UserId ?? CurrentUser.GetId(); |
|||
|
|||
return ReadOnlyRepository.Where(item => item.UserId == userId && item.BasketName == input.BasketName); |
|||
} |
|||
|
|||
public override async Task<BasketItemDto> CreateAsync(CreateBasketItemDto input) |
|||
{ |
|||
await CheckCreatePolicyAsync(); |
|||
|
|||
var userId = input.UserId ?? CurrentUser.GetId(); |
|||
|
|||
if (userId != CurrentUser.GetId() && !await IsCurrentUserManagerAsync()) |
|||
{ |
|||
throw new AbpAuthorizationException(); |
|||
} |
|||
|
|||
var productDto = await _productAppService.GetAsync(input.ProductId, input.StoreId); |
|||
|
|||
var item = await _repository.FindAsync(x => |
|||
x.UserId == userId && x.BasketName == input.BasketName && x.StoreId == input.StoreId && |
|||
x.ProductSkuId == input.ProductSkuId); |
|||
|
|||
if (item != null) |
|||
{ |
|||
await UpdateProductDataAsync(input.Quantity + item.Quantity, item, productDto); |
|||
|
|||
await Repository.UpdateAsync(item, autoSave: true); |
|||
|
|||
return MapToGetOutputDto(item); |
|||
} |
|||
|
|||
var productSkuDto = productDto.FindSkuById(input.ProductSkuId); |
|||
|
|||
if (productSkuDto == null) |
|||
{ |
|||
throw new ProductSkuNotFoundException(input.ProductId, input.ProductSkuId); |
|||
} |
|||
|
|||
item = new BasketItem(GuidGenerator.Create(), CurrentTenant.Id, input.BasketName, CurrentUser.GetId(), |
|||
input.StoreId, input.ProductId, input.ProductSkuId); |
|||
|
|||
await UpdateProductDataAsync(input.Quantity, item, productDto); |
|||
|
|||
await Repository.InsertAsync(item, autoSave: true); |
|||
|
|||
return MapToGetOutputDto(item); |
|||
} |
|||
|
|||
public override async Task<BasketItemDto> UpdateAsync(Guid id, UpdateBasketItemDto input) |
|||
{ |
|||
await CheckUpdatePolicyAsync(); |
|||
|
|||
var item = await GetEntityByIdAsync(id); |
|||
|
|||
if (item.UserId != CurrentUser.GetId() && !await IsCurrentUserManagerAsync()) |
|||
{ |
|||
throw new AbpAuthorizationException(); |
|||
} |
|||
|
|||
var productDto = await _productAppService.GetAsync(item.ProductId, item.StoreId); |
|||
|
|||
await UpdateProductDataAsync(input.Quantity, item, productDto); |
|||
|
|||
await Repository.UpdateAsync(item, autoSave: true); |
|||
|
|||
return MapToGetOutputDto(item); |
|||
} |
|||
|
|||
public override async Task DeleteAsync(Guid id) |
|||
{ |
|||
await CheckDeletePolicyAsync(); |
|||
|
|||
var item = await _repository.GetAsync(id); |
|||
|
|||
if (item.UserId != CurrentUser.GetId() && !await IsCurrentUserManagerAsync()) |
|||
{ |
|||
throw new AbpAuthorizationException(); |
|||
} |
|||
|
|||
await _repository.DeleteAsync(item, true); |
|||
} |
|||
|
|||
public virtual async Task DeleteInBulkAsync(IEnumerable<Guid> ids) |
|||
{ |
|||
await CheckDeletePolicyAsync(); |
|||
|
|||
var isCurrentUserManager = await IsCurrentUserManagerAsync(); |
|||
|
|||
foreach (var id in ids) |
|||
{ |
|||
var item = await GetEntityByIdAsync(id); |
|||
|
|||
if (item.UserId != CurrentUser.GetId() && !isCurrentUserManager) |
|||
{ |
|||
throw new AbpAuthorizationException(); |
|||
} |
|||
|
|||
await _repository.DeleteAsync(item); |
|||
} |
|||
} |
|||
|
|||
protected virtual async Task<bool> IsCurrentUserManagerAsync() |
|||
{ |
|||
return await AuthorizationService.IsGrantedAsync(BasketsPermissions.BasketItem.Manage); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System; |
|||
using Volo.Abp; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems |
|||
{ |
|||
public class ProductSkuNotFoundException : BusinessException |
|||
{ |
|||
public ProductSkuNotFoundException(Guid productId, Guid productSkuId) : base( |
|||
message: $"Product {productId} (SKU: {productSkuId}) not found.") |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
namespace EasyAbp.EShop.Plugins.Baskets |
|||
{ |
|||
public static class BasketsConsts |
|||
{ |
|||
public const string DefaultBasketName = "Default"; |
|||
} |
|||
} |
|||
@ -1,6 +1,31 @@ |
|||
{ |
|||
"culture": "cs", |
|||
"texts": { |
|||
"ManageYourProfile": "Spravovat profil" |
|||
"ManageYourProfile": "Spravovat profil", |
|||
"Permission:BasketItem": "BasketItem", |
|||
"Permission:Create": "Create", |
|||
"Permission:Update": "Update", |
|||
"Permission:Delete": "Delete", |
|||
"Menu:BasketItem": "MenuBasketItem", |
|||
"BasketItem": "BasketItem", |
|||
"BasketItemBasketName": "BasketItemBasketName", |
|||
"BasketItemUserId": "BasketItemUserId", |
|||
"BasketItemStoreId": "BasketItemStoreId", |
|||
"BasketItemProductId": "BasketItemProductId", |
|||
"BasketItemProductSkuId": "BasketItemProductSkuId", |
|||
"BasketItemQuantity": "BasketItemQuantity", |
|||
"BasketItemMediaResources": "BasketItemMediaResources", |
|||
"BasketItemProductName": "BasketItemProductName", |
|||
"BasketItemSkuDescription": "BasketItemSkuDescription", |
|||
"BasketItemCurrency": "BasketItemCurrency", |
|||
"BasketItemUnitPrice": "BasketItemUnitPrice", |
|||
"BasketItemTotalPrice": "BasketItemTotalPrice", |
|||
"BasketItemTotalDiscount": "BasketItemTotalDiscount", |
|||
"BasketItemInventory": "BasketItemInventory", |
|||
"BasketItemIsInvalid": "BasketItemIsInvalid", |
|||
"CreateBasketItem": "CreateBasketItem", |
|||
"EditBasketItem": "EditBasketItem", |
|||
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
} |
|||
@ -1,7 +1,32 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"ManageYourProfile": "Manage your profile", |
|||
"SamplePageMessage": "A sample page for the Baskets module" |
|||
"ManageYourProfile": "Manage your profile", |
|||
"SamplePageMessage": "A sample page for the Baskets module", |
|||
"Permission:BasketItem": "BasketItem", |
|||
"Permission:Create": "Create", |
|||
"Permission:Update": "Update", |
|||
"Permission:Delete": "Delete", |
|||
"Menu:BasketItem": "MenuBasketItem", |
|||
"BasketItem": "BasketItem", |
|||
"BasketItemBasketName": "BasketItemBasketName", |
|||
"BasketItemUserId": "BasketItemUserId", |
|||
"BasketItemStoreId": "BasketItemStoreId", |
|||
"BasketItemProductId": "BasketItemProductId", |
|||
"BasketItemProductSkuId": "BasketItemProductSkuId", |
|||
"BasketItemQuantity": "BasketItemQuantity", |
|||
"BasketItemMediaResources": "BasketItemMediaResources", |
|||
"BasketItemProductName": "BasketItemProductName", |
|||
"BasketItemSkuDescription": "BasketItemSkuDescription", |
|||
"BasketItemCurrency": "BasketItemCurrency", |
|||
"BasketItemUnitPrice": "BasketItemUnitPrice", |
|||
"BasketItemTotalPrice": "BasketItemTotalPrice", |
|||
"BasketItemTotalDiscount": "BasketItemTotalDiscount", |
|||
"BasketItemInventory": "BasketItemInventory", |
|||
"BasketItemIsInvalid": "BasketItemIsInvalid", |
|||
"CreateBasketItem": "CreateBasketItem", |
|||
"EditBasketItem": "EditBasketItem", |
|||
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -1,6 +1,30 @@ |
|||
{ |
|||
"culture": "pl-PL", |
|||
"texts": { |
|||
|
|||
"Permission:BasketItem": "BasketItem", |
|||
"Permission:Create": "Create", |
|||
"Permission:Update": "Update", |
|||
"Permission:Delete": "Delete", |
|||
"Menu:BasketItem": "MenuBasketItem", |
|||
"BasketItem": "BasketItem", |
|||
"BasketItemBasketName": "BasketItemBasketName", |
|||
"BasketItemUserId": "BasketItemUserId", |
|||
"BasketItemStoreId": "BasketItemStoreId", |
|||
"BasketItemProductId": "BasketItemProductId", |
|||
"BasketItemProductSkuId": "BasketItemProductSkuId", |
|||
"BasketItemQuantity": "BasketItemQuantity", |
|||
"BasketItemMediaResources": "BasketItemMediaResources", |
|||
"BasketItemProductName": "BasketItemProductName", |
|||
"BasketItemSkuDescription": "BasketItemSkuDescription", |
|||
"BasketItemCurrency": "BasketItemCurrency", |
|||
"BasketItemUnitPrice": "BasketItemUnitPrice", |
|||
"BasketItemTotalPrice": "BasketItemTotalPrice", |
|||
"BasketItemTotalDiscount": "BasketItemTotalDiscount", |
|||
"BasketItemInventory": "BasketItemInventory", |
|||
"BasketItemIsInvalid": "BasketItemIsInvalid", |
|||
"CreateBasketItem": "CreateBasketItem", |
|||
"EditBasketItem": "EditBasketItem", |
|||
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -1,6 +1,30 @@ |
|||
{ |
|||
"culture": "pt-BR", |
|||
"texts": { |
|||
|
|||
"Permission:BasketItem": "BasketItem", |
|||
"Permission:Create": "Create", |
|||
"Permission:Update": "Update", |
|||
"Permission:Delete": "Delete", |
|||
"Menu:BasketItem": "MenuBasketItem", |
|||
"BasketItem": "BasketItem", |
|||
"BasketItemBasketName": "BasketItemBasketName", |
|||
"BasketItemUserId": "BasketItemUserId", |
|||
"BasketItemStoreId": "BasketItemStoreId", |
|||
"BasketItemProductId": "BasketItemProductId", |
|||
"BasketItemProductSkuId": "BasketItemProductSkuId", |
|||
"BasketItemQuantity": "BasketItemQuantity", |
|||
"BasketItemMediaResources": "BasketItemMediaResources", |
|||
"BasketItemProductName": "BasketItemProductName", |
|||
"BasketItemSkuDescription": "BasketItemSkuDescription", |
|||
"BasketItemCurrency": "BasketItemCurrency", |
|||
"BasketItemUnitPrice": "BasketItemUnitPrice", |
|||
"BasketItemTotalPrice": "BasketItemTotalPrice", |
|||
"BasketItemTotalDiscount": "BasketItemTotalDiscount", |
|||
"BasketItemInventory": "BasketItemInventory", |
|||
"BasketItemIsInvalid": "BasketItemIsInvalid", |
|||
"CreateBasketItem": "CreateBasketItem", |
|||
"EditBasketItem": "EditBasketItem", |
|||
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -1,6 +1,31 @@ |
|||
{ |
|||
"culture": "sl", |
|||
"texts": { |
|||
"ManageYourProfile": "Upravljajte svojim profilom" |
|||
"ManageYourProfile": "Upravljajte svojim profilom", |
|||
"Permission:BasketItem": "BasketItem", |
|||
"Permission:Create": "Create", |
|||
"Permission:Update": "Update", |
|||
"Permission:Delete": "Delete", |
|||
"Menu:BasketItem": "MenuBasketItem", |
|||
"BasketItem": "BasketItem", |
|||
"BasketItemBasketName": "BasketItemBasketName", |
|||
"BasketItemUserId": "BasketItemUserId", |
|||
"BasketItemStoreId": "BasketItemStoreId", |
|||
"BasketItemProductId": "BasketItemProductId", |
|||
"BasketItemProductSkuId": "BasketItemProductSkuId", |
|||
"BasketItemQuantity": "BasketItemQuantity", |
|||
"BasketItemMediaResources": "BasketItemMediaResources", |
|||
"BasketItemProductName": "BasketItemProductName", |
|||
"BasketItemSkuDescription": "BasketItemSkuDescription", |
|||
"BasketItemCurrency": "BasketItemCurrency", |
|||
"BasketItemUnitPrice": "BasketItemUnitPrice", |
|||
"BasketItemTotalPrice": "BasketItemTotalPrice", |
|||
"BasketItemTotalDiscount": "BasketItemTotalDiscount", |
|||
"BasketItemInventory": "BasketItemInventory", |
|||
"BasketItemIsInvalid": "BasketItemIsInvalid", |
|||
"CreateBasketItem": "CreateBasketItem", |
|||
"EditBasketItem": "EditBasketItem", |
|||
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -1,7 +1,32 @@ |
|||
{ |
|||
"culture": "tr", |
|||
"texts": { |
|||
"ManageYourProfile": "Profil yönetimi", |
|||
"SamplePageMessage": "Baskets modulünden örnek bir sayfa" |
|||
"ManageYourProfile": "Profil yönetimi", |
|||
"SamplePageMessage": "Baskets modulünden örnek bir sayfa", |
|||
"Permission:BasketItem": "BasketItem", |
|||
"Permission:Create": "Create", |
|||
"Permission:Update": "Update", |
|||
"Permission:Delete": "Delete", |
|||
"Menu:BasketItem": "MenuBasketItem", |
|||
"BasketItem": "BasketItem", |
|||
"BasketItemBasketName": "BasketItemBasketName", |
|||
"BasketItemUserId": "BasketItemUserId", |
|||
"BasketItemStoreId": "BasketItemStoreId", |
|||
"BasketItemProductId": "BasketItemProductId", |
|||
"BasketItemProductSkuId": "BasketItemProductSkuId", |
|||
"BasketItemQuantity": "BasketItemQuantity", |
|||
"BasketItemMediaResources": "BasketItemMediaResources", |
|||
"BasketItemProductName": "BasketItemProductName", |
|||
"BasketItemSkuDescription": "BasketItemSkuDescription", |
|||
"BasketItemCurrency": "BasketItemCurrency", |
|||
"BasketItemUnitPrice": "BasketItemUnitPrice", |
|||
"BasketItemTotalPrice": "BasketItemTotalPrice", |
|||
"BasketItemTotalDiscount": "BasketItemTotalDiscount", |
|||
"BasketItemInventory": "BasketItemInventory", |
|||
"BasketItemIsInvalid": "BasketItemIsInvalid", |
|||
"CreateBasketItem": "CreateBasketItem", |
|||
"EditBasketItem": "EditBasketItem", |
|||
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -1,6 +1,30 @@ |
|||
{ |
|||
"culture": "vi", |
|||
"texts": { |
|||
|
|||
"Permission:BasketItem": "BasketItem", |
|||
"Permission:Create": "Create", |
|||
"Permission:Update": "Update", |
|||
"Permission:Delete": "Delete", |
|||
"Menu:BasketItem": "MenuBasketItem", |
|||
"BasketItem": "BasketItem", |
|||
"BasketItemBasketName": "BasketItemBasketName", |
|||
"BasketItemUserId": "BasketItemUserId", |
|||
"BasketItemStoreId": "BasketItemStoreId", |
|||
"BasketItemProductId": "BasketItemProductId", |
|||
"BasketItemProductSkuId": "BasketItemProductSkuId", |
|||
"BasketItemQuantity": "BasketItemQuantity", |
|||
"BasketItemMediaResources": "BasketItemMediaResources", |
|||
"BasketItemProductName": "BasketItemProductName", |
|||
"BasketItemSkuDescription": "BasketItemSkuDescription", |
|||
"BasketItemCurrency": "BasketItemCurrency", |
|||
"BasketItemUnitPrice": "BasketItemUnitPrice", |
|||
"BasketItemTotalPrice": "BasketItemTotalPrice", |
|||
"BasketItemTotalDiscount": "BasketItemTotalDiscount", |
|||
"BasketItemInventory": "BasketItemInventory", |
|||
"BasketItemIsInvalid": "BasketItemIsInvalid", |
|||
"CreateBasketItem": "CreateBasketItem", |
|||
"EditBasketItem": "EditBasketItem", |
|||
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
} |
|||
@ -1,6 +1,31 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"ManageYourProfile": "管理个人资料" |
|||
"ManageYourProfile": "管理个人资料", |
|||
"Permission:BasketItem": "BasketItem", |
|||
"Permission:Create": "Create", |
|||
"Permission:Update": "Update", |
|||
"Permission:Delete": "Delete", |
|||
"Menu:BasketItem": "MenuBasketItem", |
|||
"BasketItem": "BasketItem", |
|||
"BasketItemBasketName": "BasketItemBasketName", |
|||
"BasketItemUserId": "BasketItemUserId", |
|||
"BasketItemStoreId": "BasketItemStoreId", |
|||
"BasketItemProductId": "BasketItemProductId", |
|||
"BasketItemProductSkuId": "BasketItemProductSkuId", |
|||
"BasketItemQuantity": "BasketItemQuantity", |
|||
"BasketItemMediaResources": "BasketItemMediaResources", |
|||
"BasketItemProductName": "BasketItemProductName", |
|||
"BasketItemSkuDescription": "BasketItemSkuDescription", |
|||
"BasketItemCurrency": "BasketItemCurrency", |
|||
"BasketItemUnitPrice": "BasketItemUnitPrice", |
|||
"BasketItemTotalPrice": "BasketItemTotalPrice", |
|||
"BasketItemTotalDiscount": "BasketItemTotalDiscount", |
|||
"BasketItemInventory": "BasketItemInventory", |
|||
"BasketItemIsInvalid": "BasketItemIsInvalid", |
|||
"CreateBasketItem": "CreateBasketItem", |
|||
"EditBasketItem": "EditBasketItem", |
|||
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -1,6 +1,31 @@ |
|||
{ |
|||
"culture": "zh-Hant", |
|||
"texts": { |
|||
"ManageYourProfile": "管理個人資料" |
|||
"ManageYourProfile": "管理個人資料", |
|||
"Permission:BasketItem": "BasketItem", |
|||
"Permission:Create": "Create", |
|||
"Permission:Update": "Update", |
|||
"Permission:Delete": "Delete", |
|||
"Menu:BasketItem": "MenuBasketItem", |
|||
"BasketItem": "BasketItem", |
|||
"BasketItemBasketName": "BasketItemBasketName", |
|||
"BasketItemUserId": "BasketItemUserId", |
|||
"BasketItemStoreId": "BasketItemStoreId", |
|||
"BasketItemProductId": "BasketItemProductId", |
|||
"BasketItemProductSkuId": "BasketItemProductSkuId", |
|||
"BasketItemQuantity": "BasketItemQuantity", |
|||
"BasketItemMediaResources": "BasketItemMediaResources", |
|||
"BasketItemProductName": "BasketItemProductName", |
|||
"BasketItemSkuDescription": "BasketItemSkuDescription", |
|||
"BasketItemCurrency": "BasketItemCurrency", |
|||
"BasketItemUnitPrice": "BasketItemUnitPrice", |
|||
"BasketItemTotalPrice": "BasketItemTotalPrice", |
|||
"BasketItemTotalDiscount": "BasketItemTotalDiscount", |
|||
"BasketItemInventory": "BasketItemInventory", |
|||
"BasketItemIsInvalid": "BasketItemIsInvalid", |
|||
"CreateBasketItem": "CreateBasketItem", |
|||
"EditBasketItem": "EditBasketItem", |
|||
"BasketItemDeletionConfirmationMessage": "Are you sure to delete the basketItem {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems |
|||
{ |
|||
public interface IBasketItemRepository : IRepository<BasketItem, Guid> |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems |
|||
{ |
|||
public interface IProductData |
|||
{ |
|||
string MediaResources { get; } |
|||
|
|||
string ProductName { get; } |
|||
|
|||
string SkuDescription { get; } |
|||
|
|||
string Currency { get; } |
|||
|
|||
decimal UnitPrice { get; } |
|||
|
|||
decimal TotalPrice { get; } |
|||
|
|||
decimal TotalDiscount { get; } |
|||
|
|||
int Inventory { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using EasyAbp.EShop.Products.ProductInventories; |
|||
using EasyAbp.EShop.Products.Products; |
|||
using Volo.Abp.Domain.Entities.Events.Distributed; |
|||
using Volo.Abp.EventBus.Distributed; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems |
|||
{ |
|||
public interface IProductUpdateRecorder : |
|||
IDistributedEventHandler<EntityUpdatedEto<ProductEto>>, |
|||
IDistributedEventHandler<ProductInventoryChangedEto> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems |
|||
{ |
|||
public class ProductDataModel : IProductData |
|||
{ |
|||
public string MediaResources { get; set; } |
|||
|
|||
public string ProductName { get; set; } |
|||
|
|||
public string SkuDescription { get; set; } |
|||
|
|||
public string Currency { get; set; } |
|||
|
|||
public decimal UnitPrice { get; set; } |
|||
|
|||
public decimal TotalPrice { get; set; } |
|||
|
|||
public decimal TotalDiscount { get; set; } |
|||
|
|||
public int Inventory { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,59 @@ |
|||
using System; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Plugins.Baskets.ProductUpdates; |
|||
using EasyAbp.EShop.Products.ProductInventories; |
|||
using EasyAbp.EShop.Products.Products; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Domain.Entities.Events.Distributed; |
|||
using Volo.Abp.Guids; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems |
|||
{ |
|||
public class ProductUpdateRecorder : IProductUpdateRecorder, ITransientDependency |
|||
{ |
|||
private readonly IGuidGenerator _guidGenerator; |
|||
private readonly IProductUpdateRepository _productUpdateRepository; |
|||
|
|||
public ProductUpdateRecorder( |
|||
IGuidGenerator guidGenerator, |
|||
IProductUpdateRepository productUpdateRepository) |
|||
{ |
|||
_guidGenerator = guidGenerator; |
|||
_productUpdateRepository = productUpdateRepository; |
|||
} |
|||
|
|||
[UnitOfWork(true)] |
|||
public virtual async Task HandleEventAsync(EntityUpdatedEto<ProductEto> eventData) |
|||
{ |
|||
foreach (var skuId in eventData.Entity.ProductSkus.Select(sku => sku.Id)) |
|||
{ |
|||
await UpdateAsync(skuId); |
|||
} |
|||
} |
|||
|
|||
[UnitOfWork(true)] |
|||
public virtual async Task HandleEventAsync(ProductInventoryChangedEto eventData) |
|||
{ |
|||
await UpdateAsync(eventData.ProductSkuId); |
|||
} |
|||
|
|||
protected virtual async Task UpdateAsync(Guid skuId) |
|||
{ |
|||
var entity = await _productUpdateRepository.FindAsync(x => x.ProductSkuId == skuId); |
|||
|
|||
if (entity == null) |
|||
{ |
|||
entity = new ProductUpdate(_guidGenerator.Create(), skuId); |
|||
|
|||
await _productUpdateRepository.InsertAsync(entity); |
|||
} |
|||
else |
|||
{ |
|||
await _productUpdateRepository.UpdateAsync(entity); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.ProductUpdates |
|||
{ |
|||
public interface IProductUpdateRepository : IRepository<ProductUpdate, Guid> |
|||
{ |
|||
Task<List<ProductUpdate>> GetListByProductSkuIdsAsync(IEnumerable<Guid> productSkuIds, CancellationToken cancellationToken = default); |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.ProductUpdates |
|||
{ |
|||
public class ProductUpdate : FullAuditedAggregateRoot<Guid> |
|||
{ |
|||
public virtual Guid ProductSkuId { get; protected set; } |
|||
|
|||
protected ProductUpdate() |
|||
{ |
|||
} |
|||
|
|||
public ProductUpdate( |
|||
Guid id, |
|||
Guid productSkuId) : base(id) |
|||
{ |
|||
ProductSkuId = productSkuId; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore; |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems |
|||
{ |
|||
public class BasketItemRepository : EfCoreRepository<BasketsDbContext, BasketItem, Guid>, IBasketItemRepository |
|||
{ |
|||
public BasketItemRepository(IDbContextProvider<BasketsDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.ProductUpdates |
|||
{ |
|||
public class ProductUpdateRepository : EfCoreRepository<BasketsDbContext, ProductUpdate, Guid>, IProductUpdateRepository |
|||
{ |
|||
public ProductUpdateRepository(IDbContextProvider<BasketsDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public async Task<List<ProductUpdate>> GetListByProductSkuIdsAsync(IEnumerable<Guid> productSkuIds, CancellationToken cancellationToken = default) |
|||
{ |
|||
return await GetQueryable().Where(x => productSkuIds.Contains(x.ProductSkuId)) |
|||
.ToListAsync(cancellationToken: cancellationToken); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
@page |
|||
@using EasyAbp.EShop.Plugins.Baskets.Localization |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal |
|||
@inject IHtmlLocalizer<BasketsResource> L |
|||
@model EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem.CreateModalModel |
|||
@{ |
|||
Layout = null; |
|||
} |
|||
<abp-dynamic-form abp-model="ViewModel" data-ajaxForm="true" asp-page="CreateModal"> |
|||
<abp-modal> |
|||
<abp-modal-header title="@L["CreateBasketItem"].Value"></abp-modal-header> |
|||
<abp-modal-body> |
|||
<abp-form-content /> |
|||
</abp-modal-body> |
|||
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer> |
|||
</abp-modal> |
|||
</abp-dynamic-form> |
|||
@ -0,0 +1,28 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using EasyAbp.EShop.Plugins.Baskets.BasketItems; |
|||
using EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos; |
|||
using EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem.ViewModels; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem |
|||
{ |
|||
public class CreateModalModel : BasketsPageModel |
|||
{ |
|||
[BindProperty] |
|||
public CreateBasketItemViewModel ViewModel { get; set; } = new CreateBasketItemViewModel(); |
|||
|
|||
private readonly IBasketItemAppService _service; |
|||
|
|||
public CreateModalModel(IBasketItemAppService service) |
|||
{ |
|||
_service = service; |
|||
} |
|||
|
|||
public virtual async Task<IActionResult> OnPostAsync() |
|||
{ |
|||
var dto = ObjectMapper.Map<CreateBasketItemViewModel, CreateBasketItemDto>(ViewModel); |
|||
await _service.CreateAsync(dto); |
|||
return NoContent(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
@page |
|||
@using EasyAbp.EShop.Plugins.Baskets.Localization |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal |
|||
@inject IHtmlLocalizer<BasketsResource> L |
|||
@model EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem.EditModalModel |
|||
@{ |
|||
Layout = null; |
|||
} |
|||
<abp-dynamic-form abp-model="ViewModel" data-ajaxForm="true" asp-page="EditModal"> |
|||
<abp-modal> |
|||
<abp-modal-header title="@L["EditBasketItem"].Value"></abp-modal-header> |
|||
<abp-modal-body> |
|||
<abp-input asp-for="Id" /> |
|||
<abp-form-content /> |
|||
</abp-modal-body> |
|||
<abp-modal-footer buttons="@(AbpModalButtons.Cancel|AbpModalButtons.Save)"></abp-modal-footer> |
|||
</abp-modal> |
|||
</abp-dynamic-form> |
|||
@ -0,0 +1,39 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using EasyAbp.EShop.Plugins.Baskets.BasketItems; |
|||
using EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos; |
|||
using EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem.ViewModels; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem |
|||
{ |
|||
public class EditModalModel : BasketsPageModel |
|||
{ |
|||
[HiddenInput] |
|||
[BindProperty(SupportsGet = true)] |
|||
public Guid Id { get; set; } |
|||
|
|||
[BindProperty] |
|||
public EditBasketItemViewModel ViewModel { get; set; } |
|||
|
|||
private readonly IBasketItemAppService _service; |
|||
|
|||
public EditModalModel(IBasketItemAppService service) |
|||
{ |
|||
_service = service; |
|||
} |
|||
|
|||
public virtual async Task OnGetAsync() |
|||
{ |
|||
var dto = await _service.GetAsync(Id); |
|||
ViewModel = ObjectMapper.Map<BasketItemDto, EditBasketItemViewModel>(dto); |
|||
} |
|||
|
|||
public virtual async Task<IActionResult> OnPostAsync() |
|||
{ |
|||
var dto = ObjectMapper.Map<EditBasketItemViewModel, UpdateBasketItemDto>(ViewModel); |
|||
await _service.UpdateAsync(Id, dto); |
|||
return NoContent(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,72 @@ |
|||
@page |
|||
@using EasyAbp.EShop.Plugins.Baskets.Permissions |
|||
@using EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem |
|||
@using EasyAbp.EShop.Plugins.Baskets.Localization |
|||
@using Microsoft.AspNetCore.Authorization |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Layout |
|||
@model IndexModel |
|||
@inject IPageLayout PageLayout |
|||
@inject IHtmlLocalizer<BasketsResource> L |
|||
@inject IAuthorizationService Authorization |
|||
@{ |
|||
PageLayout.Content.Title = L["BasketItem"].Value; |
|||
PageLayout.Content.BreadCrumb.Add(L["Menu:BasketItem"].Value); |
|||
PageLayout.Content.MenuItemName = "EasyAbpEShopBasketsBasketItem"; |
|||
} |
|||
|
|||
@section scripts |
|||
{ |
|||
<abp-script src="/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/index.js" /> |
|||
} |
|||
@section styles |
|||
{ |
|||
<abp-style src="/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/index.css"/> |
|||
} |
|||
<script> |
|||
let basketName = '@Model.BasketName'; |
|||
let userId = '@Model.UserId'; |
|||
</script> |
|||
|
|||
<abp-card> |
|||
<abp-card-header> |
|||
<abp-row> |
|||
<abp-column size-md="_6"> |
|||
<abp-card-title>@L["BasketItem"]</abp-card-title> |
|||
</abp-column> |
|||
<abp-column size-md="_6" class="text-right"> |
|||
@if (await Authorization.IsGrantedAsync(BasketsPermissions.BasketItem.Create)) |
|||
{ |
|||
<abp-button id="NewBasketItemButton" |
|||
text="@L["CreateBasketItem"].Value" |
|||
icon="plus" |
|||
button-type="Primary" /> |
|||
} |
|||
</abp-column> |
|||
</abp-row> |
|||
</abp-card-header> |
|||
<abp-card-body> |
|||
<abp-table striped-rows="true" id="BasketItemTable" class="nowrap"> |
|||
<thead> |
|||
<tr> |
|||
<th>@L["Actions"]</th> |
|||
<th>@L["BasketItemBasketName"]</th> |
|||
<th>@L["BasketItemUserId"]</th> |
|||
<th>@L["BasketItemStoreId"]</th> |
|||
<th>@L["BasketItemProductId"]</th> |
|||
<th>@L["BasketItemProductSkuId"]</th> |
|||
<th>@L["BasketItemQuantity"]</th> |
|||
<th>@L["BasketItemMediaResources"]</th> |
|||
<th>@L["BasketItemProductName"]</th> |
|||
<th>@L["BasketItemSkuDescription"]</th> |
|||
<th>@L["BasketItemCurrency"]</th> |
|||
<th>@L["BasketItemUnitPrice"]</th> |
|||
<th>@L["BasketItemTotalPrice"]</th> |
|||
<th>@L["BasketItemTotalDiscount"]</th> |
|||
<th>@L["BasketItemInventory"]</th> |
|||
<th>@L["BasketItemIsInvalid"]</th> |
|||
</tr> |
|||
</thead> |
|||
</abp-table> |
|||
</abp-card-body> |
|||
</abp-card> |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem |
|||
{ |
|||
public class IndexModel : BasketsPageModel |
|||
{ |
|||
[BindProperty(SupportsGet = true)] |
|||
public string BasketName { get; set; } |
|||
|
|||
[BindProperty(SupportsGet = true)] |
|||
public Guid? UserId { get; set; } |
|||
|
|||
public virtual async Task OnGetAsync() |
|||
{ |
|||
await Task.CompletedTask; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
using System; |
|||
|
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem.ViewModels |
|||
{ |
|||
public class CreateBasketItemViewModel |
|||
{ |
|||
[Display(Name = "BasketItemBasketName")] |
|||
public string BasketName { get; set; } = BasketsConsts.DefaultBasketName; |
|||
|
|||
/// <summary>
|
|||
/// Specify the basket item owner user ID. Use current user ID if this property is null.
|
|||
/// </summary>
|
|||
[Display(Name = "BasketItemUserId")] |
|||
public Guid? UserId { get; set; } |
|||
|
|||
[Display(Name = "BasketItemStoreId")] |
|||
public Guid StoreId { get; set; } |
|||
|
|||
[Display(Name = "BasketItemProductId")] |
|||
public Guid ProductId { get; set; } |
|||
|
|||
[Display(Name = "BasketItemProductSkuId")] |
|||
public Guid ProductSkuId { get; set; } |
|||
|
|||
[Display(Name = "BasketItemQuantity")] |
|||
public int Quantity { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System; |
|||
|
|||
using System.ComponentModel.DataAnnotations; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.Web.Pages.EShop.Plugins.Baskets.BasketItems.BasketItem.ViewModels |
|||
{ |
|||
public class EditBasketItemViewModel |
|||
{ |
|||
[Display(Name = "BasketItemQuantity")] |
|||
public int Quantity { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
$(function () { |
|||
|
|||
var l = abp.localization.getResource('EShopPluginsBaskets'); |
|||
|
|||
var service = easyAbp.eShop.plugins.baskets.basketItems.basketItem; |
|||
var createModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/Baskets/BasketItems/BasketItem/CreateModal'); |
|||
var editModal = new abp.ModalManager(abp.appPath + 'EShop/Plugins/Baskets/BasketItems/BasketItem/EditModal'); |
|||
|
|||
var dataTable = $('#BasketItemTable').DataTable(abp.libs.datatables.normalizeConfiguration({ |
|||
processing: true, |
|||
serverSide: true, |
|||
paging: true, |
|||
searching: false, |
|||
autoWidth: false, |
|||
scrollCollapse: true, |
|||
order: [[1, "asc"]], |
|||
ajax: abp.libs.datatables.createAjax(service.getList, function () { |
|||
return { basketName: basketName, userId: userId } |
|||
}), |
|||
columnDefs: [ |
|||
{ |
|||
rowAction: { |
|||
items: |
|||
[ |
|||
{ |
|||
text: l('Edit'), |
|||
visible: abp.auth.isGranted('EasyAbp.EShop.Plugins.Baskets.BasketItem.Update'), |
|||
action: function (data) { |
|||
editModal.open({ id: data.record.id }); |
|||
} |
|||
}, |
|||
{ |
|||
text: l('Delete'), |
|||
visible: abp.auth.isGranted('EasyAbp.EShop.Plugins.Baskets.BasketItem.Delete'), |
|||
confirmMessage: function (data) { |
|||
return l('BasketItemDeletionConfirmationMessage', data.record.id); |
|||
}, |
|||
action: function (data) { |
|||
service.delete(data.record.id) |
|||
.then(function () { |
|||
abp.notify.info(l('SuccessfullyDeleted')); |
|||
dataTable.ajax.reload(); |
|||
}); |
|||
} |
|||
} |
|||
] |
|||
} |
|||
}, |
|||
{ data: "basketName" }, |
|||
{ data: "userId" }, |
|||
{ data: "storeId" }, |
|||
{ data: "productId" }, |
|||
{ data: "productSkuId" }, |
|||
{ data: "quantity" }, |
|||
{ data: "mediaResources" }, |
|||
{ data: "productName" }, |
|||
{ data: "skuDescription" }, |
|||
{ data: "currency" }, |
|||
{ data: "unitPrice" }, |
|||
{ data: "totalPrice" }, |
|||
{ data: "totalDiscount" }, |
|||
{ data: "inventory" }, |
|||
{ data: "isInvalid" }, |
|||
] |
|||
})); |
|||
|
|||
createModal.onResult(function () { |
|||
dataTable.ajax.reload(); |
|||
}); |
|||
|
|||
editModal.onResult(function () { |
|||
dataTable.ajax.reload(); |
|||
}); |
|||
|
|||
$('#NewBasketItemButton').click(function (e) { |
|||
e.preventDefault(); |
|||
createModal.open(); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,26 @@ |
|||
using Shouldly; |
|||
using System.Threading.Tasks; |
|||
using Xunit; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems |
|||
{ |
|||
public class BasketItemAppServiceTests : BasketsApplicationTestBase |
|||
{ |
|||
private readonly IBasketItemAppService _basketItemAppService; |
|||
|
|||
public BasketItemAppServiceTests() |
|||
{ |
|||
_basketItemAppService = GetRequiredService<IBasketItemAppService>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Test1() |
|||
{ |
|||
// Arrange
|
|||
|
|||
// Act
|
|||
|
|||
// Assert
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using System.Threading.Tasks; |
|||
using Shouldly; |
|||
using Xunit; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.BasketItems |
|||
{ |
|||
public class BasketItemDomainTests : BasketsDomainTestBase |
|||
{ |
|||
public BasketItemDomainTests() |
|||
{ |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Test1() |
|||
{ |
|||
// Arrange
|
|||
|
|||
// Assert
|
|||
|
|||
// Assert
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Plugins.Baskets.BasketItems; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Xunit; |
|||
|
|||
namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore.BasketItems |
|||
{ |
|||
public class BasketItemRepositoryTests : BasketsEntityFrameworkCoreTestBase |
|||
{ |
|||
private readonly IBasketItemRepository _basketItemRepository; |
|||
|
|||
public BasketItemRepositoryTests() |
|||
{ |
|||
_basketItemRepository = GetRequiredService<IBasketItemRepository>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Test1() |
|||
{ |
|||
await WithUnitOfWorkAsync(async () => |
|||
{ |
|||
// Arrange
|
|||
|
|||
// Act
|
|||
|
|||
//Assert
|
|||
}); |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,59 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace EShopSample.Migrations |
|||
{ |
|||
public partial class AddedMediaResourcesToProductSku : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.AddColumn<string>( |
|||
name: "MediaResources", |
|||
table: "EShopProductsProductSkus", |
|||
nullable: true); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "EShopPluginsBasketsBasketItems", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<Guid>(nullable: false), |
|||
ExtraProperties = table.Column<string>(nullable: true), |
|||
ConcurrencyStamp = table.Column<string>(maxLength: 40, nullable: true), |
|||
CreationTime = table.Column<DateTime>(nullable: false), |
|||
CreatorId = table.Column<Guid>(nullable: true), |
|||
TenantId = table.Column<Guid>(nullable: true), |
|||
BasketName = table.Column<string>(nullable: true), |
|||
UserId = table.Column<Guid>(nullable: false), |
|||
ProductId = table.Column<Guid>(nullable: false), |
|||
ProductSkuId = table.Column<Guid>(nullable: false), |
|||
Quantity = table.Column<int>(nullable: false), |
|||
MediaResources = table.Column<string>(nullable: true), |
|||
ProductName = table.Column<string>(nullable: true), |
|||
SkuDescription = table.Column<string>(nullable: true), |
|||
Currency = table.Column<string>(nullable: true), |
|||
UnitPrice = table.Column<decimal>(nullable: false), |
|||
TotalPrice = table.Column<decimal>(nullable: false), |
|||
TotalDiscount = table.Column<decimal>(nullable: false) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_EShopPluginsBasketsBasketItems", x => x.Id); |
|||
}); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_EShopPluginsBasketsBasketItems_UserId", |
|||
table: "EShopPluginsBasketsBasketItems", |
|||
column: "UserId"); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropTable( |
|||
name: "EShopPluginsBasketsBasketItems"); |
|||
|
|||
migrationBuilder.DropColumn( |
|||
name: "MediaResources", |
|||
table: "EShopProductsProductSkus"); |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,61 @@ |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace EShopSample.Migrations |
|||
{ |
|||
public partial class AddedDecimalConfigurationsToBasketItem : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.AlterColumn<decimal>( |
|||
name: "UnitPrice", |
|||
table: "EShopPluginsBasketsBasketItems", |
|||
type: "decimal(20,8)", |
|||
nullable: false, |
|||
oldClrType: typeof(decimal), |
|||
oldType: "decimal(18,2)"); |
|||
|
|||
migrationBuilder.AlterColumn<decimal>( |
|||
name: "TotalPrice", |
|||
table: "EShopPluginsBasketsBasketItems", |
|||
type: "decimal(20,8)", |
|||
nullable: false, |
|||
oldClrType: typeof(decimal), |
|||
oldType: "decimal(18,2)"); |
|||
|
|||
migrationBuilder.AlterColumn<decimal>( |
|||
name: "TotalDiscount", |
|||
table: "EShopPluginsBasketsBasketItems", |
|||
type: "decimal(20,8)", |
|||
nullable: false, |
|||
oldClrType: typeof(decimal), |
|||
oldType: "decimal(18,2)"); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.AlterColumn<decimal>( |
|||
name: "UnitPrice", |
|||
table: "EShopPluginsBasketsBasketItems", |
|||
type: "decimal(18,2)", |
|||
nullable: false, |
|||
oldClrType: typeof(decimal), |
|||
oldType: "decimal(20,8)"); |
|||
|
|||
migrationBuilder.AlterColumn<decimal>( |
|||
name: "TotalPrice", |
|||
table: "EShopPluginsBasketsBasketItems", |
|||
type: "decimal(18,2)", |
|||
nullable: false, |
|||
oldClrType: typeof(decimal), |
|||
oldType: "decimal(20,8)"); |
|||
|
|||
migrationBuilder.AlterColumn<decimal>( |
|||
name: "TotalDiscount", |
|||
table: "EShopPluginsBasketsBasketItems", |
|||
type: "decimal(18,2)", |
|||
nullable: false, |
|||
oldClrType: typeof(decimal), |
|||
oldType: "decimal(20,8)"); |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,24 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace EShopSample.Migrations |
|||
{ |
|||
public partial class AddedStoreIdToBasketItem : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.AddColumn<Guid>( |
|||
name: "StoreId", |
|||
table: "EShopPluginsBasketsBasketItems", |
|||
nullable: false, |
|||
defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropColumn( |
|||
name: "StoreId", |
|||
table: "EShopPluginsBasketsBasketItems"); |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,44 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace EShopSample.Migrations |
|||
{ |
|||
public partial class CreatedProductUpdateEntity : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.CreateTable( |
|||
name: "EShopPluginsBasketsProductUpdates", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<Guid>(nullable: false), |
|||
ExtraProperties = table.Column<string>(nullable: true), |
|||
ConcurrencyStamp = table.Column<string>(maxLength: 40, nullable: true), |
|||
CreationTime = table.Column<DateTime>(nullable: false), |
|||
CreatorId = table.Column<Guid>(nullable: true), |
|||
LastModificationTime = table.Column<DateTime>(nullable: true), |
|||
LastModifierId = table.Column<Guid>(nullable: true), |
|||
IsDeleted = table.Column<bool>(nullable: false, defaultValue: false), |
|||
DeleterId = table.Column<Guid>(nullable: true), |
|||
DeletionTime = table.Column<DateTime>(nullable: true), |
|||
TenantId = table.Column<Guid>(nullable: true), |
|||
ProductSkuId = table.Column<Guid>(nullable: false) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_EShopPluginsBasketsProductUpdates", x => x.Id); |
|||
}); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_EShopPluginsBasketsProductUpdates_ProductSkuId", |
|||
table: "EShopPluginsBasketsProductUpdates", |
|||
column: "ProductSkuId"); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropTable( |
|||
name: "EShopPluginsBasketsProductUpdates"); |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,32 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace EShopSample.Migrations |
|||
{ |
|||
public partial class ChangeBasketItemToAuditedEntity : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.AddColumn<DateTime>( |
|||
name: "LastModificationTime", |
|||
table: "EShopPluginsBasketsBasketItems", |
|||
nullable: true); |
|||
|
|||
migrationBuilder.AddColumn<Guid>( |
|||
name: "LastModifierId", |
|||
table: "EShopPluginsBasketsBasketItems", |
|||
nullable: true); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropColumn( |
|||
name: "LastModificationTime", |
|||
table: "EShopPluginsBasketsBasketItems"); |
|||
|
|||
migrationBuilder.DropColumn( |
|||
name: "LastModifierId", |
|||
table: "EShopPluginsBasketsBasketItems"); |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,33 @@ |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace EShopSample.Migrations |
|||
{ |
|||
public partial class AddInventoryAndIsInvalidToBasketItem : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.AddColumn<int>( |
|||
name: "Inventory", |
|||
table: "EShopPluginsBasketsBasketItems", |
|||
nullable: false, |
|||
defaultValue: 0); |
|||
|
|||
migrationBuilder.AddColumn<bool>( |
|||
name: "IsInvalid", |
|||
table: "EShopPluginsBasketsBasketItems", |
|||
nullable: false, |
|||
defaultValue: false); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropColumn( |
|||
name: "Inventory", |
|||
table: "EShopPluginsBasketsBasketItems"); |
|||
|
|||
migrationBuilder.DropColumn( |
|||
name: "IsInvalid", |
|||
table: "EShopPluginsBasketsBasketItems"); |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,24 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace EShopSample.Migrations |
|||
{ |
|||
public partial class RemoveTenantIdFromProductUpdate : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropColumn( |
|||
name: "TenantId", |
|||
table: "EShopPluginsBasketsProductUpdates"); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.AddColumn<Guid>( |
|||
name: "TenantId", |
|||
table: "EShopPluginsBasketsProductUpdates", |
|||
type: "uniqueidentifier", |
|||
nullable: true); |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue