# frozen_string_literal: true module Reports::FlagsStatus extend ActiveSupport::Concern class_methods do def report_flags_status(report) report.modes = [:table] report.labels = [ { type: :post, properties: { topic_id: :topic_id, number: :post_number, truncated_raw: :post_type, }, title: I18n.t("reports.flags_status.labels.flag"), }, { type: :user, properties: { username: :staff_username, id: :staff_id, avatar: :staff_avatar_template, }, title: I18n.t("reports.flags_status.labels.assigned"), }, { type: :user, properties: { username: :poster_username, id: :poster_id, avatar: :poster_avatar_template, }, title: I18n.t("reports.flags_status.labels.poster"), }, { type: :user, properties: { username: :flagger_username, id: :flagger_id, avatar: :flagger_avatar_template, }, title: I18n.t("reports.flags_status.labels.flagger"), }, { type: :seconds, property: :response_time, title: I18n.t("reports.flags_status.labels.time_to_resolution"), }, ] report.data = [] flag_types = PostActionType.flag_types sql = <<~SQL WITH period_actions AS ( SELECT id, post_action_type_id, created_at, agreed_at, disagreed_at, deferred_at, agreed_by_id, disagreed_by_id, deferred_by_id, post_id, user_id, COALESCE(disagreed_at, agreed_at, deferred_at) AS responded_at FROM post_actions WHERE post_action_type_id IN (#{flag_types.values.join(",")}) AND created_at >= '#{report.start_date}' AND created_at <= '#{report.end_date}' ORDER BY created_at DESC ), poster_data AS ( SELECT pa.id, p.user_id AS poster_id, p.topic_id as topic_id, p.post_number as post_number, u.username_lower AS poster_username, u.uploaded_avatar_id AS poster_avatar_id FROM period_actions pa JOIN posts p ON p.id = pa.post_id JOIN users u ON u.id = p.user_id ), flagger_data AS ( SELECT pa.id, u.id AS flagger_id, u.username_lower AS flagger_username, u.uploaded_avatar_id AS flagger_avatar_id FROM period_actions pa JOIN users u ON u.id = pa.user_id ), staff_data AS ( SELECT pa.id, u.id AS staff_id, u.username_lower AS staff_username, u.uploaded_avatar_id AS staff_avatar_id FROM period_actions pa JOIN users u ON u.id = COALESCE(pa.agreed_by_id, pa.disagreed_by_id, pa.deferred_by_id) ) SELECT sd.staff_username, sd.staff_id, sd.staff_avatar_id, pd.poster_username, pd.poster_id, pd.poster_avatar_id, pd.post_number, pd.topic_id, fd.flagger_username, fd.flagger_id, fd.flagger_avatar_id, pa.post_action_type_id, pa.created_at, pa.agreed_at, pa.disagreed_at, pa.deferred_at, pa.agreed_by_id, pa.disagreed_by_id, pa.deferred_by_id, COALESCE(pa.disagreed_at, pa.agreed_at, pa.deferred_at) AS responded_at FROM period_actions pa FULL OUTER JOIN staff_data sd ON sd.id = pa.id FULL OUTER JOIN flagger_data fd ON fd.id = pa.id FULL OUTER JOIN poster_data pd ON pd.id = pa.id SQL DB .query(sql) .each do |row| data = {} data[:post_type] = flag_types.key(row.post_action_type_id).to_s data[:post_number] = row.post_number data[:topic_id] = row.topic_id if row.staff_id data[:staff_username] = row.staff_username data[:staff_id] = row.staff_id data[:staff_avatar_template] = User.avatar_template( row.staff_username, row.staff_avatar_id, ) end if row.poster_id data[:poster_username] = row.poster_username data[:poster_id] = row.poster_id data[:poster_avatar_template] = User.avatar_template( row.poster_username, row.poster_avatar_id, ) end if row.flagger_id data[:flagger_id] = row.flagger_id data[:flagger_username] = row.flagger_username data[:flagger_avatar_template] = User.avatar_template( row.flagger_username, row.flagger_avatar_id, ) end if row.agreed_by_id data[:resolution] = I18n.t("reports.flags_status.values.agreed") elsif row.disagreed_by_id data[:resolution] = I18n.t("reports.flags_status.values.disagreed") elsif row.deferred_by_id data[:resolution] = I18n.t("reports.flags_status.values.deferred") else data[:resolution] = I18n.t("reports.flags_status.values.no_action") end data[:response_time] = row.responded_at ? row.responded_at - row.created_at : nil report.data << data end end end end