diff options
79 files changed, 1063 insertions, 594 deletions
| @@ -54,7 +54,7 @@ gem 'bootstrap-timepicker-rails'  # Format Output  gem 'json' -gem 'rubyzip', :require => 'zip/zip' +gem 'rubyzip', '~> 1.1.6'   gem 'roo'  # Controller diff --git a/Gemfile.lock b/Gemfile.lock index 8dafca210..5f2596da1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@  GIT    remote: https://github.com/afimb/ninoxe.git -  revision: 3727e7393fdece893e1baa49916be24140c766b9 +  revision: 139f461be9a23566d242495df14331ec06308ce1    branch: sismo    specs:      ninoxe (1.1.0) @@ -52,8 +52,8 @@ GEM      activesupport (3.2.18)        i18n (~> 0.6, >= 0.6.4)        multi_json (~> 1.0) -    acts-as-taggable-on (3.3.0) -      activerecord (>= 3, < 5) +    acts-as-taggable-on (3.4.1) +      activerecord (>= 3.2, < 5)      acts_as_list (0.1.6)      acts_as_tree-1.8 (1.1.0)        activerecord (>= 3.0.0) @@ -89,7 +89,7 @@ GEM        rack-test (>= 0.5.4)        selenium-webdriver (~> 2.0)        xpath (~> 0.1.4) -    childprocess (0.3.9) +    childprocess (0.5.3)        ffi (~> 1.0, >= 1.0.11)      choice (0.1.6)      cocoon (1.1.2) @@ -184,10 +184,10 @@ GEM        jquery-rails        jquery-ui-rails (= 4.0.3)        railties (>= 3.1.0) -    jruby-jars (1.6.7.2) +    jruby-jars (1.7.15)      jruby-openssl (0.7.7)        bouncy-castle-java (>= 1.5.0146.1) -    jruby-rack (1.1.9) +    jruby-rack (1.1.16)      jruby-rack-worker (0.4-java)        jruby-rack (>= 1.1.1)      json (1.8.1) @@ -302,17 +302,17 @@ GEM        rspec-mocks (~> 2.13.0)      ruby-graphviz (1.0.9)      ruby-ole (1.2.11.7) -    rubyzip (0.9.9) +    rubyzip (1.1.6)      sass (3.3.7)      sass-rails (3.2.6)        railties (~> 3.2.0)        sass (>= 3.1.10)        tilt (~> 1.3) -    selenium-webdriver (2.35.1) -      childprocess (>= 0.2.5) +    selenium-webdriver (2.43.0) +      childprocess (~> 0.5)        multi_json (~> 1.0) -      rubyzip (< 1.0.0) -      websocket (~> 1.0.4) +      rubyzip (~> 1.0) +      websocket (~> 1.0)      shoulda-matchers (1.2.0)        activesupport (>= 3.0.0)      simple_form (2.1.1) @@ -343,18 +343,18 @@ GEM        polyglot        polyglot (>= 0.3.1)      typeahead-rails (0.10.5) -    tzinfo (0.3.40) +    tzinfo (0.3.41)      uglifier (1.2.7)        execjs (>= 0.3.0)        multi_json (~> 1.3) -    warbler (1.3.6) -      jruby-jars (>= 1.4.0) +    warbler (1.4.4) +      jruby-jars (>= 1.5.6, < 2.0)        jruby-rack (>= 1.0.0) -      rake (>= 0.8.7) -      rubyzip (>= 0.9.4) +      rake (>= 0.9.6) +      rubyzip (>= 0.9, < 1.2)      warden (1.2.1)        rack (>= 1.0) -    websocket (1.0.7) +    websocket (1.2.1)      will_paginate (3.0.5)      will_paginate-bootstrap (1.0.0)        will_paginate (>= 3.0.3) @@ -422,7 +422,7 @@ DEPENDENCIES    remarkable_activerecord (~> 4.0.0.alpha4)    roo    rspec-rails (~> 2.0) -  rubyzip +  rubyzip (~> 1.1.6)    sass-rails (~> 3.2.3)    shoulda-matchers    simple_form @@ -57,15 +57,17 @@ sudo apt-get install make  Installation  ------------ +On debian, chouette can also be installed as package : see [debian packages](http://packages.chouette.cityway.fr/debian/chouette) +  Install chouette-gui-command to import, export and validate transport offer,  Assume Linux user is myuser and its group mygroup (that user is the one who starts Rails server)  ```sh  sudo mkdir -p /usr/local/opt/chouette-command/  sudo chown -R myuser:mygroup /usr/local/opt/chouette-command/  cd /usr/local/opt/chouette-command/ -wget http://maven.chouette.cityway.fr/fr/certu/chouette/chouette-gui-command/2.4.1/chouette-gui-command-2.4.1.zip -unzip chouette-gui-command-2.4.1.zip -cd chouette-cmd_2.4.1 +wget http://maven.chouette.cityway.fr/fr/certu/chouette/chouette-gui-command/2.5.0/chouette-gui-command-2.5.0.zip +unzip chouette-gui-command-2.5.0.zip +cd chouette-cmd_2.5.0  sudo chmod a+w .  ``` @@ -74,7 +76,7 @@ Install web application  Get git source code :  ```sh  cd -git clone -b V2_4 git://github.com/afimb/chouette2 +git clone -b V2_5 git://github.com/afimb/chouette2  cd chouette2  ```  Download gem librairies diff --git a/app/assets/images/export-pending.png b/app/assets/images/export-pending.pngBinary files differ index 7fc459926..d5af6a807 100644 --- a/app/assets/images/export-pending.png +++ b/app/assets/images/export-pending.png diff --git a/app/assets/images/export-processing.png b/app/assets/images/export-processing.pngBinary files differ new file mode 100644 index 000000000..7fc459926 --- /dev/null +++ b/app/assets/images/export-processing.png diff --git a/app/assets/images/file-validation-completed.png b/app/assets/images/file-validation-completed.pngBinary files differ deleted file mode 100644 index 242d68d3b..000000000 --- a/app/assets/images/file-validation-completed.png +++ /dev/null diff --git a/app/assets/images/file-validation-failed.png b/app/assets/images/file-validation-failed.pngBinary files differ deleted file mode 100644 index e50298a77..000000000 --- a/app/assets/images/file-validation-failed.png +++ /dev/null diff --git a/app/assets/images/file-validation-pending.png b/app/assets/images/file-validation-pending.pngBinary files differ deleted file mode 100644 index 2d19124c0..000000000 --- a/app/assets/images/file-validation-pending.png +++ /dev/null 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/access_links_controller.rb b/app/controllers/access_links_controller.rb index 8c6172a7c..4509de575 100644 --- a/app/controllers/access_links_controller.rb +++ b/app/controllers/access_links_controller.rb @@ -16,7 +16,15 @@ class AccessLinksController < ChouetteController    def show      @map = AccessLinkMap.new(resource).with_helpers(self) -    show! +    @access_point = Chouette::AccessPoint.find(params[:access_point_id]) +    @access_link = Chouette::AccessLink.find(params[:id]) +    @stop_area = @access_link.stop_area +    show! do +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +      add_breadcrumb @stop_area.name, referential_stop_area_path(@referential, @stop_area) +      add_breadcrumb @access_point.name, referential_stop_area_access_point_path(@referential, @stop_area,@access_point) +      add_breadcrumb Chouette::AccessLink.model_name.human(:count => 2), access_links_referential_stop_area_path(@referential, @stop_area) +    end    end    def new  @@ -34,7 +42,11 @@ class AccessLinksController < ChouetteController        data[:name] = name      end      @access_link = Chouette::AccessLink.new(data) -    new! +    new! do +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +      add_breadcrumb @stop_area.name, referential_stop_area_path(@referential, @stop_area) +      add_breadcrumb @access_point.name, referential_stop_area_access_point_path(@referential, @stop_area,@access_point) +    end    end    def create @@ -50,7 +62,12 @@ class AccessLinksController < ChouetteController      @access_link = Chouette::AccessLink.find(params[:id])      @stop_area = @access_link.stop_area      @orientation = @access_link.link_orientation_type -    edit! +    edit! do +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +      add_breadcrumb @stop_area.name, referential_stop_area_path(@referential, @stop_area) +      add_breadcrumb @access_point.name, referential_stop_area_access_point_path(@referential, @stop_area,@access_point) +      add_breadcrumb @access_link.name, referential_access_point_access_link_path(@referential, @access_point, @access_link) +    end    end    protected diff --git a/app/controllers/access_points_controller.rb b/app/controllers/access_points_controller.rb index cf7507100..0e06bee19 100644 --- a/app/controllers/access_points_controller.rb +++ b/app/controllers/access_points_controller.rb @@ -30,13 +30,26 @@ class AccessPointsController < ChouetteController          }        end +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +      add_breadcrumb @stop_area.name, referential_stop_area_path(@referential, @stop_area)      end    end +  def new +    new! do +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +      add_breadcrumb @stop_area.name, referential_stop_area_path(@referential, @stop_area) +    end +  end +    def edit      access_point.position ||= access_point.default_position      map.editable = true -    edit! +    edit! do +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +      add_breadcrumb @stop_area.name, referential_stop_area_path(@referential, @stop_area) +      add_breadcrumb @access_point.name, referential_stop_area_access_point_path(@referential, @stop_area,@access_point) +    end    end diff --git a/app/controllers/companies_controller.rb b/app/controllers/companies_controller.rb index 3b5631a8f..20f84e763 100644 --- a/app/controllers/companies_controller.rb +++ b/app/controllers/companies_controller.rb @@ -14,9 +14,30 @@ class CompaniesController < ChouetteController          if collection.out_of_bounds?            redirect_to params.merge(:page => 1)          end +      add_breadcrumb Referential.model_name.human(:count => 2), referentials_path() +      add_breadcrumb @referential.name, referential_path(@referential)        }      end           end +   +  def show +    show! do +      add_breadcrumb Referential.human_attribute_name("companies"), referential_companies_path(@referential) +    end +  end + +  def new +    new! do +      add_breadcrumb Referential.human_attribute_name("companies"), referential_companies_path(@referential) +    end +  end +   +  def edit +    edit! do +      add_breadcrumb Referential.human_attribute_name("companies"), referential_companies_path(@referential) +      add_breadcrumb @company.name, referential_line_path(@referential, @company) +    end +  end    protected    def collection     diff --git a/app/controllers/compliance_check_tasks_controller.rb b/app/controllers/compliance_check_tasks_controller.rb index 9acce4510..bf8a670a3 100644 --- a/app/controllers/compliance_check_tasks_controller.rb +++ b/app/controllers/compliance_check_tasks_controller.rb @@ -2,6 +2,17 @@ class ComplianceCheckTasksController < ChouetteController    respond_to :html, :js    belongs_to :referential +  def new +    new! do +      add_breadcrumb Referential.human_attribute_name("compliance_check_tasks"), referential_compliance_check_tasks_path(@referential) +    end +  end + +  def show +    show! do +      add_breadcrumb Referential.human_attribute_name("compliance_check_tasks"), referential_compliance_check_tasks_path(@referential) +    end +  end    def references      @references = referential.send(params[:type]).where("name ilike ?", "%#{params[:q]}%")      respond_to do |format| diff --git a/app/controllers/connection_links_controller.rb b/app/controllers/connection_links_controller.rb index 3c7dd3ab6..ca34aecdc 100644 --- a/app/controllers/connection_links_controller.rb +++ b/app/controllers/connection_links_controller.rb @@ -22,13 +22,31 @@ class ConnectionLinksController < ChouetteController    def show      @map = ConnectionLinkMap.new(resource).with_helpers(self) -    show! +    show! do +      add_breadcrumb Referential.human_attribute_name("connection_links"), referential_connection_links_path(@referential) +    end    end +  def new +    new! do +      add_breadcrumb Referential.human_attribute_name("connection_links"), referential_connection_links_path(@referential) +    end +  end +   +  def edit +    edit! do +      add_breadcrumb Referential.human_attribute_name("connection_links"), referential_connection_links_path(@referential) +      add_breadcrumb @connection_link.name, referential_connection_link_path(@referential, @connection_link) +    end +  end + +    def select_areas      @connection_link = connection_link      @departure = connection_link.departure      @arrival = connection_link.arrival +    add_breadcrumb Referential.human_attribute_name("connection_links"), referential_connection_links_path(@referential) +    add_breadcrumb @connection_link.name, referential_connection_link_path(@referential, @connection_link)    end    protected diff --git a/app/controllers/exports_controller.rb b/app/controllers/exports_controller.rb index ed2ecd329..d5723ff78 100644 --- a/app/controllers/exports_controller.rb +++ b/app/controllers/exports_controller.rb @@ -7,6 +7,7 @@ class ExportsController < ChouetteController    def new      new! do +      add_breadcrumb Referential.human_attribute_name("exports"), referential_exports_path(@referential)        available_exports      end    end @@ -19,6 +20,7 @@ class ExportsController < ChouetteController    end    def show +    add_breadcrumb Referential.human_attribute_name("exports"), referential_exports_path(@referential)      show! do |format|        format.zip { send_file @export.file, :type => :zip }      end diff --git a/app/controllers/group_of_lines_controller.rb b/app/controllers/group_of_lines_controller.rb index 5bbda9b84..7167cc40e 100644 --- a/app/controllers/group_of_lines_controller.rb +++ b/app/controllers/group_of_lines_controller.rb @@ -11,7 +11,9 @@ class GroupOfLinesController < ChouetteController    def show      @map = GroupOfLineMap.new(resource).with_helpers(self)      @lines = resource.lines.order(:name).paginate(:page => params[:page]) -    show! +    show! do +      add_breadcrumb Referential.human_attribute_name("group_of_lines"), referential_group_of_lines_path(@referential) +    end    end    def index     @@ -23,12 +25,24 @@ class GroupOfLinesController < ChouetteController        }      end           end +   +  def new +    new! do +      add_breadcrumb Referential.human_attribute_name("group_of_lines"), referential_group_of_lines_path(@referential) +    end +  end +   +  def edit +    edit! do +      add_breadcrumb Referential.human_attribute_name("group_of_lines"), referential_group_of_lines_path(@referential) +      add_breadcrumb @group_of_line.name, referential_group_of_line_path(@referential, @group_of_line) +    end +  end    def name_filter      respond_to do |format|          format.json { render :json => filtered_group_of_lines_maps}        end   -        end    protected diff --git a/app/controllers/import_tasks_controller.rb b/app/controllers/import_tasks_controller.rb index 1d7e8c3aa..e900c79ce 100644 --- a/app/controllers/import_tasks_controller.rb +++ b/app/controllers/import_tasks_controller.rb @@ -5,12 +5,14 @@ class ImportTasksController < ChouetteController    def new      new! do +      add_breadcrumb Referential.human_attribute_name("import_tasks"), referential_import_tasks_path(@referential)        available_imports      end    end    def show      show! do +      add_breadcrumb Referential.human_attribute_name("import_tasks"), referential_import_tasks_path(@referential)        if import_task.completed?          @files_stats = import_task.result["files"]["stats"]          @files_list = import_task.result["files"]["list"] diff --git a/app/controllers/journey_patterns_controller.rb b/app/controllers/journey_patterns_controller.rb index 0274b9b71..084f34b03 100644 --- a/app/controllers/journey_patterns_controller.rb +++ b/app/controllers/journey_patterns_controller.rb @@ -27,7 +27,28 @@ class JourneyPatternsController < ChouetteController    def show      @map = JourneyPatternMap.new(journey_pattern).with_helpers(self)      @stop_points = journey_pattern.stop_points.paginate(:page => params[:page]) -    show! +    show! do +      add_breadcrumb Referential.human_attribute_name("lines"), referential_lines_path(@referential) +      add_breadcrumb @line.name, referential_line_path(@referential, @line) +      add_breadcrumb @route.name, referential_line_route_path(@referential, @line, @route) +    end +  end + +  def new +    new! do +      add_breadcrumb Referential.human_attribute_name("lines"), referential_lines_path(@referential) +      add_breadcrumb @line.name, referential_line_path(@referential, @line) +      add_breadcrumb @route.name, referential_line_route_path(@referential, @line, @route) +    end +  end + +  def edit +    edit! do +      add_breadcrumb Referential.human_attribute_name("lines"), referential_lines_path(@referential) +      add_breadcrumb @line.name, referential_line_path(@referential, @line) +      add_breadcrumb @route.name, referential_line_route_path(@referential, @line, @route) +      add_breadcrumb @journey_pattern.name, referential_line_route_journey_pattern_path(@referential, @line, @route, @journey_pattern) +    end    end    def new_vehicle_journey diff --git a/app/controllers/lines_controller.rb b/app/controllers/lines_controller.rb index 3721a957d..2ff732721 100644 --- a/app/controllers/lines_controller.rb +++ b/app/controllers/lines_controller.rb @@ -22,9 +22,23 @@ class LinesController < ChouetteController      @map = LineMap.new(resource).with_helpers(self)      @routes = @line.routes      @group_of_lines = @line.group_of_lines -    show! +    show! do +      add_breadcrumb Referential.human_attribute_name("lines"), referential_lines_path(@referential) +    end    end +  def new +    new! do +      add_breadcrumb Referential.human_attribute_name("lines"), referential_lines_path(@referential) +    end +  end +   +  def edit +    edit! do +      add_breadcrumb Referential.human_attribute_name("lines"), referential_lines_path(@referential) +      add_breadcrumb @line.name, referential_line_path(@referential, @line) +    end +  end    # overwrite inherited resources to use delete instead of destroy     # foreign keys will propagate deletion)    def destroy_resource(object) diff --git a/app/controllers/networks_controller.rb b/app/controllers/networks_controller.rb index 04d565812..f99ff494b 100644 --- a/app/controllers/networks_controller.rb +++ b/app/controllers/networks_controller.rb @@ -10,7 +10,9 @@ class NetworksController < ChouetteController    def show      @map = NetworkMap.new(resource).with_helpers(self) -    show! +    show! do +      add_breadcrumb Referential.human_attribute_name("networks"), referential_networks_path(@referential) +    end    end    def index     @@ -23,6 +25,19 @@ class NetworksController < ChouetteController      end           end +  def new +    new! do +      add_breadcrumb Referential.human_attribute_name("networks"), referential_networks_path(@referential) +    end +  end +   +  def edit +    edit! do +      add_breadcrumb Referential.human_attribute_name("networks"), referential_networks_path(@referential) +      add_breadcrumb @network.name, referential_line_path(@referential, @network) +    end +  end +    protected    def collection     diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 7b5e096db..7d51c47ad 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -18,9 +18,26 @@ class RoutesController < ChouetteController    def show      @map = RouteMap.new(route).with_helpers(self)      @stop_points = route.stop_points.paginate(:page => params[:page]) -    show! +    show! do +      add_breadcrumb Referential.human_attribute_name("lines"), referential_lines_path(@referential) +      add_breadcrumb @line.name, referential_line_path(@referential, @line) +    end    end +  def new +    new! do +      add_breadcrumb Referential.human_attribute_name("lines"), referential_lines_path(@referential) +      add_breadcrumb @line.name, referential_line_path(@referential, @line) +    end +  end +   +  def edit +    edit! do +      add_breadcrumb Referential.human_attribute_name("lines"), referential_lines_path(@referential) +      add_breadcrumb @line.name, referential_line_path(@referential, @line) +      add_breadcrumb @route.name, referential_line_route_path(@referential, @line, @route) +    end +  end    # overwrite inherited resources to use delete instead of destroy     # foreign keys will propagate deletion)    def destroy_resource(object) diff --git a/app/controllers/rule_parameter_sets_controller.rb b/app/controllers/rule_parameter_sets_controller.rb index fbd5281c8..9918e0eb5 100644 --- a/app/controllers/rule_parameter_sets_controller.rb +++ b/app/controllers/rule_parameter_sets_controller.rb @@ -6,7 +6,26 @@ class RuleParameterSetsController < ChouetteController    def new      @rule_parameter_set = RuleParameterSet.default( @referential) -    new! +    new! do +      add_breadcrumb Referential.human_attribute_name("import_tasks"), referential_import_tasks_path(@referential) +      add_breadcrumb Referential.human_attribute_name("compliance_check_tasks"), referential_compliance_check_tasks_path(@referential)       +      add_breadcrumb Referential.human_attribute_name("rule_parameter_sets"), referential_rule_parameter_sets_path(@referential)       +    end +  end + +  def index +    index! do +      add_breadcrumb Referential.human_attribute_name("import_tasks"), referential_import_tasks_path(@referential) +      add_breadcrumb Referential.human_attribute_name("compliance_check_tasks"), referential_compliance_check_tasks_path(@referential)       +    end +  end + +  def show +    show! do +      add_breadcrumb Referential.human_attribute_name("import_tasks"), referential_import_tasks_path(@referential) +      add_breadcrumb Referential.human_attribute_name("compliance_check_tasks"), referential_compliance_check_tasks_path(@referential)       +      add_breadcrumb Referential.human_attribute_name("rule_parameter_sets"), referential_rule_parameter_sets_path(@referential)       +    end    end    def destroy diff --git a/app/controllers/stop_area_copies_controller.rb b/app/controllers/stop_area_copies_controller.rb index dbb66c2bd..642932acd 100644 --- a/app/controllers/stop_area_copies_controller.rb +++ b/app/controllers/stop_area_copies_controller.rb @@ -8,7 +8,10 @@ class StopAreaCopiesController < ChouetteController    def new          @stop_area_copy = StopAreaCopy.new(:hierarchy => params[:hierarchy], :source => parent) -    new! +    new! do +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +      add_breadcrumb @stop_area.name, referential_stop_area_path(@referential, @stop_area) +    end    end    def create 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/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb index e18f89cab..ca72c362b 100644 --- a/app/controllers/stop_areas_controller.rb +++ b/app/controllers/stop_areas_controller.rb @@ -19,30 +19,40 @@ class StopAreasController < ChouetteController    def select_parent      @stop_area = stop_area      @parent = stop_area.parent +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +      add_breadcrumb @stop_area.name, referential_stop_area_path(@referential, @stop_area)    end    def add_children      @stop_area = stop_area      @children = stop_area.children +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +      add_breadcrumb @stop_area.name, referential_stop_area_path(@referential, @stop_area)    end    def add_routing_lines      @stop_area = stop_area      @lines = stop_area.routing_lines +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +      add_breadcrumb @stop_area.name, referential_stop_area_path(@referential, @stop_area)    end    def add_routing_stops      @stop_area = stop_area      @stops = stop_area.routing_stops +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +      add_breadcrumb @stop_area.name, referential_stop_area_path(@referential, @stop_area)    end    def access_links      @stop_area = stop_area      @generic_access_links = stop_area.generic_access_link_matrix      @detail_access_links = stop_area.detail_access_link_matrix +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +      add_breadcrumb @stop_area.name, referential_stop_area_path(@referential, @stop_area)    end -  def index     +  def index      request.format.kml? ? @per_page = nil : @per_page = 12      @country_codes = referential.stop_areas.collect(&:country_code).compact.uniq      index! do |format| @@ -51,27 +61,39 @@ class StopAreasController < ChouetteController            redirect_to params.merge(:page => 1)          end        } -    end        +    end +  end + +  def new +    @map = StopAreaMap.new( Chouette::StopArea.new).with_helpers(self) +    @map.editable = true +    new! do +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +    end    end    def show      map.editable = false      @access_points = @stop_area.access_points      show! do |format| -      unless stop_area.position or params[:default] or params[:routing]  +      unless stop_area.position or params[:default] or params[:routing]          format.kml { -          render :nothing => true, :status => :not_found  +          render :nothing => true, :status => :not_found          } -         +        end +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential)      end    end -   +    def edit      stop_area.position ||= stop_area.default_position      map.editable = true -    edit! +    edit! do +      add_breadcrumb Referential.human_attribute_name("stop_areas"), referential_stop_areas_path(@referential) +      add_breadcrumb @stop_area.name, referential_stop_area_path(@referential, @stop_area) +    end    end    def default_geometry @@ -85,9 +107,9 @@ class StopAreasController < ChouetteController        format.json { render :json => referential.stop_areas.collect(&:country_code).compact.uniq.to_json }      end    end -   +    protected -   +    alias_method :stop_area, :resource    def map @@ -96,7 +118,7 @@ class StopAreasController < ChouetteController    def collection      @q = parent.present? ? parent.stop_areas.search(params[:q]) : referential.stop_areas.search(params[:q]) -    @stop_areas ||=  +    @stop_areas ||=        begin          stop_areas = @q.result(:distinct => true).order(:name)          stop_areas = stop_areas.paginate(:page => params[:page], :per_page => @per_page) if @per_page.present? diff --git a/app/controllers/vehicle_journey_exports_controller.rb b/app/controllers/vehicle_journey_exports_controller.rb index ed1cd61a6..0cc30f23a 100644 --- a/app/controllers/vehicle_journey_exports_controller.rb +++ b/app/controllers/vehicle_journey_exports_controller.rb @@ -6,21 +6,28 @@ class VehicleJourneyExportsController < ChouetteController    end    respond_to :csv, :only => [:index] -  respond_to :xls, :only => [:index] +  respond_to :zip, :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.zip do +        begin +          temp_file = Tempfile.new("vehicle_journey_export") +          VehicleJourneyExport.new(:route => route, :vehicle_journeys => vehicle_journeys).to_zip(temp_file,:col_sep => ";") +          send_data  File.read(temp_file.path), :filename => t("vehicle_journey_exports.new.basename")+"_#{route.id}.zip"  +        ensure +          temp_file.close +          temp_file.unlink +        end +      end +      #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/exporters/chouette/hub/exporter.rb b/app/exporters/chouette/hub/exporter.rb index 96e125814..2d14d3a3b 100644 --- a/app/exporters/chouette/hub/exporter.rb +++ b/app/exporters/chouette/hub/exporter.rb @@ -1,4 +1,5 @@  class Chouette::Hub::Exporter +  require "zip"    attr_reader :referential    attr_reader :hub_export, :lines, :routes, :journey_patterns @@ -174,7 +175,7 @@ class Chouette::Hub::Exporter          end -        ::Zip::ZipFile.open(zip_file_path, ::Zip::ZipFile::CREATE) do |zipfile| +        ::Zip::File.open(zip_file_path, ::Zip::File::CREATE) do |zipfile|            Dir[File.join(temp_dir, '*.TXT')].each do |f|              #Rails.logger.error("Adding File #{File.basename(f)}")              zipfile.add(File.basename(f), f) diff --git a/app/exporters/chouette/kml/exporter.rb b/app/exporters/chouette/kml/exporter.rb index 06af4bc2f..5b6170edc 100644 --- a/app/exporters/chouette/kml/exporter.rb +++ b/app/exporters/chouette/kml/exporter.rb @@ -1,5 +1,7 @@  class Chouette::Kml::Exporter +  require 'zip' +      attr_reader :referential    attr_reader :kml_export, :lines, :routes, :journey_patterns @@ -103,7 +105,7 @@ class Chouette::Kml::Exporter          end -        ::Zip::ZipFile.open(zip_file_path, ::Zip::ZipFile::CREATE) do |zipfile| +        ::Zip::File.open(zip_file_path, ::Zip::File::CREATE) do |zipfile|            Dir[File.join(temp_dir, '*.kml')].each do |f|              zipfile.add(File.basename(f), f)            end diff --git a/app/helpers/exports_helper.rb b/app/helpers/exports_helper.rb index 1ae59c190..9be7a5e46 100644 --- a/app/helpers/exports_helper.rb +++ b/app/helpers/exports_helper.rb @@ -1,15 +1,19 @@  module ExportsHelper    def fields_for_export_type(form) -    partial_name = "fields_#{form.object.type.underscore}" +    #partial_name = "fields_#{form.object.type.underscore}"      begin -      render :partial => partial_name, :locals => { :form => form } +      render :partial => export_partial_name(form), :locals => { :form => form }      rescue ActionView::MissingTemplate        ""      end    end +  def export_partial_name(form) +    "fields_#{form.object.type.underscore}" +  end +    include TypeIdsModelsHelper  end diff --git a/app/helpers/imports_helper.rb b/app/helpers/imports_helper.rb index 22ce8ea98..7f58b229e 100644 --- a/app/helpers/imports_helper.rb +++ b/app/helpers/imports_helper.rb @@ -2,14 +2,18 @@  module ImportsHelper    def fields_for_import_task_format(form) -    partial_name = "fields_#{form.object.format.underscore}_import" +    #partial_name = "fields_#{form.object.format.underscore}_import"      begin -      render :partial => partial_name, :locals => { :form => form } +      render :partial => import_partial_name(form), :locals => { :form => form }      rescue ActionView::MissingTemplate        ""      end    end +   +  def import_partial_name(form) +    "fields_#{form.object.format.underscore}_import" +  end    def compliance_icon( import_task)      return nil unless import_task.compliance_check_task diff --git a/app/maps/stop_area_map.rb b/app/maps/stop_area_map.rb index 3fff4a110..ee0adc0bb 100644 --- a/app/maps/stop_area_map.rb +++ b/app/maps/stop_area_map.rb @@ -10,9 +10,6 @@ class StopAreaMap < ApplicationMap    end    def customize_map(map, page) -      page.assign "edit_stop_area_layer", kml_layer(stop_area, { :default => editable? }, :style_map => Design::EditStopAreaStyleMap.new(helpers).style_map) -      page << map.add_layer(:edit_stop_area_layer) -        if stop_area.children.present?          page.assign "children_layer", kml_layer(stop_area, { :children => true }, :style_map => Design::StopAreasStyleMap.new(helpers).style_map)          page << map.add_layer(:children_layer) @@ -23,27 +20,106 @@ class StopAreaMap < ApplicationMap          page << map.add_control( hover_control_display_name(:routing_layer) )          page << map.zoom_to_extent(bounds.to_google.to_openlayers) if bounds        else -       -        page.assign "edit_stop_area_layer", kml_layer(stop_area, { :default => editable? }, :style_map => Design::EditStopAreaStyleMap.new(helpers).style_map) + + +        if stop_area.new_record? +          page << <<EOF +          var createStyleMap = function() { +            var defProp = {strokeColor: "red"}; +            var defProp = {strokeColor: "black", strokeOpacity: 1, strokeWidth: 2, fillColor: "white", fillOpacity: 1}; +            var defStyle = OpenLayers.Util.applyDefaults(defProp, OpenLayers.Feature.Vector.style["default"]); +            return new OpenLayers.StyleMap({'default': defStyle}); +          }; +          var edit_stop_area_layer = new OpenLayers.Layer.Vector( "edit_stop_area_layer", {styleMap: createStyleMap()}); + +EOF +        else +          page.assign "edit_stop_area_layer", kml_layer(stop_area, { :default => editable? }, :style_map => Design::EditStopAreaStyleMap.new(helpers).style_map) +        end + +          page << <<EOF +          var createAddressStyleMap = function() { +            var defProp = {strokeColor: "black", strokeOpacity: 1, strokeWidth: 2, fillColor: "#86b41d", fillOpacity: 1}; +            var defStyle = OpenLayers.Util.applyDefaults(defProp, OpenLayers.Feature.Vector.style["default"]); +            return new OpenLayers.StyleMap({'default': defStyle, }); +          }; +          var address_layer = new OpenLayers.Layer.Vector( "address_layer", {styleMap: createAddressStyleMap()}); + +          var removeAddress = function() { +            address_layer.destroyFeatures(); +          }; + +          var addAddress = function( lat, lng, name ) { +            var wgs84point = new OpenLayers.Geometry.Point( lat, lng); +            var point = transformedGeometry( wgs84point, "EPSG:4326", "EPSG:900913" ) +            var feature = new OpenLayers.Feature.Vector( point, { name: name}); +            address_layer.addFeatures( [feature]); + +            var bounds = new OpenLayers.Bounds(); +            bounds.extend( feature.geometry.getBounds()); +            for (var x in edit_stop_area_layer.features) { +                bounds.extend( edit_stop_area_layer.features[x].geometry.getBounds()); +            } +            map.zoomToExtent(bounds,true); +          }; +          var transformedGeometry = function( geometry, origin, target ) { +            return geometry.clone().transform( new OpenLayers.Projection( origin ), new OpenLayers.Projection( target )); +          } +EOF +        page << map.add_layer(:address_layer)          page << map.add_layer(:edit_stop_area_layer) -       +          if editable? -          page.assign "referential_projection", projection_type.present? ? projection("EPSG:" + projection_type) : JsVar.new("undefined")   -          # TODO virer ce code inline        +          page.assign "referential_projection", projection_type.present? ? projection("EPSG:" + projection_type) : JsVar.new("undefined") + +          # TODO virer ce code inline            page << <<EOF -          edit_stop_area_layer.events.on({  -                          'afterfeaturemodified': function(event) {  -                            geometry = event.feature.geometry.clone().transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326")); -                            $('#stop_area_coordinates').val(geometry.y.toString()+ ","+ geometry.x.toString()); - -                            if(referential_projection != undefined) -                            { -                              projection_geometry = event.feature.geometry.clone().transform(new OpenLayers.Projection("EPSG:900913"), referential_projection ); -                              $('#stop_area_projection_xy').val(projection_geometry.x.toString()+ ","+ projection_geometry.y.toString());                                                   } -                           } -                        }); + +          var getEventWGS84 = function( event) { +            return transformedGeometry( event.geometry, "EPSG:900913", "EPSG:4326"); +          } +          var getEventProjection = function( event, projCode) { +            return transformedGeometry( event.geometry, "EPSG:900913", projCode); +          } +          var updateStopAreaCoordinates = function( event ) { +            var geometry = getEventWGS84( event ); +            $('#stop_area_coordinates').val( geometry.y.toString()+ ","+ geometry.x.toString()); +          } +          var updateStopAreaProjectionXY = function( event, projCode ) { +            var geometry = getEventProjection( event, projCode); +            $('#stop_area_projection_xy').val( geometry.x.toString()+ ","+ geometry.y.toString()); +          } + +          var drawControl = new OpenLayers.Control.DrawFeature( edit_stop_area_layer, OpenLayers.Handler.Point, +              { featureAdded: function(event) { +              console.log( "featureAdded" ); +                  updateStopAreaCoordinates( event); +                  if( typeof referential_projection !== 'undefined') { +                    updateStopAreaProjectionXY( event, referential_projection.projCode); +                  } +                  this.deactivate(); +                } +              }); + +          var dragControl = new OpenLayers.Control.DragFeature( edit_stop_area_layer, +              { autoActivate: true, +                onComplete: function(event) { +                  updateStopAreaCoordinates( event); +                  if( typeof referential_projection !== 'undefined') { +                    updateStopAreaProjectionXY( event, referential_projection.projCode); +                  } +                }, +              }); +            map.addControl( dragControl); +            map.addControl( drawControl);  EOF -          page << map.add_control(OpenLayers::Control::ModifyFeature.new(:edit_stop_area_layer, :mode => 8, :autoActivate => true)) + +          if stop_area.new_record? +          page << <<EOF +            drawControl.activate(); +EOF +          end +          #page << map.add_control(OpenLayers::Control::ModifyFeature.new(:edit_stop_area_layer, :mode => 8, :autoActivate => true))          elsif stop_area.children.present?            page << map.add_control( hover_control_display_name(:children_layer) ) @@ -52,7 +128,7 @@ EOF        page << map.set_center(center.to_google.to_openlayers, 16, false, true)        end    end -   +    def projection_type      stop_area.referential.projection_type    end diff --git a/app/models/export.rb b/app/models/export.rb index 98b3f0ace..4d7b5c56c 100644 --- a/app/models/export.rb +++ b/app/models/export.rb @@ -3,7 +3,7 @@ class Export < ActiveRecord::Base    belongs_to :referential    validates_presence_of :referential_id -  validates_inclusion_of :status, :in => %w{ pending completed failed } +  validates_inclusion_of :status, :in => %w{ pending processing completed failed }    has_many :log_messages, :class_name => "ExportLogMessage", :order => :position, :dependent => :delete_all @@ -51,12 +51,7 @@ class Export < ActiveRecord::Base    end    def export_object_type -#    case references_type -#    when "Chouette::Network" -#      "ptnetwork" -#    else        references_relation ? references_relation.singularize : "line" -#    end    end    before_validation :define_default_attributes, :on => :create @@ -91,10 +86,19 @@ class Export < ActiveRecord::Base      log_messages.create :severity => result_severity, :key => status    end -  @@references_types = [ Chouette::Line, Chouette::Network, Chouette::Company ] -  cattr_reader :references_types -  validates_inclusion_of :references_type, :in => references_types.map(&:to_s), :allow_blank => true, :allow_nil => true +  def self.all_references_types +    [ Chouette::Line, Chouette::Network, Chouette::Company , Chouette::StopArea] +  end + +  def references_types +    [ Chouette::Line, Chouette::Network, Chouette::Company ] +  end + +  # @@references_types = [ Chouette::Line, Chouette::Network, Chouette::Company ] +  # cattr_reader :references_types + +  # validates_inclusion_of :references_type, :in => references_types.map(&:to_s), :allow_blank => true, :allow_nil => true    def self.format_name(format)      name_by_format = { @@ -107,6 +111,10 @@ class Export < ActiveRecord::Base      }      name_by_format[format]    end +   +  def self.format_label(format) +    I18n.t 'exchange.format.'+format.sub("Export",'').downcase +  end    def self.types      unless Rails.env.development? diff --git a/app/models/gtfs_export.rb b/app/models/gtfs_export.rb index 9c66e778b..6f43a93eb 100644 --- a/app/models/gtfs_export.rb +++ b/app/models/gtfs_export.rb @@ -5,6 +5,10 @@ class GtfsExport < Export    after_initialize :init_time_zone +  def references_types +    [ Chouette::Line, Chouette::Network, Chouette::Company, Chouette::StopArea ] +  end +    def init_time_zone      if time_zone.nil?        self.time_zone = "Paris" diff --git a/app/models/gtfs_import.rb b/app/models/gtfs_import.rb index af83d81a0..c2457548f 100644 --- a/app/models/gtfs_import.rb +++ b/app/models/gtfs_import.rb @@ -7,4 +7,8 @@ class GtfsImport < ImportTask    option :ignore_end_chars    option :max_distance_for_connection_link +  def references_types +    [ Chouette::StopArea ] +  end +  end diff --git a/app/models/import_task.rb b/app/models/import_task.rb index 90783075d..26b3808c7 100644 --- a/app/models/import_task.rb +++ b/app/models/import_task.rb @@ -15,6 +15,10 @@ class ImportTask < ActiveRecord::Base    validates_presence_of :user_name    validates_inclusion_of :status, :in => %w{ pending processing completed failed } +  def references_types +    [] +  end +    protected    def self.option(name, type=nil) @@ -41,6 +45,10 @@ class ImportTask < ActiveRecord::Base      %w{Neptune Csv Gtfs Netex}    end +  def self.format_label(format) +    I18n.t 'exchange.format.'+format.downcase +  end +    def delayed_import      delay.import    end @@ -54,6 +62,7 @@ class ImportTask < ActiveRecord::Base    option :no_save, :boolean    option :format    option :file_path +  option :references_type    validates_inclusion_of :no_save, :in => [ true, false]    validates_inclusion_of :format, :in => self.formats diff --git a/app/models/referential.rb b/app/models/referential.rb index f99c65f9f..41d239961 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -41,6 +41,10 @@ class Referential < ActiveRecord::Base      end    end +  def viewbox_left_top_right_bottom +    [  lower_corner.lng, upper_corner.lat, upper_corner.lng, lower_corner.lat ].join(',') +  end +    def human_attribute_name(*args)      self.class.human_attribute_name(*args)    end 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 52d8a94bb..000000000 --- a/app/models/stop_area_import.rb +++ /dev/null @@ -1,67 +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) -      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..3de88b608 100644 --- a/app/models/vehicle_journey_export.rb +++ b/app/models/vehicle_journey_export.rb @@ -1,12 +1,13 @@  # -*- coding: utf-8 -*-  require "csv" +require "zip"  class VehicleJourneyExport       include ActiveModel::Validations    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,20 +17,151 @@ 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(&:id) +  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 vehicle_identifier_array +    (vehicle_journeys.collect{ |vj| vj.vehicle_type_identifier ?  vj.vehicle_type_identifier : "" } ) +  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("vehicle_identifier")] + vehicle_identifier_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    end +  def tt_day_types(tt) +    type = tt.monday ? label("monday") : ".." +    type += tt.tuesday ? label("tuesday") : ".." +    type += tt.wednesday ? label("wednesday") : ".." +    type += tt.thursday ? label("thursday") : ".." +    type += tt.friday ? label("friday") : ".." +    type += tt.saturday ? label("saturday") : ".." +    type += tt.sunday ? label("sunday") : ".." +    type +  end +   +  def tt_periods(tt) +    periods = "" +    tt.periods.each do |p| +      periods += "["+p.period_start.to_s+" -> "+p.period_end.to_s+"] " +    end +    periods +  end +   +  def tt_peculiar_days(tt) +    days = "" +    tt.included_days.each do |d| +      days += d.to_s+" " +    end +    days +  end  +      +  def tt_excluded_days(tt) +    days = "" +    tt.excluded_days.each do |d| +      days += d.to_s+" " +    end +    days +  end     +   +  def tt_data(tt) +    [].tap do |array| +      # code;name;tags;start;end;day types;periods;peculiar days;excluded days +      array << tt.id.to_s +      array << tt.comment +      array << tt.tag_list +      array << tt.start_date.to_s +      array << tt.end_date.to_s +      array << tt_day_types(tt) +      array << tt_day_types(tt) +      array << tt_periods(tt) +      array << tt_peculiar_days(tt) +      array << tt_excluded_days(tt) +    end   +  end +   +  def time_tables_to_csv (options = {}) +    tts = Chouette::TimeTable.all +    CSV.generate(options) do |csv|             +      csv << label("tt_columns").split(";") +      tts.each do |tt|         +        csv << tt_data(tt) +      end +    end +  end +   +  def to_zip(temp_file,options = {}) +    ::Zip::OutputStream.open(temp_file) { |zos| } +    ::Zip::File.open(temp_file.path, ::Zip::File::CREATE) do |zipfile| +      zipfile.get_output_stream(label("vj_filename")+route.id.to_s+".csv") { |f| f.puts to_csv(options) } +      zipfile.get_output_stream(label("tt_filename")+".csv") { |f| f.puts time_tables_to_csv(options) } +    end     +  end +  end diff --git a/app/models/vehicle_journey_import.rb b/app/models/vehicle_journey_import.rb index 15569c3d4..42cc24244 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,58 @@ 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 +    vehicle_type_identifier_row = 3 +    mobility_row = 4 +    flexible_service_row = 5 +    time_tables_row = 6 + +    # rows in column (first = 0) +    first_stop_row_index = 7 +     +    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 +113,55 @@ 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] +      vehicle_journey_id = spreadsheet.column(i)[0] +      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(:id => vehicle_journey_id, :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]) +       +      # vehicle_type_identifier +      vehicle_journey.vehicle_type_identifier = spreadsheet.row(vehicle_type_identifier_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 +169,6 @@ class VehicleJourneyImport            end          end                 end -      vehicle_journey.vehicle_journey_at_stops_attributes = vehicle_journey_at_stops        vehicle_journeys << vehicle_journey      end @@ -100,7 +177,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/exports/new.html.erb b/app/views/exports/new.html.erb index 553ebe4a2..8405e2c4d 100644 --- a/app/views/exports/new.html.erb +++ b/app/views/exports/new.html.erb @@ -2,7 +2,7 @@  <%= semantic_form_for([@referential, @export], :as => :export, :url => new_referential_export_path(@referential), :method => :get) do |form| %>    <%= form.inputs do %> -    <%= form.input :type, :as => :radio, :collection => Export.types.map { |format| [ Export.format_name(format), format]}, :required => true, :include_blank => false %> +    <%= form.input :type, :as => :radio, :collection => Export.types.map { |format| [ Export.format_label(format), format]}, :required => true, :include_blank => false %>    <% end %>  <% end %> @@ -14,9 +14,10 @@    <%= form.inputs do %>      <%= form.input :type, :as => :hidden %> -    <%= form.input :references_type, :as => :select, :collection => Export.references_types.map { |c| [ c.model_name.human.capitalize.pluralize, c.name ] }, :include_blank => t(".all") %> +    <p class="warning"><%= t('.'+export_partial_name(form)+'.warning',:default => "")%></p> +    <%= form.input :references_type, :as => :select, :collection => export.references_types.map { |c| [ c.model_name.human.capitalize.pluralize, c.name ] }, :include_blank => t(".all") %> -    <% Export.references_types.each do |type| %> +    <% export.references_types.each do |type| %>        <%= type_ids_model_references_input(form, @export, Export, type).input %>      <% end %>    <% end %> diff --git a/app/views/exports/new.js.coffee b/app/views/exports/new.js.coffee index 0886f53c9..aafa70bed 100644 --- a/app/views/exports/new.js.coffee +++ b/app/views/exports/new.js.coffee @@ -1,4 +1,4 @@  jQuery -> -    <% Export.references_types.map { |type| type_ids_model_references_type( Export, type)}.each do |rt| %> +    <% Export.all_references_types.map { |type| type_ids_model_references_type( Export, type)}.each do |rt| %>         $("textarea.<%= rt.input_class %>").tokenInput('<%= references_referential_compliance_check_tasks_path(@referential, :type => rt.relation_name, :format => :json) %>', { prePopulate: $('#').data('pre'), minChars: 1, hintText: '<%= t('search_hint') %>', noResultsText: '<%= t('no_result_text') %>', searchingText: '<%= t('searching_term') %>'});      <% end %> diff --git a/app/views/help/exports.textile b/app/views/help/exports.textile index c82f8cea2..03ae1f1d0 100644 --- a/app/views/help/exports.textile +++ b/app/views/help/exports.textile @@ -39,6 +39,9 @@ la sélection propose dès le premier caractère saisi la liste des objets dont  - Fuseau horaire :=   fixe le fuseau horaire (paramètre obligatoire des données GTFS)   la valeur proposée par défaut est celle de l'espace de données =: +- Données incluses (complément) :=  +le choix des arrêts permet de n'exporter que les fichiers d'arrêts (stops.txt) et de correspondances (transfers.txt) + 3 champs sont alors ajoutés : l'adresse, la localité et le code postal; ceux-ci seront exploités en retour sur l'import GTFS d'arrêts =:  * *NeTex* : pas d'option particulière @@ -49,15 +52,15 @@ fixe le fuseau horaire (paramètre obligatoire des données GTFS)  - Début de période := permet d'exporter uniquement les courses circulant à partir de cette date  - Fin de période := permet d'exporter uniquement les courses circulant jusqu'à cette date  - Fuseau horaire :=  -fixe le fuseau horaire (paramètre obligatoire des données GTFS) +fixe le fuseau horaire   la valeur proposée par défaut est celle de l'espace de données =: -  h3. Consultation des résultats  p. L'export est lancé en différé; son état d'avancement est affiché sous la forme d'une icône donc la couleur dépend de l'état: +* blanc : en attente  * bleu : en cours  * vert : terminé correctement; un lien de téléchargement est alors disponible  * rouge : terminé en échec diff --git a/app/views/help/imports.textile b/app/views/help/imports.textile index 88b780b7f..66966b515 100644 --- a/app/views/help/imports.textile +++ b/app/views/help/imports.textile @@ -41,6 +41,8 @@ format originaire de ["Google Transit":https://support.google.com/transitpartner  p(olnext). - les données exportées en GTFS sont explicités ["ICI":http://www.normes-donnees-tc.org/format-dechange/autres-normes/]  +p(olnext). - l'import limité au sous ensemble des arrêts permet de n'importer que les arrêts et les correspondances +  h3(#com). Paramètres communs  - Pas de sauvegarde := permet d'effectuer une simulation de l'import sans enregistrer les données @@ -79,6 +81,9 @@ distance maximale entre deux arrêts pour les lier par une correspondance,  ces correspondances sont hors zone d'arrêt;  elles viennent en supplément de celles définies dans GTFS (ce mécanisme tient compte des correspondances exclues),   une distance de 0 ne génère aucune correspondance =: +- Sous-ensemble :=  +choix permetant de limiter l'import aux seuls fichiers stops.txt et transfers.txt +lors de l'import, les attributs d'adresse, localité et code postal ajoutés à l'export associé sont exploités =:  * *CSV* :  @@ -90,7 +95,7 @@ h3(#imp). l'onglet IMPORTS  p. L'onglet IMPORTS contient les objets Import de l'espace de données courant. -p. Chaque objet Import est représenté par une vignette comprenant : sa date, l'utilisateur qui l'a créé, son état (bleu : en cours ; vert : terminé correctement ; rouge : terminé en échec), un lien pour télécharger le fichier importé, un lien vers le détail de l'objet, un lien vers l'objet Validation associé). +p. Chaque objet Import est représenté par une vignette comprenant : sa date, l'utilisateur qui l'a créé, son état (blanc: en attente, bleu : en cours ; vert : terminé correctement ; rouge : terminé en échec), un lien pour télécharger le fichier importé, un lien vers le détail de l'objet, un lien vers l'objet Validation associé).  p=. !import.png! diff --git a/app/views/import_tasks/_fields_gtfs_import.erb b/app/views/import_tasks/_fields_gtfs_import.erb index 70ffb207a..8b9dabcc5 100644 --- a/app/views/import_tasks/_fields_gtfs_import.erb +++ b/app/views/import_tasks/_fields_gtfs_import.erb @@ -1,7 +1,7 @@  <%= form.input :object_id_prefix, :input_html => { :value => @referential.prefix } %> -<%= form.input :max_distance_for_commercial , :as => :number , :input_html => { :title => t("formtastic.titles.import_task.max_distance_for_commercial"), :value => 50 } %> +<%= form.input :max_distance_for_commercial , :as => :number , :input_html => { :title => t("formtastic.titles.import_task.max_distance_for_commercial"), :value => 0 } %>  <%= form.input :ignore_last_word , :as => :boolean , :input_html => { :title => t("formtastic.titles.import_task.ignore_last_word"), :value => false }%>  <%= form.input :ignore_end_chars  , :as => :number , :input_html => { :title => t("formtastic.titles.import_task.ignore_end_chars"), :value => 0 }%> -<%= form.input :max_distance_for_connection_link  , :as => :number , :input_html => { :title => t("formtastic.titles.import_task.max_distance_for_connection_link"), :value => 100 }%> +<%= form.input :max_distance_for_connection_link  , :as => :number , :input_html => { :title => t("formtastic.titles.import_task.max_distance_for_connection_link"), :value => 0 }%> diff --git a/app/views/import_tasks/new.html.erb b/app/views/import_tasks/new.html.erb index 13888ad39..65daee0ca 100644 --- a/app/views/import_tasks/new.html.erb +++ b/app/views/import_tasks/new.html.erb @@ -2,7 +2,7 @@  <%= semantic_form_for([@referential, @import_task], :as => :import_task, :url => new_referential_import_task_path(@referential), :method => :get) do |form| %>    <%= form.inputs do %> -    <%= form.input :format, :as => :radio, :collection => ImportTask.formats, :required => true, :include_blank => false %> +    <%= form.input :format, :as => :radio, :collection => ImportTask.formats.map { |format| [ ImportTask.format_label(format), format]}, :required => true, :include_blank => false %>    <% end %>  <% end %> @@ -19,6 +19,12 @@        <%= form.input :rule_parameter_set_id, :as => :select,            :collection =>  @referential.rule_parameter_sets.map { |rps| [ rps.name, rps.id ] }, :include_blank => true %>        <%= form.input :resources, :as => :file %> +       +      <% unless import_task.references_types.empty? %> +          <p class="warning"><%= t('.'+import_partial_name(form)+'.warning')%></p> +          <%= form.input :references_type, :as => :select, :collection => import_task.references_types.map { |c| [ c.model_name.human.capitalize.pluralize, c.name ] }, :include_blank => t(".all") %> +      <% end %> +            <% end %>      <%= form.actions do %> diff --git a/app/views/referentials/index.html.erb b/app/views/referentials/index.html.erb index 220fc17ba..cf4eaa245 100644 --- a/app/views/referentials/index.html.erb +++ b/app/views/referentials/index.html.erb @@ -1,4 +1,4 @@ -<%= title_tag Referential.model_name.human.pluralize %>  +<%= title_tag Referential.model_name.human(:count => 2) %>   <div class="referentials paginated_content">    <%= paginated_content @referentials %> diff --git a/app/views/routes/show.html.erb b/app/views/routes/show.html.erb index 5621f7a36..b935a6f34 100644 --- a/app/views/routes/show.html.erb +++ b/app/views/routes/show.html.erb @@ -97,6 +97,7 @@    <li><%= link_to t('journey_patterns.actions.new'), new_referential_line_route_journey_pattern_path(@referential, @line, @route), :class => "add" %></li>  <% end %>    <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 => :zip), :class => "with_fa" %></li>    <% if @route.journey_patterns.size > 0 %>    <li>      <i class="fa fa-clock-o fa-fw"></i><%= link_to t('vehicle_journeys.actions.index'), [@referential, @line, @route, :vehicle_journeys], :class => "with_fa" %> diff --git a/app/views/rule_parameter_sets/show.html.erb b/app/views/rule_parameter_sets/show.html.erb index f2427e36e..f4ca5e912 100644 --- a/app/views/rule_parameter_sets/show.html.erb +++ b/app/views/rule_parameter_sets/show.html.erb @@ -97,13 +97,12 @@  <% content_for :sidebar do %>  <ul class="actions"> +  <li><%= link_to t('rule_parameter_sets.actions.new'), new_referential_rule_parameter_set_path(@referential), :class => "add" %></li>    <% if @rule_parameter_set.persisted? %> -  <li><%= link_to t('rule_parameter_sets.actions.index'), referential_rule_parameter_sets_path(@referential), :class => "link" %></li>    <li><%= link_to t('rule_parameter_sets.actions.edit'), edit_referential_rule_parameter_set_path(@referential, @rule_parameter_set), :class => "edit" %></li>    <% if @referential.rule_parameter_sets.size > 1 %>    <li><%= link_to  t('rule_parameter_sets.actions.destroy'), referential_rule_parameter_set_path(@referential, @rule_parameter_set), :method => :delete, :data => {:confirm =>  t('rule_parameter_sets.actions.destroy_confirm')}, :class => "remove" %></li>    <% end %> -  <li><%= link_to t('rule_parameter_sets.actions.new'), new_referential_rule_parameter_set_path(@referential), :class => "add" %></li>    <% end %>  </ul>  <% end %> 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/_form.html.erb b/app/views/stop_areas/_form.html.erb index 4a1ba1c97..5a612614b 100644 --- a/app/views/stop_areas/_form.html.erb +++ b/app/views/stop_areas/_form.html.erb @@ -1,54 +1,52 @@  <%= semantic_form_for [@referential, @stop_area] do |form| %>    <div class="row"> -    <div class="col-md-6">       +    <div class="col-md-6">        <%= form.inputs do %>        <%= form.input :id, :as => :hidden %>        <%= form.input :name %>        <%= form.input :stop_area_type, :as => :select, :input_html => { :disabled => !@stop_area.new_record? }, :collection => Chouette::StopArea.stop_area_types, :include_blank => false, :member_label => Proc.new { |stop_area_type| t("area_types.label.#{stop_area_type}") }  %>        <div class="location_info">        <h3><%= t("stop_areas.stop_area.localisation") %></h3> -      <% if @stop_area.new_record? %>          <div id="prefetch">          <label><%= t('.geolocalize') %></label> -	      <input class="typeahead form-control input-lg" maxlength="255" type="text" placeholder="<%= t('.address') %>" />        +	      <input class="typeahead form-control input-lg" maxlength="255" type="text" placeholder="<%= t('.address') %>" />        </div> -      <% end %>        <% unless @referential.projection_type_label.empty? %> -  	    <%= form.input :projection_xy, :label => t("projection_xy", :projection => @referential.projection_type_label), :input_html => { :title => t("formtastic.titles.stop_area.projection_xy")} %>    +  	    <%= form.input :projection_xy, :label => t("projection_xy", :projection => @referential.projection_type_label), :input_html => { :title => t("formtastic.titles.stop_area.projection_xy")} %>  	    <% end %>  	    <%= form.input :coordinates, :input_html => { :title => t("formtastic.titles.stop_area.coordinates")} %> -      <%= form.input :street_name %>               -      <%= form.input :country_code %>               -      <%= form.input :zip_code %>               +      <%= form.input :street_name %> +      <%= form.input :country_code %> +      <%= form.input :zip_code %>        <%= form.input :city_name %> -    <% end %>   +    <% end %>      </div>      <div class="col-md-6">        <% if !manage_itl && @map %> -      <%= @map.to_html %> +        <%= @map.to_html %>        <% end %>      </div>    </div>    <div class="stop_areas.stop_area.general_info"> -    <h3><%= t("stop_area.general") %></h3>  +    <h3><%= t("stop_area.general") %></h3>      <%= form.inputs do %> -      <%= form.input :objectid, :required => !@stop_area.new_record?, :input_html => { :title => t("formtastic.titles.stop_area.objectid")} %>  -      <%= form.input :registration_number, :input_html => { :title => t("formtastic.titles.stop_area.registration_number")} %>          -      <%= form.input :fare_code, :as => :number %>               -      <%= form.input :nearest_topic_name %>               +      <%= form.input :objectid, :required => !@stop_area.new_record?, :input_html => { :title => t("formtastic.titles.stop_area.objectid")} %> +      <%= form.input :registration_number, :input_html => { :title => t("formtastic.titles.stop_area.registration_number")} %> +      <%= form.input :fare_code, :as => :number %> +      <%= form.input :nearest_topic_name %>        <%= form.input :comment, :as => :text, :input_html => { :rows => 5 } %>      <% end %> -  </div>     +  </div>    <div class="pmr_info"> -    <h3><%= t("stop_areas.stop_area.accessibility") %></h3>  +    <h3><%= t("stop_areas.stop_area.accessibility") %></h3>      <%= form.inputs do %>        <% if !manage_itl %>  	      <%= form.input :mobility_restricted_suitability,:as => :boolean %>  	      <%= form.input :stairs_availability,:as => :boolean %> -	      <%= form.input :lift_availability,:as => :boolean %>	      -      <% end %>         +	      <%= form.input :lift_availability,:as => :boolean %> +      <% end %>      <% end %> -  </div>     +  </div>    <%= form.actions do %>      <%= form.action :submit, :as => :button %> @@ -57,77 +55,92 @@  <% end %>  <script> -  var address_display = function( address ) { -    var name = ""; -    if ( address.house_number) { -      name += address.house_number+" "; -    } -    name += address.road+", "; -    if ( address.postalcode) { -      name += address.postalcode+" "; -    } -    if ( address.city) { -      name += address.city; -    } else if ( address.county ) { -      name += address.county; -    } else if ( address.country ) { -      name += address.country; -    } +  $(document).ready(function() { +    var address_display = function( address ) { +      var name = ""; +      if ( address.house_number) { +        name += address.house_number+" "; +      } +      name += address.road+", "; +      if ( address.suburb) { +        name += address.suburb+", "; +      } +      if ( address.postcode) { +        name += address.postcode+" "; +      } +      if ( address.city) { +        name += address.city; +      } else if ( address.county ) { +        name += address.county; +      } else if ( address.country ) { +        name += address.country; +      } -    return name; -  }; -  var filtering = function(list) { -    var selection = $.grep( list, function(item) { -        return (item.type == "house" || item.type == "residential") && item.address.road ; -        }); -    return $.map( selection, function( d) { -        return { postcode: d.address.postcode, -                 road: d.address.road, -                 lon: d.lon, lat: d.lat, -                 city: d.address.city, -                 postcode: d.address.postcode, -                 the_key: address_display( d.address)}; -    }); -  }; +      return name; +    }; +    var filtering = function(list) { +      // update map view +      removeAddress(); -  var addressesEngine = new Bloodhound({ -    datumTokenizer: function(d) { -      return Bloodhound.tokenizers.whitespace(d.id+" : "+d.road); -    }, -    queryTokenizer: function(d) { -      return Bloodhound.tokenizers.whitespace(d.id+" :: "+d.road); -    }, -    limit: 10, -    remote: { -      url: 'http://nominatim.openstreetmap.org/search?q=%QUERY&format=json&addressdetails=1', -      filter: filtering, -    } -  }); +      var selection = $.grep( list, function(item) { +          return (item.type == "house" || item.type == "residential" || +            item.type == "tertiary" || item.type == "primary" || +            item.type == "secondary") && item.address.road ; +          }); +      return $.map( selection, function( d) { +          return { postcode: d.address.postcode, +                   road: d.address.road, +                   lon: d.lon, lat: d.lat, +                   suburb: d.address.suburb, +                   city: d.address.city, +                   postcode: d.address.postcode, +                   the_key: address_display( d.address)}; +      }); +    }; + +    var addressesEngine = new Bloodhound({ +      datumTokenizer: function(d) { +        return Bloodhound.tokenizers.whitespace(d.id+" : "+d.road); +      }, +      queryTokenizer: function(d) { +        return Bloodhound.tokenizers.whitespace(d.id+" :: "+d.road); +      }, +      limit: 10, +      remote: { +        url: 'http://nominatim.openstreetmap.org/search?q=%QUERY&format=json&addressdetails=1&bounded=1&viewbox='+ +          '<%= @referential.viewbox_left_top_right_bottom %>', +        filter: filtering, +      } +    }); -  // kicks off the loading/processing of `local` and `prefetch` -  var promise = addressesEngine.initialize(); +    // kicks off the loading/processing of `local` and `prefetch` +    var promise = addressesEngine.initialize(); -  // passing in `null` for the `options` arguments will result in the default -  // options being used -  $('#prefetch .typeahead').typeahead( -    { -      hint: true, -      highlight: true, -      minLength: 1 -    }, -    { -      name: 'addresses', -      displayKey: 'the_key', -      source: addressesEngine.ttAdapter(), -    } -  ); +    // passing in `null` for the `options` arguments will result in the default +    // options being used +    $('#prefetch .typeahead').typeahead( +      { +        hint: true, +        highlight: true, +        minLength: 1 +      }, +      { +        name: 'addresses', +        displayKey: 'the_key', +        source: addressesEngine.ttAdapter(), +      } +    ); -  $('.typeahead').on('typeahead:selected', function($e, datum) { -    $('input[name="stop_area[coordinates]"]').val(datum.lat+","+datum.lon); -    $('input[name="stop_area[coordinates]"]').change(); -    $('input[name="stop_area[street_name]"]').val(datum.road); -    $('input[name="stop_area[zip_code]"]').val(datum.postcode); -    $('input[name="stop_area[city_name]"]').val(datum.city); -  }) +    $('.typeahead').on('typeahead:selected', function($e, datum) { +      // update map view +      addAddress( datum.lon, datum.lat, datum.road); +      // update form fields +      <% if @stop_area.new_record? %> +      $('input[name="stop_area[street_name]"]').val(datum.road); +      $('input[name="stop_area[zip_code]"]').val(datum.postcode); +      $('input[name="stop_area[city_name]"]').val(datum.city); +      <% end %> +    }) +  });  </script> 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..212c06bbf 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 => :zip), :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/exchange.yml b/config/locales/exchange.yml new file mode 100644 index 000000000..882e1feb0 --- /dev/null +++ b/config/locales/exchange.yml @@ -0,0 +1,18 @@ +en: +  exchange: +    format: +      neptune: "Neptune (French normalized format based on European Trident Standard)" +      gtfs: "GTFS (General Transit Feed Specification)" +      csv: "CSV (Chouette format)" +      netex: "NeTEx (experimental Neptune local agreement for Network Exchange CEN standard)" +      hub: "HUB (Specific Cityway Format)" +      kml: "KML (line and route drawings on Keyhole Markup Language format)" +fr: +  exchange: +    format: +      neptune: "Neptune (Format normalisé français basé sur le standard européen Trident)" +      gtfs: "GTFS (General Transit Feed Specification définit par Google)" +      csv: "CSV (format spéficique à Chouette)" +      netex: "NeTEx (Profil expérimental de Neptune sur le standard européen 'Network Exchange' )" +      hub: "HUB (format spécifique Cityway)" +      kml: "KML (tracés de lignes et de séquences d'arrêts en 'Keyhole Markup Language')" diff --git a/config/locales/exports.yml b/config/locales/exports.yml index 9f7e59e43..75002cc22 100644 --- a/config/locales/exports.yml +++ b/config/locales/exports.yml @@ -10,6 +10,8 @@ en:        all: "All"        flash: "Export task on queue, refresh page to see progression"        flash2: "On success, a link for download will be displayed" +      fields_gtfs_export: +        warning: "Stop areas choice provide only stops and transfers gtfs files, with extra data"      index:        title: "Exports"        warning: "" @@ -123,13 +125,15 @@ fr:        all: "Toutes"        flash: "La demande d'export est mise en file d'attente, veuillez rafraichir régulièrement la page pour le suivre"        flash2: "Une fois l'export terminé, un lien sera disponible pour télécharger le résultat" +      fields_gtfs_export: +        warning: "Le filtre sur arrêts produit uniquement les fichiers GTFS stops et transfers gtfs, ceux-ci contenant alors des attributs supplémentaires"      index:        title: "Exports"        warning: ""      show:        report: "Rapport"      statuses: -      pending: "En attente ou en cours ..." +      pending: "En attente ..."        processing: "En cours ..."        completed: "Achevé"        failed: "Echoué" diff --git a/config/locales/import_tasks.yml b/config/locales/import_tasks.yml index f76e56d64..a4f9ba2a5 100644 --- a/config/locales/import_tasks.yml +++ b/config/locales/import_tasks.yml @@ -6,7 +6,10 @@ en:        destroy_confirm: "Are you sure you want destroy this import?"      new:        title: "New import" +      all: "All"        flash: "Import task on queue, refresh page to see progression" +      fields_gtfs_import: +        warning: "Filter on stop areas import only GTFS stops and transfers files, these may contain extra attributes"      index:        title: "Imports"        warning: "" @@ -76,6 +79,7 @@ en:          resources: "File to import"          created_at: "Created on"          status: "Status" +        references_type: "subset"          no_save: "No save"          rule_parameter_set_id: "Rule parameter set for compliance check"          object_id_prefix: "Neptune Id prefix" @@ -98,7 +102,10 @@ fr:        destroy_confirm: "Etes vous sûr de supprimer cet import ?"      new:        title: "Nouvel import" +      all: "Tout"        flash: "La demande d'import est mise en file d'attente, veuillez rafraichir régulièrement la page pour le suivre" +      fields_gtfs_import: +        warning: "Le filtre sur arrêts importe uniquement les fichiers GTFS stops et transfers gtfs, ceux-ci pouvant contenir des attributs supplémentaires"      index:        title: "Imports"        warning: "" @@ -183,6 +190,7 @@ fr:          created_at: "Créé le"          status: "Status"          no_save: "Pas de sauvegarde" +        references_type: "Sous ensemble"          rule_parameter_set_id: "Jeu de paramètres pour validation"          object_id_prefix: "Préfixe d'identifiants"          max_distance_for_commercial: "Distance max pour créer les zones" diff --git a/config/locales/layouts.yml b/config/locales/layouts.yml index 342e052b8..d1b479254 100644 --- a/config/locales/layouts.yml +++ b/config/locales/layouts.yml @@ -7,8 +7,8 @@ en:        profile: "My Profile"        sign_out: "Sign out"      navbar: -      return_to_referentials: "Return to referentials" -      select_referential: "Select referential" +      return_to_referentials: "Return to data spaces" +      select_referential: "Select data space"        select_referential_datas: "Select datas"        return_to_dashboard: "Return to Dashboard"        referential_datas: "Datas" @@ -49,8 +49,8 @@ fr:        profile: "Mon Profil"              sign_out: "Déconnexion"      navbar: -      return_to_referentials: "Retour à la liste des référentiels" -      select_referential: "Sélection du référentiel" +      return_to_referentials: "Retour à la liste des espaces de données" +      select_referential: "Sélection de l'espace de données"        select_referential_datas: "Sélection des données"        return_to_dashboard: "Retour au Tableau de Bord"        referential_datas: "Données" diff --git a/config/locales/referentials.yml b/config/locales/referentials.yml index 8353c1e9e..0d3a63498 100644 --- a/config/locales/referentials.yml +++ b/config/locales/referentials.yml @@ -65,6 +65,7 @@ en:          import_tasks: "Imports"          export_tasks: "Exports"          compliance_check_tasks: "Validations" +        rule_parameter_sets: "Rule parameters sets"    formtastic:      titles:        referential: @@ -140,6 +141,7 @@ fr:          import_tasks: "Imports"          export_tasks: "Exports"          compliance_check_tasks: "Validations" +        rule_parameter_sets: "Jeux de paramètres"    formtastic:      titles:        referential: 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..bcfc04e9a --- /dev/null +++ b/config/locales/vehicle_journey_exports.yml @@ -0,0 +1,52 @@ +en: +  vehicle_journey_exports: +    new: +      title: "Export existing vehicle journey at stops" +      basename: "vehicle_journeys" +    label: +      vehicle_journey_id: "vj id (empty for new vj)" +      number: "number" +      time_table_ids: "timetables" +      flexible_service: "on demand (Y(es)|N(o)|empty for unknown)" +      vehicle_identifier: "vehicle identifier" +      mobility: "wheel_chairs (Y(es)|N(o)|empty for unknown)" +      stop_id: "stop id" +      stop_name: "stop name" +      b_true: "Yes" +      b_false: "No" +      tt_columns: "code;name;tags;start;end;day types;periods;peculiar days;excluded days" +      monday: "Mo" +      tuesday: "Tu" +      wednesday: "We" +      thursday: "Th" +      friday: "Fr" +      saturday: "Sa" +      sunday: "Su" +      vj_filename: "vehicle_journeys_" +      tt_filename: "time_tables" +fr: +  vehicle_journey_exports: +    new: +      title: "Exporter les horaires existants" +      basename: "courses" +    label: +      vehicle_journey_id: "id course (vide si nouvelle)" +      number: "numéro" +      time_table_ids: "calendriers" +      flexible_service: "TAD (O(ui)|N(on)|vide si inconnu)" +      vehicle_identifier: "identifiant véhicule" +      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" +      tt_columns: "code;nom;étiquettes;début;fin;types de jour;périodes;jours particuliers;jours exclus" +      monday: "Lu" +      tuesday: "Ma" +      wednesday: "Me" +      thursday: "Je" +      friday: "Ve" +      saturday: "Sa" +      sunday: "Di" +      vj_filename: "courses_" +      tt_filename: "calendriers" 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/exporters/chouette/kml/exporter_spec.rb b/spec/exporters/chouette/kml/exporter_spec.rb index 2135c0b91..a996b0746 100644 --- a/spec/exporters/chouette/kml/exporter_spec.rb +++ b/spec/exporters/chouette/kml/exporter_spec.rb @@ -28,25 +28,25 @@ describe Chouette::Kml::Exporter do      it "should return a zip file with nothing inside with no objects in arguments" do        subject.export(zip_file_path, {:export_id => 1, :o => "line"} )        File.exists?(zip_file_path).should be_true -      ::Zip::ZipFile.open(zip_file_path).size.should == 6 +      ::Zip::File.open(zip_file_path).size.should == 6      end      it "should return a zip file with 4 kml files" do        subject.export(zip_file_path, {:export_id => 1, :o => "line", :id => "#{line.id}" } )        File.exists?(zip_file_path).should be_true -      ::Zip::ZipFile.open(zip_file_path).size.should == 4 +      ::Zip::File.open(zip_file_path).size.should == 4      end      it "should return a zip file with 6 kml files" do        subject.export(zip_file_path, {:export_id => 1, :o => "line", :id => "#{line.id},#{line2.id}" } )        File.exists?(zip_file_path).should be_true -      ::Zip::ZipFile.open(zip_file_path).size.should == 6 +      ::Zip::File.open(zip_file_path).size.should == 6      end      it "should return a zip file with 6 kml files" do        subject.export(zip_file_path, {:export_id => 1, :o => "", :id => "" } )        File.exists?(zip_file_path).should be_true -      ::Zip::ZipFile.open(zip_file_path).size.should == 6 +      ::Zip::File.open(zip_file_path).size.should == 6      end     end 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..13b59b102 100644 --- a/spec/fixtures/vehicle_journey_imports_valid.csv +++ b/spec/fixtures/vehicle_journey_imports_valid.csv @@ -1,6 +1,12 @@ -"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 +;identifiant véhicule;11;12;13;14 +;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..34fbbb6bb 100644 --- a/spec/fixtures/vehicle_journey_imports_with_vj_invalid.csv +++ b/spec/fixtures/vehicle_journey_imports_with_vj_invalid.csv @@ -1,6 +1,12 @@ -"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;9999;import:VehicleJourney:2;import:VehicleJourney:3 +;numéro;1;2;3 +;identifiant véhicule;11;12;13 +;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..6dc20cfeb 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,12 @@ -"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 +;identifiant véhicule;11;12;13 +;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..c7745849f 100644 --- a/spec/fixtures/vehicle_journey_imports_with_vjas_invalid.csv +++ b/spec/fixtures/vehicle_journey_imports_with_vjas_invalid.csv @@ -1,6 +1,12 @@ -"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 +;identifiant véhicule;11;12;13 +;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_export_spec.rb b/spec/models/vehicle_journey_export_spec.rb new file mode 100644 index 000000000..5ce3b9bfc --- /dev/null +++ b/spec/models/vehicle_journey_export_spec.rb @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe VehicleJourneyExport do +   +  let!(:route) { create(:route) } +  let!(:other_route) { create(:route) } + +  let!(:journey_pattern) { create(:journey_pattern, :route => route) } +  let!(:other_journey_pattern) { create(:journey_pattern_even, :route => route) } + +  let!(:vehicle_journey1) { create(:vehicle_journey_common, :objectid => "export:VehicleJourney:1", :route_id => route.id, :journey_pattern_id => journey_pattern.id) } +  let!(:vehicle_journey2) { create(:vehicle_journey_common, :objectid => "export:VehicleJourney:2", :route_id => route.id, :journey_pattern_id => other_journey_pattern.id) } +  let!(:vehicle_journey3) { create(:vehicle_journey_common, :objectid => "export:VehicleJourney:3", :route_id => route.id, :journey_pattern_id => journey_pattern.id) } +   +  let!(:stop_point0) { route.stop_points[0] } +  let!(:stop_point1) { route.stop_points[1] } +  let!(:stop_point2) { route.stop_points[2] } +  let!(:stop_point3) { route.stop_points[3] } +  let!(:stop_point4) { route.stop_points[4] } + +  let!(:time_table) { create(:time_table)} +   +  subject { VehicleJourneyExport.new(:vehicle_journeys => route.vehicle_journeys, :route => route) }  + +  describe ".tt_day_types" do    + +    it "should return no day_type" do +      time_table.int_day_types = 0 +      expect(subject.tt_day_types(time_table)).to eq("..............") +    end + +    it "should return all days" do +      time_table.int_day_types = 4|8|16|32|64|128|256 +      expect(subject.tt_day_types(time_table)).to eq("LuMaMeJeVeSaDi") +    end +     +  end + +  describe ".tt_periods" do    + +    it "should return empty period" do +      time_table.periods.clear +      expect(subject.tt_periods(time_table)).to eq("") +    end + +    it "should return periods" do +      time_table.periods.clear +      time_table.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,1), :period_end => Date.new(2014,8,8)) +      expect(subject.tt_periods(time_table)).to eq("[2014-08-01 -> 2014-08-08] ") +    end +     +  end +   +  describe ".tt_included_days" do    + +    it "should return empty included dates" do +      time_table.dates.clear +      expect(subject.tt_peculiar_days(time_table)).to eq("") +    end + +    it "should return included date" do +      time_table.dates.clear +      time_table.dates << Chouette::TimeTableDate.new(:date => Date.new(2014,8,1), :in_out => true) +      expect(subject.tt_peculiar_days(time_table)).to eq("2014-08-01 ") +    end +     +  end + +  describe ".tt_excluded_days" do    + +    it "should return empty excluded dates" do +      time_table.dates.clear +      expect(subject.tt_excluded_days(time_table)).to eq("") +    end + +    it "should return excluded date" do +      time_table.dates.clear +      time_table.dates << Chouette::TimeTableDate.new(:date => Date.new(2014,8,1), :in_out => false) +      expect(subject.tt_excluded_days(time_table)).to eq("2014-08-01 ") +    end +     +  end +   +end diff --git a/spec/models/vehicle_journey_import_spec.rb b/spec/models/vehicle_journey_import_spec.rb index 07cd921bb..68f8669e0 100644 --- a/spec/models/vehicle_journey_import_spec.rb +++ b/spec/models/vehicle_journey_import_spec.rb @@ -4,13 +4,22 @@ 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| +      CSV.foreach( Rails.root.join("spec", "fixtures", "#{filename}").to_s , {:col_sep => ";"}) do |row|          if counter == 0 +          row2 = [] +          row.each do |cell| +            cell = vehicle_journey1.id.to_s if cell == "import:VehicleJourney:1"  +            cell = vehicle_journey2.id.to_s if cell == "import:VehicleJourney:2"  +            cell = vehicle_journey3.id.to_s if cell == "import:VehicleJourney:3"  +            row2 << cell +          end +          csv << row2 +        elsif  counter < 7            csv << row          else -          csv << ( row[0] = route.stop_points[counter - 1].id; row)           +          csv << ( row[0] = route.stop_points[counter - 7].id; row)                    end          counter += 1        end @@ -93,14 +102,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/referentials_spec.rb b/spec/requests/referentials_spec.rb index c57192d9b..975248375 100644 --- a/spec/requests/referentials_spec.rb +++ b/spec/requests/referentials_spec.rb @@ -8,7 +8,7 @@ describe "Referentials" do      it "should support no referential" do        visit referentials_path -      page.should have_content("Espace de Données") +      page.should have_content("Espaces de Données")      end      context "when several referentials exist" do 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..68fe04e0b 100644 --- a/spec/requests/vehicle_journey_imports_spec.rb +++ b/spec/requests/vehicle_journey_imports_spec.rb @@ -17,13 +17,22 @@ 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| +      CSV.foreach( Rails.root.join("spec", "fixtures", "#{filename}").to_s , {:col_sep => ";"}) do |row|          if counter == 0 +          row2 = [] +          row.each do |cell| +            cell = "" if cell == "import:VehicleJourney:1"  +            cell = "" if cell == "import:VehicleJourney:2"  +            cell = "" if cell == "import:VehicleJourney:3"  +            row2 << cell +          end +          csv << row2 +        elsif  counter < 7            csv << row          else -          csv << ( row[0] = route.stop_points[counter - 1].id; row)           +          csv << ( row[0] = route.stop_points[counter - 7].id; row)                    end          counter += 1        end @@ -34,7 +43,7 @@ describe "VehicleJourneyImports" do    end    describe "new" do       -    it "should create stop areas and return to stop areas index page" do +    it "should create vehicle journey file and return to route show page" do        visit new_referential_line_route_vehicle_journey_import_path(referential, route.line, route)        attach_file('Fichier', valid_file_path)        click_button "Lancer l'import" | 
