2020-10-02 16:29:34 +02:00
|
|
|
# == Schema Information
|
|
|
|
#
|
|
|
|
# Table name: stats
|
|
|
|
#
|
|
|
|
# id :bigint not null, primary key
|
2020-10-06 14:23:15 +02:00
|
|
|
# administrations_partenaires :bigint default(0)
|
2020-10-02 16:29:34 +02:00
|
|
|
# dossiers_brouillon :bigint default(0)
|
|
|
|
# dossiers_cumulative :jsonb not null
|
|
|
|
# dossiers_depose_avant_30_jours :bigint default(0)
|
|
|
|
# dossiers_deposes_entre_60_et_30_jours :bigint default(0)
|
|
|
|
# dossiers_en_construction :bigint default(0)
|
|
|
|
# dossiers_en_instruction :bigint default(0)
|
|
|
|
# dossiers_in_the_last_4_months :jsonb not null
|
|
|
|
# dossiers_not_brouillon :bigint default(0)
|
|
|
|
# dossiers_termines :bigint default(0)
|
|
|
|
# created_at :datetime not null
|
|
|
|
# updated_at :datetime not null
|
|
|
|
#
|
|
|
|
class Stat < ApplicationRecord
|
|
|
|
class << self
|
|
|
|
def update_stats
|
2021-11-25 09:11:05 +01:00
|
|
|
states = sum_hashes(dossiers_states, deleted_dossiers_states)
|
2020-10-02 16:29:34 +02:00
|
|
|
stat = Stat.first || Stat.new
|
|
|
|
|
|
|
|
stat.update(
|
|
|
|
dossiers_en_construction: states['en_construction'],
|
|
|
|
dossiers_en_instruction: states['en_instruction'],
|
|
|
|
dossiers_brouillon: states['brouillon'],
|
|
|
|
dossiers_depose_avant_30_jours: states['dossiers_depose_avant_30_jours'],
|
|
|
|
dossiers_deposes_entre_60_et_30_jours: states['dossiers_deposes_entre_60_et_30_jours'],
|
|
|
|
dossiers_not_brouillon: states['not_brouillon'],
|
|
|
|
dossiers_termines: states['termines'],
|
2021-11-25 09:11:05 +01:00
|
|
|
dossiers_cumulative: cumulative_hash([
|
2021-12-06 15:49:17 +01:00
|
|
|
[Dossier.state_not_brouillon, :depose_at],
|
2021-11-25 09:11:05 +01:00
|
|
|
[DeletedDossier.where.not(state: :brouillon), :deleted_at]
|
|
|
|
]),
|
|
|
|
dossiers_in_the_last_4_months: last_four_months_hash([
|
2021-12-06 15:49:17 +01:00
|
|
|
[Dossier.state_not_brouillon, :depose_at],
|
2021-11-25 09:11:05 +01:00
|
|
|
[DeletedDossier.where.not(state: :brouillon), :deleted_at]
|
|
|
|
]),
|
2020-10-06 14:23:15 +02:00
|
|
|
administrations_partenaires: AdministrateursProcedure.joins(:procedure).merge(Procedure.publiees_ou_closes).select('distinct administrateur_id').count
|
2020-10-02 16:29:34 +02:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def dossiers_states
|
2021-11-25 09:11:05 +01:00
|
|
|
sanitize_and_exec(Dossier, <<-EOF
|
|
|
|
SELECT
|
|
|
|
COUNT(*) FILTER ( WHERE state != 'brouillon' ) AS "not_brouillon",
|
2021-12-06 15:49:17 +01:00
|
|
|
COUNT(*) FILTER ( WHERE state != 'brouillon' and depose_at BETWEEN :one_month_ago AND :now ) AS "dossiers_depose_avant_30_jours",
|
|
|
|
COUNT(*) FILTER ( WHERE state != 'brouillon' and depose_at BETWEEN :two_months_ago AND :one_month_ago ) AS "dossiers_deposes_entre_60_et_30_jours",
|
2021-11-25 09:11:05 +01:00
|
|
|
COUNT(*) FILTER ( WHERE state = 'brouillon' ) AS "brouillon",
|
|
|
|
COUNT(*) FILTER ( WHERE state = 'en_construction' ) AS "en_construction",
|
|
|
|
COUNT(*) FILTER ( WHERE state = 'en_instruction' ) AS "en_instruction",
|
|
|
|
COUNT(*) FILTER ( WHERE state in ('accepte', 'refuse', 'sans_suite') ) AS "termines"
|
|
|
|
FROM dossiers
|
|
|
|
WHERE hidden_at IS NULL
|
2020-10-02 16:29:34 +02:00
|
|
|
EOF
|
2021-11-25 09:11:05 +01:00
|
|
|
)
|
|
|
|
end
|
2020-10-02 16:29:34 +02:00
|
|
|
|
2021-11-25 09:11:05 +01:00
|
|
|
def deleted_dossiers_states
|
|
|
|
sanitize_and_exec(DeletedDossier, <<-EOF
|
|
|
|
SELECT
|
|
|
|
COUNT(*) FILTER ( WHERE state != 'brouillon' ) AS "not_brouillon",
|
|
|
|
COUNT(*) FILTER ( WHERE state != 'brouillon' and deleted_at BETWEEN :one_month_ago AND :now ) AS "dossiers_depose_avant_30_jours",
|
|
|
|
COUNT(*) FILTER ( WHERE state != 'brouillon' and deleted_at BETWEEN :two_months_ago AND :one_month_ago ) AS "dossiers_deposes_entre_60_et_30_jours",
|
|
|
|
COUNT(*) FILTER ( WHERE state = 'brouillon' ) AS "brouillon",
|
|
|
|
COUNT(*) FILTER ( WHERE state = 'en_construction' ) AS "en_construction",
|
|
|
|
COUNT(*) FILTER ( WHERE state = 'en_instruction' ) AS "en_instruction",
|
|
|
|
COUNT(*) FILTER ( WHERE state in ('accepte', 'refuse', 'sans_suite') ) AS "termines"
|
|
|
|
FROM deleted_dossiers
|
|
|
|
EOF
|
|
|
|
)
|
2020-10-02 16:29:34 +02:00
|
|
|
end
|
|
|
|
|
2021-11-25 09:11:05 +01:00
|
|
|
def last_four_months_hash(associations_with_date_attribute)
|
2021-12-02 03:15:00 +01:00
|
|
|
min_date = 3.months.ago.beginning_of_month
|
2021-11-25 09:11:05 +01:00
|
|
|
timeseries = associations_with_date_attribute.map do |association, date_attribute|
|
|
|
|
association
|
|
|
|
.where(date_attribute => min_date..max_date)
|
2021-12-02 03:15:00 +01:00
|
|
|
.group("DATE_TRUNC('month', #{date_attribute}::TIMESTAMPTZ AT TIME ZONE '#{Time.zone.formatted_offset}'::INTERVAL)")
|
2021-11-25 09:11:05 +01:00
|
|
|
.count
|
|
|
|
end
|
2020-10-02 16:29:34 +02:00
|
|
|
|
2021-11-25 09:11:05 +01:00
|
|
|
sum_hashes(*timeseries)
|
2020-10-02 16:29:34 +02:00
|
|
|
.to_a
|
|
|
|
.sort_by { |a| a[0] }
|
|
|
|
.map { |e| [I18n.l(e.first, format: "%B %Y"), e.last] }
|
|
|
|
end
|
|
|
|
|
2021-11-25 09:11:05 +01:00
|
|
|
def cumulative_hash(associations_with_date_attribute)
|
|
|
|
timeseries = associations_with_date_attribute.map do |association, date_attribute|
|
|
|
|
association
|
|
|
|
.where("#{date_attribute} < ?", max_date)
|
2021-12-02 03:15:00 +01:00
|
|
|
.group("DATE_TRUNC('month', #{date_attribute}::TIMESTAMPTZ AT TIME ZONE '#{Time.zone.formatted_offset}'::INTERVAL)")
|
2021-11-25 09:11:05 +01:00
|
|
|
.count
|
|
|
|
end
|
|
|
|
|
2020-10-02 16:29:34 +02:00
|
|
|
sum = 0
|
2021-11-25 09:11:05 +01:00
|
|
|
sum_hashes(*timeseries)
|
2020-10-02 16:29:34 +02:00
|
|
|
.to_a
|
|
|
|
.sort_by { |a| a[0] }
|
|
|
|
.map { |x, y| { x => (sum += y) } }
|
|
|
|
.reduce({}, :merge)
|
|
|
|
end
|
|
|
|
|
2021-11-25 09:11:05 +01:00
|
|
|
def sum_hashes(*hashes)
|
|
|
|
{}.merge(*hashes) { |_k, hash_one_value, hash_two_value| hash_one_value + hash_two_value }
|
|
|
|
end
|
|
|
|
|
2020-10-02 16:29:34 +02:00
|
|
|
def max_date
|
|
|
|
Time.zone.now.beginning_of_month - 1.second
|
|
|
|
end
|
2021-11-25 09:11:05 +01:00
|
|
|
|
|
|
|
def sanitize_and_exec(model, query)
|
|
|
|
sanitized_query = ActiveRecord::Base.sanitize_sql([
|
|
|
|
query,
|
|
|
|
now: Time.zone.now,
|
|
|
|
one_month_ago: 1.month.ago,
|
|
|
|
two_months_ago: 2.months.ago
|
|
|
|
])
|
|
|
|
model.connection.select_all(sanitized_query).first
|
|
|
|
end
|
2020-10-02 16:29:34 +02:00
|
|
|
end
|
|
|
|
end
|