Skip to content

Commit

Permalink
Merge pull request #1889 from projectcypress/master
Browse files Browse the repository at this point in the history
Merge 7/31
  • Loading branch information
dczulada authored Jul 31, 2024
2 parents 16becaa + cc4e6ae commit efe851a
Show file tree
Hide file tree
Showing 26 changed files with 2,221 additions and 188 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ gem 'os'

gem 'cqm-models', '~> 4.2.0'
gem 'cqm-parsers', '~> 4.1.1.0'
gem 'cqm-reports', '~> 4.1.0'
gem 'cqm-reports', '~> 4.1.2'
gem 'cqm-validators', '~> 4.0.5'

# # Use faker to generate addresses
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ GEM
typhoeus
uuid (~> 2.3.7)
zip-zip (~> 0.3)
cqm-reports (4.1.1)
cqm-reports (4.1.2)
cqm-models (~> 4.0)
cqm-validators (~> 4.0)
erubis (~> 2.7)
Expand Down Expand Up @@ -608,7 +608,7 @@ DEPENDENCIES
codecov
cqm-models (~> 4.2.0)
cqm-parsers (~> 4.1.1.0)
cqm-reports (~> 4.1.0)
cqm-reports (~> 4.1.2)
cqm-validators (~> 4.0.5)
cucumber-rails
daemons
Expand Down
22 changes: 0 additions & 22 deletions app/helpers/filtering_tests_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,26 +53,4 @@ def providers_val(val)

arr
end

def generate_filter_patients(filter_tests)
return unless filter_tests

test = filter_tests.pop
test.generate_patients
test.save
test.queued
ProductTestSetupJob.perform_later(test)
patients = test.patients
filter_tests.each do |ft|
patients.collect do |p|
p2 = p.clone
p2.correlation_id = ft.id
p2.save
p2
end
ft.save
ft.queued
ProductTestSetupJob.perform_later(ft)
end
end
end
4 changes: 2 additions & 2 deletions app/helpers/products_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ module ProductsHelper
def should_show_product_tests_tab?(product, test_type)
case test_type
when 'MeasureTest'
product.product_tests.measure_tests.any?
product.c1_test || product.c2_test
when 'MultiMeasureTest'
product.product_tests.multi_measure_tests.any?
when 'CMSProgramTest'
product.product_tests.cms_program_tests.any?
when 'FilteringTest'
product.product_tests.filtering_tests.any?
product.c4_test
when 'ChecklistTest'
product.c1_test # should not check for existance of checklist test since there a user can delete checklist tests
else
Expand Down
56 changes: 56 additions & 0 deletions app/jobs/filter_test_setup_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# frozen_string_literal: true

class FilterTestSetupJob < ApplicationJob
queue_as :filter_test_setup
include Job::Status
def perform(product)
product = Product.find(product)
add_filtering_tests(product)
end

def add_filtering_tests(product)
measure = ApplicationController.helpers.pick_measure_for_filtering_test(product.measure_ids, product.bundle)
product.reload_relations

return if product.product_tests.filtering_tests.any?

# TODO: R2P: check new criteria names
criteria = %w[races ethnicities genders payers age].shuffle
filter_tests = []
filter_tests.push(build_filtering_test(product, measure, criteria[0, 2]), build_filtering_test(product, measure, criteria[2, 2]))
filter_tests << build_filtering_test(product, measure, ['providers'], 'NPI, TIN & Provider Location')
filter_tests << build_filtering_test(product, measure, ['providers'], 'NPI & TIN', incl_addr: false)
criteria = ApplicationController.helpers.measure_has_snomed_dx_criteria?(measure) ? ['problems'] : criteria.values_at(4, (0..3).to_a.sample)
filter_tests << build_filtering_test(product, measure, criteria)
generate_filter_patients(filter_tests)
end

def build_filtering_test(product, measure, criteria, display_name = '', incl_addr: true)
# construct options hash from criteria array and create the test
options = { 'filters' => criteria.to_h { |c| [c, []] } }
product.product_tests.create({ name: measure.description, product:, measure_ids: [measure.hqmf_id], cms_id: measure.cms_id,
incl_addr:, display_name:, options: }, FilteringTest)
end

def generate_filter_patients(filter_tests)
return unless filter_tests

test = filter_tests.pop
test.generate_patients
test.save
test.queued
ProductTestSetupJob.perform_later(test)
patients = test.patients
filter_tests.each do |ft|
patients.collect do |p|
p2 = p.clone
p2.correlation_id = ft.id
p2.save
p2
end
ft.save
ft.queued
ProductTestSetupJob.perform_later(ft)
end
end
end
3 changes: 1 addition & 2 deletions app/models/c2_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ def good_results
false
end
options = { provider: product_test.patients.first.providers.first, submission_program: cat3_submission_program,
start_time: start_date, end_time: end_date, ry2022_submission: product_test.bundle.major_version == '2021',
ry2025_submission: product_test.bundle.major_version == '2024' }
start_time: start_date, end_time: end_date, ry2025_submission: product_test.bundle.major_version == '2024' }
Qrda3.new(product_test.expected_results_with_all_supplemental_codes, product_test.measures, options).render
end

Expand Down
2 changes: 1 addition & 1 deletion app/models/cat3_filter_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def good_results
false
end
options = { provider: product_test.patients.first.providers.first, submission_program: cat3_submission_program,
start_time: start_date, end_time: end_date, ry2022_submission: product_test.bundle.major_version == '2021' }
start_time: start_date, end_time: end_date, ry2025_submission: product_test.bundle.major_version == '2024' }
Qrda3.new(product_test.expected_results_with_all_supplemental_codes, product_test.measures, options).render
end
end
2 changes: 1 addition & 1 deletion app/models/multi_measure_cat3_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def execute(file, user)
def good_results
# Set the Submission Program to MIPS_INDIV
options = { provider: product_test.patients.first.providers.first, submission_program: 'MIPS_INDIV',
start_time: start_date, end_time: end_date, ry2022_submission: product_test.bundle.major_version == '2021' }
start_time: start_date, end_time: end_date, ry2025_submission: product_test.bundle.major_version == '2024' }
Qrda3.new(product_test.expected_results_with_all_supplemental_codes, product_test.measures, options).render
end
end
26 changes: 1 addition & 25 deletions app/models/product.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ def update_with_tests(params)
def update_with_certification_tests(params)
add_measure_tests(params)
save!
add_filtering_tests if c4_test
add_checklist_test if c1_test
FilterTestSetupJob.perform_later(id.to_s) if c4_test
end

def update_with_cvu_plus_tests(params)
Expand Down Expand Up @@ -235,23 +235,6 @@ def add_hl7_tests(measure_ids)
reporting_program_type: 'ep' }, CMSProgramTest)
end

def add_filtering_tests
measure = ApplicationController.helpers.pick_measure_for_filtering_test(measure_ids, bundle)
reload_relations

return if product_tests.filtering_tests.any?

# TODO: R2P: check new criteria names
criteria = %w[races ethnicities genders payers age].shuffle
filter_tests = []
filter_tests.push(build_filtering_test(measure, criteria[0, 2]), build_filtering_test(measure, criteria[2, 2]))
filter_tests << build_filtering_test(measure, ['providers'], 'NPI, TIN & Provider Location')
filter_tests << build_filtering_test(measure, ['providers'], 'NPI & TIN', incl_addr: false)
criteria = ApplicationController.helpers.measure_has_snomed_dx_criteria?(measure) ? ['problems'] : criteria.values_at(4, (0..3).to_a.sample)
filter_tests << build_filtering_test(measure, criteria)
ApplicationController.helpers.generate_filter_patients(filter_tests)
end

def ep_tests?
product_tests.any?(&:ep_measures?)
end
Expand All @@ -277,11 +260,4 @@ def enforce_duplicate_patient_settings

true
end

def build_filtering_test(measure, criteria, display_name = '', incl_addr: true)
# construct options hash from criteria array and create the test
options = { 'filters' => criteria.to_h { |c| [c, []] } }
product_tests.create({ name: measure.description, product: self, measure_ids: [measure.hqmf_id], cms_id: measure.cms_id,
incl_addr:, display_name:, options: }, FilteringTest)
end
end
7 changes: 4 additions & 3 deletions app/views/products/_bulk_download.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
# must specify local variable "product"
#
%>
<% num_measure_tests = product.product_tests.measure_tests.count + product.product_tests.multi_measure_tests.count %>
<% num_measure_tests_ready = product.product_tests.measure_tests.where(state: :ready).count + product.product_tests.multi_measure_tests.where(state: :ready).count %>
<% total_filtering_tests = product.c4_test? ? 5 : 0 %>
<% num_measure_tests = product.product_tests.measure_tests.count + total_filtering_tests + product.product_tests.multi_measure_tests.count %>
<% num_measure_tests_ready = product.product_tests.measure_tests.where(state: :ready).count + product.product_tests.filtering_tests.where(state: :ready).count + product.product_tests.multi_measure_tests.where(state: :ready).count %>
<% if num_measure_tests_ready == num_measure_tests %>
<p>This download contains a folder for each measure selected for this product. Inside these folders are XML documents for each patient associated with that measure.</p>
<%= form_for product, url: patients_vendor_product_path(product.vendor_id, product), :html => { :method => 'GET' } do |f| %>
Expand All @@ -18,7 +19,7 @@
One or more of the product tests did not build correctly.
<% else %>
<p>Patient records are being built for each measure.</p>
<p><%= icon('fas fa-fw fa-spin', 'sync-alt', :"aria-hidden" => true) %><%= " #{num_measure_tests_ready} of #{num_measure_tests} measures ready" %></p>
<p><%= icon('fas fa-fw fa-spin', 'sync-alt', :"aria-hidden" => true) %><%= " #{num_measure_tests_ready} of #{num_measure_tests} tests ready" %></p>
<script>
$.ajax({url: "<%= request.env['PATH_INFO'] %>", type: "GET", dataType: 'script', data: { partial: 'bulk_download' }});
</script>
Expand Down
21 changes: 1 addition & 20 deletions app/views/records/_risk_variable_display.html.erb
Original file line number Diff line number Diff line change
@@ -1,25 +1,6 @@
<% encounter_ids = individual_result.episode_results&.keys %>
<% individual_result.collect_risk_variables.each do |key, rv_value| %>
<% next if rv_value[:values].empty? %>
<ul><%= key %>
<% rv_value[:values].each do |encounter_id, values| %>
<% if values.is_a? Hash %>
<% if values.values.compact.empty? %>
<ul>No Values Reported</ul>
<% else %>
<ul><%= "Encounter #{encounter_ids.index(encounter_id) + 1}" %></ul>
<% values.each do |key, value| %>
<% next unless value %>
<ul><%= "#{key} - #{value}"%></ul>
<% end %>
<% end %>
<% else %>
<% if encounter_id == "Other" %>
<ul><%= values%></ul>
<% else %>
<ul><%= "Encounter #{encounter_ids.index(encounter_id) + 1}"%> <%= " - #{values}" if values != 'Encounter, Performed' %></ul>
<% end %>
<% end %>
<% end %>
<pre class="pre-code"><%= JSON.pretty_generate(rv_value) %></pre>
</ul>
<% end %>
1 change: 0 additions & 1 deletion config/cypress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ version_config:
code: "854901"
codeSystem: "2.16.840.1.113883.6.88"
CMSQRDA3SchematronValidator_warnings:
- '2025 CMS QRDA III Implementation Guide for Eligible Clinicians is not available'
CMSQRDA1HQRSchematronValidator_warnings:

# Configuration for values to use when randomizing patients in test decks
Expand Down
2 changes: 1 addition & 1 deletion config/initializers/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Cypress
class Application
VERSION = '7.3.0'.freeze
VERSION = '7.3.1'.freeze
end
end
1 change: 1 addition & 0 deletions features/step_definitions/filtering_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
measure_ids: }
@product.update_with_tests(product_params)
wait_for_all_delayed_jobs_to_run
wait_for_all_delayed_jobs_to_run
@f_test1 = @product.product_tests.filtering_tests[0]
@f_test2 = @product.product_tests.filtering_tests[1]
end
Expand Down
3 changes: 2 additions & 1 deletion features/step_definitions/product.rb
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,8 @@ def build_product
product = @product
product.c4_test = true
product.save!
product.add_filtering_tests
FilterTestSetupJob.perform_later(product.id.to_s)
wait_for_all_delayed_jobs_to_run
end

# product test number the number of product test (1 indexed) for upload in order of most recently created
Expand Down
4 changes: 2 additions & 2 deletions features/step_definitions/record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@
end

Then(/^the user sees details$/) do
page.assert_text "Cypress Certification Patient Test Record: #{@patient.first_names} #{@patient.familyName}"
page.assert_text "Patient Test Record: #{@patient.first_names} #{@patient.familyName}"
page.assert_text @patient.gender
@measures = @bundle.measures.where(:_id.in => @patient.calculation_results.map(&:measure_id))
sf_patient = @patient.clone
Expand Down Expand Up @@ -185,7 +185,7 @@
end

Then(/^the user should see vendor patient details$/) do
page.assert_text "Cypress Certification Patient Test Record: #{@patient.first_names} #{@patient.familyName}"
page.assert_text "Patient Test Record: #{@patient.first_names} #{@patient.familyName}"
page.assert_text @patient.gender
page.assert_text 'View Logic Highlighting'
page.first('button', text: 'View Logic Highlighting').click
Expand Down
39 changes: 25 additions & 14 deletions lib/cypress/api_measure_evaluator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,14 @@ def run_measure_eval(c1_c2_test, c4_test)
end

def run_vendor_tests(vendor_link, measures, product_name, skip_c1_test, bundle_id)
setup_vendor_test(vendor_link, measures, product_name, skip_c1_test, bundle_id)
product_tests_link = setup_vendor_test(vendor_link, measures, product_name, skip_c1_test, bundle_id)
download_patient_test_data
@patient_links_task_hash.each do |patient_links|
calcuate_cat3(patient_links[0].split('/')[2], bundle_id)
upload_test_execution(extract_test_execution_link(patient_links[1], 'C1'), patient_links[0].split('/')[2], true) unless skip_c1_test
upload_test_execution(extract_test_execution_link(patient_links[1], 'C2'), patient_links[0].split('/')[2], false, skip_c1_test)
end
populate_filter_patient_download_hashes(product_tests_link)
download_filter_data
calculate_filtered_cat3(bundle_id)
upload_c4_test_executions
Expand Down Expand Up @@ -118,11 +119,12 @@ def setup_vendor_test(vendor_link, measures, product_name, skip_c1_test, bundle_
product_tests = parsed_api_object(call_get_product_tests(product_tests_link))

product_tests.each do |product_test|
populate_patient_download_hashes(product_test)
populate_measure_patient_download_hashes(product_test)
end
product_tests_link
end

def populate_patient_download_hashes(product_test)
def populate_measure_patient_download_hashes(product_test)
# get link for product test tasks
case product_test.type
when 'measure'
Expand All @@ -135,16 +137,25 @@ def populate_patient_download_hashes(product_test)
@patient_links_task_hash[patient_download_link] = parsed_api_object(product_test_tasks)
# hash of patient list with product tests - this is used to see if the patiets are ready
@patient_link_product_test_hash[patient_download_link] = extract_link(product_test, 'self')
when 'filter'
product_test_tasks_link = extract_link(product_test, 'tasks')
# get product tasks objects
product_test_tasks = parsed_api_object(call_get_product_test_tasks(product_test_tasks_link))
product_test_tasks.each do |product_test_task|
task_link = extract_link(product_test_task, 'self')
if product_test_task.type == 'Ct1Filter'
@cat1_filter_hash[extract_link(product_test, 'self')] = task_link
else
@cat3_filter_hash[extract_link(product_test, 'self')] = task_link
end
end

def populate_filter_patient_download_hashes(product_tests_link)
product_tests = parsed_api_object(call_get_product_tests(product_tests_link))
product_tests.each do |product_test|
# get link for product test tasks
case product_test.type
when 'filter'
product_test_tasks_link = extract_link(product_test, 'tasks')
# get product tasks objects
product_test_tasks = parsed_api_object(call_get_product_test_tasks(product_test_tasks_link))
product_test_tasks.each do |product_test_task|
task_link = extract_link(product_test_task, 'self')
if product_test_task.type == 'Ct1Filter'
@cat1_filter_hash[extract_link(product_test, 'self')] = task_link
else
@cat3_filter_hash[extract_link(product_test, 'self')] = task_link
end
end
end
end
Expand Down Expand Up @@ -477,7 +488,7 @@ def calcuate_cat3(product_test_id, bundle_id)
false
end
options = { provider: pt.patients.first.providers.first, submission_program: cat3_submission_program,
start_time: pt.start_date, end_time: pt.end_date, ry2022_submission: pt.bundle.major_version == '2021' }
start_time: pt.start_date, end_time: pt.end_date, ry2025_submission: pt.bundle.major_version == '2024' }
xml = Qrda3.new(results, pt.measures, options).render

Patient.find(patient_ids).each(&:destroy)
Expand Down
Loading

0 comments on commit efe851a

Please sign in to comment.