aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcedricnjanga2017-12-19 16:21:06 +0100
committerLuc Donnet2017-12-21 13:55:49 +0100
commit43f8c76522288a0328d520dfc753ed173fc84964 (patch)
treee067ae1f57fb34a5a82425b1e278507ccfdba4ae
parent723bee2cafff84c0b948f85ed450408d6cbc866a (diff)
downloadchouette-core-43f8c76522288a0328d520dfc753ed173fc84964.tar.bz2
BusinessCalendar => PurchaseWindow
belongs_to referential
-rw-r--r--app/assets/stylesheets/components/_color_selector.sass21
-rw-r--r--app/assets/stylesheets/typography/_sboiv.sass2
-rw-r--r--app/controllers/business_calendars_controller.rb78
-rw-r--r--app/controllers/purchase_windows_controller.rb47
-rw-r--r--app/decorators/business_calendar_decorator.rb26
-rw-r--r--app/decorators/purchase_window_decorator.rb27
-rw-r--r--app/helpers/table_builder_helper/url.rb2
-rw-r--r--app/models/business_calendar.rb16
-rw-r--r--app/models/calendar.rb9
-rw-r--r--app/models/chouette/purchase_window.rb43
-rw-r--r--app/models/concerns/date_support.rb (renamed from app/models/concerns/calendar_support.rb)84
-rw-r--r--app/models/concerns/period_support.rb80
-rw-r--r--app/models/referential.rb4
-rw-r--r--app/policies/business_calendar_policy.rb20
-rw-r--r--app/policies/purchase_window_policy.rb20
-rw-r--r--app/views/business_calendars/_filters.html.slim17
-rw-r--r--app/views/business_calendars/_form.html.slim49
-rw-r--r--app/views/business_calendars/index.html.slim48
-rw-r--r--app/views/purchase_windows/_date_value_fields.html.slim (renamed from app/views/business_calendars/_date_value_fields.html.slim)0
-rw-r--r--app/views/purchase_windows/_filters.html.slim18
-rw-r--r--app/views/purchase_windows/_form.html.slim29
-rw-r--r--app/views/purchase_windows/_period_fields.html.slim (renamed from app/views/business_calendars/_period_fields.html.slim)0
-rw-r--r--app/views/purchase_windows/index.html.slim44
-rw-r--r--app/views/purchase_windows/new.html.slim (renamed from app/views/business_calendars/new.html.slim)2
-rw-r--r--app/views/purchase_windows/show.html.slim20
-rw-r--r--config/breadcrumbs.rb11
-rw-r--r--config/locales/purchase_windows.en.yml (renamed from config/locales/business_calendars.en.yml)39
-rw-r--r--config/locales/purchase_windows.fr.yml (renamed from config/locales/business_calendars.fr.yml)10
-rw-r--r--config/routes.rb4
-rw-r--r--db/migrate/20171215144543_rename_business_calendars_to_purchase_windows.rb5
-rw-r--r--db/migrate/20171215145023_update_purchase_windows_attributes.rb13
-rw-r--r--db/schema.rb27
-rw-r--r--lib/stif/permission_translator.rb2
-rw-r--r--spec/factories/chouette_purchase_windows.rb16
-rw-r--r--spec/models/business_calendar_spec.rb5
-rw-r--r--spec/models/chouette/purchase_window_spec.rb27
-rw-r--r--spec/policies/purchase_window_policy_spec.rb15
-rw-r--r--spec/support/permissions.rb1
38 files changed, 492 insertions, 389 deletions
diff --git a/app/assets/stylesheets/components/_color_selector.sass b/app/assets/stylesheets/components/_color_selector.sass
new file mode 100644
index 000000000..07bfa0c80
--- /dev/null
+++ b/app/assets/stylesheets/components/_color_selector.sass
@@ -0,0 +1,21 @@
+select.color_selector
+ option[value='#9B9B9B']
+ background-color: #9B9B9B
+ option[value='#FFA070']
+ background-color: #FFA070
+ option[value='#C67300']
+ background-color: #C67300
+ option[value='#7F551B']
+ background-color: #7F551B
+ option[value='#41CCE3']
+ background-color: #41CCE3
+ option[value='#09B09C']
+ background-color: #09B09C
+ option[value='#3655D7']
+ background-color: #3655D7
+ option[value='#6321A0']
+ background-color: #6321A0
+ option[value='#E796C6']
+ background-color: #E796C6
+ option[value='#DD2DAA']
+ background-color: #DD2DAA \ No newline at end of file
diff --git a/app/assets/stylesheets/typography/_sboiv.sass b/app/assets/stylesheets/typography/_sboiv.sass
index f694306c4..37f393167 100644
--- a/app/assets/stylesheets/typography/_sboiv.sass
+++ b/app/assets/stylesheets/typography/_sboiv.sass
@@ -89,7 +89,7 @@
.sb-OAS:before
content: '\e90f'
-.sb-calendar:before
+.sb-calendar:before, .sb-purchase_windows:before
content: '\e910'
.sb-journey_pattern:before
diff --git a/app/controllers/business_calendars_controller.rb b/app/controllers/business_calendars_controller.rb
deleted file mode 100644
index c5fbe9c89..000000000
--- a/app/controllers/business_calendars_controller.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-class BusinessCalendarsController < ChouetteController
- include PolicyChecker
- defaults resource_class: BusinessCalendar
- before_action :ransack_contains_date, only: [:index]
- respond_to :html
- respond_to :js, only: :index
-
- def index
- index! do
- @business_calendars = ModelDecorator.decorate(@business_calendars, with: BusinessCalendarDecorator)
- end
- end
-
- def show
- show! do
- @business_calendar = @business_calendar.decorate
- end
- end
-
- def create
- puts "CREATE"
- puts build_resource.inspect
- create!
- end
-
- private
- def business_calendar_params
- params.require(:business_calendar).permit(
- :id,
- :name,
- :short_name,
- :color,
- periods_attributes: [:id, :begin, :end, :_destroy],
- date_values_attributes: [:id, :value, :_destroy])
- end
-
- def sort_column
- BusinessCalendar.column_names.include?(params[:sort]) ? params[:sort] : 'short_name'
- end
-
- def sort_direction
- %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc'
- end
-
- protected
-
- def begin_of_association_chain
- current_organisation
- end
- #
- # def build_resource
- # @business_calendar ||= current_organisation.business_calendars.new
- # end
- #
- # def resource
- # @business_calendar ||= current_organisation.business_calendars.find(params[:id])
- # end
-
- def collection
- @q = current_organisation.business_calendars.ransack(params[:q])
-
- business_calendars = @q.result
- business_calendars = business_calendars.order(sort_column + ' ' + sort_direction) if sort_column && sort_direction
- @business_calendars = business_calendars.paginate(page: params[:page])
- end
-
- def ransack_contains_date
- date =[]
- if params[:q] && !params[:q]['contains_date(1i)'].empty?
- ['contains_date(1i)', 'contains_date(2i)', 'contains_date(3i)'].each do |key|
- date << params[:q][key].to_i
- params[:q].delete(key)
- end
- params[:q]['contains_date'] = Date.new(*date) rescue nil
- end
- end
-
-end
diff --git a/app/controllers/purchase_windows_controller.rb b/app/controllers/purchase_windows_controller.rb
new file mode 100644
index 000000000..b676623ae
--- /dev/null
+++ b/app/controllers/purchase_windows_controller.rb
@@ -0,0 +1,47 @@
+class PurchaseWindowsController < ChouetteController
+ include ReferentialSupport
+ include RansackDateFilter
+ include PolicyChecker
+ before_action only: [:index] { set_date_time_params("bounding_dates", Date) }
+ defaults :resource_class => Chouette::PurchaseWindow, collection_name: 'purchase_windows', instance_name: 'purchase_window'
+ belongs_to :referential
+
+ def index
+ index! do
+ scope = self.ransack_period_range(scope: @purchase_windows, error_message: t('compliance_check_sets.filters.error_period_filter'), query: :overlapping)
+ @q = scope.ransack(params[:q])
+ @purchase_windows = decorate_purchase_windows(@q.result.paginate(page: params[:page], per_page: 30))
+ end
+ end
+
+ def show
+ show! do
+ @purchase_window = @purchase_window.decorate(context: {
+ referential: @referential
+ })
+ end
+ end
+
+ protected
+
+ def create_resource(purchase_window)
+ purchase_window.referential = @referential
+ super
+ end
+
+ private
+
+ def purchase_window_params
+ params.require(:purchase_window).permit(:id, :name, :color, :referential_id, periods_attributes: [:id, :begin, :end, :_destroy])
+ end
+
+ def decorate_purchase_windows(purchase_windows)
+ ModelDecorator.decorate(
+ purchase_windows,
+ with: PurchaseWindowDecorator,
+ context: {
+ referential: @referential
+ }
+ )
+ end
+end
diff --git a/app/decorators/business_calendar_decorator.rb b/app/decorators/business_calendar_decorator.rb
deleted file mode 100644
index 3990c3b31..000000000
--- a/app/decorators/business_calendar_decorator.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-class BusinessCalendarDecorator < Draper::Decorator
- delegate_all
-
- def action_links
- links = []
- policy = h.policy(object)
-
- if policy.edit?
- links << Link.new(
- content: h.t('business_calendars.actions.edit'),
- href: h.edit_business_calendar_path(object)
- )
- end
-
- if policy.destroy?
- links << Link.new(
- content: h.destroy_link_content,
- href: h.business_calendar_path(object),
- method: :delete,
- data: { confirm: h.t('business_calendars.actions.destroy_confirm') }
- )
- end
-
- links
- end
-end
diff --git a/app/decorators/purchase_window_decorator.rb b/app/decorators/purchase_window_decorator.rb
new file mode 100644
index 000000000..4ad5a7589
--- /dev/null
+++ b/app/decorators/purchase_window_decorator.rb
@@ -0,0 +1,27 @@
+class PurchaseWindowDecorator < Draper::Decorator
+ decorates Chouette::PurchaseWindow
+ delegate_all
+
+ def action_links
+ policy = h.policy(object)
+ links = []
+
+ if policy.update?
+ links << Link.new(
+ content: I18n.t('actions.edit'),
+ href: h.edit_referential_purchase_window_path(context[:referential].id, object)
+ )
+ end
+
+ if policy.destroy?
+ links << Link.new(
+ content: I18n.t('actions.destroy'),
+ href: h.referential_purchase_window_path(context[:referential].id, object),
+ method: :delete,
+ data: { confirm: h.t('purchase_window.actions.destroy_confirm') }
+ )
+ end
+
+ links
+ end
+end \ No newline at end of file
diff --git a/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb
index a53ac5620..28f1ade76 100644
--- a/app/helpers/table_builder_helper/url.rb
+++ b/app/helpers/table_builder_helper/url.rb
@@ -10,7 +10,7 @@ module TableBuilderHelper
polymorph_url << item.route.line if item.is_a?(Chouette::RoutingConstraintZone)
polymorph_url << item if item.respond_to? :line_referential
polymorph_url << item.stop_area if item.respond_to? :stop_area
- polymorph_url << item if item.respond_to?(:stop_points) || item.is_a?(Chouette::TimeTable)
+ polymorph_url << item if item.respond_to?(:stop_points) || item.is_a?(Chouette::TimeTable) || item.is_a?(Chouette::PurchaseWindow)
elsif item.respond_to? :referential
if item.respond_to? :workbench
polymorph_url << item.workbench
diff --git a/app/models/business_calendar.rb b/app/models/business_calendar.rb
deleted file mode 100644
index 9ada43b6f..000000000
--- a/app/models/business_calendar.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-require 'range_ext'
-require_relative 'calendar/date_value'
-require_relative 'calendar/period'
-
-class BusinessCalendar < ActiveRecord::Base
- include CalendarSupport
- extend Enumerize
- enumerize :color, in: %w(#9B9B9B #FFA070 #C67300 #7F551B #41CCE3 #09B09C #3655D7 #6321A0 #E796C6 #DD2DAA)
-
- scope :contains_date, ->(date) { where('date ? = any (dates) OR date ? <@ any (date_ranges)', date, date) }
-
- def self.ransackable_scopes(auth_object = nil)
- [:contains_date]
- end
-
-end
diff --git a/app/models/calendar.rb b/app/models/calendar.rb
index 5df2bb1da..34ed51374 100644
--- a/app/models/calendar.rb
+++ b/app/models/calendar.rb
@@ -3,7 +3,14 @@ require_relative 'calendar/date_value'
require_relative 'calendar/period'
class Calendar < ActiveRecord::Base
- include CalendarSupport
+ include DateSupport
+ include PeriodSupport
+
+ has_paper_trail
+ belongs_to :organisation
+
+ validates_presence_of :name, :short_name, :organisation
+ validates_uniqueness_of :short_name
has_many :time_tables
diff --git a/app/models/chouette/purchase_window.rb b/app/models/chouette/purchase_window.rb
new file mode 100644
index 000000000..a9bbe2003
--- /dev/null
+++ b/app/models/chouette/purchase_window.rb
@@ -0,0 +1,43 @@
+require 'range_ext'
+require_relative '../calendar/period'
+
+module Chouette
+ class PurchaseWindow < Chouette::TridentActiveRecord
+ # include ChecksumSupport
+ include ObjectidSupport
+ include PeriodSupport
+ extend Enumerize
+ enumerize :color, in: %w(#9B9B9B #FFA070 #C67300 #7F551B #41CCE3 #09B09C #3655D7 #6321A0 #E796C6 #DD2DAA)
+
+ has_paper_trail
+ belongs_to :referential
+
+ validates_presence_of :name, :referential
+
+ scope :overlapping, -> (period_range) do
+ where("(periods.begin <= :end AND periods.end >= :begin) OR (dates BETWEEN :begin AND :end)", {begin: period_range.begin, end: period_range.end})
+ end
+
+ def local_id
+ "IBOO-#{self.referential.id}-#{self.id}"
+ end
+
+ def bounding_dates
+ periods_min_date..periods_max_date if periods_min_date && periods_max_date
+ end
+
+ def periods_max_date
+ return nil if self.periods.empty?
+ self.periods.max.end
+ end
+
+ def periods_min_date
+ return nil if self.periods.empty?
+ self.periods.min.begin
+ end
+
+ # def checksum_attributes
+ # end
+
+ end
+end \ No newline at end of file
diff --git a/app/models/concerns/calendar_support.rb b/app/models/concerns/date_support.rb
index 73bb201ec..fbfe19af1 100644
--- a/app/models/concerns/calendar_support.rb
+++ b/app/models/concerns/date_support.rb
@@ -1,90 +1,14 @@
-module CalendarSupport
+module DateSupport
extend ActiveSupport::Concern
included do
- has_paper_trail
- belongs_to :organisation
+ after_initialize :init_dates
- validates_presence_of :name, :short_name, :organisation
- validates_uniqueness_of :short_name
- after_initialize :init_dates_and_date_ranges
-
-
- def init_dates_and_date_ranges
+ def init_dates
self.dates ||= []
- self.date_ranges ||= []
- end
- ### Calendar::Period
- # Required by coocon
- def build_period
- Calendar::Period.new
- end
-
- def periods
- @periods ||= init_periods
- end
-
- def init_periods
- (date_ranges || [])
- .each_with_index
- .map( &Calendar::Period.method(:from_range) )
- end
- private :init_periods
-
- validate :validate_periods
-
- def validate_periods
- periods_are_valid = periods.all?(&:valid?)
-
- periods.each do |period|
- if period.intersect?(periods)
- period.errors.add(:base, I18n.t('calendars.errors.overlapped_periods'))
- periods_are_valid = false
- end
- end
-
- unless periods_are_valid
- errors.add(:periods, :invalid)
- end
end
- def flatten_date_array attributes, key
- date_int = %w(1 2 3).map {|e| attributes["#{key}(#{e}i)"].to_i }
- Date.new(*date_int)
- end
-
- def periods_attributes=(attributes = {})
- @periods = []
- attributes.each do |index, period_attribute|
- # Convert date_select to date
- ['begin', 'end'].map do |attr|
- period_attribute[attr] = flatten_date_array(period_attribute, attr)
- end
- period = Calendar::Period.new(period_attribute.merge(id: index))
- @periods << period unless period.marked_for_destruction?
- end
-
- date_ranges_will_change!
- end
-
- before_validation :fill_date_ranges
-
- def fill_date_ranges
- if @periods
- self.date_ranges = @periods.map(&:range).compact.sort_by(&:begin)
- end
- end
-
- after_save :clear_periods
-
- def clear_periods
- @periods = nil
- end
-
- private :clear_periods
-
### Calendar::DateValue
-
# Required by coocon
def build_date_value
Calendar::DateValue.new
@@ -153,4 +77,4 @@ module CalendarSupport
private :clear_date_values
end
-end
+end \ No newline at end of file
diff --git a/app/models/concerns/period_support.rb b/app/models/concerns/period_support.rb
new file mode 100644
index 000000000..f512c4e89
--- /dev/null
+++ b/app/models/concerns/period_support.rb
@@ -0,0 +1,80 @@
+module PeriodSupport
+ extend ActiveSupport::Concern
+
+ included do
+ after_initialize :init_date_ranges
+
+ def init_date_ranges
+ self.date_ranges ||= []
+ end
+
+ ### Calendar::Period
+ # Required by coocon
+ def build_period
+ Calendar::Period.new
+ end
+
+ def periods
+ @periods ||= init_periods
+ end
+
+ def init_periods
+ (date_ranges || [])
+ .each_with_index
+ .map( &Calendar::Period.method(:from_range) )
+ end
+ private :init_periods
+
+ validate :validate_periods
+
+ def validate_periods
+ periods_are_valid = periods.all?(&:valid?)
+
+ periods.each do |period|
+ if period.intersect?(periods)
+ period.errors.add(:base, I18n.t('calendars.errors.overlapped_periods'))
+ periods_are_valid = false
+ end
+ end
+
+ unless periods_are_valid
+ errors.add(:periods, :invalid)
+ end
+ end
+
+ def flatten_date_array attributes, key
+ date_int = %w(1 2 3).map {|e| attributes["#{key}(#{e}i)"].to_i }
+ Date.new(*date_int)
+ end
+
+ def periods_attributes=(attributes = {})
+ @periods = []
+ attributes.each do |index, period_attribute|
+ # Convert date_select to date
+ ['begin', 'end'].map do |attr|
+ period_attribute[attr] = flatten_date_array(period_attribute, attr)
+ end
+ period = Calendar::Period.new(period_attribute.merge(id: index))
+ @periods << period unless period.marked_for_destruction?
+ end
+
+ date_ranges_will_change!
+ end
+
+ before_validation :fill_date_ranges
+
+ def fill_date_ranges
+ if @periods
+ self.date_ranges = @periods.map(&:range).compact.sort_by(&:begin)
+ end
+ end
+
+ after_save :clear_periods
+
+ def clear_periods
+ @periods = nil
+ end
+
+ private :clear_periods
+ end
+end \ No newline at end of file
diff --git a/app/models/referential.rb b/app/models/referential.rb
index 851a33653..122af65a1 100644
--- a/app/models/referential.rb
+++ b/app/models/referential.rb
@@ -128,6 +128,10 @@ class Referential < ActiveRecord::Base
Chouette::RoutingConstraintZone.all
end
+ def purchase_windows
+ Chouette::PurchaseWindow.all
+ end
+
before_validation :define_default_attributes
def define_default_attributes
diff --git a/app/policies/business_calendar_policy.rb b/app/policies/business_calendar_policy.rb
deleted file mode 100644
index 6be40f20f..000000000
--- a/app/policies/business_calendar_policy.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-class BusinessCalendarPolicy < ApplicationPolicy
- class Scope < Scope
- def resolve
- scope
- end
- end
-
- def create?
- user.has_permission?('business_calendars.create')
- end
-
- def destroy?
- organisation_match? && user.has_permission?('business_calendars.destroy')
- end
-
- def update?
- organisation_match? && user.has_permission?('business_calendars.update')
- end
-
-end \ No newline at end of file
diff --git a/app/policies/purchase_window_policy.rb b/app/policies/purchase_window_policy.rb
new file mode 100644
index 000000000..75143a8bd
--- /dev/null
+++ b/app/policies/purchase_window_policy.rb
@@ -0,0 +1,20 @@
+class PurchaseWindowPolicy < ApplicationPolicy
+ class Scope < Scope
+ def resolve
+ scope
+ end
+ end
+
+ def create?
+ !archived? && organisation_match? && user.has_permission?('purchase_windows.create')
+ end
+
+ def update?
+ !archived? && organisation_match? && user.has_permission?('purchase_windows.update')
+ end
+
+ def destroy?
+ !archived? && organisation_match? && user.has_permission?('purchase_windows.destroy')
+ end
+
+end \ No newline at end of file
diff --git a/app/views/business_calendars/_filters.html.slim b/app/views/business_calendars/_filters.html.slim
deleted file mode 100644
index 7f1783af2..000000000
--- a/app/views/business_calendars/_filters.html.slim
+++ /dev/null
@@ -1,17 +0,0 @@
-= search_form_for @q, url: business_calendars_path, builder: SimpleForm::FormBuilder, html: { method: :get, class: 'form form-filter' } do |f|
- .ffg-row
- .input-group.search_bar
- = f.search_field :name_cont, class: 'form-control', placeholder: 'Indiquez un nom de calendrier commercial...'
- span.input-group-btn
- button.btn.btn-default#search_btn type='submit'
- span.fa.fa-search
-
- .ffg-row
- .form-group
- = f.label BusinessCalendar.human_attribute_name(:date), class: 'control-label'
- = f.input :contains_date, as: :date, label: false, wrapper_html: { class: 'date smart_date' }, class: 'form-control', include_blank: true
-
-
- .actions
- = link_to 'Effacer', business_calendars_path, class: 'btn btn-link'
- = f.submit 'Filtrer', id: 'calendar_filter_btn', class: 'btn btn-default'
diff --git a/app/views/business_calendars/_form.html.slim b/app/views/business_calendars/_form.html.slim
deleted file mode 100644
index 0fd504e51..000000000
--- a/app/views/business_calendars/_form.html.slim
+++ /dev/null
@@ -1,49 +0,0 @@
-= simple_form_for @business_calendar, html: { class: 'form-horizontal', id: 'business_calendar_form' }, wrapper: :horizontal_form do |f|
- .row
- .col-lg-12
- = f.input :name
- = f.input :short_name
- = f.input :color, as: :select, collection: BusinessCalendar.color.values, label_method: lambda { |c| color_diplsay(c) }
-
- .separator
-
- .row
- .col-lg-12
- .subform
- .nested-head
- .wrapper
- div
- .form-group
- label.control-label
- = Calendar.human_attribute_name(:date)
- div
-
- = f.simple_fields_for :date_values do |date_value|
- = render 'date_value_fields', f: date_value
-
- .links.nested-linker
- = link_to_add_association t('simple_form.labels.business_calendar.add_a_date'), f, :date_values, class: 'btn btn-outline-primary'
-
- .separator
-
- .row
- .col-lg-12
- .subform
- .nested-head
- .wrapper
- div
- .form-group
- label.control-label
- = t('simple_form.labels.business_calendar.ranges.begin')
- div
- .form-group
- label.control-label
- = t('simple_form.labels.business_calendar.ranges.end')
- div
-
- = f.simple_fields_for :periods do |period|
- = render 'period_fields', f: period
- .links.nested-linker
- = link_to_add_association t('simple_form.labels.business_calendar.add_a_date_range'), f, :periods, class: 'btn btn-outline-primary'
-
- = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'business_calendar_form'
diff --git a/app/views/business_calendars/index.html.slim b/app/views/business_calendars/index.html.slim
deleted file mode 100644
index 4ee1d6854..000000000
--- a/app/views/business_calendars/index.html.slim
+++ /dev/null
@@ -1,48 +0,0 @@
-- breadcrumb :business_calendars
-- content_for :page_header_actions do
- - if policy(BusinessCalendar).create?
- = link_to(t('actions.add'), new_business_calendar_path, class: 'btn btn-default')
-
-.page_content
- .container-fluid
- - if params[:q].present? or @business_calendars.any?
- .row
- .col-lg-12
- = render 'filters'
-
- - if @business_calendars.any?
- .row
- .col-lg-12
- = table_builder_2 @business_calendars,
- [ \
- TableBuilderHelper::Column.new( \
- key: :name, \
- attribute: 'name', \
- link_to: lambda do |business_calendar| \
- business_calendar_path(business_calendar) \
- end \
- ), \
- TableBuilderHelper::Column.new( \
- key: :color, \
- attribute: Proc.new { |tt| tt.color ? content_tag(:span, '', class: 'fa fa-circle', style: "color:#{tt.color}") : '-' }\
- ), \
- TableBuilderHelper::Column.new( \
- key: :short_name, \
- attribute: 'short_name' \
- ), \
- TableBuilderHelper::Column.new( \
- key: :organisation, \
- attribute: Proc.new { |c| c.organisation.name } \
- ), \
- ],
- #links: [:show, :edit],
- cls: 'table has-filter'
-
- = new_pagination @business_calendars, 'pull-right'
-
- - unless @business_calendars.any?
- .row.mt-xs
- .col-lg-12
- = replacement_msg t('calendars.search_no_results')
-
-= javascript_pack_tag 'date_filters'
diff --git a/app/views/business_calendars/_date_value_fields.html.slim b/app/views/purchase_windows/_date_value_fields.html.slim
index 7bde06a94..7bde06a94 100644
--- a/app/views/business_calendars/_date_value_fields.html.slim
+++ b/app/views/purchase_windows/_date_value_fields.html.slim
diff --git a/app/views/purchase_windows/_filters.html.slim b/app/views/purchase_windows/_filters.html.slim
new file mode 100644
index 000000000..e086af4b5
--- /dev/null
+++ b/app/views/purchase_windows/_filters.html.slim
@@ -0,0 +1,18 @@
+= search_form_for @q, url: referential_purchase_windows_path, builder: SimpleForm::FormBuilder, html: { method: :get, class: 'form form-filter' } do |f|
+ .ffg-row
+ .input-group.search_bar
+ = f.search_field :name_cont, class: 'form-control', placeholder: 'Indiquez un nom de calendrier commercial...'
+ span.input-group-btn
+ button.btn.btn-default#search_btn type='submit'
+ span.fa.fa-search
+
+ .form-group.togglable
+ = f.label Chouette::PurchaseWindow.human_attribute_name(:bounding_dates), required: false, class: 'control-label'
+ .filter_menu
+ = f.simple_fields_for :bounding_dates do |p|
+ = p.input :start_date, as: :date, label: t('simple_form.from'), wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @begin_range, include_blank: @begin_range ? false : true
+ = p.input :end_date, as: :date, label: t('simple_form.to'), wrapper_html: { class: 'date smart_date filter_menu-item' }, default: @end_range, include_blank: @end_range ? false : true
+
+ .actions
+ = link_to 'Effacer', referential_purchase_windows_path, class: 'btn btn-link'
+ = f.submit 'Filtrer', id: 'purchase_window_filter_btn', class: 'btn btn-default'
diff --git a/app/views/purchase_windows/_form.html.slim b/app/views/purchase_windows/_form.html.slim
new file mode 100644
index 000000000..8f3ba769d
--- /dev/null
+++ b/app/views/purchase_windows/_form.html.slim
@@ -0,0 +1,29 @@
+= simple_form_for [@referential, @purchase_window], html: { class: 'form-horizontal', id: 'purchase_window_form' }, wrapper: :horizontal_form do |f|
+ .row
+ .col-lg-12
+ = f.input :name
+ = f.input :color, as: :select, boolean_style: :inline, collection: Chouette::PurchaseWindow.color.values, input_html: {class: 'color_selector'}
+
+ .separator
+
+ .row
+ .col-lg-12
+ .subform
+ .nested-head
+ .wrapper
+ div
+ .form-group
+ label.control-label
+ = t('simple_form.labels.purchase_window.ranges.begin')
+ div
+ .form-group
+ label.control-label
+ = t('simple_form.labels.purchase_window.ranges.end')
+ div
+
+ = f.simple_fields_for :periods do |period|
+ = render 'period_fields', f: period
+ .links.nested-linker
+ = link_to_add_association t('simple_form.labels.purchase_window.add_a_date_range'), f, :periods, class: 'btn btn-outline-primary'
+
+ = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'purchase_window_form'
diff --git a/app/views/business_calendars/_period_fields.html.slim b/app/views/purchase_windows/_period_fields.html.slim
index 95e204554..95e204554 100644
--- a/app/views/business_calendars/_period_fields.html.slim
+++ b/app/views/purchase_windows/_period_fields.html.slim
diff --git a/app/views/purchase_windows/index.html.slim b/app/views/purchase_windows/index.html.slim
new file mode 100644
index 000000000..38954b5dc
--- /dev/null
+++ b/app/views/purchase_windows/index.html.slim
@@ -0,0 +1,44 @@
+- breadcrumb :purchase_windows, @referential
+- content_for :page_header_actions do
+ - if policy(Chouette::PurchaseWindow).create?
+ = link_to(t('actions.add'), new_referential_purchase_window_path(@referential), class: 'btn btn-default')
+
+.page_content
+ .container-fluid
+ - if params[:q].present? or @purchase_windows.any?
+ .row
+ .col-lg-12
+ = render 'filters'
+
+ - if @purchase_windows.any?
+ .row
+ .col-lg-12
+ = table_builder_2 @purchase_windows,
+ [ \
+ TableBuilderHelper::Column.new( \
+ key: :name, \
+ attribute: 'name', \
+ link_to: lambda do |purchase_window| \
+ referential_purchase_window_path(purchase_window.referential, purchase_window) \
+ end \
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :color, \
+ attribute: Proc.new { |tt| tt.color ? content_tag(:span, '', class: 'fa fa-circle', style: "color:#{tt.color}") : '-' }\
+ ), \
+ TableBuilderHelper::Column.new( \
+ key: :bounding_dates, \
+ attribute: Proc.new {|w| w.bounding_dates.nil? ? '-' : t('validity_range', debut: l(w.bounding_dates.begin, format: :short), end: l(w.bounding_dates.end, format: :short))} \
+ ) \
+ ],
+ links: [:show],
+ cls: 'table has-filter'
+
+ = new_pagination @purchase_windows, 'pull-right'
+
+ - unless @purchase_windows.any?
+ .row.mt-xs
+ .col-lg-12
+ = replacement_msg t('purchase_windows.search_no_results')
+
+= javascript_pack_tag 'date_filters'
diff --git a/app/views/business_calendars/new.html.slim b/app/views/purchase_windows/new.html.slim
index ee44609ba..402084167 100644
--- a/app/views/business_calendars/new.html.slim
+++ b/app/views/purchase_windows/new.html.slim
@@ -1,4 +1,4 @@
-- breadcrumb :business_calendars
+- breadcrumb :purchase_windows, @referential
.page_content
.container-fluid
.row
diff --git a/app/views/purchase_windows/show.html.slim b/app/views/purchase_windows/show.html.slim
new file mode 100644
index 000000000..c039257f9
--- /dev/null
+++ b/app/views/purchase_windows/show.html.slim
@@ -0,0 +1,20 @@
+- breadcrumb :purchase_window, @purchase_window, @referential
+- page_header_content_for @purchase_window
+- content_for :page_header_content do
+ .row.mb-sm
+ .col-lg-12.text-right
+ - @purchase_window.action_links.each do |link|
+ = link_to link.href,
+ method: link.method,
+ data: link.data,
+ class: 'btn btn-primary' do
+ = link.content
+
+.page_content
+ .container-fluid
+ .row
+ .col-lg-6.col-md-6.col-sm-12.col-xs-12
+ = definition_list t('metadatas'),
+ { Chouette::PurchaseWindow.human_attribute_name(:name) => @purchase_window.try(:name),
+ 'Organisation' => @purchase_window.referential.organisation.name,
+ Chouette::PurchaseWindow.human_attribute_name(:date_ranges) => @purchase_window.periods.map{|d| t('validity_range', debut: l(d.begin, format: :short), end: l(d.end, format: :short))}.join('<br>').html_safe }
diff --git a/config/breadcrumbs.rb b/config/breadcrumbs.rb
index 0bca4a0be..03a98a513 100644
--- a/config/breadcrumbs.rb
+++ b/config/breadcrumbs.rb
@@ -162,13 +162,14 @@ crumb :line do |line|
parent :lines, line.line_referential
end
-crumb :business_calendars do
- link I18n.t('business_calendars.index.title'), business_calendars_path
+crumb :purchase_windows do |referential|
+ link I18n.t('purchase_windows.index.title'), referential_purchase_windows_path(referential)
+ parent :referential, referential
end
-crumb :business_calendar do |business_calendar|
- link breadcrumb_name(business_calendar), business_calendar_path(business_calendar)
- parent :business_calendars
+crumb :purchase_window do |purchase_window, referential|
+ link breadcrumb_name(purchase_window), referential_purchase_window_path(referential, purchase_window)
+ parent :purchase_windows, referential
end
crumb :calendars do
diff --git a/config/locales/business_calendars.en.yml b/config/locales/purchase_windows.en.yml
index 494136e1d..eddc0de35 100644
--- a/config/locales/business_calendars.en.yml
+++ b/config/locales/purchase_windows.en.yml
@@ -1,6 +1,6 @@
en:
- business_calendars:
- search_no_results: 'No business calendar matching your query'
+ purchase_windows:
+ search_no_results: 'No purchase window matching your query'
days:
monday: M
tuesday: Tu
@@ -23,31 +23,31 @@ en:
11: November
12: December
actions:
- new: Add a new business calendar
- edit: Edit this business calendar
- destroy: Remove this business calendar
- destroy_confirm: Are you sure you want destroy this business calendar?
+ new: Add a new purchase window
+ edit: Edit this purchase window
+ destroy: Remove this purchase window
+ destroy_confirm: Are you sure you want destroy this purchase window?
errors:
overlapped_periods: Another period is overlapped with this period
short_period: A period needs to last at least two days
index:
- title: Business calendars
+ title: purchase windows
all: All
shared: Shared
not_shared: Not shared
- search_no_results: No business calendar matching your query
+ search_no_results: No purchase window matching your query
date: Date
create:
- title: Add a new business calendar
+ title: Add a new purchase window
new:
- title: Add a new business calendar
+ title: Add a new purchase window
edit:
- title: Update business calendar %{name}
+ title: Update purchase window %{name}
show:
- title: Business calendar %{name}
+ title: purchase window %{name}
simple_form:
labels:
- business_calendar:
+ purchase_windows:
date_value: Date
add_a_date: Add a date
add_a_date_range: Add a date range
@@ -56,19 +56,18 @@ en:
end: End
activerecord:
models:
- one: business calendar
- other: business calendars
+ one: purchase window
+ other: purchase windows
attributes:
- business_calendar:
+ purchase_windows:
name: Name
- short_name: Short name
date_ranges: Date ranges
- dates: Dates
- organisation: Organisation
+ referential: Referential
color: Color
+ bounding_dates: Bounding Dates
errors:
models:
- business_calendar:
+ purchase_windows:
attributes:
dates:
date_in_date_ranges: A date can not be in Dates and in Date ranges.
diff --git a/config/locales/business_calendars.fr.yml b/config/locales/purchase_windows.fr.yml
index 3ec08ebbd..9e00b0b9c 100644
--- a/config/locales/business_calendars.fr.yml
+++ b/config/locales/purchase_windows.fr.yml
@@ -1,5 +1,5 @@
fr:
- business_calendars:
+ purchase_windows:
search_no_results: 'Aucun calendrier commercial ne correspond à votre recherche'
days:
monday: L
@@ -59,16 +59,16 @@ fr:
one: "calendrier commercial"
other: "calendriers commerciaux"
attributes:
- business_calendar:
+ purchase_window:
name: Nom
short_name: Nom court
date_ranges: Intervalles de dates
- dates: Dates
- organisation: Organisation
+ referential: Jeu de données
color: Couleur
+ bounding_dates: Période englobante
errors:
models:
- business_calendar:
+ purchase_window:
attributes:
dates:
date_in_date_ranges: Une même date ne peut pas être incluse à la fois dans la liste et dans les intervalles de dates.
diff --git a/config/routes.rb b/config/routes.rb
index b4191da0f..c231e0bf7 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -99,8 +99,6 @@ ChouetteIhm::Application.routes.draw do
resources :networks
end
- resources :business_calendars
-
resources :calendars do
get :autocomplete, on: :collection, controller: 'autocomplete_calendars'
end
@@ -173,6 +171,8 @@ ChouetteIhm::Application.routes.draw do
resources :companies, controller: "referential_companies"
+ resources :purchase_windows
+
resources :time_tables do
collection do
get :tags
diff --git a/db/migrate/20171215144543_rename_business_calendars_to_purchase_windows.rb b/db/migrate/20171215144543_rename_business_calendars_to_purchase_windows.rb
new file mode 100644
index 000000000..d4467d6a7
--- /dev/null
+++ b/db/migrate/20171215144543_rename_business_calendars_to_purchase_windows.rb
@@ -0,0 +1,5 @@
+class RenameBusinessCalendarsToPurchaseWindows < ActiveRecord::Migration
+ def change
+ rename_table :business_calendars, :purchase_windows
+ end
+end
diff --git a/db/migrate/20171215145023_update_purchase_windows_attributes.rb b/db/migrate/20171215145023_update_purchase_windows_attributes.rb
new file mode 100644
index 000000000..48dfb15bc
--- /dev/null
+++ b/db/migrate/20171215145023_update_purchase_windows_attributes.rb
@@ -0,0 +1,13 @@
+class UpdatePurchaseWindowsAttributes < ActiveRecord::Migration
+ def change
+ add_column :purchase_windows, :objectid, :string
+ add_column :purchase_windows, :checksum, :string
+ add_column :purchase_windows, :checksum_source, :text
+
+ remove_column :purchase_windows, :short_name, :string
+ remove_column :purchase_windows, :dates, :date
+ remove_column :purchase_windows, :organisation_id, :integer
+
+ add_reference :purchase_windows, :referential, type: :bigint, index: true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index faf7f3a1e..ef1e404b4 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -81,19 +81,6 @@ ActiveRecord::Schema.define(version: 20171214130636) do
add_index "api_keys", ["organisation_id"], name: "index_api_keys_on_organisation_id", using: :btree
- create_table "business_calendars", id: :bigserial, force: :cascade do |t|
- t.string "name"
- t.string "short_name"
- t.string "color"
- t.daterange "date_ranges", array: true
- t.date "dates", array: true
- t.integer "organisation_id"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- end
-
- add_index "business_calendars", ["organisation_id"], name: "index_business_calendars_on_organisation_id", using: :btree
-
create_table "calendars", id: :bigserial, force: :cascade do |t|
t.string "name"
t.string "short_name"
@@ -584,6 +571,20 @@ ActiveRecord::Schema.define(version: 20171214130636) do
add_index "pt_links", ["objectid"], name: "pt_links_objectid_key", unique: true, using: :btree
+ create_table "purchase_windows", id: :bigserial, force: :cascade do |t|
+ t.string "name"
+ t.string "color"
+ t.daterange "date_ranges", array: true
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.string "objectid"
+ t.string "checksum"
+ t.text "checksum_source"
+ t.integer "referential_id", limit: 8
+ end
+
+ add_index "purchase_windows", ["referential_id"], name: "index_purchase_windows_on_referential_id", using: :btree
+
create_table "referential_clonings", id: :bigserial, force: :cascade do |t|
t.string "status"
t.datetime "started_at"
diff --git a/lib/stif/permission_translator.rb b/lib/stif/permission_translator.rb
index b93396cc3..bb35c2784 100644
--- a/lib/stif/permission_translator.rb
+++ b/lib/stif/permission_translator.rb
@@ -18,7 +18,6 @@ module Stif
%w[
access_points
connection_links
- business_calendars
calendars
footnotes
imports
@@ -33,6 +32,7 @@ module Stif
compliance_control_sets
compliance_control_blocks
compliance_check_sets
+ purchase_windows
]
end
diff --git a/spec/factories/chouette_purchase_windows.rb b/spec/factories/chouette_purchase_windows.rb
new file mode 100644
index 000000000..4d29a8801
--- /dev/null
+++ b/spec/factories/chouette_purchase_windows.rb
@@ -0,0 +1,16 @@
+FactoryGirl.define do
+ factory :purchase_window, class: Chouette::PurchaseWindow do
+ sequence(:name) { |n| "Purchase Window #{n}" }
+ sequence(:objectid) { |n| "organisation:PurchaseWindow:#{n}:LOC" }
+ date_ranges { [generate(:periods)] }
+
+ association :referential
+
+ end
+
+ sequence :periods do |n|
+ date = Date.today + 2*n
+ date..(date+1)
+ end
+end
+
diff --git a/spec/models/business_calendar_spec.rb b/spec/models/business_calendar_spec.rb
deleted file mode 100644
index 29f67d49f..000000000
--- a/spec/models/business_calendar_spec.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-require 'rails_helper'
-
-RSpec.describe BusinessCalendar, type: :model do
- pending "add some examples to (or delete) #{__FILE__}"
-end
diff --git a/spec/models/chouette/purchase_window_spec.rb b/spec/models/chouette/purchase_window_spec.rb
new file mode 100644
index 000000000..702a44eeb
--- /dev/null
+++ b/spec/models/chouette/purchase_window_spec.rb
@@ -0,0 +1,27 @@
+RSpec.describe Chouette::PurchaseWindow, :type => :model do
+ let(:referential) {create(:referential)}
+ subject { create(:purchase_window, referential: referential) }
+
+ it { should belong_to(:referential) }
+ it { is_expected.to validate_presence_of(:name) }
+
+ describe 'validations' do
+ it 'validates and date_ranges do not overlap' do
+ expect(build(:purchase_window, referential: referential,date_ranges: [Date.today..Date.today + 10.day, Date.yesterday..Date.tomorrow])).to_not be_valid
+ # expect(build(periods: [Date.today..Date.today + 10.day, Date.yesterday..Date.tomorrow ])).to_not be_valid
+ end
+ end
+
+ describe 'before_validation' do
+ let(:purchase_window) { build(:purchase_window, referential: referential, date_ranges: []) }
+
+ it 'shoud fill date_ranges with date ranges' do
+ expected_range = Date.today..Date.tomorrow
+ purchase_window.date_ranges << expected_range
+ purchase_window.valid?
+
+ expect(purchase_window.date_ranges.map { |period| period.begin..period.end }).to eq([expected_range])
+ end
+ end
+
+end
diff --git a/spec/policies/purchase_window_policy_spec.rb b/spec/policies/purchase_window_policy_spec.rb
new file mode 100644
index 000000000..f078bf288
--- /dev/null
+++ b/spec/policies/purchase_window_policy_spec.rb
@@ -0,0 +1,15 @@
+RSpec.describe PurchaseWindowPolicy, type: :policy do
+
+ let( :record ){ build_stubbed :purchase_window }
+ before { stub_policy_scope(record) }
+
+ permissions :create? do
+ it_behaves_like 'permitted policy and same organisation', "purchase_windows.create", archived: true
+ end
+ permissions :destroy? do
+ it_behaves_like 'permitted policy and same organisation', "purchase_windows.destroy", archived: true
+ end
+ permissions :update? do
+ it_behaves_like 'permitted policy and same organisation', "purchase_windows.update", archived: true
+ end
+end
diff --git a/spec/support/permissions.rb b/spec/support/permissions.rb
index dde530871..fc378babc 100644
--- a/spec/support/permissions.rb
+++ b/spec/support/permissions.rb
@@ -29,6 +29,7 @@ module Support
compliance_control_sets
compliance_control_blocks
compliance_check_sets
+ purchase_windows
]
end
end