require_dependency "renalware/medications" module Renalware module Medications class PrescriptionsController < BaseController include PrescriptionsHelper include PresenterHelper before_action :load_patient def index @treatable = treatable_class.find(treatable_id) respond_to do |format| format.html { render_index } format.js { render_index } format.pdf { render_prescriptions_list_to_hand_to_patient } end end def new @treatable = treatable_class.find(treatable_id) prescription = build_new_prescription_for(@treatable) render_form(prescription, url: patient_prescriptions_path(patient, @treatable)) end def create @treatable = treatable_class.find(treatable_id) prescription = patient.prescriptions.new( prescription_params.merge(treatable: @treatable) ) if prescription.save render_index else render_form(prescription, url: patient_prescriptions_path(patient, @treatable)) end end def edit prescription = patient.prescriptions.find(params[:id]) @treatable = prescription.treatable render_form(prescription, url: patient_prescription_path(patient, prescription)) end def update prescription = patient.prescriptions.find(params[:id]) @treatable = prescription.treatable updated = RevisePrescription.new(prescription).call(prescription_params) if updated render_index else render_form(prescription, url: patient_prescription_path(patient, prescription)) end end private def build_new_prescription_for(treatable) gp_provider_code = Provider.codes.find{ |code| code == :gp } prescription = Prescription.new(treatable: treatable, provider: gp_provider_code) prescription.build_termination prescription end def render_index render :index, locals: locals end # rubocop:disable Metrics/LineLength # rubocop:disable Metrics/MethodLength def render_prescriptions_list_to_hand_to_patient render( pdf_options.merge( pdf: pdf_filename, disposition: "inline", print_media_type: true, locals: { patient: patient, current_prescriptions: present(current_prescriptions, PrescriptionPresenter), recently_stopped_prescriptions: present(recently_stopped_prescriptions, PrescriptionPresenter), recently_changed_prescriptions: present(recently_changed_current_prescriptions, PrescriptionPresenter) } )) end # rubocop:enable Metrics/LineLength # rubocop:enable Metrics/MethodLength def pdf_filename "#{patient.family_name}_#{patient.hospital_identifier&.id}" \ "_medications_#{I18n.l(Time.zone.today)}".upcase end def pdf_options { page_size: "A4", layout: "renalware/layouts/letter", show_as_html: params.key?(:debug), footer: { font_size: 8, right: "page [page] of [topage]" } } end def locals { patient: patient, treatable: present(@treatable, TreatablePresenter), current_search: current_prescriptions_query.search, current_prescriptions: present(current_prescriptions, PrescriptionPresenter), historical_prescriptions_search: historical_prescriptions_query.search, historical_prescriptions: present(historical_prescriptions, PrescriptionPresenter), drug_types: find_drug_types } end def render_form(prescription, url:) render "form", locals: { patient: patient, treatable: @treatable, prescription: prescription, provider_codes: present(Provider.codes, ProviderCodePresenter), medication_routes: present(MedicationRoute.all, RouteFormPresenter), url: url } end def treatable_class @treatable_class ||= treatable_type.singularize.classify.constantize end def prescription_params params .require(:medications_prescription) .permit(prescription_attributes) .to_h .deep_merge(by: current_user, termination_attributes: { by: current_user }) end def prescription_attributes [ :drug_id, :dose_amount, :dose_unit, :medication_route_id, :frequency, :administer_on_hd, :route_description, :notes, :prescribed_on, :provider, :last_delivery_date, { termination_attributes: :terminated_on } ] end def treatable_type params.fetch(:treatable_type) end def treatable_id params.fetch(:treatable_id) end def current_prescriptions_query @current_prescriptions_query ||= PrescriptionsQuery.new( relation: @treatable.prescriptions.current, search_params: params[:q] ) end def current_prescriptions call_query(current_prescriptions_query) end def historical_prescriptions_query @historical_prescriptions_query ||= PrescriptionsQuery.new( relation: @treatable.prescriptions, search_params: params[:q] ) end # Prescriptions created or with dosage changed in the last 14 days. # Because we terminated a prescription if the dosage changes, and create a new one, # we just need to search for prescriptions created in the last 14 days. def recently_changed_current_prescriptions @recently_changed_prescriptions ||= begin current_prescriptions_query .call .prescribed_between(from: 14.days.ago, to: ::Time.zone.now) end end # Find prescriptions terminated within 14 days. # Note we do not include those prescriptions which might have just had a dose change # so they were implicitly terminated and re-created. We only want ones which were explicitly # terminated. def recently_stopped_prescriptions @recently_stopped_prescriptions ||= begin historical_prescriptions_query.call .terminated .terminated_between(from: 14.days.ago, to: ::Time.zone.now) .where.not(drug_id: current_prescriptions.map(&:drug_id)) end end def call_query(query) query .call .with_created_by .with_medication_route .with_drugs .with_termination end def historical_prescriptions call_query(historical_prescriptions_query) end def find_drug_types Drugs::Type.all end end end end