/// <summary> /// 取消支付 /// </summary> /// <param name="orderId"></param> /// <param name="reason"></param> /// <returns></returns> public async Task <Result> Cancel(int orderId, string reason) { var order = await _orderRepository.Query().FirstOrDefaultAsync(e => e.Id == orderId); if (order == null) { return(Result.Fail(ResultCodes.IdInvalid)); } if (order.OrderStatus == OrderStatus.Canceled) { return(Result.Fail(ResultCodes.RequestParamError, "当前订单状态不允许删除")); } var status = new OrderStatus[] { OrderStatus.PaymentFailed, OrderStatus.PendingPayment }; if (!status.Contains(order.OrderStatus)) { return(Result.Fail(ResultCodes.RequestParamError, "当前订单状态不允许删除")); } order.OrderStatus = OrderStatus.Canceled; order.CancelReason = reason; order.CancelTime = DateTime.Now; _orderRepository.Update(order, false); using (var transaction = _orderRepository.BeginTransaction()) { await _orderRepository.SaveAsync(); transaction.Commit(); } return(Result.Ok()); }
public async Task <Result> AdminPayment(int id) { var currentUser = await _workContext.GetCurrentOrThrowAsync(); var order = await _orderRepository.Query().Where(c => c.Id == id).FirstOrDefaultAsync(); if (order == null) { return(Result.Fail("订单不存在")); } var orderSs = new OrderStatus[] { OrderStatus.New, OrderStatus.PendingPayment, OrderStatus.PaymentFailed }; if (!orderSs.Contains(order.OrderStatus)) { return(Result.Fail("当前订单状态不允许标记付款")); } await _orderService.PaymentReceived(new PaymentReceivedParam() { OrderId = order.Id, Note = "标记付款" }); return(Result.Ok()); }
public async Task <Result> Cancel(int id, [FromBody] OrderCancelParam reason) { var user = await _workContext.GetCurrentOrThrowAsync(); var order = await _orderRepository.Query() .FirstOrDefaultAsync(c => c.CustomerId == user.Id && c.Id == id); if (order == null) { return(Result.Fail("订单不存在")); } else if (order.OrderStatus == OrderStatus.Canceled) { return(Result.Fail("订单已取消")); } var orderSs = new OrderStatus[] { OrderStatus.New, OrderStatus.PendingPayment, OrderStatus.PaymentFailed }; if (!orderSs.Contains(order.OrderStatus)) { return(Result.Fail("当前订单无法取消"));; } await _orderService.Cancel(id, user.Id, reason?.Reason); return(Result.Ok()); }
public async Task <Result> Delete(int id) { var currentUser = await _workContext.GetCurrentUserAsync(); var order = await _orderRepository .Query() .Include(c => c.BillingAddress) .Include(c => c.ShippingAddress) .Include(c => c.OrderItems).ThenInclude(c => c.Product) .Where(c => c.Id == id).FirstOrDefaultAsync(); if (order == null) { return(Result.Fail("订单不存在")); } var orderSs = new OrderStatus[] { OrderStatus.Complete, OrderStatus.Canceled }; if (!orderSs.Contains(order.OrderStatus)) { return(Result.Fail("当前订单状态不允许删除")); } if (order.ShippingAddress != null) { order.ShippingAddress.IsDeleted = true; order.ShippingAddress.UpdatedOn = DateTime.Now; } if (order.BillingAddress != null) { order.BillingAddress.IsDeleted = true; order.BillingAddress.UpdatedOn = DateTime.Now; } foreach (var item in order.OrderItems) { item.IsDeleted = true; item.UpdatedOn = DateTime.Now; item.UpdatedBy = currentUser; } //删除订单暂不删除历史 order.IsDeleted = true; order.UpdatedOn = DateTime.Now; order.UpdatedBy = currentUser; await _orderRepository.SaveChangesAsync(); return(Result.Ok()); }
public async Task <Result> OnHold(int id, [FromBody] OrderOnHoldParam param) { var currentUser = await _workContext.GetCurrentUserAsync(); var order = await _orderRepository .Query() .Where(c => c.Id == id).FirstOrDefaultAsync(); if (order == null) { return(Result.Fail("订单不存在")); } if (order.OrderStatus == OrderStatus.OnHold) { return(Result.Fail("订单已挂起")); } var orderNotSs = new OrderStatus[] { OrderStatus.Canceled, OrderStatus.Complete }; if (orderNotSs.Contains(order.OrderStatus)) { return(Result.Fail("当前订单状态不允许挂起")); } var oldStatus = order.OrderStatus; order.OrderStatus = OrderStatus.OnHold; order.OnHoldReason = param?.Reason; order.UpdatedOn = DateTime.Now; order.UpdatedBy = currentUser; await _orderRepository.SaveChangesAsync(); var orderStatusChanged = new OrderChanged { OrderId = order.Id, OldStatus = oldStatus, NewStatus = order.OrderStatus, Order = order, UserId = currentUser.Id, Note = "挂起订单" }; await _mediator.Publish(orderStatusChanged); return(Result.Ok()); }
public async Task <Result> Delete(int id) { var order = await _orderRepository.FirstOrDefaultAsync(id); if (order == null) { return(Result.Fail(ResultCodes.IdInvalid)); } var status = new OrderStatus[] { OrderStatus.Complete, OrderStatus.Canceled }; if (!status.Contains(order.OrderStatus)) { return(Result.Fail(ResultCodes.RequestParamError, "当前订单状态不允许删除")); } await _orderRepository.RemoveAsync(order); return(Result.Ok()); }
public async Task <Result> DelayCinfirmReceipt(int id) { var user = await _workContext.GetCurrentOrThrowAsync(); var order = await _orderRepository.Query() .FirstOrDefaultAsync(c => c.CustomerId == user.Id && c.Id == id); if (order == null) { return(Result.Fail("订单不存在")); } else if (order.OrderStatus == OrderStatus.Canceled) { return(Result.Fail("订单已取消")); } var orderSs = new OrderStatus[] { OrderStatus.PaymentReceived, OrderStatus.Shipping, OrderStatus.Shipped }; if (!orderSs.Contains(order.OrderStatus)) { return(Result.Fail("当前订单无法延长确认收货时间"));; } var timeFromMin = await _appSettingService.Get <int>(OrderKeys.OrderAutoCompleteTimeForMinute); if (order.DeliveredEndOn == null) { order.DeliveredEndOn = DateTime.Now; } order.DeliveredEndOn = order.DeliveredEndOn.Value.AddMinutes(timeFromMin); if (order.DeliveredEndOn > order.CreatedOn.AddDays(60)) { return(Result.Fail("延长确认收货时间最大不可超过60天")); } order.UpdatedOn = DateTime.Now; order.UpdatedById = user.Id; await _orderRepository.SaveChangesAsync(); return(Result.Ok()); }
public async Task <Result> CinfirmReceipt(int id) { var user = await _workContext.GetCurrentOrThrowAsync(); var order = await _orderRepository.Query() .FirstOrDefaultAsync(c => c.CustomerId == user.Id && c.Id == id); if (order == null) { return(Result.Fail("订单不存在")); } else if (order.OrderStatus == OrderStatus.Canceled) { return(Result.Fail("订单已取消")); } var orderSs = new OrderStatus[] { OrderStatus.PaymentReceived, OrderStatus.Shipping, OrderStatus.Shipped }; if (!orderSs.Contains(order.OrderStatus)) { return(Result.Fail("当前订单无法确认收货"));; } order.OrderStatus = OrderStatus.Complete; order.ShippingStatus = ShippingStatus.Delivered; order.DeliveredOn = DateTime.Now; order.UpdatedOn = DateTime.Now; order.UpdatedById = user.Id; await _orderRepository.SaveChangesAsync(); // 自动好评 var min = await _appSettingService.Get <int>(OrderKeys.OrderCompleteAutoReviewTimeForMinute); foreach (var item in order.OrderItems) { await _jobService.Schedule(() => _reviewService.ReviewAutoGood(item.ProductId, EntityTypeWithId.Product, order.Id, ReviewSourceType.Order) , TimeSpan.FromMinutes(min)); } return(Result.Ok()); }
/// <summary> /// 库增加/存减少规则 /// 当增加下单数量时减少库存 /// 当减少下单数量时增加库存 /// </summary> /// <param name="stocks"></param> /// <param name="product"></param> /// <param name="quantity">减少或增加库存数量,减少库存负数,增加库存整数</param> /// <param name="orderId"></param> /// <param name="note"></param> void OrderStockDoWorker(IList <Stock> stocks, IList <StockHistory> addStockHistories, Product product, User user, int quantity, Order order, string note) { if (product?.StockTrackingIsEnabled != true || quantity == 0) { return; } // 交易取消、交易完成的订单修改下单数量不修改库存 var notStockOrderStatus = new OrderStatus[] { OrderStatus.Canceled, OrderStatus.Complete }; if (order == null || notStockOrderStatus.Contains(order.OrderStatus)) { return; } if (stocks.Count <= 0) { throw new Exception("商品库存不存在"); } var productStocks = stocks.Where(c => c.ProductId == product.Id && c.IsEnabled); if (productStocks.Count() <= 0) { throw new Exception($"商品:{product.Name},无可用库存"); } switch (product.StockReduceStrategy) { case StockReduceStrategy.PlaceOrderWithhold: //下单减库存时,支持成功,不减少库存 if (order.OrderStatus == OrderStatus.PaymentReceived) { return; } break; case StockReduceStrategy.PaymentSuccessDeduct: //支付减库存时,下单、待支付、支付失败,不减少库存 var oss = new OrderStatus[] { OrderStatus.New, OrderStatus.PendingPayment, OrderStatus.PaymentFailed }; if (oss.Contains(order.OrderStatus)) { return; } break; default: throw new Exception("库存扣减策略不存在"); } //分布式锁,重新获取库存 //todo if (quantity < 0) { //减少库存 var absQuantity = Math.Abs(quantity); if (productStocks.Sum(c => c.StockQuantity) < absQuantity) { throw new Exception($"商品[{product.Name}]库存不足,库存剩余:{productStocks.Sum(c => c.StockQuantity)}"); } do { var firstStock = productStocks.Where(c => c.StockQuantity > 0).OrderBy(c => c.DisplayOrder).FirstOrDefault(); if (firstStock == null) { throw new Exception($"商品[{product.Name}]库存不足"); } if (firstStock.StockQuantity >= absQuantity) { firstStock.StockQuantity = firstStock.StockQuantity - absQuantity; if (firstStock.StockQuantity < 0) { throw new Exception($"商品[{product.Name}]库存不足"); } addStockHistories.Add(new StockHistory() { Note = $"订单:{order.No},商品:{product.Name},减少库存:{absQuantity}。备注:{note}", CreatedBy = user, UpdatedBy = user, AdjustedQuantity = -absQuantity, StockQuantity = firstStock.StockQuantity, WarehouseId = firstStock.WarehouseId, ProductId = product.Id }); absQuantity = 0; } else { absQuantity = absQuantity - firstStock.StockQuantity; if (absQuantity < 0) { throw new Exception($"库存扣减异常,请重试"); } addStockHistories.Add(new StockHistory() { Note = $"订单:{order.No},商品:{product.Name},减少库存:{absQuantity}。备注:{note}", CreatedBy = user, UpdatedBy = user, AdjustedQuantity = -firstStock.StockQuantity, StockQuantity = 0, WarehouseId = firstStock.WarehouseId, ProductId = product.Id }); firstStock.StockQuantity = 0; } } while (absQuantity > 0); } else if (quantity > 0) { //增加库存 var firstStock = productStocks.OrderBy(c => c.DisplayOrder).FirstOrDefault(); if (firstStock == null) { throw new Exception($"商品:{product.Name},无可用库存"); } firstStock.StockQuantity += quantity; addStockHistories.Add(new StockHistory() { Note = $"订单:{order.No},商品:{product.Name},增加库存(减少下单商品数量):{quantity}。备注:{note}", CreatedBy = user, UpdatedBy = user, AdjustedQuantity = quantity, StockQuantity = firstStock.StockQuantity, WarehouseId = firstStock.WarehouseId, ProductId = product.Id }); } }
public async Task PaymentReceived(PaymentReceivedParam param) { if (param == null) { return; } var orderSs = new OrderStatus[] { OrderStatus.New, OrderStatus.PendingPayment, OrderStatus.PaymentFailed }; var user = await _workContext.GetCurrentUserOrNullAsync(); var userId = user?.Id ?? (int)UserWithId.System; var query = _orderRepository.Query(); if (param.OrderId.HasValue && param.OrderId.Value > 0) { query = query.Where(c => c.Id == param.OrderId.Value); } else if (!string.IsNullOrWhiteSpace(param.OrderNo)) { var longOrderNo = Convert.ToInt64(param.OrderNo); query = query.Where(c => c.No == longOrderNo); } else { return; } var order = await query.Include(c => c.OrderItems).ThenInclude(c => c.Product) .FirstOrDefaultAsync(); if (order == null || !orderSs.Contains(order.OrderStatus)) { return; } order.OrderStatus = OrderStatus.PaymentReceived; order.PaymentMethod = param.PaymentMethod; order.PaymentOn = param.PaymentOn ?? DateTime.Now; order.PaymentFeeAmount = param.PaymentFeeAmount ?? order.OrderTotal; order.UpdatedOn = DateTime.Now; order.UpdatedById = userId; //标记付款,付款减少库存商品,减少库存 var productIds = order.OrderItems.Select(c => c.ProductId).Distinct(); var stocks = await _stockRepository.Query().Where(c => productIds.Contains(c.ProductId)).ToListAsync(); var addStockHistories = new List <StockHistory>(); foreach (var item in order.OrderItems) { OrderStockDoWorker(stocks, addStockHistories, item.Product, userId, -item.Quantity, order, "标记付款"); } using (var transaction = _orderRepository.BeginTransaction()) { await _orderRepository.SaveChangesAsync(); await _stockRepository.SaveChangesAsync(); if (addStockHistories.Count > 0) { _stockHistoryRepository.AddRange(addStockHistories); await _stockHistoryRepository.SaveChangesAsync(); } transaction.Commit(); } }
public async Task Cancel(int id, int userId, string reason) { //var currentUser = await _workContext.GetCurrentUser(); var order = await _orderRepository.Query() .Include(c => c.OrderItems).ThenInclude(c => c.Product) .Where(c => c.Id == id).FirstOrDefaultAsync(); if (order == null || order.OrderStatus == OrderStatus.Canceled) { return; } var orderSs = new OrderStatus[] { OrderStatus.New, OrderStatus.PendingPayment, OrderStatus.PaymentFailed }; if (!orderSs.Contains(order.OrderStatus)) { return; } var productIds = order.OrderItems.Select(c => c.ProductId).Distinct(); var stocks = await _stockRepository.Query().Where(c => productIds.Contains(c.ProductId)).ToListAsync(); var addStockHistories = new List <StockHistory>(); //取消订单增加库存 foreach (var item in order.OrderItems) { OrderStockDoWorker(stocks, addStockHistories, item.Product, userId, item.Quantity, order, "取消订单"); } var oldStatus = order.OrderStatus; order.OrderStatus = OrderStatus.Canceled; order.CancelReason = reason; order.UpdatedOn = DateTime.Now; order.UpdatedById = userId; using (var transaction = _orderRepository.BeginTransaction()) { await _orderRepository.SaveChangesAsync(); var orderStatusChanged = new OrderChanged { OrderId = order.Id, OldStatus = oldStatus, NewStatus = order.OrderStatus, Order = order, UserId = userId, Note = "取消订单" }; await _mediator.Publish(orderStatusChanged); await _stockRepository.SaveChangesAsync(); if (addStockHistories.Count > 0) { _stockHistoryRepository.AddRange(addStockHistories); await _stockHistoryRepository.SaveChangesAsync(); } transaction.Commit(); } //var orderItems = _orderItemRepository.Query().Include(x => x.Product).Where(x => x.Order.Id == order.Id); //foreach (var item in orderItems) //{ // //if (item.Product.StockTrackingIsEnabled) // //{ // // item.Product.StockQuantity = item.Product.StockQuantity + item.Quantity; // //} // // 库存处理 //} }
public async Task <Result> Payment(int orderId) { var order = await _orderRepository.Query().FirstOrDefaultAsync(e => e.Id == orderId); if (order == null) { return(Result.Fail(ResultCodes.IdInvalid)); } var status = new OrderStatus[] { OrderStatus.PendingPayment, OrderStatus.PaymentFailed }; if (!status.Contains(order.OrderStatus)) { return(Result.Fail(ResultCodes.RequestParamError, "当前订单状态不允许付款")); } if (order.ActuallyAmount <= 0) { return(Result.Fail(ResultCodes.RequestParamError, "订单金额不能为0")); } if (order.ActuallyAmount - order.WalletAmount <= 0) { return(Result.Fail(ResultCodes.RequestParamError, "订单金额不能为0")); } var user = await _customerManager.GetUserAsync(); try { var wechatResponse = await _paymentService.GeneratePaymentOrder(new GeneratePaymentOrderRequest { OrderNo = order.OrderNo, OpenId = user.OpenId, TotalFee = order.ActuallyAmount - order.WalletAmount, Subject = "大脉商城", }); var paymentTimeoutEvent = new PaymentTimeoutEvent() { OrderId = order.Id, OrderNo = order.OrderNo }; var headers = new Dictionary <string, object>() { { "x-delay", 10 * 60 * 1000 } // 延迟10分钟 }; var properties = _client.CreateProperties(); properties.Headers = headers; _client.PushMessage(MQConstants.Exchange, MQConstants.PaymentTimeOutRouteKey, paymentTimeoutEvent, properties); return(Result.Ok(wechatResponse)); } catch (Exception ex) { _logger.LogError(ex.Message, ex); return(Result.Fail(ResultCodes.PaymentRequestError, ex.Message)); } }
public void GetOrdersArchive_should_filter_orders_by_status() { _userManager.GetByEmail(Arg.Any<string>()).ReturnsForAnyArgs(_frequentlyUsedClient); var allowedStatuses = new OrderStatus[] { OrderStatus.Completed, OrderStatus.Cancelled }; var actual = _target.GetOrdersArchive(new ClientDashboardFilter() { PageNumber = 1, ItemsPerPage = int.MaxValue }); actual.Items.Select(e => e.Status).Any(e => !allowedStatuses.Contains(e)).Should().BeFalse(); }
public void GetActiveOrders_should_filter_orders_by_status() { _userManager.GetByEmail(Arg.Any<string>()).ReturnsForAnyArgs(_frequentlyUsedClient); var excludedStatuses = new OrderStatus[] { OrderStatus.Draft, OrderStatus.PendingAssignment, OrderStatus.Completed, OrderStatus.Cancelled, OrderStatus.CreationProcess }; var actual = _target.GetActiveOrders(new ClientDashboardFilter() { PageNumber = 1, ItemsPerPage = int.MaxValue }); actual.Items.Select(e => e.Status).Any(e => excludedStatuses.Contains(e)).Should().BeFalse(); }
/// <summary> /// 支付接收 /// </summary> /// <param name="request"></param> /// <returns></returns> public async Task PaymentReceived(PaymentReceivedRequest request) { var order = await _orderRepository.Query() .Include(e => e.OrderItems) .ThenInclude(e => e.CommissionHistory) .FirstOrDefaultAsync(e => e.OrderNo == request.OrderNo); if (order == null) { return; } var status = new OrderStatus[] { OrderStatus.PendingPayment, OrderStatus.PaymentFailed }; if (!status.Contains(order.OrderStatus)) { return; } var roleResult = false; PartnerRole role = PartnerRole.Default; if (!string.IsNullOrEmpty(order.ExtendParams)) { roleResult = Enum.TryParse <PartnerRole>(order.ExtendParams, true, out role); } var totalCommission = 0; var totalAmount = 0; var commissions = order.OrderItems.Where(e => e.CommissionHistory != null).Select(e => e.CommissionHistory); if (commissions.Count() > 0) { foreach (var item in commissions) { if (order.IsFirstOrder) { totalAmount += item.Commission; item.Status = CommissionStatus.Complete; item.SettlementTime = DateTime.Now; } else { totalCommission += item.Commission; item.Status = CommissionStatus.PendingSettlement; } } } order.OrderStatus = OrderStatus.PaymentReceived; order.PaymentMethod = request.PaymentMethod; order.PaymentTime = request.PaymentTime; order.PaymentFee = request.PaymentFee; _orderRepository.Update(order, false); using (var transaction = _orderRepository.BeginTransaction()) { await _orderRepository.SaveAsync(); if (roleResult) { await _customerRepository.UpdateProperyAsync(new Customer { Id = order.CustomerId, Role = role }, nameof(Customer.Role)); } if (totalCommission > 0 || totalAmount > 0) { var parentId = commissions.Select(e => e.CustomerId).FirstOrDefault(); await _customerManager.UpdateAssets(parentId, totalCommission, totalAmount, "下级首单返佣金"); } if (order.WalletAmount > 0) { await _customerManager.UpdateAssets(order.CustomerId, 0, 0, -order.WalletAmount, "商品抵扣金额"); } transaction.Commit(); } }