Skip to content

Commit

Permalink
feat(dunning): Create dunning thresholds when creating the campaign
Browse files Browse the repository at this point in the history
  • Loading branch information
rsempe committed Oct 11, 2024
1 parent ec283dc commit eb9e097
Show file tree
Hide file tree
Showing 14 changed files with 303 additions and 17 deletions.
12 changes: 12 additions & 0 deletions app/graphql/types/dunning_campaign_thresholds/create_input.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module Types
module DunningCampaignThresholds
class CreateInput < Types::BaseInputObject
graphql_name "CreateDunningCampaignThresholdInput"

argument :amount_cents, GraphQL::Types::BigInt, required: true
argument :currency, Types::CurrencyEnum, required: true
end
end
end
12 changes: 12 additions & 0 deletions app/graphql/types/dunning_campaign_thresholds/object.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module Types
module DunningCampaignThresholds
class Object < Types::BaseObject
graphql_name "DunningCampaignThreshold"

field :amount_cents, Integer, null: false
field :currency, String, null: false
end
end
end
1 change: 1 addition & 0 deletions app/graphql/types/dunning_campaigns/create_input.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class CreateInput < Types::BaseInputObject
argument :days_between_attempts, Integer, required: true
argument :max_attempts, Integer, required: true
argument :name, String, required: true
argument :thresholds, [Types::DunningCampaignThresholds::CreateInput], required: true

argument :description, String, required: false
end
Expand Down
1 change: 1 addition & 0 deletions app/graphql/types/dunning_campaigns/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Object < Types::BaseObject
field :days_between_attempts, Integer, null: false
field :max_attempts, Integer, null: false
field :name, String, null: false
field :thresholds, [Types::DunningCampaignThresholds::Object], null: false

field :description, String, null: true

Expand Down
1 change: 1 addition & 0 deletions app/models/dunning_campaign.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class DunningCampaign < ApplicationRecord

belongs_to :organization
has_many :thresholds, class_name: "DunningCampaignThreshold", dependent: :destroy
accepts_nested_attributes_for :thresholds

validates :name, presence: true
validates :days_between_attempts, numericality: {greater_than: 0}
Expand Down
30 changes: 18 additions & 12 deletions app/services/dunning_campaigns/create_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,24 @@ def initialize(organization:, params:)
end

def call
dunning_campaign = organization.dunning_campaigns.new(
applied_to_organization: params[:applied_to_organization],
code: params[:code],
days_between_attempts: params[:days_between_attempts],
max_attempts: params[:max_attempts],
name: params[:name],
description: params[:description]
)

dunning_campaign.save!

result.dunning_campaign = dunning_campaign
# TODO: Restrict to dunning premium add-on

ActiveRecord::Base.transaction do
dunning_campaign = organization.dunning_campaigns.create!(
applied_to_organization: params[:applied_to_organization],
code: params[:code],
days_between_attempts: params[:days_between_attempts],
max_attempts: params[:max_attempts],
name: params[:name],
description: params[:description],
thresholds_attributes: params[:thresholds].map(&:to_h)
)

# TODO: If the dunning campaign is applied to the organization, we need to remove the flag from all other dunning campaigns.

result.dunning_campaign = dunning_campaign
end

result
rescue ActiveRecord::RecordInvalid => e
result.record_validation_failure!(record: e.record)
Expand Down
14 changes: 13 additions & 1 deletion schema.graphql

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

144 changes: 143 additions & 1 deletion schema.json

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

28 changes: 25 additions & 3 deletions spec/graphql/mutations/dunning_campaigns/create_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,31 @@
description: "Dunning campaign description",
maxAttempts: 3,
daysBetweenAttempts: 1,
appliedToOrganization: false
appliedToOrganization: false,
thresholds: [
{
amountCents: 10000,
currency: "EUR"
}
]
}
end

let(:mutation) do
<<-GQL
mutation($input: CreateDunningCampaignInput!) {
createDunningCampaign(input: $input) {
id name code description maxAttempts daysBetweenAttempts appliedToOrganization
id
name
code
description
maxAttempts
daysBetweenAttempts
appliedToOrganization
thresholds {
amountCents
currency
}
}
}
GQL
Expand All @@ -46,7 +62,13 @@
"description" => "Dunning campaign description",
"maxAttempts" => 3,
"daysBetweenAttempts" => 1,
"appliedToOrganization" => false
"appliedToOrganization" => false,
"thresholds" => [
{
"amountCents" => 10000,
"currency" => "EUR"
}
]
)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe Types::DunningCampaignThresholds::CreateInput do
subject { described_class }

it { is_expected.to accept_argument(:amount_cents).of_type("BigInt!") }
it { is_expected.to accept_argument(:currency).of_type("CurrencyEnum!") }
end
10 changes: 10 additions & 0 deletions spec/graphql/types/dunning_campaign_thresholds/object_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe Types::DunningCampaignThresholds::Object do
subject { described_class }

it { is_expected.to have_field(:amount_cents).of_type("Int!") }
it { is_expected.to have_field(:currency).of_type("String!") }
end
1 change: 1 addition & 0 deletions spec/graphql/types/dunning_campaigns/create_input_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
it { is_expected.to accept_argument(:days_between_attempts).of_type('Int!') }
it { is_expected.to accept_argument(:max_attempts).of_type('Int!') }
it { is_expected.to accept_argument(:name).of_type('String!') }
it { is_expected.to accept_argument(:thresholds).of_type('[CreateDunningCampaignThresholdInput!]!') }

it { is_expected.to accept_argument(:description).of_type('String') }
end
1 change: 1 addition & 0 deletions spec/graphql/types/dunning_campaigns/object_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
it { is_expected.to have_field(:days_between_attempts).of_type("Int!") }
it { is_expected.to have_field(:max_attempts).of_type("Int!") }
it { is_expected.to have_field(:name).of_type("String!") }
it { is_expected.to have_field(:thresholds).of_type("[Types::DunningCampaignThresholds::Object!]!") }

it { is_expected.to have_field(:description).of_type("String") }

Expand Down
Loading

0 comments on commit eb9e097

Please sign in to comment.