diff options
28 files changed, 265 insertions, 403 deletions
| diff --git a/app/assets/javascripts/stop_area_imports.js.coffee b/app/assets/javascripts/stop_area_imports.js.coffee deleted file mode 100644 index e69de29bb..000000000 --- a/app/assets/javascripts/stop_area_imports.js.coffee +++ /dev/null diff --git a/app/controllers/stop_area_exports_controller.rb b/app/controllers/stop_area_exports_controller.rb deleted file mode 100644 index e675a9826..000000000 --- a/app/controllers/stop_area_exports_controller.rb +++ /dev/null @@ -1,25 +0,0 @@ -class StopAreaExportsController < ChouetteController -  belongs_to :referential -     -  respond_to :csv, :only => [:index] -  respond_to :xls, :only => [:index]  - -  def index -    @column_names = column_names  -    index! do |format| -      format.csv { send_data StopAreaExport.new( {:column_names => column_names, :stop_areas => collection} ).to_csv  } -      format.xls -    end -  end -   -  protected  - -  def column_names -    ["id","name","longitude","latitude","area_type","parent_id", "comment","country_code","street_name","mobility_restricted_suitability","stairs_availability","lift_availability","int_user_needs"] -  end -   -  def collection -    @stop_areas ||= Chouette::StopArea.order(:country_code, :name) -  end -   -end diff --git a/app/controllers/stop_area_imports_controller.rb b/app/controllers/stop_area_imports_controller.rb deleted file mode 100644 index ff93dc40e..000000000 --- a/app/controllers/stop_area_imports_controller.rb +++ /dev/null @@ -1,24 +0,0 @@ -class StopAreaImportsController < ChouetteController -  belongs_to :referential -   -  actions :new, :create -  respond_to :html, :only => :new -   -  def new     -    @stop_area_import = StopAreaImport.new -    new! -  end - -  def create -    @stop_area_import = StopAreaImport.new(params[:stop_area_import]) -    if @stop_area_import.save -      redirect_to referential_stop_areas_path( @referential ), notice: I18n.t("stop_area_imports.new.success") -    else -      flash[:error] = I18n.t("stop_area_imports.errors.import_aborted") + "<br>" + @stop_area_import.errors.full_messages.join("<br>") -      render :new  -    end -  end - -  protected  - -end diff --git a/app/controllers/vehicle_journey_exports_controller.rb b/app/controllers/vehicle_journey_exports_controller.rb index ed1cd61a6..b786f00d3 100644 --- a/app/controllers/vehicle_journey_exports_controller.rb +++ b/app/controllers/vehicle_journey_exports_controller.rb @@ -6,21 +6,17 @@ class VehicleJourneyExportsController < ChouetteController    end    respond_to :csv, :only => [:index] -  respond_to :xls, :only => [:index] +  #respond_to :xls, :only => [:index]    def index -    @column_names = column_names       index! do |format|       -      format.csv { send_data VehicleJourneyExport.new(:route => route, :vehicle_journeys => vehicle_journeys, :column_names => column_names).to_csv } -      format.xls +      format.csv { send_data VehicleJourneyExport.new(:route => route, :vehicle_journeys => vehicle_journeys).to_csv(:col_sep => ";") , :filename => t("vehicle_journey_exports.new.basename")+"_#{route.id}.csv" } +      #format.xls      end    end    protected -  def column_names -    ["stop_point_id", "stop_area_name"] + vehicle_journeys.collect(&:objectid) -  end    alias_method :route, :parent diff --git a/app/controllers/vehicle_journey_imports_controller.rb b/app/controllers/vehicle_journey_imports_controller.rb index 8246541bc..136fac6d3 100644 --- a/app/controllers/vehicle_journey_imports_controller.rb +++ b/app/controllers/vehicle_journey_imports_controller.rb @@ -16,7 +16,12 @@ class VehicleJourneyImportsController < ChouetteController    def create      @vehicle_journey_import = VehicleJourneyImport.new( params[:vehicle_journey_import].present? ? params[:vehicle_journey_import].merge({:route => route}) : {:route => route} )      if @vehicle_journey_import.save -      redirect_to referential_line_route_path( @referential, @line, @route ), notice: I18n.t("vehicle_journey_imports.new.success") +      notice = I18n.t("vehicle_journey_imports.new.success") +  +      "<br>" + I18n.t("vehicle_journey_imports.success.created_jp_count",:count => @vehicle_journey_import.created_journey_pattern_count) + +      "<br>" + I18n.t("vehicle_journey_imports.success.created_vj_count",:count => @vehicle_journey_import.created_vehicle_journey_count) + +      "<br>" + I18n.t("vehicle_journey_imports.success.updated_vj_count",:count => @vehicle_journey_import.updated_vehicle_journey_count) +      +      "<br>" + I18n.t("vehicle_journey_imports.success.deleted_vj_count",:count => @vehicle_journey_import.deleted_vehicle_journey_count)        +      redirect_to referential_line_route_path( @referential, @line, @route ), notice: notice       else        flash[:error] = I18n.t("vehicle_journey_imports.errors.import_aborted") + "<br>" + @vehicle_journey_import.errors.full_messages.join("<br>")        render :new  diff --git a/app/models/stop_area_export.rb b/app/models/stop_area_export.rb deleted file mode 100644 index 1b9cc36a7..000000000 --- a/app/models/stop_area_export.rb +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -require "csv" - -class StopAreaExport    -  include ActiveModel::Validations -  include ActiveModel::Conversion -  extend  ActiveModel::Naming - -  attr_accessor :column_names, :stop_areas -   -  def initialize(attributes = {})     -    attributes.each { |name, value| send("#{name}=", value) } -  end -   -  def persisted? -    false -  end -   -  def to_csv(options = {})    -    CSV.generate(options) do |csv|       -      csv << column_names -      stop_areas.each do |stop_area| -        csv << stop_area.attributes.values_at(*column_names) -      end -    end -  end - -end diff --git a/app/models/stop_area_import.rb b/app/models/stop_area_import.rb deleted file mode 100644 index 87c72ae6c..000000000 --- a/app/models/stop_area_import.rb +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- - -class StopAreaImport    -  include ActiveModel::Validations -  include ActiveModel::Conversion -  extend  ActiveModel::Naming - -  attr_accessor :file -   -  validates_presence_of :file - -  def initialize(attributes = {})     -    attributes.each { |name, value| send("#{name}=", value) } if attributes -  end -   -  def persisted? -    false -  end -   -  def save -    begin -      Chouette::StopArea.transaction do -        if imported_stop_areas.map(&:valid?).all?  -          imported_stop_areas.each(&:save!) -          true -        else -          imported_stop_areas.each_with_index do |imported_stop_area, index| -            imported_stop_area.errors.full_messages.each do |message| -              errors.add :base, I18n.t("stop_area_imports.errors.invalid_stop_area", :column => index+2, :message => message) -            end -          end -          false -        end -      end -    rescue Exception => exception -      Rails.logger.error(exception.message) -      errors.add :base, I18n.t("stop_area_imports.errors.exception") -      false -    end -  end    -   -  def imported_stop_areas -    @imported_stop_areas ||= load_imported_stop_areas -  end   - -  def load_imported_stop_areas -    spreadsheet = open_spreadsheet(file) -    header = spreadsheet.row(1) -    (2..spreadsheet.last_row).map do |i| -      row = Hash[[header, spreadsheet.row(i)].transpose] -      stop_area = Chouette::StopArea.find_by_id(row["id"]) || Chouette::StopArea.new -       stop_area.attributes = row.to_hash.slice(*Chouette::StopArea.accessible_attributes) -      Rails.logger.info(stop_area.inspect) -      stop_area -    end -  end -   -  def open_spreadsheet(file) -    case File.extname(file.original_filename) -    when '.csv' then Roo::CSV.new(file.path) -    when '.xls' then Roo::Excel.new(file.path) -    when '.xlsx' then Roo::Excelx.new(file.path) -    else       -      raise "Unknown file type: #{file.original_filename}" -    end -  end -   -end diff --git a/app/models/vehicle_journey_export.rb b/app/models/vehicle_journey_export.rb index 7f5577e22..318e0ba30 100644 --- a/app/models/vehicle_journey_export.rb +++ b/app/models/vehicle_journey_export.rb @@ -6,7 +6,7 @@ class VehicleJourneyExport    include ActiveModel::Conversion    extend  ActiveModel::Naming -  attr_accessor :vehicle_journeys, :column_names, :route +  attr_accessor :vehicle_journeys, :route    def initialize(attributes = {})          attributes.each { |name, value| send("#{name}=", value) } @@ -16,17 +16,74 @@ class VehicleJourneyExport      false    end -  def vehicle_journey_at_stops_matrix -    (vehicle_journeys.collect{ |vj| vj.vehicle_journey_at_stops.collect(&:departure_time).collect{|time| time.strftime("%H:%M")} }).transpose +  def label(name) +    I18n.t "vehicle_journey_exports.label.#{name}" +  end + +  def column_names +    ["", label("vehicle_journey_id")] + vehicle_journeys.collect(&:objectid) +  end + +  # produce a map stop_id => departure time for a vehicle_journey +  def time_by_stops(vj) +    {}.tap do |hash| +       vj.vehicle_journey_at_stops.each do |vjas| +         hash[ "#{vjas.stop_point_id}"] = vjas.departure_time.strftime("%H:%M")  +      end +    end +  end + +  def time_tables (vj) +    (vj.time_tables.collect{ |t| t.id }) +  end + +  def time_tables_array +    (vehicle_journeys.collect{ |vj| time_tables(vj).to_s[1..-2] } ) +  end + +  def vehicle_journey_at_stops_array +    (vehicle_journeys.collect{ |vj| time_by_stops vj } ) +  end +   +  def boolean_code(b) +    b.nil? ? "" : label("b_"+b.to_s) +  end + +  def number_array +    (vehicle_journeys.collect{ |vj| vj.number ?  vj.number.to_s : "" } ) +  end + +  def flexible_service_array +    (vehicle_journeys.collect{ |vj| boolean_code vj.flexible_service  } ) +  end +   +  def mobility_restricted_suitability_array +    (vehicle_journeys.collect{ |vj| boolean_code vj.mobility_restricted_suitability  } ) +  end +   +  def empty_array +    (vehicle_journeys.collect{ |vj| "" } ) +  end + +  def times_of_stop(stop_id,vjas_array) +    a = [] +    vjas_array.each do |map| +      a << (map[stop_id.to_s].present? ? map[stop_id.to_s] : "") +    end +    a    end    def to_csv(options = {})      CSV.generate(options) do |csv|                    csv << column_names -      route.stop_points.each_with_index do |stop_point, index| -        puts vehicle_journey_at_stops_matrix[index].inspect -         -        times = vehicle_journey_at_stops_matrix[index].present? ? vehicle_journey_at_stops_matrix[index] : [] +      csv << ["", label("number")] + number_array +      csv << ["", label("mobility")] + mobility_restricted_suitability_array +      csv << ["", label("flexible_service")] + flexible_service_array +      csv << ["", label("time_table_ids")] + time_tables_array +      csv << [label("stop_id"), label("stop_name")] + empty_array +      vjas_array = vehicle_journey_at_stops_array +      route.stop_points.each_with_index do |stop_point, index|         +        times = times_of_stop(stop_point.id,vjas_array)          csv << [stop_point.id, stop_point.stop_area.name] + times        end      end diff --git a/app/models/vehicle_journey_import.rb b/app/models/vehicle_journey_import.rb index 15569c3d4..7891866ed 100644 --- a/app/models/vehicle_journey_import.rb +++ b/app/models/vehicle_journey_import.rb @@ -6,12 +6,19 @@ class VehicleJourneyImport    extend  ActiveModel::Naming    attr_accessor :file, :route +  attr_accessor :created_vehicle_journey_count,:updated_vehicle_journey_count,:deleted_vehicle_journey_count +  attr_accessor :created_journey_pattern_count,:error_count    validates_presence_of :file    validates_presence_of :route    def initialize(attributes = {})          attributes.each { |name, value| send("#{name}=", value) } if attributes +    self.created_vehicle_journey_count = 0 +    self.updated_vehicle_journey_count = 0 +    self.created_journey_pattern_count = 0 +    self.deleted_vehicle_journey_count = 0 +    self.error_count = 0    end    def persisted? @@ -27,14 +34,15 @@ class VehicleJourneyImport          else            imported_vehicle_journeys.each_with_index do |imported_vehicle_journey, index|              imported_vehicle_journey.errors.full_messages.each do |message| -              errors.add :base, I18n.t("vehicle_journey_imports.errors.invalid_vehicle_journey", :column => index, :message => message) +              errors.add :base, I18n.t("vehicle_journey_imports.errors.invalid_vehicle_journey", :column => index+1, :message => message)              end            end -          false +          raise          end        end      rescue Exception => exception        Rails.logger.error(exception.message) +      Rails.logger.error(exception.backtrace)        errors.add :base, I18n.t("vehicle_journey_imports.errors.exception")        false      end @@ -45,21 +53,57 @@ class VehicleJourneyImport    end    # Find journey pattern on stop points used in vehicle journey at stops -  def find_journey_pattern_schedule(hours_by_stop_point_ids) +  # if no stop_point used found, return nil to delete vehicle_journey if exists +  # if only 1 stop_point used found, raise exception to stop import +  def find_journey_pattern_schedule(column,hours_by_stop_point_ids)      stop_points_used = hours_by_stop_point_ids.reject{ |key,value| value == nil }.keys +    return nil if stop_points_used.empty? + +    if stop_points_used.length == 1 +      errors.add :base, I18n.t("vehicle_journey_imports.errors.one_stop_point_used", :column => column) +      raise  +    end +          journey_pattern_founded = route.journey_patterns.select{ |jp| jp.stop_points.collect(&:id) == stop_points_used }.first      # If no journey pattern founded, create a new one -    journey_pattern_founded ? journey_pattern_founded : route.journey_patterns.create(:stop_points => Chouette::StopPoint.find(stop_points_used) ) +    self.created_journey_pattern_count += 1  if journey_pattern_founded.nil? +    journey_pattern_founded ? journey_pattern_founded :  route.journey_patterns.create(:stop_points => Chouette::StopPoint.find(stop_points_used) ) +  end +   +  def as_integer(v) +    v.blank? ? nil : v.to_i +  end +   +  def as_boolean(v) +    v.blank? ? nil : (v[1..1].downcase != "n") +  end +   +  def update_time_tables(vj,tm_ids) +    vj.time_tables.clear +    return unless tm_ids.present? +    ids = tm_ids.split(",").map(&:to_i) +    vj.time_tables << Chouette::TimeTable.find(ids)    end    def load_imported_vehicle_journeys +          spreadsheet = open_spreadsheet(file) -    vehicle_journeys = [] +    vehicle_journeys = []      first_column = spreadsheet.column(1) -    stop_point_ids = first_column[1..spreadsheet.last_row].map(&:to_i) +     +    # fixed rows (first = 1) +    number_row = 2 +    mobility_row = 3 +    flexible_service_row = 4 +    time_tables_row = 5 + +    # rows in column (first = 0) +    first_stop_row_index = 6 +     +    stop_point_ids = first_column[first_stop_row_index..spreadsheet.last_row].map(&:to_i)      same_stop_points = route.stop_points.collect(&:id) == stop_point_ids      unless same_stop_points @@ -68,22 +112,52 @@ class VehicleJourneyImport      end          (3..spreadsheet.last_column).each do |i| -      vehicle_journey_at_stops = []        vehicle_journey_objectid = spreadsheet.column(i)[0] -      hours_by_stop_point_ids = Hash[[stop_point_ids, spreadsheet.column(i)[1..spreadsheet.last_row]].transpose] +      hours_by_stop_point_ids = Hash[[stop_point_ids, spreadsheet.column(i)[first_stop_row_index..spreadsheet.last_row]].transpose] +       +      journey_pattern = find_journey_pattern_schedule(i,hours_by_stop_point_ids) +       +      vehicle_journey = route.vehicle_journeys.where(:objectid => vehicle_journey_objectid, :route_id => route.id).first_or_initialize + +      if journey_pattern.nil? +        if vehicle_journey.id.present?  +          self.deleted_vehicle_journey_count += 1 +          vehicle_journey.delete +        end +        next +      end +      if vehicle_journey.id.present?  +        self.updated_vehicle_journey_count += 1 +      else +        self.created_vehicle_journey_count += 1 +      end +       +      # number +      vehicle_journey.number = as_integer(spreadsheet.row(number_row)[i-1]) +       +      # flexible_service +      vehicle_journey.flexible_service = as_boolean(spreadsheet.row(flexible_service_row)[i-1]) +       +      # mobility +      vehicle_journey.mobility_restricted_suitability = as_boolean(spreadsheet.row(mobility_row)[i-1]) +       +      # time_tables +      update_time_tables(vehicle_journey,spreadsheet.row(time_tables_row)[i-1]) -      journey_pattern = find_journey_pattern_schedule(hours_by_stop_point_ids) -      vehicle_journey = journey_pattern.vehicle_journeys.where(:objectid => vehicle_journey_objectid, :route_id => route.id, :journey_pattern_id => journey_pattern.id).first_or_initialize +      # journey_pattern +      vehicle_journey.journey_pattern = journey_pattern +      vehicle_journey.vehicle_journey_at_stops.clear        line = 0        hours_by_stop_point_ids.each_pair do |key, value|          line += 1          if value.present? # Create a vehicle journey at stop when time is present            begin  -            main_time = Time.parse(value) +            # force UTC to ignore timezone effects +            main_time = Time.parse(value+" UTC")              if main_time.present? -              vjas = { :stop_point_id => key, :vehicle_journey_id => vehicle_journey.id, :departure_time => main_time, :arrival_time => main_time } -              vehicle_journey_at_stops << vjas +              vjas = Chouette::VehicleJourneyAtStop.new(:stop_point_id => key, :vehicle_journey_id => vehicle_journey.id, :departure_time => main_time, :arrival_time => main_time ) +              vehicle_journey.vehicle_journey_at_stops << vjas              end            rescue Exception => exception              errors.add :base, I18n.t("vehicle_journey_imports.errors.invalid_vehicle_journey_at_stop", :column => i, :line => line, :time => value) @@ -91,7 +165,6 @@ class VehicleJourneyImport            end          end                 end -      vehicle_journey.vehicle_journey_at_stops_attributes = vehicle_journey_at_stops        vehicle_journeys << vehicle_journey      end @@ -100,7 +173,7 @@ class VehicleJourneyImport    def open_spreadsheet(file)      case File.extname(file.original_filename) -    when '.csv' then Roo::CSV.new(file.path) +    when '.csv' then Roo::CSV.new(file.path, csv_options: {col_sep: ";"})      when '.xls' then Roo::Excel.new(file.path)      when '.xlsx' then Roo::Excelx.new(file.path)      else diff --git a/app/views/stop_area_exports/index.xls.erb b/app/views/stop_area_exports/index.xls.erb deleted file mode 100644 index e48a97fe0..000000000 --- a/app/views/stop_area_exports/index.xls.erb +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0"?> -<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" -  xmlns:o="urn:schemas-microsoft-com:office:office" -  xmlns:x="urn:schemas-microsoft-com:office:excel" -  xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" -  xmlns:html="http://www.w3.org/TR/REC-html40"> -  <Worksheet ss:Name="Sheet1"> -    <Table> -      <Row> -        <% @column_names.each do |column_name|%> -          <Cell><Data ss:Type="String"><%= column_name %></Data></Cell> -        <% end %> -      </Row> -    <% @stop_areas.each do |stop_area| %> -      <Row> -        <Cell><Data ss:Type="Number"><%= stop_area.id %></Data></Cell> -        <Cell><Data ss:Type="String"><%= stop_area.name %></Data></Cell> -        <Cell><Data ss:Type="Number"><%= stop_area.longitude %></Data></Cell> -        <Cell><Data ss:Type="Number"><%= stop_area.latitude %></Data></Cell> -        <Cell><Data ss:Type="String"><%= stop_area.area_type %></Data></Cell> -        <Cell><Data ss:Type="Number"><%= stop_area.parent_id %></Data></Cell> -        <Cell><Data ss:Type="String"><%= stop_area.comment %></Data></Cell> -        <Cell><Data ss:Type="String"><%= stop_area.country_code %></Data></Cell> -        <Cell><Data ss:Type="String"><%= stop_area.street_name %></Data></Cell> -        <Cell><Data ss:Type="String"><%= stop_area.mobility_restricted_suitability %></Data></Cell> -        <Cell><Data ss:Type="String"><%= stop_area.stairs_availability %></Data></Cell> -        <Cell><Data ss:Type="String"><%= stop_area.lift_availability %></Data></Cell> -        <Cell><Data ss:Type="String"><%= stop_area.int_user_needs %></Data></Cell>         -      </Row> -    <% end %> -    </Table> -  </Worksheet> -</Workbook> diff --git a/app/views/stop_area_imports/new.html.erb b/app/views/stop_area_imports/new.html.erb deleted file mode 100644 index d94f1c08b..000000000 --- a/app/views/stop_area_imports/new.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -<%= title_tag t('stop_area_imports.new.title') %> - -<%= semantic_form_for [@referential, @stop_area_import] do |form| %> -  <br> -  <%= form.inputs do %>  -    <%= form.input :file, :as => :file,  :input_html => { :title => "#{t('.tooltip.file')}", :'data-placement' => "right", :'data-toggle' => "tooltip", :'data-trigger' =>"hover" } %> -  <% end %> -  <%= form.actions do %> -    <%= form.action :submit, :as => :button , :label => t( 'formtastic.import' ) %>  -    <%= form.action :cancel, :as => :link %> -  <% end %> -<% end %> diff --git a/app/views/stop_areas/index.html.erb b/app/views/stop_areas/index.html.erb index 3398b8ab7..915e4523a 100644 --- a/app/views/stop_areas/index.html.erb +++ b/app/views/stop_areas/index.html.erb @@ -33,18 +33,6 @@  <ul class="actions">    <li><%= link_to t('stop_areas.actions.new'), new_referential_stop_area_path(@referential), :class => "add" %></li>    <li><%= link_to t('stop_areas.actions.default_geometry'), default_geometry_referential_stop_areas_path(@referential), :method => :put, :class => "calculator_edit" %></li> -  <li> -    <%= link_to t('stop_area_imports.new.title'), new_referential_stop_area_import_path( @referential ), :class => "import" %> -  </li>  </ul> -  <div class="btn-group"> -    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> -       <%= t('stop_area_imports.new.export_stop_areas') %><span class="caret"></span> -    </button> -    <ul class="dropdown-menu" role="menu"> -      <li><%= link_to image_tag("icons/file_csv.png") + " Csv" , referential_stop_area_exports_path(@referential, :format => :csv) %></li> -      <li><%= link_to image_tag("icons/file_excel.png") + " Excel", referential_stop_area_exports_path(@referential, :format => :xls) %></li> -    </ul> -  </div>  <% end %> diff --git a/app/views/vehicle_journeys/index.html.erb b/app/views/vehicle_journeys/index.html.erb index 74cd73d29..de46788fa 100644 --- a/app/views/vehicle_journeys/index.html.erb +++ b/app/views/vehicle_journeys/index.html.erb @@ -56,16 +56,19 @@      <li><%= link_to t('vehicle_journeys.actions.new'), new_referential_line_route_vehicle_journey_path(@referential, @line, @route), :class => "add" %></li>      <li><%= link_to t('.timeless'), timeless_referential_line_route_vehicle_journeys_path(@referential, @line, @route), :class => "link" %></li>  	<li><%= link_to t('vehicle_journey_imports.new.title'), new_referential_line_route_vehicle_journey_import_path( @referential, @line, @route ), :class => "import" %></li> +	<li><%= link_to image_tag("icons/file_csv.png") + t('vehicle_journey_exports.new.title'), referential_line_route_vehicle_journey_exports_path(@referential, @line, @route, :format => :csv), :class => "with_fa" %></li>    </ul> +  <!--     <div class="btn-group">      <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> -       <%= t('vehicle_journey_imports.new.export_vehicle_journeys') %><span class="caret"></span> +       <%= t('vehicle_journey_exports.new.title') %><span class="caret"></span>      </button>      <ul class="dropdown-menu" role="menu">        <li><%= link_to image_tag("icons/file_csv.png") + " Csv" , referential_line_route_vehicle_journey_exports_path(@referential, @line, @route, :format => :csv) %></li>        <li><%= link_to image_tag("icons/file_excel.png") + " Excel", referential_line_route_vehicle_journey_exports_path(@referential, @line, @route, :format => :xls) %></li>      </ul>    </div> +  -->    <h4><%= t(".selection") %></h4>    <h5><%= Chouette::JourneyPattern.model_name.human.pluralize %></h5> diff --git a/app/views/vehicle_journeys/show.html.erb b/app/views/vehicle_journeys/show.html.erb index 1bd1c5ca7..c7ab1e073 100644 --- a/app/views/vehicle_journeys/show.html.erb +++ b/app/views/vehicle_journeys/show.html.erb @@ -115,4 +115,5 @@      <li><font color="#D98F3B"><i class="fa fa-cubes fa-fw"></i></font><%= link_to t('.translation_form'), new_referential_line_route_vehicle_journey_vehicle_translation_path(@referential, @line, @route, @vehicle_journey), {:remote => true, 'data-toggle' =>  "modal", 'data-target' => '#modal_translation', :class => "with_fa" } %></li>    <% end %>    </ul> +  <%= creation_tag(@vehicle_journey) %>  <% end %> diff --git a/config/locales/stop_area_imports.yml b/config/locales/stop_area_imports.yml deleted file mode 100644 index 94d09975e..000000000 --- a/config/locales/stop_area_imports.yml +++ /dev/null @@ -1,33 +0,0 @@ -en: -  stop_area_imports: -    new: -      title: "Import stop areas" -      export_stop_areas: "Export existing stop_areas" -      success: "Import is a success" -      tooltip: -        file: "Select a CSV or Excel file" -    errors: -      import_aborted: "Errors prohibited this import from completing: "     -      invalid_stop_area: "Error column %{column}, stop_area is invalid : %{message}" -      exception: "Invalid file, you must provide valid csv, xls or xlsx file" -  activemodel:         -    attributes: -      stop_area_import: -        file: "File"     -fr: -  stop_area_imports: -    new: -      title: "Import des arrêts" -      export_stop_areas: "Exporter les arrêts existants" -      success: "L'import des données est un succès" -      tooltip: -        file: "Sélectionner un fichier CSV ou Excel"   -    errors: -      import_aborted: "Des erreurs ont empéché le bon déroulement de l'import: "         -      invalid_stop_area: "Erreur colonne %{column}, l'arrêt est invalide : %{message}" -      exception: "Le fichier est invalide, vous devez fournir un fichier csv, xls ou xlsx valide" -  activemodel:         -    attributes: -      stop_area_import: -        file: "Fichier" -      
\ No newline at end of file diff --git a/config/locales/vehicle_journey_exports.yml b/config/locales/vehicle_journey_exports.yml new file mode 100644 index 000000000..17e0b66b6 --- /dev/null +++ b/config/locales/vehicle_journey_exports.yml @@ -0,0 +1,30 @@ +en: +  vehicle_journey_exports: +    new: +      title: "Export existing vehicle journey at stops" +      basename: "vehicle_journeys" +    label: +      vehicle_journey_id: "vj id" +      number: "number" +      time_table_ids: "timetables" +      flexible_service: "on demand (Y(es)|N(o)|empty for unknown)" +      mobility: "wheel_chairs (Y(es)|N(o)|empty for unknown)" +      stop_id: "stop id" +      stop_name: "stop name" +      b_true: "Yes" +      b_false: "No" +fr: +  vehicle_journey_exports: +    new: +      title: "Exporter les horaires existants" +      basename: "courses" +    label: +      vehicle_journey_id: "id course" +      number: "numéro" +      time_table_ids: "calendriers" +      flexible_service: "TAD (O(ui)|N(on)|vide si inconnu)" +      mobility: "PMR (O(ui)|N(on)|vide si inconnu)" +      stop_id: "id arrêt" +      stop_name: "nom arrêt" +      b_true: "Oui" +      b_false: "Non" diff --git a/config/locales/vehicle_journey_imports.yml b/config/locales/vehicle_journey_imports.yml index e3f3f6855..fd442d5eb 100644 --- a/config/locales/vehicle_journey_imports.yml +++ b/config/locales/vehicle_journey_imports.yml @@ -9,9 +9,15 @@ en:      errors:        import_aborted: "Errors prohibited this import from completing: "            not_same_stop_points: "Error column 1 : Not same stop points than in route %{route}" +      one_stop_point_used: "Error column %{column} : only one stop scheduled"        invalid_vehicle_journey_at_stop: "Error column %{column} line %{line} : vehicle journey at stop invalid %{time}"        invalid_vehicle_journey: "Error column %{column}, vehicle journey is invalid : %{message}"        exception: "Invalid file, you must provide valid csv, xls or xlsx file" +    success:  +      created_jp_count: "%{count} journey patterns created" +      created_vj_count: "%{count} vehicle journeys created" +      updated_vj_count: "%{count} vehicle journeys updated" +      deleted_vj_count: "%{count} vehicle journeys deleted"    activemodel:              attributes:        vehicle_journey_import: @@ -27,9 +33,15 @@ fr:      errors:        import_aborted: "Des erreurs ont empéché le bon déroulement de l'import: "                          not_same_stop_points: "Erreur colonne 1 : Pas les mêmes points d'arrêt que sur l'itinéraire %{route}" +      one_stop_point_used: "Erreur colonne %{column} : un seul arrêt desservi"        invalid_vehicle_journey_at_stop: "Erreur colonne %{column} ligne %{line} : horaire à l'arrêt invalide %{time}"        invalid_vehicle_journey: "Erreur colonne %{column}, la course est invalide : %{message}"        exception: "Le fichier est invalide, vous devez fournir un fichier csv, xls ou xlsx valide" +    success:  +      created_jp_count: "%{count} mission(s) ajoutée(s)" +      created_vj_count: "%{count} course(s) ajoutée(s)" +      updated_vj_count: "%{count} course(s) mise(s) à jour" +      deleted_vj_count: "%{count} course(s) supprimée(s)"    activemodel:              attributes:        vehicle_journey_import: diff --git a/config/routes.rb b/config/routes.rb index 86f59a516..442538868 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -37,8 +37,6 @@ ChouetteIhm::Application.routes.draw do    end    resources :referentials do -    resources :stop_area_imports -    resources :stop_area_exports      resources :api_keys      resources :rule_parameter_sets      resources :stop_point_areas diff --git a/spec/fixtures/stop_area_import_invalid.csv b/spec/fixtures/stop_area_import_invalid.csv deleted file mode 100644 index 379c33012..000000000 --- a/spec/fixtures/stop_area_import_invalid.csv +++ /dev/null @@ -1,7 +0,0 @@ -"id","name","longitude","latitude","area_type","parent_id","comment","country_code","street_name","mobility_restricted_suitability","stairs_availability","lift_availability","int_user_needs" -,"StopArea1","0.1","0.1",,,"Comment",,,,,, -,"StopArea2","0.2","0.2",,,"Comment",,,,,, -,"StopArea3","0.3","0.3",,,"Comment",,,,,, -,"StopArea4","0.4","0.4",,,"Comment",,,,,, -,"StopArea5","0.5","0.5",,,"Comment",,,,,, -,"StopArea6","0.6","0.6",,,"Comment",,,,,, diff --git a/spec/fixtures/stop_area_import_valid.csv b/spec/fixtures/stop_area_import_valid.csv deleted file mode 100644 index d3d2c6974..000000000 --- a/spec/fixtures/stop_area_import_valid.csv +++ /dev/null @@ -1,7 +0,0 @@ -"id","name","longitude","latitude","area_type","parent_id","comment","country_code","street_name","mobility_restricted_suitability","stairs_availability","lift_availability","int_user_needs" -,"StopArea1","0.1","0.1","Quay",,"Comment",,,,,, -,"StopArea2","0.2","0.2","Quay",,"Comment",,,,,, -,"StopArea3","0.3","0.3","Quay",,"Comment",,,,,, -,"StopArea4","0.4","0.4","Quay",,"Comment",,,,,, -,"StopArea5","0.5","0.5","Quay",,"Comment",,,,,, -,"StopArea6","0.6","0.6","Quay",,"Comment",,,,,, diff --git a/spec/fixtures/vehicle_journey_imports_valid.csv b/spec/fixtures/vehicle_journey_imports_valid.csv index b20d58ab5..15f66a26f 100644 --- a/spec/fixtures/vehicle_journey_imports_valid.csv +++ b/spec/fixtures/vehicle_journey_imports_valid.csv @@ -1,6 +1,11 @@ -"stop area id","stop area name","import:VehicleJourney:1","import:VehicleJourney:2","import:VehicleJourney:3","" -1,"Arrêt 1","9:00:00",,"11:10:00","12:10:00" -2,"Arrêt 2","9:05:00","10:05:00","11:15:00","12:15:00" -3,"Arrêt 3","9:10:00",,"11:20:00","12:20:00" -4,"Arrêt 4","9:15:00","10:20:00","11:25:00","12:25:00" -5,"Arrêt 5","9:20:00",,"11:30:00","12:30:00" +;id course;import:VehicleJourney:1;import:VehicleJourney:2;import:VehicleJourney:3; +;numéro;1;2;3;4 +;PMR (O(ui)|N(on)|vide si inconnu);Oui;;; +;TAD (O(ui)|N(on)|vide si inconnu);Oui;;; +;calendriers;;;; +id arrêt;nom arrêt;;;; +1;Arrêt 1;9:00:00;;11:10:00;12:10:00 +2;Arrêt 2;9:05:00;10:05:00;11:15:00;12:15:00 +3;Arrêt 3;9:10:00;;11:20:00;12:20:00 +4;Arrêt 4;9:15:00;10:20:00;11:25:00;12:25:00 +5;Arrêt 5;9:20:00;;11:30:00;12:30:00 diff --git a/spec/fixtures/vehicle_journey_imports_with_vj_invalid.csv b/spec/fixtures/vehicle_journey_imports_with_vj_invalid.csv index 1b7aeb731..6ed6d90b2 100644 --- a/spec/fixtures/vehicle_journey_imports_with_vj_invalid.csv +++ b/spec/fixtures/vehicle_journey_imports_with_vj_invalid.csv @@ -1,6 +1,11 @@ -"stop area id","stop area name",invalid vj,"import:VehicleJourney:2","import:VehicleJourney:3" -1,"Arrêt 1","9:00:00","10:05:00","11:10:00" -2,"Arrêt 2","11:05:00",,"11:15:00" -3,"Arrêt 3","11:10:00","10:20:00","11:20:00" -4,"Arrêt 4","11:15:00",,"11:25:00" -5,"Arrêt 5","9:20:00","10:30:00","11:30:00" +;id course;invalid vj;import:VehicleJourney:2;import:VehicleJourney:3 +;numéro;1;2;3 +;PMR (O(ui)|N(on)|vide si inconnu);Oui;; +;TAD (O(ui)|N(on)|vide si inconnu);Oui;; +;calendriers;;; +id arrêt;nom arrêt;;; +1;Arrêt 1;9:00:00;10:05:00;11:10:00 +2;Arrêt 2;11:05:00;;11:15:00 +3;Arrêt 3;11:10:00;10:20:00;11:20:00 +4;Arrêt 4;11:15:00;;11:25:00 +5;Arrêt 5;9:20:00;10:30:00;11:30:00 diff --git a/spec/fixtures/vehicle_journey_imports_with_vjas_bad_order.csv b/spec/fixtures/vehicle_journey_imports_with_vjas_bad_order.csv index 4096616ab..d4da585d0 100644 --- a/spec/fixtures/vehicle_journey_imports_with_vjas_bad_order.csv +++ b/spec/fixtures/vehicle_journey_imports_with_vjas_bad_order.csv @@ -1,6 +1,11 @@ -"stop area id","stop area name","import:VehicleJourney:1","import:VehicleJourney:2","" -1,"Arrêt 1","9:05:00","10:05:00","11:10:00" -2,"Arrêt 2","11:05:00",,"11:15:00" -3,"Arrêt 3","9:10:00","10:20:00","11:20:00" -4,"Arrêt 4","9:15:00","10:25:00","11:25:00" -5,"Arrêt 5","9:20:00","10:30:00","11:30:00" +;id course;import:VehicleJourney:1;import:VehicleJourney:2; +;numéro;1;2;3 +;PMR (O(ui)|N(on)|vide si inconnu);Oui;; +;TAD (O(ui)|N(on)|vide si inconnu);Oui;; +;calendriers;;; +id arrêt;nom arrêt;;; +1;Arrêt 1;9:05:00;10:05:00;11:10:00 +2;Arrêt 2;11:05:00;;11:15:00 +3;Arrêt 3;9:10:00;10:20:00;11:20:00 +4;Arrêt 4;9:15:00;10:25:00;11:25:00 +5;Arrêt 5;9:20:00;10:30:00;11:30:00 diff --git a/spec/fixtures/vehicle_journey_imports_with_vjas_invalid.csv b/spec/fixtures/vehicle_journey_imports_with_vjas_invalid.csv index c5e9e32b1..687f6b09a 100644 --- a/spec/fixtures/vehicle_journey_imports_with_vjas_invalid.csv +++ b/spec/fixtures/vehicle_journey_imports_with_vjas_invalid.csv @@ -1,6 +1,11 @@ -"stop area id","stop area name","import:VehicleJourney:1","import:VehicleJourney:2","" -1,"Arrêt 1",invalid time,"10:05:00","11:10:00" -2,"Arrêt 2","9:05:00",,"11:15:00" -3,"Arrêt 3","9:10:00","10:20:00","11:20:00" -4,"Arrêt 4","9:15:00",,"11:25:00" -5,"Arrêt 5","9:20:00","10:30:00","11:30:00" +;id course;import:VehicleJourney:1;import:VehicleJourney:2; +;numéro;1;2;3 +;PMR (O(ui)|N(on)|vide si inconnu);Oui;; +;TAD (O(ui)|N(on)|vide si inconnu);Oui;; +;calendriers;;;; +id arrêt;nom arrêt;;; +1;Arrêt 1;invalid time;10:05:00;11:10:00 +2;Arrêt 2;9:05:00;;11:15:00 +3;Arrêt 3;9:10:00;10:20:00;11:20:00 +4;Arrêt 4;9:15:00;;11:25:00 +5;Arrêt 5;9:20:00;10:30:00;11:30:00 diff --git a/spec/models/stop_area_import_spec.rb b/spec/models/stop_area_import_spec.rb deleted file mode 100644 index 07f3a111b..000000000 --- a/spec/models/stop_area_import_spec.rb +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -require 'spec_helper' - -describe StopAreaImport do - -   let(:valid_file) { -    csv_file = File.open(Rails.root.join("spec", "fixtures", "stop_area_import_valid.csv").to_s, "r") -    mock("CSV", :tempfile => csv_file, :original_filename => File.basename(csv_file), :path => File.path(csv_file) ) -  } - -  let(:invalid_file) { -    csv_file = File.open(Rails.root.join("spec", "fixtures", "stop_area_import_invalid.csv").to_s, "r") -    mock("CSV", :tempfile => csv_file, :original_filename => File.basename(csv_file), :path => File.path(csv_file) ) -  } -   -  subject { StopAreaImport.new(:file => valid_file) } - -  describe ".save" do - -    it "should validate presence of file" do -      expect(StopAreaImport.new.save).to be_false -    end -     -    it "should import stop areas and create the right number of objects" do -      expect(StopAreaImport.new(:file => valid_file).save).to be_true -      expect(Chouette::StopArea.all.size).to eq(6)      -    end - -    it "should not import vehicle_journeys and not create objects when vehicle journey at stops are not in ascendant order" do       -      expect(StopAreaImport.new(:file => invalid_file).save).to be_false -      expect(Chouette::StopArea.all.size).to eq(0) -    end    -     -  end - -  describe ".load_imported_stop_areas" do - -    # it "should return errors when stop_areas in file are invalid" do            -    #   stop_area_import = StopAreaImport.new(:referential => referential, :file => invalid_file) -    #   expect { stop_area_import.load_imported_stop_areas }.to raise_exception -    # end -   -    it "should load stop ateas" do -      expect(subject.load_imported_stop_areas.size).to eq(6) -      expect(subject.errors.messages).to eq({}) -    end -     -  end - -end diff --git a/spec/models/vehicle_journey_import_spec.rb b/spec/models/vehicle_journey_import_spec.rb index 07cd921bb..f6e82bccb 100644 --- a/spec/models/vehicle_journey_import_spec.rb +++ b/spec/models/vehicle_journey_import_spec.rb @@ -4,13 +4,13 @@ require 'spec_helper'  describe VehicleJourneyImport do    def update_csv_file_with_factory_data(filename) -    csv_file = CSV.open("/tmp/#{filename}", "wb") do |csv| +    csv_file = CSV.open("/tmp/#{filename}", "wb",{ :col_sep => ";"}) do |csv|        counter = 0 -      CSV.foreach( Rails.root.join("spec", "fixtures", "#{filename}").to_s ) do |row| -        if counter == 0 +      CSV.foreach( Rails.root.join("spec", "fixtures", "#{filename}").to_s , {:col_sep => ";"}) do |row| +        if counter < 6            csv << row          else -          csv << ( row[0] = route.stop_points[counter - 1].id; row)           +          csv << ( row[0] = route.stop_points[counter - 6].id; row)                    end          counter += 1        end @@ -93,14 +93,14 @@ describe VehicleJourneyImport do    describe ".find_journey_pattern_schedule" do         it "should return journey pattern with same stop points" do           -      expect(subject.find_journey_pattern_schedule( { stop_point0.id => "9:00", stop_point1.id => "9:05", stop_point2.id => "9:10", stop_point3.id => "9:15", stop_point4.id => "9:20"} )).to eq(journey_pattern) -      expect(subject.find_journey_pattern_schedule( { stop_point1.id => "9:00", stop_point3.id => "9:10" } )).to eq(other_journey_pattern) +      expect(subject.find_journey_pattern_schedule( 1, { stop_point0.id => "9:00", stop_point1.id => "9:05", stop_point2.id => "9:10", stop_point3.id => "9:15", stop_point4.id => "9:20"} )).to eq(journey_pattern) +      expect(subject.find_journey_pattern_schedule( 1, { stop_point1.id => "9:00", stop_point3.id => "9:10" } )).to eq(other_journey_pattern)      end      it "should return new journey_pattern if no journey pattern with same stop points is founded" do       -      expect(subject.find_journey_pattern_schedule( { stop_point0.id => "9:00", stop_point1.id => "9:05", stop_point2.id => nil, stop_point3.id => "9:15", stop_point4.id => "9:20"} )).to be_true -      expect(subject.find_journey_pattern_schedule( { stop_point0.id => "9:00", stop_point1.id => "9:05", stop_point2.id => nil, stop_point3.id => "9:15", stop_point4.id => "9:20"} ).id).not_to eq(journey_pattern.id) -      expect(subject.find_journey_pattern_schedule( { stop_point0.id => "9:00", stop_point1.id => "9:05", stop_point2.id => nil, stop_point3.id => "9:15", stop_point4.id => "9:20"} ).id).not_to eq(other_journey_pattern.id) +      expect(subject.find_journey_pattern_schedule( 1, { stop_point0.id => "9:00", stop_point1.id => "9:05", stop_point2.id => nil, stop_point3.id => "9:15", stop_point4.id => "9:20"} )).to be_true +      expect(subject.find_journey_pattern_schedule( 1, { stop_point0.id => "9:00", stop_point1.id => "9:05", stop_point2.id => nil, stop_point3.id => "9:15", stop_point4.id => "9:20"} ).id).not_to eq(journey_pattern.id) +      expect(subject.find_journey_pattern_schedule( 1, { stop_point0.id => "9:00", stop_point1.id => "9:05", stop_point2.id => nil, stop_point3.id => "9:15", stop_point4.id => "9:20"} ).id).not_to eq(other_journey_pattern.id)      end    end diff --git a/spec/requests/stop_area_imports_spec.rb b/spec/requests/stop_area_imports_spec.rb deleted file mode 100644 index c0da1edac..000000000 --- a/spec/requests/stop_area_imports_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -require 'spec_helper' - -describe "StopAreaImports" do -  login_user - -  let!(:line) { create :line } -  let!(:valid_file_path) { Rails.root + "spec/fixtures/stop_area_import_valid.csv" } -  let!(:invalid_file_path) { Rails.root + "spec/fixtures/stop_area_import_invalid.csv" } -   -  describe "new" do       -    it "should create stop areas and return to stop areas index page" do -      visit new_referential_stop_area_import_path(referential) -      attach_file('Fichier', valid_file_path) -      click_button "Lancer l'import" -      expect(page).to have_content(I18n.t("stop_area_imports.new.success")) -      expect(page).to have_content("StopArea1") -    end - -    it "should return error messages when file is invalid" do -      visit new_referential_stop_area_import_path(referential) -      attach_file('Fichier', invalid_file_path) -      click_button "Lancer l'import" -      expect(page).to have_content(I18n.t("stop_area_imports.errors.import_aborted")) -    end -     -    it "should return error message when file missing on upload" do -      visit new_referential_stop_area_import_path(referential) -      click_button "Lancer l'import" -      expect(page).to have_content(I18n.t("stop_area_imports.errors.import_aborted")) -    end     -  end -   -end diff --git a/spec/requests/vehicle_journey_imports_spec.rb b/spec/requests/vehicle_journey_imports_spec.rb index c7a772fd3..5197d4c70 100644 --- a/spec/requests/vehicle_journey_imports_spec.rb +++ b/spec/requests/vehicle_journey_imports_spec.rb @@ -17,13 +17,13 @@ describe "VehicleJourneyImports" do    }    def update_csv_file_with_factory_data(filename) -    csv_file = CSV.open("/tmp/#{filename}", "wb") do |csv| +    csv_file = CSV.open("/tmp/#{filename}", "wb",{ :col_sep => ";"}) do |csv|        counter = 0 -      CSV.foreach( Rails.root.join("spec", "fixtures", "#{filename}").to_s ) do |row| -        if counter == 0 +      CSV.foreach( Rails.root.join("spec", "fixtures", "#{filename}").to_s , {:col_sep => ";"}) do |row| +        if counter < 6            csv << row          else -          csv << ( row[0] = route.stop_points[counter - 1].id; row)           +          csv << ( row[0] = route.stop_points[counter - 6].id; row)                    end          counter += 1        end | 
