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

fix (grace_period): refactor how issuing date is set #2928

Merged
merged 4 commits into from
Dec 13, 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
12 changes: 1 addition & 11 deletions app/models/invoice.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,17 +97,7 @@ class Invoice < ApplicationRecord
scope :invisible, -> { where(status: INVISIBLE_STATUS.keys) }
scope :with_generated_number, -> { where(status: %w[finalized voided]) }
scope :ready_to_be_refreshed, -> { where(ready_to_be_refreshed: true) }
scope :ready_to_be_finalized,
lambda {
date = <<-SQL
(
invoices.created_at +
COALESCE(customers.invoice_grace_period, organizations.invoice_grace_period) * INTERVAL '1 DAY'
)
SQL

draft.joins(:customer, :organization).where("#{Arel.sql(date)} < ?", Time.current)
}
scope :ready_to_be_finalized, -> { draft.where('issuing_date <= ?', Time.current.to_date) }

scope :created_before,
lambda { |invoice|
Expand Down
36 changes: 16 additions & 20 deletions app/services/customers/update_invoice_grace_period_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,30 @@ module Customers
class UpdateInvoiceGracePeriodService < BaseService
def initialize(customer:, grace_period:)
@customer = customer
@grace_period = grace_period
@grace_period = grace_period.to_i
super
end

def call
if grace_period != customer.invoice_grace_period
old_grace_period = customer.invoice_grace_period.to_i
old_applicable_grace_period = customer.applicable_invoice_grace_period.to_i

if grace_period != old_grace_period
customer.invoice_grace_period = grace_period
customer.save!

# NOTE: Finalize related draft invoices.
customer.invoices.ready_to_be_finalized.each do |invoice|
Invoices::RefreshDraftAndFinalizeService.call(invoice:)
end
grace_period_diff = customer.applicable_invoice_grace_period.to_i - old_applicable_grace_period

# NOTE: Update issuing_date on draft invoices.
customer.invoices.draft.each do |invoice|
invoice.update!(
issuing_date: grace_period_issuing_date(invoice),
payment_due_date: grace_period_payment_due_date(invoice)
)
customer.invoices.draft.find_each do |invoice|
invoice.issuing_date = invoice.issuing_date + grace_period_diff.days
nudded marked this conversation as resolved.
Show resolved Hide resolved
invoice.payment_due_date = grace_period_payment_due_date(invoice)
invoice.save!
end

# NOTE: Finalize related draft invoices.
customer.invoices.ready_to_be_finalized.find_each do |invoice|
Invoices::RefreshDraftAndFinalizeService.call(invoice:)
end
end

Expand All @@ -35,16 +39,8 @@ def call

attr_reader :customer, :grace_period

def invoice_created_at(invoice)
invoice.created_at.in_time_zone(customer.applicable_timezone).to_date
end

def grace_period_issuing_date(invoice)
invoice_created_at(invoice) + customer.applicable_invoice_grace_period.days
end

def grace_period_payment_due_date(invoice)
grace_period_issuing_date(invoice) + customer.applicable_net_payment_term.days
invoice.issuing_date + customer.applicable_net_payment_term.days
end
end
end
38 changes: 20 additions & 18 deletions app/services/organizations/update_invoice_grace_period_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,30 @@ module Organizations
class UpdateInvoiceGracePeriodService < BaseService
def initialize(organization:, grace_period:)
@organization = organization
@grace_period = grace_period
@grace_period = grace_period.to_i
super
end

def call
if grace_period != organization.invoice_grace_period
old_grace_period = organization.invoice_grace_period.to_i

if grace_period != old_grace_period
organization.invoice_grace_period = grace_period
organization.save!

# NOTE: Finalize related draft invoices.
organization.invoices.ready_to_be_finalized.each do |invoice|
Invoices::RefreshDraftAndFinalizeService.call(invoice:)
# NOTE: Update issuing_date on draft invoices.
organization.invoices.draft.find_each do |invoice|
grace_period_diff = invoice.customer.applicable_invoice_grace_period.to_i -
old_applicable_grace_period(invoice.customer, old_grace_period)

invoice.issuing_date = invoice.issuing_date + grace_period_diff.days
invoice.payment_due_date = grace_period_payment_due_date(invoice)
invoice.save!
end

# NOTE: Update issuing_date on draft invoices.
organization.invoices.draft.each do |invoice|
invoice.update!(
issuing_date: grace_period_issuing_date(invoice),
payment_due_date: grace_period_payment_due_date(invoice)
)
# NOTE: Finalize related draft invoices.
organization.invoices.ready_to_be_finalized.find_each do |invoice|
Invoices::RefreshDraftAndFinalizeService.call(invoice:)
end
end

Expand All @@ -35,16 +39,14 @@ def call

attr_reader :organization, :grace_period

def invoice_created_at(invoice)
invoice.created_at.in_time_zone(invoice.customer.applicable_timezone).to_date
def grace_period_payment_due_date(invoice)
invoice.issuing_date + invoice.customer.applicable_net_payment_term.days
end

def grace_period_issuing_date(invoice)
invoice_created_at(invoice) + invoice.customer.applicable_invoice_grace_period.days
end
def old_applicable_grace_period(customer, old_org_grace_period)
return customer.invoice_grace_period if customer.invoice_grace_period.present?

def grace_period_payment_due_date(invoice)
grace_period_issuing_date(invoice) + invoice.customer.applicable_net_payment_term.days
old_org_grace_period
end
end
end
4 changes: 2 additions & 2 deletions spec/jobs/clock/finalize_invoices_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
create(
:invoice,
status: :draft,
created_at: DateTime.parse('20 Jun 2022'),
issuing_date: DateTime.parse('23 Jun 2022').to_date,
customer:,
organization: customer.organization
)
Expand All @@ -20,7 +20,7 @@
create(
:invoice,
status: :finalized,
created_at: DateTime.parse('20 Jun 2022'),
issuing_date: DateTime.parse('23 Jun 2022').to_date,
customer:,
organization: customer.organization
)
Expand Down
18 changes: 18 additions & 0 deletions spec/models/invoice_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,24 @@
end
end

describe 'ready_to_be_finalized' do
let(:invoice) { create(:invoice, status: :draft, issuing_date: Time.current - 1.day) }

before { invoice }

it 'returns all invoices that are ready for finalization' do
expect(described_class.ready_to_be_finalized.pluck(:id)).to include(invoice.id)
end

context 'when issuing date has not been reached' do
let(:invoice) { create(:invoice, status: :draft, issuing_date: Time.current + 1.day) }

it 'returns all invoices that are ready for finalization' do
expect(described_class.ready_to_be_finalized.pluck(:id)).not_to include(invoice.id)
end
end
end

describe 'when status is visible' do
it do
described_class::VISIBLE_STATUS.keys.each do |status|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@

describe '#call' do
let(:invoice_to_be_finalized) do
create(:invoice, status: :draft, customer:, created_at: DateTime.parse('19 Jun 2022'), organization:)
create(:invoice, status: :draft, customer:, issuing_date: DateTime.parse('19 Jun 2022').to_date, organization:)
end

let(:invoice_to_not_be_finalized) do
create(:invoice, status: :draft, customer:, created_at: DateTime.parse('21 Jun 2022'), organization:)
create(:invoice, status: :draft, customer:, issuing_date: DateTime.parse('21 Jun 2022').to_date, organization:)
end

before do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@

describe '#call' do
let(:invoice_to_be_finalized) do
create(:invoice, status: :draft, customer:, created_at: DateTime.parse('19 Jun 2022'), organization:)
create(:invoice, status: :draft, customer:, issuing_date: DateTime.parse('19 Jun 2022').to_date, organization:)
end

let(:invoice_to_not_be_finalized) do
create(:invoice, status: :draft, customer:, created_at: DateTime.parse('21 Jun 2022'), organization:)
create(:invoice, status: :draft, customer:, issuing_date: DateTime.parse('21 Jun 2022').to_date, organization:)
end

before do
Expand Down
4 changes: 2 additions & 2 deletions spec/services/organizations/update_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@
let(:customer) { create(:customer, organization:) }

let(:invoice_to_be_finalized) do
create(:invoice, status: :draft, customer:, created_at: DateTime.parse('19 Jun 2022'), organization:)
create(:invoice, status: :draft, customer:, issuing_date: DateTime.parse('19 Jun 2022').to_date, organization:)
end

let(:invoice_to_not_be_finalized) do
create(:invoice, status: :draft, customer:, created_at: DateTime.parse('21 Jun 2022'), organization:)
create(:invoice, status: :draft, customer:, issuing_date: DateTime.parse('21 Jun 2022').to_date, organization:)
end

let(:invoice_grace_period) { 2 }
Expand Down
Loading