diff --git a/app/assets/javascripts/event_suggestions.js b/app/assets/javascripts/event_suggestions.js
new file mode 100644
index 00000000..efb8fdaf
--- /dev/null
+++ b/app/assets/javascripts/event_suggestions.js
@@ -0,0 +1,152 @@
+// // Place all the behaviors and hooks related to the matching controller here.
+// // All this logic will automatically be available in application.js.
+EVENT_URL = '/events/'
+SUGGEST_URL = '/new_event_suggestion'
+
+var ready;
+ready = function() {
+ var typingTimer;
+ var doneTypingInterval = 1000;
+ $('#sugguest-form input').change(function() {
+ clearTimeout(typingTimer);
+ typingTimer = setTimeout(checkVacancy, doneTypingInterval);
+ });
+
+ $('#sugguest-form #selectpicker').change(function() {
+ clearTimeout(typingTimer);
+ typingTimer = setTimeout(checkVacancy, doneTypingInterval);
+ });
+// $(document).ajaxComplete(function(event, request) {
+// var flash = $.parseJSON(request.getResponseHeader('X-Flash-Messages'));
+// if(!flash) return;
+// if(flash.notice) { $('.notice').html('
× ' + flash.notice + '
'); }
+// if(flash.warning) { $('.notice').html('× ' + flash.warning + '
');}
+// if(flash.error) { /* code to display the 'error' flash */ alert("aa"); }
+// });
+
+ function checkVacancy(e) {
+ rooms = []
+ $("#selectpicker option:selected").each(function(){ rooms.push($(this).val());});
+
+ var data = {
+ event: {
+ starts_at_date: $('#event_suggestion_starts_at_date').val(),
+ starts_at_time: $('#event_suggestion_starts_at_time').val(),
+ ends_at_date: $('#event_suggestion_ends_at_date').val(),
+ ends_at_time: $('#event_suggestion_ends_at_time').val(),
+ room_ids: rooms
+ }
+ }
+ $.ajax({
+ url: '/checkVacancy',
+ type: 'PATCH',
+ data: data,
+ dataType: 'json',
+ beforeSend: function(xhr) {
+ xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));},
+ success:(function(data){
+ if (!data["status"]) {
+ flashWarning(data);
+ }
+ else
+ clearFlash();
+ // var data = JSON.parse(data);
+ // if(data['status']){
+ // alert('true');
+ // }
+ // else
+ // alert('false');
+ })
+ // })
+ });
+ };
+
+ function flashWarning(data) {
+ messages = []
+ for(var i in data) {
+ if(isNum(i)) {
+ if(data[i]["rooms"].length > 1) {
+ room = ""
+ for(var j in rooms) {
+ if( room == "") {
+ room = data[i]["rooms"][j];
+ }
+ else {
+ room += ", " + data[i]["rooms"][j];
+ }
+ }
+ room_msg = "in den Räumen " + room;
+ }
+ else {
+ room_msg = "im Raum " + data[i].rooms[0] ;
+ }
+ var starts_at = convertUTCDateToLocalDate(new Date(data[i]["starts_at"]));
+ var ends_at = convertUTCDateToLocalDate(new Date(data[i]["ends_at"]));
+ var starts_at_date = starts_at.getDate() + "." + (starts_at.getMonth() + 1) + "." + starts_at.getFullYear();
+
+ if(isSameDay(starts_at, ends_at)) {
+ time_msg = "am " + starts_at_date
+ }
+ else {
+ var ends_at_date = ends_at.getDate() + "." + (ends_at.getMonth() + 1) + "." + ends_at.getFullYear();
+ time_msg = "vom " + starts_at_date + " bis zum " + ends_at_date;
+ }
+ var starts_at_time = getTime(starts_at);
+ var ends_at_time = getTime(ends_at);
+
+ time_msg += " von " + starts_at_time + " bis " + ends_at_time;
+ msg = "Ihre Alternative konfligiert mit dem Event " + i + " stattfindend " + " " + time_msg + " " + room_msg;
+ msg += suggestionLink(i);
+ messages.push(msg)
+ }
+ }
+ output = ""
+ for( var i in messages) {
+ output += '× ' + messages[i] + '
';
+ }
+
+ $(".notice").html(output);
+ }
+
+ function convertUTCDateToLocalDate(date) {
+ var newDate = new Date(date.getTime()+date.getTimezoneOffset()*60*1000);
+
+ var offset = date.getTimezoneOffset() / 60;
+ var hours = date.getHours();
+
+ newDate.setHours(hours - offset);
+
+ return newDate;
+ }
+ function isNum(val) {
+ return /^\d+$/.test(val);
+ }
+
+ function isSameDay(startDate, endDate) {
+ if(startDate.getDate() == endDate.getDate() && startDate.getMonth() == endDate.getMonth()) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ function getTime(date) {
+ var hours = date.getHours();
+ var mins = date.getMinutes();
+
+ var hourOutput = ((hours < 10) ? "0" + hours : hours);
+ var minOutput = ((mins < 10) ? "0" + mins : mins);(hours < 10 );
+ return hourOutput + ":" + minOutput + " Uhr"
+ }
+
+ function suggestionLink(id) {
+ return " Alternative für Event " + id + " vorschlagen ";
+ }
+
+ function clearFlash() {
+ $(".notice").html("");
+ }
+};
+$(document).ready(ready);
+$(document).on('page:load', ready);
\ No newline at end of file
diff --git a/app/assets/javascripts/events.js b/app/assets/javascripts/events.js
index f711d478..910d866e 100644
--- a/app/assets/javascripts/events.js
+++ b/app/assets/javascripts/events.js
@@ -2,4 +2,147 @@
// // All this logic will automatically be available in application.js.
+var ready;
+ready = function() {
+ var typingTimer;
+ var doneTypingInterval = 1000;
+ $('#event-form input').change(function() {
+ clearTimeout(typingTimer);
+ typingTimer = setTimeout(checkVacancy, doneTypingInterval);
+ });
+ $('#event-form #selectpicker').change(function() {
+ clearTimeout(typingTimer);
+ typingTimer = setTimeout(checkVacancy, doneTypingInterval);
+ });
+// $(document).ajaxComplete(function(event, request) {
+// var flash = $.parseJSON(request.getResponseHeader('X-Flash-Messages'));
+// if(!flash) return;
+// if(flash.notice) { $('.notice').html('× ' + flash.notice + '
'); }
+// if(flash.warning) { $('.notice').html('× ' + flash.warning + '
');}
+// if(flash.error) { /* code to display the 'error' flash */ alert("aa"); }
+// });
+
+ function checkVacancy(e) {
+ rooms = []
+ $("#selectpicker option:selected").each(function(){ rooms.push($(this).val());});
+
+ var data = {
+ event: {
+ starts_at_date: $('#event_starts_at_date').val(),
+ starts_at_time: $('#event_starts_at_time').val(),
+ ends_at_date: $('#event_ends_at_date').val(),
+ ends_at_time: $('#event_ends_at_time').val(),
+ room_ids: rooms
+ }
+ }
+ $.ajax({
+ url: '/checkVacancy',
+ type: 'PATCH',
+ data: data,
+ dataType: 'json',
+ beforeSend: function(xhr) {
+ xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));},
+ success:(function(data){
+ if (!data["status"]) {
+ flashWarning(data);
+ }
+ else
+ clearFlash();
+ // var data = JSON.parse(data);
+ // if(data['status']){
+ // alert('true');
+ // }
+ // else
+ // alert('false');
+ })
+ // })
+ });
+ };
+
+ function flashWarning(data) {
+ messages = []
+ for(var i in data) {
+ if(isNum(i)) {
+ if(data[i]["rooms"].length > 1) {
+ room = ""
+ for(var j in rooms) {
+ if( room == "") {
+ room = data[i]["rooms"][j];
+ }
+ else {
+ room += ", " + data[i]["rooms"][j];
+ }
+ }
+ room_msg = "in den Räumen " + room;
+ }
+ else {
+ room_msg = "im Raum " + data[i].rooms[0] ;
+ }
+ var starts_at = convertUTCDateToLocalDate(new Date(data[i]["starts_at"]));
+ var ends_at = convertUTCDateToLocalDate(new Date(data[i]["ends_at"]));
+ var starts_at_date = starts_at.getDate() + "." + (starts_at.getMonth() + 1) + "." + starts_at.getFullYear();
+
+ if(isSameDay(starts_at, ends_at)) {
+ time_msg = "am " + starts_at_date
+ }
+ else {
+ var ends_at_date = ends_at.getDate() + "." + (ends_at.getMonth() + 1) + "." + ends_at.getFullYear();
+ time_msg = "vom " + starts_at_date + " bis zum " + ends_at_date;
+ }
+ var starts_at_time = getTime(starts_at);
+ var ends_at_time = getTime(ends_at);
+
+ time_msg += " von " + starts_at_time + " bis " + ends_at_time;
+ msg = "Ihr Event konfligiert mit dem Event ”" + data[i]["event_name"] + "” stattfindend " + " " + time_msg + " " + room_msg;
+ messages.push(msg)
+ }
+ }
+ output = ""
+ for( var i in messages) {
+ output += '× ' + messages[i] + '
';
+ }
+
+ $(".notice").html(output);
+ }
+
+ function convertUTCDateToLocalDate(date) {
+ var newDate = new Date(date.getTime()+date.getTimezoneOffset()*60*1000);
+
+ var offset = date.getTimezoneOffset() / 60;
+ var hours = date.getHours();
+
+ newDate.setHours(hours - offset);
+
+ return newDate;
+ }
+ function isNum(val) {
+ return /^\d+$/.test(val);
+ }
+
+ function isSameDay(startDate, endDate) {
+ if(startDate.getDate() == endDate.getDate() && startDate.getMonth() == endDate.getMonth()) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ function getTime(date) {
+ var hours = date.getHours();
+ var mins = date.getMinutes();
+
+ var hourOutput = ((hours < 10) ? "0" + hours : hours);
+ var minOutput = ((mins < 10) ? "0" + mins : mins);(hours < 10 );
+ return hourOutput + ":" + minOutput + " Uhr"
+ }
+
+
+
+ function clearFlash() {
+ $(".notice").html("");
+ }
+};
+$(document).ready(ready);
+$(document).on('page:load', ready);
\ No newline at end of file
diff --git a/app/assets/javascripts/events_approval.js b/app/assets/javascripts/events_approval.js
index dee720fa..bbfd26d3 100644
--- a/app/assets/javascripts/events_approval.js
+++ b/app/assets/javascripts/events_approval.js
@@ -1,2 +1,80 @@
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
+EVENT_URL = '/events/'
+SUGGEST_URL = '/new_event_suggestion'
+DECLINE_URL = '/decline'
+
+
+
+var ready;
+
+ready = function () {
+ $(".decline-btn").click(function(e) {
+ e.preventDefault();
+ var id = this.id;
+ var event_id = id.split("#")[1]
+ $.ajax({
+ url: EVENT_URL + event_id + ".json",
+ type: 'GET',
+ dataType: 'json',
+ beforeSend: function(xhr) {
+ xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));},
+ success:(function(data){
+ // alert("success");
+ insertDeclineLink(data["id"]);
+ insertSuggestLink(data["id"]);
+ insertEventIntoModal(data);
+ $('#myModal').modal('toggle');
+ })
+ });
+ });
+ function insertEventIntoModal(data) {
+ var starts_at = convertUTCDateToLocalDate(new Date(data["starts_at"]));
+ var ends_at = convertUTCDateToLocalDate(new Date(data["ends_at"]));
+ $("#myModalLabel").html("Event " + data["id"]);
+ $("#event_id").html(data["id"]);
+ $("#event_name").html(data["name"]);
+ $("#event_description").html(data["description"]);
+ $("#event_rooms").html(getRoomNames(data["rooms"]));
+ $("#event_participant_count").html(data["participant_count"]);
+ $("#event_starts_at").html(starts_at.toLocaleString());
+ $("#event_ends_at").html(ends_at.toLocaleString());
+ $("#event_user").html(data["user"]);
+
+ }
+
+ function insertSuggestLink(id) {
+ $(".suggest-btn").attr("href", EVENT_URL + id + SUGGEST_URL);
+ }
+
+ function insertDeclineLink(id) {
+ $(".modal-decline-btn").attr("href", EVENT_URL + id + DECLINE_URL);
+ }
+
+ function getRoomNames(rooms) {
+ room_names = ""
+ for ( var i in rooms) {
+ if( room_names == "") {
+ room_names += rooms[i]["name"]
+ }
+ else {
+ room_names += ", " + rooms[i]["name"]
+ }
+ }
+ return room_names //rooms.toString();
+ }
+
+ function convertUTCDateToLocalDate(date) {
+ var newDate = new Date(date.getTime()+date.getTimezoneOffset()*60*1000);
+
+ var offset = date.getTimezoneOffset() / 60;
+ var hours = date.getHours();
+
+ newDate.setHours(hours - offset);
+
+ return newDate;
+ }
+};
+
+$(document).ready(ready);
+$(document).on('page:load', ready);
\ No newline at end of file
diff --git a/app/assets/stylesheets/bootstrap_and_overrides.css b/app/assets/stylesheets/bootstrap_and_overrides.css
index f1683ae3..3513f79a 100644
--- a/app/assets/stylesheets/bootstrap_and_overrides.css
+++ b/app/assets/stylesheets/bootstrap_and_overrides.css
@@ -12,4 +12,8 @@
font-family: 'Glyphicons Halflings';
src: url('/assets/glyphicons-halflings-regular.eot');
src: url('/assets/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('/assets/glyphicons-halflings-regular.woff') format('woff'), url('/assets/glyphicons-halflings-regular.ttf') format('truetype'), url('/assets/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
+}
+
+.modal-body {
+ height: 200px;
}
\ No newline at end of file
diff --git a/app/controllers/event_suggestions_controller.rb b/app/controllers/event_suggestions_controller.rb
new file mode 100644
index 00000000..f06bac93
--- /dev/null
+++ b/app/controllers/event_suggestions_controller.rb
@@ -0,0 +1,60 @@
+class EventSuggestionsController < ApplicationController
+ before_action :set_event_suggestion, only: [:show, :edit, :update, :destroy]
+
+ def index
+ @event_suggestions = EventSuggestion.all
+ respond_to do |format|
+ format.html
+ format.js
+ end
+ end
+
+ def show
+ # respond_with(@event_suggestion)
+ end
+
+ def new
+ @event_suggestion = EventSuggestion.new
+ time = Time.new.getlocal
+ time -= time.sec
+ time += time.min % 15
+ @event_suggestion.starts_at = time
+ @event_suggestion.ends_at = (time+(60*60))
+ end
+
+ def edit
+ end
+
+ def create
+ logger.info event_suggestion_params.inspect
+ @event_suggestion = EventSuggestion.new(event_suggestion_params)
+ respond_to do |format|
+ if @event_suggestion.save
+ format.html { redirect_to @event_suggestion, notice: t('notices.successful_create', :model => EventSuggestion.model_name.human) }
+ format.json { render :show, status: :created, location: @event_suggestion }
+ else
+ format.html { render :new }
+ format.json { render json: @event_suggestion.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ def update
+ @event_suggestion.update(event_suggestion_params)
+ respond_with(@event_suggestion)
+ end
+
+ def destroy
+ @event_suggestion.destroy
+ respond_with(@event_suggestion)
+ end
+
+ private
+ def set_event_suggestion
+ @event_suggestion = EventSuggestion.find(params[:id])
+ end
+
+ def event_suggestion_params
+ params.require(:event_suggestion).permit(:event_suggestion_id, :starts_at_date, :starts_at_time, :ends_at_date, :ends_at_time, :room_ids => [])
+ end
+end
diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb
index 5fb211d2..ab7ee726 100644
--- a/app/controllers/events_controller.rb
+++ b/app/controllers/events_controller.rb
@@ -1,14 +1,26 @@
class EventsController < ApplicationController
-
+ skip_filter :verify_authenticity_token, :check_vacancy
+ # skip_filter :authenticate_user, :check_vacancy
+ skip_before_filter :authenticate_user!
before_action :authenticate_user!
- before_action :set_event, only: [:show, :edit, :update, :destroy, :approve, :new_event_template]
+ before_action :set_event, only: [:show, :edit, :update, :destroy, :approve, :decline, :new_event_template, :new_event_suggestion]
load_and_authorize_resource
- skip_load_and_authorize_resource :only =>[:index, :show, :new, :create, :new_event_template, :reset_filterrific]
-
+ skip_load_and_authorize_resource :only =>[:index, :show, :new, :create, :new_event_template, :reset_filterrific, :check_vacancy, :new_event_suggestion, :decline, :approve]
+ after_filter :flash_to_headers, :only => :check_vacancy
+
def current_user_id
current_user.id
end
+ def flash_to_headers
+ if request.xhr?
+ #avoiding XSS injections via flash
+ flash_json = Hash[flash.map{|k,v| [k,ERB::Util.h(v)] }].to_json
+ response.headers['X-Flash-Messages'] = flash_json
+ flash.discard
+ end
+ end
+
# GET /events/1/new_event_template
def new_event_template
@event_template = EventTemplate.new
@@ -19,6 +31,14 @@ def new_event_template
render "event_templates/new"
end
+ def new_event_suggestion
+ @event_suggestion = EventSuggestion.new
+ @event_suggestion.starts_at = @event.starts_at
+ @event_suggestion.ends_at = @event.ends_at
+ @event_suggestion.rooms = @event.rooms
+ render "event_suggestions/new"
+ end
+
# GET /events
# GET /events.json
def index
@@ -55,21 +75,45 @@ def reset_filterrific
end
def approve
- puts "approve"
@event.update(approved: true)
redirect_to events_approval_path(date: params[:date]) #params are not checked as date is no attribute of event and passed on as a html parameter
end
def decline
- puts "decline"
@event.update(approved: false)
redirect_to events_approval_path(date: params[:date]) #params are not checked as date is no attribute of event and passed on as a html parameter
end
+ def check_vacancy
+ checked_params = event_params
+
+ @event = Event.new(event_params)
+ @event.user_id = current_user_id
+
+ conflicting_events = @event.checkVacancy event_params[:room_ids]
+
+ respond_to do |format|
+ if conflicting_events.empty?
+ flash[:notice] = "Vacant"
+ format.json { render :json => {status: true}}
+ else
+ flash[:warning] = "Not available"
+
+ msg = Hash[conflicting_events.map { |event|
+ eventname = @event.id
+ eventname = event.name if (event.user_id == current_user_id || !event.is_private)
+ [event.id, {"event_name" => eventname, "starts_at" => event.starts_at, "ends_at" => event.ends_at, "rooms" => event.rooms.pluck(:name)}]}]
+ msg[:status]= false
+ format.json { render :json => msg}
+ end
+ end
+ end
+
# GET /events/1
# GET /events/1.json
def show
@user = User.find(@event.user_id).identity_url
+ logger.info @event.rooms.inspect
end
# GET /events/new
@@ -90,33 +134,19 @@ def edit
def sugguest
end
- def create_suggestion
- @event = Event.new(event_params)
- @event.user_id = current_user_id
- logger.info @event.inspect
- respond_to do |format|
- if @event.save
- if Event.checkVacancy(@event.starts_at_date, @event.ends_at_time, params[:event][:room_ids])
- format.html { redirect_to @event, notice: t('notices.successful_sugguest', :model => Event.model_name.human) }
- format.json { render :show, status: :created, location: @event }
- else
- format.html { redirect_to @event, alert: t('alert.successful_sugguest_conflict', :model => Event.model_name.human) }
- format.json { render json: @event.errors, status: :unprocessable_entity }
- end
- else
- format.html { render :sugguest }
- format.json { render json: @event.errors, status: :unprocessable_entity }
- end
- end
- end
# POST /events
# POST /events.json
def create
@event = Event.new(event_params)
@event.user_id = current_user_id
logger.info @event.inspect
+
respond_to do |format|
if @event.save
+ conflicting_events = @event.checkVacancy event_params[:room_ids]
+ if conflicting_events.size > 1 ## this event is also in the returned list
+ format.html { redirect_to @event, alert: t('alert.conflict_detected', :model => Event.model_name.human) }
+ end
format.html { redirect_to @event, notice: t('notices.successful_create', :model => Event.model_name.human) }
format.json { render :show, status: :created, location: @event }
else
@@ -131,6 +161,12 @@ def create
def update
respond_to do |format|
if @event.update(event_params)
+ conflicting_events = @event.checkVacancy event_params[:room_ids]
+ logger.info "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ logger.info conflicting_events.inspect
+ if conflicting_events.size > 1 ## this event is also in the returned list
+ format.html { redirect_to @event, alert: t('alert.conflict_detected', :model => Event.model_name.human) }
+ end
format.html { redirect_to @event, notice: t('notices.successful_update', :model => Event.model_name.human) }
# format.json { render :show, status: :ok, location: @event }
else
@@ -158,6 +194,6 @@ def set_event
# Never trust parameters from the scary internet, only allow the white list through.
def event_params
- params.require(:event).permit(:name, :description, :participant_count, :starts_at_date, :starts_at_time, :ends_at_date, :ends_at_time, :is_private, :show_only_my_events, :room_ids => [])
+ params.require(:event).permit(:event_id, :name, :description, :participant_count, :starts_at_date, :starts_at_time, :ends_at_date, :ends_at_time, :is_private, :show_only_my_events, :room_ids => [])
end
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index f4d1cb3f..ee455e72 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -9,7 +9,7 @@ def bootstrap_flash(options = {})
logger.info type
type = type.to_sym
type = :success if type == :notice
- type = :warning if type == :alert #alert should be treated as a warning and not as a success
+ type = :warning if type == :alert #alert should be treated as a warning and not as a success
type = :danger if type == :error
next unless ALERT_TYPES.include?(type)
diff --git a/app/helpers/event_suggestions_helper.rb b/app/helpers/event_suggestions_helper.rb
new file mode 100644
index 00000000..4d20bbe6
--- /dev/null
+++ b/app/helpers/event_suggestions_helper.rb
@@ -0,0 +1,2 @@
+module EventSuggestionsHelper
+end
diff --git a/app/models/event.rb b/app/models/event.rb
index f294145d..b10a6a65 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -31,13 +31,13 @@ class Event < ActiveRecord::Base
validate :dates_cannot_be_in_the_past,:start_before_end_date
- def dates_cannot_be_in_the_past
- errors.add(:starts_at, "can't be in the past") if starts_at && starts_at < Date.today
- errors.add(:ends_at, "can't be in the past") if ends_at && ends_at < Date.today
- end
- def start_before_end_date
- errors.add(:starts_at, "start has to be before the end") if starts_at && starts_at && ends_at < starts_at
- end
+ def dates_cannot_be_in_the_past
+ errors.add(I18n.t('time.starts_at'), I18n.t('errors.messages.date_in_the_past')) if starts_at < Date.today
+ errors.add(I18n.t('time.ends_at'), I18n.t('errors.messages.date_in_the_past')) if ends_at < Date.today
+ end
+ def start_before_end_date
+ errors.add(I18n.t('time.starts_at'), I18n.t('errors.messages.start_date_not_before_end_date')) if starts_at && starts_at && ends_at < starts_at
+ end
# Scope definitions. We implement all Filterrific filters through ActiveRecord
# scopes. In this example we omit the implementation of the scopes for brevity.
@@ -72,6 +72,19 @@ def start_before_end_date
where("user_id = ?",user_id) if user_id
}
+ scope :other_to, lambda { |event_id|
+ where("id <> ?",event_id) if event_id
+ }
+
+ scope :not_approved, lambda {
+ where("approved is NULL OR approved = TRUE")
+ }
+
+ scope :overlapping, lambda { |start, ende|
+ where(" (:start BETWEEN starts_at AND ends_at)
+ OR (:ende BETWEEN starts_at AND ends_at)
+ OR (:start < starts_at AND :ende > ends_at)", {start:start, ende: ende})
+ }
def self.options_for_sorted_by
[
[(I18n.t 'sort_options.sort_name'), 'name_asc'],
@@ -85,14 +98,29 @@ def self.options_for_sorted_by
]
end
- def self.checkVacancy(startDateTime, endDateTime, rooms)
- #event = self.find_by_starts_at_and_ends_at(startDateTime, endDateTime)
- #if event
- # return false
- #else
- # return true
- # logger.info startDateTime
-# end
- return true
+ def checkVacancy(rooms)
+ logger.info self.starts_at
+ logger.info self.ends_at
+ logger.info rooms
+ colliding_events = []
+ unless rooms.nil?
+ rooms = rooms.collect{|i| i.to_i}
+ end
+
+ events = Event.other_to(id).not_approved.overlapping(starts_at,ends_at)
+ if events.empty?
+ logger.info "XX"
+ return colliding_events
+ else
+ unless rooms.nil?
+ rooms_count = rooms.size
+ events.each do | event |
+ if (rooms - event.rooms.pluck(:id)).size < rooms_count
+ colliding_events.push(event)
+ end
+ end
+ end
+ end
+ return colliding_events
end
end
diff --git a/app/models/event_suggestion.rb b/app/models/event_suggestion.rb
new file mode 100644
index 00000000..11194516
--- /dev/null
+++ b/app/models/event_suggestion.rb
@@ -0,0 +1,24 @@
+class EventSuggestion < ActiveRecord::Base
+ include DateTimeAttribute
+ has_and_belongs_to_many :rooms
+ accepts_nested_attributes_for :rooms
+
+ date_time_attribute :starts_at
+ date_time_attribute :ends_at
+
+ validate :dates_cannot_be_in_the_past,:start_before_end_date
+
+
+ validates :starts_at, presence: true
+ validates :ends_at, presence: true
+
+
+ def dates_cannot_be_in_the_past
+ errors.add(I18n.t('time.starts_at'), I18n.t('errors.messages.date_in_the_past')) if starts_at < Date.today
+ errors.add(I18n.t('time.ends_at'), I18n.t('errors.messages.date_in_the_past')) if ends_at < Date.today
+ end
+ def start_before_end_date
+ errors.add(I18n.t('time.starts_at'), I18n.t('errors.messages.start_date_not_before_end_date')) if starts_at && starts_at && ends_at < starts_at
+ end
+
+end
diff --git a/app/models/room.rb b/app/models/room.rb
index df3136f9..875ab7c6 100644
--- a/app/models/room.rb
+++ b/app/models/room.rb
@@ -3,7 +3,7 @@ class Room < ActiveRecord::Base
has_many :equipment # The plural of 'equipment' is 'equipment'
has_and_belongs_to_many :properties, :class_name => 'RoomProperty'
has_and_belongs_to_many :events
-
+ has_and_belongs_to_many :event_suggestions
def upcoming_events
return self.events.where(['ends_at >= ?', Date.today]).order('starts_at asc')
end
diff --git a/app/views/event_suggestions/_form.html.erb b/app/views/event_suggestions/_form.html.erb
new file mode 100644
index 00000000..fcbfef3d
--- /dev/null
+++ b/app/views/event_suggestions/_form.html.erb
@@ -0,0 +1,59 @@
+<%= form_for @event_suggestion, :html => {:id => "sugguest-form" } do |f| %>
+ <% if @event_suggestion.errors.any? %>
+
+
+
<%= t 'errors.template.header.other', :model => EventSuggestion.model_name.human, :count => @event_suggestion.errors.count %>
+
+
+
+ <% @event_suggestion.errors.full_messages.each do |msg| %>
+ <%= msg %>
+ <% end %>
+
+
+
+ <% end %>
+
+ <%= f.label model_class.human_attribute_name(:starts_at), :class => 'control-label' %>
+
+
+ <%= f.date_field :starts_at_date, :class => 'form-control' %>
+ <%= error_span(@event_suggestion[:starts_at_date]) %>
+
+
+ <%= f.time_field :starts_at_time, :class => 'form-control', value: @event_suggestion.starts_at_time.strftime('%H:%M') %>
+ <%= error_span(@event_suggestion[:starts_at_time]) %>
+
+
+
+
+
+ <%= f.label model_class.human_attribute_name(:ends_at) , :class => 'control-label' %>
+
+
+ <%= f.date_field :ends_at_date, :class => 'form-control' %>
+ <%= error_span(@event_suggestion[:ends_at_date]) %>
+
+
+ <%= f.time_field :ends_at_time, :class => 'form-control', value: @event_suggestion.ends_at_time.strftime('%H:%M') %>
+ <%= error_span(@event_suggestion[:ends_at_time]) %>
+
+
+
+
+ <%= f.label model_class.human_attribute_name(:rooms), :class => 'control-label' %>
+
+ <%= f.select :room_ids, options_from_collection_for_select(Room.all, :id, :name, selected:@event_suggestion.rooms.map(&:id)), {}, {:class=> 'selectpicker', :id => 'selectpicker', :multiple =>'' }%>
+
+
+ <%= error_span(@event_suggestion[:rooms]) %>
+
+
+
+ <%= f.submit nil, :class => 'btn btn-primary' %>
+ <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
+ events_path, :class => 'btn btn-default' %>
+
+<% end %>
diff --git a/app/views/event_suggestions/edit.html.erb b/app/views/event_suggestions/edit.html.erb
new file mode 100644
index 00000000..35054939
--- /dev/null
+++ b/app/views/event_suggestions/edit.html.erb
@@ -0,0 +1,6 @@
+Editing event_suggestion
+
+<%= render 'form' %>
+
+<%= link_to 'Show', @event_suggestion %> |
+<%= link_to 'Back', event_suggestions_path %>
diff --git a/app/views/event_suggestions/index.html.erb b/app/views/event_suggestions/index.html.erb
new file mode 100644
index 00000000..e5f4e715
--- /dev/null
+++ b/app/views/event_suggestions/index.html.erb
@@ -0,0 +1,33 @@
+Listing event_suggestions
+
+
+
+
+ Starts at
+ Datetime
+ Ends at
+ Datetime
+ Status
+ Room
+
+
+
+
+
+ <% @event_suggestions.each do |event_suggestion| %>
+
+ <%= event_suggestion.starts_at %>
+ <%= event_suggestion.ends_at %>
+ <%= event_suggestion.status %>
+ <%= event_suggestion.room_id %>
+ <%= link_to 'Show', event_suggestion %>
+ <%= link_to 'Edit', edit_event_suggestion_path(event_suggestion) %>
+ <%= link_to 'Destroy', event_suggestion, method: :delete, data: { confirm: 'Are you sure?' } %>
+
+ <% end %>
+
+
+
+
+
+<%= link_to 'New Event suggestion', new_event_suggestion_path %>
diff --git a/app/views/event_suggestions/index.json.jbuilder b/app/views/event_suggestions/index.json.jbuilder
new file mode 100644
index 00000000..596bc1b6
--- /dev/null
+++ b/app/views/event_suggestions/index.json.jbuilder
@@ -0,0 +1,4 @@
+json.array!(@event_suggestions) do |event_suggestion|
+ json.extract! event_suggestion, :id, :starts_at, :datetime, :ends_at, :datetime, :status, :room_id
+ json.url event_suggestion_url(event_suggestion, format: :json)
+end
diff --git a/app/views/event_suggestions/new.html.erb b/app/views/event_suggestions/new.html.erb
new file mode 100644
index 00000000..c04ca4d0
--- /dev/null
+++ b/app/views/event_suggestions/new.html.erb
@@ -0,0 +1,5 @@
+<%- model_class = EventSuggestion -%>
+
+<%= render :partial => 'event_suggestions/form', locals: {model_class: model_class} %>
\ No newline at end of file
diff --git a/app/views/event_suggestions/show.html.erb b/app/views/event_suggestions/show.html.erb
new file mode 100644
index 00000000..41489810
--- /dev/null
+++ b/app/views/event_suggestions/show.html.erb
@@ -0,0 +1,35 @@
+<%- model_class = EventSuggestion -%>
+
+
+ <%= model_class.human_attribute_name(:id) %>:
+ <%= @event_suggestion.id %>
+ <%= model_class.human_attribute_name(:rooms) %>:
+ <%= concat_rooms(@event_suggestion) %>
+ <%= model_class.human_attribute_name(:starts_at) %>:
+ <% if @event_suggestion.starts_at%>
+ <%= @event_suggestion.starts_at.strftime("%d.%m.%Y %T") %>
+ <% end %>
+ <%= model_class.human_attribute_name(:ends_at) %>:
+ <% if @event_suggestion.ends_at%>
+ <%= @event_suggestion.ends_at.strftime("%d.%m.%Y %T")%>
+ <% end %>
+ <%= model_class.human_attribute_name(:user) %>:
+ <%= @user %>
+ <%= model_class.human_attribute_name(:created_at) %>:
+ <%= @event_suggestion.created_at.strftime("%d.%m.%Y %T") %>
+ <%= model_class.human_attribute_name(:updated_at) %>:
+ <%= @event_suggestion.updated_at.strftime("%d.%m.%Y %T") %>
+
+
+<%= link_to t('.back', :default => t("helpers.links.back")),
+ event_suggestion_path, :class => 'btn btn-default' %>
+<%= link_to t('.edit', :default => t("helpers.links.edit")),
+ edit_event_suggestion_path(@event_suggestion), :class => 'btn btn-default' %>
+
+ <%= link_to t('.destroy', :default => t("helpers.links.destroy")),
+ event_suggestion_path(@event_suggestion),
+ :method => 'delete',
+ :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
+ :class => 'btn btn-danger' %>
\ No newline at end of file
diff --git a/app/views/event_suggestions/show.json.jbuilder b/app/views/event_suggestions/show.json.jbuilder
new file mode 100644
index 00000000..bcf1d1e5
--- /dev/null
+++ b/app/views/event_suggestions/show.json.jbuilder
@@ -0,0 +1 @@
+json.extract! @event_suggestion, :id, :starts_at, :datetime, :ends_at, :datetime, :status, :room_id, :created_at, :updated_at
diff --git a/app/views/event_templates/_form.html.erb b/app/views/event_templates/_form.html.erb
index 5147b115..3ca08a0a 100644
--- a/app/views/event_templates/_form.html.erb
+++ b/app/views/event_templates/_form.html.erb
@@ -49,6 +49,6 @@
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
- events_path, :class => 'btn btn-default' %>
+ event_templates_path, :class => 'btn btn-default' %>
<% end %>
diff --git a/app/views/event_templates/_list.html.erb b/app/views/event_templates/_list.html.erb
index 2685f1ff..a2aca10b 100644
--- a/app/views/event_templates/_list.html.erb
+++ b/app/views/event_templates/_list.html.erb
@@ -23,14 +23,16 @@
<% if can? :edit, event_template%>
<%= link_to t('.edit', :default => t("helpers.links.edit")),
edit_event_template_path(event_template), :class => 'btn btn-default btn-xs' %>
- <% end %>
- <% if can? :destroy, event_template %>
+ <% end %>
+ <% if can? :destroy, event_template %>
<%= link_to t('.destroy', :default => t("helpers.links.destroy")),
event_template_path(event_template),
:method => :delete,
:data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
:class => 'btn btn-xs btn-danger' %>
- <% end %>
+ <% end %>
+ <%= link_to t('.create', :default => t("helpers.submit.create", :model => Event.model_name.human.titleize)),
+ new_event_from_template_path(event_template), :class => 'btn btn-default btn-xs' %>
<% end %>
diff --git a/app/views/events/_form.html.erb b/app/views/events/_form.html.erb
index f8fec31e..c446b40c 100644
--- a/app/views/events/_form.html.erb
+++ b/app/views/events/_form.html.erb
@@ -1,4 +1,4 @@
-<%= form_for @event, :html => { :class => "form-horizontal event" } do |f| %>
+<%= form_for @event, :html => { :class => "form-horizontal event", :id => "event-form" } do |f| %>
<% if @event.errors.any? %>
@@ -84,6 +84,9 @@
+
+
+
<%= f.submit nil, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
events_path, :class => 'btn btn-default' %>
diff --git a/app/views/events/_list.html.erb b/app/views/events/_list.html.erb
index 59f9b2bc..a18a4151 100644
--- a/app/views/events/_list.html.erb
+++ b/app/views/events/_list.html.erb
@@ -41,11 +41,6 @@
:data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
:class => 'btn btn-xs btn-danger' %>
<% end %>
- <% if can? :sugguest, event%>
- <%= link_to t('.sugguest', :default => t("helpers.links.sugguest")),
- sugguest_event_path(event),
- :class => 'btn btn-xs btn-warning' %>
- <% end %>
<% end %>
diff --git a/app/views/events/show.html.erb b/app/views/events/show.html.erb
index 4a809677..7ec43e02 100644
--- a/app/views/events/show.html.erb
+++ b/app/views/events/show.html.erb
@@ -4,9 +4,8 @@
- <%= t('events.show.id') %>:
- <%= @event.id %>
- <%= t('events.show.name') %>:
+ <%= model_class.human_attribute_name(:id) %>: <%= @event.id %>
+ <%= model_class.human_attribute_name(:name) %>:
<%= @event.name %>
<%= t('events.show.description') %>:
<%= raw nl2br h @event.description %>
@@ -17,11 +16,11 @@
<%= t('events.show.private') %>:
<%= check_box_tag 'private', 'private', @event.is_private, disabled: :disabled %>
<%= t('events.show.starts_at') %>:
- <% if @event.starts_at %>
+ <% if @event.starts_at %>
<%= @event.starts_at.strftime("%d.%m.%Y - %H:%M") %>
- <% end %>
+ <% end %>
<%= t('events.show.ends_at') %>:
- <% if @event.ends_at%>
+ <% if @event.ends_at%>
<%= @event.ends_at.strftime("%d.%m.%Y - %H:%M") %>
<% end %>
<%= t('events.show.user') %>:
@@ -36,13 +35,13 @@
<%= link_to t('.back', :default => t("helpers.links.back")),
events_path, :class => 'btn btn-default' %>
-<% if can? :edit, @event %>
+<% if can? :edit, @event %>
<%= link_to t('.edit', :default => t("helpers.links.edit")),
edit_event_path(@event), :class => 'btn btn-default' %>
<% end %>
<%= link_to t('.create', :default => t("helpers.submit.create", :model => EventTemplate.model_name.human.titleize)),
new_event_template_from_event_path(@event), :class => 'btn btn-default' %>
-<% if can? :destroy, @event %>
+<% if can? :destroy, @event %>
<%= link_to t('.destroy', :default => t("helpers.links.destroy")),
event_path(@event),
:method => 'delete',
diff --git a/app/views/events/show.json.jbuilder b/app/views/events/show.json.jbuilder
index 8a823314..91f0ce46 100644
--- a/app/views/events/show.json.jbuilder
+++ b/app/views/events/show.json.jbuilder
@@ -1 +1 @@
-json.extract! @event, :id, :name, :description, :participant_count, :starts_at, :ends_at, :created_at, :updated_at, :is_private, :user_id
+json.extract! @event, :id, :name, :description, :participant_count, :starts_at, :ends_at, :created_at, :updated_at, :is_private, :user_id, :rooms
diff --git a/app/views/events/sugguest.html.erb b/app/views/events/sugguest.html.erb
index 8c30f36a..9af985b1 100644
--- a/app/views/events/sugguest.html.erb
+++ b/app/views/events/sugguest.html.erb
@@ -3,7 +3,7 @@
<%=t '.title', :default => [:'helpers.titles.sugguest', 'Sugguest %{model}'], :model => model_class.model_name.human.titleize %>
-<%= form_for @event, :url => {action: "create_suggestion"}, :method => "patch", :html => { :class => "form-horizontal event" } do |f| %>
+<%= form_for @event, :url => {action: "create_suggestion"}, :method => "patch", :remote => true, :html => { :class => "form-horizontal event", :id => "sugguest-form" } do |f| %>
<% if @event.errors.any? %>
<% end %>
-
+ <%= f.hidden_field :id, :value => @event.id%>
<%= f.label model_class.human_attribute_name(:name), :class => 'control-label' %>
@@ -74,9 +74,9 @@
-
- <%= f.submit t('.sugguest', :default => t("helpers.links.sugguest")), :class => 'btn btn-primary' %>
+ <%= f.submit t('.sugguest', :default => t("helpers.links.sugguest")), :class => 'btn btn-primary', :id => "submit_suggestion" %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
events_path, :class => 'btn btn-default' %>
+ <%= link_to t('.sugguest', :default => t("helpers.links.sugguest")), sugguest_event_path(17), :target => "_blank" %>
<% end %>
diff --git a/app/views/events_approval/index.html.erb b/app/views/events_approval/index.html.erb
index 3831f35c..a94d3494 100644
--- a/app/views/events_approval/index.html.erb
+++ b/app/views/events_approval/index.html.erb
@@ -5,6 +5,7 @@
Event
Bookings
+ Aktion
@@ -13,6 +14,7 @@
Max Mustermann requests
+ <%=event.id%>
<%= link_to event.name, event_path(event) %> -
<%= event.description %>
(<%= event.participant_count %>)
@@ -30,8 +32,8 @@
<% end %>
- <%= link_to "Decline", decline_event_path(event, date: @date), :method => :decline, :class => 'btn btn-danger btn-xs' %>
- <%= link_to "Approve", approve_event_path(event, date: @date), :method => :approve, :class => 'btn btn-success btn-xs' %>
+ <%= t('.decline', :default => t("helpers.links.decline"))%>
+ <%= link_to t('.approve', :default => t("helpers.links.approve")), approve_event_path(event, date: @date), :method => :approve, :class => 'btn btn-success btn-xs' %>
<% end %>
@@ -72,4 +74,38 @@
<% if !bookings_exist %>
No approved bookings.
-<% end %>
\ No newline at end of file
+<% end %>
+
+
+
+
+
+
+ <%= Event.human_attribute_name(:id) %>:
+
+ <%= Event.human_attribute_name(:name) %>:
+
+ <%= Event.human_attribute_name(:description) %>:
+
+ <%= Event.human_attribute_name(:rooms) %>:
+
+ <%= Event.human_attribute_name(:participant_count) %>:
+
+ <%= Event.human_attribute_name(:starts_at) %>:
+
+ <%= Event.human_attribute_name(:ends_at) %>:
+
+ <%= Event.human_attribute_name(:user) %>:
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 454a18fd..0479c040 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -55,9 +55,9 @@
<%= link_to Room.model_name.human.pluralize, rooms_path %>
<%= link_to Group.model_name.human.pluralize, groups_path %>
<%= link_to Task.model_name.human.pluralize, tasks_path %>
- <%= link_to "Booking", "bookings/new" %>
- <%= link_to "Filtering", "rooms/list" %>
- <%= link_to "Process Requests", "events_approval/" %>
+ <%= link_to Booking.model_name.human.pluralize, new_booking_path %>
+ <%= link_to "Filtering", rooms_list_path %>
+ <%= link_to "Process Requests", events_approval_path %>
<% if user_signed_in? %>
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 9ba6e056..b2fff595 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -122,6 +122,8 @@ de:
too_long: ist zu lang (mehr als %{count} Zeichen)
too_short: ist zu kurz (weniger als %{count} Zeichen)
wrong_length: hat die falsche Länge (muss genau %{count} Zeichen haben)
+ date_in_the_past: kann nicht in der Vergangenheit liegen
+ start_date_not_before_end_date: muss vor dem Endzeitpunkt liegen
template:
body: ! 'Bitte überprüfen Sie die folgenden Felder:'
header:
@@ -135,9 +137,11 @@ de:
submit: ! '%{model} speichern'
update: ! '%{model} aktualisieren'
links:
- sugguest: ! 'Erneut vorschlagen'
+ suggest: ! 'Alternative vorschlagen'
+ decline: ! 'Ablehnen'
+ approve: ! 'Akzeptieren'
titles:
- sugguest: 'Event erneut vorschlagen'
+ suggest: 'Alternative vorschlagen'
number:
currency:
format:
@@ -201,6 +205,8 @@ de:
long: ! '%A, %d. %B %Y, %H:%M Uhr'
short: ! '%d. %B, %H:%M Uhr'
pm: nachmittags
+ starts_at: Startzeitpunkt
+ ends_at: Endzeitpunkt
notices:
successful_create: ! '%{model} wurde erfolgreich erstellt.'
successful_update: ! '%{model} wurde erfolgreich aktualisiert.'
@@ -208,6 +214,7 @@ de:
successful_sugguest: ! '%{model} wurde erfolgreich erneut vorgeschlagen.'
alert:
successful_sugguest_conflict: ! '%{model} konfligiert mit anderem %{model}. %{model} wurde erfolgreich erneut vorgeschlagen.'
+ conflict_detected: ! '%{model} konfligiert mit anderem %{model}.'
tasks:
status:
not_assigned: nicht zugewiesen
diff --git a/config/routes.rb b/config/routes.rb
index f23bab85..e14830ec 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,9 +1,8 @@
Rails.application.routes.draw do
- get 'events_approval/index'
- get 'events_approval/' => 'events_approval#index'
- post 'events/:id/approve' => 'events#approve', as: "approve_event"
- post 'events/:id/decline' => 'events#decline', as: "decline_event"
+ resources :event_suggestions
+
+
get 'rooms/list'
get 'rooms/:id/details' => 'rooms#details'
post 'rooms/list'
@@ -28,6 +27,8 @@
resources :equipment
+ patch 'checkVacancy' => 'events#check_vacancy', as: :check_event_vacancy
+
resources :events do
get :reset_filterrific, on: :collection
end
@@ -48,9 +49,14 @@
get 'templates/:id/new_event' => 'event_templates#new_event', as: :new_event_from_template
get 'events/:id/new_event_template' => 'events#new_event_template', as: :new_event_template_from_event
+ get 'events/:id/new_event_suggestion' => 'events#new_event_suggestion', as: :new_event_suggestion_from_event
get 'events/:id/sugguest' => 'events#sugguest', as: :sugguest_event
- patch 'events/:id/sugguest' => 'events#create_suggestion', as: :create_suggestion
+
+ get 'events_approval/index'
+ get 'events_approval/' => 'events_approval#index'
+ get 'events/:id/approve' => 'events#approve', as: "approve_event"
+ get 'events/:id/decline' => 'events#decline', as: "decline_event"
# Example of regular route:
# get 'products/:id' => 'catalog#view'
diff --git a/db/migrate/20141208110258_add_event_suggestions_to_rooms.rb b/db/migrate/20141208110258_add_event_suggestions_to_rooms.rb
new file mode 100644
index 00000000..c741d8a8
--- /dev/null
+++ b/db/migrate/20141208110258_add_event_suggestions_to_rooms.rb
@@ -0,0 +1,5 @@
+class AddEventSuggestionsToRooms < ActiveRecord::Migration
+ def change
+ add_reference :rooms, :event_suggestion, index: true
+ end
+end
diff --git a/db/migrate/20141208110937_create_event_suggestions_rooms.rb b/db/migrate/20141208110937_create_event_suggestions_rooms.rb
new file mode 100644
index 00000000..0aa7b2fc
--- /dev/null
+++ b/db/migrate/20141208110937_create_event_suggestions_rooms.rb
@@ -0,0 +1,8 @@
+class CreateEventSuggestionsRooms < ActiveRecord::Migration
+ def change
+ create_table :event_suggestions_rooms do |t|
+ t.belongs_to :event_suggestion
+ t.belongs_to :room
+ end
+ end
+end
diff --git a/db/migrate/20141210144902_create_event_suggestions.rb b/db/migrate/20141210144902_create_event_suggestions.rb
new file mode 100644
index 00000000..1887d64b
--- /dev/null
+++ b/db/migrate/20141210144902_create_event_suggestions.rb
@@ -0,0 +1,13 @@
+class CreateEventSuggestions < ActiveRecord::Migration
+ def change
+ create_table :event_suggestions do |t|
+ t.datetime :starts_at
+ t.datetime :ends_at
+ t.string :status
+ t.timestamps
+ end
+ add_reference :event_suggestions, :room, index: true
+ add_reference :event_suggestions, :user, index: true
+
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index a38c2047..dd54796a 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,10 +11,11 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20141126141428) do
+ActiveRecord::Schema.define(version: 20141210144902) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
+ enable_extension "hstore"
create_table "attachments", force: true do |t|
t.string "title"
@@ -51,6 +52,24 @@
add_index "equipment", ["room_id"], name: "index_equipment_on_room_id", using: :btree
+ create_table "event_suggestions", force: true do |t|
+ t.datetime "starts_at"
+ t.datetime "ends_at"
+ t.string "status"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.integer "room_id"
+ t.integer "user_id"
+ end
+
+ add_index "event_suggestions", ["room_id"], name: "index_event_suggestions_on_room_id", using: :btree
+ add_index "event_suggestions", ["user_id"], name: "index_event_suggestions_on_user_id", using: :btree
+
+ create_table "event_suggestions_rooms", force: true do |t|
+ t.integer "event_suggestion_id"
+ t.integer "room_id"
+ end
+
create_table "event_templates", force: true do |t|
t.string "name"
t.text "description"
@@ -76,10 +95,10 @@
t.integer "user_id"
t.integer "room_id"
t.boolean "is_private"
+ t.boolean "approved"
t.string "status", default: "In Bearbeitung"
t.datetime "starts_at"
t.datetime "ends_at"
- t.boolean "approved"
t.date "start_date"
t.time "start_time"
t.date "end_date"
@@ -117,8 +136,11 @@
t.integer "size"
t.datetime "created_at"
t.datetime "updated_at"
+ t.integer "event_suggestion_id"
end
+ add_index "rooms", ["event_suggestion_id"], name: "index_rooms_on_event_suggestion_id", using: :btree
+
create_table "tasks", force: true do |t|
t.string "name"
t.string "description"