feat: add coupon support to orders and create user_coupons model
- Added CouponID field to Order model to track used coupons. - Updated order query generation to include CouponID. - Introduced UserCoupon model to manage user coupon associations. - Implemented query methods for UserCoupon to facilitate CRUD operations. - Updated query context and default query setup to include UserCoupon.
This commit is contained in:
@@ -91,11 +91,30 @@ func (s *order) Create(ctx context.Context, form *transaction_dto.OrderCreateFor
|
||||
|
||||
price, err := models.ContentPriceQuery.WithContext(ctx).Where(models.ContentPriceQuery.ContentID.Eq(cid)).First()
|
||||
if err != nil {
|
||||
// If price missing, treat as error? Or maybe 0?
|
||||
// Better to require price record.
|
||||
return nil, errorx.ErrDataCorrupted.WithCause(err).WithMsg("价格信息缺失")
|
||||
}
|
||||
|
||||
amountOriginal := price.PriceAmount
|
||||
var amountDiscount int64 = 0
|
||||
var couponID int64 = 0
|
||||
|
||||
// Validate Coupon
|
||||
if form.UserCouponID != "" {
|
||||
ucid := cast.ToInt64(form.UserCouponID)
|
||||
discount, err := Coupon.Validate(ctx, uid, ucid, amountOriginal)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
amountDiscount = discount
|
||||
|
||||
uc, err := models.UserCouponQuery.WithContext(ctx).Where(models.UserCouponQuery.ID.Eq(ucid)).First()
|
||||
if err == nil {
|
||||
couponID = uc.CouponID
|
||||
}
|
||||
}
|
||||
|
||||
amountPaid := amountOriginal - amountDiscount
|
||||
|
||||
// 2. Create Order (Status: Created)
|
||||
order := &models.Order{
|
||||
TenantID: content.TenantID,
|
||||
@@ -103,27 +122,46 @@ func (s *order) Create(ctx context.Context, form *transaction_dto.OrderCreateFor
|
||||
Type: consts.OrderTypeContentPurchase,
|
||||
Status: consts.OrderStatusCreated,
|
||||
Currency: consts.Currency(price.Currency),
|
||||
AmountOriginal: price.PriceAmount,
|
||||
AmountDiscount: 0,
|
||||
AmountPaid: price.PriceAmount,
|
||||
AmountOriginal: amountOriginal,
|
||||
AmountDiscount: amountDiscount,
|
||||
AmountPaid: amountPaid,
|
||||
CouponID: couponID,
|
||||
IdempotencyKey: uuid.NewString(),
|
||||
Snapshot: types.NewJSONType(fields.OrdersSnapshot{}),
|
||||
}
|
||||
|
||||
if err := models.OrderQuery.WithContext(ctx).Create(order); err != nil {
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
err = models.Q.Transaction(func(tx *models.Query) error {
|
||||
if err := tx.Order.WithContext(ctx).Create(order); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 3. Create Order Item
|
||||
item := &models.OrderItem{
|
||||
TenantID: content.TenantID,
|
||||
UserID: uid,
|
||||
OrderID: order.ID,
|
||||
ContentID: cid,
|
||||
ContentUserID: content.UserID,
|
||||
AmountPaid: order.AmountPaid,
|
||||
}
|
||||
if err := models.OrderItemQuery.WithContext(ctx).Create(item); err != nil {
|
||||
// 3. Create Order Item
|
||||
item := &models.OrderItem{
|
||||
TenantID: content.TenantID,
|
||||
UserID: uid,
|
||||
OrderID: order.ID,
|
||||
ContentID: cid,
|
||||
ContentUserID: content.UserID,
|
||||
AmountPaid: amountPaid,
|
||||
}
|
||||
if err := tx.OrderItem.WithContext(ctx).Create(item); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Mark Coupon Used
|
||||
if form.UserCouponID != "" {
|
||||
if err := Coupon.MarkUsed(ctx, tx, cast.ToInt64(form.UserCouponID), order.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
if _, ok := err.(*errorx.AppError); ok {
|
||||
return nil, err
|
||||
}
|
||||
return nil, errorx.ErrDatabaseError.WithCause(err)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user