1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-19 13:54:25 +01:00

change statistic_service to use statistic_profile + use raw sql in migrations

This commit is contained in:
Sylvain 2019-06-06 13:58:49 +02:00
parent fe2a6f7120
commit 35da65b686
10 changed files with 65 additions and 47 deletions

View File

@ -1,3 +1,3 @@
#web: bundle exec rails server puma -p $PORT -b0.0.0.0
web: bundle exec rails server puma -p $PORT -b0.0.0.0
worker: bundle exec sidekiq -C ./config/sidekiq.yml
mail: bundle exec mailcatcher --foreground

View File

@ -1,13 +1,18 @@
# frozen_string_literal: true
# A special plan associated which can be associated with some users (with role 'partner')
# These partners will be notified when the subscribers to this plan are realizing some actions
class PartnerPlan < Plan
resourcify
before_create :assign_default_values
def partners
User.joins(:roles).where(roles: { name: 'partner', resource_type: 'PartnerPlan', resource_id: self.id })
User.joins(:roles).where(roles: { name: 'partner', resource_type: 'PartnerPlan', resource_id: id })
end
private
def assign_default_values
assign_attributes(is_rolling: false)
end

View File

@ -1,6 +1,6 @@
class Role < ActiveRecord::Base
has_and_belongs_to_many :users, :join_table => :users_roles
belongs_to :resource, :polymorphic => true
has_and_belongs_to_many :users, join_table: 'users_roles'
belongs_to :resource, polymorphic: true
scopify
end

View File

@ -1,5 +1,7 @@
# frozen_string_literal: true
AVG_DAYS_PER_YEAR = 365.2425
# This table will save the user's profile data needed for statistical purposes.
# GDPR requires that an user can delete his account at any time but we need to keep the statistics original data to being able to
# rebuild them at any time.
@ -7,6 +9,7 @@
class StatisticProfile < ActiveRecord::Base
belongs_to :user
belongs_to :group
belongs_to :role
has_many :subscriptions, dependent: :destroy
accepts_nested_attributes_for :subscriptions, allow_destroy: false
@ -25,7 +28,7 @@ class StatisticProfile < ActiveRecord::Base
def age
if birthday.present?
now = Time.now.utc.to_date
(now - birthday).to_f / 365.2425
(now - birthday).to_f / AVG_DAYS_PER_YEAR
else
''
end

View File

@ -373,7 +373,8 @@ class User < ActiveRecord::Base
if statistic_profile.nil?
StatisticProfile.create!(
user: self,
group_id: group_id
group_id: group_id,
role_id: roles.first.id
)
else
update_statistic_profile
@ -388,6 +389,7 @@ class User < ActiveRecord::Base
)
end
# will update the statistic_profile after a group switch. Updating the role is not supported
def update_statistic_profile
raise NoProfileError if statistic_profile.nil?

View File

@ -127,7 +127,7 @@ class StatisticService
def subscriptions_list(options = default_options)
result = []
InvoiceItem.where('invoice_items.created_at >= :start_date AND invoice_items.created_at <= :end_date', options)
.eager_load(invoice: [:coupon], subscription: [:plan, user: %i[profile group]]).each do |i|
.eager_load(invoice: [:coupon], subscription: [:plan, statistic_profile: [:group]]).each do |i|
next if i.invoice.is_a?(Avoir)
sub = i.subscription
@ -135,7 +135,7 @@ class StatisticService
ca = i.amount.to_i / 100.0
ca = CouponService.new.ventilate(get_invoice_total_no_coupon(i.invoice), ca, i.invoice.coupon) unless i.invoice.coupon_id.nil?
u = sub.user
profile = sub.statistic_profile
p = sub.plan
result.push OpenStruct.new({
date: options[:start_date].to_date,
@ -149,7 +149,7 @@ class StatisticService
subscription_id: sub.id,
invoice_item_id: i.id,
ca: ca
}.merge(user_info(u)))
}.merge(user_info(profile)))
end
result
end
@ -158,11 +158,11 @@ class StatisticService
result = []
Reservation
.where("reservable_type = 'Machine' AND reservations.created_at >= :start_date AND reservations.created_at <= :end_date", options)
.eager_load(:slots, user: %i[profile group], invoice: [:invoice_items])
.eager_load(:slots, statistic_profile: [:group], invoice: [:invoice_items])
.each do |r|
next unless r.reservable
u = r.user
profile = r.statistic_profile
result.push OpenStruct.new({
date: options[:start_date].to_date,
reservation_id: r.id,
@ -171,7 +171,7 @@ class StatisticService
machine_name: r.reservable.name,
nb_hours: r.slots.size,
ca: calcul_ca(r.invoice)
}.merge(user_info(u)))
}.merge(user_info(profile)))
end
result
end
@ -180,11 +180,11 @@ class StatisticService
result = []
Reservation
.where("reservable_type = 'Space' AND reservations.created_at >= :start_date AND reservations.created_at <= :end_date", options)
.eager_load(:slots, user: %i[profile group], invoice: [:invoice_items])
.eager_load(:slots, statistic_profile: [:group], invoice: [:invoice_items])
.each do |r|
next unless r.reservable
u = r.user
profile = r.statistic_profile
result.push OpenStruct.new({
date: options[:start_date].to_date,
reservation_id: r.id,
@ -193,7 +193,7 @@ class StatisticService
space_type: r.reservable.slug,
nb_hours: r.slots.size,
ca: calcul_ca(r.invoice)
}.merge(user_info(u)))
}.merge(user_info(profile)))
end
result
end
@ -202,11 +202,11 @@ class StatisticService
result = []
Reservation
.where("reservable_type = 'Training' AND reservations.created_at >= :start_date AND reservations.created_at <= :end_date", options)
.eager_load(:slots, user: %i[profile group], invoice: [:invoice_items])
.eager_load(:slots, statistic_profile: [:group], invoice: [:invoice_items])
.each do |r|
next unless r.reservable
u = r.user
profile = r.statistic_profile
slot = r.slots.first
result.push OpenStruct.new({
date: options[:start_date].to_date,
@ -217,7 +217,7 @@ class StatisticService
training_date: slot.start_at.to_date,
nb_hours: difference_in_hours(slot.start_at, slot.end_at),
ca: calcul_ca(r.invoice)
}.merge(user_info(u)))
}.merge(user_info(profile)))
end
result
end
@ -226,11 +226,11 @@ class StatisticService
result = []
Reservation
.where("reservable_type = 'Event' AND reservations.created_at >= :start_date AND reservations.created_at <= :end_date", options)
.eager_load(:slots, user: %i[profile group], invoice: [:invoice_items])
.eager_load(:slots, statistic_profile: [:group], invoice: [:invoice_items])
.each do |r|
next unless r.reservable
u = r.user
profile = r.statistic_profile
slot = r.slots.first
result.push OpenStruct.new({
date: options[:start_date].to_date,
@ -244,7 +244,7 @@ class StatisticService
nb_places: r.total_booked_seats,
nb_hours: difference_in_hours(slot.start_at, slot.end_at),
ca: calcul_ca(r.invoice)
}.merge(user_info(u)))
}.merge(user_info(profile)))
end
result
end
@ -254,21 +254,27 @@ class StatisticService
reservations_ca_list = []
avoirs_ca_list = []
result = []
Reservation .where('reservations.created_at >= :start_date AND reservations.created_at <= :end_date', options)
.eager_load(:slots, user: %i[profile group], invoice: [:invoice_items])
.each do |r|
Reservation.where('reservations.created_at >= :start_date AND reservations.created_at <= :end_date', options)
.eager_load(:slots, statistic_profile: [:group], invoice: [:invoice_items])
.each do |r|
next unless r.reservable
reservations_ca_list.push OpenStruct.new({ date: options[:start_date].to_date, ca: calcul_ca(r.invoice) }.merge(user_info(r.user)))
reservations_ca_list.push OpenStruct.new({
date: options[:start_date].to_date,
ca: calcul_ca(r.invoice)
}.merge(user_info(r.statistic_profile)))
end
Avoir.where('invoices.created_at >= :start_date AND invoices.created_at <= :end_date', options)
.eager_load(:invoice_items, user: %i[profile group])
.eager_load(:invoice_items, statistic_profile: [:group])
.each do |i|
avoirs_ca_list.push OpenStruct.new({ date: options[:start_date].to_date, ca: calcul_avoir_ca(i) }.merge(user_info(i.user)))
avoirs_ca_list.push OpenStruct.new({
date: options[:start_date].to_date,
ca: calcul_avoir_ca(i)
}.merge(user_info(i.statistic_profile)))
end
reservations_ca_list.concat(subscriptions_ca_list).concat(avoirs_ca_list).each do |e|
user = User.find(e.user_id)
u = find_or_create_user_info_info_list(user, result)
profile = StatisticProfile.find(e.statistic_profile_id)
u = find_or_create_user_info_info_list(profile, result)
u.date = options[:start_date].to_date
e.ca = 0 unless e.ca
if u.ca
@ -284,10 +290,9 @@ class StatisticService
def members_list(options = default_options)
result = []
User.with_role(:member)
.includes(:profile)
.where('users.created_at >= :start_date AND users.created_at <= :end_date', options)
.each do |u|
member = Role.find_by(name: 'member')
StatisticProfile.where('role_id = :member, users.created_at >= :start_date AND users.created_at <= :end_date', options.merge(member: member.id))
.each do |u|
next if u.need_completion?
result.push OpenStruct.new({
@ -353,13 +358,13 @@ class StatisticService
end
end
def user_info(user)
def user_info(statistic_profile)
{
user_id: user.id,
gender: user.statistic_profile.str_gender,
age: user.statistic_profile.age,
group: user.group ? user.group.slug : nil,
email: user.email
statistic_profile_id: statistic_profile.id,
user_id: statistic_profile.user_id,
gender: statistic_profile.str_gender,
age: statistic_profile.age,
group: statistic_profile.group ? statistic_profile.group.slug : nil
}
end
@ -484,10 +489,10 @@ class StatisticService
total / 100.0
end
def find_or_create_user_info_info_list(user, list)
def find_or_create_user_info_info_list(profile, list)
found = list.select do |l|
l.user_id == user.id
l.statistic_profile_id == profile.id
end.first
found || OpenStruct.new(user_info(user))
found || OpenStruct.new(user_info(profile))
end
end

View File

@ -5,6 +5,7 @@ class CreateStatisticProfile < ActiveRecord::Migration
t.date :birthday
t.belongs_to :group, index: true, foreign_key: true
t.belongs_to :user, index: true, foreign_key: true
t.belongs_to :role, index: true, foreign_key: true
end
add_reference :reservations, :statistic_profile, index: true, foreign_key: true

View File

@ -7,6 +7,7 @@ class MigrateProfileToStatisticProfile < ActiveRecord::Migration
StatisticProfile.create!(
user: u,
group: u.group,
role: u.roles.first,
gender: p.gender,
birthday: p.birthday
)

View File

@ -4,11 +4,9 @@ class MigrateUserTrainingsToStatisticProfileTrainings < ActiveRecord::Migration
user_trainings.each do |ut|
user = User.find(ut['user_id'])
StatisticProfileTraining.create!(
statistic_profile_id: user.statistic_profile.id,
training_id: ut['training_id'],
created_at: ut['created_at']
)
# here we use raw sql to prevent the notify_user callback the email the whole DB
execute("INSERT INTO statistic_profile_trainings (statistic_profile_id, training_id, created_at, updated_at)
VALUES (#{user.statistic_profile.id}, #{ut['training_id']}, '#{ut['created_at'].utc}', '#{DateTime.now.utc}')")
end
end

View File

@ -677,9 +677,11 @@ ActiveRecord::Schema.define(version: 20190606074801) do
t.date "birthday"
t.integer "group_id"
t.integer "user_id"
t.integer "role_id"
end
add_index "statistic_profiles", ["group_id"], name: "index_statistic_profiles_on_group_id", using: :btree
add_index "statistic_profiles", ["role_id"], name: "index_statistic_profiles_on_role_id", using: :btree
add_index "statistic_profiles", ["user_id"], name: "index_statistic_profiles_on_user_id", using: :btree
create_table "statistic_sub_types", force: :cascade do |t|
@ -923,6 +925,7 @@ ActiveRecord::Schema.define(version: 20190606074801) do
add_foreign_key "statistic_profile_trainings", "statistic_profiles"
add_foreign_key "statistic_profile_trainings", "trainings"
add_foreign_key "statistic_profiles", "groups"
add_foreign_key "statistic_profiles", "roles"
add_foreign_key "statistic_profiles", "users"
add_foreign_key "subscriptions", "statistic_profiles"
add_foreign_key "tickets", "event_price_categories"