mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-18 07:52:23 +01:00
[bug] when an event is modified, the member's reservations does not reflect the new event date
This commit is contained in:
parent
1c22d3a62a
commit
588b8050db
@ -6,6 +6,7 @@
|
||||
- Updated environment documentation
|
||||
- Removed useless locales' configuration files
|
||||
- OpenAPI's endpoints will now return more detailed error messages when something wrong occurs
|
||||
- Fix a bug: when an event is modified, the member's reservations does not reflect the new event date
|
||||
- Fix a security issue: updated ini to 1.3.8 to fix [CVE-2020-7788](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7788)
|
||||
− Fix a security issue: updated nokogiri to 1.11.1 to fix [CVE-2020-26247](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-26247)
|
||||
- Updated caxlsx to 3.0.4, and the dependencies of caxlsx_rail
|
||||
|
@ -2,172 +2,192 @@
|
||||
|
||||
# Provides helper methods for Events resources and properties
|
||||
class EventService
|
||||
def self.process_params(params)
|
||||
# handle dates & times (whole-day events or not, maybe during many days)
|
||||
range = EventService.date_range({ date: params[:start_date], time: params[:start_time] },
|
||||
{ date: params[:end_date], time: params[:end_time] },
|
||||
params[:all_day] == 'true')
|
||||
params.merge!(availability_attributes: { id: params[:availability_id],
|
||||
start_at: range[:start_at],
|
||||
end_at: range[:end_at],
|
||||
available_type: 'event' })
|
||||
.extract!(:start_date, :end_date, :start_time, :end_time, :all_day)
|
||||
# convert main price to centimes
|
||||
params[:amount] = (params[:amount].to_f * 100 if params[:amount].present?)
|
||||
# delete non-complete "other" prices and convert them to centimes
|
||||
unless params[:event_price_categories_attributes].nil?
|
||||
params[:event_price_categories_attributes].delete_if do |price_cat|
|
||||
price_cat[:price_category_id].empty? || price_cat[:amount].empty?
|
||||
end
|
||||
params[:event_price_categories_attributes].each do |price_cat|
|
||||
price_cat[:amount] = price_cat[:amount].to_f * 100
|
||||
end
|
||||
end
|
||||
# return the resulting params object
|
||||
params
|
||||
end
|
||||
|
||||
def self.date_range(starting, ending, all_day)
|
||||
start_date = Time.zone.parse(starting[:date])
|
||||
end_date = Time.zone.parse(ending[:date])
|
||||
start_time = Time.parse(starting[:time]) if starting[:time]
|
||||
end_time = Time.parse(ending[:time]) if ending[:time]
|
||||
if all_day
|
||||
start_at = DateTime.new(start_date.year, start_date.month, start_date.day, 0, 0, 0, start_date.zone)
|
||||
end_at = DateTime.new(end_date.year, end_date.month, end_date.day, 23, 59, 59, end_date.zone)
|
||||
else
|
||||
start_at = DateTime.new(start_date.year, start_date.month, start_date.day, start_time.hour, start_time.min, start_time.sec, start_date.zone)
|
||||
end_at = DateTime.new(end_date.year, end_date.month, end_date.day, end_time.hour, end_time.min, end_time.sec, end_date.zone)
|
||||
end
|
||||
{ start_at: start_at, end_at: end_at }
|
||||
end
|
||||
|
||||
# delete one or more events (if periodic)
|
||||
def self.delete(event_id, mode = 'single')
|
||||
results = []
|
||||
event = Event.find(event_id)
|
||||
events = case mode
|
||||
when 'single'
|
||||
[event]
|
||||
when 'next'
|
||||
Event.includes(:availability)
|
||||
.where(
|
||||
'availabilities.start_at >= ? AND events.recurrence_id = ?',
|
||||
event.availability.start_at,
|
||||
event.recurrence_id
|
||||
)
|
||||
.references(:availabilities, :events)
|
||||
when 'all'
|
||||
Event.where(
|
||||
'recurrence_id = ?',
|
||||
event.recurrence_id
|
||||
)
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
events.each do |e|
|
||||
# here we use double negation because safe_destroy can return either a boolean (false) or an Availability (in case of delete success)
|
||||
results.push status: !!e.safe_destroy, event: e # rubocop:disable Style/DoubleNegation
|
||||
end
|
||||
results
|
||||
end
|
||||
|
||||
# update one or more events (if periodic)
|
||||
def self.update(event, event_params, mode = 'single')
|
||||
results = []
|
||||
events = case mode
|
||||
when 'single'
|
||||
[event]
|
||||
when 'next'
|
||||
Event.includes(:availability, :event_price_categories, :event_files)
|
||||
.where(
|
||||
'availabilities.start_at >= ? AND events.recurrence_id = ?',
|
||||
event.availability.start_at,
|
||||
event.recurrence_id
|
||||
)
|
||||
.references(:availabilities, :events)
|
||||
when 'all'
|
||||
Event.includes(:availability, :event_price_categories, :event_files)
|
||||
.where(
|
||||
'recurrence_id = ?',
|
||||
event.recurrence_id
|
||||
)
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
events.each do |e|
|
||||
next unless e.id != event.id
|
||||
|
||||
start_at = event_params['availability_attributes']['start_at']
|
||||
end_at = event_params['availability_attributes']['end_at']
|
||||
event_price_categories_attributes = event_params['event_price_categories_attributes']
|
||||
event_files_attributes = event_params['event_files_attributes']
|
||||
e_params = event_params.merge(
|
||||
availability_id: e.availability_id,
|
||||
availability_attributes: {
|
||||
id: e.availability_id,
|
||||
start_at: e.availability.start_at.change(hour: start_at.hour, min: start_at.min),
|
||||
end_at: e.availability.end_at.change(hour: end_at.hour, min: end_at.min),
|
||||
available_type: e.availability.available_type
|
||||
}
|
||||
)
|
||||
epc_attributes = []
|
||||
event_price_categories_attributes&.each do |epca|
|
||||
epc = e.event_price_categories.find_by(price_category_id: epca['price_category_id'])
|
||||
if epc
|
||||
epc_attributes.push(
|
||||
id: epc.id,
|
||||
price_category_id: epc.price_category_id,
|
||||
amount: epca['amount'],
|
||||
_destroy: epca['_destroy']
|
||||
)
|
||||
elsif epca['id'].present?
|
||||
event_price = event.event_price_categories.find(epca['id'])
|
||||
epc_attributes.push(
|
||||
price_category_id: epca['price_category_id'],
|
||||
amount: event_price.amount,
|
||||
_destroy: ''
|
||||
)
|
||||
class << self
|
||||
def process_params(params)
|
||||
# handle dates & times (whole-day events or not, maybe during many days)
|
||||
range = EventService.date_range({ date: params[:start_date], time: params[:start_time] },
|
||||
{ date: params[:end_date], time: params[:end_time] },
|
||||
params[:all_day] == 'true')
|
||||
params.merge!(availability_attributes: { id: params[:availability_id],
|
||||
start_at: range[:start_at],
|
||||
end_at: range[:end_at],
|
||||
available_type: 'event' })
|
||||
.extract!(:start_date, :end_date, :start_time, :end_time, :all_day)
|
||||
# convert main price to centimes
|
||||
params[:amount] = (params[:amount].to_f * 100 if params[:amount].present?)
|
||||
# delete non-complete "other" prices and convert them to centimes
|
||||
unless params[:event_price_categories_attributes].nil?
|
||||
params[:event_price_categories_attributes].delete_if do |price_cat|
|
||||
price_cat[:price_category_id].empty? || price_cat[:amount].empty?
|
||||
end
|
||||
params[:event_price_categories_attributes].each do |price_cat|
|
||||
price_cat[:amount] = price_cat[:amount].to_f * 100
|
||||
end
|
||||
end
|
||||
unless epc_attributes.empty?
|
||||
e_params = e_params.merge(
|
||||
event_price_categories_attributes: epc_attributes
|
||||
)
|
||||
end
|
||||
# return the resulting params object
|
||||
params
|
||||
end
|
||||
|
||||
ef_attributes = []
|
||||
event_files_attributes&.each do |efa|
|
||||
if efa['id'].present?
|
||||
event_file = event.event_files.find(efa['id'])
|
||||
ef = e.event_files.find_by(attachment: event_file.attachment.file.filename)
|
||||
if ef
|
||||
ef_attributes.push(
|
||||
id: ef.id,
|
||||
attachment: efa['attachment'],
|
||||
_destroy: efa['_destroy']
|
||||
def date_range(starting, ending, all_day)
|
||||
start_date = Time.zone.parse(starting[:date])
|
||||
end_date = Time.zone.parse(ending[:date])
|
||||
start_time = Time.parse(starting[:time]) if starting[:time]
|
||||
end_time = Time.parse(ending[:time]) if ending[:time]
|
||||
if all_day
|
||||
start_at = DateTime.new(start_date.year, start_date.month, start_date.day, 0, 0, 0, start_date.zone)
|
||||
end_at = DateTime.new(end_date.year, end_date.month, end_date.day, 23, 59, 59, end_date.zone)
|
||||
else
|
||||
start_at = DateTime.new(start_date.year, start_date.month, start_date.day, start_time.hour, start_time.min, start_time.sec, start_date.zone)
|
||||
end_at = DateTime.new(end_date.year, end_date.month, end_date.day, end_time.hour, end_time.min, end_time.sec, end_date.zone)
|
||||
end
|
||||
{ start_at: start_at, end_at: end_at }
|
||||
end
|
||||
|
||||
# delete one or more events (if periodic)
|
||||
def delete(event_id, mode = 'single')
|
||||
results = []
|
||||
event = Event.find(event_id)
|
||||
events = case mode
|
||||
when 'single'
|
||||
[event]
|
||||
when 'next'
|
||||
Event.includes(:availability)
|
||||
.where(
|
||||
'availabilities.start_at >= ? AND events.recurrence_id = ?',
|
||||
event.availability.start_at,
|
||||
event.recurrence_id
|
||||
)
|
||||
.references(:availabilities, :events)
|
||||
when 'all'
|
||||
Event.where(
|
||||
'recurrence_id = ?',
|
||||
event.recurrence_id
|
||||
)
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
events.each do |e|
|
||||
# here we use double negation because safe_destroy can return either a boolean (false) or an Availability (in case of delete success)
|
||||
results.push status: !!e.safe_destroy, event: e # rubocop:disable Style/DoubleNegation
|
||||
end
|
||||
results
|
||||
end
|
||||
|
||||
# update one or more events (if periodic)
|
||||
def update(event, event_params, mode = 'single')
|
||||
events = case mode
|
||||
when 'single'
|
||||
[event]
|
||||
when 'next'
|
||||
Event.includes(:availability, :event_price_categories, :event_files)
|
||||
.where(
|
||||
'availabilities.start_at >= ? AND events.recurrence_id = ?',
|
||||
event.availability.start_at,
|
||||
event.recurrence_id
|
||||
)
|
||||
.references(:availabilities, :events)
|
||||
when 'all'
|
||||
Event.includes(:availability, :event_price_categories, :event_files)
|
||||
.where(
|
||||
'recurrence_id = ?',
|
||||
event.recurrence_id
|
||||
)
|
||||
else
|
||||
[]
|
||||
end
|
||||
update_events(event, events, event_params)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_events(event, events, event_params)
|
||||
results = []
|
||||
events.each do |e|
|
||||
next unless e.id != event.id
|
||||
|
||||
start_at = event_params['availability_attributes']['start_at']
|
||||
end_at = event_params['availability_attributes']['end_at']
|
||||
event_price_categories_attributes = event_params['event_price_categories_attributes']
|
||||
event_files_attributes = event_params['event_files_attributes']
|
||||
e_params = event_params.merge(
|
||||
availability_id: e.availability_id,
|
||||
availability_attributes: {
|
||||
id: e.availability_id,
|
||||
start_at: e.availability.start_at.change(hour: start_at.hour, min: start_at.min),
|
||||
end_at: e.availability.end_at.change(hour: end_at.hour, min: end_at.min),
|
||||
available_type: e.availability.available_type
|
||||
}
|
||||
)
|
||||
epc_attributes = []
|
||||
event_price_categories_attributes&.each do |epca|
|
||||
epc = e.event_price_categories.find_by(price_category_id: epca['price_category_id'])
|
||||
if epc
|
||||
epc_attributes.push(
|
||||
id: epc.id,
|
||||
price_category_id: epc.price_category_id,
|
||||
amount: epca['amount'],
|
||||
_destroy: epca['_destroy']
|
||||
)
|
||||
elsif epca['id'].present?
|
||||
event_price = event.event_price_categories.find(epca['id'])
|
||||
epc_attributes.push(
|
||||
price_category_id: epca['price_category_id'],
|
||||
amount: event_price.amount,
|
||||
_destroy: ''
|
||||
)
|
||||
end
|
||||
else
|
||||
ef_attributes.push(efa)
|
||||
end
|
||||
unless epc_attributes.empty?
|
||||
e_params = e_params.merge(
|
||||
event_price_categories_attributes: epc_attributes
|
||||
)
|
||||
end
|
||||
|
||||
ef_attributes = []
|
||||
event_files_attributes&.each do |efa|
|
||||
if efa['id'].present?
|
||||
event_file = event.event_files.find(efa['id'])
|
||||
ef = e.event_files.find_by(attachment: event_file.attachment.file.filename)
|
||||
if ef
|
||||
ef_attributes.push(
|
||||
id: ef.id,
|
||||
attachment: efa['attachment'],
|
||||
_destroy: efa['_destroy']
|
||||
)
|
||||
end
|
||||
else
|
||||
ef_attributes.push(efa)
|
||||
end
|
||||
end
|
||||
e_params = e_params.merge(
|
||||
event_files_attributes: ef_attributes
|
||||
)
|
||||
begin
|
||||
results.push status: !!e.update(e_params.permit!), event: e # rubocop:disable Style/DoubleNegation
|
||||
rescue StandardError => err
|
||||
results.push status: false, event: e, error: err.try(:record).try(:class).try(:name), message: err.message
|
||||
end
|
||||
results.concat(update_slots(e.availability_id))
|
||||
end
|
||||
e_params = e_params.merge(
|
||||
event_files_attributes: ef_attributes
|
||||
)
|
||||
begin
|
||||
results.push status: !!e.update(e_params.permit!), event: e # rubocop:disable Style/DoubleNegation
|
||||
results.push status: !!event.update(event_params), event: event # rubocop:disable Style/DoubleNegation
|
||||
rescue StandardError => err
|
||||
results.push status: false, event: e, error: err.try(:record).try(:class).try(:name), message: err.message
|
||||
results.push status: false, event: event, error: err.try(:record).try(:class).try(:name), message: err.message
|
||||
end
|
||||
results.concat(update_slots(event.availability_id))
|
||||
results
|
||||
end
|
||||
begin
|
||||
results.push status: !!event.update(event_params), event: event # rubocop:disable Style/DoubleNegation
|
||||
rescue StandardError => err
|
||||
results.push status: false, event: event, error: err.try(:record).try(:class).try(:name), message: err.message
|
||||
|
||||
def update_slots(availability_id)
|
||||
results = []
|
||||
avail = Availability.find(availability_id)
|
||||
avail.slots.each do |s|
|
||||
results.push(status: !!s.update_attributes(start_at: avail.start_at, end_at: avail.end_at), slot: s) # rubocop:disable Style/DoubleNegation
|
||||
rescue StandardError => err
|
||||
results.push status: false, slot: s, error: err.try(:record).try(:class).try(:name), message: err.message
|
||||
end
|
||||
results
|
||||
end
|
||||
results
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user