# frozen_string_literal: true require 'fuzzy_match' module Nuva module Queries class ValencesByVaccine 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 VaccinesByValence 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 VaccinesByDisease 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 ValencesByDisease 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 DiseasesByVaccine 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 DiseasesByValence 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 VaccineFuzzySearch def initialize(repositories) @engine = FuzzyMatch.new(repositories.vaccines.all, read: ->(v) { v.name }) end def call(pattern) @engine.find_all(pattern) end end # lookupVaccineByCode(code: string): Vaccine | undefined; # lookupEquivalentVaccines(vaccine: Vaccine): Vaccine[]; # lookupSpecializedVaccines(vaccine: Vaccine): Vaccine[]; # lookupGeneralizedVaccines(vaccine: Vaccine): Vaccine[]; # allNomenclatures(): string[]; # allCodeByNomenclature(): { # [nomenclature: string]: Code[]; # }; class LookupVaccineByCode def initialize(repositories) @vaccines = repositories.vaccines end def call(code) @vaccines.all.find do |vac| "NUVA-#{vac.code}" == code || vac.codes.any? do |x| x.value == code end end end end class LookupEquivalentVaccines 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 LookupGeneralizedVaccines 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 do |v| -@valencesByVaccine.(v).length end 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 AllNomenclatures def initialize(repositories) @vaccines = repositories.vaccines end def call (@vaccines.all.flat_map do |v| v.codes.map(&:nomenclature) end).uniq end end class AllCodeByNomenclature def initialize(repositories) @vaccines = repositories.vaccines end def call @vaccines .all .flat_map(&:codes) .reduce(Hash.new { |hash, key| hash[key] = [] }) { |hash, code| hash[code.nomenclature] << code.value hash } .map { |key, value| [key, value.uniq] } .to_h end end end end