ajout d'évènement avec test des conflits de dates

This commit is contained in:
François Vaux 2010-07-23 17:51:04 +02:00
parent 09c465a721
commit a1afe00476
5 changed files with 72 additions and 10 deletions

View File

@ -8,18 +8,46 @@ class EventsController < ApplicationController
@item = Item.find_by_key(params[:key])
dates = params[:event].delete(:dates)
e = Event.new(params[:event].merge(:item => @item))
if e.valid?
dates = extract_dates(dates)
p dates
event = Event.new(params[:event].merge(:item => @item))
flash[:errors] = ""
flash[:title] = params[:event][:title]
flash[:details] = params[:event][:details]
flash[:dates] = dates
if event.valid?
event.save
parsed_dates = extract_dates(dates)
if parsed_dates.all? {|d| d.first == :success }
bookings = []
parsed_dates.map do |d|
bookings << Booking.new(:start_at => d[1], :end_at => d[2], :event => event)
end
if bookings.all?(&:valid?)
bookings.each do |b|
b.event = event
b.save
end
else
bookings.each do |b|
b.errors.each do |_,msg|
flash[:errors] += "<li>#{msg}</li>"
end
end
end
else
parsed_dates.select {|d| d.first == :error}.each do |err|
flash[:errors] += "<li>La date à la ligne #{err.last+1} est invalide</li>"
end
end
else
flash[:errors] = ""
e.errors.each do |attr,msg|
flash[:errors] += "<li>#{msg}</li>"
end
redirect_to item_path(:key => @item.key)
end
redirect_to item_path(:key => @item.key)
end
# PUT /:key/event/:id
@ -32,6 +60,23 @@ class EventsController < ApplicationController
private
def extract_dates(text)
text.each_line.to_a
results = []
text.each_line.to_a.map(&:chomp).each_with_index do |line,lineno|
if line =~ /^(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):(\d{2}) (\d{2}):(\d{2})/
day = "%s-%s-%s" % [$~[3], $~[2], $~[1]]
begin
start_at = ("#{day} %s:%s:00" % [$~[4], $~[5]]).to_datetime
end_at = ("#{day} %s:%s:00" % [$~[6], $~[7]]).to_datetime
rescue ArgumentError
results << [:error, lineno]
next
end
results << [:success, start_at, end_at]
else
results << [:error, lineno]
end
end
results
end
end

View File

@ -1,5 +1,6 @@
module ItemHelper
def default_dates
return flash[:dates] if flash[:dates]
[ @date.strftime('%d/%m/%Y'), hour(+0), hour(+1) ].join(' ')
end

View File

@ -1,5 +1,6 @@
class Booking < ActiveRecord::Base
UNIT = 100 / 24.0 / 4
belongs_to :event
def margin_for(date, offset)
@ -15,4 +16,17 @@ class Booking < ActiveRecord::Base
end_at - start_at
end
def validate
if self[:start_at] > self[:end_at]
errors.add_to_base("Date de départ et de fin incohérentes.")
end
bs = self.event.item.bookings.count(:conditions =>
['(start_at > ? AND start_at < ?) OR'+
'(end_at > ? AND end_at < ?)',
self[:start_at], self[:end_at],
self[:start_at], self[:end_at]])
errors.add_to_base("Conflit de date.") unless bs.zero?
end
end

View File

@ -4,6 +4,8 @@ class Event < ActiveRecord::Base
belongs_to :item
has_many :bookings
before_create :generate_color
validates_presence_of :title, :message => "Le titre ne peut pas être vide"
validates_length_of :title, :within => 4...140,
:message => "Le titre doit faire entre 4 et 140 caractères"

View File

@ -8,7 +8,7 @@
<div id="actions">
<div id="booking-form">
<h2>Réserver</h2>
<% if flash[:errors] %>
<% if flash[:errors] && !flash[:errors].empty? %>
<ul class="errors">
<%= flash[:errors] %>
</ul>
@ -16,12 +16,12 @@
<% form_for :event, :url => add_event_path(:key => @item.key) do |f| %>
<p>
<%= f.label :title, "Titre :" %>
<%= f.text_field :title %>
<%= text_field_tag 'event[title]', flash[:title]||"" %>
<span class="form-field-info">140 caractères maximum</span>
</p>
<p>
<%= f.label :details, "Détails :" %>
<%= f.text_area :details, :rows => 5, :cols => 20 %>
<%= text_area_tag 'event[details]', flash[:details]||"", :rows => 5, :cols => 20 %>
</p>
<p>
<%= f.label :dates, "Dates :" %>