3scale/porta

View on GitHub
app/models/finance/postpaid_billing_strategy.rb

Summary

Maintainability
A
25 mins
Test Coverage
# frozen_string_literal: true

class Finance::PostpaidBillingStrategy < Finance::BillingStrategy

  # called by Finance::BillingStrategy::daily with a single :buyer_ids
  def daily(options = {})
    now = options[:now].presence || Time.now.utc
    bill_and_charge_each(options) do |buyer|
      Rails.logger.info("#{log_prefix(buyer)} started daily billing and charging at #{now} (postpaid)")
      bill_expired_trials(buyer, now)

      only_on_days(now, 1) do
        bill_variable_costs(buyer, now - 1.month) # bill for costs until end of yesterday (last day of month)
        finalize_invoices_of(buyer, now)
        bill_fixed_costs(buyer, now) # I assume creates the invoice for the new month
      end

      issue_invoices_of(buyer, now)

      charge_invoices(buyer, now)

      info("#{log_prefix(buyer)} successfully finished daily billing and charging (postpaid)")
    end

    notify_billing_finished(now) unless options[:skip_notifications] # In Sidekiq, notifications are triggered by the callback of the jobs batch
  end

  def name
    'postpaid'
  end

  def bill_plan_change(contract, period)
    plan = contract.plan
    old_plan = contract.old_plan

    period_begin = period.begin
    invoice = invoice_for(contract.user_account, period_begin)
    contract.bill_for(Month.new(period_begin), invoice, old_plan)

    add_plan_cost(:refund, contract, old_plan, period)
    add_plan_cost(:bill, contract, plan, period)
  end

  # Differs from Postpaid #bill_variable_costs just by the invoice
  # that is used to bill on: here it is the current month.
  #
  def bill_variable_costs(buyer, now = Time.now.utc)
    info("#{log_prefix(buyer)} billing variable costs at #{now}", buyer)
    buyer.billable_contracts.find_each(batch_size: 100) do |contract|
      contract.bill_for_variable(Month.new(now), invoice_for(buyer, now))
    end
  end

  protected

  def invoices_to_finalize_of(buyer, now)
    account.buyer_invoices.by_buyer(buyer).before(now).opened
  end
end