# frozen_string_literal: true require "fuzzy_match" module Nuva module Queries class Query def inspect "#<#{self.class.name}>" end end class ValencesByVaccineQuery < Query def initialize(repositories) hash = Hash.new { |h, k| h[k] = [] } @valences_by_vaccine_id = repositories[:valences] .all .reduce(hash) do |acc, valence| valence.vaccine_ids.each do |vaccine_id| acc[vaccine_id] << valence end acc end end def call(vaccine) @valences_by_vaccine_id[vaccine.id] end end class VaccinesByValenceQuery < Query def initialize(repositories) hash = Hash.new { |h, k| h[k] = [] } @vaccines_by_valence_id = repositories[:vaccines] .all .reduce(hash) do |acc, vaccine| vaccine.valence_ids.each do |valence_id| acc[valence_id] << vaccine end acc end end def call(valence) @vaccines_by_valence_id[valence.id] end end class VaccinesByDiseaseQuery < Query def initialize(repositories) hash = Hash.new { |h, k| h[k] = [] } @vaccines_by_disease_id = repositories[:valences] .all .reduce(hash) do |acc, valence| valence.disease_ids.each do |disease_id| valence.vaccine_ids.each do |vaccine_id| acc[disease_id] << repositories[:vaccines].find(vaccine_id) end end acc end end def call(disease) @vaccines_by_disease_id[disease.id].uniq(&:id) end end class ValencesByDiseaseQuery < Query def initialize(repositories) hash = Hash.new { |h, k| h[k] = [] } @valences_by_disease_id = repositories[:valences] .all .reduce(hash) do |acc, valence| valence.disease_ids.each do |disease_id| acc[disease_id] << valence end acc end end def call(disease) @valences_by_disease_id[disease.id] end end class DiseasesByVaccineQuery < Query def initialize(repositories) hash = Hash.new { |h, k| h[k] = [] } @diseases_by_vaccine_id = repositories[:valences] .all .reduce(hash) do |acc, valence| valence.vaccine_ids.each do |vaccine_id| valence.disease_ids.each do |disease_id| acc[vaccine_id] << repositories[:diseases].find(disease_id) end end acc end end def call(vaccine) @diseases_by_vaccine_id[vaccine.id].uniq(&:id) end end class DiseasesByValenceQuery < Query def initialize(repositories) hash = Hash.new { |h, k| h[k] = [] } @diseases_by_valence_id = repositories[:diseases] .all .reduce(hash) do |acc, disease| disease.valence_ids.each do |valence_id| acc[valence_id] << disease end acc end end def call(valence) @diseases_by_valence_id[valence.id] end end class VaccineFuzzySearchQuery < Query def initialize(repositories) @engine = FuzzyMatch.new(repositories.vaccines.all, read: ->(v) { v.name }) end def call(pattern) @engine.find_all(pattern) end end class LookupVaccineByCodeQuery < Query def initialize(repositories) @vaccines = repositories.vaccines end def call(code) @vaccines.all.find do |vac| "NUVA-#{vac.code}" == code || vac.codes.any? { |x| x.value == code } end end end class LookupEquivalentVaccinesQuery < Query def initialize(repositories) @vaccines = repositories.vaccines end def call(vaccine) vids = vaccine.valence_ids.sort @vaccines.all.filter do |v| v.valence_ids.length == vids.length && v.id != vaccine.id && vids == v.valence_ids.sort end end end class LookupGeneralizedVaccinesQuery < Query def initialize(repositories, valencesByVaccine) @vaccines = repositories.vaccines @valences = repositories.valences @valencesByVaccine = valencesByVaccine end def call(vaccine) targetValences = @valencesByVaccine.(vaccine) list = @vaccines.all.filter do |candidate| next if candidate.id == vaccine.id || !candidate.generic @valencesByVaccine .(candidate) .all? do |candidateValence| targetValences.any? do |targetValence| parent_of?(candidateValence, targetValence) end end end list.sort_by { |v| -@valencesByVaccine.(v).length } end private def child_of?(valence, parent) until valence.nil? return true if valence.id == parent.id valence = @valences.find(valence.parent_id) end false end def parent_of?(parent, child) child_of?(child, parent) end end class AllNomenclaturesQuery < Query def initialize(repositories) @vaccines = repositories.vaccines end def call (@vaccines.all.flat_map { |v| v.codes.map(&:nomenclature) }).uniq end end class AllCodeByNomenclatureQuery < Query def initialize(repositories) @vaccines = repositories.vaccines end def call @vaccines .all .flat_map(&:codes) .reduce(Hash.new { |hash, key| hash[key] = [] }) do |hash, code| hash[code.nomenclature] << code.value hash end .map { |key, value| [key, value.uniq] } .to_h end end end end