mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-19 13:54:25 +01:00
(feat) statistics improvements
This commit is contained in:
parent
d70501e066
commit
a10f3cffe4
@ -6,6 +6,14 @@
|
||||
- Fix a bug: unable to update status to paid for latest payment schedule item
|
||||
- Fix a bug: unable to generate statistic
|
||||
- Feature: add a filter in members list (admin) to show only "not validated" members
|
||||
- Concerning statistics:
|
||||
- removes age and type column from all statistics tabs (only in web, not in xlsx export file)
|
||||
- index:
|
||||
- renames user column header for projects tab and projects xlsx export
|
||||
- adds group name of user for every tab except projects tab
|
||||
- adds status and project users names for projects tab
|
||||
- [TODO DEPLOY] `rails db:seed`
|
||||
- [TODO DEPLOY] `rails fablab:es:build_stats`
|
||||
- [TODO DEPLOY] `rails fablab:maintenance:regenerate_statistics[2014,1]`
|
||||
|
||||
## v6.0.13 2023 August 28
|
||||
|
@ -256,12 +256,11 @@
|
||||
<tr>
|
||||
<th ng-if="['booking', 'hour'].includes(type.active.key)" translate>{{ 'app.admin.statistics.reservation_date' }}</th>
|
||||
<th ng-if="!['booking', 'hour'].includes(type.active.key)" translate>{{ 'app.admin.statistics.date' }}</th>
|
||||
<th translate>{{ 'app.admin.statistics.user' }}</th>
|
||||
<th ng-if="['project'].includes(type.active.key)" translate>{{ 'app.admin.statistics.project_author' }}</th>
|
||||
<th ng-if="!['project'].includes(type.active.key)" translate>{{ 'app.admin.statistics.user' }}</th>
|
||||
<th ng-if="reservationContextFeatureEnabled && reservationContextIsApplicable(selectedIndex.es_type_key)">
|
||||
{{ 'app.admin.statistics.reservation_context' | translate }}
|
||||
</th>
|
||||
<th translate>{{ 'app.admin.statistics.age' }}</th>
|
||||
<th translate>{{ 'app.admin.statistics.type' }}</th>
|
||||
<th ng-if="!type.active.simple">{{type.active.label}}</th>
|
||||
<th ng-repeat="field in selectedIndex.additional_fields">{{field.label}}</th>
|
||||
<th ng-if="selectedIndex.ca">{{ 'app.admin.statistics.revenue' | translate }}
|
||||
@ -285,11 +284,6 @@
|
||||
<td ng-if="reservationContextFeatureEnabled && reservationContextIsApplicable(selectedIndex.es_type_key)">
|
||||
{{ formatReservationContext(datum._source.reservationContextId) }}
|
||||
</td>
|
||||
<td>
|
||||
<span ng-if="datum._source.age">{{datum._source.age}} {{ 'app.admin.statistics.years_old' | translate }}</span>
|
||||
<span ng-if="!datum._source.age" translate>{{ 'app.admin.statistics.unknown' }}</span>
|
||||
</td>
|
||||
<td>{{formatSubtype(datum._source.subType)}}</td>
|
||||
<td ng-if="!type.active.simple">{{datum._source.stat}}</td>
|
||||
<td ng-repeat="field in selectedIndex.additional_fields">
|
||||
<ng-switch on="field.data_type">
|
||||
|
@ -13,6 +13,7 @@ module StatConcern
|
||||
attribute :gender, String
|
||||
attribute :age, Integer
|
||||
attribute :group, String
|
||||
attribute :groupName, String
|
||||
|
||||
# has include Elasticsearch::Persistence::Model
|
||||
index_name 'stats'
|
||||
|
@ -12,4 +12,6 @@ class Stats::Project
|
||||
attribute :components, Array
|
||||
attribute :machines, Array
|
||||
attribute :users, Integer
|
||||
attribute :status, String
|
||||
attribute :projectUserNames, Array
|
||||
end
|
||||
|
@ -11,7 +11,8 @@ class Statistics::Builders::MembersBuilderService
|
||||
Stats::Account.create({ date: format_date(m[:date]),
|
||||
type: 'member',
|
||||
subType: 'created',
|
||||
stat: 1 }.merge(user_info_stat(m)))
|
||||
stat: 1,
|
||||
groupName: m[:groupName] }.merge(user_info_stat(m)))
|
||||
end
|
||||
|
||||
# member ca list
|
||||
@ -19,7 +20,8 @@ class Statistics::Builders::MembersBuilderService
|
||||
Stats::User.create({ date: format_date(m[:date]),
|
||||
type: 'revenue',
|
||||
subType: m[:group],
|
||||
stat: m[:ca] }.merge(user_info_stat(m)))
|
||||
stat: m[:ca],
|
||||
groupName: m[:groupName] }.merge(user_info_stat(m)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -19,7 +19,8 @@ class Statistics::Builders::ReservationsBuilderService
|
||||
name: r["#{category}_name".to_sym],
|
||||
reservationId: r[:reservation_id],
|
||||
reservationContextId: r[:reservation_context_id],
|
||||
coupon: r[:coupon]
|
||||
coupon: r[:coupon],
|
||||
groupName: r[:groupName],
|
||||
}.merge(user_info_stat(r)))
|
||||
stat[:stat] = (type == 'booking' ? 1 : r[:nb_hours])
|
||||
stat["#{category}Id".to_sym] = r["#{category}_id".to_sym]
|
||||
|
@ -23,6 +23,7 @@ class Statistics::Builders::StoreOrdersBuilderService
|
||||
orderId: o[:order_id],
|
||||
state: o[:order_state],
|
||||
coupon: o[:coupon],
|
||||
groupName: o[:groupName],
|
||||
stat: 1 }.merge(user_info_stat(o)))
|
||||
end
|
||||
end
|
||||
|
@ -31,6 +31,12 @@ module Statistics::Concerns::ProjectsConcern
|
||||
sum
|
||||
end
|
||||
|
||||
def get_project_user_names(project)
|
||||
project.project_users.map do |project_user|
|
||||
{ id: project_user.user.id, name: project_user.user.profile.full_name }
|
||||
end
|
||||
end
|
||||
|
||||
def project_info(project)
|
||||
{
|
||||
project_id: project.id,
|
||||
@ -41,7 +47,9 @@ module Statistics::Concerns::ProjectsConcern
|
||||
project_themes: get_project_themes(project),
|
||||
project_components: get_projects_components(project),
|
||||
project_machines: get_projects_machines(project),
|
||||
project_users: get_project_users(project)
|
||||
project_users: get_project_users(project),
|
||||
project_status: project.status&.name,
|
||||
project_user_names: get_project_user_names(project),
|
||||
}
|
||||
end
|
||||
|
||||
@ -53,7 +61,9 @@ module Statistics::Concerns::ProjectsConcern
|
||||
themes: project[:project_themes],
|
||||
components: project[:project_components],
|
||||
machines: project[:project_machines],
|
||||
users: project[:project_users]
|
||||
users: project[:project_users],
|
||||
status: project[:project_status],
|
||||
projectUserNames: project[:project_user_names],
|
||||
}
|
||||
end
|
||||
end
|
||||
|
@ -207,7 +207,7 @@ class Statistics::FetcherService
|
||||
# @yieldparam [Hash]
|
||||
def each_project(options = default_options)
|
||||
Project.where('projects.published_at >= :start_date AND projects.published_at <= :end_date', options)
|
||||
.eager_load(:licence, :themes, :components, :machines, :project_users, author: [:group])
|
||||
.eager_load(:licence, :themes, :components, :machines, :status, project_users: [{ user: :profile }], author: [:group])
|
||||
.find_each do |p|
|
||||
result = { date: p.created_at.to_date }.merge(user_info(p.author)).merge(project_info(p))
|
||||
yield result
|
||||
@ -261,7 +261,8 @@ class Statistics::FetcherService
|
||||
user_id: statistic_profile.user_id,
|
||||
gender: statistic_profile.str_gender,
|
||||
age: statistic_profile.age,
|
||||
group: statistic_profile.group ? statistic_profile.group.slug : nil
|
||||
group: statistic_profile.group ? statistic_profile.group.slug : nil,
|
||||
groupName: statistic_profile.group ? statistic_profile.group.name : nil,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
@ -20,7 +20,8 @@ wb.add_worksheet(name: ExcelService.name_safe(index.label)) do |sheet|
|
||||
|
||||
## data table
|
||||
# heading labels
|
||||
columns = [t('export.date'), t('export.user'), t('export.email'), t('export.phone'), t('export.gender'), t('export.age'),
|
||||
user_heading_text = index.es_type_key == "project" ? t('export.project_author') : t('export.user')
|
||||
columns = [t('export.date'), user_heading_text, t('export.email'), t('export.phone'), t('export.gender'), t('export.age'),
|
||||
t('export.type')]
|
||||
columns.push type.label unless type.simple
|
||||
fields.each do |f|
|
||||
|
@ -12,7 +12,8 @@ indices.each do |index|
|
||||
wb.add_worksheet(name: ExcelService.statistic_type_sheet_name(type, wb)) do |sheet|
|
||||
## data table
|
||||
# heading labels
|
||||
columns = [t('export.date'), t('export.user'), t('export.email'), t('export.phone'), t('export.gender'), t('export.age'),
|
||||
user_heading_text = index.es_type_key == "project" ? t('export.project_author') : t('export.user')
|
||||
columns = [t('export.date'), user_heading_text, t('export.email'), t('export.phone'), t('export.gender'), t('export.age'),
|
||||
t('export.type')]
|
||||
columns.push type.label unless type.simple
|
||||
index.statistic_fields.each do |f|
|
||||
|
@ -1538,6 +1538,7 @@ en:
|
||||
click_here: "Click here to create your first one."
|
||||
average_cart: "Average cart:"
|
||||
reservation_context: Reservation context
|
||||
project_author: Author
|
||||
#statistics graphs
|
||||
stats_graphs:
|
||||
statistics: "Statistics"
|
||||
|
@ -1538,6 +1538,7 @@ fr:
|
||||
click_here: "Cliquez ici pour créer votre première formule."
|
||||
average_cart: "Panier moyen :"
|
||||
reservation_context: Nature de la réservation
|
||||
project_author: Auteur
|
||||
#statistics graphs
|
||||
stats_graphs:
|
||||
statistics: "Statistiques"
|
||||
|
@ -489,6 +489,9 @@ en:
|
||||
store: "Store"
|
||||
paid-processed: "Paid and/or processed"
|
||||
aborted: "Aborted"
|
||||
project_status: Status
|
||||
project_name: Name
|
||||
project_user_names: Collaborators
|
||||
#statistics exports to the Excel file format
|
||||
export:
|
||||
entries: "Entries"
|
||||
@ -507,6 +510,7 @@ en:
|
||||
deleted_user: "Deleted user"
|
||||
reservation_context: "Reservation context"
|
||||
coupon: "Coupon"
|
||||
project_author: Author
|
||||
#initial price's category for events, created to replace the old "reduced amount" property
|
||||
price_category:
|
||||
reduced_fare: "Reduced fare"
|
||||
|
@ -489,6 +489,9 @@ fr:
|
||||
store: "Boutique"
|
||||
paid-processed: "Payée et/ou traitée"
|
||||
aborted: "Interrompue"
|
||||
project_status: Statut
|
||||
project_name: Nom
|
||||
project_user_names: Collaborateurs
|
||||
#statistics exports to the Excel file format
|
||||
export:
|
||||
entries: "Entrées"
|
||||
@ -507,6 +510,7 @@ fr:
|
||||
deleted_user: "Utilisateur supprimé"
|
||||
reservation_context: "Nature de la réservation"
|
||||
coupon: "Code promo"
|
||||
project_author: Auteur
|
||||
#initial price's category for events, created to replace the old "reduced amount" property
|
||||
price_category:
|
||||
reduced_fare: "Tarif réduit"
|
||||
|
@ -30,49 +30,76 @@ statistic_index_space = StatisticIndex.find_by(es_type_key: 'space')
|
||||
statistic_index_order = StatisticIndex.find_by(es_type_key: 'order')
|
||||
|
||||
# statistic_fields
|
||||
unless StatisticField.find_by(key: 'spaceDates')
|
||||
unless StatisticField.find_by(key: 'spaceDates', statistic_index_id: statistic_index_space.id)
|
||||
StatisticField.create!({ key: 'spaceDates', label: I18n.t('statistics.space_dates'),
|
||||
statistic_index_id: statistic_index_space.id, data_type: 'list' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'machineDates')
|
||||
unless StatisticField.find_by(key: 'groupName', statistic_index_id: statistic_index_space.id)
|
||||
StatisticField.create!({ key: 'groupName', label: I18n.t('statistics.group'), statistic_index_id: statistic_index_space.id, data_type: 'text' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'machineDates', statistic_index_id: 2)
|
||||
StatisticField.create!({ key: 'machineDates', label: I18n.t('statistics.machine_dates'), statistic_index_id: 2, data_type: 'list' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'trainingId')
|
||||
unless StatisticField.find_by(key: 'groupName', statistic_index_id: 2)
|
||||
StatisticField.create!({ key: 'groupName', label: I18n.t('statistics.group'), statistic_index_id: 2, data_type: 'text' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'trainingId', statistic_index_id: 3)
|
||||
StatisticField.create!({ key: 'trainingId', label: I18n.t('statistics.training_id'), statistic_index_id: 3, data_type: 'index' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'trainingDate')
|
||||
unless StatisticField.find_by(key: 'trainingDate', statistic_index_id: 3)
|
||||
StatisticField.create!({ key: 'trainingDate', label: I18n.t('statistics.training_date'), statistic_index_id: 3, data_type: 'date' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'eventId')
|
||||
unless StatisticField.find_by(key: 'groupName', statistic_index_id: 3)
|
||||
StatisticField.create!({ key: 'groupName', label: I18n.t('statistics.group'), statistic_index_id: 3, data_type: 'text' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'eventId', statistic_index_id: 4)
|
||||
StatisticField.create!({ key: 'eventId', label: I18n.t('statistics.event_id'), statistic_index_id: 4, data_type: 'index' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'eventDate')
|
||||
unless StatisticField.find_by(key: 'eventDate', statistic_index_id: 4)
|
||||
StatisticField.create!({ key: 'eventDate', label: I18n.t('statistics.event_date'), statistic_index_id: 4, data_type: 'date' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'themes')
|
||||
unless StatisticField.find_by(key: 'groupName', statistic_index_id: 4)
|
||||
StatisticField.create!({ key: 'groupName', label: I18n.t('statistics.group'), statistic_index_id: 4, data_type: 'text' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'groupName', statistic_index_id: 5)
|
||||
StatisticField.create!({ key: 'groupName', label: I18n.t('statistics.group'), statistic_index_id: 5, data_type: 'text' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'themes', statistic_index_id: 6)
|
||||
StatisticField.create!({ key: 'themes', label: I18n.t('statistics.themes'), statistic_index_id: 6, data_type: 'list' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'components')
|
||||
unless StatisticField.find_by(key: 'components', statistic_index_id: 6)
|
||||
StatisticField.create!({ key: 'components', label: I18n.t('statistics.components'), statistic_index_id: 6, data_type: 'list' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'machines')
|
||||
unless StatisticField.find_by(key: 'machines', statistic_index_id: 6)
|
||||
StatisticField.create!({ key: 'machines', label: I18n.t('statistics.machines'), statistic_index_id: 6, data_type: 'list' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'name')
|
||||
unless StatisticField.find_by(key: 'status', statistic_index_id: 6)
|
||||
StatisticField.create!({ key: 'status', label: I18n.t('statistics.project_status'), statistic_index_id: 6, data_type: 'text' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'name', statistic_index_id: 6)
|
||||
StatisticField.create!({ key: 'name', label: I18n.t('statistics.project_name'), statistic_index_id: 6, data_type: 'text' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'projectUserNames', statistic_index_id: 6)
|
||||
StatisticField.create!({ key: 'projectUserNames', label: I18n.t('statistics.project_user_names'), statistic_index_id: 6, data_type: 'list' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'name', statistic_index_id: 4)
|
||||
StatisticField.create!({ key: 'name', label: I18n.t('statistics.event_name'), statistic_index_id: 4, data_type: 'text' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'userId')
|
||||
unless StatisticField.find_by(key: 'userId', statistic_index_id: 7)
|
||||
StatisticField.create!({ key: 'userId', label: I18n.t('statistics.user_id'), statistic_index_id: 7, data_type: 'index' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'eventTheme')
|
||||
unless StatisticField.find_by(key: 'eventTheme', statistic_index_id: 4)
|
||||
StatisticField.create!({ key: 'eventTheme', label: I18n.t('statistics.event_theme'), statistic_index_id: 4, data_type: 'text' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'ageRange')
|
||||
unless StatisticField.find_by(key: 'ageRange', statistic_index_id: 4)
|
||||
StatisticField.create!({ key: 'ageRange', label: I18n.t('statistics.age_range'), statistic_index_id: 4, data_type: 'text' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'groupName')
|
||||
unless StatisticField.find_by(key: 'groupName', statistic_index_id: 1)
|
||||
StatisticField.create!({ key: 'groupName', label: I18n.t('statistics.group'), statistic_index_id: 1, data_type: 'text' })
|
||||
end
|
||||
unless StatisticField.find_by(key: 'groupName', statistic_index_id: statistic_index_order.id)
|
||||
StatisticField.create!({ key: 'groupName', label: I18n.t('statistics.group'), statistic_index_id: statistic_index_order.id, data_type: 'text' })
|
||||
end
|
||||
|
||||
# statistic_types
|
||||
unless StatisticType.find_by(key: 'booking', statistic_index_id: 2)
|
||||
|
Loading…
x
Reference in New Issue
Block a user