Skip to content

Commit

Permalink
added Reverse payments functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
elraphty committed Nov 11, 2024
1 parent d7b8012 commit 59e3d25
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 15 deletions.
1 change: 1 addition & 0 deletions db/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,5 @@ type Database interface {
SetPaymentAsComplete(tag string) bool
SetPaymentStatusByBountyId(bountyId uint, tagResult V2TagRes) bool
GetWorkspacePendingPayments(workspace_uuid string) []NewPaymentHistory
ProcessReversePayments(paymentId uint) error
}
91 changes: 91 additions & 0 deletions db/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -683,3 +683,94 @@ func (db database) GetFeaturePhasesBountiesCount(bountyType string, phaseUuid st
query.Count(&count)
return count
}

func (db database) ProcessReversePayments(paymentId uint) error {
// Start db transaction
tx := db.db.Begin()

var err error

defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()

if err = tx.Error; err != nil {
return err
}

// Get payment history and update budget
paymentHistory := NewPaymentHistory{}
tx.Model(&NewPaymentHistory{}).Where("id = ?", paymentId).Find(&paymentHistory)

bounty_id := paymentHistory.BountyId

if bounty_id == 0 {
tx.Rollback()
return errors.New("not a valid bounty payment")
}

if paymentHistory.WorkspaceUuid != "" && paymentHistory.Amount != 0 {
paymentHistory.PaymentStatus = PaymentFailed

workspace_uuid := paymentHistory.WorkspaceUuid

// check that the sum of budget withdrawals and payments is not greater than deposits

var depositAmount uint
tx.Model(&NewPaymentHistory{}).Where("workspace_uuid = ?", workspace_uuid).Where("status = ?", true).Where("payment_type = ?", "deposit").Select("SUM(amount)").Row().Scan(&depositAmount)

var withdrawalAmount uint
tx.Model(&NewPaymentHistory{}).Where("workspace_uuid = ?", workspace_uuid).Where("status = ?", true).Where("payment_type != ?", "deposit").Select("SUM(amount)").Row().Scan(&withdrawalAmount)

if withdrawalAmount > depositAmount {
tx.Rollback()
return errors.New("cannot perform this reversal")
}

// Update payment history
if err = tx.Where("id = ?", paymentId).Where("workspace_uuid = ?", workspace_uuid).Updates(paymentHistory).Error; err != nil {
tx.Rollback()
}

// get Workspace budget and add payment to total budget
workspaceBudget := NewBountyBudget{}
tx.Model(&NewBountyBudget{}).Where("workspace_uuid = ?", workspace_uuid).Find(&workspaceBudget)

// roleback transaction if there is no workspace budget
if workspaceBudget.WorkspaceUuid == "" {
tx.Rollback()
} else {
totalBudget := workspaceBudget.TotalBudget
workspaceBudget.TotalBudget = totalBudget + paymentHistory.Amount

if err = tx.Model(&NewBountyBudget{}).Where("workspace_uuid = ?", workspaceBudget.WorkspaceUuid).Updates(map[string]interface{}{
"total_budget": workspaceBudget.TotalBudget,
}).Error; err != nil {
tx.Rollback()
}
}
}

var bounty NewBounty

// Get bounty
if err = tx.Model(&NewBounty{}).Where("id = ?", bounty_id).Find(&bounty).Error; err != nil {
tx.Rollback()
}

bounty.PaymentPending = false
bounty.Paid = false
bounty.PaymentFailed = true

if err = tx.Model(&NewBounty{}).Where("id = ?", bounty_id).Updates(map[string]interface{}{
"paid": bounty.Paid,
"payment_pending": bounty.PaymentPending,
"payment_failed": bounty.PaymentFailed,
}).Error; err != nil {
tx.Rollback()
}

return tx.Commit().Error
}
10 changes: 4 additions & 6 deletions handlers/bounty.go
Original file line number Diff line number Diff line change
Expand Up @@ -1002,14 +1002,12 @@ func (h *bountyHandler) UpdateBountyPaymentStatus(w http.ResponseWriter, r *http
json.NewEncoder(w).Encode(msg)
return
} else if tagResult.Status == db.PaymentFailed {
// Handle failed payments
h.db.SetPaymentStatusByBountyId(bounty.ID, tagResult)

bounty.Paid = false
bounty.PaymentPending = false
bounty.PaymentFailed = true
err = h.db.ProcessReversePayments(payment.ID)

h.db.UpdateBounty(bounty)
if err != nil {
log.Printf("Could not reverse bounty payment : Bounty ID - %d, Payment ID - %d, Error - %s", bounty.ID, payment.ID, err)
}

w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(msg)
Expand Down
15 changes: 6 additions & 9 deletions handlers/v2_payments_cron.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func InitV2PaymentsCron() {
if tagResult.Status == db.PaymentComplete {
db.DB.SetPaymentAsComplete(tag)

bounty := db.DB.GetBounty(payment.ID)
bounty := db.DB.GetBounty(payment.BountyId)

if bounty.ID > 0 {
now := time.Now()
Expand All @@ -37,16 +37,13 @@ func InitV2PaymentsCron() {
}
} else if tagResult.Status == db.PaymentFailed {
// Handle failed payments
bounty := db.DB.GetBounty(payment.ID)
bounty := db.DB.GetBounty(payment.BountyId)

if bounty.ID > 0 {
db.DB.SetPaymentStatusByBountyId(bounty.ID, tagResult)

bounty.Paid = false
bounty.PaymentPending = false
bounty.PaymentFailed = true

db.DB.UpdateBounty(bounty)
err := db.DB.ProcessReversePayments(payment.ID)
if err != nil {
log.Printf("Could not reverse bounty payment : Bounty ID - %d, Payment ID - %d, Error - %s", bounty.ID, payment.ID, err)
}
}
}
}
Expand Down
46 changes: 46 additions & 0 deletions mocks/Database.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 59e3d25

Please sign in to comment.