protected virtual Task ValidatePreOrderAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku) { if (!product.IsPublished) { throw new BusinessException(FlashSalesErrorCodes.ProductIsNotPublished); } if (product.InventoryStrategy != InventoryStrategy.FlashSales) { throw new UnexpectedInventoryStrategyException(InventoryStrategy.FlashSales); } if (!plan.IsPublished) { throw new EntityNotFoundException(typeof(FlashSalePlan), plan.Id); } if (Clock.Now >= plan.EndTime) { throw new BusinessException(FlashSalesErrorCodes.FlashSaleIsOver); } if (productSku.Inventory < 1) { throw new BusinessException(FlashSalesErrorCodes.ProductSkuInventoryExceeded); } return(Task.CompletedTask); }
protected virtual Task <CreateFlashSaleOrderEto> PrepareCreateFlashSaleOrderEtoAsync( FlashSalePlanCacheItem plan, Guid resultId, CreateOrderInput input, Guid userId, DateTime now, string hashToken) { var planEto = ObjectMapper.Map <FlashSalePlanCacheItem, FlashSalePlanEto>(plan); planEto.TenantId = CurrentTenant.Id; var eto = new CreateFlashSaleOrderEto() { TenantId = CurrentTenant.Id, PlanId = plan.Id, UserId = userId, PendingResultId = resultId, StoreId = plan.StoreId, CreateTime = now, CustomerRemark = input.CustomerRemark, Plan = planEto, HashToken = hashToken }; foreach (var item in input.ExtraProperties) { eto.ExtraProperties.Add(item.Key, item.Value); } return(Task.FromResult(eto)); }
protected virtual async Task SetPreOrderCacheAsync(FlashSalePlanCacheItem plan, ProductDto product, ProductSkuDto productSku, DateTimeOffset expirationTime) { var hashToken = await FlashSalePlanHasher.HashAsync(plan.LastModificationTime, product.LastModificationTime, productSku.LastModificationTime); await PreOrderDistributedCache.SetAsync(await GetPreOrderCacheKeyAsync(plan.Id), new FlashSalePlanPreOrderCacheItem() { HashToken = hashToken, PlanId = plan.Id, ProductId = product.Id, ProductSkuId = productSku.Id, InventoryProviderName = product.InventoryProviderName, }, new DistributedCacheEntryOptions() { AbsoluteExpiration = expirationTime }); }
protected virtual async Task <FlashSaleResult> CreatePendingFlashSaleResultAsync(FlashSalePlanCacheItem plan, Guid userId, Func <Guid, Task> existResultPreProcess) { // Prevent repeat submit var existsResult = await FlashSaleResultRepository.FirstOrDefaultAsync(x => x.PlanId == plan.Id && x.UserId == userId && x.Status != FlashSaleResultStatus.Failed && x.Reason != FlashSaleResultFailedReason.InvalidHashToken); if (existsResult != null) { await existResultPreProcess(existsResult.Id); throw new BusinessException(FlashSalesErrorCodes.DuplicateFlashSalesOrder); } var result = new FlashSaleResult( id: GuidGenerator.Create(), tenantId: CurrentTenant.Id, storeId: plan.StoreId, planId: plan.Id, userId: userId ); return(await FlashSaleResultRepository.InsertAsync(result, autoSave : true)); }