1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-28 09:24:24 +01:00

Merge branch 'dev' for release 5.7.2

This commit is contained in:
Sylvain 2023-02-24 16:49:24 +01:00
commit 2d83e7a7f5
11 changed files with 167 additions and 14 deletions

View File

@ -1,5 +1,11 @@
# Changelog Fab-manager
## v5.7.2 2023 February 24
- Fix a bug: unable to update recurrent events
- Fix a bug: invalid border color for slots
- Fix a bug: members can change/cancel their reservations
## v5.7.1 2023 February 20
- Fix a bug: timezone is ignored while configuring calendar opening/closing time

View File

@ -23,10 +23,11 @@ module AvailabilityHelper
end
# @param slot [Slot]
# @param reservable [Machine]
# @param customer [User]
def machines_slot_border_color(slot, customer = nil)
if slot.reserved?
slot.reserved_by?(customer&.id) ? IS_RESERVED_BY_CURRENT_USER : IS_FULL
def machines_slot_border_color(slot, reservable = nil, customer = nil)
if slot.reserved?(reservable)
slot.reserved_by?(customer&.id, [reservable]) ? IS_RESERVED_BY_CURRENT_USER : IS_FULL
else
MACHINE_COLOR
end

View File

@ -89,9 +89,9 @@ class Event::UpdateEventService
)
end
ef_attributes = file_attributes(base_event, occurrence, event_params)
e_params.merge(
event_files_attributes: ef_attributes
event_files_attributes: file_attributes(base_event, occurrence, event_params),
event_image_attributes: image_attributes(occurrence, event_params)
)
end
@ -137,5 +137,15 @@ class Event::UpdateEventService
end
ef_attributes
end
# @param occurrence [Event]
# @param event_params [ActionController::Parameters]
def image_attributes(occurrence, event_params)
if event_params['event_image_attributes'].nil? || event_params['event_image_attributes']['id'].present?
{ id: occurrence.event_image&.id }
else
event_params['event_image_attributes']
end
end
end
end

View File

@ -11,7 +11,7 @@ class Slots::TitleService
# @param reservables [Array<Machine, Space, Training, Event>]
def call(slot, reservables = nil)
reservables = all_reservables(slot) if reservables.nil?
is_reserved = slot.reserved?
is_reserved = reservables.map { |r| slot.reserved?(r) }.reduce(:|)
is_reserved_by_user = slot.reserved_by?(@user&.id, reservables)
name = reservables.map(&:name).join(', ')
@ -37,6 +37,7 @@ class Slots::TitleService
end
# @param slot [Slot]
# @return [Array<Machine, Space, Training, Event>]
def all_reservables(slot)
slot.places.pluck('reservable_type', 'reservable_id').map { |r| r[0].classify.constantize.find(r[1]) }
end

View File

@ -1,8 +1,8 @@
# frozen_string_literal: true
json.slot_id slot.id
json.can_modify slot.modifiable?(operator_role, @user&.id, reservable)
json.title Slots::TitleService.new(operator_role, @user).call(slot, [reservable])
json.can_modify slot.modifiable?(operator_role, user&.id, reservable)
json.title Slots::TitleService.new(operator_role, user).call(slot, [reservable])
json.start slot.start_at.iso8601
json.end slot.end_at.iso8601
json.is_reserved slot.reserved?(reservable)
@ -10,7 +10,7 @@ json.is_completed slot.full?(reservable)
json.backgroundColor 'white'
json.availability_id slot.availability_id
json.slots_reservations_ids Slots::ReservationsService.user_reservations(slot, @user, reservable)[:reservations]
json.slots_reservations_ids Slots::ReservationsService.user_reservations(slot, user, reservable)[:reservations]
json.tag_ids slot.availability.tag_ids
json.tags slot.availability.tags do |t|

View File

@ -1,8 +1,8 @@
# frozen_string_literal: true
json.array!(@slots) do |slot|
json.partial! 'api/availabilities/slot', slot: slot, operator_role: @operator_role, reservable: @machine
json.borderColor machines_slot_border_color(slot, @customer)
json.partial! 'api/availabilities/slot', slot: slot, operator_role: @operator_role, reservable: @machine, user: @customer
json.borderColor machines_slot_border_color(slot, @machine, @customer)
json.machine do
json.id @machine.id

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
json.array!(@slots) do |slot|
json.partial! 'api/availabilities/slot', slot: slot, operator_role: @operator_role, reservable: @space
json.partial! 'api/availabilities/slot', slot: slot, operator_role: @operator_role, reservable: @space, user: @customer
json.is_completed slot.full?
json.borderColor space_slot_border_color(slot)

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
json.array!(@slots) do |slot|
json.partial! 'api/availabilities/slot', slot: slot, operator_role: @operator_role, reservable: slot.availability.trainings.first
json.partial! 'api/availabilities/slot', slot: slot, operator_role: @operator_role, reservable: slot.availability.trainings.first, user: @customer
json.borderColor trainings_events_border_color(slot.availability)
json.is_completed slot.full?

View File

@ -1,6 +1,6 @@
{
"name": "fab-manager",
"version": "5.7.1",
"version": "5.7.2",
"description": "Fab-manager is the FabLab management solution. It provides a comprehensive, web-based, open-source tool to simplify your administrative tasks and your marker's projects.",
"keywords": [
"fablab",

View File

@ -0,0 +1,134 @@
# frozen_string_literal: true
require 'test_helper'
module Events; end
class Events::RecurrenceUpdateTest < ActionDispatch::IntegrationTest
def setup
@admin = User.find_by(username: 'admin')
login_as(@admin, scope: :user)
end
test 'update a recurrent event' do
# first create a recurrent event
name = 'Fablab party'
post '/api/events',
params: {
event: {
title: name,
event_image_attributes: {
attachment: fixture_file_upload('/files/event/Party.jpg')
},
description: 'Come party tonight at the fablab...',
start_date: 2.weeks.from_now,
end_date: 2.weeks.from_now,
all_day: false,
start_time: '18:00',
end_time: '23:29',
amount: 20,
category_id: 2,
recurrence: 'month',
recurrence_end_at: 2.weeks.from_now + 3.months
}
},
headers: upload_headers
# Check response format & status
assert_equal 201, response.status, response.body
assert_equal Mime[:json], response.content_type
# Check the events were correctly created
db_events = Event.where(title: name)
assert_equal 4, db_events.count
# Update all the events
event = db_events.first
new_title = 'Skateboard party'
new_descr = 'Come make a skateboard tonight at the Fablab'
new_image = '/files/event/Skateboard.jpg'
put "/api/events/#{event&.id}", params: {
event: {
title: new_title,
event_image_attributes: {
attachment: fixture_file_upload(new_image)
},
description: new_descr,
category_id: 1,
event_theme_ids: [1],
age_range_id: 1,
start_date: event&.availability&.start_at,
end_date: event&.availability&.end_at,
all_day: false,
start_time: '18:00',
end_time: '23:29',
amount: 20
},
edit_mode: 'all'
}, headers: upload_headers
# Check response format & status
assert_response :success, response.body
assert_equal Mime[:json], response.content_type
# Check the events were correctly updated
res = json_response(response.body)
assert_equal 'update', res[:action]
assert_equal 4, res[:total]
assert_equal 4, res[:updated]
res[:details][:events].each do |res_event|
assert res_event[:status]
db_event = Event.find(res_event[:event][:id])
assert_equal new_title, db_event.title
assert_equal new_descr, db_event.description
assert_equal 1, db_event.category_id
assert_includes db_event.event_theme_ids, 1
assert_equal 1, db_event.age_range_id
assert FileUtils.compare_file(
File.join(ActionDispatch::IntegrationTest.fixture_path, new_image),
db_event.event_image.attachment.file.path
)
end
# Update again but only the next events
event = Event.includes(:availability).where(title: new_title).order('availabilities.start_at').limit(2)[1]
put "/api/events/#{event&.id}", params: {
event: {
title: event.title,
description: event.description,
event_image_attributes: {
id: event.event_image.id
},
category_id: 2,
event_theme_ids: [1],
age_range_id: 1,
start_date: event.availability.start_at,
end_date: event.availability.end_at,
all_day: false,
start_time: '18:00',
end_time: '23:29',
amount: 20
},
edit_mode: 'next'
}.to_json, headers: default_headers
# Check response format & status
assert_response :success, response.body
assert_equal Mime[:json], response.content_type
# Check the events were correctly updated
res = json_response(response.body)
assert_equal 'update', res[:action]
assert_equal 3, res[:total]
assert_equal 3, res[:updated]
res[:details][:events].each do |res_event|
assert res_event[:status]
db_event = Event.find(res_event[:event][:id])
assert_equal 2, db_event.category_id
assert FileUtils.compare_file(
File.join(ActionDispatch::IntegrationTest.fixture_path, new_image),
db_event.event_image.attachment.file.path
)
end
end
end

View File

@ -12,6 +12,7 @@ require 'sidekiq/testing'
require 'minitest/reporters'
require 'helpers/invoice_helper'
require 'helpers/archive_helper'
require 'fileutils'
VCR.configure do |config|
config.cassette_library_dir = 'test/vcr_cassettes'