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

misc(daily_usage): Extract daily_usage history from rake task to a service #2843

Merged
merged 1 commit into from
Nov 21, 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
11 changes: 11 additions & 0 deletions app/jobs/daily_usages/fill_history_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

module DailyUsages
class FillHistoryJob < ApplicationJob
queue_as 'low_priority'

def perform(subscription:, from_datetime:)
DailyUsages::FillHistoryService.call!(subscription:, from_datetime:)
end
end
end
75 changes: 75 additions & 0 deletions app/services/daily_usages/fill_history_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# frozen_string_literal: true

module DailyUsages
class FillHistoryService < BaseService
def initialize(subscription:, from_datetime:)
@subscription = subscription
@from_datetime = from_datetime

super
end

def call
previous_daily_usage = nil

(from..to).each do |date|
datetime = date.in_time_zone(subscription.customer.applicable_timezone).beginning_of_day.utc

next if date == Time.zone.today &&
DailyUsage.refreshed_at_in_timezone(datetime).where(subscription_id: subscription.id).exists?

Timecop.freeze(datetime + 5.minutes) do
usage = Invoices::CustomerUsageService.call(
customer: subscription.customer,
subscription: subscription,
apply_taxes: false,
with_cache: false,
max_to_datetime: datetime
).raise_if_error!.usage

if previous_daily_usage.present? && previous_daily_usage.from_datetime != usage.from_datetime
# NOTE: A new billing period was started, the diff should contains the complete current usage
previous_daily_usage = nil
end

daily_usage = DailyUsage.new(
organization:,
customer: subscription.customer,
subscription:,
external_subscription_id: subscription.external_id,
usage: ::V1::Customers::UsageSerializer.new(usage, includes: %i[charges_usage]).serialize,
from_datetime: usage.from_datetime,
to_datetime: usage.to_datetime,
refreshed_at: datetime
)

daily_usage.usage_diff = DailyUsages::ComputeDiffService
.call(daily_usage:, previous_daily_usage:)
.raise_if_error!
.usage_diff

daily_usage.save!

previous_daily_usage = daily_usage
end
end

result
end

attr_reader :subscription, :from_datetime
delegate :organization, to: :subscription

def from
return @from if defined?(@from)

@from = subscription.started_at.to_date
@from = from_datetime.to_date if @from < from_datetime
@from
end

def to
@to ||= (subscription.terminated_at || Time.current).to_date
end
end
end
51 changes: 1 addition & 50 deletions lib/tasks/daily_usages.rake
Original file line number Diff line number Diff line change
Expand Up @@ -19,56 +19,7 @@ namespace :daily_usages do
.includes(customer: :organization)

subscriptions.find_each do |subscription|
from = subscription.started_at.to_date
if from < days_ago
from = days_ago.to_date
end

to = (subscription.terminated_at || Time.current).to_date

previous_daily_usage = nil

(from..to).each do |date|
datetime = date.in_time_zone(subscription.customer.applicable_timezone).beginning_of_day.utc

next if date == Date.today &&
DailyUsage.refreshed_at_in_timezone(datetime).where(subscription_id: subscription.id).exists?

Timecop.freeze(datetime + 5.minutes) do
usage = Invoices::CustomerUsageService.call(
customer: subscription.customer,
subscription: subscription,
apply_taxes: false,
with_cache: false,
max_to_datetime: datetime
).raise_if_error!.usage

if previous_daily_usage.present? && previous_daily_usage.from_datetime != usage.from_datetime
# NOTE: A new billing period was started, the diff should contains the complete current usage
previous_daily_usage = nil
end

daily_usage = DailyUsage.new(
organization:,
customer: subscription.customer,
subscription:,
external_subscription_id: subscription.external_id,
usage: ::V1::Customers::UsageSerializer.new(usage, includes: %i[charges_usage]).serialize,
from_datetime: usage.from_datetime,
to_datetime: usage.to_datetime,
refreshed_at: datetime
)

daily_usage.usage_diff = DailyUsages::ComputeDiffService
.call(daily_usage:, previous_daily_usage:)
.raise_if_error!
.usage_diff

daily_usage.save!

previous_daily_usage = daily_usage
end
end
DailyUsages::FillHistoryJob.perform_later(subscription:, from_datetime: days_ago)
end
end
end