|
| 1 | +# frozen_string_literal: true |
| 2 | + |
| 3 | +class CaseContactDatatable < ApplicationDatatable |
| 4 | + ORDERABLE_FIELDS = %w[ |
| 5 | + occurred_at |
| 6 | + contact_made |
| 7 | + medium_type |
| 8 | + duration_minutes |
| 9 | + ].freeze |
| 10 | + |
| 11 | + private |
| 12 | + |
| 13 | + def data |
| 14 | + records.map do |case_contact| |
| 15 | + { |
| 16 | + id: case_contact.id, |
| 17 | + occurred_at: I18n.l(case_contact.occurred_at, format: :full, default: nil), |
| 18 | + casa_case: { |
| 19 | + id: case_contact.casa_case_id, |
| 20 | + case_number: case_contact.casa_case&.case_number |
| 21 | + }, |
| 22 | + contact_types: case_contact.contact_types.map(&:name).join(", "), |
| 23 | + medium_type: case_contact.medium_type&.titleize, |
| 24 | + creator: { |
| 25 | + id: case_contact.creator_id, |
| 26 | + display_name: case_contact.creator&.display_name, |
| 27 | + email: case_contact.creator&.email, |
| 28 | + role: case_contact.creator&.role |
| 29 | + }, |
| 30 | + contact_made: case_contact.contact_made, |
| 31 | + duration_minutes: case_contact.duration_minutes, |
| 32 | + contact_topics: case_contact.contact_topics.map(&:question).join(" | "), |
| 33 | + is_draft: !case_contact.active?, |
| 34 | + has_followup: case_contact.followups.requested.exists? |
| 35 | + } |
| 36 | + end |
| 37 | + end |
| 38 | + |
| 39 | + def filtered_records |
| 40 | + raw_records.where(search_filter) |
| 41 | + end |
| 42 | + |
| 43 | + def raw_records |
| 44 | + base_relation |
| 45 | + .joins("INNER JOIN users creators ON creators.id = case_contacts.creator_id") |
| 46 | + .left_joins(:casa_case) |
| 47 | + .includes(:contact_types, :contact_topics, :followups, :creator) |
| 48 | + .order(order_clause) |
| 49 | + .order(:id) |
| 50 | + end |
| 51 | + |
| 52 | + def search_filter |
| 53 | + return "TRUE" if search_term.blank? |
| 54 | + |
| 55 | + ilike_fields = %w[ |
| 56 | + creators.display_name |
| 57 | + creators.email |
| 58 | + casa_cases.case_number |
| 59 | + case_contacts.notes |
| 60 | + ] |
| 61 | + |
| 62 | + ilike_clauses = ilike_fields.map { |field| "#{field} ILIKE ?" }.join(" OR ") |
| 63 | + contact_type_clause = "case_contacts.id IN (#{contact_type_search_subquery})" |
| 64 | + |
| 65 | + full_clause = "#{ilike_clauses} OR #{contact_type_clause}" |
| 66 | + [full_clause, ilike_fields.count.times.map { "%#{search_term}%" }].flatten |
| 67 | + end |
| 68 | + |
| 69 | + def contact_type_search_subquery |
| 70 | + @contact_type_search_subquery ||= lambda { |
| 71 | + return "SELECT NULL WHERE FALSE" if search_term.blank? |
| 72 | + |
| 73 | + CaseContact |
| 74 | + .select("DISTINCT case_contacts.id") |
| 75 | + .joins(case_contact_contact_types: :contact_type) |
| 76 | + .where("contact_types.name ILIKE ?", "%#{search_term}%") |
| 77 | + .to_sql |
| 78 | + }.call |
| 79 | + end |
| 80 | + |
| 81 | + def order_clause |
| 82 | + @order_clause ||= build_order_clause |
| 83 | + end |
| 84 | +end |
0 commit comments