diff --git a/app/exporters/bangladesh_dhis2_exporter.rb b/app/exporters/bangladesh_dhis2_exporter.rb deleted file mode 100644 index 24151263e8..0000000000 --- a/app/exporters/bangladesh_dhis2_exporter.rb +++ /dev/null @@ -1,33 +0,0 @@ -class BangladeshDhis2Exporter - def self.export - periods = (current_month_period.advance(months: -24)..current_month_period) - - exporter = Dhis2Exporter.new( - facility_identifiers: FacilityBusinessIdentifier.dhis2_org_unit_id, - periods: periods, - data_elements_map: CountryConfig.dhis2_data_elements.fetch(:dhis2_data_elements) - ) - - exporter.export do |facility_identifier, period| - repository = Reports::Repository.new(facility_identifier.facility.region, periods: periods) - facility = facility_identifier.facility - slug = facility_identifier.facility.region.slug - { - cumulative_assigned: repository.cumulative_assigned_patients[slug][period], - cumulative_assigned_adjusted: repository.adjusted_patients_with_ltfu[slug][period], - controlled: repository.controlled[slug][period], - uncontrolled: repository.uncontrolled[slug][period], - missed_visits: repository.missed_visits[slug][period], - ltfu: repository.ltfu[slug][period], - # NOTE: dead patients are always the current count due to lack of status timestamps - dead: facility.assigned_patients.with_hypertension.status_dead.count, - cumulative_registrations: repository.cumulative_registrations[slug][period], - monthly_registrations: repository.monthly_registrations[slug][period] - } - end - end - - def self.current_month_period - @current_month_period ||= Period.current.previous - end -end diff --git a/app/exporters/bangladesh_disaggregated_dhis2_exporter.rb b/app/exporters/bangladesh_disaggregated_dhis2_exporter.rb deleted file mode 100644 index b4296e70c7..0000000000 --- a/app/exporters/bangladesh_disaggregated_dhis2_exporter.rb +++ /dev/null @@ -1,55 +0,0 @@ -class BangladeshDisaggregatedDhis2Exporter - STEP = 5 - BUCKETS = (15..75).step(STEP).to_a - - def self.export - exporter = Dhis2Exporter.new( - facility_identifiers: FacilityBusinessIdentifier.dhis2_org_unit_id, - periods: (current_month_period.advance(months: -24)..current_month_period), - data_elements_map: CountryConfig.dhis2_data_elements.fetch(:disaggregated_dhis2_data_elements), - category_option_combo_ids: CountryConfig.dhis2_data_elements.fetch(:dhis2_category_option_combo) - ) - - exporter.export_disaggregated do |facility_identifier, period| - region = facility_identifier.facility.region - { - htn_cumulative_assigned_patients: PatientStates::Hypertension::CumulativeAssignedPatientsQuery.new(region, period).call, - htn_controlled_patients: PatientStates::Hypertension::ControlledPatientsQuery.new(region, period).call, - htn_uncontrolled_patients: PatientStates::Hypertension::UncontrolledPatientsQuery.new(region, period).call, - htn_patients_who_missed_visits: PatientStates::Hypertension::MissedVisitsPatientsQuery.new(region, period).call, - htn_patients_lost_to_follow_up: PatientStates::Hypertension::LostToFollowUpPatientsQuery.new(region, period).call, - htn_dead_patients: PatientStates::Hypertension::DeadPatientsQuery.new(region, period).call, - htn_cumulative_registered_patients: PatientStates::Hypertension::CumulativeRegistrationsQuery.new(region, period).call, - htn_monthly_registered_patients: PatientStates::Hypertension::MonthlyRegistrationsQuery.new(region, period).call, - htn_cumulative_assigned_patients_adjusted: PatientStates::Hypertension::AdjustedAssignedPatientsQuery.new(region, period).call - }.transform_values { |patient_states| disaggregate_by_gender_age(patient_states) } - end - end - - def self.disaggregate_by_gender_age(patient_states) - gender_age_counts(patient_states).transform_keys do |(gender, age_bucket_index)| - gender_age_range_key(gender, age_bucket_index) - end - end - - def self.gender_age_counts(patient_states) - PatientStates::DisaggregatedPatientCountQuery.disaggregate_by_age( - BUCKETS, - PatientStates::DisaggregatedPatientCountQuery.disaggregate_by_gender(patient_states) - ).count - end - - def self.gender_age_range_key(gender, age_bucket_index) - age_range_start = BUCKETS[age_bucket_index - 1] - if age_range_start == BUCKETS.last - "#{gender}_#{age_range_start}_plus" - else - age_range_end = BUCKETS[age_bucket_index] - 1 - "#{gender}_#{age_range_start}_#{age_range_end}" - end - end - - def self.current_month_period - @current_month_period ||= Period.current.previous - end -end diff --git a/app/exporters/dhis2/ethiopia_exporter.rb b/app/exporters/dhis2/ethiopia_exporter.rb deleted file mode 100644 index bad6b08c4a..0000000000 --- a/app/exporters/dhis2/ethiopia_exporter.rb +++ /dev/null @@ -1,30 +0,0 @@ -class Dhis2::EthiopiaExporter - PREVIOUS_MONTHS = 24 - - def self.export - current_month_period = Dhis2::Helpers.current_month_period - periods = (current_month_period.advance(months: -PREVIOUS_MONTHS)..current_month_period) - - exporter = Dhis2Exporter.new( - facility_identifiers: FacilityBusinessIdentifier.dhis2_org_unit_id, - periods: periods, - data_elements_map: CountryConfig.dhis2_data_elements.fetch(:dhis2_data_elements) - ) - - exporter.export do |facility_identifier, period| - region = facility_identifier.facility.region - - { - htn_controlled: Dhis2::Helpers.htn_controlled(region, period), - htn_cumulative_assigned: Dhis2::Helpers.htn_cumulative_assigned(region, period), - htn_cumulative_assigned_adjusted: Dhis2::Helpers.htn_cumulative_assigned_adjusted(region, period), - htn_cumulative_registrations: Dhis2::Helpers.htn_cumulative_registrations(region, period), - htn_dead: Dhis2::Helpers.htn_dead(region, period), - htn_monthly_registrations: Dhis2::Helpers.htn_monthly_registrations(region, period), - htn_ltfu: Dhis2::Helpers.htn_ltfu(region, period), - htn_missed_visits: Dhis2::Helpers.htn_missed_visits(region, period), - htn_uncontrolled: Dhis2::Helpers.htn_uncontrolled(region, period) - } - end - end -end diff --git a/app/exporters/dhis2/helpers.rb b/app/exporters/dhis2/helpers.rb deleted file mode 100644 index f5de8cbb22..0000000000 --- a/app/exporters/dhis2/helpers.rb +++ /dev/null @@ -1,68 +0,0 @@ -module Dhis2::Helpers - def self.current_month_period - @current_month_period ||= Period.current.previous - end - - def self.htn_controlled(region, period) - PatientStates::Hypertension::ControlledPatientsQuery - .new(region, period) - .call - .count - end - - def self.htn_cumulative_assigned(region, period) - PatientStates::Hypertension::CumulativeAssignedPatientsQuery - .new(region, period) - .call - .count - end - - def self.htn_cumulative_assigned_adjusted(region, period) - PatientStates::Hypertension::AdjustedAssignedPatientsQuery - .new(region, period) - .call - .count - end - - def self.htn_cumulative_registrations(region, period) - PatientStates::Hypertension::CumulativeRegistrationsQuery - .new(region, period) - .call - .count - end - - def self.htn_dead(region, period) - PatientStates::Hypertension::DeadPatientsQuery - .new(region, period) - .call - .count - end - - def self.htn_monthly_registrations(region, period) - PatientStates::Hypertension::MonthlyRegistrationsQuery - .new(region, period) - .call - .count - end - - def self.htn_ltfu(region, period) - PatientStates::Hypertension::LostToFollowUpPatientsQuery - .new(region, period) - .call - .count - end - - def self.htn_missed_visits(region, period) - PatientStates::Hypertension::MissedVisitsPatientsQuery - .new(region, period) - .call - .count - end - - def self.htn_uncontrolled(region, period) - PatientStates::Hypertension::UncontrolledPatientsQuery - .new(region, period) - .call - .count - end -end diff --git a/app/exporters/dhis2_exporter.rb b/app/exporters/dhis2_exporter.rb deleted file mode 100644 index 8ebe1a280f..0000000000 --- a/app/exporters/dhis2_exporter.rb +++ /dev/null @@ -1,79 +0,0 @@ -require "dhis2" -class Dhis2Exporter - attr_reader :facility_identifiers, :periods, :data_elements_map, :category_option_combo_ids - - def initialize(facility_identifiers:, periods:, data_elements_map:, category_option_combo_ids: []) - throw "DHIS2 export not enabled in Flipper" unless Flipper.enabled?(:dhis2_export) - - @facility_identifiers = facility_identifiers - @periods = periods - @data_elements_map = data_elements_map - @category_option_combo_ids = category_option_combo_ids - - Dhis2.configure do |config| - config.url = ENV.fetch("DHIS2_URL") - config.user = ENV.fetch("DHIS2_USERNAME") - config.password = ENV.fetch("DHIS2_PASSWORD") - config.version = ENV.fetch("DHIS2_VERSION") - end - end - - def export - @facility_identifiers.each do |facility_identifier| - data_values = [] - @periods.each do |period| - facility_data = yield(facility_identifier, period) - facility_data.each do |data_element, value| - data_values << { - data_element: data_elements_map[data_element], - org_unit: facility_identifier.identifier, - period: reporting_period(period), - value: value - } - puts "Adding data for #{facility_identifier.facility.name}, #{period}, #{data_element}: #{data_values.last}" - end - end - send_data_to_dhis2(data_values) - end - end - - def export_disaggregated - @facility_identifiers.each do |facility_identifier| - data_values = [] - @periods.each do |period| - facility_data = yield(facility_identifier, period) - facility_data.each do |data_element, value| - results = disaggregate_data_values(data_elements_map[data_element], facility_identifier, period, value) - data_values << results - results.each { |result| puts "Adding data for #{facility_identifier.facility.name}, #{period}, #{data_element}: #{result}" } - end - end - data_values = data_values.flatten - send_data_to_dhis2(data_values) - end - end - - def send_data_to_dhis2(data_values) - pp Dhis2.client.data_value_sets.bulk_create(data_values: data_values) - end - - def disaggregate_data_values(data_element_id, facility_identifier, period, values) - category_option_combo_ids.map do |combo, id| - { - data_element: data_element_id, - org_unit: facility_identifier.identifier, - category_option_combo: id, - period: reporting_period(period), - value: values.with_indifferent_access[combo] || 0 - } - end - end - - def reporting_period(month_period) - if Flipper.enabled?(:dhis2_use_ethiopian_calendar) - EthiopiaCalendarUtilities.gregorian_month_period_to_ethiopian(month_period).to_s(:dhis2) - else - month_period.to_s(:dhis2) - end - end -end diff --git a/app/jobs/dhis2/bangladesh_disaggregated_exporter_job.rb b/app/jobs/dhis2/bangladesh_disaggregated_exporter_job.rb new file mode 100644 index 0000000000..da57794e84 --- /dev/null +++ b/app/jobs/dhis2/bangladesh_disaggregated_exporter_job.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module Dhis2 + class BangladeshDisaggregatedExporterJob < Dhis2ExporterJob + MIN_AGE = 15 + MAX_AGE = 75 + AGE_BUCKET_SIZE = 5 + + private + + def facility_data_for_period(region, period) + { + htn_cumulative_assigned: PatientStates::Hypertension::CumulativeAssignedPatientsQuery.new(region, period).call, + htn_controlled: PatientStates::Hypertension::ControlledPatientsQuery.new(region, period).call, + htn_uncontrolled: PatientStates::Hypertension::UncontrolledPatientsQuery.new(region, period).call, + htn_missed_visits: PatientStates::Hypertension::MissedVisitsPatientsQuery.new(region, period).call, + htn_ltfu: PatientStates::Hypertension::LostToFollowUpPatientsQuery.new(region, period).call, + htn_dead: PatientStates::Hypertension::DeadPatientsQuery.new(region, period).call, + htn_cumulative_registrations: PatientStates::Hypertension::CumulativeRegistrationsQuery.new(region, period).call, + htn_monthly_registrations: PatientStates::Hypertension::MonthlyRegistrationsQuery.new(region, period).call, + htn_cumulative_assigned_adjusted: PatientStates::Hypertension::AdjustedAssignedPatientsQuery.new(region, period).call + }.transform_values { |patient_states| disaggregate_by_gender_age(patient_states, data_buckets(MIN_AGE, MAX_AGE, AGE_BUCKET_SIZE)) } + end + + def data_elements_map + CountryConfig.dhis2_data_elements.fetch(:disaggregated_dhis2_data_elements) + end + + def category_option_combo_ids + CountryConfig.dhis2_data_elements.fetch(:dhis2_category_option_combo) + end + + def format_facility_period_data(facility_data, facility_identifier, period) + formatted_facility_data = [] + facility_data.each do |data_element, values| + category_option_combo_ids.each do |combo, id| + formatted_facility_data << { + data_element: data_elements_map[data_element], + org_unit: facility_identifier.identifier, + category_option_combo: id, + period: reporting_period(period), + value: values.with_indifferent_access[combo] || 0 + } + end + end + formatted_facility_data + end + end +end diff --git a/app/jobs/dhis2/bangladesh_exporter_job.rb b/app/jobs/dhis2/bangladesh_exporter_job.rb new file mode 100644 index 0000000000..3b04f94354 --- /dev/null +++ b/app/jobs/dhis2/bangladesh_exporter_job.rb @@ -0,0 +1,23 @@ +module Dhis2 + class BangladeshExporterJob < Dhis2ExporterJob + private + + def facility_data_for_period(region, period) + { + htn_cumulative_assigned: PatientStates::Hypertension::CumulativeAssignedPatientsQuery.new(region, period).call.count, + htn_controlled: PatientStates::Hypertension::ControlledPatientsQuery.new(region, period).call.count, + htn_uncontrolled: PatientStates::Hypertension::UncontrolledPatientsQuery.new(region, period).call.count, + htn_missed_visits: PatientStates::Hypertension::MissedVisitsPatientsQuery.new(region, period).call.count, + htn_ltfu: PatientStates::Hypertension::LostToFollowUpPatientsQuery.new(region, period).call.count, + htn_dead: PatientStates::Hypertension::DeadPatientsQuery.new(region, period).call.count, + htn_cumulative_registrations: PatientStates::Hypertension::CumulativeRegistrationsQuery.new(region, period).call.count, + htn_monthly_registrations: PatientStates::Hypertension::MonthlyRegistrationsQuery.new(region, period).call.count, + htn_cumulative_assigned_adjusted: PatientStates::Hypertension::AdjustedAssignedPatientsQuery.new(region, period).call.count + } + end + + def data_elements_map + CountryConfig.dhis2_data_elements.fetch(:dhis2_data_elements) + end + end +end diff --git a/app/jobs/dhis2/dhis2_exporter_job.rb b/app/jobs/dhis2/dhis2_exporter_job.rb new file mode 100644 index 0000000000..741612008d --- /dev/null +++ b/app/jobs/dhis2/dhis2_exporter_job.rb @@ -0,0 +1,105 @@ +require "dhis2" + +module Dhis2 + class Dhis2ExporterJob + include Sidekiq::Job + + attr_reader :client + + def initialize + throw "DHIS2 export not enabled in Flipper" unless Flipper.enabled?(:dhis2_export) + + configuration = Dhis2::Configuration.new.tap do |config| + config.url = ENV.fetch("DHIS2_URL") + config.user = ENV.fetch("DHIS2_USERNAME") + config.password = ENV.fetch("DHIS2_PASSWORD") + config.version = ENV.fetch("DHIS2_VERSION") + end + @client = Dhis2::Client.new(configuration.client_params) + end + + def perform(facility_identifier_id, total_months) + facility_identifier = FacilityBusinessIdentifier.find(facility_identifier_id) + region = Region.find_by!(source_id: facility_identifier.facility_id) + periods = last_n_month_periods(total_months) + export_data = [] + periods.each do |period| + facility_data_for_period = facility_data_for_period(region, period) + export_data << format_facility_period_data( + facility_data_for_period, + facility_identifier, + period + ) + end + export(export_data.flatten) + Rails.logger.info("Dhis2::Dhis2ExporterJob for facility identifier #{facility_identifier} succeeded.") + end + + def export(data_values) + response = @client.data_value_sets.bulk_create(data_values: data_values) + Rails.logger.info("Exported to Dhis2 with response: ", response) + end + + def disaggregate_by_gender_age(patient_states, buckets) + gender_age_counts(patient_states, buckets).transform_keys do |(gender, age_bucket_index)| + gender_age_range_key(gender, buckets, age_bucket_index) + end + end + + private + + def facility_data_for_period(region, period) + raise NotImplementedError + end + + def format_facility_period_data(facility_data, facility_identifier, period) + formatted_facility_data = [] + facility_data.each do |data_element, value| + formatted_facility_data << { + data_element: data_elements_map[data_element], + org_unit: facility_identifier.identifier, + period: reporting_period(period), + value: value + } + end + formatted_facility_data + end + + def data_elements_map + raise NotImplementedError + end + + def last_n_month_periods(n) + (Period.current.advance(months: -n)..Period.current.previous) + end + + def reporting_period(month_period) + if Flipper.enabled?(:dhis2_use_ethiopian_calendar) + EthiopiaCalendarUtilities.gregorian_month_period_to_ethiopian(month_period).to_s(:dhis2) + else + month_period.to_s(:dhis2) + end + end + + def data_buckets(min, max, bucket_size) + (min..max).step(bucket_size).to_a + end + + def gender_age_counts(patient_states, buckets) + PatientStates::DisaggregatedPatientCountQuery.disaggregate_by_age( + buckets, + PatientStates::DisaggregatedPatientCountQuery.disaggregate_by_gender(patient_states) + ).count + end + + def gender_age_range_key(gender, buckets, age_bucket_index) + age_range_start = buckets[age_bucket_index - 1] + if age_range_start == buckets.last + "#{gender}_#{age_range_start}_plus" + else + age_range_end = buckets[age_bucket_index] - 1 + "#{gender}_#{age_range_start}_#{age_range_end}" + end + end + end +end diff --git a/app/jobs/dhis2/ethiopia_exporter_job.rb b/app/jobs/dhis2/ethiopia_exporter_job.rb new file mode 100644 index 0000000000..33f6d330eb --- /dev/null +++ b/app/jobs/dhis2/ethiopia_exporter_job.rb @@ -0,0 +1,23 @@ +module Dhis2 + class EthiopiaExporterJob < Dhis2ExporterJob + private + + def facility_data_for_period(region, period) + { + htn_cumulative_assigned: PatientStates::Hypertension::CumulativeAssignedPatientsQuery.new(region, period).call.count, + htn_controlled: PatientStates::Hypertension::ControlledPatientsQuery.new(region, period).call.count, + htn_uncontrolled: PatientStates::Hypertension::UncontrolledPatientsQuery.new(region, period).call.count, + htn_missed_visits: PatientStates::Hypertension::MissedVisitsPatientsQuery.new(region, period).call.count, + htn_ltfu: PatientStates::Hypertension::LostToFollowUpPatientsQuery.new(region, period).call.count, + htn_dead: PatientStates::Hypertension::DeadPatientsQuery.new(region, period).call.count, + htn_cumulative_registrations: PatientStates::Hypertension::CumulativeRegistrationsQuery.new(region, period).call.count, + htn_monthly_registrations: PatientStates::Hypertension::MonthlyRegistrationsQuery.new(region, period).call.count, + htn_cumulative_assigned_adjusted: PatientStates::Hypertension::AdjustedAssignedPatientsQuery.new(region, period).call.count + } + end + + def data_elements_map + CountryConfig.dhis2_data_elements.fetch(:dhis2_data_elements) + end + end +end diff --git a/config/data/dhis2/bangladesh-production.yml b/config/data/dhis2/bangladesh-production.yml index f885592c91..54ec46d281 100644 --- a/config/data/dhis2/bangladesh-production.yml +++ b/config/data/dhis2/bangladesh-production.yml @@ -1,24 +1,24 @@ -dhis2_data_elements: - cumulative_assigned: "eNtDKQTRdto" - cumulative_assigned_adjusted: "jCn7IIHtlXf" - controlled: "oVfmtlxYhOH" - uncontrolled: "QO2eTU3dW18" - missed_visits: "w7NRchlv0Rb" - ltfu: "w91dERGRhJ4" - dead: "SyduEtVKvlF" - cumulative_registrations: "bdMBWIf2i1h" - monthly_registrations: "tI9g0mtCzOv" +dhis2_data_elements: + htn_cumulative_assigned: "eNtDKQTRdto" + htn_cumulative_assigned_adjusted: "jCn7IIHtlXf" + htn_controlled: "oVfmtlxYhOH" + htn_uncontrolled: "QO2eTU3dW18" + htn_missed_visits: "w7NRchlv0Rb" + htn_ltfu: "w91dERGRhJ4" + htn_dead: "SyduEtVKvlF" + htn_cumulative_registrations: "bdMBWIf2i1h" + htn_monthly_registrations: "tI9g0mtCzOv" disaggregated_dhis2_data_elements: - htn_controlled_patients: "AA6Oc6DV3Lh" - htn_uncontrolled_patients: "zdjelro1SmB" - htn_cumulative_assigned_patients: "G6Btpbfkq2W" - htn_cumulative_assigned_patients_adjusted: "Xf20lyLSBmA" - htn_cumulative_registered_patients: "aiFkmP0vSur" - htn_dead_patients: "bIO8RQ1zSC7" - htn_monthly_registered_patients: "svwuMGBC3to" - htn_patients_lost_to_follow_up: "kjt9YiJPRYT" - htn_patients_who_missed_visits: "DktVuX67zy3" + htn_controlled: "AA6Oc6DV3Lh" + htn_uncontrolled: "zdjelro1SmB" + htn_cumulative_assigned: "G6Btpbfkq2W" + htn_cumulative_assigned_adjusted: "Xf20lyLSBmA" + htn_cumulative_registrations: "aiFkmP0vSur" + htn_dead: "bIO8RQ1zSC7" + htn_monthly_registrations: "svwuMGBC3to" + htn_ltfu: "kjt9YiJPRYT" + htn_missed_visits: "DktVuX67zy3" dhis2_category_option_combo: male_15_19: "lD5fJ7FH7F5" diff --git a/config/data/dhis2/sandbox.yml b/config/data/dhis2/sandbox.yml index 54049d60e2..a8df73165d 100644 --- a/config/data/dhis2/sandbox.yml +++ b/config/data/dhis2/sandbox.yml @@ -1,14 +1,14 @@ disaggregated_dhis2_data_elements: - htn_controlled_patients: "HjtYhPqccW1" - htn_uncontrolled_patients: "BrSik6uiybJ" - htn_cumulative_assigned_patients: "tJKupDifWrk" - htn_cumulative_assigned_patients_adjusted: "zxUkgo0WoG3" - htn_cumulative_registered_patients: "D2LQDgOKrY5" - htn_dead_patients: "w5wLncrFOa3" - htn_monthly_registered_patients: "LpfOZRIPSkH" - htn_patients_lost_to_follow_up: "JbbqrwFlrBn" - htn_patients_who_missed_visits: "pgC3wKFmKvm" - + htn_controlled: "HjtYhPqccW1" + htn_uncontrolled: "BrSik6uiybJ" + htn_cumulative_assigned: "tJKupDifWrk" + htn_cumulative_assigned_adjusted: "zxUkgo0WoG3" + htn_cumulative_registrations: "D2LQDgOKrY5" + htn_dead: "w5wLncrFOa3" + htn_monthly_registrations: "LpfOZRIPSkH" + htn_ltfu: "JbbqrwFlrBn" + htn_missed_visits: "pgC3wKFmKvm" + dhis2_category_option_combo: female_15_19: "rFFfisB1oI2" male_15_19: "a14qYZzDU6W" diff --git a/config/schedule.rb b/config/schedule.rb index ee8db53a99..a482a71489 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -106,7 +106,7 @@ def local(time) every 1.month, at: local("04:00 am"), roles: [:cron] do if Flipper.enabled?(:dhis2_export) - rake "dhis2:export" + rake "dhis2:bangladesh_export" end end diff --git a/lib/tasks/dhis2.rake b/lib/tasks/dhis2.rake index 90b3dec6a9..b74c4c0c4c 100644 --- a/lib/tasks/dhis2.rake +++ b/lib/tasks/dhis2.rake @@ -1,16 +1,22 @@ namespace :dhis2 do desc "Export indicator data of each facility to Bangladesh DHIS2" - task export: :environment do - BangladeshDhis2Exporter.export + task bangladesh_export: :environment do + FacilityBusinessIdentifier.dhis2_org_unit_id.each do |facility_identifier| + Dhis2::BangladeshExporterJob.perform_async(facility_identifier.id, 24) + end end desc "Export disaggregated indicator data of each facility to Bangladesh DHIS2" task bangladesh_disaggregated_export: :environment do - BangladeshDisaggregatedDhis2Exporter.export + FacilityBusinessIdentifier.dhis2_org_unit_id.each do |facility_identifier| + Dhis2::BangladeshDisaggregatedExporterJob.perform_async(facility_identifier.id, 24) + end end desc "Export data of each facility to Ethiopia DHIS2" task ethiopia_export: :environment do - Dhis2::EthiopiaExporter.export + FacilityBusinessIdentifier.dhis2_org_unit_id.each do |facility_identifier| + Dhis2::EthiopiaExporterJob.perform_async(facility_identifier.id, 24) + end end end diff --git a/spec/exporters/bangladesh_disaggregated_dhis2_exporter_spec.rb b/spec/exporters/bangladesh_disaggregated_dhis2_exporter_spec.rb deleted file mode 100644 index 70a0e923a9..0000000000 --- a/spec/exporters/bangladesh_disaggregated_dhis2_exporter_spec.rb +++ /dev/null @@ -1,113 +0,0 @@ -require "rails_helper" - -describe BangladeshDisaggregatedDhis2Exporter do - before(:each) do - Flipper.enable(:dhis2_export) - end - - before do - ENV["DHIS2_DATA_ELEMENTS_FILE"] = "config/data/dhis2/sandbox.yml" - Rails.application.config.country = CountryConfig.for(:BD) - end - - after do - Rails.application.config.country = CountryConfig.for(ENV.fetch("DEFAULT_COUNTRY")) - end - - describe ".export" do - it "should pass the correct config to the main exporter object" do - expected_arguments = { - facility_identifiers: FacilityBusinessIdentifier.dhis2_org_unit_id, - periods: (Period.current.previous.advance(months: -24)..Period.current.previous), - data_elements_map: CountryConfig.dhis2_data_elements.fetch(:disaggregated_dhis2_data_elements), - category_option_combo_ids: CountryConfig.dhis2_data_elements.fetch(:dhis2_category_option_combo) - } - - expect(Dhis2Exporter).to receive(:new).with(expected_arguments).and_call_original - - described_class.export - end - - it "should call export_disaggregated with a block that generates correct facility-period data for each facility-period combination" do - facility_identifier = create(:facility_business_identifier) - period = Period.current - - htn_cumulative_assigned_patients = "htn_cumulative_assigned_patients" - htn_controlled_patients = "htn_controlled_patients" - htn_uncontrolled_patients = "htn_uncontrolled_patients" - htn_patients_who_missed_visits = "htn_patients_who_missed_visits" - htn_patients_lost_to_follow_up = "htn_patients_lost_to_follow_up" - htn_dead_patients = "htn_dead_patients" - htn_cumulative_registered_patients = "htn_cumulative_registered_patients" - htn_monthly_registered_patients = "htn_monthly_registered_patients" - htn_cumulative_assigned_patients_adjusted = "htn_cumulative_assigned_patients_adjusted" - - expect_any_instance_of(PatientStates::Hypertension::CumulativeAssignedPatientsQuery).to receive(:call).and_return(htn_cumulative_assigned_patients) - expect_any_instance_of(PatientStates::Hypertension::ControlledPatientsQuery).to receive(:call).and_return(htn_controlled_patients) - expect_any_instance_of(PatientStates::Hypertension::UncontrolledPatientsQuery).to receive(:call).and_return(htn_uncontrolled_patients) - expect_any_instance_of(PatientStates::Hypertension::MissedVisitsPatientsQuery).to receive(:call).and_return(htn_patients_who_missed_visits) - expect_any_instance_of(PatientStates::Hypertension::LostToFollowUpPatientsQuery).to receive(:call).and_return(htn_patients_lost_to_follow_up) - expect_any_instance_of(PatientStates::Hypertension::DeadPatientsQuery).to receive(:call).and_return(htn_dead_patients) - expect_any_instance_of(PatientStates::Hypertension::CumulativeRegistrationsQuery).to receive(:call).and_return(htn_cumulative_registered_patients) - expect_any_instance_of(PatientStates::Hypertension::MonthlyRegistrationsQuery).to receive(:call).and_return(htn_monthly_registered_patients) - expect_any_instance_of(PatientStates::Hypertension::AdjustedAssignedPatientsQuery).to receive(:call).and_return(htn_cumulative_assigned_patients_adjusted) - - allow(described_class).to receive(:disaggregate_by_gender_age) do |value| - value - end - - expected_result_from_block = { - htn_cumulative_assigned_patients: htn_cumulative_assigned_patients, - htn_controlled_patients: htn_controlled_patients, - htn_uncontrolled_patients: htn_uncontrolled_patients, - htn_patients_who_missed_visits: htn_patients_who_missed_visits, - htn_patients_lost_to_follow_up: htn_patients_lost_to_follow_up, - htn_dead_patients: htn_dead_patients, - htn_cumulative_registered_patients: htn_cumulative_registered_patients, - htn_monthly_registered_patients: htn_monthly_registered_patients, - htn_cumulative_assigned_patients_adjusted: htn_cumulative_assigned_patients_adjusted - } - - expect_any_instance_of(Dhis2Exporter).to receive(:export_disaggregated) do |&block| - result = block.call(facility_identifier, period) - expect(result).to eq(expected_result_from_block) - end - - described_class.export - end - end - - describe ".disaggregate_by_gender_age" do - it "should take patient states and return their counts disaggregated by gender and age" do - _patient1 = create(:patient, gender: :male, age: 77) - _patient2 = create(:patient, gender: :male, age: 64) - _patient3 = create(:patient, gender: :female, age: 50) - _patient4 = create(:patient, gender: :transgender, age: 28) - - refresh_views - - patient_states = Reports::PatientState.all - expected_disaggregated_counts = { - "male_75_plus" => 1, - "male_60_64" => 1, - "female_50_54" => 1, - "transgender_25_29" => 1 - } - - expect(described_class.disaggregate_by_gender_age(patient_states)).to eq(expected_disaggregated_counts) - expect(described_class.disaggregate_by_gender_age(patient_states)).not_to have_key(:female_15_19) - end - end - - describe ".gender_age_range_symbol" do - it "should take a gender and age bucket index and return a symbol concatenating the gender and age range" do - gender = "male" - age_bucket_index = BangladeshDisaggregatedDhis2Exporter::BUCKETS.find_index(20) + 1 - expect(described_class.gender_age_range_key(gender, age_bucket_index)).to eq("male_20_24") - end - it "should append _plus in for the last age bucket" do - gender = "male" - expect(described_class.gender_age_range_key(gender, BangladeshDisaggregatedDhis2Exporter::BUCKETS.length)).to eq("male_75_plus") - end - end -end diff --git a/spec/exporters/dhis2/ethiopia_exporter_spec.rb b/spec/exporters/dhis2/ethiopia_exporter_spec.rb deleted file mode 100644 index e3efb0ba19..0000000000 --- a/spec/exporters/dhis2/ethiopia_exporter_spec.rb +++ /dev/null @@ -1,61 +0,0 @@ -require "rails_helper" -require "dhis2" - -describe Dhis2::EthiopiaExporter do - before(:each) do - Flipper.enable(:dhis2_export) - end - - before do - ENV["DHIS2_DATA_ELEMENTS_FILE"] = "config/data/dhis2/ethiopia-production.yml" - end - - describe ".export" do - let(:data_elements) { CountryConfig.dhis2_data_elements.fetch(:dhis2_data_elements) } - let(:facilities) { create_list(:facility, 2, :dhis2) } - let(:export_values) { - { - htn_controlled: :htn_controlled, - htn_cumulative_assigned: :htn_cumulative_assigned, - htn_cumulative_assigned_adjusted: :htn_cumulative_assigned_adjusted, - htn_cumulative_registrations: :htn_cumulative_registrations, - htn_dead: :htn_dead, - htn_monthly_registrations: :htn_monthly_registrations, - htn_ltfu: :htn_ltfu, - htn_missed_visits: :htn_missed_visits, - htn_uncontrolled: :htn_uncontrolled - } - } - - it "exports simple metrics for the last 24 months to dhis2 in ethiopia" do - current_month_period = Period.current.previous - periods = (current_month_period.advance(months: -24)..current_month_period) - - export_values.each do |key, value| - allow(Dhis2::Helpers).to receive(key).and_return(value) - end - - business_identifiers = facilities.flat_map { |facility| facility.business_identifiers.dhis2_org_unit_id } - expected_values = business_identifiers.map do |business_identifier| - periods.flat_map do |period| - export_values.keys.map do |key| - { - data_element: data_elements[key], - org_unit: business_identifier.identifier, - period: period.to_s(:dhis2), - value: export_values[key] - } - end - end - end - - data_value_sets = double - dhis2_client = double - allow(Dhis2).to receive(:client).and_return(dhis2_client) - allow(dhis2_client).to receive(:data_value_sets).and_return(data_value_sets) - expect(data_value_sets).to receive(:bulk_create).with(data_values: expected_values[0]) - expect(data_value_sets).to receive(:bulk_create).with(data_values: expected_values[1]) - Dhis2::EthiopiaExporter.export - end - end -end diff --git a/spec/exporters/dhis2_exporter_spec.rb b/spec/exporters/dhis2_exporter_spec.rb deleted file mode 100644 index 7293e555e8..0000000000 --- a/spec/exporters/dhis2_exporter_spec.rb +++ /dev/null @@ -1,172 +0,0 @@ -require "rails_helper" - -describe Dhis2Exporter do - let(:facilities) { create_list(:facility, 2) } - let(:facility_identifiers) { - facilities.map do |facility| - create(:facility_business_identifier, facility: facility) - end.to_a - } - let(:periods) { (Period.current.previous.advance(months: -1)..Period.current.previous).to_a } - let(:data_elements_map) { {indicator1: "indicator id 1", indicator2: "indicator id 2"} } - let(:category_option_combo_ids) { {category_option_combo1: "combo id 1", category_option_combo2: "combo id 2"} } - - before(:each) do - Flipper.enable(:dhis2_export) - end - - describe "#export" do - it "sends data element values for all facilities, given facility identifiers, periods and data elements" do - exporter = described_class.new( - facility_identifiers: facility_identifiers, - periods: periods, - data_elements_map: data_elements_map - ) - value = 0 - expected_data_values = facility_identifiers.map { |facility_identifier| - periods.product(data_elements_map.values).map { |period, data_element_id| - { - data_element: data_element_id, - org_unit: facility_identifier.identifier, - period: exporter.reporting_period(period), - value: value - } - } - } - - allow(exporter).to receive(:send_data_to_dhis2) - - expect(exporter).to receive(:send_data_to_dhis2).with(expected_data_values.first) - expect(exporter).to receive(:send_data_to_dhis2).with(expected_data_values.second) - - exporter.export do |_facility_identifier, _period| - { - data_elements_map.keys.first => value, - data_elements_map.keys.second => value - } - end - end - end - - describe "#export_disaggregated" do - it "sends disaggregated data element values for all facilities, given facility identifiers, periods and data elements" do - exporter = described_class.new( - facility_identifiers: facility_identifiers, - periods: periods, - data_elements_map: data_elements_map, - category_option_combo_ids: category_option_combo_ids - ) - value = 0 - expected_data_values = facility_identifiers.map do |facility_identifier| - periods.product(data_elements_map.values).map do |period, data_element_id| - category_option_combo_ids.map do |_combo, id| - { - data_element: data_element_id, - org_unit: facility_identifier.identifier, - category_option_combo: id, - period: exporter.reporting_period(period), - value: value - } - end - end.flatten - end - disaggregated_data_values = category_option_combo_ids.transform_values { |_value| value } - - allow(exporter).to receive(:send_data_to_dhis2) - - expect(exporter).to receive(:send_data_to_dhis2).with(expected_data_values.first) - expect(exporter).to receive(:send_data_to_dhis2).with(expected_data_values.second) - - exporter.export_disaggregated do |_facility_identifier, _period| - { - data_elements_map.keys.first => disaggregated_data_values, - data_elements_map.keys.second => disaggregated_data_values - } - end - end - end - - describe "#disaggregate_data_values" do - it "should return a list of disaggregated data values for each category-option combo for the given data element and period" do - value = 5 - facility_identifier = facility_identifiers.first - exporter = described_class.new( - facility_identifiers: [facility_identifier], - periods: periods, - data_elements_map: data_elements_map, - category_option_combo_ids: category_option_combo_ids - ) - indicator1_disaggregated_values = category_option_combo_ids.transform_values { |_value| value } - expected_disaggregated_values = category_option_combo_ids.map do |combo, id| - { - data_element: data_elements_map.keys.first, - org_unit: facility_identifier.identifier, - category_option_combo: id, - period: exporter.reporting_period(periods.first), - value: indicator1_disaggregated_values[combo] - } - end - - disaggregated_values = exporter.disaggregate_data_values( - exporter.data_elements_map.keys.first, - exporter.facility_identifiers.first, - exporter.periods.first, - indicator1_disaggregated_values - ) - - expect(disaggregated_values).to match_array(expected_disaggregated_values) - disaggregated_values.map do |export_value| - expect(export_value[:value]).not_to eq(nil) - end - end - - it "should set value to zero for category-option combos that don't have values for a given data element" do - value = 5 - period = "dummy2020" - indicator1_disaggregated_values = {category_option_combo_ids.keys.first => value} - - exporter = described_class.new( - facility_identifiers: facility_identifiers, - periods: periods, - data_elements_map: data_elements_map, - category_option_combo_ids: category_option_combo_ids - ) - allow(exporter).to receive(:reporting_period).and_return(period) - disaggregated_values = exporter.disaggregate_data_values( - exporter.data_elements_map.keys.first, - exporter.facility_identifiers.first, - exporter.periods.first, - indicator1_disaggregated_values - ) - - expect(disaggregated_values.first[:value]).to eq(value) - expect(disaggregated_values.second[:value]).to eq(0) - end - end - - describe "#reporting_period" do - it "should format month_date to DHIS2 format by the Ethiopian calendar if Flipper flag is enabled" do - Flipper.enable(:dhis2_use_ethiopian_calendar) - expected_month_date = EthiopiaCalendarUtilities.gregorian_month_period_to_ethiopian(periods.first).to_s(:dhis2) - exporter = described_class.new( - facility_identifiers: facility_identifiers, - periods: periods, - data_elements_map: data_elements_map - ) - - expect(exporter.reporting_period(periods.first)).to eq(expected_month_date) - end - - it "should format month_date to DHIS2 format by the Gregorian calendar if Flipper flag is disabled" do - Flipper.disable(:dhis2_use_ethiopian_calendar) - expected_month_date = periods.first.to_s(:dhis2) - exporter = described_class.new( - facility_identifiers: facility_identifiers, - periods: periods, - data_elements_map: data_elements_map - ) - - expect(exporter.reporting_period(periods.first)).to eq(expected_month_date) - end - end -end diff --git a/spec/jobs/dhis2/bangladesh_disaggregated_exporter_job_spec.rb b/spec/jobs/dhis2/bangladesh_disaggregated_exporter_job_spec.rb new file mode 100644 index 0000000000..6f40298c98 --- /dev/null +++ b/spec/jobs/dhis2/bangladesh_disaggregated_exporter_job_spec.rb @@ -0,0 +1,70 @@ +require "rails_helper" +require "dhis2" + +describe Dhis2::BangladeshDisaggregatedExporterJob do + describe "#perform" do + before do + allow(ENV).to receive(:fetch).and_call_original + allow(ENV).to receive(:fetch).with("DHIS2_DATA_ELEMENTS_FILE").and_return("config/data/dhis2/bangladesh-production.yml") + allow(Flipper).to receive(:enabled?).with(:dhis2_export).and_return(true) + allow(Flipper).to receive(:enabled?).with(:dhis2_use_ethiopian_calendar).and_return(false) + end + let(:data_elements) { CountryConfig.dhis2_data_elements.fetch(:disaggregated_dhis2_data_elements) } + let(:category_option_combo_ids) { CountryConfig.dhis2_data_elements.fetch(:dhis2_category_option_combo) } + let(:age_buckets) { [15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75] } + let(:facility_data) { + { + htn_cumulative_assigned: :htn_cumulative_assigned, + htn_controlled: :htn_controlled, + htn_uncontrolled: :htn_uncontrolled, + htn_missed_visits: :htn_missed_visits, + htn_ltfu: :htn_ltfu, + htn_dead: :htn_dead, + htn_cumulative_registrations: :htn_cumulative_registrations, + htn_monthly_registrations: :htn_monthly_registrations, + htn_cumulative_assigned_adjusted: :htn_cumulative_assigned_adjusted + } + } + + it "exports disaggregated HTN metrics for a facility over the last n months to Bangladesh DHIS2" do + facility_identifier = create(:facility_business_identifier) + total_months = 2 + periods = (Period.current.advance(months: -total_months)..Period.current.previous) + export_data = [] + periods.each do |period| + facility_data.each do |data_element, value| + allow_any_instance_of(described_class).to receive(:disaggregate_by_gender_age).with(data_element, age_buckets).and_return({data_element => value}) + category_option_combo_ids.each do |_combo, id| + export_data << { + data_element: data_elements[data_element], + org_unit: facility_identifier.identifier, + category_option_combo: id, + period: period.to_s(:dhis2), + value: 0 + } + end + end + end + + allow_any_instance_of(PatientStates::Hypertension::CumulativeAssignedPatientsQuery).to receive(:call).and_return(:htn_cumulative_assigned) + allow_any_instance_of(PatientStates::Hypertension::ControlledPatientsQuery).to receive(:call).and_return(:htn_controlled) + allow_any_instance_of(PatientStates::Hypertension::UncontrolledPatientsQuery).to receive(:call).and_return(:htn_uncontrolled) + allow_any_instance_of(PatientStates::Hypertension::MissedVisitsPatientsQuery).to receive(:call).and_return(:htn_missed_visits) + allow_any_instance_of(PatientStates::Hypertension::LostToFollowUpPatientsQuery).to receive(:call).and_return(:htn_ltfu) + allow_any_instance_of(PatientStates::Hypertension::DeadPatientsQuery).to receive(:call).and_return(:htn_dead) + allow_any_instance_of(PatientStates::Hypertension::CumulativeRegistrationsQuery).to receive(:call).and_return(:htn_cumulative_registrations) + allow_any_instance_of(PatientStates::Hypertension::MonthlyRegistrationsQuery).to receive(:call).and_return(:htn_monthly_registrations) + allow_any_instance_of(PatientStates::Hypertension::AdjustedAssignedPatientsQuery).to receive(:call).and_return(:htn_cumulative_assigned_adjusted) + client = double + data_value_sets = double + allow_any_instance_of(Dhis2::Configuration).to receive(:client_params).and_return({}) + allow(Dhis2::Client).to receive(:new).with({}).and_return(client) + allow(client).to receive(:data_value_sets).and_return(data_value_sets) + expect(data_value_sets).to receive(:bulk_create).with(data_values: export_data.flatten) + + Sidekiq::Testing.inline! do + described_class.perform_async(facility_identifier.id, total_months) + end + end + end +end diff --git a/spec/jobs/dhis2/bangladesh_exporter_job_spec.rb b/spec/jobs/dhis2/bangladesh_exporter_job_spec.rb new file mode 100644 index 0000000000..a5e7b43159 --- /dev/null +++ b/spec/jobs/dhis2/bangladesh_exporter_job_spec.rb @@ -0,0 +1,65 @@ +require "rails_helper" +require "dhis2" + +describe Dhis2::BangladeshExporterJob do + describe "#perform" do + before do + allow(ENV).to receive(:fetch).and_call_original + allow(ENV).to receive(:fetch).with("DHIS2_DATA_ELEMENTS_FILE").and_return("config/data/dhis2/bangladesh-production.yml") + allow(Flipper).to receive(:enabled?).with(:dhis2_export).and_return(true) + allow(Flipper).to receive(:enabled?).with(:dhis2_use_ethiopian_calendar).and_return(false) + end + let(:data_elements) { CountryConfig.dhis2_data_elements.fetch(:dhis2_data_elements) } + let(:facility_data) { + { + htn_cumulative_assigned: :htn_cumulative_assigned, + htn_controlled: :htn_controlled, + htn_uncontrolled: :htn_uncontrolled, + htn_missed_visits: :htn_missed_visits, + htn_ltfu: :htn_ltfu, + htn_dead: :htn_dead, + htn_cumulative_registrations: :htn_cumulative_registrations, + htn_monthly_registrations: :htn_monthly_registrations, + htn_cumulative_assigned_adjusted: :htn_cumulative_assigned_adjusted + } + } + + it "exports HTN metrics required by Bangladesh for a facility for the last n months to DHIS2" do + facility_identifier = create(:facility_business_identifier) + total_months = 2 + periods = (Period.current.advance(months: -total_months)..Period.current.previous) + export_data = [] + periods.each do |period| + facility_data.each do |data_element, value| + export_data << { + data_element: data_elements[data_element], + org_unit: facility_identifier.identifier, + period: period.to_s(:dhis2), + value: value + } + end + end + + expect_any_instance_of(PatientStates::Hypertension::CumulativeAssignedPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_cumulative_assigned) + expect_any_instance_of(PatientStates::Hypertension::ControlledPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_controlled) + expect_any_instance_of(PatientStates::Hypertension::UncontrolledPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_uncontrolled) + expect_any_instance_of(PatientStates::Hypertension::MissedVisitsPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_missed_visits) + expect_any_instance_of(PatientStates::Hypertension::LostToFollowUpPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_ltfu) + expect_any_instance_of(PatientStates::Hypertension::DeadPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_dead) + expect_any_instance_of(PatientStates::Hypertension::CumulativeRegistrationsQuery).to receive_message_chain(:call, :count).and_return(:htn_cumulative_registrations) + expect_any_instance_of(PatientStates::Hypertension::MonthlyRegistrationsQuery).to receive_message_chain(:call, :count).and_return(:htn_monthly_registrations) + expect_any_instance_of(PatientStates::Hypertension::AdjustedAssignedPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_cumulative_assigned_adjusted) + client = double + data_value_sets = double + configuration = {} + allow_any_instance_of(Dhis2::Configuration).to receive(:client_params).and_return(configuration) + allow(Dhis2::Client).to receive(:new).with(configuration).and_return(client) + allow(client).to receive(:data_value_sets).and_return(data_value_sets) + expect(data_value_sets).to receive(:bulk_create).with(data_values: export_data.flatten) + + Sidekiq::Testing.inline! do + described_class.perform_async(facility_identifier.id, total_months) + end + end + end +end diff --git a/spec/jobs/dhis2/ethiopia_exporter_job_spec.rb b/spec/jobs/dhis2/ethiopia_exporter_job_spec.rb new file mode 100644 index 0000000000..1c880dff17 --- /dev/null +++ b/spec/jobs/dhis2/ethiopia_exporter_job_spec.rb @@ -0,0 +1,65 @@ +require "rails_helper" +require "dhis2" + +describe Dhis2::EthiopiaExporterJob do + describe "#perform" do + before do + allow(ENV).to receive(:fetch).and_call_original + allow(ENV).to receive(:fetch).with("DHIS2_DATA_ELEMENTS_FILE").and_return("config/data/dhis2/ethiopia-production.yml") + allow(Flipper).to receive(:enabled?).with(:dhis2_export).and_return(true) + allow(Flipper).to receive(:enabled?).with(:dhis2_use_ethiopian_calendar).and_return(true) + end + let(:data_elements) { CountryConfig.dhis2_data_elements.fetch(:dhis2_data_elements) } + let(:facility_data) { + { + htn_cumulative_assigned: :htn_cumulative_assigned, + htn_controlled: :htn_controlled, + htn_uncontrolled: :htn_uncontrolled, + htn_missed_visits: :htn_missed_visits, + htn_ltfu: :htn_ltfu, + htn_dead: :htn_dead, + htn_cumulative_registrations: :htn_cumulative_registrations, + htn_monthly_registrations: :htn_monthly_registrations, + htn_cumulative_assigned_adjusted: :htn_cumulative_assigned_adjusted + } + } + + it "exports HTN metrics required by Ethiopia for a facility for the last n months to DHIS2" do + facility_identifier = create(:facility_business_identifier) + total_months = 2 + periods = (Period.current.advance(months: -total_months)..Period.current.previous) + export_data = [] + periods.each do |period| + facility_data.each do |data_element, value| + export_data << { + data_element: data_elements[data_element], + org_unit: facility_identifier.identifier, + period: EthiopiaCalendarUtilities.gregorian_month_period_to_ethiopian(period).to_s(:dhis2), + value: value + } + end + end + + expect_any_instance_of(PatientStates::Hypertension::CumulativeAssignedPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_cumulative_assigned) + expect_any_instance_of(PatientStates::Hypertension::ControlledPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_controlled) + expect_any_instance_of(PatientStates::Hypertension::UncontrolledPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_uncontrolled) + expect_any_instance_of(PatientStates::Hypertension::MissedVisitsPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_missed_visits) + expect_any_instance_of(PatientStates::Hypertension::LostToFollowUpPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_ltfu) + expect_any_instance_of(PatientStates::Hypertension::DeadPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_dead) + expect_any_instance_of(PatientStates::Hypertension::CumulativeRegistrationsQuery).to receive_message_chain(:call, :count).and_return(:htn_cumulative_registrations) + expect_any_instance_of(PatientStates::Hypertension::MonthlyRegistrationsQuery).to receive_message_chain(:call, :count).and_return(:htn_monthly_registrations) + expect_any_instance_of(PatientStates::Hypertension::AdjustedAssignedPatientsQuery).to receive_message_chain(:call, :count).and_return(:htn_cumulative_assigned_adjusted) + client = double + data_value_sets = double + configuration = {} + allow_any_instance_of(Dhis2::Configuration).to receive(:client_params).and_return(configuration) + allow(Dhis2::Client).to receive(:new).with(configuration).and_return(client) + allow(client).to receive(:data_value_sets).and_return(data_value_sets) + expect(data_value_sets).to receive(:bulk_create).with(data_values: export_data.flatten) + + Sidekiq::Testing.inline! do + described_class.perform_async(facility_identifier.id, total_months) + end + end + end +end