refactor(distribution): 重写分销迁移并落地利润百分比分成与货架比例
将 000064-000078 合并为 064/065/066,默认规则改为收号 35%、卖出 40%、服务费 25%。 货架调价改为增加分站 1 元兑换哈夫币比例。sql-guard 仅保护 main 已发布迁移。
This commit is contained in:
@@ -148,7 +148,7 @@ func ResolveOrderSourceTx(tx *gorm.DB, siteCode string, listingID, accountID uin
|
||||
}
|
||||
|
||||
func ruleFromVersion(rule model.DistributionRuleVersion) Rule {
|
||||
return Rule{
|
||||
parsed := Rule{
|
||||
Mode: rule.Mode,
|
||||
PlatformReceiveRatio: rule.PlatformReceiveRatio,
|
||||
PlatformSellRatio: rule.PlatformSellRatio,
|
||||
@@ -162,6 +162,8 @@ func ruleFromVersion(rule model.DistributionRuleVersion) Rule {
|
||||
TaxEnabled: rule.TaxEnabled,
|
||||
TaxRateBPS: rule.TaxRateBPS,
|
||||
}
|
||||
normalizeRulePercents(&parsed)
|
||||
return parsed
|
||||
}
|
||||
|
||||
// calculateForRule 按规则快照计算手续费、服务费和分成基数。
|
||||
@@ -170,7 +172,7 @@ func calculateForRule(rule model.DistributionRuleVersion, input SettlementInput)
|
||||
}
|
||||
|
||||
// SnapshotPaidOrderTx 在支付确认事务内幂等写入财务和参与方快照。
|
||||
// 参与方金额按规则比例对分成基数拆分,剩余(含尾差)记入 RoundingAdjustmentCent 归平台。
|
||||
// 利润 = 租金 − 号主 − 通道手续费,再按 35%/40%/25% 切;尾差记入 RoundingAdjustmentCent。
|
||||
func SnapshotPaidOrderTx(tx *gorm.DB, orderID uint64, grossPaidCent int64) error {
|
||||
if !distributionTablesPresent(tx) {
|
||||
return nil
|
||||
@@ -186,16 +188,24 @@ func SnapshotPaidOrderTx(tx *gorm.DB, orderID uint64, grossPaidCent int64) error
|
||||
if err := tx.First(&rule, *order.DistributionRuleVersionID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
grossRent := order.RentAmountCent
|
||||
if grossRent <= 0 {
|
||||
grossRent = grossPaidCent
|
||||
}
|
||||
markup := order.ShelfMarkupCent
|
||||
if markup < 0 {
|
||||
markup = 0
|
||||
}
|
||||
result, err := calculateForRule(rule, SettlementInput{GrossPaidAmountCent: grossPaidCent, MarkupAmountCent: markup})
|
||||
ownerRent := order.OwnerRentAmountCent
|
||||
if ownerRent < 0 {
|
||||
ownerRent = 0
|
||||
}
|
||||
result, err := calculateForRule(rule, SettlementInput{GrossPaidAmountCent: grossRent, OwnerRentAmountCent: ownerRent, MarkupAmountCent: markup})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
splits := SplitSettlement(ruleFromVersion(rule), result.SplitBaseAmountCent, markup)
|
||||
financial := model.DistributionOrderFinancial{OrderID: order.ID, SiteID: *order.DistributionSiteID, RuleVersionID: rule.ID, GrossPaidAmountCent: grossPaidCent, NetPaidAmountCent: result.NetPaidAmountCent, PaymentFeeBPS: rule.PaymentFeeBPS, PaymentFeeCent: result.PaymentFeeCent, ServiceFeeValue: rule.ServiceFeeValue, ServiceFeeUnit: rule.ServiceFeeUnit, ServiceFeeCent: result.ServiceFeeCent, MarkupAmountCent: markup, TaxEnabled: rule.TaxEnabled, TaxRateBPS: rule.TaxRateBPS, TaxAmountCent: result.TaxAmountCent, SplitBaseAmountCent: result.SplitBaseAmountCent, RoundingAdjustmentCent: SplitRemainderCent(result.SplitBaseAmountCent, splits), SettlementStatus: "pending"}
|
||||
splits := SplitSettlement(ruleFromVersion(rule), result.SplitBaseAmountCent)
|
||||
financial := model.DistributionOrderFinancial{OrderID: order.ID, SiteID: *order.DistributionSiteID, RuleVersionID: rule.ID, GrossPaidAmountCent: grossRent, NetPaidAmountCent: result.NetPaidAmountCent, PaymentFeeBPS: rule.PaymentFeeBPS, PaymentFeeCent: result.PaymentFeeCent, ServiceFeeValue: rule.ServiceFeeValue, ServiceFeeUnit: rule.ServiceFeeUnit, ServiceFeeCent: result.ServiceFeeCent, MarkupAmountCent: markup, TaxEnabled: rule.TaxEnabled, TaxRateBPS: rule.TaxRateBPS, TaxAmountCent: result.TaxAmountCent, SplitBaseAmountCent: result.SplitBaseAmountCent, RoundingAdjustmentCent: SplitRoundingCent(result.SplitBaseAmountCent, result.ServiceFeeCent, splits), SettlementStatus: "pending"}
|
||||
if err := tx.Where("order_id = ?", order.ID).Assign(financial).FirstOrCreate(&financial).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -242,19 +252,30 @@ func ApplyRefundTx(tx *gorm.DB, orderID uint64, refundAmountCent int64) error {
|
||||
}
|
||||
return err
|
||||
}
|
||||
if refundAmountCent < 0 || refundAmountCent > financial.GrossPaidAmountCent {
|
||||
if refundAmountCent < 0 {
|
||||
return ErrInvalidAmount
|
||||
}
|
||||
if refundAmountCent > financial.GrossPaidAmountCent {
|
||||
refundAmountCent = financial.GrossPaidAmountCent
|
||||
}
|
||||
var rule model.DistributionRuleVersion
|
||||
if err := tx.First(&rule, financial.RuleVersionID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := calculateForRule(rule, SettlementInput{GrossPaidAmountCent: financial.GrossPaidAmountCent, RefundAmountCent: refundAmountCent, MarkupAmountCent: financial.MarkupAmountCent})
|
||||
var order model.RentalOrder
|
||||
ownerRent := int64(0)
|
||||
if err := tx.Select("owner_rent_amount_cent").First(&order, orderID).Error; err == nil {
|
||||
ownerRent = order.OwnerRentAmountCent
|
||||
if ownerRent < 0 {
|
||||
ownerRent = 0
|
||||
}
|
||||
}
|
||||
result, err := calculateForRule(rule, SettlementInput{GrossPaidAmountCent: financial.GrossPaidAmountCent, RefundAmountCent: refundAmountCent, OwnerRentAmountCent: ownerRent, MarkupAmountCent: financial.MarkupAmountCent})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
splits := SplitSettlement(ruleFromVersion(rule), result.SplitBaseAmountCent, financial.MarkupAmountCent)
|
||||
if err := tx.Model(&financial).Updates(map[string]any{"refund_amount_cent": refundAmountCent, "net_paid_amount_cent": result.NetPaidAmountCent, "payment_fee_cent": result.PaymentFeeCent, "service_fee_cent": result.ServiceFeeCent, "split_base_amount_cent": result.SplitBaseAmountCent, "rounding_adjustment_cent": SplitRemainderCent(result.SplitBaseAmountCent, splits), "settlement_status": "pending"}).Error; err != nil {
|
||||
splits := SplitSettlement(ruleFromVersion(rule), result.SplitBaseAmountCent)
|
||||
if err := tx.Model(&financial).Updates(map[string]any{"refund_amount_cent": refundAmountCent, "net_paid_amount_cent": result.NetPaidAmountCent, "payment_fee_cent": result.PaymentFeeCent, "service_fee_cent": result.ServiceFeeCent, "split_base_amount_cent": result.SplitBaseAmountCent, "rounding_adjustment_cent": SplitRoundingCent(result.SplitBaseAmountCent, result.ServiceFeeCent, splits), "settlement_status": "pending"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
for _, split := range splits {
|
||||
|
||||
Reference in New Issue
Block a user