aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorZakaria BOUZIANE2015-04-27 13:24:38 +0200
committerZakaria BOUZIANE2015-04-27 13:24:38 +0200
commit1496115311c71ff448a9ca7c2646faca7bca9d51 (patch)
tree1930447b136f1279822d3ccc818ee6dba0dc1c08 /app
parent69167f2bd60ac393e0c724ebaf1402c5619112d3 (diff)
downloadchouette-core-1496115311c71ff448a9ca7c2646faca7bca9d51.tar.bz2
Validation and CSV export of results
Diffstat (limited to 'app')
-rw-r--r--app/assets/stylesheets/main/validations.css.scss200
-rw-r--r--app/controllers/compliance_check_controller.rb0
-rw-r--r--app/controllers/compliance_checks_controller.rb0
-rw-r--r--app/controllers/validation_results_controller.rb35
-rw-r--r--app/controllers/validations_controller.rb10
-rw-r--r--app/helpers/validation_results_helper.rb71
-rw-r--r--app/models/export.rb1
-rw-r--r--app/models/export_report.rb1
-rw-r--r--app/models/import.rb2
-rw-r--r--app/models/import_report.rb1
-rw-r--r--app/models/import_task.rb1
-rw-r--r--app/models/validation.rb55
-rw-r--r--app/models/validation_export.rb54
-rw-r--r--app/models/validation_report.rb117
-rw-r--r--app/views/compliance_check_tasks/show.html.erb2
-rw-r--r--app/views/exports/_export.erb4
-rw-r--r--app/views/imports/_import.erb4
-rw-r--r--app/views/shared/_header.erb2
-rw-r--r--app/views/validation_results/_validation_result.erb21
-rw-r--r--app/views/validation_results/index.html.erb75
-rw-r--r--app/views/validation_results/index.js.coffee8
-rw-r--r--app/views/validations/_validation.erb4
-rw-r--r--app/views/validations/detailed_errors_index.csv.erb2
-rw-r--r--app/views/validations/show.html.erb60
-rw-r--r--app/views/validations/show.js.coffee75
-rw-r--r--app/views/validations/summary_errors_index.csv.erb3
26 files changed, 672 insertions, 136 deletions
diff --git a/app/assets/stylesheets/main/validations.css.scss b/app/assets/stylesheets/main/validations.css.scss
new file mode 100644
index 000000000..6fea56818
--- /dev/null
+++ b/app/assets/stylesheets/main/validations.css.scss
@@ -0,0 +1,200 @@
+#workspace.validations.index
+{
+}
+
+#workspace.validations.show {
+
+ .status {
+ margin-left: 10px;
+ }
+
+ .status_failed { color: #a94442;}
+ .status_pending { color: #31708f;}
+ .status_processing { color: #31708f;}
+ .status_completed { color: #3c763d;}
+
+ .links{
+ margin: 0px 0 20px 0;
+
+ img{ margin: 0 5px 0 15px; }
+ }
+
+ .order{
+ margin-bottom: 10px;
+ padding: 5px;
+ border-top: 1px solid #e4e4e4;
+ border-bottom: 1px solid #e4e4e4;
+ }
+
+ .status_ok_error { color: #8fc861; }
+ .status_nok_error { color: #e22b1b; }
+ .status_na_error { color: #898e7f; }
+
+ .status_ok_warning { color: #8fc861; }
+ .status_nok_warning { color: #ffbd2b; }
+ .status_na_warning { color: #898e7f; }
+
+ .resume {
+ &:after{
+ content: " ";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+ }
+
+ .col1 {
+ float: left;
+ width: 45%;
+ }
+
+ .col2 {
+ margin-left: 10px;
+ float: left;
+ width: 45%;
+ }
+
+ .graph { height: 200px; }
+
+ .caption {
+ text-align :center;
+ font-weight: bold;
+ }
+ }
+
+ .report{
+ .table { margin-top: 20px; }
+
+ }
+
+ .severity__improvment, .severity_warning, .severity_error {
+ border: 1px solid;
+ margin: 10px 0px;
+ padding:10px 10px 10px 10px;
+ background-repeat: no-repeat;
+ background-position: 10px center;-moz-border-radius:.5em;
+ -webkit-border-radius:.5em;
+ border-radius:.5em;
+ height: 100%;
+
+ &:after{
+ content: " ";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+ }
+
+ .status_icon {
+ float: left;
+ width: 20%;
+ height: auto;
+
+ img {
+ vertical-align: middle;
+ width: 48px;
+ height: 48px;
+ }
+ }
+
+ .status_text{
+ float: left;
+ width: 70%;
+
+ .code{
+ font-size: 12px;
+ font-weight: bold;
+ }
+
+ .severity {
+ font-size: 10px;
+ }
+
+ .explanation{
+ display: none;
+ font-size: 12px;
+ margin: 5px 0 0 0;
+ }
+
+ .attributes{
+ font-size: 10px;
+ font-weight: bold;
+ margin: 5px 0 0px 0;
+ }
+ }
+
+ }
+
+ .severity_improvment {
+ color: black;
+ background-color: #c5cf4c;
+ }
+
+ .severity_warning {
+ color: black;
+ background-color: #f1dd30;
+ }
+
+ .severity_error {
+ color: black;
+ background-color: #ff9a0c;
+ }
+
+ .td_error {
+ width: 30%;
+
+ .title_error i { margin-right: 5px; }
+
+ div.details_error{
+ margin: 0px 0px 0px 3px !important;
+ display: none;
+
+ p.detail_error{
+ margin: 0px 0px 5px 0px !important;
+ }
+
+ .file_error{
+ margin-left: 26px;
+ font-size: 10px;
+ color: #898e7f;
+ }
+ }
+ }
+}
+
+#workspace.validations.new, #workspace.validations.create
+{
+ padding: 0;
+ margin-top: -0.3em;
+ margin-bottom: 1em;
+
+
+
+ .inputs ol {
+ margin-top: -0.3em;
+ margin-bottom: 1em;
+ padding: 0;
+ width: 100%;
+ }
+ .inputs ol li { padding : 0.3em 0; }
+
+ .inputs ol li textarea {
+ width: 54%;
+ }
+ .inputs ol li label {
+ width: 40%;
+ margin-top: -0.3em;
+ }
+
+ .inputs ol li.fl label { width: 40%; margin-top: -0.3em; }
+ .inputs ol li.fl input { width: 21%; padding: 0; }
+
+ .inputs ol li.fl1 {float: left; width: 70% ;}
+ .inputs ol li.fl1 label {width: 57%; margin-top: -0.3em; }
+ .inputs ol li.fl1 input { width: 30%; }
+
+ .inputs ol li.fl2 {float: left; width: 25% ;}
+ .inputs ol li.fl2 label {width: 10%; margin-top: -0.3em;}
+ .inputs ol li.fl2 input { width: 85%; }
+
+}
diff --git a/app/controllers/compliance_check_controller.rb b/app/controllers/compliance_check_controller.rb
deleted file mode 100644
index e69de29bb..000000000
--- a/app/controllers/compliance_check_controller.rb
+++ /dev/null
diff --git a/app/controllers/compliance_checks_controller.rb b/app/controllers/compliance_checks_controller.rb
deleted file mode 100644
index e69de29bb..000000000
--- a/app/controllers/compliance_checks_controller.rb
+++ /dev/null
diff --git a/app/controllers/validation_results_controller.rb b/app/controllers/validation_results_controller.rb
new file mode 100644
index 000000000..dde9bcbd2
--- /dev/null
+++ b/app/controllers/validation_results_controller.rb
@@ -0,0 +1,35 @@
+class ValidationResultsController < ChouetteController
+
+ defaults :resource_class => ValidationReport
+
+ respond_to :json
+ respond_to :js, :only => :index
+
+ def index
+ index! do |format|
+ format.html { render :layout => false }
+ end
+ end
+
+ protected
+
+ def validation_service
+ ValidationService.new(@referential)
+ end
+
+ def validation
+ @validation ||= validation_service.find( params[:validation_id] )
+ end
+
+ def validation_report
+ @validation_report ||= validation.report
+ end
+
+ def collection
+ @validation_results ||= validation_report.all(params[:status], params[:severity]) #.paginate(:page => params[:page])
+ end
+
+ def rule_parameter_set
+ @rule_parameter_set = RuleParameterSet.new.tap { |rps| rps.parameters = resource.parameter_set }
+ end
+end
diff --git a/app/controllers/validations_controller.rb b/app/controllers/validations_controller.rb
index e07a51f7f..f25e8763b 100644
--- a/app/controllers/validations_controller.rb
+++ b/app/controllers/validations_controller.rb
@@ -72,9 +72,17 @@ class ValidationsController < ChouetteController
redirect_to referential_path(@referential)
end
end
+
+ def export
+ respond_to do |format|
+ format.zip { send_file ValidationExport.new(resource, @referential.id, request).export, :type => :zip }
+ end
+ end
protected
+ alias_method :validation, :resource
+
def validation_service
ValidationService.new(@referential)
end
@@ -84,7 +92,7 @@ class ValidationsController < ChouetteController
end
def resource
- @validation ||= validation_service.find( params[:id] )
+ @validation ||= validation_service.find(params[:id] )
end
def collection
diff --git a/app/helpers/validation_results_helper.rb b/app/helpers/validation_results_helper.rb
new file mode 100644
index 000000000..c225039a2
--- /dev/null
+++ b/app/helpers/validation_results_helper.rb
@@ -0,0 +1,71 @@
+module ValidationResultsHelper
+
+ def status_icon( validation_result_result, validation_result_severity )
+ if validation_result_result == "UNCHECK"
+ ("<i class='fa fa-ban status_na_" + validation_result_severity.downcase + "'></i>").html_safe
+ elsif validation_result_result == "OK"
+ ("<i class='fa fa-check status_ok_" + validation_result_severity.downcase + "'></i>").html_safe
+ else
+ ("<i class='fa fa-times status_nok_" + validation_result_severity.downcase + "'></i>").html_safe
+ end
+ end
+
+ def test_definition (validation_result_code)
+ Rails.application.config.validation_spec + I18n.locale.to_s + "/" + validation_result_code +".html"
+ end
+
+ def object_url (referential_id, error)
+ location = "/referentials/" + referential_id.to_s
+ if error[:source].object_path.kind_of?(Array)
+ error[:source].object_path.reverse.each { |sub_path| location = location + "/" + sub_path["type"].to_s.pluralize + "/" + sub_path["id"].to_s }
+ else
+ location = location + "/" + error[:source].object_path.type.to_s + "s/" + error[:source].object_path.id.to_s
+ end
+ return location
+ end
+
+ def object_labels_hash (error)
+ ### THE error HASH STRUCTURE
+ # 1. error[:source]
+ # 0..1 file
+ # 1 filename
+ # 0..1 line_number
+ # 0..1 column_number
+ # 0..1 objectid
+ # 0..1 label
+ # 0.. object_path
+ # 1 type
+ # 1 id
+ # 0.. error[:target]
+ # 0..1 error[:error_value]
+ # 0..1 error[:reference_value]
+ object_labels_hash = Hash.new
+ object_labels_hash[:source_objectid] = error[:source].objectid if error[:source].objectid.present?
+ object_labels_hash[:source_label] = error[:source].label if error[:source].label.present?
+ if error[:source].file.present?
+ object_labels_hash[:filename] = error[:source].file.filename
+ object_labels_hash[:line_number] = error[:source].file.line_number if error[:source].file.line_number.present?
+ object_labels_hash[:column_number] = error[:source].file.column_number if error[:source].file.column_number.present?
+ end
+
+ if error[:target].present?
+ if error[:target].kind_of?(Array)
+ error[:target].each_with_index do |target, index|
+ object_labels_hash["target_#{index}_objectid".to_sym] = target[:objectid] if target[:objectid]
+ object_labels_hash["target_#{index}_label".to_sym] = target[:label] if target[:label]
+ end
+ else
+ object_labels_hash[:target_0_objectid] = error[:target][:objectid] if error[:target][:objectid]
+ object_labels_hash[:target_0_label] = error[:target][:label] if error[:target][:label]
+ end
+ end
+ if error[:error_value].present?
+ object_labels_hash[:error_value] = error[:error_value]
+ end
+ if error[:reference_value].present?
+ object_labels_hash[:reference_value] = error[:reference_value]
+ end
+ return object_labels_hash
+ end
+
+end
diff --git a/app/models/export.rb b/app/models/export.rb
index 5cd0db17e..95317504a 100644
--- a/app/models/export.rb
+++ b/app/models/export.rb
@@ -1,6 +1,7 @@
class Export
extend Enumerize
extend ActiveModel::Naming
+ extend ActiveModel::Translation
include ActiveModel::Model
attr_reader :datas
diff --git a/app/models/export_report.rb b/app/models/export_report.rb
index f739bf1a9..a843d8148 100644
--- a/app/models/export_report.rb
+++ b/app/models/export_report.rb
@@ -1,5 +1,6 @@
class ExportReport
extend ActiveModel::Naming
+ extend ActiveModel::Translation
include ActiveModel::Model
attr_reader :datas, :errors, :metadatas
diff --git a/app/models/import.rb b/app/models/import.rb
index 9629881d3..f596fe82a 100644
--- a/app/models/import.rb
+++ b/app/models/import.rb
@@ -1,6 +1,7 @@
class Import
extend Enumerize
extend ActiveModel::Naming
+ extend ActiveModel::Translation
include ActiveModel::Model
# enumerize :status, in: %w{started scheduled terminated canceled aborted}, default: "created", predicates: true
@@ -10,6 +11,7 @@ class Import
def initialize( response )
@datas = response
+ Validation.new(response)
# @status = @datas.status.downcase if @datas.status?
# @format = @datas.type.downcase if @datas.type?
end
diff --git a/app/models/import_report.rb b/app/models/import_report.rb
index fff209e8e..803460fb8 100644
--- a/app/models/import_report.rb
+++ b/app/models/import_report.rb
@@ -1,5 +1,6 @@
class ImportReport
extend ActiveModel::Naming
+ extend ActiveModel::Translation
include ActiveModel::Model
attr_reader :datas
diff --git a/app/models/import_task.rb b/app/models/import_task.rb
index d53c04766..dc1ab1ba7 100644
--- a/app/models/import_task.rb
+++ b/app/models/import_task.rb
@@ -3,6 +3,7 @@ require "zip"
class ImportTask
extend Enumerize
extend ActiveModel::Naming
+ extend ActiveModel::Translation
include ActiveModel::Validations
include ActiveModel::Conversion
diff --git a/app/models/validation.rb b/app/models/validation.rb
index d674c79dc..d97d854cc 100644
--- a/app/models/validation.rb
+++ b/app/models/validation.rb
@@ -1,29 +1,50 @@
class Validation
extend Enumerize
extend ActiveModel::Naming
+ extend ActiveModel::Translation
include ActiveModel::Model
# enumerize :status, in: %w{created scheduled terminated canceled aborted}, default: "created", predicates: true
# enumerize :format, in: %w{neptune netex gtfs}, default: "neptune", predicates: true
attr_reader :datas
-
- def initialize( response )
+
+ def initialize(response)
@datas = response
- # @status = @datas.status.downcase if @datas.status?
- # @format = @datas.type.downcase if @datas.type?
end
def report
- report_path = datas.links.select{ |link| link["rel"] == "action_report"}.first.href
+ report_path = datas.links.select{ |link| link["rel"] == "validation_report"}.first.href
if report_path
response = Ievkit.get(report_path)
ValidationReport.new(response)
else
raise Ievkit::IevError("Impossible to access report path link for validation")
end
- end
+ end
+
+ def import
+ if datas.action == "importer"
+ Import.new(Ievkit.scheduled_job(referential_name, id, { :action => "importer" }) )
+ end
+ end
+
+ def export
+ if datas.action == "exporter"
+ Export.new(Ievkit.scheduled_job(referential_name, id, { :action => "exporter" }) )
+ end
+ end
+ def rule_parameter_set
+ rule_parameter_set = datas.links.select{ |link| link["rel"] == "validation_params"}.first.href
+ if rule_parameter_set
+ response = Ievkit.get(rule_parameter_set)
+ rule_parameter_set = RuleParameterSet.new.tap { |rps| rps.parameters = response.validation }
+ else
+ raise Ievkit::Error("Impossible to access rule parameter set link for validation")
+ end
+ end
+
def compliance_check
compliance_check_path = datas.links.select{ |link| link["rel"] == "validation_report"}.first.href
if compliance_check_path
@@ -57,7 +78,23 @@ class Validation
end
def status
- datas.status
+ # pending processing completed failed
+ # CREATED, SCHEDULED, STARTED, TERMINATED, CANCELED, ABORTED, DELETED
+ if datas.status == "CREATED"
+ "pending"
+ elsif datas.status == "SCHEDULED"
+ "pending"
+ elsif datas.status == "STARTED"
+ "processing"
+ elsif datas.status == "TERMINATED"
+ "completed"
+ elsif datas.status == "CANCELED"
+ "failed"
+ elsif datas.status == "ABORTED"
+ "failed"
+ elsif datas.status == "DELETED"
+ "failed"
+ end
end
def format
@@ -81,6 +118,10 @@ class Validation
20
end
end
+
+ def referential_id
+ Referential.where(:slug => referential_name).id
+ end
def referential_name
datas.referential
diff --git a/app/models/validation_export.rb b/app/models/validation_export.rb
new file mode 100644
index 000000000..86ff2c477
--- /dev/null
+++ b/app/models/validation_export.rb
@@ -0,0 +1,54 @@
+require 'tempfile'
+
+class ValidationExport
+ include ERB::Util
+ include ValidationResultsHelper
+
+ require 'zip'
+
+ attr_accessor :template, :detailed_errors_template, :request
+ attr_reader :validation
+
+ def initialize(validation, referential_id, request)
+ @request = request
+ @validation = validation
+ @referential_id = referential_id
+ @template = File.open('app/views/validations/summary_errors_index.csv.erb' ) { |f| f.read }
+ @detailed_errors_template = File.open('app/views/validations/detailed_errors_index.csv.erb' ) { |f| f.read }
+ end
+
+ def export
+ begin
+ Dir.mktmpdir("#{I18n.t('validation_results.file.zip_name_prefix')}_#{@referential_id}_#{@validation.id}_", Dir.tmpdir) { |temp_dir|
+
+ File.open(temp_dir + "/#{I18n.t('validation_results.file.summary_errors_file_prefix')}" , "a") do |f|
+ f.write(render)
+ f.flush
+ end
+
+ File.open(temp_dir + "/#{I18n.t('validation_results.file.detailed_errors_file_prefix')}" , "a") do |f|
+ f.write(detailed_errors_render)
+ f.flush
+ end
+
+ zip_file = Tempfile.new(["#{I18n.t('validation_results.file.zip_name_prefix')}_#{@referential_id}_#{@validation.id}_", ".zip"])
+
+ ::Zip::File.open(zip_file.path, ::Zip::File::CREATE) do |zipfile|
+ Dir[File.join(temp_dir, '*.csv')].each do |f|
+ zipfile.add(File.basename(f), f)
+ end
+ end
+ return zip_file
+ }
+ end
+ end
+
+ def render()
+ ERB.new(@template).result(binding)
+ end
+
+ def detailed_errors_render()
+ ERB.new(@detailed_errors_template).result(binding)
+ end
+
+end
diff --git a/app/models/validation_report.rb b/app/models/validation_report.rb
index 6c98776cd..7f9b8366d 100644
--- a/app/models/validation_report.rb
+++ b/app/models/validation_report.rb
@@ -1,111 +1,64 @@
class ValidationReport
extend ActiveModel::Naming
+ extend ActiveModel::Translation
include ActiveModel::Model
attr_reader :datas
- def initialize( response )
- @datas = response[:action_report]
+ def initialize(response)
+ @datas = response[:validation_report].tests.sort_by { |hash| [ hash[:severity], hash[:result], hash[:test_id]] }
end
- def zip_file
- datas.zip_file
- end
-
- def error_files
- datas.files.select{ |file| file[:status] == "ERROR"}
- end
-
- def ignored_files
- datas.files.select{ |file| file[:status] == "IGNORED"}
- end
-
- def ok_files
- datas.files.select{ |file| file[:status] == "OK"}
- end
-
- def files
- datas.files
- end
-
- def line_items
- [].tap do |line_items|
- datas.lines.each do |line|
- line_items << LineItem.new(line)
- end
- end
- end
-
- def lines
- datas.stats.line_count if datas.stats.line_count?
+ def ok_error
+ @datas.select { |test| (test[:result] == "OK" && test[:severity] == "ERROR") }
end
- def routes
- datas.stats.route_count if datas.stats.route_count?
+ def nok_error
+ @datas.select { |test| (test[:result] == "NOK" && test[:severity] == "ERROR")}
end
- def connection_links
- datas.stats.connection_link_count if datas.stats.connection_link_count?
+ def na_error
+ @datas.select { |test| (test[:result] == "UNCHECK" && test[:severity] == "ERROR")}
end
-
- def time_tables
- datas.stats.time_table_count if datas.stats.time_table_count?
- end
-
- def stop_areas
- datas.stats.stop_area_count if datas.stats.stop_area_count?
+
+ def ok_warning
+ @datas.select { |test| (test[:result] == "OK" && test[:severity] == "WARNING")}
end
- def access_points
- datas.stats.access_point_count if datas.stats.access_point_count?
+ def nok_warning
+ @datas.select { |test| (test[:result] == "NOK" && test[:severity] == "WARNING")}
end
- def vehicle_journeys
- datas.stats.vehicle_journey_count if datas.stats.vehicle_journey_count?
+ def na_warning
+ @datas.select { |test| (test[:result] == "UNCHECK" && test[:severity] == "WARNING")}
end
- def journey_patterns
- datas.stats.journey_pattern_count if datas.stats.journey_pattern_count?
+ def mandatory_tests
+ @datas.select { |test| test[:severity] == "ERROR"}
end
-
- class LineItem
- attr_reader :name, :status, :stats
-
- def initialize( options = Hashie::Mash.new )
- @name = options.name if options.name?
- @status = options.status if options.status?
- @stats = options.stats if options.stats?
- end
-
- def routes
- stats.route_count
- end
- def connection_links
- stats.connection_link_count
- end
+ def optional_tests
+ @datas.select { |test| test[:severity] == "WARNING"}
+ end
- def time_tables
- stats.time_table_count
- end
+ def ok_tests
+ @datas.select { |test| test[:result] == "OK"}
+ end
- def stop_areas
- stats.stop_area_count
- end
+ def nok_tests
+ @datas.select { |test| test[:result] == "NOK"}
+ end
- def access_points
- stats.access_point_count
- end
-
- def vehicle_journeys
- stats.vehicle_journey_count
- end
+ def uncheck_tests
+ @datas.select { |test| test[:result] == "UNCHECK"}
+ end
- def journey_patterns
- stats.journey_pattern_count
- end
+ def all(status, severity)
+ @datas.select { |test| ( test[:result] == status && test[:severity] == severity ) }
+ end
+ def validation_results
+ return @datas
end
end
-
diff --git a/app/views/compliance_check_tasks/show.html.erb b/app/views/compliance_check_tasks/show.html.erb
index d41e0da1d..a59844378 100644
--- a/app/views/compliance_check_tasks/show.html.erb
+++ b/app/views/compliance_check_tasks/show.html.erb
@@ -30,7 +30,7 @@
</div>
</div>
<div class="order" style="display: none;">
- Filtre : <%= select_tag "order", ("<option value='severity'>" + ComplianceCheckResult.human_attribute_name(:severity) +"</option><option value='status'>" + ComplianceCheckResult.human_attribute_name(:status) + "</option>").html_safe, :include_blank => false %>
+ Filtre : <!-- %= select_tag "order", ("<option value='severity'>" + ComplianceCheckResult.human_attribute_name(:severity) +"</option><option value='status'>" + ComplianceCheckResult.human_attribute_name(:status) + "</option>").html_safe, :include_blank => false % -->
</div>
<div class="report"></div>
diff --git a/app/views/exports/_export.erb b/app/views/exports/_export.erb
index 1477c63bc..c5d8b7002 100644
--- a/app/views/exports/_export.erb
+++ b/app/views/exports/_export.erb
@@ -2,7 +2,9 @@
<div class="panel-heading">
<div class="panel-title clearfix">
<span class="pull-right">
- <% location = export.datas.links.select { |link| link["rel"] == "location" }.first.href %>
+ <% location = export.datas.links.select { |link| link["rel"] == "location" } %>
+ <% location = location.first if location %>
+ <% location = location.href if location %>
<%= link_to "#{location}", :method => :delete, :data => {:confirm => t('exports.actions.destroy_confirm')}, :class => "btn btn-danger btn-sm" do %>
<span class="fa fa-trash-o"></span>
<% end %>
diff --git a/app/views/imports/_import.erb b/app/views/imports/_import.erb
index 8245e23e3..14e29cb32 100644
--- a/app/views/imports/_import.erb
+++ b/app/views/imports/_import.erb
@@ -2,7 +2,9 @@
<div class="panel-heading">
<div class="panel-title clearfix">
<span class="pull-right">
- <% location = import.datas.links.select { |link| link["rel"] == "location" }.first.href %>
+ <% location = import.datas.links.select { |link| link["rel"] == "location" } %>
+ <% location = location.first if location %>
+ <% location = location.href if location %>
<%= link_to referential_import_path(@referential, import.id), :method => :delete, :data => {:confirm => t('import_tasks.actions.destroy_confirm')}, :class => "btn btn-danger btn-sm" do %>
<span class="fa fa-trash-o"></span>
<% end %>
diff --git a/app/views/shared/_header.erb b/app/views/shared/_header.erb
index d90117859..1d8b3ca66 100644
--- a/app/views/shared/_header.erb
+++ b/app/views/shared/_header.erb
@@ -69,7 +69,7 @@
</li>
<li><%= link_to Referential.human_attribute_name("imports"), referential_imports_path(@referential) %></li>
<li><%= link_to Referential.human_attribute_name("export_tasks"), referential_exports_path(@referential) %></li>
- <li><%= link_to Referential.human_attribute_name("compliance_check_tasks"), referential_compliance_check_tasks_path(@referential) %></li>
+ <li><%= link_to Referential.human_attribute_name("validations"), referential_validations_path(@referential) %></li>
<% end %>
</ul>
<ul class="nav navbar-nav navbar-right">
diff --git a/app/views/validation_results/_validation_result.erb b/app/views/validation_results/_validation_result.erb
new file mode 100644
index 000000000..43baf0a0e
--- /dev/null
+++ b/app/views/validation_results/_validation_result.erb
@@ -0,0 +1,21 @@
+ <div class="severity_<%= validation_result.severity %> status_<%= validation_result.status %>">
+ <div class="status_icon">
+ <%= image_tag "icons/status_#{validation_result.status}.png", :class => "status" %>
+ </div>
+ <div class="status_text">
+ <div class="code">
+ <%= validation_result.rule_code %>
+ </div>
+ <div class="severity">
+ [ <%= ValidationReport.human_attribute_name(:severity) %> : <%= t validation_result.severity, :scope => "validation_result.severities" %> ]
+ </div>
+ <div class="explanation">
+ <%= ValidationReport.human_attribute_name(validation_result.rule_code) %>
+ </div>
+ <div class="attributes">
+ <% if validation_result.violation_count > 0 %>
+ <%= ValidationReport.human_attribute_name(:violation_count) %> :
+ <% end %>
+ </div>
+ </div>
+</div>
diff --git a/app/views/validation_results/index.html.erb b/app/views/validation_results/index.html.erb
new file mode 100644
index 000000000..c93f8f2bd
--- /dev/null
+++ b/app/views/validation_results/index.html.erb
@@ -0,0 +1,75 @@
+<table class="table table-hover">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th><%= t("activemodel.attributes.validation_result.status") %></th>
+ <th><%= t("activemodel.attributes.validation_result.severity") %></th>
+ <th><%= t("activemodel.attributes.validation_result.rule_code") %></th>
+ <% if @validation_results && @validation_results.first.result == "NOK" %>
+ <th><%= t("activemodel.attributes.validation_result.detail") %></th>
+ <% end %>
+ </tr>
+ </thead>
+ <tbody>
+ <% @validation_results.each_with_index do |validation_result, index| %>
+ <tr>
+ <td><%= index + 1 %></td>
+ <td><%= status_icon( validation_result.result, validation_result.severity ) %> </td>
+ <td><%= t("validation_result.severities." + validation_result.severity.downcase + "_txt") %></td>
+ <td>
+ <% data_content = t ( "activemodel.attributes.validation_result." + validation_result.test_id ) %>
+ <% data_title = t ( "activemodel.attributes.validation_result.title" ) %>
+ <button data-content='<%= data_content %>' data-title='<%= data_title %>' rel="popover" data-toggle="popover" class="notice btn btn-info btn-xs" >
+ <i class="fa fa-info"></i>
+ </button>
+ <%= link_to validation_result.test_id, test_definition(validation_result.test_id), :title => ValidationReport.human_attribute_name(validation_result.test_id), :target => "validation" %>
+ </td>
+ <% if @validation_results && @validation_results.first.result == "NOK" %>
+ <td class="td_error">
+ <% if validation_result.errors.present? %>
+ <span class="title_error">
+ <i class="fa fa-plus-square"></i>
+ <%= validation_result.error_count.to_s + " " + ValidationReport.human_attribute_name("validation_result.violation_count") %>
+ </span>
+ <div class="details_error">
+ <% validation_result.errors.first(10).each do |error| %>
+ <p class="detail_error">
+ <% if error[:source].objectid %>
+ <!-- % data_content_1 = ValidationReport.human_attribute_name(validation_result.test_id) + t("validation_result.details." + error[:error_id]) % --> <!--, error[:source].objectid ) % -->
+ <% data_content_1 = t("activemodel.attributes.validation_result." + validation_result.test_id) + ". " +
+ t("validation_result.details.detail_" + error[:error_id], object_labels_hash(error) ) %>
+ <% data_title_1 = t("activemodel.attributes.validation_result.detail") %>
+ |- <button data-content='<%= data_content_1 %>' data-title='<%= data_title_1 %>' data-toggle="popover" class="notice btn btn-info btn-xs"><i class="fa fa-info"></i></button>
+ <% else %>
+ <!-- % data_content_2 = ValidationReport.human_attribute_name(validation_result.test_id) + t("validation_result.detailss." + error[:error_id] ) % -->
+ <% data_content_2 = ValidationReport.human_attribute_name(validation_result.test_id) + t("validation_result.details." + error[:error_id] ) %>
+ <% data_title_2 = t("activemodel.attributes.validation_result.detail") %>
+ |- <button data-content='<%= data_content_2 %>' data-title='<%= data_title_2 %>' data-toggle="popover" class="notice btn btn-info btn-xs"><i class="fa fa-info"></i></button>
+ <% end %>
+ <% if error[:source].object_path.present? %>
+ <%= link_to error[:source].label, object_url(@referential.id, error) %>
+ <% end %>
+ <!-- %= link_to error["objectId"], referential_path(@referential) + "/" + error["location"]["url"] % -->
+ <!-- % elsif error["location"]["filename"].present? % -->
+ <!-- %= error["objectId"] % --><br>
+ <span class="file_error">
+ <%= error[:source].objectid %>
+ <!-- %= File.basename(error["location"]["filename"]) % -->
+ <!-- %= t("validation_results.index.column") % -->:
+ <!-- %= error["location"]["columnNumber"] % -->,
+ <!-- %= t("validation_results.index.line") % -->:
+ <!-- %= error["location"]["lineNumber"] % -->
+ </span>
+ <!-- % end % -->
+ </p>
+ <% end %>
+ </div>
+ <% end %>
+ </td>
+ <% end %>
+ </tr>
+ <% end %>
+ </tbody>
+</table>
+<%= javascript_include_tag referential_validation_validation_results_path(@referential, @validation.id, :format => :js) %>
+
diff --git a/app/views/validation_results/index.js.coffee b/app/views/validation_results/index.js.coffee
new file mode 100644
index 000000000..10821a031
--- /dev/null
+++ b/app/views/validation_results/index.js.coffee
@@ -0,0 +1,8 @@
+jQuery ->
+ $(".notice").popover({ container: "body", html: false, trigger: "focus", placement: "bottom" })
+
+ # Hide and show error details
+ $(".title_error").each ->
+ $( this ).click ->
+ $(this).next(".details_error").toggle()
+ $(this).children("i").toggleClass("fa-plus-square fa-minus-square") \ No newline at end of file
diff --git a/app/views/validations/_validation.erb b/app/views/validations/_validation.erb
index d288c8b7e..85e1b3101 100644
--- a/app/views/validations/_validation.erb
+++ b/app/views/validations/_validation.erb
@@ -2,7 +2,9 @@
<div class="panel-heading">
<div class="panel-title clearfix">
<span class="pull-right">
- <% location = validation.datas.links.select { |link| link["rel"] == "location" }.first.href %>
+ <% location = validation.datas.links.select { |link| link["rel"] == "location" } %>
+ <% location = location.first if location %>
+ <% location = location.href if location %>
<%= link_to "#{location}", :method => :delete, :data => {:confirm => t('validation_tasks.actions.destroy_confirm')}, :class => "btn btn-danger btn-sm" do %>
<span class="fa fa-trash-o"></span>
<% end %>
diff --git a/app/views/validations/detailed_errors_index.csv.erb b/app/views/validations/detailed_errors_index.csv.erb
new file mode 100644
index 000000000..3c727f9a4
--- /dev/null
+++ b/app/views/validations/detailed_errors_index.csv.erb
@@ -0,0 +1,2 @@
+<%= I18n.t("activemodel.attributes.validation_result.severity") %>;<%= I18n.t("activemodel.attributes.validation_result.rule_code") %>;<%= I18n.t("activemodel.attributes.validation_result.object") %>;<%= I18n.t("activemodel.attributes.validation_result.resource") %>;<%= I18n.t("activemodel.attributes.validation_result.title") %>;<%= I18n.t("activemodel.attributes.validation_result.detail") %>
+<% @validation.report.validation_results.each do |r| %><% if r.errors.present? %><% r.errors.first(10).each do |error| %><% case r.severity %><% when "WARNING" %><%= I18n.t "validation_result.severities.warning_txt" %><% when "ERROR" %><%= I18n.t "validation_result.severities.error_txt" %><% end %>;<%= r.test_id %>;<% if error["source"].present? %><%= error["source"]["objectid"] if error["source"]["objectid"].present? %>;<% if error["source"]["object_path"].present? %><%= object_url(@referential_id, error) %><% elsif error["source"]["file"].present? %><%= File.basename(error["source"]["file"]["filename"]) +" - " %><%= I18n.t "validation_results.index.column" %>:<%= error["source"]["file"]["column_number"] %>,<%= I18n.t "validation_results.index.line" %>:<%= error["source"]["file"]["line_number"] %><% end %>;<% else %>;;<% end %><%= I18n.t("activemodel.attributes.validation_result."+r.test_id) %>;<%= I18n.t("validation_result.details.detail_" + error["error_id"], object_labels_hash(error) )%><%= "\n" %><% end %><% end %><% end %> \ No newline at end of file
diff --git a/app/views/validations/show.html.erb b/app/views/validations/show.html.erb
index b7b655850..d0537c81b 100644
--- a/app/views/validations/show.html.erb
+++ b/app/views/validations/show.html.erb
@@ -1,15 +1,63 @@
-<div class="test">
- <% title = @validation.no_save ? "": "<i class='fa fa-save'></i>" %>
- <%= title_tag "#{title} #{@validation.name} <span class='status status_#{@validation.status}'>#{ t('validations.statuses.'+ @validation.status) }</span>" %>
-</div>
+<%= title_tag "#{@validation.name} <span class='status status_#{@validation.status}'>#{ t('validations.show.'+@validation.status) }</span>" %>
+<% @title = "#{@validation.name}" %>
<div class="validation_show">
- <%= render( :partial => "results_dashboard", :locals => { :referential => @referential} ) %>
+ <div class="links">
+ <% if @validation.import %>
+ <%= link_to image_tag('icons/link_page.png') + t("compliance_check_tasks.import_task"), referential_import_path(@referential, @validation.import) %>
+ <% elsif @validation.export %>
+ <%= link_to image_tag('icons/link_page.png') + t("compliance_check_tasks.export_task"), referential_export_path(@referential, @validation.export) %>
+ <% end %>
+ <%= link_to image_tag('icons/link_page.png') + t("compliance_check_tasks.rule_parameter_set"), organisation_rule_parameter_set_path(@referential.organisation, @validation.rule_parameter_set) %>
+ <div class="btn-group pull-right">
+ <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
+ <%= t(".export") %> <span class="caret"></span>
+ </button>
+ <ul class="dropdown-menu" role="menu">
+ <li><%= link_to t(".export_csv"), export_referential_validation_path(@referential, @validation.id) %></li>
+ </ul>
+ </div>
+
+ <!-- % if @validation.status == 'completed'% -->
+ <div class="resume">
+ <div class="col1">
+ <div class="caption">
+ <%= t "validation_result.severities.error" %>
+ </div>
+ <div class="graph" id="error">
+ </div>
+ </div>
+ <div class="col2">
+ <div class="caption">
+ <%= t "validation_result.severities.warning" %>
+ </div>
+ <div class="graph" id="warning">
+ </div>
+ </div>
+ </div>
+ <div class="order" style="display: none;">
+ Filtre : <%= select_tag "order", ("<option value='severity'>" + ComplianceCheckResult.human_attribute_name(:severity) +"</option><option value='status'>" + ComplianceCheckResult.human_attribute_name(:status) + "</option>").html_safe, :include_blank => false %>
+ </div>
+
+ <div class="report">
+ </div>
+ <!-- % end % -->
+ <%= javascript_include_tag referential_validation_path(@referential, @validation.id, :format => :js) %>
+ </div>
</div>
+
+<!-- div class="validation_show" -->
+ <!-- %= render( :partial => "results_dashboard", :locals => { :referential => @referential} ) % -->
+<!-- /div -->
+
<% content_for :sidebar do %>
<ul class="actions">
- <li><%= link_to t('validations.actions.destroy'), referential_validation_path(@referential, @validation.id), :method => :delete, :data => {:confirm => t('validations.actions.destroy_confirm')}, :class => "remove" %></li>
+ <li>
+ <% unless (@validation.import || @validation.export) %>
+ <%= link_to t('validations.actions.destroy'), referential_validation_path(@referential, @validation.id), :method => :delete, :data => {:confirm => t('validations.actions.destroy_confirm')}, :class => "remove" %>
+ <% end %>
+ </li>
</ul>
<%= history_tag(@validation) %>
diff --git a/app/views/validations/show.js.coffee b/app/views/validations/show.js.coffee
index e74612354..19455f4c7 100644
--- a/app/views/validations/show.js.coffee
+++ b/app/views/validations/show.js.coffee
@@ -1,45 +1,50 @@
jQuery ->
-
- get_validation_results = (html_container, html_element) ->
- html_container.children().each ->
- if( $( this ).is(html_element) )
- $( this ).show()
- else
- $( this ).hide()
+
+ get_validation_results = (html_container, status, severity) ->
+ h = new Object()
+ h["status"] = status if status
+ h["severity"] = severity if severity
+
+ $.get(
+ "<%= @validation.id %>/validation_results",
+ h,
+ update = (data) ->
+ html_container.empty()
+ html_container.append(data)
+ )
Morris.Donut({
- element: 'files_statistics',
+ element: 'error',
data: [
- {label: "<%= t 'validations.show.graph.files.error' %>", value: <%= @validation.report.error_files.count %> },
- {label: "<%= t 'validations.show.graph.files.ignored' %>", value: <%= @validation.report.ignored_files.count %> },
- {label: "<%= t 'validations.show.graph.files.ok' %>", value: <%= @validation.report.ok_files.count %> }
+ {label: "<%= t 'nok', :scope => 'validation_result.statuses' %>", value: <%= @validation.report.nok_error.count %>},
+ {label: "<%= t 'na', :scope => 'validation_result.statuses' %>", value: <%= @validation.report.na_error.count %>},
+ {label: "<%= t 'ok', :scope => 'validation_result.statuses' %>", value: <%= @validation.report.ok_error.count %>}
]
colors: [ "#e22b1b", "#898e7f", "#8fc861" ]
}).on('click', update = (i, row) ->
- switch i
- when 0 then get_validation_results( $(".report"), $(".files_error"))
- when 1 then get_validation_results( $(".report"), $(".files_ignored"))
- when 2 then get_validation_results( $(".report"), $(".files_ok"))
- else console.log "Error no other value for donut chart")
+ switch i
+ when 0 then get_validation_results( $(".report"), "NOK", "ERROR")
+ when 1 then get_validation_results( $(".report"), "UNCHECK", "ERROR")
+ when 2 then get_validation_results( $(".report"), "OK", "ERROR")
+ else console.log "Error no other value for donut chart")
- Morris.Bar({
- element: 'objects_statistics',
+ Morris.Donut({
+ element: 'warning',
data: [
- { object: "<%= t("validations.show.graph.lines.lines_stats").html_safe %>", value: <%= @validation.report.lines %> },
- { object: "<%= t("validations.show.graph.lines.routes_stats").html_safe %>", value: <%= @validation.report.routes %> },
- { object: "<%= t("validations.show.graph.lines.connection_links_stats").html_safe %>", value: <%= @validation.report.connection_links %> },
- { object: "<%= t("validations.show.graph.lines.time_tables_stats").html_safe %>", value: <%= @validation.report.time_tables %> },
- { object: "<%= t("validations.show.graph.lines.stop_areas_stats").html_safe %>", value: <%= @validation.report.stop_areas %> },
- { object: "<%= t("validations.show.graph.lines.access_points_stats").html_safe %>", value: <%= @validation.report.access_points %> },
- { object: "<%= t("validations.show.graph.lines.vehicle_journeys_stats").html_safe %>", value: <%= @validation.report.vehicle_journeys %> },
- { object: "<%= t("validations.show.graph.lines.journey_patterns_stats").html_safe %>", value: <%= @validation.report.journey_patterns %> },
- ],
- xkey: 'object',
- ykeys: ['value'],
- labels: ['<%= t "validations.show.graph.lines.objects_label" %>']
- xLabelAngle: 40,
- xAxisLabelTopPadding: 7,
- padding: 40,
- hideHover: true
+ {label: "<%= t 'nok', :scope => 'validation_result.statuses' %>", value: <%= @validation.report.nok_warning.count %>},
+ {label: "<%= t 'na', :scope => 'validation_result.statuses' %>", value: <%= @validation.report.na_warning.count %>},
+ {label: "<%= t 'ok', :scope => 'validation_result.statuses' %>", value: <%= @validation.report.ok_warning.count %>}
+ ]
+ colors: [ "#ffbd2b", "#898e7f", "#8fc861" ]
}).on('click', update = (i, row) ->
- get_validation_results( $(".report"), $(".lines")) ) \ No newline at end of file
+ switch i
+ when 0 then get_validation_results( $(".report"), "NOK", "WARNING")
+ when 1 then get_validation_results( $(".report"), "UNCHECK", "WARNING")
+ when 2 then get_validation_results( $(".report"), "OK", "WARNING")
+ else console.log "Error no other value for donut chart")
+
+ $(".resume .col1 .caption").click ->
+ get_validation_results( $(".report"), null, "ERROR")
+
+ $(".resume .col2 .caption").click ->
+ get_validation_results( $(".report"), null, "warning")
diff --git a/app/views/validations/summary_errors_index.csv.erb b/app/views/validations/summary_errors_index.csv.erb
new file mode 100644
index 000000000..cec4d2e09
--- /dev/null
+++ b/app/views/validations/summary_errors_index.csv.erb
@@ -0,0 +1,3 @@
+<%= I18n.t("activemodel.attributes.validation_result.severity") %>;<%= I18n.t("activemodel.attributes.validation_result.status") %>;<%= I18n.t("activemodel.attributes.validation_result.rule_code") %>;<%= I18n.t("activemodel.attributes.validation_result.title") %>;<%= I18n.t("activemodel.attributes.validation_result.url") %>;<%= I18n.t("activemodel.attributes.validation_result.violation_count_txt") %>;<%= I18n.t("activemodel.attributes.validation_result.objects") %>
+<% @validation.report.validation_results.each do |r| %><% case r.severity %><% when "WARNING" %><%= I18n.t "validation_result.severities.warning_txt" %><% when "ERROR" %><%= I18n.t "validation_result.severities.error_txt" %><% end %>;<%= r.result %>;<%= r.test_id %>;<%= I18n.t("activemodel.attributes.validation_result."+r.test_id) %>;<%= Rails.application.config.validation_spec + I18n.locale.to_s + "/" + r.test_id + ".html" %>;<%= r.error_count %><% if r.error_count > 0 %><% if r.errors.present? %>;<% r.errors.first(10).each do |error| %><% if error["source"] %><%= error["source"]["objectid"] + " " %><% else %><%= " " %><% end %><% end %><% end %><% end %>
+<% end %> \ No newline at end of file