diff --git a/.rubocop.yml b/.rubocop.yml index b05f0c547..828578211 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -114,7 +114,7 @@ Style/LineEndConcatenation: Enabled: false Layout/LineLength: - Max: 80 + Max: 100 Metrics/MethodLength: Enabled: false diff --git a/app/admin/dashboard.rb b/app/admin/dashboard.rb index 5279e5308..647b6d254 100644 --- a/app/admin/dashboard.rb +++ b/app/admin/dashboard.rb @@ -16,16 +16,20 @@ column do panel "Recent Users" do ul do - User.last(5).map do |u| - li link_to(u, admin_user_path(u)) + User.last(5).map do |user| + li link_to(user, admin_user_path(user)) end end end end column do - panel "Info" do - para "Welcome to ActiveAdmin." + panel "Recent Posts" do + ul do + Post.last(5).map do |post| + li link_to(post, admin_post_path(post)) + end + end end end end diff --git a/app/controllers/statistics_controller.rb b/app/controllers/statistics_controller.rb index ded39a636..ba2e4c9e3 100644 --- a/app/controllers/statistics_controller.rb +++ b/app/controllers/statistics_controller.rb @@ -1,92 +1,75 @@ class StatisticsController < ApplicationController - AGE_GROUP_LABELS = { - 0..17 => " -17", - 18..24 => "18-24", - 25..34 => "25-34", - 35..44 => "35-44", - 45..54 => "45-54", - 55..64 => "55-64", - 65..100 => "65+", - } - before_action :authenticate_user! - def statistics_global_activity - @members = current_organization.members - @active_members = @members.active + def global_activity + members = current_organization.members + @active_members = members.active + @total_hours = num_movements = 0 - @members.each do |m| + members.each do |m| num_movements += m.account.movements.count @total_hours += m.account.movements.map do |a| (a.amount > 0) ? a.amount : 0 end.inject(0, :+) end - # cada intercambio implica dos movimientos - @num_swaps = (num_movements + - current_organization.account.movements.count) / 2 - # intercambios con el banco @total_hours += current_organization.account.movements. map { |a| (a.amount > 0) ? a.amount : 0 }.inject(0, :+) - # periodo a mostrar actividades globales, por defecto 6 meses - ini = params[:ini].presence.try(:to_date) || DateTime.now.to_date - 5.month - fin = params[:fin].presence.try(:to_date) || DateTime.now.to_date - if ini.present? - # calculo numero de meses - num_months = (fin.year * 12 + fin.month) - (ini.year * 12 + ini.month) + 1 - date = ini - # vector para los meses de la gráfica ["Enero", "Febrero",...] - @months_names = [] - # y vectores con los datos para la gráfica - @user_reg_months = [] - @num_swaps_months = [] - @hours_swaps_months = [] - # valores por cada mes - num_months.times do - @months_names.push(l(date, format: "%B %Y")) - @user_reg_months.push(@members.by_month(date).count) - # movimientos de los miembros en dicho mes - swaps_members = @members.map { |a| a.account.movements.by_month(date) } - # movimimentos del banco - swaps_organization = current_organization.account. - movements.by_month(date) - # numero de movimientos totales - sum_swaps = (swaps_members.flatten.count + swaps_organization.count) / 2 - @num_swaps_months.push(sum_swaps) - # horas intercambiadas - sum_hours = 0 - swaps_members.flatten.each do |s| - sum_hours += (s.amount > 0) ? s.amount : 0 - end - sum_hours += swaps_organization.map do - |a| (a.amount > 0) ? a.amount : 0 - end.inject(0, :+) - sum_hours = sum_hours / 3600.0 if sum_hours > 0 - @hours_swaps_months.push(sum_hours) - date = date.next_month + + @num_swaps = (num_movements + current_organization.account.movements.count) / 2 + + from = params[:from].presence.try(:to_date) || DateTime.now.to_date - 5.month + to = params[:to].presence.try(:to_date) || DateTime.now.to_date + num_months = (to.year * 12 + to.month) - (from.year * 12 + from.month) + 1 + date = from + + @months_names = [] + @user_reg_months = [] + @num_swaps_months = [] + @hours_swaps_months = [] + + num_months.times do + @months_names << l(date, format: "%B %Y") + @user_reg_months << members.by_month(date).count + + swaps_members = members.map { |a| a.account.movements.by_month(date) } + swaps_organization = current_organization.account.movements.by_month(date) + sum_swaps = (swaps_members.flatten.count + swaps_organization.count) / 2 + @num_swaps_months << sum_swaps + + sum_hours = 0 + swaps_members.flatten.each do |s| + sum_hours += (s.amount > 0) ? s.amount : 0 end + sum_hours += swaps_organization.map do + |a| (a.amount > 0) ? a.amount : 0 + end.inject(0, :+) + sum_hours = sum_hours / 3600.0 if sum_hours > 0 + @hours_swaps_months << sum_hours + + date = date.next_month end end - def statistics_inactive_users + def inactive_users @members = current_organization.members.active end - def statistics_demographics - @members = current_organization.members - @age_counts = age_counts - @gender_counts = gender_counts + def demographics + members = current_organization.members + @age_counts = age_counts(members) + @gender_counts = gender_counts(members) end - def statistics_last_login + def last_login @members = current_organization.members.active.joins(:user). order("users.current_sign_in_at ASC NULLS FIRST") end - def statistics_without_offers + def without_offers @members = current_organization.members.active end - def statistics_type_swaps + def type_swaps offers = current_organization.posts. where(type: "Offer").joins(:transfers, transfers: :movements). select("posts.tags, posts.category_id, SUM(movements.amount) as @@ -99,7 +82,7 @@ def statistics_type_swaps sort_by(&:last).reverse end - def statistics_all_transfers + def all_transfers @transfers = current_organization.all_transfers. includes(movements: {account: :accountable}). order("transfers.created_at DESC"). @@ -110,73 +93,79 @@ def statistics_all_transfers protected - def age(date_of_birth) - return unless date_of_birth - age_in_days = Date.today - date_of_birth - (age_in_days / 365.26).to_i - end - - # returns a hash of - # { - # [ category_label, tag_label ] => [ sum, count, ratio ], - # ... - # } def count_offers_by_label(offers) - # Cannot use Hash.new([0, 0]) because then - # counters[key][0] += n + # Cannot use Hash.new([0, 0]) because then counters[key][0] += n # will modify directly the "global default" instead of # first assigning a new array with the zeroed counters. counters = Hash.new { |h, k| h[k] = [0, 0] } + offers.each do |offer| labels_for_offer(offer).each do |labels| - # labels = [ category_label, tag_label ] counters[labels][0] += offer.sum_of_transfers counters[labels][1] += offer.count_of_transfers end end - add_ratios!(counters) + add_ratios(counters) + counters end - def add_ratios!(counters) - # add the ratio at the end of each value + def add_ratios(counters) total_count = counters.values.map { |_, counts| counts }.sum + counters.each do |_, v| v << v[1].to_f / total_count end end - # returns an array of - # [category_name, tag_name] - # one item per each tag. If the category or the tags are missing, they are - # replaced with a fallback "Unknown" label. def labels_for_offer(offer) tag_labels = offer.tags.presence || - [t("statistics.statistics_type_swaps.without_tags")] + [t("statistics.type_swaps.without_tags")] category_label = offer.category.try(:name) || - t("statistics.statistics_type_swaps.without_category") + t("statistics.type_swaps.without_category") [category_label].product(tag_labels) end - def age_counts - @members.each_with_object(Hash.new(0)) do |member, counts| - age = age(member.user_date_of_birth) - age_label = AGE_GROUP_LABELS.detect do |range, _| + def age_counts(members) + members.each_with_object(Hash.new(0)) do |member, counts| + age = compute_age(member.user_date_of_birth) + + age_label = age_group_labels.detect do |range, _| range.include? age - end.try(:last) || t("statistics.statistics_demographics.unknown") + end.try(:last) || t("statistics.demographics.unknown") + counts[age_label] += 1 end end - def gender_counts - @members.each_with_object(Hash.new(0)) do |member, counts| + def compute_age(date_of_birth) + return unless date_of_birth + + age_in_days = Date.today - date_of_birth + (age_in_days / 365.26).to_i + end + + def age_group_labels + { + 0..17 => "-17", + 18..24 => "18-24", + 25..34 => "25-34", + 35..44 => "35-44", + 45..54 => "45-54", + 55..64 => "55-64", + 65..100 => "65+", + } + end + + def gender_counts(members) + members.each_with_object(Hash.new(0)) do |member, counts| gender = member.user_gender gender_label = if gender.present? t("simple_form.options.user.gender.#{gender}") else - t("statistics.statistics_demographics.unknown") + t("statistics.demographics.unknown") end counts[gender_label] += 1 end diff --git a/app/views/application/menus/_organization_statistics_menu.html.erb b/app/views/application/menus/_organization_statistics_menu.html.erb index e51130d6d..2c777d619 100644 --- a/app/views/application/menus/_organization_statistics_menu.html.erb +++ b/app/views/application/menus/_organization_statistics_menu.html.erb @@ -6,43 +6,43 @@