From 42ac1fa61ea79fe612bcd98f2b38bad5b6f24421 Mon Sep 17 00:00:00 2001
From: Zog
Date: Tue, 24 Apr 2018 14:00:17 +0200
Subject: Rework imports to use Resources and make the a little more verbose
---
 app/assets/stylesheets/application.sass            |  3 +
 app/controllers/import_resources_controller.rb     |  9 ++
 app/helpers/exports_helper.rb                      |  2 +-
 app/helpers/imports_helper.rb                      | 24 ++++--
 app/helpers/table_builder_helper.rb                |  6 +-
 app/models/concerns/iev_interfaces/resource.rb     | 20 ++++-
 app/models/import/base.rb                          |  8 ++
 app/models/import/gtfs.rb                          | 36 +++++++-
 app/models/import/netex.rb                         | 53 ++++++++++--
 app/models/import/resource.rb                      | 12 +++
 app/models/import/workbench.rb                     | 10 ++-
 app/models/referential.rb                          |  1 +
 app/views/import_resources/show.html.slim          | 52 ++++++++++++
 app/views/imports/show.html.slim                   | 97 +++++++++++-----------
 .../object_state_updater.rb                        | 17 +++-
 15 files changed, 276 insertions(+), 74 deletions(-)
 create mode 100644 app/views/import_resources/show.html.slim
(limited to 'app')
diff --git a/app/assets/stylesheets/application.sass b/app/assets/stylesheets/application.sass
index 3f8467efe..632ade179 100644
--- a/app/assets/stylesheets/application.sass
+++ b/app/assets/stylesheets/application.sass
@@ -21,3 +21,6 @@
 @import 'modules/import_messages'
 
 @import 'flag-icon'
+
+span.fa + span
+  margin-left: 0.2em
diff --git a/app/controllers/import_resources_controller.rb b/app/controllers/import_resources_controller.rb
index 1535fd171..46f8f0337 100644
--- a/app/controllers/import_resources_controller.rb
+++ b/app/controllers/import_resources_controller.rb
@@ -24,6 +24,15 @@ class ImportResourcesController < ChouetteController
     @import_resources ||= parent.resources
   end
 
+  def resource
+    @import ||= Import::Base.find params[:import_id]
+    @import_resource ||= begin
+      import_resource = Import::Resource.find params[:id]
+      raise ActiveRecord::RecordNotFound unless import_resource.import == @import
+      import_resource
+    end
+  end
+
   private
 
   def decorate_import_resources(import_resources)
diff --git a/app/helpers/exports_helper.rb b/app/helpers/exports_helper.rb
index 2e784ad35..f30a80ed9 100644
--- a/app/helpers/exports_helper.rb
+++ b/app/helpers/exports_helper.rb
@@ -17,7 +17,7 @@ module ExportsHelper
       message.message_attributes["text"]
     else
       t([message.class.name.underscore.gsub('/', '_').pluralize, message.message_key].join('.'), message.message_attributes&.symbolize_keys || {})
-    end
+    end.html_safe
   end
 
   def fields_for_export_task_format(form)
diff --git a/app/helpers/imports_helper.rb b/app/helpers/imports_helper.rb
index 140660153..a297c2521 100644
--- a/app/helpers/imports_helper.rb
+++ b/app/helpers/imports_helper.rb
@@ -2,33 +2,47 @@
 module ImportsHelper
 
   # Import statuses helper
-  def import_status(status)
-    if %w[new running pending].include? status
+  def import_status(status, verbose: false)
+    status = status.to_s.downcase
+    out = if %w[new running pending].include? status
       content_tag :span, '', class: "fa fa-clock-o"
     else
       cls =''
       cls = 'success' if status == 'successful'
+      cls = 'success' if status == 'ok'
       cls = 'warning' if status == 'warning'
-      cls = 'danger' if %w[failed aborted canceled].include? status
+      cls = 'danger' if %w[failed aborted canceled error].include? status
 
       content_tag :span, '', class: "fa fa-circle text-#{cls}"
     end
+    if verbose
+      out += content_tag :span do
+        txt = "imports.status.#{status}".t(fallback: "")
+      end
+    end
+    out
   end
 
   # Compliance check set messages
   def bootstrap_class_for_message_criticity message_criticity
-    case message_criticity
-      when "error"
+    case message_criticity.downcase
+      when "error", "aborted"
         "alert alert-danger"
       when "warning"
         "alert alert-warning"
       when "info"
         "alert alert-info"
+      when "ok", "success"
+        "alert alert-success"
       else
         message_criticity.to_s
     end
   end
 
+  def import_message_content message
+    export_message_content message
+  end
+
   ##############################
   #      TO CLEAN!!!
   ##############################
diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb
index e2aa2e9ea..8c73cb33c 100644
--- a/app/helpers/table_builder_helper.rb
+++ b/app/helpers/table_builder_helper.rb
@@ -153,7 +153,7 @@ module TableBuilderHelper
             i = columns.index(column)
 
             if overhead[i].blank?
-              if (i > 0) && (overhead[i - 1][:width] > 1)
+              if (i > 0) && overhead[i - 1][:width] && (overhead[i - 1][:width] > 1)
                 clsArrayH = overhead[i - 1][:cls].split
 
                 hcont << content_tag(:th, build_column_header(
@@ -225,7 +225,7 @@ module TableBuilderHelper
 
         if column.linkable?
           path = column.link_to(item)
-          link = value.present? && path.present? ? link_to(value, path) : ""
+          link = value.present? && path.present? ? link_to(value, path) : value
 
           if overhead.empty?
             bcont << content_tag(:td, link, title: 'Voir', class: extra_class)
@@ -234,7 +234,7 @@ module TableBuilderHelper
             i = columns.index(column)
 
             if overhead[i].blank?
-              if (i > 0) && (overhead[i - 1][:width] > 1)
+              if (i > 0) && overhead[i - 1][:width] && (overhead[i - 1][:width] > 1)
                 clsArrayAlt = overhead[i - 1][:cls].split
 
                 bcont << content_tag(:td, link, title: 'Voir', class: td_cls(clsArrayAlt, extra_class))
diff --git a/app/models/concerns/iev_interfaces/resource.rb b/app/models/concerns/iev_interfaces/resource.rb
index 7f8c3eefd..254f88a33 100644
--- a/app/models/concerns/iev_interfaces/resource.rb
+++ b/app/models/concerns/iev_interfaces/resource.rb
@@ -4,6 +4,24 @@ module IevInterfaces::Resource
   included do
     extend Enumerize
     enumerize :status, in: %i(OK ERROR WARNING IGNORED), scope: true
-    validates_presence_of :name, :resource_type, :reference
+    validates_presence_of :name, :resource_type
+  end
+
+  def update_status_from_importer importer_status
+    self.update status: status_from_importer(importer_status)
+  end
+
+  def status_from_importer importer_status
+    return nil unless importer_status.present?
+    {
+      new: nil,
+      pending: nil,
+      successful: :OK,
+      warning: :WARNING,
+      failed: :ERROR,
+      running: nil,
+      aborted: :ERROR,
+      canceled: :ERROR
+    }[importer_status.to_sym]
   end
 end
diff --git a/app/models/import/base.rb b/app/models/import/base.rb
index f98e359d4..333fb0f56 100644
--- a/app/models/import/base.rb
+++ b/app/models/import/base.rb
@@ -39,6 +39,14 @@ class Import::Base < ApplicationModel
 
   private
 
+  def failed!
+    update status: :failed
+  end
+
+  def aborted!
+    update status: :aborted
+  end
+
   def initialize_fields
     super
     self.token_download ||= SecureRandom.urlsafe_base64
diff --git a/app/models/import/gtfs.rb b/app/models/import/gtfs.rb
index ceb849bd8..e1bac36a6 100644
--- a/app/models/import/gtfs.rb
+++ b/app/models/import/gtfs.rb
@@ -1,10 +1,28 @@
 class Import::Gtfs < Import::Base
   after_commit :launch_worker, :on => :create
 
+  after_commit do
+    main_resource.update_status_from_importer self.status
+    true
+  end
+
   def launch_worker
     GtfsImportWorker.perform_async id
   end
 
+  def main_resource
+    @resource ||= parent.resources.find_or_create_by(name: self.name, resource_type: "referential", reference: self.name)
+  end
+
+  def notify_parent
+    super
+    main_resource.update_status_from_importer self.status
+  end
+
+  def create_message args
+    main_resource.messages.create args
+  end
+
   def import
     update status: 'running', started_at: Time.now
 
@@ -35,6 +53,7 @@ class Import::Gtfs < Import::Base
       workbench_id: workbench.id,
       metadatas: [referential_metadata]
     )
+    main_resource.update referential: referential
   end
 
   def referential_metadata
@@ -131,17 +150,21 @@ class Import::Gtfs < Import::Base
   end
 
   def import_agencies
+    count = 0
     Chouette::Company.transaction do
       source.agencies.each do |agency|
         company = line_referential.companies.find_or_initialize_by(registration_number: agency.id)
         company.attributes = { name: agency.name }
 
         save_model company
+        count += 1
       end
     end
+    create_message criticity: "info", message_key: "gtfs.agencies.imported", message_attributes: {count: count}
   end
 
   def import_stops
+    count = 0
     Chouette::StopArea.transaction do
       source.stops.each do |stop|
         stop_area = stop_area_referential.stop_areas.find_or_initialize_by(registration_number: stop.id)
@@ -155,11 +178,14 @@ class Import::Gtfs < Import::Base
         # TODO correct default timezone
 
         save_model stop_area
+        count += 1
       end
+      create_message criticity: "info", message_key: "gtfs.stops.imported", message_attributes: {count: count}
     end
   end
 
   def import_routes
+    count = 0
     Chouette::Line.transaction do
       source.routes.each do |route|
         line = line_referential.lines.find_or_initialize_by(registration_number: route.id)
@@ -178,7 +204,9 @@ class Import::Gtfs < Import::Base
         line.url = route.url
 
         save_model line
+        count += 1
       end
+      create_message criticity: "info", message_key: "gtfs.routes.imported", message_attributes: {count: count}
     end
   end
 
@@ -187,6 +215,7 @@ class Import::Gtfs < Import::Base
   end
 
   def import_trips
+    count = 0
     source.trips.each_slice(100) do |slice|
       slice.each do |trip|
         Chouette::Route.transaction do
@@ -205,18 +234,20 @@ class Import::Gtfs < Import::Base
           vehicle_journey = journey_pattern.vehicle_journeys.build route: route
           vehicle_journey.published_journey_name = trip.headsign.presence || trip.id
           save_model vehicle_journey
+          count += 1
 
           time_table = referential.time_tables.find_by(id: time_tables_by_service_id[trip.service_id]) if time_tables_by_service_id[trip.service_id]
           if time_table
             vehicle_journey.time_tables << time_table
           else
-            messages.create! criticity: "warning", message_key: "gtfs.trips.unkown_service_id", message_attributes: {service_id: trip.service_id}
+            create_message criticity: "warning", message_key: "gtfs.trips.unkown_service_id", message_attributes: {service_id: trip.service_id}
           end
 
           vehicle_journey_by_trip_id[trip.id] = vehicle_journey.id
         end
       end
     end
+    create_message criticity: "info", message_key: "gtfs.trips.imported", message_attributes: {count: count}
   end
 
   def import_stop_times
@@ -262,6 +293,7 @@ class Import::Gtfs < Import::Base
   end
 
   def import_calendars
+    count = 0
     source.calendars.each_slice(500) do |slice|
       Chouette::TimeTable.transaction do
         slice.each do |calendar|
@@ -272,11 +304,13 @@ class Import::Gtfs < Import::Base
           time_table.periods.build period_start: calendar.start_date, period_end: calendar.end_date
 
           save_model time_table
+          count += 1
 
           time_tables_by_service_id[calendar.service_id] = time_table.id
         end
       end
     end
+    create_message criticity: "info", message_key: "gtfs.calendars.imported", message_attributes: {count: count}
   end
 
   def import_calendar_dates
diff --git a/app/models/import/netex.rb b/app/models/import/netex.rb
index 49554ee90..e27f1a34c 100644
--- a/app/models/import/netex.rb
+++ b/app/models/import/netex.rb
@@ -4,6 +4,11 @@ class Import::Netex < Import::Base
 
   after_commit :call_iev_callback, on: :create
 
+  after_commit do
+    main_resource.update_status_from_importer self.status
+    true
+  end
+
   before_save do
     self.status = 'aborted' unless referential
     self.referential&.failed! if self.status == 'aborted' || self.status == 'failed'
@@ -11,7 +16,22 @@ class Import::Netex < Import::Base
 
   validates_presence_of :parent
 
+  def main_resource
+    @resource ||= parent.resources.find_or_create_by(name: self.name, resource_type: "referential", reference: self.name)
+  end
+
+  def notify_parent
+    super
+    main_resource.update_status_from_importer self.status
+  end
+
+  def create_message args
+    main_resource.messages.create args
+  end
+
   def create_with_referential!
+    save unless persisted?
+
     self.referential =
       Referential.new(
         name: self.name,
@@ -20,15 +40,35 @@ class Import::Netex < Import::Base
         metadatas: [referential_metadata]
       )
     self.referential.save
-    if self.referential.invalid?
+
+    if self.referential.valid?
+      main_resource.update referential: referential
+      call_iev_callback
+      save!
+    else
       Rails.logger.info "Can't create referential for import #{self.id}: #{referential.inspect} #{referential.metadatas.inspect} #{referential.errors.messages}"
-      if referential.metadatas.all?{|m| m.line_ids.present? && m.line_ids.empty?}
-        parent.messages.create criticity: :error, message_key: "referential_creation_missing_lines", message_attributes: {referential_name: referential.name}
+      aborted!
+      if referential.metadatas.all?{|m| m.line_ids.empty? && m.line_ids.empty?}
+        create_message criticity: :error, message_key: "referential_creation_missing_lines", message_attributes: {referential_name: referential.name}
+      elsif (overlapped_referential_ids = referential.overlapped_referential_ids).any?
+        overlapped = Referential.find overlapped_referential_ids.last
+        create_message(
+          criticity: :error,
+          message_key: "referential_creation_overlapping_existing_referential",
+          message_attributes: {
+            referential_name: referential.name,
+            overlapped_name: overlapped.name,
+            overlapped_url:  Rails.application.routes.url_helpers.referential_path(overlapped)
+          }
+        )
       else
-        parent.messages.create criticity: :error, message_key: "referential_creation", message_attributes: {referential_name: referential.name}
+        create_message(
+          criticity: :error,
+          message_key: "referential_creation",
+          message_attributes: {referential_name: referential.name},
+          resource_attributes: referential.errors.messages
+        )
       end
-    else
-      save!
     end
   end
 
@@ -55,6 +95,7 @@ class Import::Netex < Import::Base
         metadata.periodes = frame.periods
 
         line_objectids = frame.line_refs.map { |ref| "STIF:CODIFLIGNE:Line:#{ref}" }
+        create_message criticity: :info, message_key: "referential_creation_lines_found", message_attributes: {line_objectids: line_objectids.to_sentence}
         metadata.line_ids = workbench.lines.where(objectid: line_objectids).pluck(:id)
       end
     end
diff --git a/app/models/import/resource.rb b/app/models/import/resource.rb
index 1951daacd..e6de935ae 100644
--- a/app/models/import/resource.rb
+++ b/app/models/import/resource.rb
@@ -4,5 +4,17 @@ class Import::Resource < ApplicationModel
   include IevInterfaces::Resource
 
   belongs_to :import, class_name: Import::Base
+  belongs_to :referential
   has_many :messages, class_name: "Import::Message", foreign_key: :resource_id
+
+  def root_import
+    import = self.import
+    import = import.parent while import.parent
+    import
+  end
+
+  def netex_import
+    return unless self.resource_type == "referential"
+    import.children.where(name: self.reference).last
+  end
 end
diff --git a/app/models/import/workbench.rb b/app/models/import/workbench.rb
index 124b9b0d8..95d23fe5b 100644
--- a/app/models/import/workbench.rb
+++ b/app/models/import/workbench.rb
@@ -9,14 +9,18 @@ class Import::Workbench < Import::Base
     end
   end
 
+  # def main_resource
+  #   @resource ||= resources.find_or_create_by(name: self.name, resource_type: "workbench_import")
+  # end
+
   def import_gtfs
     update_column :status, 'running'
     update_column :started_at, Time.now
 
-    Import::Gtfs.create! parent_id: self.id, workbench: workbench, file: File.new(file.path), name: "Import GTFS", creator: "Web service"
+    Import::Gtfs.create! parent_type: self.class.name, parent_id: self.id, workbench: workbench, file: File.new(file.path), name: "Import GTFS", creator: "Web service"
 
-    update_column :status, 'successful'
-    update_column :ended_at, Time.now
+    # update_column :status, 'successful'
+    # update_column :ended_at, Time.now
   rescue Exception => e
     Rails.logger.error "Error while processing GTFS file: #{e}"
 
diff --git a/app/models/referential.rb b/app/models/referential.rb
index 792353a73..76b3bd84d 100644
--- a/app/models/referential.rb
+++ b/app/models/referential.rb
@@ -26,6 +26,7 @@ class Referential < ApplicationModel
 
   has_one :user
   has_many :api_keys, class_name: 'Api::V1::ApiKey', dependent: :destroy
+  has_many :import_resources, class_name: 'Import::Resource', dependent: :destroy
 
   belongs_to :organisation
   validates_presence_of :organisation
diff --git a/app/views/import_resources/show.html.slim b/app/views/import_resources/show.html.slim
new file mode 100644
index 000000000..7fd8b4456
--- /dev/null
+++ b/app/views/import_resources/show.html.slim
@@ -0,0 +1,52 @@
+- breadcrumb :import_resource, @import_resource
+
+.page_content.import_messages
+  .container-fluid
+    .row
+      .col-lg-12
+        - metadata = { 'Bilan d\'import' => link_to(@import_resource.root_import.name, workbench_import_path(@import_resource.root_import.workbench, @import_resource.root_import) ),
+            'Jeu de données associé' => ( @import_resource.referential.present? ? link_to(@import_resource.referential.name, referential_path(@import_resource.referential)) : '-' ) }
+        - metadata = metadata.update({t('.status') => import_status(@import_resource.status, verbose: true) })
+        = definition_list t('metadatas'), metadata
+
+
+      .col-lg-12
+        .error_messages
+          = render 'shared/iev_interfaces/messages', messages: @import_resource.messages
+
+
+      // XXX
+      //- if @import_resource.children.present?
+      - if @import_resource&.netex_import&.resources.present?
+        .col-lg-12
+          h2 = t('.table_title')
+        .col-lg-12
+          = t('.table_explanation')
+        .col-lg-12
+          = table_builder_2 @import_resource.netex_import.resources.where(resource_type: :file),
+            [ \
+              TableBuilderHelper::Column.new( \
+                key: :name, \
+                attribute: 'name', \
+                sortable: false, \
+              ), \
+              TableBuilderHelper::Column.new( \
+                key: :status, \
+                attribute: Proc.new { |n| import_resource_status(n.status) }, \
+                sortable: false, \
+              ), \
+              TableBuilderHelper::Column.new( \
+                name: 'Résultat des tests' , \
+                attribute: Proc.new { |n| I18n.t('import_resources.index.metrics', n.metrics.deep_symbolize_keys) }, \
+                sortable: false, \
+              ), \
+              TableBuilderHelper::Column.new( \
+                name: 'Téléchargement' , \
+                attribute: Proc.new { |n| ''.html_safe }, \
+                sortable: false, \
+                link_to: lambda do |import_resource| \
+                  workbench_import_import_resource_import_messages_path(import_resource.import.workbench, import_resource.import, import_resource, format: 'csv' ) \
+                end \
+              ), \
+            ],
+            cls: 'table has-search'
diff --git a/app/views/imports/show.html.slim b/app/views/imports/show.html.slim
index 9d0a6423d..99458c7fe 100644
--- a/app/views/imports/show.html.slim
+++ b/app/views/imports/show.html.slim
@@ -6,55 +6,52 @@
   .container-fluid
     .row
       .col-lg-6.col-md-6.col-sm-12.col-xs-12
-        = definition_list t('metadatas'), { t('.data_recovery') => '-', t('.filename') => @import.try(:file_identifier)}
+        - metadata = { t('.data_recovery') => '-', t('.filename') => @import.try(:file_identifier)}
+        - metadata = metadata.update({t('.status') => import_status(@import.status, verbose: true) })
+        = definition_list t('metadatas'), metadata
 
-    .row
-      .col-lg-12
-        .error_messages
-          = render 'shared/iev_interfaces/messages', messages: @import.messages
+    .col-lg-12
+      .error_messages
+        = render 'shared/iev_interfaces/messages', messages: @import.messages
 
-    - if @import.children.any?
-      .row
-        .col-lg-12
-          = table_builder_2 @import.children,
-            [ \
-              TableBuilderHelper::Column.new( \
-                name: t('.referential_name'), \
-                attribute: 'name', \
-                sortable: false, \
-                link_to: lambda do |import| \
-                  referential_path(import.referential) if import.referential.present? \
-                end \
-              ), \
-              TableBuilderHelper::Column.new( \
-                key: :status, \
-                attribute: Proc.new { |n| import_status(n.status) }, \
-                sortable: false, \
-                link_to: lambda do |import| \
-                  workbench_import_import_resources_path(import.workbench_id, import) \
-                end \
-              ), \
-              TableBuilderHelper::Column.new( \
-                name: t('.stif_control'), \
-                attribute: '', \
-                sortable: false, \
-              ), \
-              TableBuilderHelper::Column.new( \
-                name: t('.organisation_control'), \
-                attribute: '', \
-                sortable: false, \
-              ) \
-            ],
-            cls: 'table',
-            overhead: [ \
-              {}, \
-              { \
-                title: I18n.t('imports.show.results', count: @import.children_succeedeed, total: @import.children.count), \
-                width: 1, \
-                cls: "#{@import.import_status_css_class} full-border" \
-              }, { \
-                title: I18n.t('imports.show.summary').html_safe, \
-                width: 2, \
-                cls: 'overheaded-default colspan="2"' \
-              } \
-            ]
+    - if @import.resources.any?
+      .col-lg-12
+        = table_builder_2 @import.resources,
+          [ \
+            TableBuilderHelper::Column.new( \
+              name: t('.referential_name'), \
+              attribute: 'name', \
+              sortable: false, \
+              link_to: lambda do |item| \
+                referential_path(item.referential) if item.referential.present? \
+              end \
+            ), \
+            TableBuilderHelper::Column.new( \
+              key: :status, \
+              attribute: Proc.new { |n| import_status(n.status) }, \
+              sortable: false, \
+              link_to: lambda do |item| \
+                workbench_import_import_resource_path(@import.workbench_id, @import, item) \
+              end \
+            ), \
+            TableBuilderHelper::Column.new( \
+              name: t('.stif_control'), \
+              attribute: '', \
+              sortable: false, \
+            ), \
+            TableBuilderHelper::Column.new( \
+              name: t('.organisation_control'), \
+              attribute: '', \
+              sortable: false, \
+            ) \
+          ],
+          cls: 'table',
+          overhead: [ \
+            {}, \
+            {}, \
+            { \
+              title: I18n.t('imports.show.summary').html_safe, \
+              width: 2, \
+              cls: 'overheaded-default colspan="2"' \
+            } \
+          ]
diff --git a/app/workers/workbench_import_worker/object_state_updater.rb b/app/workers/workbench_import_worker/object_state_updater.rb
index 1edc6b9a1..39d5f20b1 100644
--- a/app/workers/workbench_import_worker/object_state_updater.rb
+++ b/app/workers/workbench_import_worker/object_state_updater.rb
@@ -2,6 +2,11 @@
 class WorkbenchImportWorker
   module ObjectStateUpdater
 
+    def resource entry
+      @_resources ||= {}
+      @_resources[entry.name] ||= workbench_import.resources.find_or_create_by(name: entry.name, resource_type: "referential")
+    end
+
     def update_object_state entry, count
       workbench_import.update( total_steps: count )
       update_spurious entry
@@ -14,44 +19,48 @@ class WorkbenchImportWorker
 
     def update_foreign_lines entry
       return if entry.foreign_lines.empty?
-      workbench_import.messages.create(
+      resource(entry).messages.create(
         criticity: :error,
         message_key: 'foreign_lines_in_referential',
         message_attributes: {
           'source_filename' => workbench_import.file.file.file,
           'foreign_lines'   => entry.foreign_lines.join(', ')
         })
+      resource(entry).update status: :ERROR
     end
 
     def update_spurious entry
       return if entry.spurious.empty?
-      workbench_import.messages.create(
+      resource(entry).messages.create(
         criticity: :error,
         message_key: 'inconsistent_zip_file',
         message_attributes: {
           'source_filename' => workbench_import.file.file.file,
           'spurious_dirs'   => entry.spurious.join(', ')
         })
+      resource(entry).update status: :ERROR
     end
 
     def update_missing_calendar entry
       return unless entry.missing_calendar
-      workbench_import.messages.create(
+      resource(entry).messages.create(
         criticity: :error,
         message_key: 'missing_calendar_in_zip_file',
         message_attributes: {
           'source_filename' => entry.name
         })
+      resource(entry).update status: :ERROR
     end
 
     def update_wrong_calendar entry
       return unless entry.wrong_calendar
-      workbench_import.messages.create(
+      resource(entry).messages.create(
         criticity: :error,
         message_key: 'wrong_calendar_in_zip_file',
         message_attributes: {
           'source_filename' => entry.name
         })
+      resource(entry).update status: :ERROR
     end
   end
 end
-- 
cgit v1.2.3
From 657fea85b193fb9908dcaa42391bec230e93d857 Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 30 Apr 2018 07:12:49 +0200
Subject: Fix NETEX imports
---
 app/models/import/base.rb                     |  1 +
 app/models/import/gtfs.rb                     |  3 +-
 app/models/import/netex.rb                    |  7 ++--
 app/views/imports/import/_netex.html.slim     | 43 ++++++++++++++++++++++
 app/views/imports/import/_workbench.html.slim | 51 ++++++++++++++++++++++++++
 app/views/imports/show.html.slim              | 52 +--------------------------
 6 files changed, 101 insertions(+), 56 deletions(-)
 create mode 100644 app/views/imports/import/_netex.html.slim
 create mode 100644 app/views/imports/import/_workbench.html.slim
(limited to 'app')
diff --git a/app/models/import/base.rb b/app/models/import/base.rb
index 333fb0f56..606c39974 100644
--- a/app/models/import/base.rb
+++ b/app/models/import/base.rb
@@ -44,6 +44,7 @@ class Import::Base < ApplicationModel
   end
 
   def aborted!
+    Rails.logger.info "=== aborted ==="
     update status: :aborted
   end
 
diff --git a/app/models/import/gtfs.rb b/app/models/import/gtfs.rb
index e1bac36a6..4f0dde9d1 100644
--- a/app/models/import/gtfs.rb
+++ b/app/models/import/gtfs.rb
@@ -28,10 +28,11 @@ class Import::Gtfs < Import::Base
 
     import_without_status
     update status: 'successful', ended_at: Time.now
-    referential&.ready!
+    referential&.active!
   rescue Exception => e
     update status: 'failed', ended_at: Time.now
     Rails.logger.error "Error in GTFS import: #{e} #{e.backtrace.join('\n')}"
+    create_message criticity: :error, message_key: :full_text, message_attributes: {text: e.message}
     referential&.failed!
   ensure
     notify_parent
diff --git a/app/models/import/netex.rb b/app/models/import/netex.rb
index e27f1a34c..f64a18e98 100644
--- a/app/models/import/netex.rb
+++ b/app/models/import/netex.rb
@@ -2,15 +2,12 @@ require 'net/http'
 class Import::Netex < Import::Base
   before_destroy :destroy_non_ready_referential
 
-  after_commit :call_iev_callback, on: :create
-
   after_commit do
     main_resource.update_status_from_importer self.status
     true
   end
 
   before_save do
-    self.status = 'aborted' unless referential
     self.referential&.failed! if self.status == 'aborted' || self.status == 'failed'
   end
 
@@ -47,7 +44,7 @@ class Import::Netex < Import::Base
       save!
     else
       Rails.logger.info "Can't create referential for import #{self.id}: #{referential.inspect} #{referential.metadatas.inspect} #{referential.errors.messages}"
-      aborted!
+
       if referential.metadatas.all?{|m| m.line_ids.empty? && m.line_ids.empty?}
         create_message criticity: :error, message_key: "referential_creation_missing_lines", message_attributes: {referential_name: referential.name}
       elsif (overlapped_referential_ids = referential.overlapped_referential_ids).any?
@@ -69,6 +66,8 @@ class Import::Netex < Import::Base
           resource_attributes: referential.errors.messages
         )
       end
+      self.referential = nil
+      aborted!
     end
   end
 
diff --git a/app/views/imports/import/_netex.html.slim b/app/views/imports/import/_netex.html.slim
new file mode 100644
index 000000000..5542e389f
--- /dev/null
+++ b/app/views/imports/import/_netex.html.slim
@@ -0,0 +1,43 @@
+.row
+  .col-lg-6.col-md-6.col-sm-12.col-xs-12
+    - metadata = { t('.parent') => link_to(@import.parent.name, [@import.parent.workbench, @import.parent]) }
+    - metadata = metadata.update({t('.status') => import_status(@import.status, verbose: true) })
+    = definition_list t('metadatas'), metadata
+
+.col-lg-12
+  .error_messages
+    = render 'shared/iev_interfaces/messages', messages: @import.main_resource.messages
+
+- if @import.resources.present?
+  .col-lg-12
+    h2 = t('.table_title')
+  .col-lg-12
+    = t('.table_explanation')
+  .col-lg-12
+    = table_builder_2 @import.resources.where(resource_type: :file),
+      [ \
+        TableBuilderHelper::Column.new( \
+          key: :name, \
+          attribute: 'name', \
+          sortable: false, \
+        ), \
+        TableBuilderHelper::Column.new( \
+          key: :status, \
+          attribute: Proc.new { |n| import_resource_status(n.status) }, \
+          sortable: false, \
+        ), \
+        TableBuilderHelper::Column.new( \
+          name: 'Résultat des tests' , \
+          attribute: Proc.new { |n| I18n.t('import_resources.index.metrics', n.metrics.deep_symbolize_keys) }, \
+          sortable: false, \
+        ), \
+        TableBuilderHelper::Column.new( \
+          name: 'Téléchargement' , \
+          attribute: Proc.new { |n| ''.html_safe }, \
+          sortable: false, \
+          link_to: lambda do |import_resource| \
+            workbench_import_import_resource_import_messages_path(import_resource.import.workbench, import_resource.import, import_resource, format: 'csv' ) \
+          end \
+        ), \
+      ],
+      cls: 'table has-search'
diff --git a/app/views/imports/import/_workbench.html.slim b/app/views/imports/import/_workbench.html.slim
new file mode 100644
index 000000000..d384cbbe2
--- /dev/null
+++ b/app/views/imports/import/_workbench.html.slim
@@ -0,0 +1,51 @@
+.row
+  .col-lg-6.col-md-6.col-sm-12.col-xs-12
+    - metadata = { t('.data_recovery') => '-', t('.filename') => @import.try(:file_identifier)}
+    - metadata = metadata.update({t('.status') => import_status(@import.status, verbose: true) })
+    = definition_list t('metadatas'), metadata
+
+.col-lg-12
+  .error_messages
+    = render 'shared/iev_interfaces/messages', messages: @import.messages
+
+- if @import.resources.any?
+  .col-lg-12
+    = table_builder_2 @import.resources,
+      [ \
+        TableBuilderHelper::Column.new( \
+          name: t('.referential_name'), \
+          attribute: 'name', \
+          sortable: false, \
+          link_to: lambda do |item| \
+            referential_path(item.referential) if item.referential.present? \
+          end \
+        ), \
+        TableBuilderHelper::Column.new( \
+          key: :status, \
+          attribute: Proc.new { |n| import_status(n.status) }, \
+          sortable: false, \
+          link_to: lambda do |item| \
+            item.netex_import.present? ? [@import.workbench, item.netex_import] : [@import.workbench, @import, item] \
+          end \
+        ), \
+        TableBuilderHelper::Column.new( \
+          name: t('.stif_control'), \
+          attribute: '', \
+          sortable: false, \
+        ), \
+        TableBuilderHelper::Column.new( \
+          name: t('.organisation_control'), \
+          attribute: '', \
+          sortable: false, \
+        ) \
+      ],
+      cls: 'table',
+      overhead: [ \
+        {}, \
+        {}, \
+        { \
+          title: I18n.t('imports.show.summary').html_safe, \
+          width: 2, \
+          cls: 'overheaded-default colspan="2"' \
+        } \
+      ]
diff --git a/app/views/imports/show.html.slim b/app/views/imports/show.html.slim
index 99458c7fe..10552129d 100644
--- a/app/views/imports/show.html.slim
+++ b/app/views/imports/show.html.slim
@@ -4,54 +4,4 @@
 
 .page_content
   .container-fluid
-    .row
-      .col-lg-6.col-md-6.col-sm-12.col-xs-12
-        - metadata = { t('.data_recovery') => '-', t('.filename') => @import.try(:file_identifier)}
-        - metadata = metadata.update({t('.status') => import_status(@import.status, verbose: true) })
-        = definition_list t('metadatas'), metadata
-
-    .col-lg-12
-      .error_messages
-        = render 'shared/iev_interfaces/messages', messages: @import.messages
-
-    - if @import.resources.any?
-      .col-lg-12
-        = table_builder_2 @import.resources,
-          [ \
-            TableBuilderHelper::Column.new( \
-              name: t('.referential_name'), \
-              attribute: 'name', \
-              sortable: false, \
-              link_to: lambda do |item| \
-                referential_path(item.referential) if item.referential.present? \
-              end \
-            ), \
-            TableBuilderHelper::Column.new( \
-              key: :status, \
-              attribute: Proc.new { |n| import_status(n.status) }, \
-              sortable: false, \
-              link_to: lambda do |item| \
-                workbench_import_import_resource_path(@import.workbench_id, @import, item) \
-              end \
-            ), \
-            TableBuilderHelper::Column.new( \
-              name: t('.stif_control'), \
-              attribute: '', \
-              sortable: false, \
-            ), \
-            TableBuilderHelper::Column.new( \
-              name: t('.organisation_control'), \
-              attribute: '', \
-              sortable: false, \
-            ) \
-          ],
-          cls: 'table',
-          overhead: [ \
-            {}, \
-            {}, \
-            { \
-              title: I18n.t('imports.show.summary').html_safe, \
-              width: 2, \
-              cls: 'overheaded-default colspan="2"' \
-            } \
-          ]
+    = render partial: "imports/#{@import.type.tableize.singularize}"
-- 
cgit v1.2.3
From 7b336d1e47164a15c273f0899e8710e4fee273f8 Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 30 Apr 2018 09:15:54 +0200
Subject: Trigger compliance checks after imports
---
 app/controllers/imports_controller.rb         |  9 +++++-
 app/helpers/imports_helper.rb                 |  1 +
 app/models/compliance_check_set.rb            |  5 ++++
 app/models/concerns/iev_interfaces/task.rb    | 11 +++++--
 app/models/import/base.rb                     |  9 ++++--
 app/models/import/netex.rb                    | 10 +++++--
 app/models/import/resource.rb                 | 42 +++++++++++++++++++++++++++
 app/models/workbench.rb                       |  4 +++
 app/models/workgroup.rb                       |  5 ++++
 app/views/imports/import/_netex.html.slim     |  1 +
 app/views/imports/import/_workbench.html.slim | 10 +++++--
 11 files changed, 97 insertions(+), 10 deletions(-)
(limited to 'app')
diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb
index 8d7a723a0..b98d7da8d 100644
--- a/app/controllers/imports_controller.rb
+++ b/app/controllers/imports_controller.rb
@@ -4,6 +4,7 @@ class ImportsController < ChouetteController
   include IevInterfaces
   skip_before_action :authenticate_user!, only: [:download]
   defaults resource_class: Import::Base, collection_name: 'imports', instance_name: 'import'
+  before_action :notify_parents
 
   def download
     if params[:token] == resource.token_download
@@ -18,7 +19,7 @@ class ImportsController < ChouetteController
   def index_model
     Import::Workbench
   end
-  
+
   def build_resource
     @import ||= Import::Workbench.new(*resource_params) do |import|
       import.workbench = parent
@@ -43,4 +44,10 @@ class ImportsController < ChouetteController
       }
     )
   end
+
+  def notify_parents
+    if Rails.env.development?
+      ParentNotifier.new(Import::Base).notify_when_finished
+    end
+  end
 end
diff --git a/app/helpers/imports_helper.rb b/app/helpers/imports_helper.rb
index a297c2521..341f87037 100644
--- a/app/helpers/imports_helper.rb
+++ b/app/helpers/imports_helper.rb
@@ -3,6 +3,7 @@ module ImportsHelper
 
   # Import statuses helper
   def import_status(status, verbose: false)
+    return "" unless status
     status = status.to_s.downcase
     out = if %w[new running pending].include? status
       content_tag :span, '', class: "fa fa-clock-o"
diff --git a/app/models/compliance_check_set.rb b/app/models/compliance_check_set.rb
index 8b1dbdd68..eb0e23d82 100644
--- a/app/models/compliance_check_set.rb
+++ b/app/models/compliance_check_set.rb
@@ -68,6 +68,11 @@ class ComplianceCheckSet < ApplicationModel
     end
 
     update attributes
+    import_resource&.next_step
+  end
+
+  def import_resource
+    referential&.import_resources.main_resources.last
   end
 
 
diff --git a/app/models/concerns/iev_interfaces/task.rb b/app/models/concerns/iev_interfaces/task.rb
index 6be33734b..3e4dd52ca 100644
--- a/app/models/concerns/iev_interfaces/task.rb
+++ b/app/models/concerns/iev_interfaces/task.rb
@@ -56,13 +56,14 @@ module IevInterfaces::Task
   end
 
   def notify_parent
-    return unless self.class.finished_statuses.include?(status)
+    return false unless self.class.finished_statuses.include?(status)
 
-    return unless parent.present?
-    return if notified_parent_at
+    return false unless parent.present?
+    return false if notified_parent_at
     parent.child_change
 
     update_column :notified_parent_at, Time.now
+    true
   end
 
   def children_succeedeed
@@ -94,6 +95,10 @@ module IevInterfaces::Task
     update attributes
   end
 
+  def successful?
+    status.to_s == "successful"
+  end
+
   def child_change
     return if self.class.finished_statuses.include?(status)
     update_status
diff --git a/app/models/import/base.rb b/app/models/import/base.rb
index 606c39974..baa25c3df 100644
--- a/app/models/import/base.rb
+++ b/app/models/import/base.rb
@@ -32,8 +32,13 @@ class Import::Base < ApplicationModel
     Rails.logger.info "update_referentials for #{inspect}"
     return unless self.class.finished_statuses.include?(status)
 
-    children.each do |import|
-      import.referential.update(ready: true) if import.referential
+    # We treat all created referentials in a batch
+    # If a single fails, we consider they all failed
+    # Ohana means family !
+    if self.successful?
+      children.map(&:referential).compact.each &:active!
+    else
+      children.map(&:referential).compact.each &:failed!
     end
   end
 
diff --git a/app/models/import/netex.rb b/app/models/import/netex.rb
index f64a18e98..b4422328c 100644
--- a/app/models/import/netex.rb
+++ b/app/models/import/netex.rb
@@ -18,8 +18,14 @@ class Import::Netex < Import::Base
   end
 
   def notify_parent
-    super
-    main_resource.update_status_from_importer self.status
+    if super
+      main_resource.update_status_from_importer self.status
+      next_step
+    end
+  end
+
+  def next_step
+    main_resource.next_step
   end
 
   def create_message args
diff --git a/app/models/import/resource.rb b/app/models/import/resource.rb
index e6de935ae..27dc367a8 100644
--- a/app/models/import/resource.rb
+++ b/app/models/import/resource.rb
@@ -7,14 +7,56 @@ class Import::Resource < ApplicationModel
   belongs_to :referential
   has_many :messages, class_name: "Import::Message", foreign_key: :resource_id
 
+  scope :main_resources, ->{ where(resource_type: "referential") }
+
   def root_import
     import = self.import
     import = import.parent while import.parent
     import
   end
 
+  def next_step
+    if root_import.class == Import::Workbench
+
+      # XXX
+      # return unless netex_import&.successful?
+
+      if workbench.import_compliance_control_set_id.present? && workbench_import_control_set.nil?
+        ComplianceControlSetCopyWorker.perform_async workbench.import_compliance_control_set_id, referential_id
+        return
+      end
+
+      # XXX
+      # return if workbench_import_control_set && !workbench_import_control_set.successful?
+
+      if workgroup.import_compliance_control_set_id.present? && workgroup_import_control_set.nil?
+        ComplianceControlSetCopyWorker.perform_async workgroup.import_compliance_control_set_id, referential_id
+      end
+    end
+  end
+
+  def workbench
+    import.workbench
+  end
+
+  def workgroup
+    workbench.workgroup
+  end
+
   def netex_import
     return unless self.resource_type == "referential"
     import.children.where(name: self.reference).last
   end
+
+  def workbench_import_control_set
+    return unless referential.present?
+    return unless referential.workbench.import_compliance_control_set_id.present?
+    referential.compliance_check_sets.where(compliance_control_set_id: referential.workbench.import_compliance_control_set_id, referential_id: referential_id).last
+  end
+
+  def workgroup_import_control_set
+    return unless referential.present?
+    return unless referential.workbench.workgroup.import_compliance_control_set_id.present?
+    referential.compliance_check_sets.where(compliance_control_set_id: referential.workbench.workgroup.import_compliance_control_set_id, referential_id: referential_id).last
+  end
 end
diff --git a/app/models/workbench.rb b/app/models/workbench.rb
index 1c54e8904..14406c9f4 100644
--- a/app/models/workbench.rb
+++ b/app/models/workbench.rb
@@ -51,6 +51,10 @@ class Workbench < ApplicationModel
     where(name: DEFAULT_WORKBENCH_NAME).last
   end
 
+  def import_compliance_control_set
+    ComplianceControlSet.find(import_compliance_control_set_id)
+  end
+
   private
 
   def initialize_output
diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb
index 3e8409634..9ae5e564d 100644
--- a/app/models/workgroup.rb
+++ b/app/models/workgroup.rb
@@ -23,4 +23,9 @@ class Workgroup < ApplicationModel
   def has_export? export_name
     export_types.include? export_name
   end
+
+  def import_compliance_control_set_id
+    # XXX
+    1
+  end
 end
diff --git a/app/views/imports/import/_netex.html.slim b/app/views/imports/import/_netex.html.slim
index 5542e389f..2f341016a 100644
--- a/app/views/imports/import/_netex.html.slim
+++ b/app/views/imports/import/_netex.html.slim
@@ -2,6 +2,7 @@
   .col-lg-6.col-md-6.col-sm-12.col-xs-12
     - metadata = { t('.parent') => link_to(@import.parent.name, [@import.parent.workbench, @import.parent]) }
     - metadata = metadata.update({t('.status') => import_status(@import.status, verbose: true) })
+    - metadata = metadata.update({t('.referential') => @import.referential ? link_to(@import.referential.name, [@import.referential]) : "-" })
     = definition_list t('metadatas'), metadata
 
 .col-lg-12
diff --git a/app/views/imports/import/_workbench.html.slim b/app/views/imports/import/_workbench.html.slim
index d384cbbe2..cec5d837c 100644
--- a/app/views/imports/import/_workbench.html.slim
+++ b/app/views/imports/import/_workbench.html.slim
@@ -30,13 +30,19 @@
         ), \
         TableBuilderHelper::Column.new( \
           name: t('.stif_control'), \
-          attribute: '', \
+          attribute: Proc.new { |n| import_status(n.workbench_import_control_set&.status) }, \
           sortable: false, \
+          link_to: lambda do |item| \
+            item.workbench_import_control_set.present? && [@import.workbench, item.workbench_import_control_set] \
+          end \
         ), \
         TableBuilderHelper::Column.new( \
           name: t('.organisation_control'), \
-          attribute: '', \
+          attribute: Proc.new { |n| import_status(n.workgroup_import_control_set&.status) }, \
           sortable: false, \
+          link_to: lambda do |item| \
+            item.workgroup_import_control_set.present? && [@import.workbench, item.workgroup_import_control_set] \
+          end \
         ) \
       ],
       cls: 'table',
-- 
cgit v1.2.3
From f0bbc8d002f845efe0bfecf37477e96c84a6b41c Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 30 Apr 2018 09:28:33 +0200
Subject: Ignore failed Referentials when looking for duplicates
---
 app/models/referential.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'app')
diff --git a/app/models/referential.rb b/app/models/referential.rb
index 76b3bd84d..0c6e71d47 100644
--- a/app/models/referential.rb
+++ b/app/models/referential.rb
@@ -399,7 +399,7 @@ class Referential < ApplicationModel
 
     query = "select distinct(public.referential_metadata.referential_id) FROM public.referential_metadata, unnest(line_ids) line, LATERAL unnest(periodes) period
     WHERE public.referential_metadata.referential_id
-    IN (SELECT public.referentials.id FROM public.referentials WHERE referentials.workbench_id = #{workbench_id} and referentials.archived_at is null and referentials.referential_suite_id is null #{not_myself})
+    IN (SELECT public.referentials.id FROM public.referentials WHERE referentials.workbench_id = #{workbench_id} and referentials.archived_at is null and referentials.referential_suite_id is null #{not_myself} AND referentials.failed_at IS NULL)
     AND line in (#{line_ids.join(',')}) and (#{periods_query});"
 
     self.class.connection.select_values(query).map(&:to_i)
-- 
cgit v1.2.3
From af49fd1021ee6b22fd8ca6c6592c5f7d64c23aa0 Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 30 Apr 2018 14:22:53 +0200
Subject: Better views
---
 app/helpers/imports_helper.rb                  |  5 ++--
 app/models/import/resource.rb                  |  6 ++--
 app/models/workbench.rb                        |  2 +-
 app/models/workgroup.rb                        |  6 +++-
 app/views/compliance_check_sets/show.html.slim |  1 +
 app/views/imports/import/_workbench.html.slim  | 41 ++++++++++++++------------
 6 files changed, 34 insertions(+), 27 deletions(-)
(limited to 'app')
diff --git a/app/helpers/imports_helper.rb b/app/helpers/imports_helper.rb
index 341f87037..f06d77eca 100644
--- a/app/helpers/imports_helper.rb
+++ b/app/helpers/imports_helper.rb
@@ -2,8 +2,9 @@
 module ImportsHelper
 
   # Import statuses helper
-  def import_status(status, verbose: false)
-    return "" unless status
+  def import_status(status, verbose: false, default_status: nil)
+    status ||= default_status
+    return unless status
     status = status.to_s.downcase
     out = if %w[new running pending].include? status
       content_tag :span, '', class: "fa fa-clock-o"
diff --git a/app/models/import/resource.rb b/app/models/import/resource.rb
index 27dc367a8..2c7889240 100644
--- a/app/models/import/resource.rb
+++ b/app/models/import/resource.rb
@@ -18,16 +18,14 @@ class Import::Resource < ApplicationModel
   def next_step
     if root_import.class == Import::Workbench
 
-      # XXX
-      # return unless netex_import&.successful?
+      return unless netex_import&.successful?
 
       if workbench.import_compliance_control_set_id.present? && workbench_import_control_set.nil?
         ComplianceControlSetCopyWorker.perform_async workbench.import_compliance_control_set_id, referential_id
         return
       end
 
-      # XXX
-      # return if workbench_import_control_set && !workbench_import_control_set.successful?
+      return if workbench_import_control_set && !workbench_import_control_set.successful?
 
       if workgroup.import_compliance_control_set_id.present? && workgroup_import_control_set.nil?
         ComplianceControlSetCopyWorker.perform_async workgroup.import_compliance_control_set_id, referential_id
diff --git a/app/models/workbench.rb b/app/models/workbench.rb
index 14406c9f4..d99197b47 100644
--- a/app/models/workbench.rb
+++ b/app/models/workbench.rb
@@ -52,7 +52,7 @@ class Workbench < ApplicationModel
   end
 
   def import_compliance_control_set
-    ComplianceControlSet.find(import_compliance_control_set_id)
+    import_compliance_control_set_id && ComplianceControlSet.find(import_compliance_control_set_id)
   end
 
   private
diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb
index 9ae5e564d..6a1746eb8 100644
--- a/app/models/workgroup.rb
+++ b/app/models/workgroup.rb
@@ -26,6 +26,10 @@ class Workgroup < ApplicationModel
 
   def import_compliance_control_set_id
     # XXX
-    1
+    nil
+  end
+
+  def import_compliance_control_set
+    import_compliance_control_set_id && ComplianceControlSet.find(import_compliance_control_set_id)
   end
 end
diff --git a/app/views/compliance_check_sets/show.html.slim b/app/views/compliance_check_sets/show.html.slim
index 4e1a8e2f9..bf4642b21 100644
--- a/app/views/compliance_check_sets/show.html.slim
+++ b/app/views/compliance_check_sets/show.html.slim
@@ -9,6 +9,7 @@
         = definition_list( t('metadatas'),
           { I18n.t("compliance_check_sets.show.metadatas.referential") => (@compliance_check_set.referential.nil? ? '' : link_to(@compliance_check_set.referential.name, referential_path(@compliance_check_set.referential)) ),
             I18n.t("compliance_check_sets.show.metadatas.referential_type") => 'Jeu de données',
+            I18n.t("compliance_check_sets.show.metadatas.status") => import_status(@compliance_check_set.status, verbose: true),
             I18n.t("compliance_check_sets.show.metadatas.compliance_check_set_executed") => link_to(@compliance_check_set.name, executed_workbench_compliance_check_set_path(@compliance_check_set.workbench_id, @compliance_check_set)),
             I18n.t("compliance_check_sets.show.metadatas.compliance_control_owner") => @compliance_check_set.organisation.name,
             I18n.t("compliance_check_sets.show.metadatas.import") => '' })
diff --git a/app/views/imports/import/_workbench.html.slim b/app/views/imports/import/_workbench.html.slim
index cec5d837c..0b6cc5945 100644
--- a/app/views/imports/import/_workbench.html.slim
+++ b/app/views/imports/import/_workbench.html.slim
@@ -8,6 +8,25 @@
   .error_messages
     = render 'shared/iev_interfaces/messages', messages: @import.messages
 
+ruby:
+ controls = []
+ controls << TableBuilderHelper::Column.new(
+   name: t('.stif_control'),
+   attribute: Proc.new { |n| import_status(n.workbench_import_control_set&.status, verbose: true, default_status: :pending) },
+   sortable: false,
+   link_to: lambda do |item|
+     item.workbench_import_control_set.present? && [@import.workbench, item.workbench_import_control_set]
+   end
+ ) if @workbench.import_compliance_control_set.present?
+ controls << TableBuilderHelper::Column.new(
+   name: t('.stif_control'),
+   attribute: Proc.new { |n| import_status(n.workgroup_import_control_set&.status, verbose: true, default_status: :pending) },
+   sortable: false,
+   link_to: lambda do |item|
+     item.workbench_import_control_set.present? && [@import.workbench, item.workgroup_import_control_set]
+   end
+ ) if @workbench.workgroup.import_compliance_control_set.present?
+
 - if @import.resources.any?
   .col-lg-12
     = table_builder_2 @import.resources,
@@ -22,28 +41,12 @@
         ), \
         TableBuilderHelper::Column.new( \
           key: :status, \
-          attribute: Proc.new { |n| import_status(n.status) }, \
+          attribute: Proc.new { |n| import_status(n.status, verbose: true, default_status: :pending) }, \
           sortable: false, \
           link_to: lambda do |item| \
             item.netex_import.present? ? [@import.workbench, item.netex_import] : [@import.workbench, @import, item] \
           end \
-        ), \
-        TableBuilderHelper::Column.new( \
-          name: t('.stif_control'), \
-          attribute: Proc.new { |n| import_status(n.workbench_import_control_set&.status) }, \
-          sortable: false, \
-          link_to: lambda do |item| \
-            item.workbench_import_control_set.present? && [@import.workbench, item.workbench_import_control_set] \
-          end \
-        ), \
-        TableBuilderHelper::Column.new( \
-          name: t('.organisation_control'), \
-          attribute: Proc.new { |n| import_status(n.workgroup_import_control_set&.status) }, \
-          sortable: false, \
-          link_to: lambda do |item| \
-            item.workgroup_import_control_set.present? && [@import.workbench, item.workgroup_import_control_set] \
-          end \
-        ) \
+        ), *controls \
       ],
       cls: 'table',
       overhead: [ \
@@ -51,7 +54,7 @@
         {}, \
         { \
           title: I18n.t('imports.show.summary').html_safe, \
-          width: 2, \
+          width: controls.size, \
           cls: 'overheaded-default colspan="2"' \
         } \
       ]
-- 
cgit v1.2.3
From d041b6b07cc2b9c2b48e6da929c8d7f1e0ec8bca Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 30 Apr 2018 14:40:04 +0200
Subject: Add import_compliance_control_sets to Workgroups And rename resource
 methods for better consistency
---
 app/models/import/resource.rb                 | 23 ++++++++++++++---------
 app/models/workgroup.rb                       |  9 ++-------
 app/views/imports/import/_workbench.html.slim | 22 ++++++++++++----------
 3 files changed, 28 insertions(+), 26 deletions(-)
(limited to 'app')
diff --git a/app/models/import/resource.rb b/app/models/import/resource.rb
index 2c7889240..e88f03088 100644
--- a/app/models/import/resource.rb
+++ b/app/models/import/resource.rb
@@ -20,15 +20,18 @@ class Import::Resource < ApplicationModel
 
       return unless netex_import&.successful?
 
-      if workbench.import_compliance_control_set_id.present? && workbench_import_control_set.nil?
+      if workbench.import_compliance_control_set_id.present? && workbench_import_check_set.nil?
         ComplianceControlSetCopyWorker.perform_async workbench.import_compliance_control_set_id, referential_id
         return
       end
 
-      return if workbench_import_control_set && !workbench_import_control_set.successful?
-
-      if workgroup.import_compliance_control_set_id.present? && workgroup_import_control_set.nil?
-        ComplianceControlSetCopyWorker.perform_async workgroup.import_compliance_control_set_id, referential_id
+      return if workbench_import_check_set && !workbench_import_control_set.successful?
+      workgroup.import_compliance_control_set_ids.each_with_index do |id, index|
+        compliance_check_set = workgroup_import_check_set[index]
+        return if compliance_check_set && !compliance_check_set.successful?
+        if compliance_check_set.nil?
+          ComplianceControlSetCopyWorker.perform_async id, referential_id
+        end
       end
     end
   end
@@ -46,15 +49,17 @@ class Import::Resource < ApplicationModel
     import.children.where(name: self.reference).last
   end
 
-  def workbench_import_control_set
+  def workbench_import_check_set
     return unless referential.present?
     return unless referential.workbench.import_compliance_control_set_id.present?
     referential.compliance_check_sets.where(compliance_control_set_id: referential.workbench.import_compliance_control_set_id, referential_id: referential_id).last
   end
 
-  def workgroup_import_control_set
+  def workgroup_import_check_set(index)
     return unless referential.present?
-    return unless referential.workbench.workgroup.import_compliance_control_set_id.present?
-    referential.compliance_check_sets.where(compliance_control_set_id: referential.workbench.workgroup.import_compliance_control_set_id, referential_id: referential_id).last
+    return unless referential.workbench.workgroup.import_compliance_control_set_ids.present?
+    cs = referential.workbench.workgroup.import_compliance_control_sets[index]
+    return unless cs
+    referential.compliance_check_sets.where(compliance_control_set_id: cs.id, referential_id: referential_id).last
   end
 end
diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb
index 6a1746eb8..247873869 100644
--- a/app/models/workgroup.rb
+++ b/app/models/workgroup.rb
@@ -24,12 +24,7 @@ class Workgroup < ApplicationModel
     export_types.include? export_name
   end
 
-  def import_compliance_control_set_id
-    # XXX
-    nil
-  end
-
-  def import_compliance_control_set
-    import_compliance_control_set_id && ComplianceControlSet.find(import_compliance_control_set_id)
+  def import_compliance_control_sets
+    @import_compliance_control_sets ||= import_compliance_control_set_ids.map{|id| ComplianceControlSet.find(id)}
   end
 end
diff --git a/app/views/imports/import/_workbench.html.slim b/app/views/imports/import/_workbench.html.slim
index 0b6cc5945..4dcf949b0 100644
--- a/app/views/imports/import/_workbench.html.slim
+++ b/app/views/imports/import/_workbench.html.slim
@@ -12,20 +12,22 @@ ruby:
  controls = []
  controls << TableBuilderHelper::Column.new(
    name: t('.stif_control'),
-   attribute: Proc.new { |n| import_status(n.workbench_import_control_set&.status, verbose: true, default_status: :pending) },
+   attribute: Proc.new { |n| import_status(n.workbench_import_check_set&.status, verbose: true, default_status: :pending) },
    sortable: false,
    link_to: lambda do |item|
-     item.workbench_import_control_set.present? && [@import.workbench, item.workbench_import_control_set]
+     item.workbench_import_check_set.present? && [@import.workbench, item.workbench_import_check_set]
    end
  ) if @workbench.import_compliance_control_set.present?
- controls << TableBuilderHelper::Column.new(
-   name: t('.stif_control'),
-   attribute: Proc.new { |n| import_status(n.workgroup_import_control_set&.status, verbose: true, default_status: :pending) },
-   sortable: false,
-   link_to: lambda do |item|
-     item.workbench_import_control_set.present? && [@import.workbench, item.workgroup_import_control_set]
-   end
- ) if @workbench.workgroup.import_compliance_control_set.present?
+ controls += @workbench.workgroup.import_compliance_control_sets.each_with_index.map do |cs, i|
+   TableBuilderHelper::Column.new(
+     name: t('.organisation_control'),
+     attribute: Proc.new { |n| import_status(n.workgroup_import_check_set(i)&.status, verbose: true, default_status: :pending) },
+     sortable: false,
+     link_to: lambda do |item|
+       item.workgroup_import_check_set(i).present? && [@import.workbench, item.workgroup_import_check_set(i)]
+    end
+    )
+  end
 
 - if @import.resources.any?
   .col-lg-12
-- 
cgit v1.2.3
From fac03f56f2e84705cd30fc31d8007cc64f77d500 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 2 May 2018 12:12:18 +0200
Subject: Add GTFS views
---
 app/views/imports/import/_gtf.html.slim       | 42 +++++++++++++++++++++++++++
 app/views/imports/import/_workbench.html.slim |  6 ++--
 2 files changed, 45 insertions(+), 3 deletions(-)
 create mode 100644 app/views/imports/import/_gtf.html.slim
(limited to 'app')
diff --git a/app/views/imports/import/_gtf.html.slim b/app/views/imports/import/_gtf.html.slim
new file mode 100644
index 000000000..8b92f2e92
--- /dev/null
+++ b/app/views/imports/import/_gtf.html.slim
@@ -0,0 +1,42 @@
+.row
+  .col-lg-6.col-md-6.col-sm-12.col-xs-12
+    - metadata = { t('.parent') => link_to(@import.parent.name, [@import.parent.workbench, @import.parent]) }
+    - metadata = metadata.update({t('.status') => import_status(@import.status, verbose: true) })
+    - metadata = metadata.update({t('.referential') => @import.referential ? link_to(@import.referential.name, [@import.referential]) : "-" })
+    = definition_list t('metadatas'), metadata
+
+.col-lg-12
+  .error_messages
+    = render 'shared/iev_interfaces/messages', messages: @import.main_resource.messages
+
+- if @import.resources.any?
+  .col-lg-12
+    = table_builder_2 @import.resources,
+      [ \
+        TableBuilderHelper::Column.new( \
+          name: t('.referential_name'), \
+          attribute: 'name', \
+          sortable: false, \
+          link_to: lambda do |item| \
+            referential_path(item.referential) if item.referential.present? \
+          end \
+        ), \
+        TableBuilderHelper::Column.new( \
+          key: :status, \
+          attribute: Proc.new { |n| import_status(n.status, verbose: true, default_status: :pending) }, \
+          sortable: false, \
+          link_to: lambda do |item| \
+            item.netex_import.present? ? [@import.workbench, item.netex_import] : [@import.workbench, @import, item] \
+          end \
+        )\
+      ],
+      cls: 'table',
+      overhead: [ \
+        {}, \
+        {}, \
+        { \
+          title: I18n.t('imports.show.summary').html_safe, \
+          width: controls.size, \
+          cls: 'overheaded-default colspan="2"' \
+        } \
+      ]
diff --git a/app/views/imports/import/_workbench.html.slim b/app/views/imports/import/_workbench.html.slim
index 4dcf949b0..17341913c 100644
--- a/app/views/imports/import/_workbench.html.slim
+++ b/app/views/imports/import/_workbench.html.slim
@@ -54,9 +54,9 @@ ruby:
       overhead: [ \
         {}, \
         {}, \
-        { \
+        controls.present? ? { \
           title: I18n.t('imports.show.summary').html_safe, \
           width: controls.size, \
           cls: 'overheaded-default colspan="2"' \
-        } \
-      ]
+        } : nil \
+      ].compact
-- 
cgit v1.2.3
From fb4d1c66cb4c0cd83e183a13ca5f9ea44803631b Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 7 May 2018 15:25:50 +0200
Subject: Refs #6960; Add owners to workgroups
And define policies
---
 app/models/workgroup.rb          |  1 +
 app/policies/workgroup_policy.rb | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)
 create mode 100644 app/policies/workgroup_policy.rb
(limited to 'app')
diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb
index 247873869..a264247c7 100644
--- a/app/models/workgroup.rb
+++ b/app/models/workgroup.rb
@@ -1,6 +1,7 @@
 class Workgroup < ApplicationModel
   belongs_to :line_referential
   belongs_to :stop_area_referential
+  belongs_to :owner, class_name: "Organisation"
 
   has_many :workbenches
   has_many :calendars
diff --git a/app/policies/workgroup_policy.rb b/app/policies/workgroup_policy.rb
new file mode 100644
index 000000000..01914bb51
--- /dev/null
+++ b/app/policies/workgroup_policy.rb
@@ -0,0 +1,19 @@
+class WorkgroupPolicy < ApplicationPolicy
+  class Scope < Scope
+    def resolve
+      scope
+    end
+  end
+
+  def create?
+    false
+  end
+
+  def desrtroy?
+    false
+  end
+
+  def update?
+    record.owner == user.organisation
+  end
+end
-- 
cgit v1.2.3
From 430550b965035be3d78abad790e6c44fdc69087f Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 7 May 2018 16:57:22 +0200
Subject: Refs #6960; Add a view to set the controls associated to each
 workbench
---
 app/controllers/workgroups_controller.rb             | 13 +++++++++++++
 app/models/workbench.rb                              | 10 ++++++++--
 app/models/workgroup.rb                              | 20 ++++++++++++++++++--
 .../navigation/_main_nav_left_content_stif.html.slim |  3 +++
 app/views/workgroups/_form.html.slim                 | 15 +++++++++++++++
 app/views/workgroups/edit.html.slim                  |  8 ++++++++
 6 files changed, 65 insertions(+), 4 deletions(-)
 create mode 100644 app/controllers/workgroups_controller.rb
 create mode 100644 app/views/workgroups/_form.html.slim
 create mode 100644 app/views/workgroups/edit.html.slim
(limited to 'app')
diff --git a/app/controllers/workgroups_controller.rb b/app/controllers/workgroups_controller.rb
new file mode 100644
index 000000000..5d422380c
--- /dev/null
+++ b/app/controllers/workgroups_controller.rb
@@ -0,0 +1,13 @@
+class WorkgroupsController < ChouetteController
+  defaults resource_class: Workgroup
+
+  include PolicyChecker
+
+  def show
+    redirect_to "/"
+  end
+
+  def workgroup_params
+    params[:workgroup].permit(workbenches_attributes: [:id, owner_compliance_control_set_ids: @workgroup.available_compliance_control_sets.keys])
+  end
+end
diff --git a/app/models/workbench.rb b/app/models/workbench.rb
index d99197b47..64e9ae92d 100644
--- a/app/models/workbench.rb
+++ b/app/models/workbench.rb
@@ -51,8 +51,14 @@ class Workbench < ApplicationModel
     where(name: DEFAULT_WORKBENCH_NAME).last
   end
 
-  def import_compliance_control_set
-    import_compliance_control_set_id && ComplianceControlSet.find(import_compliance_control_set_id)
+  # XXX
+  # def import_compliance_control_set
+  #   import_compliance_control_set_id && ComplianceControlSet.find(import_compliance_control_set_id)
+  # end
+
+  def compliance_control_set key
+    id = (owner_compliance_control_set_ids || {})[key.to_s]
+    id.present? && ComplianceControlSet.find(id)
   end
 
   private
diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb
index a264247c7..b1cdde2c1 100644
--- a/app/models/workgroup.rb
+++ b/app/models/workgroup.rb
@@ -17,6 +17,8 @@ class Workgroup < ApplicationModel
 
   has_many :custom_fields
 
+  accepts_nested_attributes_for :workbenches
+
   def custom_fields_definitions
     Hash[*custom_fields.map{|cf| [cf.code, cf]}.flatten]
   end
@@ -25,7 +27,21 @@ class Workgroup < ApplicationModel
     export_types.include? export_name
   end
 
-  def import_compliance_control_sets
-    @import_compliance_control_sets ||= import_compliance_control_set_ids.map{|id| ComplianceControlSet.find(id)}
+  def available_compliance_control_sets
+    %i(
+      import
+      merge
+      automatic
+      workgroup
+      workbench
+    ).inject({}) do |h, k|
+      h[k] = "workgroups.available_compliance_control_sets.#{k}".t.capitalize
+      h
+    end
   end
+
+  # XXX
+  # def import_compliance_control_sets
+  #   @import_compliance_control_sets ||= import_compliance_control_set_ids.map{|id| ComplianceControlSet.find(id)}
+  # end
 end
diff --git a/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim b/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim
index 9404eeae6..382d80e0d 100644
--- a/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim
+++ b/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim
@@ -14,6 +14,9 @@
             span = t('layouts.navbar.workbench_outputs.organisation')
           = link_to '#', class: 'list-group-item disabled' do
             span = t('layouts.navbar.workbench_outputs.workgroup')
+          - if policy(workbench.workgroup).edit?
+            = link_to [:edit, workbench.workgroup], class: 'list-group-item' do
+              span = t('layouts.navbar.workbench_outputs.edit_workgroup')
 
     .menu-item.panel
       .panel-heading
diff --git a/app/views/workgroups/_form.html.slim b/app/views/workgroups/_form.html.slim
new file mode 100644
index 000000000..c32be6d22
--- /dev/null
+++ b/app/views/workgroups/_form.html.slim
@@ -0,0 +1,15 @@
+= simple_form_for @workgroup, html: { class: 'form-horizontal', id: 'workgroup_form' }, wrapper: :horizontal_form do |f|
+  table.table
+    thead
+      th
+        - @workgroup.available_compliance_control_sets.values.each do |cc|
+          th= cc
+    - @workgroup.workbenches.each_with_index do |w,i|
+      tr
+        th= w.organisation.name
+        - @workgroup.available_compliance_control_sets.keys.each do |cc|
+          td
+            = hidden_field_tag "workgroup[workbenches_attributes][#{i}][id]", w.id
+            = select_tag "workgroup[workbenches_attributes][#{i}][owner_compliance_control_set_ids][#{cc}]", options_from_collection_for_select(w.organisation.compliance_control_sets, :id, :name, w.compliance_control_set(cc).try(:id)), include_blank: true
+
+  = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'workgroup_form'
diff --git a/app/views/workgroups/edit.html.slim b/app/views/workgroups/edit.html.slim
new file mode 100644
index 000000000..49847acf2
--- /dev/null
+++ b/app/views/workgroups/edit.html.slim
@@ -0,0 +1,8 @@
+- breadcrumb @workgroup
+- page_header_content_for @workgroup
+
+.page_content
+ .container-fluid
+   .row
+     .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1
+       == render 'form'
-- 
cgit v1.2.3
From 9434284e4f12b4b576762dabbd2b0a308e28bc61 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 9 May 2018 08:41:23 +0200
Subject: Refs #6960; Update imports to use nesw implementation
---
 app/helpers/table_builder_helper.rb               | 24 +++++++++++++++++--
 app/models/compliance_check_set.rb                |  4 ++++
 app/models/concerns/iev_interfaces/task.rb        | 12 ++++++++++
 app/models/import/base.rb                         |  9 -------
 app/models/import/gtfs.rb                         | 13 +++++-----
 app/models/import/resource.rb                     | 29 +++++++----------------
 app/models/workgroup.rb                           |  9 +++++++
 app/views/imports/import/_workbench.html.slim     | 21 +++++-----------
 app/workers/compliance_control_set_copy_worker.rb |  1 -
 9 files changed, 67 insertions(+), 55 deletions(-)
(limited to 'app')
diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb
index 8c73cb33c..0b24a9c05 100644
--- a/app/helpers/table_builder_helper.rb
+++ b/app/helpers/table_builder_helper.rb
@@ -153,7 +153,17 @@ module TableBuilderHelper
             i = columns.index(column)
 
             if overhead[i].blank?
-              if (i > 0) && overhead[i - 1][:width] && (overhead[i - 1][:width] > 1)
+              prev = nil
+              if i > 0
+                (i-1..0).each do |j|
+                  o = overhead[j]
+                  if (j + o[:width].to_i) >= i
+                    prev = o
+                    break
+                  end
+                end
+              end
+              if prev
                 clsArrayH = overhead[i - 1][:cls].split
 
                 hcont << content_tag(:th, build_column_header(
@@ -234,7 +244,17 @@ module TableBuilderHelper
             i = columns.index(column)
 
             if overhead[i].blank?
-              if (i > 0) && overhead[i - 1][:width] && (overhead[i - 1][:width] > 1)
+              prev = nil
+              if i > 0
+                (i-1..0).each do |j|
+                  o = overhead[j]
+                  if (j + o[:width].to_i) >= i
+                    prev = o
+                    break
+                  end
+                end
+              end
+              if prev
                 clsArrayAlt = overhead[i - 1][:cls].split
 
                 bcont << content_tag(:td, link, title: 'Voir', class: td_cls(clsArrayAlt, extra_class))
diff --git a/app/models/compliance_check_set.rb b/app/models/compliance_check_set.rb
index eb0e23d82..f29ff4de5 100644
--- a/app/models/compliance_check_set.rb
+++ b/app/models/compliance_check_set.rb
@@ -26,6 +26,10 @@ class ComplianceCheckSet < ApplicationModel
     %w(successful failed warning aborted canceled)
   end
 
+  def successful?
+    status.to_s == "successful"
+  end
+
   def self.abort_old
     where(
       'created_at < ? AND status NOT IN (?)',
diff --git a/app/models/concerns/iev_interfaces/task.rb b/app/models/concerns/iev_interfaces/task.rb
index 3e4dd52ca..70250b3c0 100644
--- a/app/models/concerns/iev_interfaces/task.rb
+++ b/app/models/concerns/iev_interfaces/task.rb
@@ -31,6 +31,16 @@ module IevInterfaces::Task
 
     before_save :initialize_fields, on: :create
     after_save :notify_parent
+
+    status.values.each do |s|
+      define_method "#{s}!" do
+        update status: s
+      end
+
+      define_method "#{s}?" do
+        status&.to_s == s
+      end
+    end
   end
 
   module ClassMethods
@@ -117,9 +127,11 @@ module IevInterfaces::Task
 
   def call_boiv_iev
     Rails.logger.error("Begin IEV call for import")
+    running!
     Net::HTTP.get iev_callback_url
     Rails.logger.error("End IEV call for import")
   rescue Exception => e
+    aborted!
     logger.error "IEV server error : #{e.message}"
     logger.error e.backtrace.inspect
   end
diff --git a/app/models/import/base.rb b/app/models/import/base.rb
index baa25c3df..dcd710e58 100644
--- a/app/models/import/base.rb
+++ b/app/models/import/base.rb
@@ -44,15 +44,6 @@ class Import::Base < ApplicationModel
 
   private
 
-  def failed!
-    update status: :failed
-  end
-
-  def aborted!
-    Rails.logger.info "=== aborted ==="
-    update status: :aborted
-  end
-
   def initialize_fields
     super
     self.token_download ||= SecureRandom.urlsafe_base64
diff --git a/app/models/import/gtfs.rb b/app/models/import/gtfs.rb
index 4f0dde9d1..520cc88e9 100644
--- a/app/models/import/gtfs.rb
+++ b/app/models/import/gtfs.rb
@@ -14,9 +14,8 @@ class Import::Gtfs < Import::Base
     @resource ||= parent.resources.find_or_create_by(name: self.name, resource_type: "referential", reference: self.name)
   end
 
-  def notify_parent
-    super
-    main_resource.update_status_from_importer self.status
+  def next_step
+    main_resource.next_step
   end
 
   def create_message args
@@ -336,10 +335,10 @@ class Import::Gtfs < Import::Base
   end
 
   def notify_parent
-    return unless parent.present?
-    return if notified_parent_at
-    parent.child_change
-    update_column :notified_parent_at, Time.now
+    if super
+      main_resource.update_status_from_importer self.status
+      next_step
+    end
   end
 
 end
diff --git a/app/models/import/resource.rb b/app/models/import/resource.rb
index e88f03088..343eb9b7d 100644
--- a/app/models/import/resource.rb
+++ b/app/models/import/resource.rb
@@ -20,17 +20,11 @@ class Import::Resource < ApplicationModel
 
       return unless netex_import&.successful?
 
-      if workbench.import_compliance_control_set_id.present? && workbench_import_check_set.nil?
-        ComplianceControlSetCopyWorker.perform_async workbench.import_compliance_control_set_id, referential_id
-        return
-      end
-
-      return if workbench_import_check_set && !workbench_import_control_set.successful?
-      workgroup.import_compliance_control_set_ids.each_with_index do |id, index|
-        compliance_check_set = workgroup_import_check_set[index]
-        return if compliance_check_set && !compliance_check_set.successful?
+      workbench.workgroup.import_compliance_control_sets.map do |key, label|
+        next unless (control_set = workbench.compliance_control_set(key)).present?
+        compliance_check_set = workbench_import_check_set key
         if compliance_check_set.nil?
-          ComplianceControlSetCopyWorker.perform_async id, referential_id
+          ComplianceControlSetCopyWorker.perform_async control_set.id, referential_id
         end
       end
     end
@@ -49,17 +43,10 @@ class Import::Resource < ApplicationModel
     import.children.where(name: self.reference).last
   end
 
-  def workbench_import_check_set
-    return unless referential.present?
-    return unless referential.workbench.import_compliance_control_set_id.present?
-    referential.compliance_check_sets.where(compliance_control_set_id: referential.workbench.import_compliance_control_set_id, referential_id: referential_id).last
-  end
-
-  def workgroup_import_check_set(index)
+  def workbench_import_check_set key
     return unless referential.present?
-    return unless referential.workbench.workgroup.import_compliance_control_set_ids.present?
-    cs = referential.workbench.workgroup.import_compliance_control_sets[index]
-    return unless cs
-    referential.compliance_check_sets.where(compliance_control_set_id: cs.id, referential_id: referential_id).last
+    control_set = referential.workbench.compliance_control_set(key)
+    return unless control_set.present?
+    referential.compliance_check_sets.where(compliance_control_set_id: control_set.id, referential_id: referential_id).last
   end
 end
diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb
index b1cdde2c1..499441cd3 100644
--- a/app/models/workgroup.rb
+++ b/app/models/workgroup.rb
@@ -39,6 +39,15 @@ class Workgroup < ApplicationModel
       h
     end
   end
+  def import_compliance_control_sets
+    %i(
+      import
+      workbench
+    ).inject({}) do |h, k|
+      h[k] = "workgroups.available_compliance_control_sets.#{k}".t.capitalize
+      h
+    end
+  end
 
   # XXX
   # def import_compliance_control_sets
diff --git a/app/views/imports/import/_workbench.html.slim b/app/views/imports/import/_workbench.html.slim
index 17341913c..a2eeca1e5 100644
--- a/app/views/imports/import/_workbench.html.slim
+++ b/app/views/imports/import/_workbench.html.slim
@@ -9,22 +9,13 @@
     = render 'shared/iev_interfaces/messages', messages: @import.messages
 
 ruby:
- controls = []
- controls << TableBuilderHelper::Column.new(
-   name: t('.stif_control'),
-   attribute: Proc.new { |n| import_status(n.workbench_import_check_set&.status, verbose: true, default_status: :pending) },
-   sortable: false,
-   link_to: lambda do |item|
-     item.workbench_import_check_set.present? && [@import.workbench, item.workbench_import_check_set]
-   end
- ) if @workbench.import_compliance_control_set.present?
- controls += @workbench.workgroup.import_compliance_control_sets.each_with_index.map do |cs, i|
+ controls = @workbench.workgroup.available_compliance_control_sets.map do |key, label|
    TableBuilderHelper::Column.new(
-     name: t('.organisation_control'),
-     attribute: Proc.new { |n| import_status(n.workgroup_import_check_set(i)&.status, verbose: true, default_status: :pending) },
+     name: label,
+     attribute: Proc.new { |n| n.workbench.compliance_control_set(key).present? ? import_status(n.workbench_import_check_set(key)&.status, verbose: true, default_status: (n.status == "ERROR" ? :aborted : :pending)) : '-' },
      sortable: false,
      link_to: lambda do |item|
-       item.workgroup_import_check_set(i).present? && [@import.workbench, item.workgroup_import_check_set(i)]
+       item.workbench_import_check_set(key).present? && [@import.workbench, item.workbench_import_check_set(key)]
     end
     )
   end
@@ -43,7 +34,7 @@ ruby:
         ), \
         TableBuilderHelper::Column.new( \
           key: :status, \
-          attribute: Proc.new { |n| import_status(n.status, verbose: true, default_status: :pending) }, \
+          attribute: Proc.new { |n| import_status(n.netex_import&.status || n.status, verbose: true, default_status: :pending) }, \
           sortable: false, \
           link_to: lambda do |item| \
             item.netex_import.present? ? [@import.workbench, item.netex_import] : [@import.workbench, @import, item] \
@@ -57,6 +48,6 @@ ruby:
         controls.present? ? { \
           title: I18n.t('imports.show.summary').html_safe, \
           width: controls.size, \
-          cls: 'overheaded-default colspan="2"' \
+          cls: "overheaded-default colspan='#{controls.size}'" \
         } : nil \
       ].compact
diff --git a/app/workers/compliance_control_set_copy_worker.rb b/app/workers/compliance_control_set_copy_worker.rb
index d18bb0c88..337b92f4b 100644
--- a/app/workers/compliance_control_set_copy_worker.rb
+++ b/app/workers/compliance_control_set_copy_worker.rb
@@ -3,7 +3,6 @@ class ComplianceControlSetCopyWorker
 
   def perform(control_set_id, referential_id)
     check_set = ComplianceControlSetCopier.new.copy(control_set_id, referential_id)
-
     begin
       Net::HTTP.get(URI("#{Rails.configuration.iev_url}/boiv_iev/referentials/validator/new?id=#{check_set.id}"))
     rescue Exception => e
-- 
cgit v1.2.3
From 64933b6903583b585f7de5bc391a9ab2ade1c6a7 Mon Sep 17 00:00:00 2001
From: Zog
Date: Wed, 9 May 2018 10:19:33 +0200
Subject: Refs #6961; Update Workbench#edit
- Update the form
- Use policies and update the seeds accordingly
- Add a link in the navbar(s)
---
 app/controllers/workbenches_controller.rb                         | 2 +-
 app/policies/workbench_policy.rb                                  | 2 +-
 app/views/layouts/navigation/_main_nav_left_content.html.slim     | 8 +++++++-
 .../layouts/navigation/_main_nav_left_content_stif.html.slim      | 3 +++
 app/views/workbenches/_form.html.slim                             | 5 +++--
 5 files changed, 15 insertions(+), 5 deletions(-)
(limited to 'app')
diff --git a/app/controllers/workbenches_controller.rb b/app/controllers/workbenches_controller.rb
index 43415ff60..cecd071d8 100644
--- a/app/controllers/workbenches_controller.rb
+++ b/app/controllers/workbenches_controller.rb
@@ -42,7 +42,7 @@ class WorkbenchesController < ChouetteController
   private
 
   def workbench_params
-    params.require(:workbench).permit(:import_compliance_control_set_id, :merge_compliance_control_set_id)
+    params.require(:workbench).permit(owner_compliance_control_set_ids: @workbench.workgroup.available_compliance_control_sets.keys)
   end
 
   def resource
diff --git a/app/policies/workbench_policy.rb b/app/policies/workbench_policy.rb
index 7b925e91a..9f2279c38 100644
--- a/app/policies/workbench_policy.rb
+++ b/app/policies/workbench_policy.rb
@@ -6,6 +6,6 @@ class WorkbenchPolicy < ApplicationPolicy
   end
 
   def update?
-    true
+    user.has_permission?('workbenches.update')
   end
 end
diff --git a/app/views/layouts/navigation/_main_nav_left_content.html.slim b/app/views/layouts/navigation/_main_nav_left_content.html.slim
index 0b55578a7..889f8f944 100644
--- a/app/views/layouts/navigation/_main_nav_left_content.html.slim
+++ b/app/views/layouts/navigation/_main_nav_left_content.html.slim
@@ -15,6 +15,9 @@
             span = t('layouts.navbar.workbench_outputs.organisation')
           = link_to '#', class: 'list-group-item disabled' do
             span = t('layouts.navbar.workbench_outputs.workgroup')
+          - if policy(workbench.workgroup).edit?
+            = link_to [:edit, workbench.workgroup], class: 'list-group-item' do
+              span = t('layouts.navbar.workbench_outputs.edit_workgroup')
 
     .menu-item.panel
       .panel-heading
@@ -36,7 +39,10 @@
             span = t('activerecord.models.compliance_check_set.other').capitalize
           = link_to compliance_control_sets_path, class: 'list-group-item' do
             span = t('activerecord.models.compliance_control_set.other').capitalize
-            
+          - if policy(workbench).edit?
+            = link_to [:edit, workbench], class: 'list-group-item' do
+              span = t('workbenches.edit.link')
+
     .menu-item.panel
       .panel-heading
         h4.panel-title
diff --git a/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim b/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim
index 382d80e0d..a7bb3f511 100644
--- a/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim
+++ b/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim
@@ -38,6 +38,9 @@
             span = t('activerecord.models.compliance_check_set.other').capitalize
           = link_to compliance_control_sets_path, class: 'list-group-item' do
             span = t('activerecord.models.compliance_control_set.other').capitalize
+          - if policy(workbench).edit?
+            = link_to [:edit, workbench], class: 'list-group-item' do
+              span = t('workbenches.edit.link')
 
     .menu-item.panel
       .panel-heading
diff --git a/app/views/workbenches/_form.html.slim b/app/views/workbenches/_form.html.slim
index 534a5f378..a6b778e94 100644
--- a/app/views/workbenches/_form.html.slim
+++ b/app/views/workbenches/_form.html.slim
@@ -1,8 +1,9 @@
 = simple_form_for @workbench, html: { class: 'form-horizontal', id: 'workbench_form' }, wrapper: :horizontal_form do |f|
   .row
     .col-lg-12
-      = f.input :import_compliance_control_set_id, as: :select, collection: current_organisation.compliance_control_sets, value_method: :id
-      = f.input :merge_compliance_control_set_id, as: :select, collection: current_organisation.compliance_control_sets, value_method: :id
+      = f.fields_for :owner_compliance_control_set_ids do |ff|
+        - @workbench.workgroup.available_compliance_control_sets.each do |cc, label|
+          = ff.input cc, as: :select, collection: current_organisation.compliance_control_sets, value_method: :id, label: label, selected: @workbench.compliance_control_set(cc).try(:id).try(:to_s), include_blank: true
 
   .separator
 
-- 
cgit v1.2.3
From 9684831ac650d633ddfab1062e2285f9482b1157 Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Wed, 9 May 2018 15:15:05 +0200
Subject: Rewrite compliance_control_sets associated to workbench or workgroup
 edits and imports. Refs #6960
---
 app/controllers/workbenches_controller.rb     |  2 +-
 app/controllers/workgroups_controller.rb      |  2 +-
 app/models/workgroup.rb                       | 46 +++++++++++++++------------
 app/views/imports/import/_workbench.html.slim |  2 +-
 app/views/workbenches/_form.html.slim         |  4 +--
 app/views/workgroups/_form.html.slim          |  6 ++--
 6 files changed, 32 insertions(+), 30 deletions(-)
(limited to 'app')
diff --git a/app/controllers/workbenches_controller.rb b/app/controllers/workbenches_controller.rb
index cecd071d8..1432518dc 100644
--- a/app/controllers/workbenches_controller.rb
+++ b/app/controllers/workbenches_controller.rb
@@ -42,7 +42,7 @@ class WorkbenchesController < ChouetteController
   private
 
   def workbench_params
-    params.require(:workbench).permit(owner_compliance_control_set_ids: @workbench.workgroup.available_compliance_control_sets.keys)
+    params.require(:workbench).permit(owner_compliance_control_set_ids: @workbench.workgroup.compliance_control_sets_by_workbench.keys)
   end
 
   def resource
diff --git a/app/controllers/workgroups_controller.rb b/app/controllers/workgroups_controller.rb
index 5d422380c..70aa89cf9 100644
--- a/app/controllers/workgroups_controller.rb
+++ b/app/controllers/workgroups_controller.rb
@@ -8,6 +8,6 @@ class WorkgroupsController < ChouetteController
   end
 
   def workgroup_params
-    params[:workgroup].permit(workbenches_attributes: [:id, owner_compliance_control_set_ids: @workgroup.available_compliance_control_sets.keys])
+    params[:workgroup].permit(workbenches_attributes: [:id, owner_compliance_control_set_ids: @workgroup.compliance_control_sets_by_workgroup.keys])
   end
 end
diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb
index 499441cd3..6bb03c7fa 100644
--- a/app/models/workgroup.rb
+++ b/app/models/workgroup.rb
@@ -27,30 +27,34 @@ class Workgroup < ApplicationModel
     export_types.include? export_name
   end
 
-  def available_compliance_control_sets
-    %i(
-      import
-      merge
-      automatic
-      workgroup
-      workbench
-    ).inject({}) do |h, k|
-      h[k] = "workgroups.available_compliance_control_sets.#{k}".t.capitalize
-      h
-    end
+  def all_compliance_control_sets
+    %i(after_import
+      after_import_by_workgroup
+      before_merge
+      before_merge_by_workgroup
+      after_merge
+      after_merge_by_workgroup
+      automatic_by_workgroup
+    )
+  end
+
+  def compliance_control_sets_by_workgroup
+    compliance_control_sets_labels all_compliance_control_sets.grep(/by_workgroup$/)
+  end
+
+  def compliance_control_sets_by_workbench
+    compliance_control_sets_labels all_compliance_control_sets.grep_v(/by_workgroup$/)
   end
+
   def import_compliance_control_sets
-    %i(
-      import
-      workbench
-    ).inject({}) do |h, k|
-      h[k] = "workgroups.available_compliance_control_sets.#{k}".t.capitalize
+    compliance_control_sets_labels all_compliance_control_sets.grep(/^after_import/)
+  end
+
+  private
+  def compliance_control_sets_labels(keys)
+    keys.inject({}) do |h, k|
+      h[k] = "workgroups.compliance_control_sets.#{k}".t.capitalize
       h
     end
   end
-
-  # XXX
-  # def import_compliance_control_sets
-  #   @import_compliance_control_sets ||= import_compliance_control_set_ids.map{|id| ComplianceControlSet.find(id)}
-  # end
 end
diff --git a/app/views/imports/import/_workbench.html.slim b/app/views/imports/import/_workbench.html.slim
index a2eeca1e5..e41ceb0f0 100644
--- a/app/views/imports/import/_workbench.html.slim
+++ b/app/views/imports/import/_workbench.html.slim
@@ -9,7 +9,7 @@
     = render 'shared/iev_interfaces/messages', messages: @import.messages
 
 ruby:
- controls = @workbench.workgroup.available_compliance_control_sets.map do |key, label|
+ controls = @workbench.workgroup.import_compliance_control_sets.map do |key, label|
    TableBuilderHelper::Column.new(
      name: label,
      attribute: Proc.new { |n| n.workbench.compliance_control_set(key).present? ? import_status(n.workbench_import_check_set(key)&.status, verbose: true, default_status: (n.status == "ERROR" ? :aborted : :pending)) : '-' },
diff --git a/app/views/workbenches/_form.html.slim b/app/views/workbenches/_form.html.slim
index a6b778e94..95c7d16b3 100644
--- a/app/views/workbenches/_form.html.slim
+++ b/app/views/workbenches/_form.html.slim
@@ -2,9 +2,7 @@
   .row
     .col-lg-12
       = f.fields_for :owner_compliance_control_set_ids do |ff|
-        - @workbench.workgroup.available_compliance_control_sets.each do |cc, label|
+        - @workbench.workgroup.compliance_control_sets_by_workbench.each do |cc, label|
           = ff.input cc, as: :select, collection: current_organisation.compliance_control_sets, value_method: :id, label: label, selected: @workbench.compliance_control_set(cc).try(:id).try(:to_s), include_blank: true
 
-  .separator
-
   = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'workbench_form'
diff --git a/app/views/workgroups/_form.html.slim b/app/views/workgroups/_form.html.slim
index c32be6d22..bd02fdc80 100644
--- a/app/views/workgroups/_form.html.slim
+++ b/app/views/workgroups/_form.html.slim
@@ -2,14 +2,14 @@
   table.table
     thead
       th
-        - @workgroup.available_compliance_control_sets.values.each do |cc|
+        - @workgroup.compliance_control_sets_by_workgroup.values.each do |cc|
           th= cc
     - @workgroup.workbenches.each_with_index do |w,i|
       tr
         th= w.organisation.name
-        - @workgroup.available_compliance_control_sets.keys.each do |cc|
+        - @workgroup.compliance_control_sets_by_workgroup.keys.each do |cc|
           td
             = hidden_field_tag "workgroup[workbenches_attributes][#{i}][id]", w.id
-            = select_tag "workgroup[workbenches_attributes][#{i}][owner_compliance_control_set_ids][#{cc}]", options_from_collection_for_select(w.organisation.compliance_control_sets, :id, :name, w.compliance_control_set(cc).try(:id)), include_blank: true
+            = select_tag "workgroup[workbenches_attributes][#{i}][owner_compliance_control_set_ids][#{cc}]", options_from_collection_for_select(current_organisation.compliance_control_sets, :id, :name, w.compliance_control_set(cc).try(:id)), include_blank: true
 
   = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'workgroup_form'
-- 
cgit v1.2.3
From d0ab0eb848a96587ac0e0ab26db962c15e559185 Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Wed, 9 May 2018 15:41:06 +0200
Subject: Associate ComplianceControlSet with parent operation when created.
 Refs #6960
---
 app/models/import/resource.rb                     | 2 +-
 app/workers/compliance_control_set_copy_worker.rb | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)
(limited to 'app')
diff --git a/app/models/import/resource.rb b/app/models/import/resource.rb
index 343eb9b7d..43690755d 100644
--- a/app/models/import/resource.rb
+++ b/app/models/import/resource.rb
@@ -24,7 +24,7 @@ class Import::Resource < ApplicationModel
         next unless (control_set = workbench.compliance_control_set(key)).present?
         compliance_check_set = workbench_import_check_set key
         if compliance_check_set.nil?
-          ComplianceControlSetCopyWorker.perform_async control_set.id, referential_id
+          ComplianceControlSetCopyWorker.perform_async control_set.id, referential_id, root_import.class.name, root_import.id
         end
       end
     end
diff --git a/app/workers/compliance_control_set_copy_worker.rb b/app/workers/compliance_control_set_copy_worker.rb
index 337b92f4b..b87f5ad8e 100644
--- a/app/workers/compliance_control_set_copy_worker.rb
+++ b/app/workers/compliance_control_set_copy_worker.rb
@@ -1,8 +1,10 @@
 class ComplianceControlSetCopyWorker
   include Sidekiq::Worker
 
-  def perform(control_set_id, referential_id)
+  def perform(control_set_id, referential_id, parent_type = nil, parent_id = nil)
     check_set = ComplianceControlSetCopier.new.copy(control_set_id, referential_id)
+    check_set.update parent_type: parent_type, parent_id: parent_id if parent_type && parent_id
+
     begin
       Net::HTTP.get(URI("#{Rails.configuration.iev_url}/boiv_iev/referentials/validator/new?id=#{check_set.id}"))
     rescue Exception => e
-- 
cgit v1.2.3
From 7107266518c028bebea7e4a89fd1db1040935b35 Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Wed, 9 May 2018 15:53:44 +0200
Subject: Use Workbench#compliance_control_set_ids virtual attribute to merge
 with existing owner_compliance_control_set_ids. Refs #6960
---
 app/controllers/workbenches_controller.rb | 2 +-
 app/controllers/workgroups_controller.rb  | 2 +-
 app/models/workbench.rb                   | 4 ++++
 app/views/workbenches/_form.html.slim     | 2 +-
 app/views/workgroups/_form.html.slim      | 2 +-
 5 files changed, 8 insertions(+), 4 deletions(-)
(limited to 'app')
diff --git a/app/controllers/workbenches_controller.rb b/app/controllers/workbenches_controller.rb
index 1432518dc..d4dfdebe3 100644
--- a/app/controllers/workbenches_controller.rb
+++ b/app/controllers/workbenches_controller.rb
@@ -42,7 +42,7 @@ class WorkbenchesController < ChouetteController
   private
 
   def workbench_params
-    params.require(:workbench).permit(owner_compliance_control_set_ids: @workbench.workgroup.compliance_control_sets_by_workbench.keys)
+    params.require(:workbench).permit(compliance_control_set_ids: @workbench.workgroup.compliance_control_sets_by_workbench.keys)
   end
 
   def resource
diff --git a/app/controllers/workgroups_controller.rb b/app/controllers/workgroups_controller.rb
index 70aa89cf9..3acea248d 100644
--- a/app/controllers/workgroups_controller.rb
+++ b/app/controllers/workgroups_controller.rb
@@ -8,6 +8,6 @@ class WorkgroupsController < ChouetteController
   end
 
   def workgroup_params
-    params[:workgroup].permit(workbenches_attributes: [:id, owner_compliance_control_set_ids: @workgroup.compliance_control_sets_by_workgroup.keys])
+    params[:workgroup].permit(workbenches_attributes: [:id, compliance_control_set_ids: @workgroup.compliance_control_sets_by_workgroup.keys])
   end
 end
diff --git a/app/models/workbench.rb b/app/models/workbench.rb
index 64e9ae92d..1bca91c56 100644
--- a/app/models/workbench.rb
+++ b/app/models/workbench.rb
@@ -61,6 +61,10 @@ class Workbench < ApplicationModel
     id.present? && ComplianceControlSet.find(id)
   end
 
+  def compliance_control_set_ids=(compliance_control_set_ids)
+    self.owner_compliance_control_set_ids = (owner_compliance_control_set_ids || {}).merge compliance_control_set_ids
+  end
+
   private
 
   def initialize_output
diff --git a/app/views/workbenches/_form.html.slim b/app/views/workbenches/_form.html.slim
index 95c7d16b3..819346c35 100644
--- a/app/views/workbenches/_form.html.slim
+++ b/app/views/workbenches/_form.html.slim
@@ -1,7 +1,7 @@
 = simple_form_for @workbench, html: { class: 'form-horizontal', id: 'workbench_form' }, wrapper: :horizontal_form do |f|
   .row
     .col-lg-12
-      = f.fields_for :owner_compliance_control_set_ids do |ff|
+      = f.fields_for :compliance_control_set_ids do |ff|
         - @workbench.workgroup.compliance_control_sets_by_workbench.each do |cc, label|
           = ff.input cc, as: :select, collection: current_organisation.compliance_control_sets, value_method: :id, label: label, selected: @workbench.compliance_control_set(cc).try(:id).try(:to_s), include_blank: true
 
diff --git a/app/views/workgroups/_form.html.slim b/app/views/workgroups/_form.html.slim
index bd02fdc80..7245cfc40 100644
--- a/app/views/workgroups/_form.html.slim
+++ b/app/views/workgroups/_form.html.slim
@@ -10,6 +10,6 @@
         - @workgroup.compliance_control_sets_by_workgroup.keys.each do |cc|
           td
             = hidden_field_tag "workgroup[workbenches_attributes][#{i}][id]", w.id
-            = select_tag "workgroup[workbenches_attributes][#{i}][owner_compliance_control_set_ids][#{cc}]", options_from_collection_for_select(current_organisation.compliance_control_sets, :id, :name, w.compliance_control_set(cc).try(:id)), include_blank: true
+            = select_tag "workgroup[workbenches_attributes][#{i}][compliance_control_set_ids][#{cc}]", options_from_collection_for_select(current_organisation.compliance_control_sets, :id, :name, w.compliance_control_set(cc).try(:id)), include_blank: true
 
   = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'workgroup_form'
-- 
cgit v1.2.3
From 091b582db02ca6f8304cb0176b818a7a90be8d88 Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Wed, 9 May 2018 17:02:23 +0200
Subject: Don't change IEV operation status before pinging java API. Refs #6960
---
 app/models/concerns/iev_interfaces/task.rb | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
(limited to 'app')
diff --git a/app/models/concerns/iev_interfaces/task.rb b/app/models/concerns/iev_interfaces/task.rb
index 70250b3c0..e40808009 100644
--- a/app/models/concerns/iev_interfaces/task.rb
+++ b/app/models/concerns/iev_interfaces/task.rb
@@ -127,7 +127,10 @@ module IevInterfaces::Task
 
   def call_boiv_iev
     Rails.logger.error("Begin IEV call for import")
-    running!
+
+    # Java code expects tasks in NEW status
+    # Don't change status before calling iev
+
     Net::HTTP.get iev_callback_url
     Rails.logger.error("End IEV call for import")
   rescue Exception => e
-- 
cgit v1.2.3
From 65afd2cfe722e57241d27cf8a1069ca67aafc3e0 Mon Sep 17 00:00:00 2001
From: Alban Peignier
Date: Thu, 10 May 2018 19:39:10 +0200
Subject: Fix specs. Refs #6960
---
 app/models/import/gtfs.rb | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
(limited to 'app')
diff --git a/app/models/import/gtfs.rb b/app/models/import/gtfs.rb
index 520cc88e9..9dab11f0e 100644
--- a/app/models/import/gtfs.rb
+++ b/app/models/import/gtfs.rb
@@ -11,15 +11,15 @@ class Import::Gtfs < Import::Base
   end
 
   def main_resource
-    @resource ||= parent.resources.find_or_create_by(name: self.name, resource_type: "referential", reference: self.name)
+    @resource ||= parent.resources.find_or_create_by(name: self.name, resource_type: "referential", reference: self.name) if parent
   end
 
   def next_step
-    main_resource.next_step
+    main_resource&.next_step
   end
 
   def create_message args
-    main_resource.messages.create args
+    (main_resource || self).messages.build args
   end
 
   def import
@@ -53,7 +53,7 @@ class Import::Gtfs < Import::Base
       workbench_id: workbench.id,
       metadatas: [referential_metadata]
     )
-    main_resource.update referential: referential
+    main_resource.update referential: referential if main_resource
   end
 
   def referential_metadata
-- 
cgit v1.2.3