diff --git a/app/controllers/internal_api/v1/invoices/view_controller.rb b/app/controllers/internal_api/v1/invoices/view_controller.rb index ecc5946d34..137d966c8e 100644 --- a/app/controllers/internal_api/v1/invoices/view_controller.rb +++ b/app/controllers/internal_api/v1/invoices/view_controller.rb @@ -9,7 +9,7 @@ class InternalApi::V1::Invoices::ViewController < InternalApi::V1::ApplicationCo def show invoice.viewed! if invoice.sent? Invoices::EventTrackerService.new("view", invoice, params).process - render :show, locals: { invoice:, stripe_connected_account: } + render :show, locals: { invoice:, stripe_connected_account:, bank_account: invoice.company.bank_account } end private diff --git a/app/controllers/internal_api/v1/payment_settings_controller.rb b/app/controllers/internal_api/v1/payment_settings_controller.rb index 0d79d2ecd7..1a18b20858 100644 --- a/app/controllers/internal_api/v1/payment_settings_controller.rb +++ b/app/controllers/internal_api/v1/payment_settings_controller.rb @@ -4,13 +4,13 @@ class InternalApi::V1::PaymentSettingsController < InternalApi::V1::ApplicationC after_action :save_stripe_settings, only: :index def index - authorize :index, policy_class: PaymentSettingsPolicy + authorize current_company, policy_class: PaymentSettingsPolicy - render :index, locals: { stripe_connected_account: } + render :index, locals: { stripe_connected_account:, bank_account: current_company.bank_account } end def connect_stripe - authorize :connect_stripe, policy_class: PaymentSettingsPolicy + authorize current_company, policy_class: PaymentSettingsPolicy StripeConnectedAccount.create!({ company: current_company }) if stripe_connected_account.nil? @@ -18,7 +18,7 @@ def connect_stripe end def destroy - authorize :destroy, policy_class: PaymentSettingsPolicy + authorize current_company, policy_class: PaymentSettingsPolicy if stripe_connected_account.destroy render json: { notice: "Stripe connection disconnected" }, status: :ok @@ -27,6 +27,17 @@ def destroy end end + def update_bank_account + authorize current_company, policy_class: PaymentSettingsPolicy + + @bank_account = current_company.bank_account || current_company.build_bank_account + if @bank_account.update(bank_account_params) + render json: { notice: "Bank account details updated successfully" }, status: :ok + else + render json: { error: @bank_account.errors.full_messages }, status: :unprocessable_entity + end + end + private def stripe_connected_account @@ -36,4 +47,8 @@ def stripe_connected_account def save_stripe_settings PaymentProviders::CreateStripeProviderService.process(current_company) end + + def bank_account_params + params.require(:bank_account).permit(:routing_number, :account_number, :account_type, :bank_name) + end end diff --git a/app/controllers/payment_settings_controller.rb b/app/controllers/payment_settings_controller.rb index 41a28005cf..27b9f43592 100644 --- a/app/controllers/payment_settings_controller.rb +++ b/app/controllers/payment_settings_controller.rb @@ -2,11 +2,11 @@ class PaymentSettingsController < ApplicationController def index - authorize :index, policy_class: PaymentSettingsPolicy + authorize current_company, policy_class: PaymentSettingsPolicy end def refresh_stripe_connect - authorize :refresh_stripe_connect, policy_class: PaymentSettingsPolicy + authorize current_company, policy_class: PaymentSettingsPolicy redirect_to stripe_connected_account.url, allow_other_host: true end diff --git a/app/models/bank_account.rb b/app/models/bank_account.rb new file mode 100644 index 0000000000..11b092377f --- /dev/null +++ b/app/models/bank_account.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class BankAccount < ApplicationRecord + belongs_to :company + + validates :routing_number, presence: true + validates :account_number, presence: true + validates :account_type, presence: true, inclusion: { in: %w[checking savings] } + validates :bank_name, presence: true +end diff --git a/app/models/company.rb b/app/models/company.rb index 07eb91e3f6..4706a4abe7 100644 --- a/app/models/company.rb +++ b/app/models/company.rb @@ -31,6 +31,7 @@ class Company < ApplicationRecord has_many :invoices has_many :payments, through: :invoices has_one :stripe_connected_account, dependent: :destroy + has_one :bank_account, dependent: :destroy has_many :payments_providers, dependent: :destroy has_many :addresses, as: :addressable, dependent: :destroy has_many :devices, dependent: :destroy diff --git a/app/policies/payment_settings_policy.rb b/app/policies/payment_settings_policy.rb index 508aaf33a8..3cb35c78e1 100644 --- a/app/policies/payment_settings_policy.rb +++ b/app/policies/payment_settings_policy.rb @@ -2,18 +2,31 @@ class PaymentSettingsPolicy < ApplicationPolicy def index? - user_owner_role? || user_admin_role? + has_owner_or_admin_role?(record) end def connect_stripe? - user_owner_role? || user_admin_role? + has_owner_or_admin_role?(record) end def destroy? - user_owner_role? || user_admin_role? + has_owner_or_admin_role?(record) end def refresh_stripe_connect? - user_owner_role? || user_admin_role? + has_owner_or_admin_role?(record) end + + def update_bank_account? + has_owner_or_admin_role?(record) + end + + private + + def has_owner_or_admin_role?(company) + user.has_any_role?( + { name: :admin, resource: company }, + { name: :owner, resource: company } + ) + end end diff --git a/app/services/invoice_payment/pdf_generation.rb b/app/services/invoice_payment/pdf_generation.rb index 3bae8dd76d..9bbe106333 100644 --- a/app/services/invoice_payment/pdf_generation.rb +++ b/app/services/invoice_payment/pdf_generation.rb @@ -9,6 +9,7 @@ def initialize(invoice, company_logo, root_url, filepath = nil) @base_currency = invoice.company.base_currency @root_url = root_url @filepath = filepath + @bank_account = invoice.company.bank_account end def process @@ -24,7 +25,8 @@ def process client: @invoice.client, invoice_line_items: invoice_data[:invoice_line_items], sub_total: format_currency(invoice_data[:sub_total]), - total: format_currency(invoice_data[:total]) + total: format_currency(invoice_data[:total]), + bank_account: @bank_account } Pdf::HtmlGenerator.new( diff --git a/app/views/internal_api/v1/invoices/_bank_account.json.jbuilder b/app/views/internal_api/v1/invoices/_bank_account.json.jbuilder new file mode 100644 index 0000000000..733072e463 --- /dev/null +++ b/app/views/internal_api/v1/invoices/_bank_account.json.jbuilder @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +json.bank_name bank_account&.bank_name +json.account_type bank_account&.account_type&.capitalize +json.routing_number bank_account&.routing_number +json.account_number bank_account&.account_number diff --git a/app/views/internal_api/v1/invoices/view/show.json.jbuilder b/app/views/internal_api/v1/invoices/view/show.json.jbuilder index 5d2106b80e..70312d4dfa 100644 --- a/app/views/internal_api/v1/invoices/view/show.json.jbuilder +++ b/app/views/internal_api/v1/invoices/view/show.json.jbuilder @@ -11,3 +11,6 @@ end json.client do json.partial! "internal_api/v1/partial/client", locals: { client: invoice.client } end +json.bank_account do + json.partial! "internal_api/v1/invoices/bank_account", bank_account: +end diff --git a/app/views/internal_api/v1/payment_settings/index.json.jbuilder b/app/views/internal_api/v1/payment_settings/index.json.jbuilder index 605ec49271..4d58245eaa 100644 --- a/app/views/internal_api/v1/payment_settings/index.json.jbuilder +++ b/app/views/internal_api/v1/payment_settings/index.json.jbuilder @@ -10,4 +10,7 @@ json.providers do json.paypal do json.connected false end + json.bank_account do + json.partial! "internal_api/v1/invoices/bank_account", bank_account: + end end diff --git a/app/views/pdfs/invoices.html.erb b/app/views/pdfs/invoices.html.erb index 0a4a7266ae..b7a300d3a7 100644 --- a/app/views/pdfs/invoices.html.erb +++ b/app/views/pdfs/invoices.html.erb @@ -137,4 +137,13 @@ html { + <% if bank_account %> +
Bank Name: <%= bank_account[:bank_name] %>
+Account Type: <%= bank_account[:account_type].capitalize %>
+Routing Number: <%= bank_account[:routing_number] %>
+Account Number: <%= bank_account[:account_number] %>
+