[Snow Team] backend-fixer: auto-commit work
This commit is contained in:
@@ -25,7 +25,8 @@ type FreezeRequest struct {
|
||||
}
|
||||
|
||||
type DepositFreeQuotaRequest struct {
|
||||
Amount float64 `json:"amount"`
|
||||
AmountCent int64 `json:"amount_cent"`
|
||||
Amount float64 `json:"amount"`
|
||||
}
|
||||
|
||||
type PaginatedResult struct {
|
||||
|
||||
@@ -2,6 +2,7 @@ package adminuser
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
|
||||
"hfb_sys/backend/internal/auditlog"
|
||||
"hfb_sys/backend/internal/model"
|
||||
@@ -60,24 +61,29 @@ func (r *Repository) Unfreeze(adminID uint64, userID uint64, meta AuditMeta) (*U
|
||||
}
|
||||
|
||||
func (r *Repository) SetDepositFreeQuota(adminID uint64, userID uint64, req DepositFreeQuotaRequest, meta AuditMeta) (*UserDTO, error) {
|
||||
amount := roundMoney(req.Amount)
|
||||
if amount < 0 {
|
||||
amountCent := depositFreeQuotaAmountCent(req)
|
||||
if amountCent < 0 {
|
||||
return nil, ErrInvalidUser
|
||||
}
|
||||
amount := float64(amountCent) / 100
|
||||
err := r.db.Transaction(func(tx *gorm.DB) error {
|
||||
var user model.User
|
||||
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).First(&user, userID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
beforeAmount := user.DepositFreeQuota
|
||||
beforeAmountCent := user.DepositFreeQuotaCent
|
||||
user.DepositFreeQuota = amount
|
||||
user.DepositFreeQuotaCent = amountCent
|
||||
if err := tx.Save(&user).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return appendAuditLog(tx, adminID, "admin_user.set_deposit_free_quota", user.ID, meta, map[string]any{
|
||||
"user_id": user.ID,
|
||||
"before_amount": beforeAmount,
|
||||
"after_amount": amount,
|
||||
"user_id": user.ID,
|
||||
"before_amount": beforeAmount,
|
||||
"after_amount": amount,
|
||||
"before_amount_cent": beforeAmountCent,
|
||||
"after_amount_cent": amountCent,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
@@ -172,6 +178,13 @@ func roundMoney(value float64) float64 {
|
||||
return money.Round(value)
|
||||
}
|
||||
|
||||
func depositFreeQuotaAmountCent(req DepositFreeQuotaRequest) int64 {
|
||||
if req.AmountCent != 0 {
|
||||
return req.AmountCent
|
||||
}
|
||||
return int64(math.Round(req.Amount * 100))
|
||||
}
|
||||
|
||||
func appendAuditLog(tx *gorm.DB, actorID uint64, action string, bizID uint64, meta AuditMeta, detail map[string]any) error {
|
||||
return auditlog.Append(tx, auditlog.Entry{
|
||||
ActorType: "admin",
|
||||
|
||||
@@ -345,11 +345,20 @@ type arbitrationSettlement struct {
|
||||
}
|
||||
|
||||
func buildArbitrationSettlement(order model.RentalOrder, req ArbitrateRequest, renterFrozenBalance float64) (arbitrationSettlement, error) {
|
||||
total := roundMoney(order.RentAmount + order.DepositAmount)
|
||||
ownerRentAmount := roundMoney(order.OwnerRentAmount)
|
||||
if ownerRentAmount <= 0 || ownerRentAmount > order.RentAmount {
|
||||
ownerRentAmount = roundMoney(order.RentAmount)
|
||||
rentAmount := float64(order.RentAmountCent) / 100
|
||||
if rentAmount <= 0 {
|
||||
rentAmount = order.RentAmount
|
||||
}
|
||||
depositAmount := float64(order.DepositAmountCent) / 100
|
||||
if depositAmount <= 0 {
|
||||
depositAmount = order.DepositAmount
|
||||
}
|
||||
ownerRentAmount := float64(order.OwnerRentAmountCent) / 100
|
||||
if ownerRentAmount <= 0 || ownerRentAmount > rentAmount {
|
||||
ownerRentAmount = rentAmount
|
||||
}
|
||||
total := roundMoney(rentAmount + depositAmount)
|
||||
ownerRentAmount = roundMoney(ownerRentAmount)
|
||||
settlement := arbitrationSettlement{}
|
||||
orderID := order.ID
|
||||
releaseFrozenAmount := minMoney(total, roundMoney(renterFrozenBalance))
|
||||
@@ -398,21 +407,21 @@ func buildArbitrationSettlement(order model.RentalOrder, req ArbitrateRequest, r
|
||||
return settlement, ErrInvalidDispute
|
||||
}
|
||||
addRenterRefund(req.Amount, "仲裁部分退款")
|
||||
addOwnerIncome(minMoney(total-req.Amount, ownerRentAmount+order.DepositAmount), "仲裁剩余金额结算给号主")
|
||||
addOwnerIncome(minMoney(total-req.Amount, ownerRentAmount+depositAmount), "仲裁剩余金额结算给号主")
|
||||
case "release_deposit":
|
||||
addOwnerIncome(ownerRentAmount, "仲裁确认订单金额结算给号主")
|
||||
addRenterRefund(order.DepositAmount, "仲裁释放押金给租客")
|
||||
addRenterRefund(depositAmount, "仲裁释放押金给租客")
|
||||
case "deduct_deposit", "compensate_owner":
|
||||
deductAmount := roundMoney(req.Amount)
|
||||
if deductAmount <= 0 {
|
||||
deductAmount = order.DepositAmount
|
||||
deductAmount = depositAmount
|
||||
}
|
||||
if deductAmount > order.DepositAmount {
|
||||
if deductAmount > depositAmount {
|
||||
return settlement, ErrInvalidDispute
|
||||
}
|
||||
settlement.DepositDeductAmount = deductAmount
|
||||
addOwnerIncome(ownerRentAmount+deductAmount, "仲裁订单金额及押金赔付结算给号主")
|
||||
addRenterRefund(order.DepositAmount-deductAmount, "仲裁退回剩余押金给租客")
|
||||
addRenterRefund(depositAmount-deductAmount, "仲裁退回剩余押金给租客")
|
||||
case "order_close":
|
||||
// Only release frozen funds. No available-balance settlement happens in development mode.
|
||||
case "mark_abnormal":
|
||||
|
||||
@@ -9,13 +9,13 @@ import (
|
||||
|
||||
func TestBuildArbitrationSettlementSkipsFrozenReleaseWhenNoFrozenBalance(t *testing.T) {
|
||||
order := model.RentalOrder{
|
||||
ID: 11,
|
||||
OrderNo: "RO202606080001",
|
||||
RenterID: 101,
|
||||
OwnerID: 202,
|
||||
RentAmount: 200,
|
||||
OwnerRentAmount: 180,
|
||||
DepositAmount: 100,
|
||||
ID: 11,
|
||||
OrderNo: "RO202606080001",
|
||||
RenterID: 101,
|
||||
OwnerID: 202,
|
||||
RentAmountCent: 20000,
|
||||
OwnerRentAmountCent: 18000,
|
||||
DepositAmountCent: 10000,
|
||||
}
|
||||
|
||||
settlement, err := buildArbitrationSettlement(order, ArbitrateRequest{
|
||||
@@ -46,13 +46,13 @@ func TestBuildArbitrationSettlementSkipsFrozenReleaseWhenNoFrozenBalance(t *test
|
||||
|
||||
func TestBuildArbitrationSettlementLimitsFrozenReleaseToExistingBalance(t *testing.T) {
|
||||
order := model.RentalOrder{
|
||||
ID: 12,
|
||||
OrderNo: "RO202606080002",
|
||||
RenterID: 101,
|
||||
OwnerID: 202,
|
||||
RentAmount: 200,
|
||||
OwnerRentAmount: 180,
|
||||
DepositAmount: 100,
|
||||
ID: 12,
|
||||
OrderNo: "RO202606080002",
|
||||
RenterID: 101,
|
||||
OwnerID: 202,
|
||||
RentAmountCent: 20000,
|
||||
OwnerRentAmountCent: 18000,
|
||||
DepositAmountCent: 10000,
|
||||
}
|
||||
|
||||
settlement, err := buildArbitrationSettlement(order, ArbitrateRequest{
|
||||
@@ -69,8 +69,8 @@ func TestBuildArbitrationSettlementLimitsFrozenReleaseToExistingBalance(t *testi
|
||||
continue
|
||||
}
|
||||
releaseEntryCount++
|
||||
if entry.Amount != 120 {
|
||||
t.Fatalf("release frozen amount = %.1f, want 120.0", entry.Amount)
|
||||
if entry.AmountCent != 12000 {
|
||||
t.Fatalf("release frozen amount cent = %d, want 12000", entry.AmountCent)
|
||||
}
|
||||
}
|
||||
if releaseEntryCount != 1 {
|
||||
|
||||
@@ -82,14 +82,16 @@ func (r *Repository) Create(ownerID uint64, req CreateRequest, reviewRequired bo
|
||||
price := normalizedListingPrice(req)
|
||||
depositAmount := roundMoney(req.DepositAmount)
|
||||
listing := model.RentalListing{
|
||||
ListingNo: listingNo,
|
||||
AccountID: account.ID,
|
||||
OwnerID: ownerID,
|
||||
Price: price,
|
||||
DepositAmount: depositAmount,
|
||||
Status: listingStatus,
|
||||
ReviewStatus: reviewStatus,
|
||||
PublishedAt: publishedAt,
|
||||
ListingNo: listingNo,
|
||||
AccountID: account.ID,
|
||||
OwnerID: ownerID,
|
||||
Price: price,
|
||||
PriceCent: int64(math.Round(price * 100)),
|
||||
DepositAmount: depositAmount,
|
||||
DepositAmountCent: int64(math.Round(depositAmount * 100)),
|
||||
Status: listingStatus,
|
||||
ReviewStatus: reviewStatus,
|
||||
PublishedAt: publishedAt,
|
||||
}
|
||||
if err := tx.Create(&listing).Error; err != nil {
|
||||
return err
|
||||
@@ -147,14 +149,18 @@ func (r *Repository) CreateFromExternalUpload(upload externalUploadCreate, req C
|
||||
if err := tx.Create(&account).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
price := normalizedListingPrice(req)
|
||||
depositAmount := roundMoney(req.DepositAmount)
|
||||
listing := model.RentalListing{
|
||||
ListingNo: listingNo,
|
||||
AccountID: account.ID,
|
||||
OwnerID: owner.ID,
|
||||
Price: normalizedListingPrice(req),
|
||||
DepositAmount: roundMoney(req.DepositAmount),
|
||||
Status: "draft",
|
||||
ReviewStatus: "pending",
|
||||
ListingNo: listingNo,
|
||||
AccountID: account.ID,
|
||||
OwnerID: owner.ID,
|
||||
Price: price,
|
||||
PriceCent: int64(math.Round(price * 100)),
|
||||
DepositAmount: depositAmount,
|
||||
DepositAmountCent: int64(math.Round(depositAmount * 100)),
|
||||
Status: "draft",
|
||||
ReviewStatus: "pending",
|
||||
}
|
||||
if err := tx.Create(&listing).Error; err != nil {
|
||||
return err
|
||||
@@ -1439,14 +1445,14 @@ func (row listingRow) toDTO() ListingDTO {
|
||||
screenshotURLS := cleanScreenshotURLs(decodeScreenshots(row.ScreenshotURLS))
|
||||
reviewStatus, reviewReason := normalizedReviewState(row.Status, row.ReviewStatus, row.ReviewReason)
|
||||
return ListingDTO{
|
||||
ID: row.ID,
|
||||
ListingNo: row.ListingNo,
|
||||
AccountID: row.AccountID,
|
||||
OwnerID: row.OwnerID,
|
||||
OwnerPhone: row.OwnerPhone,
|
||||
OwnerNickname: row.OwnerNickname,
|
||||
Title: row.Title,
|
||||
Description: row.Description,
|
||||
ID: row.ID,
|
||||
ListingNo: row.ListingNo,
|
||||
AccountID: row.AccountID,
|
||||
OwnerID: row.OwnerID,
|
||||
OwnerPhone: row.OwnerPhone,
|
||||
OwnerNickname: row.OwnerNickname,
|
||||
Title: row.Title,
|
||||
Description: row.Description,
|
||||
GameName: row.GameName,
|
||||
ServerRegion: row.ServerRegion,
|
||||
LoginPlatform: row.LoginPlatform,
|
||||
|
||||
@@ -69,7 +69,7 @@ func TestCreateRequiresPublishAgreements(t *testing.T) {
|
||||
|
||||
func TestApplySellerListingPriceUsesSellerTotalPrice(t *testing.T) {
|
||||
item := &ListingDTO{
|
||||
Price: 238,
|
||||
PriceCent: 23800,
|
||||
AssetSummary: map[string]any{
|
||||
"price_breakdown": map[string]any{
|
||||
"seller_total_price": 200,
|
||||
@@ -79,14 +79,14 @@ func TestApplySellerListingPriceUsesSellerTotalPrice(t *testing.T) {
|
||||
|
||||
applySellerListingPrice(item)
|
||||
|
||||
if item.Price != 200 {
|
||||
t.Fatalf("expected seller price 200, got %.2f", item.Price)
|
||||
if item.PriceCent != 20000 {
|
||||
t.Fatalf("expected seller price 20000, got %d", item.PriceCent)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplySellerListingPriceKeepsFallbackPrice(t *testing.T) {
|
||||
item := &ListingDTO{
|
||||
Price: 238,
|
||||
PriceCent: 23800,
|
||||
AssetSummary: map[string]any{
|
||||
"price_breakdown": map[string]any{
|
||||
"seller_total_price": 0,
|
||||
@@ -96,8 +96,8 @@ func TestApplySellerListingPriceKeepsFallbackPrice(t *testing.T) {
|
||||
|
||||
applySellerListingPrice(item)
|
||||
|
||||
if item.Price != 238 {
|
||||
t.Fatalf("expected fallback price 238, got %.2f", item.Price)
|
||||
if item.PriceCent != 23800 {
|
||||
t.Fatalf("expected fallback price 23800, got %d", item.PriceCent)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -185,11 +185,17 @@ func (r *Repository) Create(renterID uint64, req CreateRequest) (*OrderDTO, erro
|
||||
OwnerID: listing.OwnerID,
|
||||
RenterID: renterID,
|
||||
EstimatedDurationHours: rentHours,
|
||||
RentAmount: float64(pricing.RentAmountCent) / 100,
|
||||
RentAmountCent: pricing.RentAmountCent,
|
||||
OwnerRentAmount: float64(pricing.OwnerRentAmountCent) / 100,
|
||||
OwnerRentAmountCent: pricing.OwnerRentAmountCent,
|
||||
DepositAmount: paidDepositAmount,
|
||||
DepositAmountCent: int64(math.Round(paidDepositAmount * 100)),
|
||||
DepositOriginalAmount: depositOriginalAmount,
|
||||
DepositOriginalAmountCent: int64(math.Round(depositOriginalAmount * 100)),
|
||||
DepositWaivedAmount: waivedDepositAmount,
|
||||
DepositWaivedAmountCent: int64(math.Round(waivedDepositAmount * 100)),
|
||||
PlatformFee: float64(pricing.PlatformFeeCent) / 100,
|
||||
PlatformFeeCent: pricing.PlatformFeeCent,
|
||||
AccountSnapshot: snapshot,
|
||||
Status: "pending_payment",
|
||||
@@ -690,10 +696,10 @@ func (r *Repository) CounterCheckout(userID uint64, orderID uint64, req CounterC
|
||||
return nil, err
|
||||
}
|
||||
dto := toCheckoutDTOForUser(*checkout, userID, model.RentalOrder{
|
||||
OwnerID: userID,
|
||||
RentAmountCent: int64(math.Round(checkout.RentAmount * 100)),
|
||||
OwnerID: userID,
|
||||
RentAmountCent: int64(math.Round(checkout.RentAmount * 100)),
|
||||
OwnerRentAmountCent: int64(math.Round(checkout.OwnerRentAmount * 100)),
|
||||
DepositAmountCent: int64(math.Round(checkout.DepositAmount * 100)),
|
||||
DepositAmountCent: int64(math.Round(checkout.DepositAmount * 100)),
|
||||
})
|
||||
return &dto, nil
|
||||
}
|
||||
@@ -1244,21 +1250,30 @@ func buildCheckout(order model.RentalOrder, initiatedBy uint64, status string, c
|
||||
return model.OrderCheckout{}, err
|
||||
}
|
||||
return model.OrderCheckout{
|
||||
OrderID: order.ID,
|
||||
InitiatedBy: initiatedBy,
|
||||
Status: status,
|
||||
RentAmount: float64(settlement.ActualRentAmountCent) / 100,
|
||||
OwnerRentAmount: float64(settlement.OwnerRentIncomeCent) / 100,
|
||||
PlatformFee: float64(settlement.PlatformFeeCent) / 100,
|
||||
DepositAmount: depositAmountFromCent,
|
||||
ConsumableAmount: consumableAmount,
|
||||
CoinConsumedM: roundQuantity(coinConsumedM),
|
||||
OtherAmount: otherAmount,
|
||||
DepositDeductAmount: roundMoney(deductAmount),
|
||||
RenterRefundAmount: float64(settlement.RenterRefundCent) / 100,
|
||||
OwnerIncomeAmount: float64(settlement.OwnerIncomeCent) / 100,
|
||||
Content: content,
|
||||
EvidenceURLS: evidence,
|
||||
OrderID: order.ID,
|
||||
InitiatedBy: initiatedBy,
|
||||
Status: status,
|
||||
RentAmount: float64(settlement.ActualRentAmountCent) / 100,
|
||||
RentAmountCent: settlement.ActualRentAmountCent,
|
||||
OwnerRentAmount: float64(settlement.OwnerRentIncomeCent) / 100,
|
||||
OwnerRentAmountCent: settlement.OwnerRentIncomeCent,
|
||||
PlatformFee: float64(settlement.PlatformFeeCent) / 100,
|
||||
PlatformFeeCent: settlement.PlatformFeeCent,
|
||||
DepositAmount: depositAmountFromCent,
|
||||
DepositAmountCent: order.DepositAmountCent,
|
||||
ConsumableAmount: consumableAmount,
|
||||
ConsumableAmountCent: int64(math.Round(consumableAmount * 100)),
|
||||
CoinConsumedM: roundQuantity(coinConsumedM),
|
||||
OtherAmount: otherAmount,
|
||||
OtherAmountCent: int64(math.Round(otherAmount * 100)),
|
||||
DepositDeductAmount: roundMoney(deductAmount),
|
||||
DepositDeductAmountCent: settlement.DepositCompensationCent,
|
||||
RenterRefundAmount: float64(settlement.RenterRefundCent) / 100,
|
||||
RenterRefundAmountCent: settlement.RenterRefundCent,
|
||||
OwnerIncomeAmount: float64(settlement.OwnerIncomeCent) / 100,
|
||||
OwnerIncomeAmountCent: settlement.OwnerIncomeCent,
|
||||
Content: content,
|
||||
EvidenceURLS: evidence,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ import (
|
||||
|
||||
func TestCalculateCheckoutSettlementRefundsUnusedRent(t *testing.T) {
|
||||
order := model.RentalOrder{
|
||||
RentAmount: 383,
|
||||
OwnerRentAmount: 353,
|
||||
DepositAmount: 150,
|
||||
RentAmountCent: 38300,
|
||||
OwnerRentAmountCent: 35300,
|
||||
DepositAmountCent: 15000,
|
||||
AccountSnapshot: datatypes.JSON([]byte(`{
|
||||
"haf_coin_amount": 100000000,
|
||||
"asset_summary": {
|
||||
@@ -30,35 +30,35 @@ func TestCalculateCheckoutSettlementRefundsUnusedRent(t *testing.T) {
|
||||
settlement := calculateCheckoutSettlement(order, 7, 90, 0)
|
||||
|
||||
// 角精度:243.7 = roundMoney(236.7 + 7)
|
||||
if settlement.ActualRentAmount != 243.7 {
|
||||
t.Fatalf("ActualRentAmount = %.1f, want 243.7", settlement.ActualRentAmount)
|
||||
if float64(settlement.ActualRentAmountCent)/100 != 243.7 {
|
||||
t.Fatalf("ActualRentAmount = %.1f, want 243.7", float64(settlement.ActualRentAmountCent)/100)
|
||||
}
|
||||
// 角精度:216.7 = roundMoney(209.7 + 7) 卖家币价+消耗品
|
||||
if settlement.OwnerRentIncome != 216.7 {
|
||||
t.Fatalf("OwnerRentIncome = %.1f, want 216.7", settlement.OwnerRentIncome)
|
||||
if float64(settlement.OwnerRentIncomeCent)/100 != 216.7 {
|
||||
t.Fatalf("OwnerRentIncome = %.1f, want 216.7", float64(settlement.OwnerRentIncomeCent)/100)
|
||||
}
|
||||
// 角精度:27.0 = roundMoney(27) 平台费
|
||||
if settlement.PlatformFee != 27.0 {
|
||||
t.Fatalf("PlatformFee = %.1f, want 27.0", settlement.PlatformFee)
|
||||
if float64(settlement.PlatformFeeCent)/100 != 27.0 {
|
||||
t.Fatalf("PlatformFee = %.1f, want 27.0", float64(settlement.PlatformFeeCent)/100)
|
||||
}
|
||||
// 角精度:139.3 = roundMoney(383 - 243.7)
|
||||
if settlement.RentRefund != 139.3 {
|
||||
t.Fatalf("RentRefund = %.1f, want 139.3", settlement.RentRefund)
|
||||
if float64(settlement.RentRefundCent)/100 != 139.3 {
|
||||
t.Fatalf("RentRefund = %.1f, want 139.3", float64(settlement.RentRefundCent)/100)
|
||||
}
|
||||
if settlement.DepositRefund != 150 {
|
||||
t.Fatalf("DepositRefund = %.1f, want 150.0", settlement.DepositRefund)
|
||||
if float64(settlement.DepositRefundCent)/100 != 150 {
|
||||
t.Fatalf("DepositRefund = %.1f, want 150.0", float64(settlement.DepositRefundCent)/100)
|
||||
}
|
||||
// 角精度:289.3 = roundMoney(139.3 + 150)
|
||||
if settlement.RenterRefund != 289.3 {
|
||||
t.Fatalf("RenterRefund = %.1f, want 289.3", settlement.RenterRefund)
|
||||
if float64(settlement.RenterRefundCent)/100 != 289.3 {
|
||||
t.Fatalf("RenterRefund = %.1f, want 289.3", float64(settlement.RenterRefundCent)/100)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateCheckoutSettlementUsesBuyerAndSellerRatiosSeparately(t *testing.T) {
|
||||
order := model.RentalOrder{
|
||||
RentAmount: 383,
|
||||
OwnerRentAmount: 353,
|
||||
DepositAmount: 150,
|
||||
RentAmountCent: 38300,
|
||||
OwnerRentAmountCent: 35300,
|
||||
DepositAmountCent: 15000,
|
||||
AccountSnapshot: datatypes.JSON([]byte(`{
|
||||
"haf_coin_amount": 100000000,
|
||||
"asset_summary": {
|
||||
@@ -74,24 +74,24 @@ func TestCalculateCheckoutSettlementUsesBuyerAndSellerRatiosSeparately(t *testin
|
||||
settlement := calculateCheckoutSettlement(order, 0, 50, 0)
|
||||
|
||||
// 角精度:131.5 = roundMoney(131.5)
|
||||
if settlement.ActualRentAmount != 131.5 {
|
||||
t.Fatalf("租客侧实际租金 = %.1f, want 131.5", settlement.ActualRentAmount)
|
||||
if float64(settlement.ActualRentAmountCent)/100 != 131.5 {
|
||||
t.Fatalf("租客侧实际租金 = %.1f, want 131.5", float64(settlement.ActualRentAmountCent)/100)
|
||||
}
|
||||
// 角精度:116.5 = roundMoney(116.5)
|
||||
if settlement.OwnerRentIncome != 116.5 {
|
||||
t.Fatalf("卖家侧租金收入 = %.1f, want 116.5", settlement.OwnerRentIncome)
|
||||
if float64(settlement.OwnerRentIncomeCent)/100 != 116.5 {
|
||||
t.Fatalf("卖家侧租金收入 = %.1f, want 116.5", float64(settlement.OwnerRentIncomeCent)/100)
|
||||
}
|
||||
// 角精度:15.0 = roundMoney(15)
|
||||
if settlement.PlatformFee != 15.0 {
|
||||
t.Fatalf("平台差价 = %.1f, want 15.0", settlement.PlatformFee)
|
||||
if float64(settlement.PlatformFeeCent)/100 != 15.0 {
|
||||
t.Fatalf("平台差价 = %.1f, want 15.0", float64(settlement.PlatformFeeCent)/100)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateCheckoutSettlementAddsDepositCompensation(t *testing.T) {
|
||||
order := model.RentalOrder{
|
||||
RentAmount: 383,
|
||||
OwnerRentAmount: 353,
|
||||
DepositAmount: 150,
|
||||
RentAmountCent: 38300,
|
||||
OwnerRentAmountCent: 35300,
|
||||
DepositAmountCent: 15000,
|
||||
AccountSnapshot: datatypes.JSON([]byte(`{
|
||||
"haf_coin_amount": 100000000,
|
||||
"asset_summary": {
|
||||
@@ -106,20 +106,20 @@ func TestCalculateCheckoutSettlementAddsDepositCompensation(t *testing.T) {
|
||||
|
||||
settlement := calculateCheckoutSettlement(order, 120, 100, 30)
|
||||
|
||||
if settlement.ActualRentAmount != 383 {
|
||||
t.Fatalf("ActualRentAmount = %.2f, want 383.00", settlement.ActualRentAmount)
|
||||
if float64(settlement.ActualRentAmountCent)/100 != 383 {
|
||||
t.Fatalf("ActualRentAmount = %.2f, want 383.00", float64(settlement.ActualRentAmountCent)/100)
|
||||
}
|
||||
if settlement.OwnerRentIncome != 353 {
|
||||
t.Fatalf("OwnerRentIncome = %.2f, want 353.00", settlement.OwnerRentIncome)
|
||||
if float64(settlement.OwnerRentIncomeCent)/100 != 353 {
|
||||
t.Fatalf("OwnerRentIncome = %.2f, want 353.00", float64(settlement.OwnerRentIncomeCent)/100)
|
||||
}
|
||||
if settlement.DepositCompensation != 30 {
|
||||
t.Fatalf("DepositCompensation = %.2f, want 30.00", settlement.DepositCompensation)
|
||||
if float64(settlement.DepositCompensationCent)/100 != 30 {
|
||||
t.Fatalf("DepositCompensation = %.2f, want 30.00", float64(settlement.DepositCompensationCent)/100)
|
||||
}
|
||||
if settlement.OwnerIncome != 383 {
|
||||
t.Fatalf("OwnerIncome = %.2f, want 383.00", settlement.OwnerIncome)
|
||||
if float64(settlement.OwnerIncomeCent)/100 != 383 {
|
||||
t.Fatalf("OwnerIncome = %.2f, want 383.00", float64(settlement.OwnerIncomeCent)/100)
|
||||
}
|
||||
if settlement.RenterRefund != 120 {
|
||||
t.Fatalf("RenterRefund = %.2f, want 120.00", settlement.RenterRefund)
|
||||
if float64(settlement.RenterRefundCent)/100 != 120 {
|
||||
t.Fatalf("RenterRefund = %.2f, want 120.00", float64(settlement.RenterRefundCent)/100)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@ import (
|
||||
|
||||
func TestApplyEntryRoundsMoneyBeforeComparing(t *testing.T) {
|
||||
account := model.WalletAccount{
|
||||
UserID: 7,
|
||||
FrozenBalance: 606.41,
|
||||
UserID: 7,
|
||||
FrozenBalanceCent: 60641,
|
||||
}
|
||||
entry := Entry{
|
||||
UserID: 7,
|
||||
Direction: "out",
|
||||
Amount: 406.41 + 200.00,
|
||||
AmountCent: 60641,
|
||||
BalanceType: "frozen",
|
||||
}
|
||||
|
||||
@@ -26,20 +26,20 @@ func TestApplyEntryRoundsMoneyBeforeComparing(t *testing.T) {
|
||||
if balanceAfter != 0 {
|
||||
t.Fatalf("balanceAfter = %v, want 0", balanceAfter)
|
||||
}
|
||||
if account.FrozenBalance != 0 {
|
||||
t.Fatalf("FrozenBalance = %v, want 0", account.FrozenBalance)
|
||||
if account.FrozenBalanceCent != 0 {
|
||||
t.Fatalf("FrozenBalanceCent = %d, want 0", account.FrozenBalanceCent)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyEntryKeepsWalletMoneyAtJiaoPrecision(t *testing.T) {
|
||||
account := model.WalletAccount{
|
||||
UserID: 8,
|
||||
AvailableBalance: 0,
|
||||
UserID: 8,
|
||||
AvailableBalanceCent: 0,
|
||||
}
|
||||
entry := Entry{
|
||||
UserID: 8,
|
||||
Direction: "in",
|
||||
Amount: 2.30,
|
||||
AmountCent: 230,
|
||||
BalanceType: "available",
|
||||
}
|
||||
|
||||
@@ -47,11 +47,11 @@ func TestApplyEntryKeepsWalletMoneyAtJiaoPrecision(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("applyEntry() error = %v", err)
|
||||
}
|
||||
if balanceAfter != 2.3 {
|
||||
t.Fatalf("balanceAfter = %v, want 2.3", balanceAfter)
|
||||
if balanceAfter != 230 {
|
||||
t.Fatalf("balanceAfter = %d, want 230", balanceAfter)
|
||||
}
|
||||
if account.AvailableBalance != 2.3 {
|
||||
t.Fatalf("AvailableBalance = %v, want 2.3", account.AvailableBalance)
|
||||
if account.AvailableBalanceCent != 230 {
|
||||
t.Fatalf("AvailableBalanceCent = %d, want 230", account.AvailableBalanceCent)
|
||||
}
|
||||
|
||||
if rounded := roundWalletMoney(2.36); rounded != 2.4 {
|
||||
|
||||
@@ -58,8 +58,11 @@ func (r *Repository) Create(userID uint64, req CreateWithdrawalRequest) (*Withdr
|
||||
withdrawal := model.WithdrawalRequest{
|
||||
WithdrawNo: withdrawNo,
|
||||
UserID: userID,
|
||||
Amount: float64(req.AmountCent) / 100,
|
||||
AmountCent: req.AmountCent,
|
||||
Fee: float64(feeCent) / 100,
|
||||
FeeCent: feeCent,
|
||||
ActualAmount: float64(actualAmountCent) / 100,
|
||||
ActualAmountCent: actualAmountCent,
|
||||
PaymentAccountID: &req.PaymentAccountID,
|
||||
AccountType: paymentAccount.AccountType,
|
||||
|
||||
Reference in New Issue
Block a user