diff --git a/app/controllers/internal_api/v1/invoices_controller.rb b/app/controllers/internal_api/v1/invoices_controller.rb index 58b9e6e821..45feb4dad3 100644 --- a/app/controllers/internal_api/v1/invoices_controller.rb +++ b/app/controllers/internal_api/v1/invoices_controller.rb @@ -39,6 +39,14 @@ def update } end + def send_invoice + authorize invoice + + invoice.send_to_email(subject: invoice_email_params[:subject], recipients: invoice_email_params[:recipients]) + + render json: { message: "Invoice will be sent!" }, status: :accepted + end + private def load_client(client_id) @@ -54,4 +62,8 @@ def invoice_params policy(Invoice).permitted_attributes ) end + + def invoice_email_params + params.require(:invoice_email).permit(:subject, :body, recipients: []) + end end diff --git a/app/policies/invoice_policy.rb b/app/policies/invoice_policy.rb index 0bbeea43b7..171b85bfff 100644 --- a/app/policies/invoice_policy.rb +++ b/app/policies/invoice_policy.rb @@ -17,6 +17,10 @@ def show? user_owner_or_admin? end + def send_invoice? + user_owner_or_admin? + end + def permitted_attributes [ :issue_date, :due_date, diff --git a/config/routes/internal_api.rb b/config/routes/internal_api.rb index 370a7a184f..5caa717d49 100644 --- a/config/routes/internal_api.rb +++ b/config/routes/internal_api.rb @@ -13,7 +13,9 @@ resources :timesheet_entry, only: [:index, :create, :update, :destroy] resources :reports, only: [:index] resources :workspaces, only: [:update] - resources :invoices, only: [:index, :create, :update] + resources :invoices, only: [:index, :create, :update] do + post :send_invoice, on: :member + end resources :generate_invoice, only: [:index, :show] end end diff --git a/spec/requests/internal_api/v1/invoices/send_invoice_spec.rb b/spec/requests/internal_api/v1/invoices/send_invoice_spec.rb new file mode 100644 index 0000000000..fdc99ea30e --- /dev/null +++ b/spec/requests/internal_api/v1/invoices/send_invoice_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe "InternalApi::V1::Invoices#send_invoice", type: :request do + let(:client) { create :client_with_invoices } + let(:company) { client.company } + let(:invoice) { client.invoices.first } + let(:user) { create :user, current_workspace_id: company.id } + + context "when user is signed in" do + before do + create(:company_user, company:, user:) + end + + let(:invoice_email) do + { subject: "Some Subject", recipients: [client.email, "miru@example.com"], body: "You have an invoice!" } + end + + context "when user is an admin" do + before do + user.add_role :admin, company + sign_in user + end + + it "returns a 202 response" do + post send_invoice_internal_api_v1_invoice_path(id: invoice.id), params: { invoice_email: } + + expect(response).to have_http_status :accepted + expect(json_response["message"]).to eq("Invoice will be sent!") + end + + it "enqueues an email for delivery" do + expect do + post send_invoice_internal_api_v1_invoice_path(id: invoice.id), params: { invoice_email: } + end.to have_enqueued_mail(InvoiceMailer, :invoice) + end + + context "when invoice doesn't exist" do + it "returns 404 response" do + post send_invoice_internal_api_v1_invoice_path(id: "random") + + expect(response).to have_http_status :not_found + expect(json_response["errors"]).to eq "Couldn't find Invoice with 'id'=random" + end + end + end + + context "when user is an employee" do + before do + user.add_role :employee, company + sign_in user + end + + it "returns a 403 response" do + post send_invoice_internal_api_v1_invoice_path(id: invoice.id) + + expect(response).to have_http_status(:forbidden) + end + end + end + + context "when user is logged out" do + it "returns a 401 response" do + post send_invoice_internal_api_v1_invoice_path(id: invoice.id) + + expect(response).to have_http_status(:unauthorized) + expect(json_response["error"]).to eq("You need to sign in or sign up before continuing.") + end + end +end