fix: 禁止后台单独取消子订单,避免父订单支付后子订单被复活或余额未退
This commit is contained in:
1 parent
495a0ce0f0
commit
ff9d9a1f61
3 files changed
+30
No files matched your search
@@ -39,6 +39,7 @@ func TestOrderServiceTestsAreSplitByResponsibility(t *testing.T) {
|
||||
"TestCalcParentStatus", "TestCalcParentStatusAllRefunded", "TestCalcParentStatusPartiallyRefunded",
|
||||
"TestExpectedRefundStatus", "TestResolvedParentStatusPrefersOwnRefund",
|
||||
"TestIsTransitionAllowedRefunded", "TestUpdateOrderStatusParentToPartiallyRefundedSyncsChildren",
|
||||
"TestUpdateOrderStatusRejectsCancelingChildOrder",
|
||||
"TestUpdateOrderStatusRejectsCancelingPaidParent",
|
||||
"TestUpdateOrderStatusRejectsManualPaidTransition",
|
||||
"TestCanCompleteParentOrder", "TestCanCompleteParentOrderRejectInvalidStatus",
|
||||
|
||||
@@ -281,6 +281,11 @@ func (s *OrderService) UpdateOrderStatus(orderID uint, targetStatus string) (*or
|
||||
if !IsTransitionAllowed(order.Status, target) {
|
||||
return nil, ErrOrderStatusInvalid
|
||||
}
|
||||
// 子订单不能单独取消:父订单的钱包扣款与优惠券不会随之回滚,
|
||||
// 且父订单后续支付会把已取消的子订单重新置为已支付。取消须针对父订单。
|
||||
if target == constants.OrderStatusCanceled && order.ParentID != nil {
|
||||
return nil, ErrOrderStatusInvalid
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
updates := map[string]interface{}{
|
||||
|
||||
@@ -370,3 +370,27 @@ func TestUpdateOrderStatusRejectsCancelingPaidParent(t *testing.T) {
|
||||
t.Fatalf("paid parent status mutated to %s", stored.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateOrderStatusRejectsCancelingChildOrder(t *testing.T) {
|
||||
dsn := fmt.Sprintf("file:order_service_reject_cancel_child_%d?mode=memory&cache=shared", time.Now().UnixNano())
|
||||
db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("open sqlite failed: %v", err)
|
||||
}
|
||||
if err := db.AutoMigrate(&orderdomain.Order{}, &orderdomain.OrderItem{}, &fulfillmentdomain.Fulfillment{}); err != nil {
|
||||
t.Fatalf("auto migrate failed: %v", err)
|
||||
}
|
||||
now := time.Now()
|
||||
parent := &orderdomain.Order{OrderNo: "CHILD-CANCEL-PARENT", Status: constants.OrderStatusPendingPayment, Currency: "CNY", CreatedAt: now, UpdatedAt: now}
|
||||
if err := db.Create(parent).Error; err != nil {
|
||||
t.Fatalf("create parent failed: %v", err)
|
||||
}
|
||||
child := &orderdomain.Order{OrderNo: "CHILD-CANCEL-PARENT-A", ParentID: &parent.ID, Status: constants.OrderStatusPendingPayment, Currency: "CNY", CreatedAt: now, UpdatedAt: now}
|
||||
if err := db.Create(child).Error; err != nil {
|
||||
t.Fatalf("create child failed: %v", err)
|
||||
}
|
||||
svc := NewOrderService(OrderServiceOptions{OrderStore: ordergormstore.New(db, "test-guest-credential-secret-with-32-bytes")})
|
||||
if _, err := svc.UpdateOrderStatus(child.ID, constants.OrderStatusCanceled); err != ErrOrderStatusInvalid {
|
||||
t.Fatalf("cancel child error = %v, want %v", err, ErrOrderStatusInvalid)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user