diff --git a/Gemfile b/Gemfile index e73d36d..54e5a8c 100644 --- a/Gemfile +++ b/Gemfile @@ -7,17 +7,8 @@ gem "rails" gem "sinatra" -# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] - gem "puma" -group :development, :test do - gem "pry-byebug" -end - -group :development do -end - gem "pg" gem "activerecord" @@ -25,7 +16,15 @@ gem 'outboxer', '1.0.0.pre.beta' gem "sidekiq" +group :development do +end + +group :test do + gem 'database_cleaner-active_record' +end + group :development, :test do + gem "pry-byebug" gem 'rspec-rails' gem 'factory_bot_rails' end diff --git a/Gemfile.lock b/Gemfile.lock index 75102eb..173348d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -83,6 +83,10 @@ GEM concurrent-ruby (1.2.3) connection_pool (2.4.1) crass (1.0.6) + database_cleaner-active_record (2.1.0) + activerecord (>= 5.a) + database_cleaner-core (~> 2.0.0) + database_cleaner-core (2.0.1) date (3.3.4) diff-lcs (1.5.1) drb (2.2.1) @@ -258,6 +262,7 @@ PLATFORMS DEPENDENCIES activerecord + database_cleaner-active_record factory_bot_rails outboxer (= 1.0.0.pre.beta) pg diff --git a/app/jobs/accountify/aged_receivables_report/generate_job.rb b/app/jobs/accountify/aged_receivables_report/generate_job.rb new file mode 100644 index 0000000..e06e963 --- /dev/null +++ b/app/jobs/accountify/aged_receivables_report/generate_job.rb @@ -0,0 +1,12 @@ +module Accountify + module AgedReceivablesReport + class GenerateJob + include Sidekiq::Job + + def perform(args) + AgedReceivablesReport.generate({ + 'iam_tenant_id' => args['iam_tenant_id'] }) + end + end + end +end diff --git a/app/jobs/event/created_job.rb b/app/jobs/event/created_job.rb new file mode 100644 index 0000000..a59b002 --- /dev/null +++ b/app/jobs/event/created_job.rb @@ -0,0 +1,27 @@ +module Event + class CreatedJob + include Sidekiq::Job + + sidekiq_options queue: 'events', retry: false + + def perform(args) + case args['type'] + when 'Accountify::Invoice::IssuedEvent' + Accountify::AgedReceivablesReport::GenerateJob.perform_async({ + 'iam_tenant_id' => args['iam_tenant_id'] }) + when 'Accountify::Invoice::UpdatedEvent' + Accountify::AgedReceivablesReport::GenerateJob.perform_async({ + 'iam_tenant_id' => args['iam_tenant_id'] }) + when 'Accountify::Invoice::PaidEvent' + Accountify::AgedReceivablesReport::GenerateJob.perform_async({ + 'iam_tenant_id' => args['iam_tenant_id'] }) + when 'Accountify::Invoice::VoidedEvent' + Accountify::AgedReceivablesReport::GenerateJob.perform_async({ + 'iam_tenant_id' => args['iam_tenant_id'] }) + when 'Accountify::Invoice::DeletedEvent' + Accountify::AgedReceivablesReport::GenerateJob.perform_async({ + 'iam_tenant_id' => args['iam_tenant_id'] }) + end + end + end +end diff --git a/db/migrate/20240620220408_create_accountify_aged_receivables_reports.rb b/db/migrate/20240620220408_create_accountify_aged_receivables_reports.rb new file mode 100644 index 0000000..ad5f112 --- /dev/null +++ b/db/migrate/20240620220408_create_accountify_aged_receivables_reports.rb @@ -0,0 +1,16 @@ +class CreateAccountifyAgedReceivablesReports < ActiveRecord::Migration[7.1] + def change + create_table :accountify_aged_receivables_reports do |t| + t.bigint :iam_tenant_id, null: false, index: { unique: true } + + t.date :as_at_date, null: false + t.string :currency_code, null: false + t.integer :num_periods, null: false + t.integer :period_amount, null: false + t.string :period_unit, null: false + t.string :ageing_by, null: false + + t.timestamps + end + end +end diff --git a/db/migrate/20240620220453_create_accountify_aged_receivables_report_periods.rb b/db/migrate/20240620220453_create_accountify_aged_receivables_report_periods.rb new file mode 100644 index 0000000..7aa7c25 --- /dev/null +++ b/db/migrate/20240620220453_create_accountify_aged_receivables_report_periods.rb @@ -0,0 +1,15 @@ +class CreateAccountifyAgedReceivablesReportPeriods < ActiveRecord::Migration[7.1] + def change + create_table :accountify_aged_receivables_report_periods do |t| + t.references :aged_receivables_report, + null: false, index: true, foreign_key: { to_table: :accountify_aged_receivables_reports } + + t.date :start_date, null: false + t.date :end_date, null: false + t.decimal :sub_total_amount, precision: 12, scale: 2, null: false + t.string :sub_total_currency_code, null: false + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index e27aec3..114e084 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,10 +10,34 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_05_30_211442) do +ActiveRecord::Schema[7.1].define(version: 2024_06_20_220453) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" + create_table "accountify_aged_receivables_report_periods", force: :cascade do |t| + t.bigint "aged_receivables_report_id", null: false + t.date "start_date", null: false + t.date "end_date", null: false + t.decimal "sub_total_amount", precision: 12, scale: 2, null: false + t.string "sub_total_currency_code", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["aged_receivables_report_id"], name: "idx_on_aged_receivables_report_id_7f32513b52" + end + + create_table "accountify_aged_receivables_reports", force: :cascade do |t| + t.bigint "iam_tenant_id", null: false + t.date "as_at_date", null: false + t.string "currency_code", null: false + t.integer "num_periods", null: false + t.integer "period_amount", null: false + t.string "period_unit", null: false + t.string "ageing_by", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["iam_tenant_id"], name: "index_accountify_aged_receivables_reports_on_iam_tenant_id", unique: true + end + create_table "accountify_contacts", force: :cascade do |t| t.bigint "iam_tenant_id", null: false t.bigint "organisation_id", null: false @@ -95,6 +119,7 @@ t.index ["status", "created_at"], name: "index_outboxer_messages_on_status_and_created_at" end + add_foreign_key "accountify_aged_receivables_report_periods", "accountify_aged_receivables_reports", column: "aged_receivables_report_id" add_foreign_key "accountify_contacts", "accountify_organisations", column: "organisation_id" add_foreign_key "accountify_invoice_line_items", "accountify_invoices", column: "invoice_id" add_foreign_key "accountify_invoices", "accountify_contacts", column: "contact_id" diff --git a/lib/accountify/aged_receivables_report.rb b/lib/accountify/aged_receivables_report.rb new file mode 100644 index 0000000..366201c --- /dev/null +++ b/lib/accountify/aged_receivables_report.rb @@ -0,0 +1,229 @@ +module Accountify + module AgedReceivablesReport + extend self + + def generate(iam_tenant_id:, + as_at_date:, num_periods:, period_amount:, period_unit:, + ageing_by:, currency_code:) + validate( + as_at_date: as_at_date, + num_periods: num_periods, + period_amount: period_amount, + period_unit: period_unit, + ageing_by: ageing_by, + currency_code: currency_code) + + id = nil + + ActiveRecord::Base.transaction(isolation: :repeatable_read) do + current_utc_time = Time.current.utc + + report = Models::AgedReceivablesReport.create( + iam_tenant_id: iam_tenant_id, + as_at_date: as_at_date, + currency_code: currency_code, + num_periods: num_periods, + period_amount: period_amount, + period_unit: period_unit, + ageing_by: ageing_by, + created_at: current_utc_time, + updated_at: current_utc_time) + + period_ranges = generate_period_ranges( + as_at_date: as_at_date, + num_periods: num_periods, + period_amount: period_amount, + period_unit: period_unit) + + period_ranges.each do |period_range| + sub_total_amount = Models::Invoice + .where(iam_tenant_id: iam_tenant_id) + .where(sub_total_currency_code: currency_code) + .where( + "#{ageing_by} >= ? AND #{ageing_by} <= ?", + period_range[:start_date], period_range[:end_date]) + .sum(:sub_total_amount) + + report.periods.create!( + start_date: period_range[:start_date], + end_date: period_range[:end_date], + sub_total_amount: sub_total_amount, + sub_total_currency_code: currency_code) + end + + id = report.id + end + + find_by_id(iam_tenant_id: iam_tenant_id, id: id) + rescue ActiveRecord::RecordNotUnique + regenerate( + iam_tenant_id: iam_tenant_id, + as_at_date: as_at_date, + num_periods: num_period, + period_amount: period_amount, + period_unit: period_unit, + ageing_by: ageing_by, + currency_code: currency_code) + end + + def regenerate(iam_tenant_id:, + as_at_date:, num_periods:, period_amount:, period_unit:, + ageing_by:, currency_code:) + id = nil + + ActiveRecord::Base.transaction(transaction_isolation: :repeatable_read) do + current_utc_time = Time.current.utc + + report = Models::AgedReceivablesReport + .where(iam_tenant_id: iam_tenant_id) + .lock('FOR UPDATE NOWAIT') + .first! + + if report.generated_at <= generate_at + report.periods.delete_all + + report.update!( + as_at_date: as_at_date, + currency_code: currency_code, + num_periods: num_periods, + period_amount: period_amount, + period_unit: period_unit, + ageing_by: ageing_by, + created_at: current_utc_time, + updated_at: current_utc_time) + + period_ranges = generate_period_ranges( + as_at_date: as_at_date, + num_periods: num_periods, + period_amount: period_amount, + period_unit: period_unit) + + period_ranges.each do |period_range| + sub_total_amount = Models::Invoice + .where(iam_tenant_id: iam_tenant_id) + .where(sub_total_currency_code: currency_code) + .where( + "#{ageing_by} >= ? AND #{ageing_by} <= ?", + period_range[:start_date], period_range[:end_date]) + .sum(:sub_total_amount) + + report.periods.create!( + start_date: period_range[:start_date], + end_date: period_range[:end_date], + sub_total_amount: sub_total_amount, + sub_total_currency_code: currency_code) + end + end + + id = report.id + end + + find_by_id(iam_tenant_id: iam_tenant_id, id: id) + end + + def find_by_id(iam_tenant_id:, id:) + report = nil + + ActiveRecord::Base.transaction(isolation: :repeatable_read) do + report = Models::AgedReceivablesReport + .includes(:periods) + .where(iam_tenant_id: iam_tenant_id) + .find_by!(id: id) + end + + { + id: report.id, + as_at_date: report.as_at_date, + currency_code: report.currency_code, + num_periods: report.num_periods, + period_amount: report.period_amount, + period_unit: report.period_unit.to_sym, + created_at: report.created_at, + updated_at: report.updated_at, + periods: report.periods.map do |period| + { + start_date: period.start_date, + end_date: period.end_date, + sub_total: { + amount: period.sub_total_amount, + currency_code: period.sub_total_currency_code + } + } + end + } + end + + def generate_period_ranges(as_at_date:, num_periods:, period_amount:, period_unit:) + (1..num_periods).map do |i| + start_date = + case period_unit + when :month + as_at_date + ((i - 1) * period_amount.months) + when :week + as_at_date + ((i - 1) * period_amount.weeks) + when :day + as_at_date + ((i - 1) * period_amount.days) + end + + end_date = + case period_unit + when :month + as_at_date + (i * period_amount.months) - 1.day + when :week + as_at_date + (i * period_amount.weeks) - 1.day + when :day + as_at_date + (i * period_amount.days) - 1.day + end + + { start_date: start_date, end_date: end_date } + end + end + + def validate(as_at_date:, num_periods:, period_amount:, period_unit:, + ageing_by:, currency_code:) + if !as_at_date.is_a?(Date) + raise ArgumentError.new('as_at_date must be a valid date') + end + + if !num_periods.is_a?(Integer) + raise ArgumentError.new('num_periods must be an integer') + end + + if !period_amount.is_a?(Integer) + raise ArgumentError.new('period_amount must be an integer') + end + + if !period_unit.is_a?(Symbol) + raise ArgumentError.new('period_unit must be a symbol') + end + + if !ageing_by.is_a?(Symbol) + raise ArgumentError.new('ageing_by must be a symbol') + end + + if !currency_code.is_a?(String) + raise ArgumentError.new('currency_code must be a string') + end + + if !(1..24).include?(num_periods) + raise ArgumentError.new('num_periods must be within range 1..24 inclusive') + end + + if !(1..24).include?(period_amount) + raise ArgumentError.new('period_amount must be within range 1..24 inclusive') + end + + if ![:day, :week, :month].include?(period_unit) + raise ArgumentError.new('period_unit must be :day, :week, or :month') + end + + if ![:issue_date, :due_date].include?(ageing_by) + raise ArgumentError.new('ageing_by must be :issue_date or :due_date') + end + + if !['AUD'].include?(currency_code) + raise ArgumentError.new("currency_code must be 'AUD'") + end + end + end +end diff --git a/lib/accountify/models/aged_receivables_report.rb b/lib/accountify/models/aged_receivables_report.rb new file mode 100644 index 0000000..8e8de10 --- /dev/null +++ b/lib/accountify/models/aged_receivables_report.rb @@ -0,0 +1,11 @@ +module Accountify + module Models + class AgedReceivablesReport < ActiveRecord::Base + self.table_name = 'accountify_aged_receivables_reports' + + class Period < ActiveRecord::Base; end + + has_many :periods + end + end +end diff --git a/lib/event/created_job.rb b/lib/event/created_job.rb deleted file mode 100644 index b9d0c84..0000000 --- a/lib/event/created_job.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Event - class CreatedJob - include Sidekiq::Job - - sidekiq_options retry: false, backtrace: true - - def perform(args) - event = Models::Event - .where(iam_tenant_id: args['iam_tenant_id']) - .find(args['id']) - - logger.info "event #{event.id} processed" - end - end -end diff --git a/spec/jobs/event/created_job/accountify/invoice/deleted_event_spec.rb b/spec/jobs/event/created_job/accountify/invoice/deleted_event_spec.rb new file mode 100644 index 0000000..77a161f --- /dev/null +++ b/spec/jobs/event/created_job/accountify/invoice/deleted_event_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +module Event + RSpec.describe CreatedJob, type: :job do + let(:iam_tenant_id) { 555 } + + before do + Event::CreatedJob.new.perform({ + 'iam_tenant_id' => iam_tenant_id, + 'type' => 'Accountify::Invoice::DeletedEvent' }) + end + + describe 'when Accountify::Invoice::DeletedEvent' do + it 'performs Accountify::AgedReceivablesReport::GenerateJob async' do + expect(Accountify::AgedReceivablesReport::GenerateJob.jobs).to match([ + hash_including( + 'args' => [ + hash_including( + 'iam_tenant_id' => iam_tenant_id )])]) + end + end + end +end diff --git a/spec/jobs/event/created_job/accountify/invoice/issued_spec.rb b/spec/jobs/event/created_job/accountify/invoice/issued_spec.rb new file mode 100644 index 0000000..1316a76 --- /dev/null +++ b/spec/jobs/event/created_job/accountify/invoice/issued_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +module Event + RSpec.describe CreatedJob, type: :job do + let(:iam_tenant_id) { 555 } + + before do + Event::CreatedJob.new.perform({ + 'iam_tenant_id' => iam_tenant_id, + 'type' => 'Accountify::Invoice::IssuedEvent' }) + end + + describe 'when Accountify::Invoice::IssuedEvent' do + it 'performs Accountify::AgedReceivablesReport::GenerateJob async' do + expect(Accountify::AgedReceivablesReport::GenerateJob.jobs).to match([ + hash_including( + 'args' => [ + hash_including( + 'iam_tenant_id' => iam_tenant_id )])]) + end + end + end +end diff --git a/spec/jobs/event/created_job/accountify/invoice/paid_spec.rb b/spec/jobs/event/created_job/accountify/invoice/paid_spec.rb new file mode 100644 index 0000000..41f2aec --- /dev/null +++ b/spec/jobs/event/created_job/accountify/invoice/paid_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +module Event + RSpec.describe CreatedJob, type: :job do + let(:iam_tenant_id) { 555 } + + before do + Event::CreatedJob.new.perform({ + 'iam_tenant_id' => iam_tenant_id, + 'type' => 'Accountify::Invoice::PaidEvent' }) + end + + describe 'when Accountify::Invoice::PaidEvent' do + it 'performs Accountify::AgedReceivablesReport::GenerateJob async' do + expect(Accountify::AgedReceivablesReport::GenerateJob.jobs).to match([ + hash_including( + 'args' => [ + hash_including( + 'iam_tenant_id' => iam_tenant_id )])]) + end + end + end +end diff --git a/spec/jobs/event/created_job/accountify/invoice/updated_spec.rb b/spec/jobs/event/created_job/accountify/invoice/updated_spec.rb new file mode 100644 index 0000000..cff5f9d --- /dev/null +++ b/spec/jobs/event/created_job/accountify/invoice/updated_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +module Event + RSpec.describe CreatedJob, type: :job do + let(:iam_tenant_id) { 555 } + + before do + Event::CreatedJob.new.perform({ + 'iam_tenant_id' => iam_tenant_id, + 'type' => 'Accountify::Invoice::UpdatedEvent' }) + end + + describe 'when Accountify::Invoice::UpdatedEvent' do + it 'performs Accountify::AgedReceivablesReport::GenerateJob async' do + expect(Accountify::AgedReceivablesReport::GenerateJob.jobs).to match([ + hash_including( + 'args' => [ + hash_including( + 'iam_tenant_id' => iam_tenant_id )])]) + end + end + end +end diff --git a/spec/jobs/event/created_job/accountify/invoice/voided_spec.rb b/spec/jobs/event/created_job/accountify/invoice/voided_spec.rb new file mode 100644 index 0000000..0c19e9c --- /dev/null +++ b/spec/jobs/event/created_job/accountify/invoice/voided_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +module Event + RSpec.describe CreatedJob, type: :job do + let(:iam_tenant_id) { 555 } + + before do + Event::CreatedJob.new.perform({ + 'iam_tenant_id' => iam_tenant_id, + 'type' => 'Accountify::Invoice::VoidedEvent' }) + end + + describe 'when Accountify::Invoice::VoidedEvent' do + it 'performs Accountify::AgedReceivablesReport::GenerateJob async' do + expect(Accountify::AgedReceivablesReport::GenerateJob.jobs).to match([ + hash_including( + 'args' => [ + hash_including( + 'iam_tenant_id' => iam_tenant_id )])]) + end + end + end +end diff --git a/spec/lib/accountify/aged_receivables_report/generate_spec.rb b/spec/lib/accountify/aged_receivables_report/generate_spec.rb new file mode 100644 index 0000000..b465ab7 --- /dev/null +++ b/spec/lib/accountify/aged_receivables_report/generate_spec.rb @@ -0,0 +1,194 @@ +require 'rails_helper' + +module Accountify + RSpec.describe AgedReceivablesReport, type: :module do + describe '.generate' do + let(:current_date) { Date.parse('2024-06-23') } + + let(:iam_tenant_id) { 4 } + + let(:organisation) do + create(:accountify_organisation, iam_tenant_id: iam_tenant_id) + end + + let(:contact) do + create(:accountify_contact, + iam_tenant_id: iam_tenant_id, organisation_id: organisation.id) + end + + let!(:invoice_1) do + create(:accountify_invoice, + iam_tenant_id: iam_tenant_id, + organisation_id: organisation.id, + contact_id: contact.id, + currency_code: "AUD", + status: Invoice::Status::ISSUED, + due_date: current_date, + sub_total_amount: BigDecimal("100.00"), + sub_total_currency_code: "AUD") + end + + let!(:invoice_2) do + create(:accountify_invoice, + iam_tenant_id: iam_tenant_id, + organisation_id: organisation.id, + contact_id: contact.id, + currency_code: "AUD", + status: Invoice::Status::ISSUED, + due_date: current_date + 1.month, + sub_total_amount: BigDecimal("200.00"), + sub_total_currency_code: "AUD") + end + + let!(:invoice_3) do + create(:accountify_invoice, + iam_tenant_id: iam_tenant_id, + organisation_id: organisation.id, + contact_id: contact.id, + currency_code: "AUD", + status: Invoice::Status::ISSUED, + due_date: current_date + 2.months, + sub_total_amount: BigDecimal("300.00"), + sub_total_currency_code: "AUD") + end + + let!(:invoice_4) do + create(:accountify_invoice, + iam_tenant_id: iam_tenant_id, + organisation_id: organisation.id, + contact_id: contact.id, + currency_code: "AUD", + status: Invoice::Status::ISSUED, + due_date: current_date + 3.months, + sub_total_amount: BigDecimal("400.00"), + sub_total_currency_code: "AUD") + end + + let(:as_at_date) { Date.parse('2024-06-23') } + let(:currency_code) { 'AUD' } + let(:num_periods) { 4 } + let(:period_amount) { 1 } + let(:period_unit) { :month } + let(:ageing_by) { :due_date } + + let(:report) do + AgedReceivablesReport.generate( + iam_tenant_id: iam_tenant_id, + as_at_date: as_at_date, + currency_code: currency_code, + num_periods: num_periods, + period_amount: period_amount, + period_unit: period_unit, + ageing_by: ageing_by) + end + + let(:report_model) do + Models::AgedReceivablesReport + .where(iam_tenant_id: iam_tenant_id) + .find_by!(id: report[:id]) + end + + it 'creates model' do + expect( + report_model.attributes.slice( + 'id', + 'as_at_date', + 'currency_code', + 'num_periods', + 'period_amount', + 'period_unit' + ).merge( + 'periods' => report_model.periods.map do |period| + period.slice( + 'start_date', + 'end_date', + 'sub_total_amount', + 'sub_total_currency_code') + end + ) + ).to eq( + 'id' => report_model.id, + 'as_at_date' => Date.parse('2024-06-23'), + 'currency_code' => 'AUD', + 'num_periods' => 4, + 'period_amount' => 1, + 'period_unit' => 'month', + 'periods' => [ + { + 'start_date' => Date.parse('2024-06-23'), + 'end_date' => Date.parse('2024-07-22'), + 'sub_total_amount' => 100.0, + 'sub_total_currency_code' => 'AUD' + }, + { + 'start_date' => Date.parse('2024-07-23'), + 'end_date' => Date.parse('2024-08-22'), + 'sub_total_amount' => 200.0, + 'sub_total_currency_code' => 'AUD' + }, + { + 'start_date' => Date.parse('2024-08-23'), + 'end_date' => Date.parse('2024-09-22'), + 'sub_total_amount' => 300.0, + 'sub_total_currency_code' => 'AUD' + }, + { + 'start_date' => Date.parse('2024-09-23'), + 'end_date' => Date.parse('2024-10-22'), + 'sub_total_amount' => 400.0, + 'sub_total_currency_code' => 'AUD' + } + ] + ) + end + + it 'returns report' do + expect(report).to include({ + id: be_a(Integer), + as_at_date: Date.parse('2024-06-23'), + currency_code: 'AUD', + num_periods: 4, + period_amount: 1, + period_unit: :month, + created_at: be_present, + updated_at: be_present, + periods: [ + { + start_date: Date.parse('2024-06-23'), + end_date: Date.parse('2024-07-22'), + sub_total: { + amount: BigDecimal('100.0'), + currency_code: 'AUD' + } + }, + { + start_date: Date.parse('2024-07-23'), + end_date: Date.parse('2024-08-22'), + sub_total: { + amount: BigDecimal('200.0'), + currency_code: 'AUD' + } + }, + { + start_date: Date.parse('2024-08-23'), + end_date: Date.parse('2024-09-22'), + sub_total: { + amount: BigDecimal('300.0'), + currency_code: 'AUD' + } + }, + { + start_date: Date.parse('2024-09-23'), + end_date: Date.parse('2024-10-22'), + sub_total: { + amount: BigDecimal('400.0'), + currency_code: 'AUD' + } + } + ] + }) + end + + end + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index b0e7f18..b4db3ac 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,7 +1,9 @@ +ENV['RAILS_ENV'] ||= 'test' + require 'spec_helper' require 'factory_bot_rails' +require 'database_cleaner/active_record' -ENV['RAILS_ENV'] ||= 'test' require_relative '../config/environment' abort("The Rails environment is running in production mode!") if Rails.env.production? @@ -19,7 +21,15 @@ RSpec.configure do |config| config.fixture_paths = [Rails.root.join('spec/fixtures')] - config.use_transactional_fixtures = true + config.use_transactional_fixtures = false + + config.before(:each) do + DatabaseCleaner.strategy = :truncation + end + + config.before(:each) do + DatabaseCleaner.clean + end config.infer_spec_type_from_file_location!