Skip to content

Commit

Permalink
Payout#issue creates Payment for Trust#beneficiaries
Browse files Browse the repository at this point in the history
This sketches in the `Payout#issue` method's line-of-action, which is to
iterate through the `Payout#trust#beneficiaries` and add a `Payment` to the set
of `Payout#payments` for the per-beneficiary amount.

That said, there's a few outstanding questions we'll probably want to
add some tests to interrogate, especially around:

1. What happens if the method is ran twice with the same data?
2. What about if the set of `Payout#trust#beneficiaries` is changed
   between calls to `Payout#issue`?
3. What happens when the `Payout#payout_amount` doesn't divide evenly
   between the `Payout#beneficiaries?
  • Loading branch information
zspencer committed Jan 29, 2024
1 parent 059f854 commit 9a1e213
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 3 deletions.
2 changes: 2 additions & 0 deletions app/furniture/tobias.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class Tobias
end
9 changes: 9 additions & 0 deletions app/furniture/tobias/beneficiary.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Tobias
class Beneficiary < Record
self.table_name = "tobias_beneficiaries"

belongs_to :trust

has_many :payments
end
end
7 changes: 7 additions & 0 deletions app/furniture/tobias/payment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Tobias
class Payment < Record
self.table_name = "tobias_payments"

monetize :amount_cents
end
end
19 changes: 19 additions & 0 deletions app/furniture/tobias/payout.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class Tobias
class Payout < ApplicationRecord
self.table_name = "tobias_payouts"

belongs_to :trust
has_many :beneficiaries, through: :trust
has_many :payments

monetize :payout_amount_cents

def issue
per_beneficiary_amount = (payout_amount / beneficiaries.count)
beneficiaries.each do |beneficiary|

payments.create_with(amount: per_beneficiary_amount).find_or_create_by(beneficiary_id: beneficiary.id)
end
end
end
end
9 changes: 9 additions & 0 deletions app/furniture/tobias/record.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Tobias
class Record < ApplicationRecord
self.abstract_class = true

def self.model_name
@_model_name ||= ActiveModel::Name.new(self, ::Tobias)
end
end
end
8 changes: 8 additions & 0 deletions app/furniture/tobias/trust.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class Tobias
class Trust < Record
self.table_name = "tobias_trusts"

has_many :beneficiaries

end
end
27 changes: 27 additions & 0 deletions db/migrate/20240127063826_create_tobias_payouts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class CreateTobiasPayouts < ActiveRecord::Migration[7.1]
def change
create_table :tobias_trusts, id: :uuid do |t|
t.timestamps
end

create_table :tobias_beneficiaries, id: :uuid do |t|
t.references :trust, type: :uuid, foreign_key: {to_table: :tobias_trusts}

t.timestamps
end

create_table :tobias_payouts, id: :uuid do |t|
t.monetize :payout_amount
t.references :trust, type: :uuid, foreign_key: {to_table: :tobias_trusts}
t.timestamps
end

create_table :tobias_payments, id: :uuid do |t|
t.references :payout, type: :uuid, foreign_key: {to_table: :tobias_payouts}
t.references :beneficiary, type: :uuid, foreign_key: {to_table: :tobias_beneficiaries}
t.monetize :amount

t.timestamps
end
end
end
38 changes: 37 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.1].define(version: 2024_01_20_034325) do
ActiveRecord::Schema[7.1].define(version: 2024_01_27_063826) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
Expand Down Expand Up @@ -295,6 +295,38 @@
t.index ["slug", "client_id"], name: "index_spaces_on_slug_and_client_id", unique: true
end

create_table "tobias_beneficiaries", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.uuid "trust_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["trust_id"], name: "index_tobias_beneficiaries_on_trust_id"
end

create_table "tobias_payments", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.uuid "payout_id"
t.uuid "beneficiary_id"
t.integer "amount_cents", default: 0, null: false
t.string "amount_currency", default: "USD", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["beneficiary_id"], name: "index_tobias_payments_on_beneficiary_id"
t.index ["payout_id"], name: "index_tobias_payments_on_payout_id"
end

create_table "tobias_payouts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.integer "payout_amount_cents", default: 0, null: false
t.string "payout_amount_currency", default: "USD", null: false
t.uuid "trust_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["trust_id"], name: "index_tobias_payouts_on_trust_id"
end

create_table "tobias_trusts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

create_table "utility_hookups", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.uuid "space_id"
t.string "name", null: false
Expand Down Expand Up @@ -326,4 +358,8 @@
add_foreign_key "rooms", "media", column: "hero_image_id"
add_foreign_key "space_agreements", "spaces"
add_foreign_key "spaces", "rooms", column: "entrance_id"
add_foreign_key "tobias_beneficiaries", "tobias_trusts", column: "trust_id"
add_foreign_key "tobias_payments", "tobias_beneficiaries", column: "beneficiary_id"
add_foreign_key "tobias_payments", "tobias_payouts", column: "payout_id"
add_foreign_key "tobias_payouts", "tobias_trusts", column: "trust_id"
end
5 changes: 5 additions & 0 deletions spec/tobias/factories/beneficiary_factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FactoryBot.define do
factory :tobias_beneficiary, class: "Tobias::Beneficiary" do

end
end
7 changes: 7 additions & 0 deletions spec/tobias/factories/payout_factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require_relative "trust_factory"

FactoryBot.define do
factory :tobias_payout, class: "Tobias::Payout" do
association(:trust, factory: :tobias_trust)
end
end
5 changes: 5 additions & 0 deletions spec/tobias/factories/trust_factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FactoryBot.define do
factory :tobias_trust, class: "Tobias::Trust" do

end
end
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
require "rails_helper"
require_relative "factories/payout_factory"
require_relative "factories/beneficiary_factory"

RSpec.describe Tobias::Payout do
describe "#issue" do
it "issues a Payment to each Beneficiary for their share of the #payout_amount" do
payout = create(:tobias_payout, payout_amount_cents: 150_00)

beneficiaries = create_list(10, :tobias_beneficiary, trust: payout.trust)
beneficiaries = create_list(:tobias_beneficiary, 10, trust: payout.trust)

payout.issue

beneficiaries.each do |beneficiary|
expect(beneficiary.payments).to exist(amount_cents: 15)
expect(beneficiary.payments).to exist(amount_cents: 15_00)
end
end
end
Expand Down

0 comments on commit 9a1e213

Please sign in to comment.