From b9d4fea143de4cec529e543464cce82031d047d2 Mon Sep 17 00:00:00 2001 From: Eric Schultz Date: Mon, 14 Jul 2025 14:06:27 -0500 Subject: [PATCH 1/5] Add Refund#amount --- app/models/refund.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/refund.rb b/app/models/refund.rb index b6bd67336..e71b89aed 100644 --- a/app/models/refund.rb +++ b/app/models/refund.rb @@ -27,6 +27,8 @@ class Refund < ApplicationRecord has_many :manual_balance_adjustments, as: :entity + validates :amount, presence: true, numericality: {only_integer: true, greater_than: 0} + def original_payment charge&.payment end From 347109c28363bcad7bf041d2e2a428899ffc1d0d Mon Sep 17 00:00:00 2001 From: Eric Schultz Date: Mon, 14 Jul 2025 14:14:50 -0500 Subject: [PATCH 2/5] Add validations for `Refund` --- app/models/refund.rb | 4 ++-- spec/models/refund_spec.rb | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/models/refund.rb b/app/models/refund.rb index e71b89aed..23b7fe9a8 100644 --- a/app/models/refund.rb +++ b/app/models/refund.rb @@ -15,8 +15,8 @@ class Refund < ApplicationRecord attr_accessor :failure_message - belongs_to :charge - belongs_to :payment + belongs_to :charge, optional: false + belongs_to :payment, optional: false has_one :subtransaction_payment, through: :payment has_one :misc_refund_info has_one :nonprofit, through: :charge diff --git a/spec/models/refund_spec.rb b/spec/models/refund_spec.rb index ddbf73324..1dc318557 100644 --- a/spec/models/refund_spec.rb +++ b/spec/models/refund_spec.rb @@ -2,8 +2,8 @@ require "rails_helper" RSpec.describe Refund, type: :model do - it { is_expected.to belong_to(:charge) } - it { is_expected.to belong_to(:payment) } + it { is_expected.to belong_to(:charge).required(true) } + it { is_expected.to belong_to(:payment).required(true) } it { is_expected.to have_one(:subtransaction_payment).through(:payment) } it { is_expected.to have_one(:misc_refund_info) } @@ -11,6 +11,9 @@ it { is_expected.to have_one(:supporter).through(:charge) } it { is_expected.to have_many(:manual_balance_adjustments) } + it { is_expected.to validate_presence_of(:amount) } + it { is_expected.to validate_numericality_of(:amount).only_integer.is_greater_than(0) } + describe "#from_donation?" do it "is true when refund is associated with a donation" do expect(build(:refund, :from_donation).from_donation?).to eq true From 91863a9b82d168766819591e9fd51a4dd9959d02 Mon Sep 17 00:00:00 2001 From: Eric Schultz Date: Mon, 14 Jul 2025 12:00:22 -0500 Subject: [PATCH 3/5] Add spec for Activity --- app/models/activity.rb | 7 ++++--- spec/models/activity_spec.rb | 13 +++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 spec/models/activity_spec.rb diff --git a/app/models/activity.rb b/app/models/activity.rb index 88c34b554..9ce32b1dd 100644 --- a/app/models/activity.rb +++ b/app/models/activity.rb @@ -1,6 +1,7 @@ # License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later class Activity < ApplicationRecord - belongs_to :attachment, polymorphic: true - belongs_to :supporter - belongs_to :nonprofit + belongs_to :attachment, polymorphic: true, optional: false + belongs_to :supporter, optional: false + belongs_to :nonprofit, optional: false + belongs_to :user, optional: true end diff --git a/spec/models/activity_spec.rb b/spec/models/activity_spec.rb new file mode 100644 index 000000000..b58028acc --- /dev/null +++ b/spec/models/activity_spec.rb @@ -0,0 +1,13 @@ +# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later +require "rails_helper" +RSpec.describe Activity, type: :model do + context "validation" do + it { is_expected.to belong_to(:attachment).required(true) } + it { is_expected.to belong_to(:supporter).required(true) } + + it { is_expected.to belong_to(:nonprofit).required(true) } + + it { is_expected.to belong_to(:user).required(false) } + + end +end From a214ff195ec27a9e2d1e8cd7bb74414ceb4e517a Mon Sep 17 00:00:00 2001 From: Eric Schultz Date: Mon, 14 Jul 2025 15:43:53 -0500 Subject: [PATCH 4/5] Some rearranging of InsertRefunds to fix tests --- app/legacy_lib/insert_refunds.rb | 38 +++++++++++++++----------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/app/legacy_lib/insert_refunds.rb b/app/legacy_lib/insert_refunds.rb index eb0fadfb1..ab1cf4263 100644 --- a/app/legacy_lib/insert_refunds.rb +++ b/app/legacy_lib/insert_refunds.rb @@ -29,36 +29,34 @@ def self.modern_refund(charge, h) results = InsertRefunds.perform_stripe_refund(nonprofit_id: charge["nonprofit_id"], refund_data: refund_data, charge_date: charge["created_at"]) Refund.transaction do - refund = Refund.create!({amount: h["amount"], - comment: h["comment"], - reason: h["reason"], - stripe_refund_id: results[:stripe_refund].id, - charge_id: charge["id"]}) - - refund.create_misc_refund_info(is_modern: true, stripe_application_fee_refund_id: results[:stripe_app_fee_refund]&.id) - - gross = -h["amount"] - fees = (results[:stripe_app_fee_refund] && results[:stripe_app_fee_refund].amount) || 0 - net = gross + fees + gross_amount = -h["amount"] + fee_total = results[:stripe_app_fee_refund]&.amount || 0 + net_amount = gross_amount + fee_total + date = Time.current - # Create a corresponding./run negative payment record payment = Payment.create!({ - gross_amount: gross, - fee_total: fees, - net_amount: net, + gross_amount:, + fee_total:, + net_amount:, kind: "Refund", towards: original_payment.towards, - date: refund.created_at, + date:, nonprofit_id: charge["nonprofit_id"], supporter_id: charge["supporter_id"] }) - InsertActivities.for_refunds([payment.id]) + refund = Refund.create!( + amount: h["amount"], + comment: h["comment"], + reason: h["reason"], + stripe_refund_id: results[:stripe_refund].id, + charge_id: charge["id"], + payment: payment + ) - # Update the refund to have the above payment_id - refund.payment = payment - refund.save! + refund.create_misc_refund_info(is_modern: true, stripe_application_fee_refund_id: results[:stripe_app_fee_refund]&.id) + InsertActivities.for_refunds([payment.id]) # Update original payment to increment its refund_total for any future refund attempts original_payment.refund_total += h["amount"].to_i original_payment.save! From a487b86aedfda032189799c167a1849d85f4085c Mon Sep 17 00:00:00 2001 From: Eric Schultz Date: Tue, 15 Jul 2025 19:20:22 -0500 Subject: [PATCH 5/5] Add the user belong_to relationship on Refund --- app/models/refund.rb | 1 + spec/models/refund_spec.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/app/models/refund.rb b/app/models/refund.rb index 23b7fe9a8..923a4e695 100644 --- a/app/models/refund.rb +++ b/app/models/refund.rb @@ -17,6 +17,7 @@ class Refund < ApplicationRecord belongs_to :charge, optional: false belongs_to :payment, optional: false + belongs_to :user, optional: true has_one :subtransaction_payment, through: :payment has_one :misc_refund_info has_one :nonprofit, through: :charge diff --git a/spec/models/refund_spec.rb b/spec/models/refund_spec.rb index 1dc318557..b19918522 100644 --- a/spec/models/refund_spec.rb +++ b/spec/models/refund_spec.rb @@ -4,6 +4,7 @@ RSpec.describe Refund, type: :model do it { is_expected.to belong_to(:charge).required(true) } it { is_expected.to belong_to(:payment).required(true) } + it { is_expected.to belong_to(:user).required(false) } it { is_expected.to have_one(:subtransaction_payment).through(:payment) } it { is_expected.to have_one(:misc_refund_info) }