Skip to content

Commit

Permalink
Use refreshed_at for identifying existing DailyUsage
Browse files Browse the repository at this point in the history
  • Loading branch information
vincent-pochet committed Oct 25, 2024
1 parent b32b60c commit 950bb1f
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 11 deletions.
4 changes: 2 additions & 2 deletions app/services/daily_usages/compute_all_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def call
attr_reader :timestamp

def subscriptions
# TODO: Filter subscriptions based on the feature availability at organization level
# TODO(DailyUsage): Filter subscriptions based on the feature availability at organization level - Not Decided Yet
Subscription
.with(already_refreshed_today: already_refreshed_today)
.joins(customer: :organization)
Expand All @@ -36,7 +36,7 @@ def subscriptions
def already_refreshed_today
where_clause = <<-SQL
DATE(
(daily_usages.created_at)#{at_time_zone(customer: "cus", organization: "org")}
(daily_usages.refreshed_at)#{at_time_zone(customer: "cus", organization: "org")}
) = DATE(:timestamp#{at_time_zone(customer: "cus", organization: "org")})
SQL

Expand Down
7 changes: 4 additions & 3 deletions app/services/daily_usages/compute_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ def call
customer: subscription.customer,
subscription:,
external_subscription_id: subscription.external_id,
usage: ::V1::Customers::UsageSerializer.new(current_usage).serialize.to_json,
usage: ::V1::Customers::UsageSerializer.new(current_usage).serialize,
from_datetime: current_usage.from_datetime,
to_datetime: current_usage.to_datetime # TODO: persist the timestamp
to_datetime: current_usage.to_datetime,
refreshed_at: timestamp
)

result.daily_usage = daily_usage
Expand All @@ -44,7 +45,7 @@ def existing_daily_usage
@existing_daily_usage ||= DailyUsage
.joins(customer: :organization)
.where(subscription_id: subscription.id)
.where("DATE((daily_usages.created_at)#{at_time_zone}) = DATE(:timestamp#{at_time_zone})", timestamp:)
.where("DATE((daily_usages.refreshed_at)#{at_time_zone}) = DATE(:timestamp#{at_time_zone})", timestamp:)
.first
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
class AddRefreshedAtToDailyUsage < ActiveRecord::Migration[7.1]
def change
safety_assured do
add_column :daily_usages, :refreshed_at, :datetime, null: false
add_column :daily_usages, :refreshed_at, :datetime, null: false # rubocop:disable Rails/NotNullColumn
end
end
end
1 change: 1 addition & 0 deletions spec/factories/daily_usages.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
external_subscription_id { subscription.external_id }
from_datetime { Time.current.beginning_of_month }
to_datetime { Time.current.end_of_month }
refreshed_at { Time.current }
usage { {} }
end
end
4 changes: 4 additions & 0 deletions spec/factories/subscriptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,9 @@
started_at { 1.month.ago }
terminated_at { Time.zone.now }
end

trait :calendar do
billing_time { :calendar }
end
end
end
2 changes: 1 addition & 1 deletion spec/services/daily_usages/compute_all_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
end

context 'when subscription usage was already computed' do
before { create(:daily_usage, subscription:, created_at: timestamp + 2.minutes) }
before { create(:daily_usage, subscription:, refreshed_at: timestamp + 2.minutes) }

it 'does not enqueue any job' do
expect(compute_service.call).to be_success
Expand Down
42 changes: 38 additions & 4 deletions spec/services/daily_usages/compute_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

let(:organization) { create(:organization) }
let(:customer) { create(:customer, organization:) }
let(:subscription) { create(:subscription, customer:) }
let(:plan) { create(:plan, organization:) }
let(:subscription) { create(:subscription, :calendar, customer:, plan:, started_at: 1.year.ago) }

let(:timestamp) { Time.zone.parse('2024-10-22 00:05:00') }

Expand All @@ -20,14 +21,17 @@
organization_id: organization.id,
customer_id: customer.id,
subscription_id: subscription.id,
external_subscription_id: subscription.external_id
# TODO
external_subscription_id: subscription.external_id,
usage: Hash
)
expect(daily_usage.refreshed_at).to match_datetime(timestamp)
expect(daily_usage.from_datetime).to match_datetime(timestamp.beginning_of_month)
expect(daily_usage.to_datetime).to match_datetime(timestamp.end_of_month)
end

context 'when a daily usage already exists' do
let(:existing_daily_usage) do
create(:daily_usage, subscription:, organization:, customer:, created_at: timestamp)
create(:daily_usage, subscription:, organization:, customer:, refreshed_at: timestamp)
end

before { existing_daily_usage }
Expand All @@ -38,6 +42,36 @@
expect(result).to be_success
expect(result.daily_usage).to eq(existing_daily_usage)
end

context 'when the organization has a timezone' do
let(:organization) { create(:organization, timezone: 'America/Sao_Paulo') }

let(:existing_daily_usage) do
create(:daily_usage, subscription:, organization:, customer:, refreshed_at: timestamp - 4.hours)
end

it 'takes the timezone into account' do
result = compute_service.call

expect(result).to be_success
expect(result.daily_usage).to eq(existing_daily_usage)
end
end

context 'when the customer has a timezone' do
let(:customer) { create(:customer, organization:, timezone: 'America/Sao_Paulo') }

let(:existing_daily_usage) do
create(:daily_usage, subscription:, organization:, customer:, refreshed_at: timestamp - 4.hours)
end

it 'takes the timezone into account' do
result = compute_service.call

expect(result).to be_success
expect(result.daily_usage).to eq(existing_daily_usage)
end
end
end
end
end

0 comments on commit 950bb1f

Please sign in to comment.