Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dunning): Prevent creating payment request when not overdue #2445

Merged
merged 2 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions app/services/payment_requests/create_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ def initialize(organization:, params:)
end

def call
# TODO: Return error unless premium license
unless License.premium? && organization.premium_integrations.include?("dunning")
return result.not_allowed_failure!(code: "premium_addon_feature_missing")
end

return result.not_found_failure!(resource: "customer") unless customer
return result.not_found_failure!(resource: "invoice") if invoices.empty?

# TODO: Return error if invoices are not overdue
if invoices.exists?(payment_overdue: false)
return result.not_allowed_failure!(code: "invoices_not_overdue")
end

ActiveRecord::Base.transaction do
# NOTE: Create payable group for the overdue invoices
Expand Down
11 changes: 0 additions & 11 deletions spec/requests/api/v1/payment_requests_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,6 @@
}
end

context "when customer is not found" do
let(:params) do
{external_customer_id: "unknown"}
end

it "returns a not found error" do
post_with_token(organization, "/api/v1/payment_requests", {payment_request: params})
expect(response).to have_http_status(:not_found)
end
end

it "delegates to PaymentRequests::CreateService", :aggregate_failures do
payment_request = create(:payment_request)
allow(PaymentRequests::CreateService).to receive(:call).and_return(
Expand Down
48 changes: 46 additions & 2 deletions spec/services/payment_requests/create_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
let(:organization) { membership.organization }
let(:customer) { create(:customer, organization:) }

let(:first_invoice) { create(:invoice, customer:) }
let(:second_invoice) { create(:invoice, customer:) }
let(:first_invoice) { create(:invoice, customer:, payment_overdue: true) }
let(:second_invoice) { create(:invoice, customer:, payment_overdue: true) }
let(:params) do
{
external_customer_id: customer.external_id,
Expand All @@ -19,7 +19,39 @@
}
end

around { |test| lago_premium!(&test) }

before { organization.update!(premium_integrations: ["dunning"]) }

describe "#call" do
context "when organization is not premium" do
before do
allow(License).to receive(:premium?).and_return(false)
end

it "returns not allowed failure", :aggregate_failures do
result = create_service.call

expect(result).not_to be_success
expect(result.error).to be_a(BaseService::MethodNotAllowedFailure)
expect(result.error.code).to eq("premium_addon_feature_missing")
end
end

context "when organization does not have premium dunning integration" do
before do
allow(organization).to receive(:premium_integrations).and_return([])
end

it "returns not allowed failure", :aggregate_failures do
result = create_service.call

expect(result).not_to be_success
expect(result.error).to be_a(BaseService::MethodNotAllowedFailure)
expect(result.error.code).to eq("premium_addon_feature_missing")
end
end

context "when customer does not exist" do
before { params[:external_customer_id] = "non-existing-id" }

Expand All @@ -44,6 +76,18 @@
end
end

context "when invoices are not overdue" do
before { first_invoice.update!(payment_overdue: false) }

it "returns not allowed failure", :aggregate_failures do
result = create_service.call

expect(result).not_to be_success
expect(result.error).to be_a(BaseService::MethodNotAllowedFailure)
expect(result.error.code).to eq("invoices_not_overdue")
end
end

it "creates a payable group for the customer" do
expect { create_service.call }.to change { customer.payable_groups.count }.by(1)
end
Expand Down