不允许购买第二个主套餐
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m50s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m50s
This commit is contained in:
@@ -2,8 +2,10 @@ package purchase_validation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
packagepkg "github.com/break/junhong_cmp_fiber/internal/service/package"
|
||||
"github.com/break/junhong_cmp_fiber/internal/service/packageprice"
|
||||
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
@@ -82,6 +84,10 @@ func (s *Service) ValidateCardPurchase(ctx context.Context, cardID uint, package
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.validatePackageUsageRules(ctx, constants.AssetWalletResourceTypeIotCard, card.ID, packages); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &PurchaseValidationResult{
|
||||
Card: card,
|
||||
Packages: packages,
|
||||
@@ -113,6 +119,10 @@ func (s *Service) ValidateDevicePurchase(ctx context.Context, deviceID uint, pac
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.validatePackageUsageRules(ctx, constants.AssetWalletResourceTypeDevice, device.ID, packages); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &PurchaseValidationResult{
|
||||
Device: device,
|
||||
Packages: packages,
|
||||
@@ -179,6 +189,61 @@ func (s *Service) validatePackages(ctx context.Context, packageIDs []uint, serie
|
||||
return packages, totalPrice, nil
|
||||
}
|
||||
|
||||
// validatePackageUsageRules 校验主套餐和加油包的购买前置条件。
|
||||
func (s *Service) validatePackageUsageRules(ctx context.Context, carrierType string, carrierID uint, packages []*model.Package) error {
|
||||
formalCount := 0
|
||||
hasAddon := false
|
||||
for _, pkg := range packages {
|
||||
if pkg == nil {
|
||||
continue
|
||||
}
|
||||
switch pkg.PackageType {
|
||||
case constants.PackageTypeFormal:
|
||||
formalCount++
|
||||
case constants.PackageTypeAddon:
|
||||
hasAddon = true
|
||||
}
|
||||
if formalCount > 0 && hasAddon {
|
||||
return errors.New(errors.CodeMixedOrderForbidden)
|
||||
}
|
||||
}
|
||||
|
||||
if formalCount > 1 {
|
||||
return errors.New(errors.CodeMainPackageExists, "一次只能购买一个主套餐")
|
||||
}
|
||||
|
||||
if formalCount == 1 {
|
||||
hasBlockingMain, err := packagepkg.HasBlockingMainPackageForFormal(
|
||||
s.db.WithContext(ctx),
|
||||
carrierType,
|
||||
carrierID,
|
||||
time.Now(),
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.CodeDatabaseError, err, "查询主套餐失败")
|
||||
}
|
||||
if hasBlockingMain {
|
||||
return errors.New(errors.CodeMainPackageExists)
|
||||
}
|
||||
}
|
||||
|
||||
if hasAddon {
|
||||
if _, err := packagepkg.FindAttachableMainPackageForAddon(
|
||||
s.db.WithContext(ctx),
|
||||
carrierType,
|
||||
carrierID,
|
||||
time.Now(),
|
||||
); err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return errors.New(errors.CodeNoMainPackage)
|
||||
}
|
||||
return errors.Wrap(errors.CodeDatabaseError, err, "查询主套餐失败")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateAgentAllocation 校验卖家代理的分配记录上架状态,并返回分配记录
|
||||
func (s *Service) validateAgentAllocation(ctx context.Context, sellerShopID, packageID uint) (*model.ShopPackageAllocation, error) {
|
||||
allocation, err := s.packageAllocationStore.GetByShopAndPackageForSystem(ctx, sellerShopID, packageID)
|
||||
@@ -252,6 +317,10 @@ func (s *Service) ValidateAdminOfflineCardPurchase(ctx context.Context, cardID u
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.validatePackageUsageRules(ctx, constants.AssetWalletResourceTypeIotCard, card.ID, packages); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &PurchaseValidationResult{
|
||||
Card: card,
|
||||
Packages: packages,
|
||||
@@ -279,6 +348,10 @@ func (s *Service) ValidateAdminOfflineDevicePurchase(ctx context.Context, device
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.validatePackageUsageRules(ctx, constants.AssetWalletResourceTypeDevice, device.ID, packages); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &PurchaseValidationResult{
|
||||
Device: device,
|
||||
Packages: packages,
|
||||
|
||||
Reference in New Issue
Block a user