diff options
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 | 
