Skip to content

Commit

Permalink
feat(precise_amount): Add migration, model methods and serializer (#2516
Browse files Browse the repository at this point in the history
)

## Context

For some customers some amounts are not enough precise as Lago convert
fees to `amount_cent`.

## Description

Add migration for columns for precise amount cents, add model methods
and serializer attributes.
  • Loading branch information
ivannovosad authored Aug 30, 2024
1 parent 2456a9c commit f2bd12a
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 12 deletions.
14 changes: 14 additions & 0 deletions app/models/fee.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class Fee < ApplicationRecord
monetize :amount_cents
monetize :taxes_amount_cents, with_model_currency: :currency
monetize :total_amount_cents
monetize :precise_amount_cents, with_model_currency: :currency
monetize :taxes_precise_amount_cents, with_model_currency: :currency
monetize :precise_total_amount_cents
monetize :unit_amount_cents, disable_validation: true, allow_nil: true, with_model_currency: :currency

# TODO: Deprecate add_on type in the near future
Expand Down Expand Up @@ -132,11 +135,20 @@ def sub_total_excluding_taxes_amount_cents
amount_cents - precise_coupons_amount_cents
end

def sub_total_excluding_taxes_precise_amount_cents
precise_amount_cents - precise_coupons_amount_cents
end

def total_amount_cents
amount_cents + taxes_amount_cents
end
alias_method :total_amount_currency, :currency

def precise_total_amount_cents
precise_amount_cents + taxes_precise_amount_cents
end
alias_method :precise_total_amount_currency, :currency

def creditable_amount_cents
amount_cents - credit_note_items.sum(:amount_cents)
end
Expand Down Expand Up @@ -175,12 +187,14 @@ def has_charge_filters?
# invoiceable_type :string
# pay_in_advance :boolean default(FALSE), not null
# payment_status :integer default("pending"), not null
# precise_amount_cents :decimal(40, 15) default(0.0), not null
# precise_coupons_amount_cents :decimal(30, 5) default(0.0), not null
# precise_unit_amount :decimal(30, 15) default(0.0), not null
# properties :jsonb not null
# refunded_at :datetime
# succeeded_at :datetime
# taxes_amount_cents :bigint not null
# taxes_precise_amount_cents :decimal(40, 15) default(0.0), not null
# taxes_rate :float default(0.0), not null
# total_aggregated_units :decimal(, )
# unit_amount_cents :bigint default(0), not null
Expand Down
23 changes: 12 additions & 11 deletions app/models/fee/applied_tax.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@ class AppliedTax < ApplicationRecord
#
# Table name: fees_taxes
#
# id :uuid not null, primary key
# amount_cents :bigint default(0), not null
# amount_currency :string not null
# tax_code :string not null
# tax_description :string
# tax_name :string not null
# tax_rate :float default(0.0), not null
# created_at :datetime not null
# updated_at :datetime not null
# fee_id :uuid not null
# tax_id :uuid
# id :uuid not null, primary key
# amount_cents :bigint default(0), not null
# amount_currency :string not null
# precise_amount_cents :decimal(40, 15) default(0.0), not null
# tax_code :string not null
# tax_description :string
# tax_name :string not null
# tax_rate :float default(0.0), not null
# created_at :datetime not null
# updated_at :datetime not null
# fee_id :uuid not null
# tax_id :uuid
#
# Indexes
#
Expand Down
5 changes: 5 additions & 0 deletions app/serializers/v1/fee_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
module V1
class FeeSerializer < ModelSerializer
def serialize
# subunit_to_unit = model.amount.currency.subunit_to_unit

payload = {
lago_id: model.id,
lago_charge_filter_id: model.charge_filter_id,
Expand All @@ -29,7 +31,10 @@ def serialize
invoiceable:,
amount_cents: model.amount_cents,
amount_currency: model.amount_currency,
# precise_amount: model.precise_amount_cents.fdiv(subunit_to_unit),
# precise_total_amount: model.precise_total_amount_cents.fdiv(subunit_to_unit),
taxes_amount_cents: model.taxes_amount_cents,
# taxes_precise_amount: model.taxes_precise_amount_cents.fdiv(subunit_to_unit),
taxes_rate: model.taxes_rate,
total_amount_cents: model.total_amount_cents,
total_amount_currency: model.amount_currency,
Expand Down
16 changes: 16 additions & 0 deletions db/migrate/20240829093425_add_precise_amount_cents_columns.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

class AddPreciseAmountCentsColumns < ActiveRecord::Migration[7.1]
def change
safety_assured do
change_table :fees, bulk: true do |t|
t.decimal :precise_amount_cents, precision: 40, scale: 15, default: '0.0', null: false
t.decimal :taxes_precise_amount_cents, precision: 40, scale: 15, default: '0.0', null: false
end

change_table :fees_taxes, bulk: true do |t|
t.decimal :precise_amount_cents, precision: 40, scale: 15, default: '0.0', null: false
end
end
end
end
5 changes: 4 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions spec/factories/fees.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
subscription

amount_cents { 200 }
precise_amount_cents { 200.0000000001 }
amount_currency { 'EUR' }
taxes_amount_cents { 2 }
taxes_precise_amount_cents { 2.0000000001 }

invoiceable_type { 'Subscription' }
invoiceable_id { subscription.id }
Expand Down
20 changes: 20 additions & 0 deletions spec/models/fee_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,26 @@
it { expect(fee.total_amount_currency).to eq('EUR') }
end

describe '#precise_total_amount_cents' do
subject(:method_call) { fee.precise_total_amount_cents }

let(:fee) { create(:fee, precise_amount_cents: 200.0000000123, taxes_precise_amount_cents: 20.00000000012) }

it 'returns sum of precise amount cents and taxes precise amount cents' do
expect(subject).to eq(220.00000001242)
end
end

describe '#sub_total_excluding_taxes_precise_amount_cents' do
subject(:method_call) { fee.sub_total_excluding_taxes_precise_amount_cents }

let(:fee) { create(:fee, precise_amount_cents: 200.00456000123, precise_coupons_amount_cents: 150.00123) }

it 'returns sub total minus coupons amount cents' do
expect(subject).to eq(50.00333000123)
end
end

describe '#invoice_sorting_clause' do
let(:charge) { create(:standard_charge, properties:) }
let(:fee) { fee_model.new(charge:, fee_type: 'charge', grouped_by:) }
Expand Down
3 changes: 3 additions & 0 deletions spec/serializers/v1/fee_serializer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
'taxes_rate' => fee.taxes_rate,
'total_amount_cents' => fee.total_amount_cents,
'total_amount_currency' => fee.amount_currency,
# 'precise_amount' => fee.precise_amount_cents.fdiv(100),
# 'taxes_precise_amount' => fee.taxes_precise_amount_cents.fdiv(100),
# 'precise_total_amount' => fee.precise_total_amount_cents.fdiv(100),
'units' => fee.units.to_s,
'precise_unit_amount' => fee.precise_unit_amount.to_s,
'precise_coupons_amount_cents' => fee.precise_coupons_amount_cents.to_s,
Expand Down

0 comments on commit f2bd12a

Please sign in to comment.