2019-02-13 12:59:28 +01:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
# Correctives for bugs or upgrades migrations tasks
|
2016-05-04 18:17:50 +02:00
|
|
|
namespace :fablab do
|
|
|
|
namespace :fix do
|
2019-02-13 12:59:28 +01:00
|
|
|
desc '[release 2.3.0] update reservations referencing reservables not present in database'
|
2016-05-04 18:17:50 +02:00
|
|
|
task reservations_not_existing_reservable: :environment do
|
2022-11-21 17:34:06 +01:00
|
|
|
ActiveRecord::Base.logger = Logger.new($stdout)
|
2016-05-04 18:17:50 +02:00
|
|
|
ActiveRecord::Base.connection.execute(
|
2022-11-21 17:34:06 +01:00
|
|
|
'UPDATE reservations SET reservable_type = NULL, reservable_id = NULL ' \
|
|
|
|
'WHERE NOT EXISTS (SELECT 1 FROM events WHERE events.id = reservations.reservable_id) ' \
|
|
|
|
"AND reservations.reservable_type = 'Event'"
|
2016-05-04 18:17:50 +02:00
|
|
|
)
|
|
|
|
end
|
2016-08-11 11:07:49 +02:00
|
|
|
|
2019-02-13 12:59:28 +01:00
|
|
|
desc '[release 2.4.0] put every non-categorized events into a new category called "No Category", to ease re-categorization'
|
2016-08-11 11:07:49 +02:00
|
|
|
task assign_category_to_uncategorized_events: :environment do
|
2019-02-13 12:59:28 +01:00
|
|
|
c = Category.find_or_create_by!(name: 'No category')
|
2016-08-11 11:07:49 +02:00
|
|
|
Event.where(category: nil).each do |e|
|
|
|
|
e.category = c
|
|
|
|
e.save!
|
|
|
|
end
|
|
|
|
end
|
2017-03-15 12:50:19 +01:00
|
|
|
|
2019-02-13 12:59:28 +01:00
|
|
|
desc '[release 2.4.11] fix is_rolling for edited plans'
|
2017-03-15 12:50:19 +01:00
|
|
|
task rolling_plans: :environment do
|
|
|
|
Plan.where(is_rolling: nil).each do |p|
|
2019-02-13 12:59:28 +01:00
|
|
|
if p.is_rolling.nil? && p.is_rolling != false
|
2017-03-15 12:50:19 +01:00
|
|
|
p.is_rolling = true
|
|
|
|
p.save!
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-03-21 15:47:25 +01:00
|
|
|
|
2019-02-13 12:59:28 +01:00
|
|
|
desc '[release 2.5.0] create missing plans in statistics'
|
2017-03-21 15:47:25 +01:00
|
|
|
task new_plans_statistics: :environment do
|
|
|
|
StatisticSubType.where(key: nil).each do |sst|
|
|
|
|
p = Plan.find_by(name: sst.label)
|
|
|
|
if p
|
|
|
|
sst.key = p.slug
|
|
|
|
sst.save!
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-05-15 15:25:27 +02:00
|
|
|
|
2019-02-13 12:59:28 +01:00
|
|
|
desc '[release 2.5.5] create missing space prices'
|
2017-05-15 15:25:27 +02:00
|
|
|
task new_group_space_prices: :environment do
|
|
|
|
Space.all.each do |space|
|
|
|
|
Group.all.each do |group|
|
2022-11-18 18:58:17 +01:00
|
|
|
Price.find(priceable: space, group: group)
|
|
|
|
rescue ActiveRecord::RecordNotFound
|
|
|
|
Price.create(priceable: space, group: group, amount: 0)
|
2017-05-15 15:25:27 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-08-30 14:57:06 +02:00
|
|
|
|
2019-02-13 12:59:28 +01:00
|
|
|
desc '[release 2.5.11] put all admins in a special group'
|
2017-08-30 14:57:06 +02:00
|
|
|
task migrate_admins_group: :environment do
|
|
|
|
admins = Group.find_by(slug: 'admins')
|
|
|
|
User.all.each do |user|
|
2019-01-14 12:57:31 +01:00
|
|
|
if user.admin?
|
2017-08-30 14:57:06 +02:00
|
|
|
user.group = admins
|
|
|
|
user.save!
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-09-04 17:27:18 +02:00
|
|
|
|
2019-02-13 12:59:28 +01:00
|
|
|
desc '[release 2.5.14] fix times of recursive events that crosses DST periods'
|
2017-09-04 17:27:18 +02:00
|
|
|
task recursive_events_over_DST: :environment do
|
2023-02-14 13:10:58 +01:00
|
|
|
def dst_correction(reference, datetime)
|
|
|
|
res = datetime.in_time_zone(reference.time_zone.tzinfo.name)
|
|
|
|
res -= 1.hour if res.dst? && !reference.dst?
|
|
|
|
res += 1.hour if reference.dst? && !res.dst?
|
|
|
|
res
|
|
|
|
end
|
2017-09-11 16:32:33 +02:00
|
|
|
failed_ids = []
|
2017-09-04 17:27:18 +02:00
|
|
|
groups = Event.group(:recurrence_id).count
|
2022-11-18 18:58:17 +01:00
|
|
|
groups.each_key do |recurrent_event_id|
|
2019-02-13 12:59:28 +01:00
|
|
|
next unless recurrent_event_id
|
|
|
|
|
|
|
|
begin
|
|
|
|
initial_event = Event.find(recurrent_event_id)
|
|
|
|
Event.where(recurrence_id: recurrent_event_id).where.not(id: recurrent_event_id).each do |event|
|
|
|
|
availability = event.availability
|
|
|
|
next if initial_event.availability.start_at.hour == availability.start_at.hour
|
|
|
|
|
|
|
|
availability.start_at = dst_correction(initial_event.availability.start_at, availability.start_at)
|
|
|
|
availability.end_at = dst_correction(initial_event.availability.end_at, availability.end_at)
|
|
|
|
availability.save!
|
2017-09-05 10:36:49 +02:00
|
|
|
end
|
2019-02-13 12:59:28 +01:00
|
|
|
rescue ActiveRecord::RecordNotFound
|
|
|
|
failed_ids.push recurrent_event_id
|
2017-09-04 17:27:18 +02:00
|
|
|
end
|
|
|
|
end
|
2017-09-11 16:32:33 +02:00
|
|
|
|
2019-02-13 12:59:28 +01:00
|
|
|
if failed_ids.size.positive?
|
|
|
|
puts "WARNING: The events with IDs #{failed_ids} were not found.\n These were initial events of a recurrence.\n\n" \
|
|
|
|
"You may have to correct the following events manually (IDs): #{Event.where(recurrence_id: failed_ids).map(&:id)}"
|
2017-09-11 16:32:33 +02:00
|
|
|
end
|
2017-09-04 17:27:18 +02:00
|
|
|
end
|
2018-07-12 12:48:50 +02:00
|
|
|
|
2019-02-13 12:59:28 +01:00
|
|
|
desc '[release 2.6.6] reset slug in events categories'
|
2018-07-12 12:48:50 +02:00
|
|
|
task categories_slugs: :environment do
|
|
|
|
Category.all.each do |cat|
|
2022-11-18 18:58:17 +01:00
|
|
|
# rubocop:disable Layout/LineLength
|
2022-11-21 17:34:06 +01:00
|
|
|
`curl -XPOST http://#{ENV.fetch('ELASTICSEARCH_HOST', nil)}:9200/stats/event/_update_by_query?conflicts=proceed\\&refresh\\&wait_for_completion -d '
|
2018-07-12 12:48:50 +02:00
|
|
|
{
|
|
|
|
"script": {
|
|
|
|
"source": "ctx._source.subType = params.slug",
|
|
|
|
"lang": "painless",
|
|
|
|
"params": {
|
|
|
|
"slug": "#{cat.slug}"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"query": {
|
|
|
|
"term": {
|
|
|
|
"subType": "#{cat.name}"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}';`
|
2022-11-18 18:58:17 +01:00
|
|
|
# rubocop:enable Layout/LineLength
|
2018-07-12 12:48:50 +02:00
|
|
|
end
|
|
|
|
end
|
2019-02-13 12:59:28 +01:00
|
|
|
|
|
|
|
desc '[release 2.4.10] set slugs to plans'
|
|
|
|
task set_plans_slugs: :environment do
|
|
|
|
# this will maintain compatibility with existing statistics
|
|
|
|
Plan.all.each do |p|
|
|
|
|
p.slug = p.stp_plan_id
|
|
|
|
p.save
|
|
|
|
end
|
|
|
|
end
|
2019-04-16 12:37:47 +02:00
|
|
|
|
|
|
|
desc '[release 3.1.2] fix users with invalid group_id'
|
|
|
|
task users_group_ids: :environment do
|
|
|
|
User.where.not(group_id: Group.all.map(&:id)).each do |u|
|
2023-02-14 13:10:58 +01:00
|
|
|
u.update_columns(group_id: Group.first.id, updated_at: Time.current) # rubocop:disable Rails/SkipsModelValidations
|
2019-04-16 12:37:47 +02:00
|
|
|
|
|
|
|
meta_data = { ex_group_name: 'invalid group' }
|
|
|
|
|
|
|
|
NotificationCenter.call type: :notify_admin_user_group_changed,
|
|
|
|
receiver: User.admins,
|
|
|
|
attached_object: u,
|
|
|
|
meta_data: meta_data
|
|
|
|
|
|
|
|
NotificationCenter.call type: :notify_user_user_group_changed,
|
|
|
|
receiver: u,
|
|
|
|
attached_object: u
|
|
|
|
end
|
|
|
|
end
|
2020-01-27 17:10:29 +01:00
|
|
|
|
|
|
|
desc '[release 4.3.0] add name to theme stylesheet'
|
|
|
|
task name_stylesheet: :environment do
|
2022-11-18 18:58:17 +01:00
|
|
|
Stylesheet.order(:created_at).first&.update(
|
2020-01-27 17:10:29 +01:00
|
|
|
name: 'theme'
|
|
|
|
)
|
|
|
|
end
|
2020-04-01 12:51:18 +02:00
|
|
|
|
|
|
|
desc '[release 4.3.3] add statistic_profile_id to refund invoices for WalletTransactions'
|
|
|
|
task avoirs_wallet_transaction: :environment do
|
|
|
|
Avoir.where(invoiced_type: WalletTransaction.name).each do |a|
|
|
|
|
next unless a.statistic_profile_id.nil?
|
|
|
|
|
|
|
|
begin
|
|
|
|
a.statistic_profile_id = a.invoiced.wallet.user&.statistic_profile&.id
|
|
|
|
a.save!
|
|
|
|
rescue ActiveRecord::RecordInvalid => e
|
|
|
|
printf "Unable to modify the refund invoice (id %<id>s): %<error>s\nIgnoring that record...\n", id: a.id, error: e
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2020-05-18 16:23:53 +02:00
|
|
|
|
|
|
|
desc '[release 4.4.2] add missing role to StatisticProfile'
|
|
|
|
task role_in_statistic_profile: :environment do
|
|
|
|
puts "Fixing #{StatisticProfile.where(role_id: nil).count} bugged profiles...\n"
|
|
|
|
StatisticProfile.where(role_id: nil).each do |sp|
|
2022-11-18 18:58:17 +01:00
|
|
|
role_id = sp.user&.roles&.first&.id
|
2020-05-18 16:23:53 +02:00
|
|
|
sp.role_id = role_id
|
|
|
|
sp.save!
|
|
|
|
end
|
|
|
|
end
|
2020-05-25 11:02:49 +02:00
|
|
|
|
|
|
|
desc '[release 4.4.3] fix duration of recurring availabilities'
|
|
|
|
task availabilities_duration: :environment do
|
2023-01-10 11:28:20 +01:00
|
|
|
Availability.select('occurrence_id').where(is_recurrent: true).group('occurrence_id').each do |a|
|
2020-05-25 11:02:49 +02:00
|
|
|
occurrences = Availability.where(occurrence_id: a.occurrence_id)
|
|
|
|
next unless occurrences.map(&:slot_duration).uniq.size > 1
|
|
|
|
|
|
|
|
duration = occurrences.map(&:slot_duration).uniq.detect { |e| !e.nil? }
|
|
|
|
occurrences.each do |o|
|
2022-11-18 18:58:17 +01:00
|
|
|
o.update(slot_duration: duration)
|
2020-05-25 11:02:49 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2021-05-14 17:07:38 +02:00
|
|
|
|
|
|
|
desc '[release 4.7.9] fix invoicing profiles without names'
|
|
|
|
task invoices_without_names: :environment do
|
|
|
|
InvoicingProfile.where('(first_name IS NULL OR last_name IS NULL) AND user_id IS NOT NULL').each do |ip|
|
2022-11-18 18:58:17 +01:00
|
|
|
ip.update(first_name: ip.user.profile.first_name)
|
|
|
|
ip.update(last_name: ip.user.profile.last_name)
|
2021-05-14 17:07:38 +02:00
|
|
|
end
|
|
|
|
end
|
2022-03-29 17:08:35 +02:00
|
|
|
|
|
|
|
desc '[release 5.3.8] fix invoicing profiles without names and email'
|
|
|
|
task invoices_without_names_and_email: :environment do
|
|
|
|
InvoicingProfile.where('(first_name IS NULL OR last_name IS NULL OR email IS NULL) AND user_id IS NOT NULL').each do |ip|
|
2022-11-18 18:58:17 +01:00
|
|
|
ip.update(first_name: ip.user.profile.first_name)
|
|
|
|
ip.update(last_name: ip.user.profile.last_name)
|
|
|
|
ip.update(email: ip.user.email)
|
2022-03-29 17:08:35 +02:00
|
|
|
end
|
|
|
|
end
|
2022-10-19 15:19:28 +02:00
|
|
|
|
|
|
|
desc '[release 5.4.24] fix prepaid pack hours dont count down after a reservation of machine'
|
|
|
|
task :prepaid_pack_count_down, %i[start_date end_date] => :environment do |_task, args|
|
|
|
|
# set start date to the date of deployment of v5.4.13 that product the bug
|
2023-02-14 13:10:58 +01:00
|
|
|
start_date = Time.zone.parse('2022-07-28T10:00:00+02:00')
|
2022-10-19 15:19:28 +02:00
|
|
|
if args.start_date
|
|
|
|
begin
|
2023-02-14 13:10:58 +01:00
|
|
|
start_date = Time.zone.parse(args.start_date)
|
2022-10-19 15:19:28 +02:00
|
|
|
rescue ArgumentError => e
|
|
|
|
raise e
|
|
|
|
end
|
|
|
|
end
|
|
|
|
# set end date to the date of deployment of v5.4.24 after fix the bug
|
2023-02-14 13:10:58 +01:00
|
|
|
end_date = Time.zone.parse('2022-10-14T18:40:00+02:00')
|
2022-10-19 15:19:28 +02:00
|
|
|
if args.end_date
|
|
|
|
begin
|
2023-02-14 13:10:58 +01:00
|
|
|
end_date = Time.zone.parse(args.end_date)
|
2022-10-19 15:19:28 +02:00
|
|
|
rescue ArgumentError => e
|
|
|
|
raise e
|
|
|
|
end
|
|
|
|
end
|
|
|
|
# find all machines that has prepaid pack
|
|
|
|
machine_ids = PrepaidPack.where(disabled: nil).all.map(&:priceable_id).uniq
|
|
|
|
# find all memders that bought a prepaid pack
|
|
|
|
statistic_profile_ids = StatisticProfilePrepaidPack.all.map(&:statistic_profile_id).uniq
|
|
|
|
# find the reservations that use prepaid pack by machine_ids, members and preriod
|
|
|
|
reservations = Reservation.where(reservable_type: 'Machine', reservable_id: machine_ids, statistic_profile_id: statistic_profile_ids,
|
2023-01-10 11:28:20 +01:00
|
|
|
created_at: start_date..end_date).order(statistic_profile_id: :asc, created_at: :asc)
|
2022-10-19 15:19:28 +02:00
|
|
|
infos = []
|
|
|
|
reservations.each do |reservation|
|
|
|
|
# find pack by pack's created_at before reservation's create_at and pack's expries_at before start_date
|
|
|
|
packs = StatisticProfilePrepaidPack
|
|
|
|
.includes(:prepaid_pack)
|
|
|
|
.references(:prepaid_packs)
|
2022-11-18 18:58:17 +01:00
|
|
|
.where(prepaid_packs: { priceable_id: reservation.reservable.id })
|
|
|
|
.where(prepaid_packs: { priceable_type: reservation.reservable.class.name })
|
2022-10-19 15:19:28 +02:00
|
|
|
.where(statistic_profile_id: reservation.statistic_profile_id)
|
|
|
|
.where('statistic_profile_prepaid_packs.created_at <= ?', reservation.created_at)
|
|
|
|
.where('expires_at is NULL or expires_at > ?', start_date)
|
2023-01-10 11:28:20 +01:00
|
|
|
.order(created_at: :asc)
|
2022-10-19 15:19:28 +02:00
|
|
|
|
|
|
|
# passe reservation if cannot find any pack
|
2022-11-18 18:58:17 +01:00
|
|
|
next if packs.empty?
|
2022-10-19 15:19:28 +02:00
|
|
|
|
|
|
|
user = reservation.statistic_profile.user
|
|
|
|
pack = packs.last
|
|
|
|
|
|
|
|
slots_minutes = reservation.slots.map do |slot|
|
|
|
|
(slot.end_at.to_time - slot.start_at.to_time) / 60.0
|
|
|
|
end
|
|
|
|
# get reservation total minutes
|
|
|
|
reservation_minutes = slots_minutes.reduce(:+) || 0
|
|
|
|
|
|
|
|
info = {
|
|
|
|
user: "#{user.profile.full_name} - #{user.email}",
|
2022-11-18 18:58:17 +01:00
|
|
|
reservation: "Reservation #{reservation.original_invoice.reference} for the machine #{reservation.reservable.name} " \
|
|
|
|
"by #{reservation_minutes / 60.0} hours at #{I18n.l(reservation.created_at.to_date)}",
|
2022-10-19 15:19:28 +02:00
|
|
|
pack_before: "Prepaid pack of hours has used #{pack.minutes_used / 60.0} hours / #{pack.prepaid_pack.minutes / 60.0} hours"
|
|
|
|
}
|
|
|
|
|
|
|
|
if pack.minutes_used == pack.prepaid_pack.minutes && pack.updated_at > start_date
|
|
|
|
info[:pack_after] = 'Reservation minutes is exceed prepaid pack of hours'
|
|
|
|
infos.push(info)
|
|
|
|
elsif pack.minutes_used < pack.prepaid_pack.minutes
|
|
|
|
PrepaidPackService.update_user_minutes(user, reservation)
|
|
|
|
pack.reload
|
|
|
|
info[:pack_after] = "Prepaid pack of hours used #{pack.minutes_used / 60.0} hours after paid this reservation"
|
|
|
|
infos.push(info)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
infos.each do |i|
|
|
|
|
puts i
|
|
|
|
end
|
|
|
|
end
|
2023-01-10 11:28:20 +01:00
|
|
|
|
|
|
|
desc '[release 5.6.6] fix invoice items in error'
|
|
|
|
task invoice_items_in_error: :environment do
|
|
|
|
next if InvoiceItem.where(object_type: 'Error').count.zero?
|
|
|
|
|
|
|
|
InvoiceItem.where(object_type: 'Error').update_all(object_id: 0) # rubocop:disable Rails/SkipsModelValidations
|
|
|
|
|
|
|
|
Fablab::Application.load_tasks if Rake::Task.tasks.empty?
|
|
|
|
Rake::Task['fablab:chain:invoices_items'].invoke
|
|
|
|
end
|
2022-12-30 17:52:28 +01:00
|
|
|
|
2023-03-08 17:08:12 +01:00
|
|
|
desc '[release 5.8.2] fix operator of self-bought carts'
|
2023-02-22 12:02:37 +01:00
|
|
|
task cart_operator: :environment do |_task, _args|
|
|
|
|
Order.where.not(statistic_profile_id: nil).find_each do |order|
|
|
|
|
order.update(operator_profile_id: order.user&.invoicing_profile&.id)
|
|
|
|
end
|
|
|
|
Order.where.not(operator_profile_id: nil).find_each do |order|
|
|
|
|
order.update(statistic_profile_id: order.operator_profile&.user&.statistic_profile&.id)
|
|
|
|
end
|
2022-12-30 17:52:28 +01:00
|
|
|
end
|
2023-03-08 17:08:12 +01:00
|
|
|
|
|
|
|
desc '[release 5.8.2] fix prepaid packs minutes_used'
|
|
|
|
task pack_minutes_used: :environment do |_task, _args|
|
|
|
|
StatisticProfilePrepaidPack.where('minutes_used < 0').find_each do |sppp|
|
|
|
|
previous_packs = sppp.statistic_profile.statistic_profile_prepaid_packs
|
|
|
|
.includes(:prepaid_pack)
|
|
|
|
.where(prepaid_packs: { priceable: sppp.prepaid_pack.priceable })
|
|
|
|
.where("statistic_profile_prepaid_packs.created_at <= '#{sppp.created_at.utc.strftime('%Y-%m-%d %H:%M:%S.%6N')}'")
|
|
|
|
.order('statistic_profile_prepaid_packs.created_at')
|
|
|
|
remaining = {}
|
|
|
|
previous_packs.each do |pack|
|
|
|
|
available_minutes = pack.prepaid_pack.minutes
|
|
|
|
reservations = Reservation.where(reservable: sppp.prepaid_pack.priceable)
|
|
|
|
.where(statistic_profile_id: sppp.statistic_profile_id)
|
|
|
|
.where("created_at > '#{pack.created_at.utc.strftime('%Y-%m-%d %H:%M:%S.%6N')}'")
|
|
|
|
reservations.each do |reservation|
|
|
|
|
next if available_minutes.zero?
|
|
|
|
|
|
|
|
# if the previous pack has not covered all the duration of this reservation, we substract the remaining minutes from the current pack
|
|
|
|
if remaining[reservation.id]
|
|
|
|
if remaining[reservation.id] > available_minutes
|
|
|
|
consumed = available_minutes
|
|
|
|
remaining[reservation.id] = remaining[reservation.id] - available_minutes
|
|
|
|
else
|
|
|
|
consumed = remaining[reservation.id]
|
|
|
|
remaining.except!(reservation.id)
|
|
|
|
end
|
|
|
|
else
|
|
|
|
# if there was no remaining from the previous pack, we substract the reservation duration from the current pack
|
|
|
|
reservation_minutes = reservation.slots.map { |slot| (slot.end_at.to_time - slot.start_at.to_time) / 60.0 }.reduce(:+) || 0
|
|
|
|
if reservation_minutes > available_minutes
|
|
|
|
consumed = available_minutes
|
|
|
|
remaining[reservation.id] = reservation_minutes - consumed
|
|
|
|
else
|
|
|
|
consumed = reservation_minutes
|
|
|
|
end
|
|
|
|
end
|
|
|
|
available_minutes -= consumed
|
|
|
|
end
|
|
|
|
pack.update(minutes_used: pack.prepaid_pack.minutes - available_minutes)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2022-12-30 17:52:28 +01:00
|
|
|
end
|
2016-05-04 18:17:50 +02:00
|
|
|
end
|