app/workers/invoice_for_project_anchor_worker.rb

Summary

Maintainability
A
2 hrs
Test Coverage
B
86%
# frozen_string_literal: true

class InvoiceForProjectAnchorWorker
  include Sidekiq::Worker
  include Sidekiq::Throttled::Worker

  sidekiq_options(
    retry: 11 # around 7h max in the queue
  )

  sidekiq_throttle(
    concurrency: { limit: ENV.fetch("SDKQ_MAX_CONCURRENT_INVOICE", 3).to_i },
    key_suffix:  ->(project_anchor_id, _year, _quarter, _selected_org_unit_ids = nil, _options = {}) {
      per_process_id = ENV.fetch("HEROKU_DYNO_ID", $PROCESS_ID)
      [project_anchor_id, per_process_id].join("-")
    }
  )

  def perform(project_anchor_id, year, quarter, selected_org_unit_ids = nil, options = {})
    default_options = {
      slice_size: 25
    }
    raise "no more supported : should provide an single selected_org_unit_ids " if selected_org_unit_ids.nil? || selected_org_unit_ids.size > 1

    options = default_options.merge(options)
    project_anchor = ProjectAnchor.find(project_anchor_id)
    InvoicingJob.execute(project_anchor, "#{year}Q#{quarter}", selected_org_unit_ids&.first) do |invoicing_job|
      request = InvoicingRequest.new(year: year, quarter: quarter)

      project = project_anchor.projects.for_date(request.end_date_as_date) || project_anchor.latest_draft
      request.engine_version = project.engine_version

      options = Invoicing::InvoicingOptions.new(
        publish_to_dhis2:       true,
        force_project_id:       nil,
        allow_fresh_dhis2_data: false,
        invoicing_job:          invoicing_job,
        sidekiq_job_ref:        jid
      )
      request.entity = selected_org_unit_ids.first
      invoice_entity = Invoicing::InvoiceEntity.new(project_anchor, request, options)
      invoice_entity.call
    end
  rescue Invoicing::PublishingError => e
    puts "job failed #{e.message} : #{project_anchor}, #{year}Q#{quarter} #{selected_org_unit_ids}"
  rescue Hesabu::Error => e
    if e.message =~ /In equation/
    # The job won't magically heal itself, since the equation
    # can't compute. This way we keep our queue clean.
    else
      raise e
    end
  end
end