Merge pull request #4906 from betagouv/dev

2020-03-18-01
This commit is contained in:
Keirua 2020-03-18 14:24:46 +01:00 committed by GitHub
commit 584d5f1812
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
65 changed files with 871 additions and 387 deletions

View file

@ -116,6 +116,9 @@ jobs:
eval $COMMAND eval $COMMAND
- store_test_results: - store_test_results:
path: ~/test_results path: ~/test_results
- store_artifacts:
path: tmp/capybara
destination: screenshots
lint: lint:
<<: *defaults <<: *defaults
steps: steps:

View file

@ -1,6 +1,9 @@
require: require:
- rubocop/rspec/focused - rubocop/rspec/focused
- ./lib/cops/unscoped.rb - ./lib/cops/unscoped.rb
inherit_gem:
rubocop-rails_config:
- config/rails.yml
AllCops: AllCops:
Exclude: Exclude:
@ -30,13 +33,13 @@ Gemspec/RequiredRubyVersion:
Layout/AccessModifierIndentation: Layout/AccessModifierIndentation:
Enabled: true Enabled: true
Layout/AlignArray: Layout/ArrayAlignment:
Enabled: true Enabled: true
Layout/AlignHash: Layout/HashAlignment:
Enabled: false Enabled: false
Layout/AlignParameters: Layout/ParameterAlignment:
Enabled: true Enabled: true
EnforcedStyle: with_fixed_indentation EnforcedStyle: with_fixed_indentation
@ -89,6 +92,7 @@ Layout/EmptyLineAfterGuardClause:
# FIXME: private should not be a column name on TypeDeChamp # FIXME: private should not be a column name on TypeDeChamp
Layout/EmptyLinesAroundAccessModifier: Layout/EmptyLinesAroundAccessModifier:
Enabled: true Enabled: true
EnforcedStyle: around
Exclude: Exclude:
- "spec/factories/type_de_champ.rb" - "spec/factories/type_de_champ.rb"
@ -141,22 +145,23 @@ Layout/FirstMethodParameterLineBreak:
Layout/FirstParameterIndentation: Layout/FirstParameterIndentation:
Enabled: true Enabled: true
Layout/IndentArray: Layout/FirstArrayElementIndentation:
Enabled: true Enabled: true
EnforcedStyle: consistent EnforcedStyle: consistent
Layout/IndentAssignment: Layout/AssignmentIndentation:
Enabled: true Enabled: true
Layout/IndentHash: Layout/FirstHashElementIndentation:
Enabled: true Enabled: true
EnforcedStyle: consistent EnforcedStyle: consistent
Layout/IndentHeredoc: Layout/HeredocIndentation:
Enabled: true Enabled: true
Layout/IndentationConsistency: Layout/IndentationConsistency:
Enabled: true Enabled: true
EnforcedStyle: normal
Layout/IndentationWidth: Layout/IndentationWidth:
Enabled: true Enabled: true
@ -275,7 +280,7 @@ Layout/SpaceInsideStringInterpolation:
Layout/Tab: Layout/Tab:
Enabled: true Enabled: true
Layout/TrailingBlankLines: Layout/TrailingEmptyLines:
Enabled: true Enabled: true
Layout/TrailingWhitespace: Layout/TrailingWhitespace:
@ -314,7 +319,7 @@ Lint/DuplicateCaseCondition:
Lint/DuplicateMethods: Lint/DuplicateMethods:
Enabled: true Enabled: true
Lint/DuplicatedKey: Lint/DuplicateHashKey:
Enabled: true Enabled: true
Lint/EachWithObjectArgument: Lint/EachWithObjectArgument:
@ -347,7 +352,7 @@ Lint/FloatOutOfRange:
Lint/FormatParameterMismatch: Lint/FormatParameterMismatch:
Enabled: true Enabled: true
Lint/HandleExceptions: Lint/SuppressedException:
Enabled: false Enabled: false
Lint/ImplicitStringConcatenation: Lint/ImplicitStringConcatenation:
@ -374,7 +379,7 @@ Lint/Loop:
Lint/MissingCopEnableDirective: Lint/MissingCopEnableDirective:
Enabled: true Enabled: true
Lint/MultipleCompare: Lint/MultipleComparison:
Enabled: true Enabled: true
Lint/NestedMethodDefinition: Lint/NestedMethodDefinition:
@ -445,7 +450,7 @@ Lint/ShadowedException:
Lint/ShadowingOuterLocalVariable: Lint/ShadowingOuterLocalVariable:
Enabled: false Enabled: false
Lint/StringConversionInInterpolation: Lint/RedundantStringCoercion:
Enabled: true Enabled: true
Lint/Syntax: Lint/Syntax:
@ -457,16 +462,16 @@ Lint/UnderscorePrefixedVariableName:
Lint/UnifiedInteger: Lint/UnifiedInteger:
Enabled: true Enabled: true
Lint/UnneededCopDisableDirective: Lint/RedundantCopDisableDirective:
Enabled: true Enabled: true
Lint/UnneededCopEnableDirective: Lint/RedundantCopEnableDirective:
Enabled: true Enabled: true
Lint/UnneededRequireStatement: Lint/RedundantRequireStatement:
Enabled: true Enabled: true
Lint/UnneededSplatExpansion: Lint/RedundantSplatExpansion:
Enabled: false Enabled: false
Lint/UnreachableCode: Lint/UnreachableCode:
@ -519,7 +524,7 @@ Metrics/ClassLength:
Metrics/CyclomaticComplexity: Metrics/CyclomaticComplexity:
Enabled: false Enabled: false
Metrics/LineLength: Layout/LineLength:
Enabled: false Enabled: false
Metrics/MethodLength: Metrics/MethodLength:
@ -567,10 +572,10 @@ Naming/MethodName:
Naming/PredicateName: Naming/PredicateName:
Enabled: false Enabled: false
Naming/UncommunicativeBlockParamName: Naming/BlockParameterName:
Enabled: true Enabled: true
Naming/UncommunicativeMethodParamName: Naming/MethodParameterName:
Enabled: false Enabled: false
Naming/VariableName: Naming/VariableName:
@ -593,6 +598,8 @@ Performance/CompareWithBlock:
Performance/Count: Performance/Count:
Enabled: true Enabled: true
Exclude:
- "app/services/administrateur_usage_statistics_service.rb"
Performance/Detect: Performance/Detect:
Enabled: true Enabled: true
@ -609,9 +616,6 @@ Performance/FixedSize:
Performance/FlatMap: Performance/FlatMap:
Enabled: true Enabled: true
Performance/LstripRstrip:
Enabled: true
Performance/RangeInclude: Performance/RangeInclude:
Enabled: true Enabled: true
@ -624,7 +628,7 @@ Performance/RedundantMatch:
Performance/RedundantMerge: Performance/RedundantMerge:
Enabled: true Enabled: true
Performance/RedundantSortBy: Style/RedundantSortBy:
Enabled: true Enabled: true
Performance/RegexpMatch: Performance/RegexpMatch:
@ -633,7 +637,7 @@ Performance/RegexpMatch:
Performance/ReverseEach: Performance/ReverseEach:
Enabled: true Enabled: true
Performance/Sample: Style/Sample:
Enabled: true Enabled: true
Performance/Size: Performance/Size:
@ -669,6 +673,12 @@ Rails/ApplicationJob:
Rails/ApplicationRecord: Rails/ApplicationRecord:
Enabled: true Enabled: true
Rails/ApplicationController:
Enabled: false
Rails/RakeEnvironment:
Enabled: false
Rails/Blank: Rails/Blank:
Enabled: true Enabled: true
@ -707,7 +717,7 @@ Rails/Exit:
Enabled: true Enabled: true
Rails/FilePath: Rails/FilePath:
Enabled: true Enabled: false
Rails/FindBy: Rails/FindBy:
Enabled: true Enabled: true
@ -754,6 +764,9 @@ Rails/Present:
Rails/ReadWriteAttribute: Rails/ReadWriteAttribute:
Enabled: false Enabled: false
Rails/RedundantAllowNil:
Enabled: false
Rails/RedundantReceiverInWithOptions: Rails/RedundantReceiverInWithOptions:
Enabled: true Enabled: true
@ -766,9 +779,6 @@ Rails/RequestReferer:
Rails/ReversibleMigration: Rails/ReversibleMigration:
Enabled: false Enabled: false
Rails/SafeNavigation:
Enabled: true
Rails/SaveBang: Rails/SaveBang:
Enabled: false Enabled: false
@ -846,9 +856,6 @@ Style/BlockDelimiters:
Exclude: Exclude:
- "spec/**/*" - "spec/**/*"
Style/BracesAroundHashParameters:
Enabled: false
Style/CaseEquality: Style/CaseEquality:
Enabled: true Enabled: true
@ -955,9 +962,6 @@ Style/EvenOdd:
Style/ExpandPathArguments: Style/ExpandPathArguments:
Enabled: true Enabled: true
Style/FlipFlop:
Enabled: true
Style/For: Style/For:
Enabled: true Enabled: true
@ -965,7 +969,7 @@ Style/FormatString:
Enabled: true Enabled: true
Style/FormatStringToken: Style/FormatStringToken:
Enabled: true Enabled: false
EnforcedStyle: template EnforcedStyle: template
Style/FrozenStringLiteralComment: Style/FrozenStringLiteralComment:
@ -1267,13 +1271,13 @@ Style/TrivialAccessors:
Style/UnlessElse: Style/UnlessElse:
Enabled: true Enabled: true
Style/UnneededCapitalW: Style/RedundantCapitalW:
Enabled: true Enabled: true
Style/UnneededInterpolation: Style/RedundantInterpolation:
Enabled: true Enabled: true
Style/UnneededPercentQ: Style/RedundantPercentQ:
Enabled: true Enabled: true
Style/VariableInterpolation: Style/VariableInterpolation:

13
Gemfile
View file

@ -9,7 +9,6 @@ gem 'activestorage-openstack'
gem 'administrate' gem 'administrate'
gem 'after_party' gem 'after_party'
gem 'anchored' gem 'anchored'
gem 'axlsx', '~> 3.0.0.pre' # https://github.com/randym/axlsx/issues/501#issuecomment-373640365
gem 'bcrypt' gem 'bcrypt'
gem 'bootstrap-sass', '>= 3.4.1' gem 'bootstrap-sass', '>= 3.4.1'
gem 'bootstrap-wysihtml5-rails', '~> 0.3.3.8' gem 'bootstrap-wysihtml5-rails', '~> 0.3.3.8'
@ -29,8 +28,6 @@ gem 'dotenv-rails', require: 'dotenv/rails-now' # dotenv should always be loaded
gem 'flipper' gem 'flipper'
gem 'flipper-active_record' gem 'flipper-active_record'
gem 'flipper-ui' gem 'flipper-ui'
gem 'fog-openstack'
gem 'font-awesome-rails'
gem 'geocoder' gem 'geocoder'
gem 'gon' gem 'gon'
gem 'graphiql-rails' gem 'graphiql-rails'
@ -48,12 +45,10 @@ gem 'mailjet'
gem 'omniauth-github' gem 'omniauth-github'
gem 'omniauth-rails_csrf_protection', '~> 0.1' gem 'omniauth-rails_csrf_protection', '~> 0.1'
gem 'openid_connect' gem 'openid_connect'
gem 'openstack'
gem 'pg' gem 'pg'
gem 'phonelib' gem 'phonelib'
gem 'prawn' # PDF Generation gem 'prawn-rails' # PDF Generation
gem 'prawn-svg' gem 'prawn-svg'
gem 'prawn_rails'
gem 'premailer-rails' gem 'premailer-rails'
gem 'puma' # Use Puma as the app server gem 'puma' # Use Puma as the app server
gem 'pundit' gem 'pundit'
@ -63,15 +58,14 @@ gem 'rails'
gem 'rails-i18n' # Locales par défaut gem 'rails-i18n' # Locales par défaut
gem 'rake-progressbar', require: false gem 'rake-progressbar', require: false
gem 'react-rails' gem 'react-rails'
gem 'rest-client'
gem 'rgeo-geojson' gem 'rgeo-geojson'
gem 'sanitize-url' gem 'sanitize-url'
gem 'sassc-rails' # Use SCSS for stylesheets gem 'sassc-rails' # Use SCSS for stylesheets
gem 'scenic'
gem 'sentry-raven' gem 'sentry-raven'
gem 'skylight' gem 'skylight'
gem 'smart_listing' gem 'smart_listing'
gem 'spreadsheet_architect' gem 'spreadsheet_architect'
gem 'sprockets', '< 4'
gem 'turbolinks' # Turbolinks makes following links in your web application faster gem 'turbolinks' # Turbolinks makes following links in your web application faster
gem 'typhoeus' gem 'typhoeus'
gem 'warden' gem 'warden'
@ -103,6 +97,7 @@ group :development do
gem 'haml-lint' gem 'haml-lint'
gem 'letter_opener_web' gem 'letter_opener_web'
gem 'rubocop', require: false gem 'rubocop', require: false
gem 'rubocop-rails_config'
gem 'rubocop-rspec-focused', require: false gem 'rubocop-rspec-focused', require: false
gem 'scss_lint', require: false gem 'scss_lint', require: false
gem 'web-console' gem 'web-console'
@ -114,7 +109,7 @@ group :development, :test do
gem 'graphql-schema_comparator' gem 'graphql-schema_comparator'
gem 'mina', git: 'https://github.com/mina-deploy/mina.git', require: false # Deploy gem 'mina', git: 'https://github.com/mina-deploy/mina.git', require: false # Deploy
gem 'pry-byebug' gem 'pry-byebug'
gem 'rspec-rails' gem 'rspec-rails', '~> 4.0.0.beta'
gem 'rspec_junit_formatter', require: false gem 'rspec_junit_formatter', require: false
gem 'ruby-debug-ide', require: false gem 'ruby-debug-ide', require: false
gem 'simple_xlsx_reader' gem 'simple_xlsx_reader'

View file

@ -78,16 +78,16 @@ GEM
tzinfo (~> 1.1) tzinfo (~> 1.1)
addressable (2.7.0) addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0) public_suffix (>= 2.0.2, < 5.0)
administrate (0.11.0) administrate (0.12.0)
actionpack (>= 4.2, < 6.0) actionpack (>= 4.2)
actionview (>= 4.2, < 6.0) actionview (>= 4.2)
activerecord (>= 4.2, < 6.0) activerecord (>= 4.2)
autoprefixer-rails (>= 6.0) autoprefixer-rails (>= 6.0)
datetime_picker_rails (~> 0.0.7) datetime_picker_rails (~> 0.0.7)
jquery-rails (>= 4.0) jquery-rails (>= 4.0)
kaminari (>= 1.0) kaminari (>= 1.0)
momentjs-rails (~> 2.8) momentjs-rails (~> 2.8)
sass-rails (~> 5.0) sassc-rails (~> 2.1)
selectize-rails (~> 0.6) selectize-rails (~> 0.6)
aes_key_wrap (1.0.1) aes_key_wrap (1.0.1)
after_party (1.10.0) after_party (1.10.0)
@ -95,16 +95,11 @@ GEM
arel (9.0.0) arel (9.0.0)
ast (2.4.0) ast (2.4.0)
attr_required (1.0.1) attr_required (1.0.1)
autoprefixer-rails (9.4.4) autoprefixer-rails (9.7.4)
execjs execjs
axlsx (3.0.0.pre) axlsx_styler (1.0.0)
htmlentities (~> 4.3, >= 4.3.4)
mimemagic (~> 0.3)
nokogiri (~> 1.8, >= 1.8.2)
rubyzip (~> 1.2, >= 1.2.1)
axlsx_styler (0.2.0)
activesupport (>= 3.1) activesupport (>= 3.1)
axlsx (>= 2.0, < 4) caxlsx (>= 2.0.2)
babel-source (5.8.35) babel-source (5.8.35)
babel-transpiler (0.7.0) babel-transpiler (0.7.0)
babel-source (>= 4.0, < 6) babel-source (>= 4.0, < 6)
@ -118,7 +113,7 @@ GEM
bootstrap-wysihtml5-rails (0.3.3.8) bootstrap-wysihtml5-rails (0.3.3.8)
railties (>= 3.0) railties (>= 3.0)
brakeman (4.3.1) brakeman (4.3.1)
browser (2.5.3) browser (4.0.0)
builder (3.2.4) builder (3.2.4)
byebug (10.0.2) byebug (10.0.2)
capybara (3.29.0) capybara (3.29.0)
@ -140,6 +135,11 @@ GEM
selenium-webdriver selenium-webdriver
case_transform (0.2) case_transform (0.2)
activesupport activesupport
caxlsx (3.0.1)
htmlentities (~> 4.3, >= 4.3.4)
mimemagic (~> 0.3)
nokogiri (~> 1.10, >= 1.10.4)
rubyzip (>= 1.3.0, < 3)
chartkick (3.3.1) chartkick (3.3.1)
childprocess (0.9.0) childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11) ffi (~> 1.0, >= 1.0.11)
@ -158,21 +158,21 @@ GEM
crack (0.4.3) crack (0.4.3)
safe_yaml (~> 1.0.0) safe_yaml (~> 1.0.0)
crass (1.0.6) crass (1.0.6)
css_parser (1.6.0) css_parser (1.7.1)
addressable addressable
curb (0.9.10) curb (0.9.10)
daemons (1.3.1) daemons (1.3.1)
database_cleaner (1.7.0) database_cleaner (1.7.0)
datetime_picker_rails (0.0.7) datetime_picker_rails (0.0.7)
momentjs-rails (>= 2.8.1) momentjs-rails (>= 2.8.1)
deep_cloneable (2.3.2) deep_cloneable (3.0.0)
activerecord (>= 3.1.0, < 6) activerecord (>= 3.1.0, < 7)
delayed_cron_job (0.7.2) delayed_cron_job (0.7.2)
delayed_job (>= 4.1) delayed_job (>= 4.1)
delayed_job (4.1.5) delayed_job (4.1.8)
activesupport (>= 3.0, < 5.3) activesupport (>= 3.0, < 6.1)
delayed_job_active_record (4.1.3) delayed_job_active_record (4.1.4)
activerecord (>= 3.0, < 5.3) activerecord (>= 3.0, < 6.1)
delayed_job (>= 3.0, < 5) delayed_job (>= 3.0, < 5)
delayed_job_web (1.4.3) delayed_job_web (1.4.3)
activerecord (> 3.0.0) activerecord (> 3.0.0)
@ -193,10 +193,11 @@ GEM
activerecord (>= 4.2, < 7) activerecord (>= 4.2, < 7)
domain_name (0.5.20180417) domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
dotenv (2.5.0) dotenv (2.7.5)
dotenv-rails (2.5.0) dotenv-rails (2.7.5)
dotenv (= 2.5.0) dotenv (= 2.7.5)
railties (>= 3.2, < 6.0) railties (>= 3.2, < 6.1)
dry-inflector (0.2.0)
em-websocket (0.5.1) em-websocket (0.5.1)
eventmachine (>= 0.12.9) eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0) http_parser.rb (~> 0.6.0)
@ -233,8 +234,6 @@ GEM
fog-core (~> 2.1) fog-core (~> 2.1)
fog-json (>= 1.0) fog-json (>= 1.0)
ipaddress (>= 0.8) ipaddress (>= 0.8)
font-awesome-rails (4.7.0.4)
railties (>= 3.2, < 6.0)
formatador (0.2.5) formatador (0.2.5)
geocoder (1.6.0) geocoder (1.6.0)
globalid (0.4.2) globalid (0.4.2)
@ -260,8 +259,8 @@ GEM
bundler (>= 1.14) bundler (>= 1.14)
graphql (~> 1.10) graphql (~> 1.10)
thor (>= 0.19, < 2.0) thor (>= 0.19, < 2.0)
groupdate (4.1.1) groupdate (5.0.0)
activesupport (>= 4.2) activesupport (>= 5)
guard (2.15.0) guard (2.15.0)
formatador (>= 0.2.4) formatador (>= 0.2.4)
listen (>= 2.7, < 4.0) listen (>= 2.7, < 4.0)
@ -281,21 +280,20 @@ GEM
guard (~> 2.1) guard (~> 2.1)
guard-compat (~> 1.1) guard-compat (~> 1.1)
rspec (>= 2.99.0, < 4.0) rspec (>= 2.99.0, < 4.0)
haml (5.0.4) haml (5.1.2)
temple (>= 0.8.0) temple (>= 0.8.0)
tilt tilt
haml-lint (0.999.999) haml-lint (0.999.999)
haml_lint haml_lint
haml-rails (1.0.0) haml-rails (2.0.1)
actionpack (>= 4.0.1) actionpack (>= 5.1)
activesupport (>= 4.0.1) activesupport (>= 5.1)
haml (>= 4.0.6, < 6.0) haml (>= 4.0.6, < 6.0)
html2haml (>= 1.0.1) html2haml (>= 1.0.1)
railties (>= 4.0.1) railties (>= 5.1)
haml_lint (0.28.0) haml_lint (0.35.0)
haml (>= 4.0, < 5.1) haml (>= 4.0, < 5.2)
rainbow rainbow
rake (>= 10, < 13)
rubocop (>= 0.50.0) rubocop (>= 0.50.0)
sysexits (~> 1.1) sysexits (~> 1.1)
hashdiff (0.3.8) hashdiff (0.3.8)
@ -313,12 +311,11 @@ GEM
i18n (1.8.2) i18n (1.8.2)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
ipaddress (0.8.3) ipaddress (0.8.3)
jaro_winkler (1.5.2) jaro_winkler (1.5.4)
jquery-rails (4.3.3) jquery-rails (4.3.5)
rails-dom-testing (>= 1, < 3) rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0) railties (>= 4.2.0)
thor (>= 0.14, < 2.0) thor (>= 0.14, < 2.0)
json (2.2.0)
json-jwt (1.11.0) json-jwt (1.11.0)
activesupport (>= 4.2) activesupport (>= 4.2)
aes_key_wrap aes_key_wrap
@ -418,31 +415,31 @@ GEM
validate_email validate_email
validate_url validate_url
webfinger (>= 1.0.1) webfinger (>= 1.0.1)
openstack (3.3.21)
json
orm_adapter (0.5.0) orm_adapter (0.5.0)
parallel (1.12.1) parallel (1.19.1)
parser (2.5.3.0) parser (2.7.0.4)
ast (~> 2.4.0) ast (~> 2.4.0)
pdf-core (0.7.0) pdf-core (0.7.0)
pg (1.1.3) pg (1.1.3)
phonelib (0.6.39) phonelib (0.6.39)
powerpack (0.1.2)
prawn (2.2.2) prawn (2.2.2)
pdf-core (~> 0.7.0) pdf-core (~> 0.7.0)
ttfunk (~> 1.5) ttfunk (~> 1.5)
prawn-rails (1.3.0)
prawn
prawn-table
rails (>= 3.1.0)
prawn-svg (0.29.1) prawn-svg (0.29.1)
css_parser (~> 1.6) css_parser (~> 1.6)
prawn (>= 0.11.1, < 3) prawn (>= 0.11.1, < 3)
prawn_rails (0.0.11) prawn-table (0.2.2)
prawn (>= 0.11.1) prawn (>= 1.3.0, < 3.0.0)
railties (>= 3.0.0)
premailer (1.11.1) premailer (1.11.1)
addressable addressable
css_parser (>= 1.6.0) css_parser (>= 1.6.0)
htmlentities (>= 4.0.0) htmlentities (>= 4.0.0)
premailer-rails (1.10.2) premailer-rails (1.10.3)
actionmailer (>= 3, < 6) actionmailer (>= 3)
premailer (~> 1.7, >= 1.7.9) premailer (~> 1.7, >= 1.7.9)
promise.rb (0.7.4) promise.rb (0.7.4)
pry (0.12.2) pry (0.12.2)
@ -507,7 +504,7 @@ GEM
rake (12.3.3) rake (12.3.3)
rake-progressbar (0.0.5) rake-progressbar (0.0.5)
rb-fsevent (0.10.3) rb-fsevent (0.10.3)
rb-inotify (0.10.0) rb-inotify (0.10.1)
ffi (~> 1.0) ffi (~> 1.0)
react-rails (2.4.7) react-rails (2.4.7)
babel-transpiler (>= 0.7.0) babel-transpiler (>= 0.7.0)
@ -525,12 +522,13 @@ GEM
http-cookie (>= 1.0.2, < 2.0) http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0) mime-types (>= 1.16, < 4.0)
netrc (~> 0.8) netrc (~> 0.8)
rexml (3.2.4)
rgeo (2.0.0) rgeo (2.0.0)
rgeo-geojson (2.1.1) rgeo-geojson (2.1.1)
rgeo (>= 1.0.0) rgeo (>= 1.0.0)
rodf (1.0.0) rodf (1.1.1)
activesupport (>= 3.0)
builder (>= 3.0) builder (>= 3.0)
dry-inflector (~> 0.1)
rubyzip (>= 1.0) rubyzip (>= 1.0)
rouge (3.16.0) rouge (3.16.0)
rspec (3.9.0) rspec (3.9.0)
@ -545,47 +543,51 @@ GEM
rspec-mocks (3.9.1) rspec-mocks (3.9.1)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0) rspec-support (~> 3.9.0)
rspec-rails (3.9.0) rspec-rails (4.0.0.beta4)
actionpack (>= 3.0) actionpack (>= 4.2)
activesupport (>= 3.0) activesupport (>= 4.2)
railties (>= 3.0) railties (>= 4.2)
rspec-core (~> 3.9.0) rspec-core (~> 3.9)
rspec-expectations (~> 3.9.0) rspec-expectations (~> 3.9)
rspec-mocks (~> 3.9.0) rspec-mocks (~> 3.9)
rspec-support (~> 3.9.0) rspec-support (~> 3.9)
rspec-support (3.9.2) rspec-support (3.9.2)
rspec_junit_formatter (0.4.1) rspec_junit_formatter (0.4.1)
rspec-core (>= 2, < 4, != 2.12.0) rspec-core (>= 2, < 4, != 2.12.0)
rubocop (0.62.0) rubocop (0.80.1)
jaro_winkler (~> 1.5.1) jaro_winkler (~> 1.5.1)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 2.5, != 2.5.1.1) parser (>= 2.7.0.1)
powerpack (~> 0.1)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
rexml
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.4.0) unicode-display_width (>= 1.4.0, < 1.7)
rubocop-performance (1.5.2)
rubocop (>= 0.71.0)
rubocop-rails (2.4.2)
rack (>= 1.1)
rubocop (>= 0.72.0)
rubocop-rails_config (0.10.0)
railties (>= 5.0)
rubocop (~> 0.80)
rubocop-performance (~> 1.3)
rubocop-rails (~> 2.0)
rubocop-rspec-focused (1.0.0) rubocop-rspec-focused (1.0.0)
rubocop (>= 0.51) rubocop (>= 0.51)
ruby-debug-ide (0.6.1) ruby-debug-ide (0.6.1)
rake (>= 0.8.1) rake (>= 0.8.1)
ruby-progressbar (1.10.0) ruby-progressbar (1.10.1)
ruby_dep (1.5.0) ruby_dep (1.5.0)
ruby_parser (3.12.0) ruby_parser (3.14.2)
sexp_processor (~> 4.9) sexp_processor (~> 4.9)
rubyzip (1.3.0) rubyzip (1.3.0)
safe_yaml (1.0.4) safe_yaml (1.0.4)
sanitize-url (0.1.4) sanitize-url (0.1.4)
sass (3.7.3) sass (3.7.4)
sass-listen (~> 4.0.0) sass-listen (~> 4.0.0)
sass-listen (4.0.0) sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4) rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7) rb-inotify (~> 0.9, >= 0.9.7)
sass-rails (5.0.7)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
sassc (2.0.0) sassc (2.0.0)
ffi (~> 1.9.6) ffi (~> 1.9.6)
rake rake
@ -595,9 +597,6 @@ GEM
sprockets (> 3.0) sprockets (> 3.0)
sprockets-rails sprockets-rails
tilt tilt
scenic (1.4.1)
activerecord (>= 4.0.0)
railties (>= 4.0.0)
scss_lint (0.57.1) scss_lint (0.57.1)
rake (>= 0.9, < 13) rake (>= 0.9, < 13)
sass (~> 3.5, >= 3.5.5) sass (~> 3.5, >= 3.5.5)
@ -607,7 +606,7 @@ GEM
rubyzip (~> 1.2, >= 1.2.2) rubyzip (~> 1.2, >= 1.2.2)
sentry-raven (2.7.4) sentry-raven (2.7.4)
faraday (>= 0.7.6, < 1.0) faraday (>= 0.7.6, < 1.0)
sexp_processor (4.11.0) sexp_processor (4.14.1)
shellany (0.0.1) shellany (0.0.1)
shoulda-matchers (4.0.1) shoulda-matchers (4.0.1)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
@ -628,9 +627,9 @@ GEM
jquery-rails jquery-rails
kaminari (>= 0.17) kaminari (>= 0.17)
rails (>= 3.2) rails (>= 3.2)
spreadsheet_architect (3.2.0) spreadsheet_architect (4.0.0)
axlsx (>= 2, < 4) axlsx_styler (>= 1.0.0, < 2)
axlsx_styler (>= 0.1.7, < 2) caxlsx (>= 2.0.2, < 4)
rodf (>= 1.0.0, < 2) rodf (>= 1.0.0, < 2)
spring (2.0.2) spring (2.0.2)
activesupport (>= 4.2) activesupport (>= 4.2)
@ -648,10 +647,10 @@ GEM
attr_required (>= 0.0.5) attr_required (>= 0.0.5)
httpclient (>= 2.4) httpclient (>= 2.4)
sysexits (1.2.0) sysexits (1.2.0)
temple (0.8.0) temple (0.8.2)
thor (1.0.1) thor (1.0.1)
thread_safe (0.3.6) thread_safe (0.3.6)
tilt (2.0.9) tilt (2.0.10)
timecop (0.9.1) timecop (0.9.1)
ttfunk (1.5.1) ttfunk (1.5.1)
turbolinks (5.2.0) turbolinks (5.2.0)
@ -664,7 +663,7 @@ GEM
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext
unf_ext (0.0.7.5) unf_ext (0.0.7.5)
unicode-display_width (1.4.1) unicode-display_width (1.6.1)
validate_email (0.1.6) validate_email (0.1.6)
activemodel (>= 3.0) activemodel (>= 3.0)
mail (>= 2.2.5) mail (>= 2.2.5)
@ -721,7 +720,6 @@ DEPENDENCIES
administrate administrate
after_party after_party
anchored anchored
axlsx (~> 3.0.0.pre)
bcrypt bcrypt
bootstrap-sass (>= 3.4.1) bootstrap-sass (>= 3.4.1)
bootstrap-wysihtml5-rails (~> 0.3.3.8) bootstrap-wysihtml5-rails (~> 0.3.3.8)
@ -749,8 +747,6 @@ DEPENDENCIES
flipper flipper
flipper-active_record flipper-active_record
flipper-ui flipper-ui
fog-openstack
font-awesome-rails
geocoder geocoder
gon gon
graphiql-rails graphiql-rails
@ -776,12 +772,10 @@ DEPENDENCIES
omniauth-github omniauth-github
omniauth-rails_csrf_protection (~> 0.1) omniauth-rails_csrf_protection (~> 0.1)
openid_connect openid_connect
openstack
pg pg
phonelib phonelib
prawn prawn-rails
prawn-svg prawn-svg
prawn_rails
premailer-rails premailer-rails
pry-byebug pry-byebug
puma puma
@ -793,16 +787,15 @@ DEPENDENCIES
rails-i18n rails-i18n
rake-progressbar rake-progressbar
react-rails react-rails
rest-client
rgeo-geojson rgeo-geojson
rspec-rails rspec-rails (~> 4.0.0.beta)
rspec_junit_formatter rspec_junit_formatter
rubocop rubocop
rubocop-rails_config
rubocop-rspec-focused rubocop-rspec-focused
ruby-debug-ide ruby-debug-ide
sanitize-url sanitize-url
sassc-rails sassc-rails
scenic
scss_lint scss_lint
sentry-raven sentry-raven
shoulda-matchers shoulda-matchers
@ -812,6 +805,7 @@ DEPENDENCIES
spreadsheet_architect spreadsheet_architect
spring spring
spring-commands-rspec spring-commands-rspec
sprockets (< 4)
timecop timecop
turbolinks turbolinks
typhoeus typhoeus

View file

@ -34,7 +34,6 @@
// = require_self // = require_self
// = require leaflet // = require leaflet
// = require font-awesome
// = require franceconnect // = require franceconnect
// = require bootstrap-wysihtml5 // = require bootstrap-wysihtml5

View file

@ -198,7 +198,7 @@ class ApplicationController < ActionController::Base
# return at this location # return at this location
# after the device is trusted # after the device is trusted
store_location_for(:user, request.fullpath) store_location_for(:user, request.fullpath) if get_stored_location_for(:user).blank?
send_login_token_or_bufferize(current_instructeur) send_login_token_or_bufferize(current_instructeur)
redirect_to link_sent_path(email: current_instructeur.email) redirect_to link_sent_path(email: current_instructeur.email)
@ -233,7 +233,7 @@ class ApplicationController < ActionController::Base
key: sentry[:client_key], key: sentry[:client_key],
enabled: sentry[:enabled], enabled: sentry[:enabled],
environment: sentry[:environment], environment: sentry[:environment],
browser: { modern: browser.modern? }, browser: { modern: BrowserSupport.supported?(browser) },
user: sentry_user user: sentry_user
} }
end end

View file

@ -62,7 +62,7 @@ class Champs::CarteController < ApplicationController
@champ.save @champ.save
end end
rescue RestClient::ResourceNotFound rescue ApiCarto::API::ResourceNotFound
flash.alert = 'Les données cartographiques sont temporairement indisponibles. Réessayez dans un instant.' flash.alert = 'Les données cartographiques sont temporairement indisponibles. Réessayez dans un instant.'
response.status = 503 response.status = 503
end end

View file

@ -16,7 +16,7 @@ class Champs::SiretController < ApplicationController
begin begin
etablissement = find_etablissement_with_siret etablissement = find_etablissement_with_siret
rescue RestClient::RequestFailed rescue ApiEntreprise::API::RequestFailed
return siret_error(:network_error) return siret_error(:network_error)
end end
if etablissement.blank? if etablissement.blank?

View file

@ -58,7 +58,6 @@ class StatsController < ApplicationController
.includes(:procedure, :user) .includes(:procedure, :user)
.in_batches .in_batches
.flat_map do |dossiers| .flat_map do |dossiers|
dossiers dossiers
.pluck( .pluck(
"dossiers.id", "dossiers.id",

View file

@ -16,6 +16,20 @@ module Users
render 'commencer/show' render 'commencer/show'
end end
def dossier_vide_pdf
@procedure = retrieve_procedure
return procedure_not_found if @procedure.blank? || @procedure.brouillon?
generate_empty_pdf(@procedure)
end
def dossier_vide_pdf_test
@procedure = retrieve_procedure
return procedure_not_found if @procedure.blank? || @procedure.publiee?
generate_empty_pdf(@procedure)
end
def sign_in def sign_in
@procedure = retrieve_procedure @procedure = retrieve_procedure
return procedure_not_found if @procedure.blank? return procedure_not_found if @procedure.blank?
@ -65,5 +79,11 @@ module Users
def store_user_location!(procedure) def store_user_location!(procedure)
store_location_for(:user, helpers.procedure_lien(procedure)) store_location_for(:user, helpers.procedure_lien(procedure))
end end
def generate_empty_pdf(procedure)
@dossier = procedure.new_dossier
s = render_to_string(file: 'dossiers/dossier_vide', formats: [:pdf])
send_data(s, :filename => "#{procedure.libelle}.pdf")
end
end end
end end

View file

@ -106,7 +106,7 @@ module Users
sanitized_siret = siret_model.siret sanitized_siret = siret_model.siret
begin begin
etablissement_attributes = ApiEntrepriseService.get_etablissement_params_for_siret(sanitized_siret, @dossier.procedure.id) etablissement_attributes = ApiEntrepriseService.get_etablissement_params_for_siret(sanitized_siret, @dossier.procedure.id)
rescue RestClient::RequestFailed rescue ApiEntreprise::API::RequestFailed
return render_siret_error(t('errors.messages.siret_network_error')) return render_siret_error(t('errors.messages.siret_network_error'))
end end
if etablissement_attributes.blank? if etablissement_attributes.blank?

View file

@ -131,4 +131,12 @@ module ApplicationHelper
def has_dismissed_outdated_browser_banner? def has_dismissed_outdated_browser_banner?
cookies[:dismissed_outdated_browser_banner] == 'true' cookies[:dismissed_outdated_browser_banner] == 'true'
end end
def supported_browser?
BrowserSupport.supported?(browser)
end
def show_outdated_browser_banner?
!supported_browser? && !has_dismissed_outdated_browser_banner?
end
end end

View file

@ -2,4 +2,8 @@ module FlipperHelper
def feature_enabled?(feature_name) def feature_enabled?(feature_name)
Flipper.enabled?(feature_name, current_user) Flipper.enabled?(feature_name, current_user)
end end
def feature_enabled_for?(feature_name, item)
Flipper.enabled?(feature_name, item)
end
end end

View file

@ -1,4 +1,7 @@
class ApiCarto::API class ApiCarto::API
class ResourceNotFound < StandardError
end
def self.search_qp(geojson) def self.search_qp(geojson)
url = [API_CARTO_URL, "quartiers-prioritaires", "search"].join("/") url = [API_CARTO_URL, "quartiers-prioritaires", "search"].join("/")
call(url, geojson) call(url, geojson)
@ -19,7 +22,7 @@ class ApiCarto::API
else else
message = response.code == 0 ? response.return_message : response.code.to_s message = response.code == 0 ? response.return_message : response.code.to_s
Rails.logger.error "[ApiCarto] Error on #{url}: #{message}" Rails.logger.error "[ApiCarto] Error on #{url}: #{message}"
raise RestClient::ResourceNotFound raise ResourceNotFound
end end
end end
end end

View file

@ -9,7 +9,7 @@ class ApiEntreprise::Adapter
def data_source def data_source
begin begin
@data_source ||= get_resource @data_source ||= get_resource
rescue RestClient::ResourceNotFound rescue ApiEntreprise::API::ResourceNotFound
@data_source = nil @data_source = nil
end end
end end

View file

@ -6,6 +6,12 @@ class ApiEntreprise::API
TIMEOUT = 15 TIMEOUT = 15
class ResourceNotFound < StandardError
end
class RequestFailed < StandardError
end
def self.entreprise(siren, procedure_id) def self.entreprise(siren, procedure_id)
call(ENTREPRISE_RESOURCE_NAME, siren, procedure_id) call(ENTREPRISE_RESOURCE_NAME, siren, procedure_id)
end end
@ -35,9 +41,9 @@ class ApiEntreprise::API
if response.success? if response.success?
JSON.parse(response.body, symbolize_names: true) JSON.parse(response.body, symbolize_names: true)
elsif response.code&.between?(401, 499) elsif response.code&.between?(401, 499)
raise RestClient::ResourceNotFound raise ResourceNotFound
else else
raise RestClient::RequestFailed raise RequestFailed
end end
end end
@ -56,6 +62,7 @@ class ApiEntreprise::API
context: "demarches-simplifiees.fr", context: "demarches-simplifiees.fr",
recipient: siret_or_siren, recipient: siret_or_siren,
object: "procedure_id: #{procedure_id}", object: "procedure_id: #{procedure_id}",
non_diffusables: true,
token: token token: token
} }
end end

View file

@ -24,7 +24,8 @@ class ApiEntreprise::EtablissementAdapter < ApiEntreprise::Adapter
:siret, :siret,
:siege_social, :siege_social,
:naf, :naf,
:libelle_naf :libelle_naf,
:diffusable_commercialement
] ]
end end

View file

@ -51,20 +51,29 @@ class Pipedrive::API
api_token: token api_token: token
}) })
response = RestClient.get(url, params: params) response = Typhoeus.get(url, params: params)
JSON.parse(response.body)['data']
if response.success?
JSON.parse(response.body)['data']
end
end end
def self.put(url, params) def self.put(url, params)
url = "#{url}?api_token=#{token}" Typhoeus.put(
url,
RestClient.put(url, params.to_json, { content_type: :json }) params: { api_token: token },
body: params.to_json,
headers: { 'content-type' => 'application/json' }
)
end end
def self.post(url, params) def self.post(url, params)
url = "#{url}?api_token=#{token}" Typhoeus.post(
url,
RestClient.post(url, params.to_json, { content_type: :json }) params: { api_token: token },
body: params.to_json,
headers: { 'content-type' => 'application/json' }
)
end end
def self.token def self.token

View file

@ -85,6 +85,11 @@ class Administrateur < ApplicationRecord
next_administrateur = procedure.administrateurs.where.not(id: self.id).first next_administrateur = procedure.administrateurs.where.not(id: self.id).first
procedure.service.update(administrateur: next_administrateur) procedure.service.update(administrateur: next_administrateur)
end end
services.each do |service|
service.destroy unless service.procedures.any?
end
destroy destroy
end end
end end

View file

@ -692,7 +692,6 @@ class Dossier < ApplicationRecord
.includes(:procedure, :user) .includes(:procedure, :user)
.group_by(&:user) .group_by(&:user)
.each do |(user, dossiers)| .each do |(user, dossiers)|
dossier_hashes = dossiers.map(&:hash_for_deletion_mail) dossier_hashes = dossiers.map(&:hash_for_deletion_mail)
DossierMailer.notify_brouillon_deletion(user, dossier_hashes).deliver_later DossierMailer.notify_brouillon_deletion(user, dossier_hashes).deliver_later

View file

@ -148,11 +148,12 @@ class Instructeur < ApplicationRecord
def email_notification_data def email_notification_data
groupe_instructeur_with_email_notifications groupe_instructeur_with_email_notifications
.reduce([]) do |acc, groupe| .reduce([]) do |acc, groupe|
procedure = groupe.procedure procedure = groupe.procedure
h = { h = {
nb_en_construction: groupe.dossiers.en_construction.count, nb_en_construction: groupe.dossiers.en_construction.count,
nb_en_instruction: groupe.dossiers.en_instruction.count,
nb_accepted: groupe.dossiers.accepte.where(processed_at: Time.zone.yesterday.beginning_of_day..Time.zone.yesterday.end_of_day).count,
nb_notification: notifications_for_procedure(procedure, :not_archived).count nb_notification: notifications_for_procedure(procedure, :not_archived).count
} }
@ -162,6 +163,14 @@ class Instructeur < ApplicationRecord
acc << h acc << h
end end
[["en_instruction", h[:nb_en_instruction]], ["accepte", h[:nb_accepted]]].each do |state, count|
if procedure.declarative_with_state == state && count > 0
h[:procedure_id] = procedure.id
h[:procedure_libelle] = procedure.libelle
acc << h
end
end
acc acc
end end
end end

View file

@ -496,6 +496,10 @@ class Procedure < ApplicationRecord
dossiers.discard_all dossiers.discard_all
end end
def flipper_id
"Procedure;#{id}"
end
private private
def move_type_de_champ_attributes(types_de_champ, type_de_champ, new_index) def move_type_de_champ_attributes(types_de_champ, type_de_champ, new_index)

View file

@ -4,7 +4,7 @@ class ApiEntrepriseService
# Returns nil if the SIRET is unknown; and nested params # Returns nil if the SIRET is unknown; and nested params
# suitable for being saved into a Etablissement object otherwise. # suitable for being saved into a Etablissement object otherwise.
# #
# Raises a RestClient::RequestFailed exception on transcient errors # Raises a ApiEntreprise::API::RequestFailed exception on transcient errors
# (timeout, 5XX HTTP error code, etc.) # (timeout, 5XX HTTP error code, etc.)
def self.get_etablissement_params_for_siret(siret, procedure_id) def self.get_etablissement_params_for_siret(siret, procedure_id)
etablissement_params = ApiEntreprise::EtablissementAdapter.new(siret, procedure_id).to_params etablissement_params = ApiEntreprise::EtablissementAdapter.new(siret, procedure_id).to_params
@ -14,13 +14,13 @@ class ApiEntrepriseService
begin begin
association_params = ApiEntreprise::RNAAdapter.new(siret, procedure_id).to_params association_params = ApiEntreprise::RNAAdapter.new(siret, procedure_id).to_params
etablissement_params.merge!(association_params) etablissement_params.merge!(association_params)
rescue RestClient::RequestFailed rescue ApiEntreprise::API::RequestFailed
end end
begin begin
exercices_params = ApiEntreprise::ExercicesAdapter.new(siret, procedure_id).to_params exercices_params = ApiEntreprise::ExercicesAdapter.new(siret, procedure_id).to_params
etablissement_params.merge!(exercices_params) etablissement_params.merge!(exercices_params)
rescue RestClient::RequestFailed rescue ApiEntreprise::API::RequestFailed
end end
etablissement_params.merge(entreprise_params) etablissement_params.merge(entreprise_params)

View file

@ -0,0 +1,13 @@
class BrowserSupport
def self.supported?(browser)
# See .browserslistrc
[
browser.chrome? && browser.version.to_i >= 50 && !browser.platform.ios?,
browser.edge? && browser.version.to_i >= 14 && !browser.compatibility_view?,
browser.firefox? && browser.version.to_i >= 50 && !browser.platform.ios?,
browser.opera? && browser.version.to_i >= 40,
browser.safari? && browser.version.to_i >= 8,
browser.platform.ios? && browser.platform.version.to_i >= 8
].any?
end
end

View file

@ -40,3 +40,15 @@
%h2.huge-title Vous avez déjà des dossiers pour cette démarche %h2.huge-title Vous avez déjà des dossiers pour cette démarche
= link_to 'Voir mes dossiers en cours', dossiers_path, class: ['button large expand primary'] = link_to 'Voir mes dossiers en cours', dossiers_path, class: ['button large expand primary']
= link_to 'Commencer un nouveau dossier', url_for_new_dossier(@procedure), class: ['button large expand'] = link_to 'Commencer un nouveau dossier', url_for_new_dossier(@procedure), class: ['button large expand']
- if feature_enabled_for?(:dossier_pdf_vide, @procedure)
- pdf_link = commencer_dossier_vide_path(path: @procedure.path)
- if @procedure.brouillon?
- pdf_link = commencer_dossier_vide_test_path(path: @procedure.path)
%hr
%p
Vous souhaitez effectuer une demande par papier ? Vous pouvez télécharger un dossier vide au format PDF,
et l'envoyer à ladministration concernée :
#{@procedure&.service&.nom} - #{@procedure&.service&.adresse}
%br
= link_to 'Télécharger un dossier vide au format PDF', pdf_link, class: ['button large expand']

View file

@ -0,0 +1,196 @@
require 'prawn/measurement_extensions'
def render_in_2_columns(pdf, label, text)
pdf.text_box label, width: 200, height: 100, overflow: :expand, at: [0, pdf.cursor]
pdf.text_box ":", width: 10, height: 100, overflow: :expand, at: [100, pdf.cursor]
pdf.text_box text, width: 420, height: 100, overflow: :expand, at: [110, pdf.cursor]
pdf.text "\n"
end
def format_in_2_lines(pdf, label, nb_lines = 1)
add_single_line(pdf, label, 12, :bold)
height = 10 * (nb_lines+1)
pdf.bounding_box([0, pdf.cursor],:width => 460,:height => height) do
pdf.stroke_bounds
end
pdf.text "\n"
end
def format_in_2_columns(pdf, label)
pdf.text_box label, width: 200, height: 100, overflow: :expand, at: [0, pdf.cursor]
pdf.bounding_box([110, pdf.cursor+5],:width => 350,:height => 20) do
pdf.stroke_bounds
end
pdf.text "\n"
end
def format_with_checkbox(pdf, label, offset = 0)
pdf.font 'liberation serif', size: 12 do
pdf.stroke_rectangle [0 + offset, pdf.cursor], 10, 10
pdf.text_box label, at: [15 + offset, pdf.cursor]
end
pdf.text "\n"
end
def add_page_numbering(pdf)
# This method should be called at the end of the drawing since pages drawn after
# do not have page numbering
string = '<page> / <total>'
options = {
at: [0, -15],
align: :right
}
pdf.number_pages string, options
end
def add_procedure(pdf, dossier)
pdf.repeat(lambda {|page| page > 1 }) do
pdf.draw_text dossier.procedure.libelle, :at => pdf.bounds.top_left
end
end
def format_date(date)
I18n.l(date, format: :message_date_with_year)
end
def add_identite_individual(pdf, dossier)
format_in_2_columns(pdf, "Civilité")
format_in_2_columns(pdf, "Nom")
format_in_2_columns(pdf, "Prénom")
format_in_2_columns(pdf, "Date de naissance")
end
def add_identite_etablissement(pdf, libelle)
add_single_line(pdf, libelle, 12, :bold)
format_in_2_columns(pdf, "SIRET")
format_in_2_columns(pdf, "Dénomination")
format_in_2_columns(pdf, "Forme juridique")
end
def add_single_line(pdf, libelle, size, style)
pdf.font 'liberation serif', style: style, size: size do
pdf.text libelle
end
end
def add_title(pdf, title)
add_single_line(pdf, title, 24, :bold)
pdf.text "\n"
end
def add_libelle(pdf, champ)
add_single_line(pdf, champ.libelle, 12, :bold)
end
def add_explanation(pdf, explanation)
add_single_line(pdf, explanation, 9, :italic)
end
def render_single_champ(pdf, champ)
case champ.type
when 'Champs::RepetitionChamp'
raise 'There should not be a RepetitionChamp here !'
when 'Champs::PieceJustificativeChamp'
add_single_line(pdf, 'Pièce justificative à joindre', 12, :bold)
pdf.text champ.libelle
pdf.text champ.description
pdf.text "\n"
when 'Champs::YesNoChamp', 'Champs::CheckboxChamp'
add_libelle(pdf, champ)
add_explanation(pdf, 'Cochez la mention applicable')
format_with_checkbox(pdf, 'Oui')
format_with_checkbox(pdf, 'Non')
pdf.text "\n"
when 'Champs::CiviliteChamp'
add_libelle(pdf, champ)
format_with_checkbox(pdf, Individual::GENDER_FEMALE)
format_with_checkbox(pdf, Individual::GENDER_MALE)
pdf.text "\n"
when 'Champs::HeaderSectionChamp'
add_single_line(pdf, champ.libelle, 18, :bold)
pdf.text "\n"
when 'Champs::ExplicationChamp'
add_libelle(pdf, champ)
pdf.text champ.description
pdf.text "\n"
when 'Champs::AddressChamp', 'Champs::CarteChamp', 'Champs::TextareaChamp'
format_in_2_lines(pdf, champ.libelle, 3)
when 'Champs::DropDownListChamp'
add_libelle(pdf, champ)
add_explanation(pdf, 'Cochez la mention applicable, une seule valeur possible')
champ.drop_down_list.options.reject(&:blank?).each do |option|
format_with_checkbox(pdf, option)
end
pdf.text "\n"
when 'Champs::MultipleDropDownListChamp'
add_libelle(pdf, champ)
add_explanation(pdf, 'Cochez la mention applicable, plusieurs valeurs possibles')
champ.drop_down_list.options.reject(&:blank?).each do |option|
format_with_checkbox(pdf, option)
end
pdf.text "\n"
when 'Champs::LinkedDropDownListChamp'
add_libelle(pdf, champ)
champ.primary_options.reject(&:blank?).each do |o|
format_with_checkbox(pdf, o)
champ.secondary_options[o].reject(&:blank?).each do |secondary_option|
format_with_checkbox(pdf, secondary_option, 15)
end
end
pdf.text "\n"
when 'Champs::SiretChamp'
add_identite_etablissement(pdf, champ.libelle)
else
format_in_2_lines(pdf, champ.libelle)
end
end
def add_champs(pdf, champs)
champs.each do |champ|
if champ.type == 'Champs::RepetitionChamp'
add_libelle(pdf, champ)
(1..3).each do
champ.rows.each do |row|
row.each do |inner_champ|
render_single_champ(pdf, inner_champ)
end
end
end
else
render_single_champ(pdf, champ)
end
end
end
prawn_document(page_size: "A4") do |pdf|
pdf.font_families.update( 'liberation serif' => {
normal: Rails.root.join('lib/prawn/fonts/liberation_serif/LiberationSerif-Regular.ttf' ),
bold: Rails.root.join('lib/prawn/fonts/liberation_serif/LiberationSerif-Bold.ttf' ),
italic: Rails.root.join('lib/prawn/fonts/liberation_serif/LiberationSerif-Italic.ttf' ),
})
pdf.font 'liberation serif'
pdf.svg IO.read("app/assets/images/header/logo-ds-wide.svg"), width: 300, position: :center
pdf.move_down(40)
render_in_2_columns(pdf, 'Démarche', @dossier.procedure.libelle)
render_in_2_columns(pdf, 'Organisme', @dossier.procedure.organisation_name)
pdf.text "\n"
add_title(pdf, "Identité du demandeur")
format_in_2_columns(pdf, "Email")
if @dossier.procedure.for_individual?
add_identite_individual(pdf, @dossier)
else
render_identite_etablissement(pdf, @dossier.etablissement) if @dossier.etablissement.present?
end
pdf.text "\n"
add_title(pdf, 'Formulaire')
add_champs(pdf, @dossier.champs)
add_page_numbering(pdf)
add_procedure(pdf, @dossier)
end

View file

@ -16,5 +16,12 @@
- if datum[:nb_notification] > 0 - if datum[:nb_notification] > 0
%br %br
#{datum[:nb_notification]} #{'notification'.pluralize(datum[:nb_notification])} #{datum[:nb_notification]} #{'notification'.pluralize(datum[:nb_notification])}
- if datum[:nb_en_instruction] > 0
%br
#{datum[:nb_en_instruction]} #{'dossier'.pluralize(datum[:nb_en_instruction])}
- if datum[:nb_accepted] > 0
%br
#{datum[:nb_accepted]} #{'dossier'.pluralize(datum[:nb_accepted])}
= render partial: "layouts/mailers/signature" = render partial: "layouts/mailers/signature"

View file

@ -1,5 +1,4 @@
-# See config/browser.rb - if show_outdated_browser_banner?
- if !browser.modern? && !has_dismissed_outdated_browser_banner?
#outdated-browser-banner.site-banner #outdated-browser-banner.site-banner
.container .container
.site-banner-icon ⚠️ .site-banner-icon ⚠️

View file

@ -121,4 +121,4 @@
Par défaut, un dossier déposé peut être complété ou corrigé par le demandeur jusqu'à sa mise en instruction.<br> Par défaut, un dossier déposé peut être complété ou corrigé par le demandeur jusqu'à sa mise en instruction.<br>
Dans une démarche déclarative, une fois déposé, un dossier ne peut plus être modifié. Dans une démarche déclarative, une fois déposé, un dossier ne peut plus être modifié.
Soit il passe immédiatement « en instruction » pour être traité soit il est immédiatement « accepté ». Soit il passe immédiatement « en instruction » pour être traité soit il est immédiatement « accepté ».
= f.select :declarative_with_state, Procedure.declarative_attributes_for_select, { prompt: 'Non' }, class: 'form-control' = f.select :declarative_with_state, Procedure.declarative_attributes_for_select, { include_blank: 'Non' }, class: 'form-control'

View file

@ -1,76 +1,80 @@
%table.table.vertical.dossier-champs %table.table.vertical.dossier-champs
%tbody %tbody
%tr - if etablissement.diffusable_commercialement == false && profile != 'instructeur'
%th.libelle Dénomination : %tr
%td= raison_sociale_or_name(etablissement) %td= t('warning_for_private_info', etablissement: raison_sociale_or_name(etablissement), scope: 'views.shared.dossiers.identite_entreprise')
%tr - else
%th.libelle SIRET : %tr
%td= etablissement.siret %th.libelle Dénomination :
%td= raison_sociale_or_name(etablissement)
%tr
%th.libelle SIRET :
%td= etablissement.siret
- if etablissement.siret != etablissement.entreprise.siret_siege_social - if etablissement.siret != etablissement.entreprise.siret_siege_social
%tr
%th.libelle SIRET du siège social:
%td= etablissement.entreprise.siret_siege_social
%tr %tr
%th.libelle SIRET du siège social: %th.libelle Forme juridique :
%td= etablissement.entreprise.siret_siege_social %td= sanitize(etablissement.entreprise.forme_juridique)
%tr
%th.libelle Forme juridique :
%td= sanitize(etablissement.entreprise.forme_juridique)
%tr
%th.libelle Libellé NAF :
%td= etablissement.libelle_naf
%tr
%th.libelle Code NAF :
%td= etablissement.naf
%tr
%th.libelle Date de création :
%td= try_format_date(etablissement.entreprise.date_creation)
%tr
%th.libelle Effectif de l'organisation :
%td= effectif(etablissement)
%tr
%th.libelle Code effectif :
%td= etablissement.entreprise.code_effectif_entreprise
%tr
%th.libelle Numéro de TVA intracommunautaire :
%td= etablissement.entreprise.numero_tva_intracommunautaire
%tr
%th.libelle Adresse :
%td
- etablissement.adresse.split("\n").each do |line|
= line
%br
%tr
%th.libelle Capital social :
%td= pretty_currency(etablissement.entreprise.capital_social)
%tr
%th.libelle Exercices :
%td
- if profile == 'instructeur'
- etablissement.exercices.each_with_index do |exercice, index|
= "#{exercice.date_fin_exercice.year} : "
= pretty_currency(exercice.ca)
%br
- elsif etablissement.exercices.present?
= t('activemodel.models.exercices_summary', count: etablissement.exercices.count)
- if etablissement.association?
%tr %tr
%th.libelle Numéro RNA : %th.libelle Libellé NAF :
%td= etablissement.association_rna %td= etablissement.libelle_naf
%tr %tr
%th.libelle Titre : %th.libelle Code NAF :
%td= etablissement.association_titre %td= etablissement.naf
%tr
%th.libelle Objet :
%td= etablissement.association_objet
%tr %tr
%th.libelle Date de création : %th.libelle Date de création :
%td= try_format_date(etablissement.association_date_creation) %td= try_format_date(etablissement.entreprise.date_creation)
%tr %tr
%th.libelle Date de publication : %th.libelle Effectif de l'organisation :
%td= try_format_date(etablissement.association_date_publication) %td= effectif(etablissement)
%tr %tr
%th.libelle Date de déclaration : %th.libelle Code effectif :
%td= try_format_date(etablissement.association_date_declaration) %td= etablissement.entreprise.code_effectif_entreprise
%tr
%th.libelle Numéro de TVA intracommunautaire :
%td= etablissement.entreprise.numero_tva_intracommunautaire
%tr
%th.libelle Adresse :
%td
- etablissement.adresse.split("\n").each do |line|
= line
%br
%tr
%th.libelle Capital social :
%td= pretty_currency(etablissement.entreprise.capital_social)
%tr
%th.libelle Exercices :
%td
- if profile == 'instructeur'
- etablissement.exercices.each_with_index do |exercice, index|
= "#{exercice.date_fin_exercice.year} : "
= pretty_currency(exercice.ca)
%br
- elsif etablissement.exercices.present?
= t('activemodel.models.exercices_summary', count: etablissement.exercices.count)
- if etablissement.association?
%tr
%th.libelle Numéro RNA :
%td= etablissement.association_rna
%tr
%th.libelle Titre :
%td= etablissement.association_titre
%tr
%th.libelle Objet :
%td= etablissement.association_objet
%tr
%th.libelle Date de création :
%td= try_format_date(etablissement.association_date_creation)
%tr
%th.libelle Date de publication :
%td= try_format_date(etablissement.association_date_publication)
%tr
%th.libelle Date de déclaration :
%td= try_format_date(etablissement.association_date_declaration)
%p %p
= link_to '➡ Autres informations sur lorganisme sur « entreprise.data.gouv.fr »', = link_to '➡ Autres informations sur lorganisme sur « entreprise.data.gouv.fr »',

View file

@ -7,20 +7,25 @@
.container .container
%h1 Informations sur létablissement %h1 Informations sur létablissement
%p - etablissement = @dossier.etablissement
Nous avons récupéré auprès de lINSEE et dInfogreffe les informations suivantes concernant votre établissement. - if etablissement.diffusable_commercialement == false
%p= t('warning_for_private_info', etablissement: raison_sociale_or_name(etablissement), scope: 'views.shared.dossiers.identite_entreprise')
%p - else
Ces informations seront jointes à votre dossier. %p
Nous avons récupéré auprès de lINSEE et dInfogreffe les informations suivantes concernant votre établissement.
.etablissement-infos.card.featured %p
- etablissement = @dossier.etablissement Ces informations seront jointes à votre dossier.
%h2.card-title= raison_sociale_or_name(etablissement)
= render partial: 'users/dossiers/etablissement/infos_entreprise', locals: { etablissement: etablissement } .etablissement-infos.card.featured
- if etablissement.association? %h2.card-title= raison_sociale_or_name(etablissement)
= render partial: 'users/dossiers/etablissement/infos_association', locals: { etablissement: etablissement }
= render partial: 'users/dossiers/etablissement/infos_entreprise', locals: { etablissement: etablissement }
- if etablissement.association?
= render partial: 'users/dossiers/etablissement/infos_association', locals: { etablissement: etablissement }
.actions .actions
= link_to 'Utiliser un autre numéro SIRET', siret_dossier_path(@dossier), class: 'button' = link_to 'Utiliser un autre numéro SIRET', siret_dossier_path(@dossier), class: 'button'

View file

@ -1,8 +0,0 @@
# See .browserslistrc
Browser.modern_rules.clear
Browser.modern_rules << -> b { b.chrome? && b.version.to_i >= 50 && !b.platform.ios? }
Browser.modern_rules << -> b { b.edge? && b.version.to_i >= 14 && !b.compatibility_view? }
Browser.modern_rules << -> b { b.firefox? && b.version.to_i >= 50 && !b.platform.ios? }
Browser.modern_rules << -> b { b.opera? && b.version.to_i >= 40 }
Browser.modern_rules << -> b { b.safari? && b.version.to_i >= 8 }
Browser.modern_rules << -> b { b.platform.ios? && b.platform.version.to_i >= 8 }

View file

@ -1,9 +1,4 @@
Rails.application.config.content_security_policy do |policy| Rails.application.config.content_security_policy do |policy|
if Rails.env.development?
# les CSP ne sont pas appliquées en dev: on notifie cependant une url quelconque de la violation
# pour détecter les erreurs lors de l'ajout d'une nouvelle brique externe durant le développement
policy.report_uri "http://#{ENV['APP_HOST']}/csp/"
end
# Whitelist image # Whitelist image
policy.img_src :self, "*.openstreetmap.org", "static.demarches-simplifiees.fr", "*.cloud.ovh.net", "stats.data.gouv.fr", "*", :data policy.img_src :self, "*.openstreetmap.org", "static.demarches-simplifiees.fr", "*.cloud.ovh.net", "stats.data.gouv.fr", "*", :data
# Whitelist JS: nous, sendinblue et matomo # Whitelist JS: nous, sendinblue et matomo
@ -17,4 +12,11 @@ Rails.application.config.content_security_policy do |policy|
# Pour tout le reste, par défaut on accepte uniquement ce qui vient de chez nous # Pour tout le reste, par défaut on accepte uniquement ce qui vient de chez nous
# et dans la notification on inclue la source de l'erreur # et dans la notification on inclue la source de l'erreur
policy.default_src :self, :data, :report_sample, "fonts.gstatic.com", "in-automate.sendinblue.com", "player.vimeo.com", "app.franceconnect.gouv.fr", "sentry.io", "static.demarches-simplifiees.fr", "*.crisp.chat", "crisp.chat", "*.crisp.help", "*.sibautomation.com", "sibautomation.com", "data" policy.default_src :self, :data, :report_sample, "fonts.gstatic.com", "in-automate.sendinblue.com", "player.vimeo.com", "app.franceconnect.gouv.fr", "sentry.io", "static.demarches-simplifiees.fr", "*.crisp.chat", "crisp.chat", "*.crisp.help", "*.sibautomation.com", "sibautomation.com", "data"
if Rails.env.development?
# Les CSP ne sont pas appliquées en dev: on notifie cependant une url quelconque de la violation
# pour détecter les erreurs lors de l'ajout d'une nouvelle brique externe durant le développement
policy.report_uri "http://#{ENV['APP_HOST']}/csp/"
# En développement, quand bin/webpack-dev-server est utilisé, on autorise les requêtes faites par le live-reload
policy.connect_src(*policy.connect_src, "ws://localhost:3035", "localhost:3035")
end
end end

View file

@ -1 +0,0 @@
OpenStack::VERSION = 2.0

View file

@ -0,0 +1,6 @@
fr:
views:
shared:
dossiers:
identite_entreprise:
warning_for_private_info: "L'établissement %{etablissement} a exercé son droit à la non publication des informations relatives à son identité. Les informations ne seront donc visibles que de la part des services instructeurs"

View file

@ -242,8 +242,10 @@ Rails.application.routes.draw do
scope module: 'users' do scope module: 'users' do
namespace :commencer do namespace :commencer do
get '/test/:path/dossier_vide', action: 'dossier_vide_pdf_test', as: :dossier_vide_test
get '/test/:path', action: 'commencer_test', as: :test get '/test/:path', action: 'commencer_test', as: :test
get '/:path', action: 'commencer' get '/:path', action: 'commencer'
get '/:path/dossier_vide', action: 'dossier_vide_pdf', as: :dossier_vide
get '/:path/sign_in', action: 'sign_in', as: :sign_in get '/:path/sign_in', action: 'sign_in', as: :sign_in
get '/:path/sign_up', action: 'sign_up', as: :sign_up get '/:path/sign_up', action: 'sign_up', as: :sign_up
get '/:path/france_connect', action: 'france_connect', as: :france_connect get '/:path/france_connect', action: 'france_connect', as: :france_connect

View file

@ -0,0 +1,5 @@
class AddDiffusableCommercialementToEtablissements < ActiveRecord::Migration[5.2]
def change
add_column :etablissements, :diffusable_commercialement, :boolean
end
end

View file

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_02_27_100001) do ActiveRecord::Schema.define(version: 2020_03_04_155418) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -304,6 +304,7 @@ ActiveRecord::Schema.define(version: 2020_02_27_100001) do
t.date "association_date_publication" t.date "association_date_publication"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.boolean "diffusable_commercialement"
t.index ["dossier_id"], name: "index_etablissements_on_dossier_id" t.index ["dossier_id"], name: "index_etablissements_on_dossier_id"
end end

View file

@ -16,4 +16,4 @@ user = User.create!(
confirmed_at: Time.zone.now confirmed_at: Time.zone.now
) )
user.create_instructeur! user.create_instructeur!
user.create_administrateur!(email: user.email) user.create_administrateur!

View file

@ -1,18 +0,0 @@
namespace :after_party do
desc 'Deployment task: create_dummy_paths_for_archived_and_hidden_procedures'
task create_dummy_paths_for_archived_and_hidden_procedures: :environment do
rake_puts "Running deploy task 'create_dummy_paths_for_archived_procedures'"
Procedure.with_discarded.archivees.where(path: nil).each do |p|
p.update_column(:path, SecureRandom.uuid)
end
Procedure.hidden.where(path: nil).each do |p|
p.update_column(:path, SecureRandom.uuid)
end
# Update task as completed. If you remove the line below, the task will
# run with every deploy (or every time you call after_party:run).
AfterParty::TaskRecord.create version: '20190704133852'
end
end

View file

@ -1,28 +0,0 @@
namespace :after_party do
desc 'Deployment task: migrate_geo_area_data'
task migrate_geo_area_data: :environment do
rake_puts "Running deploy task 'migrate_geo_area_data'"
progress = ProgressReport.new(Champs::CarteChamp.count)
Champs::CarteChamp.includes(:geo_areas).find_each do |champ|
geo_area = champ.geo_areas.find(&:selection_utilisateur?)
geo_json = champ.geo_json_from_value
if geo_area.blank? && geo_json.present?
GeoArea.create(
champ: champ,
geometry: geo_json,
source: GeoArea.sources.fetch(:selection_utilisateur)
)
progress.inc
end
end
progress.finish
# Update task as completed. If you remove the line below, the task will
# run with every deploy (or every time you call after_party:run).
AfterParty::TaskRecord.create version: '20190731152733'
end
end

View file

@ -1,33 +0,0 @@
namespace :after_party do
desc 'Deployment task: migrate_flipflop_to_flipper'
task migrate_flipflop_to_flipper: :environment do
rake_puts "Running deploy task 'migrate_flipflop_to_flipper'"
Instructeur.includes(:user).find_each do |instructeur|
if instructeur.features['download_as_zip_enabled']
pp "enable :instructeur_download_as_zip for #{instructeur.user.email}"
Flipper.enable_actor(:instructeur_download_as_zip, instructeur.user)
end
if instructeur.features['bypass_email_login_token']
pp "enable :instructeur_bypass_email_login_token for #{instructeur.user.email}"
Flipper.enable_actor(:instructeur_bypass_email_login_token, instructeur.user)
end
end
Administrateur.includes(:user).find_each do |administrateur|
if administrateur.features['web_hook']
pp "enable :administrateur_web_hook for #{administrateur.user.email}"
Flipper.enable_actor(:administrateur_web_hook, administrateur.user)
end
if administrateur.features['champ_integer_number']
pp "enable :administrateur_champ_integer_number for #{administrateur.user.email}"
Flipper.enable_actor(:administrateur_champ_integer_number, administrateur.user)
end
end
# Update task as completed. If you remove the line below, the task will
# run with every deploy (or every time you call after_party:run).
AfterParty::TaskRecord.create version: '20190829065022'
end
end

View file

@ -1,16 +0,0 @@
namespace :after_party do
desc 'Deployment task: backfill_daily_email_notification_columns'
task backfill_daily_email_notification_columns: :environment do
puts "Running deploy task 'backfill_daily_email_notification_columns'"
AssignTo.find_each do |assign_to|
columns_to_update = {}
if assign_to.email_notifications_enabled != assign_to.daily_email_notifications_enabled
columns_to_update[:daily_email_notifications_enabled] = assign_to.email_notifications_enabled
end
assign_to.update_columns(columns_to_update) unless columns_to_update.empty?
end
# Update task as completed. If you remove the line below, the task will
# run with every deploy (or every time you call after_party:run).
AfterParty::TaskRecord.create version: '20200220142710'
end # task :backfill_daily_email_notification_columns
end # namespace :after_party

View file

@ -164,6 +164,7 @@ describe ApplicationController, type: :controller do
allow(@controller).to receive(:instructeur_signed_in?).and_return(instructeur_signed_in) allow(@controller).to receive(:instructeur_signed_in?).and_return(instructeur_signed_in)
allow(@controller).to receive(:sensitive_path).and_return(sensitive_path) allow(@controller).to receive(:sensitive_path).and_return(sensitive_path)
allow(@controller).to receive(:send_login_token_or_bufferize) allow(@controller).to receive(:send_login_token_or_bufferize)
allow(@controller).to receive(:get_stored_location_for).and_return(nil)
allow(@controller).to receive(:store_location_for) allow(@controller).to receive(:store_location_for)
allow(IPService).to receive(:ip_trusted?).and_return(ip_trusted) allow(IPService).to receive(:ip_trusted?).and_return(ip_trusted)
end end

View file

@ -75,7 +75,7 @@ describe Champs::CarteController, type: :controller do
allow_any_instance_of(ApiCarto::QuartiersPrioritairesAdapter) allow_any_instance_of(ApiCarto::QuartiersPrioritairesAdapter)
.to receive(:results) .to receive(:results)
.and_raise(RestClient::ResourceNotFound) .and_raise(ApiCarto::API::ResourceNotFound)
post :show, params: params, format: 'js' post :show, params: params, format: 'js'
end end

View file

@ -59,7 +59,7 @@ describe Champs::SiretController, type: :controller do
let(:siret) { '82161143100015' } let(:siret) { '82161143100015' }
before do before do
allow(controller).to receive(:find_etablissement_with_siret).and_raise(RestClient::RequestFailed) allow(controller).to receive(:find_etablissement_with_siret).and_raise(ApiEntreprise::API::RequestFailed)
end end
subject! { get :show, params: params, format: 'js' } subject! { get :show, params: params, format: 'js' }

View file

@ -29,6 +29,10 @@ FactoryBot.define do
create(:exercice, etablissement: etablissement) create(:exercice, etablissement: etablissement)
end end
end end
trait :non_diffusable do
diffusable_commercialement { false }
end
end end
trait :is_association do trait :is_association do

View file

@ -14,7 +14,7 @@ FactoryBot.define do
path { SecureRandom.uuid } path { SecureRandom.uuid }
transient do transient do
administrateur {} administrateur { }
instructeurs { [] } instructeurs { [] }
end end

View file

@ -110,4 +110,16 @@ feature 'Creating a new dossier:' do
end end
end end
end end
context 'when the user is not signed in' do
let(:instructeur) { create(:instructeur) }
let(:procedure) { create(:procedure, :published) }
scenario 'the user is an instructeur with untrusted device' do
visit commencer_path(path: procedure.path)
click_on "Jai déjà un compte"
sign_in_with(instructeur.email, instructeur.user.password, true)
expect(page).to have_current_path(commencer_path(path: procedure.path))
end
end
end end

View file

@ -26,7 +26,7 @@
"code": null, "code": null,
"value": null "value": null
}, },
"diffusable_commercialement": null, "diffusable_commercialement": true,
"adresse": { "adresse": {
"l1": "OCTO TECHNOLOGY", "l1": "OCTO TECHNOLOGY",
"l2": null, "l2": null,

View file

@ -0,0 +1,49 @@
{
"etablissement": {
"siege_social": true,
"siret": "41816609600051",
"naf": "6202A",
"libelle_naf": "Conseil en systèmes et logiciels informatiques",
"date_mise_a_jour": 1449183600,
"tranche_effectif_salarie_etablissement": {
"de": 200,
"a": 249,
"code": "31",
"date_reference": "2014",
"intitule": "200 à 249 salariés"
},
"date_creation_etablissement": 1108594800,
"enseigne": null,
"region_implantation": {
"code": "11",
"value": "Île-de-France"
},
"commune_implantation": {
"code": "75108",
"value": "PARIS 8"
},
"pays_implantation": {
"code": null,
"value": null
},
"diffusable_commercialement": false,
"adresse": {
"l1": "OCTO TECHNOLOGY",
"l2": null,
"l3": null,
"l4": "50 AVENUE DES CHAMPS ELYSEES",
"l5": null,
"l6": "75008 PARIS",
"l7": "FRANCE",
"numero_voie": "50",
"type_voie": "AV",
"nom_voie": "DES CHAMPS ELYSEES",
"complement_adresse": "complement_adresse",
"code_postal": "75008",
"localite": "PARIS 8",
"code_insee_localite": "75108",
"cedex": null
}
},
"gateway_error": false
}

View file

@ -15,8 +15,8 @@ describe ApiCarto::API do
let(:status) { 404 } let(:status) { 404 }
let(:body) { '' } let(:body) { '' }
it 'raises RestClient::ResourceNotFound' do it 'raises ApiCarto::API::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound) expect { subject }.to raise_error(ApiCarto::API::ResourceNotFound)
end end
end end
@ -25,8 +25,8 @@ describe ApiCarto::API do
let(:status) { 500 } let(:status) { 500 }
let(:body) { 'toto' } let(:body) { 'toto' }
it 'raises RestClient::ResourceNotFound' do it 'raises ApiCarto::API::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound) expect { subject }.to raise_error(ApiCarto::API::ResourceNotFound)
end end
end end
@ -63,8 +63,8 @@ describe ApiCarto::API do
let(:status) { 404 } let(:status) { 404 }
let(:body) { '' } let(:body) { '' }
it 'raises RestClient::ResourceNotFound' do it 'raises ApiCarto::API::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound) expect { subject }.to raise_error(ApiCarto::API::ResourceNotFound)
end end
end end

View file

@ -60,6 +60,6 @@ describe ApiCarto::CadastreAdapter do
let(:status) { 404 } let(:status) { 404 }
let(:body) { '' } let(:body) { '' }
it { expect { subject }.to raise_error(RestClient::ResourceNotFound) } it { expect { subject }.to raise_error(ApiCarto::API::ResourceNotFound) }
end end
end end

View file

@ -33,6 +33,6 @@ describe ApiCarto::QuartiersPrioritairesAdapter do
let(:status) { 404 } let(:status) { 404 }
let(:body) { '' } let(:body) { '' }
it { expect { subject }.to raise_error(RestClient::ResourceNotFound) } it { expect { subject }.to raise_error(ApiCarto::API::ResourceNotFound) }
end end
end end

View file

@ -16,8 +16,8 @@ describe ApiEntreprise::API do
let(:status) { 502 } let(:status) { 502 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_unavailable.json') } let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_unavailable.json') }
it 'raises RestClient::RequestFailed' do it 'raises ApiEntreprise::API::RequestFailed' do
expect { subject }.to raise_error(RestClient::RequestFailed) expect { subject }.to raise_error(ApiEntreprise::API::RequestFailed)
end end
end end
@ -26,8 +26,8 @@ describe ApiEntreprise::API do
let(:status) { 404 } let(:status) { 404 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_not_found.json') } let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_not_found.json') }
it 'raises RestClient::ResourceNotFound' do it 'raises ApiEntreprise::API::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound) expect { subject }.to raise_error(ApiEntreprise::API::ResourceNotFound)
end end
end end
@ -36,8 +36,8 @@ describe ApiEntreprise::API do
let(:status) { 403 } let(:status) { 403 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_private.json') } let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_private.json') }
it 'raises RestClient::ResourceNotFound' do it 'raises ApiEntreprise::API::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound) expect { subject }.to raise_error(ApiEntreprise::API::ResourceNotFound)
end end
end end
@ -55,7 +55,7 @@ describe ApiEntreprise::API do
describe '.etablissement' do describe '.etablissement' do
subject { described_class.etablissement(siret, procedure_id) } subject { described_class.etablissement(siret, procedure_id) }
before do before do
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*token=/) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*non_diffusables=true&.*token=/)
.to_return(status: status, body: body) .to_return(status: status, body: body)
end end
@ -64,8 +64,8 @@ describe ApiEntreprise::API do
let(:status) { 404 } let(:status) { 404 }
let(:body) { '' } let(:body) { '' }
it 'raises RestClient::ResourceNotFound' do it 'raises ApiEntreprise::API::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound) expect { subject }.to raise_error(ApiEntreprise::API::ResourceNotFound)
end end
end end
@ -93,8 +93,8 @@ describe ApiEntreprise::API do
let(:status) { 404 } let(:status) { 404 }
let(:body) { '' } let(:body) { '' }
it 'raises RestClient::ResourceNotFound' do it 'raises ApiEntreprise::API::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound) expect { subject }.to raise_error(ApiEntreprise::API::ResourceNotFound)
end end
end end
@ -105,7 +105,7 @@ describe ApiEntreprise::API do
let(:status) { 200 } let(:status) { 200 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/exercices.json') } let(:body) { File.read('spec/fixtures/files/api_entreprise/exercices.json') }
it 'raises RestClient::Unauthorized' do it 'success' do
expect(subject).to eq(JSON.parse(body, symbolize_names: true)) expect(subject).to eq(JSON.parse(body, symbolize_names: true))
end end
end end
@ -124,8 +124,8 @@ describe ApiEntreprise::API do
let(:status) { 404 } let(:status) { 404 }
let(:body) { '' } let(:body) { '' }
it 'raises RestClient::ResourceNotFound' do it 'raises ApiEntreprise::API::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound) expect { subject }.to raise_error(ApiEntreprise::API::ResourceNotFound)
end end
end end

View file

@ -84,7 +84,7 @@ describe ApiEntreprise::EntrepriseAdapter do
let(:status) { 502 } let(:status) { 502 }
it 'raises an exception' do it 'raises an exception' do
expect { subject }.to raise_error(RestClient::RequestFailed) expect { subject }.to raise_error(ApiEntreprise::API::RequestFailed)
end end
end end
end end

View file

@ -3,7 +3,7 @@ require 'spec_helper'
describe ApiEntreprise::EtablissementAdapter do describe ApiEntreprise::EtablissementAdapter do
let(:procedure_id) { 33 } let(:procedure_id) { 33 }
context 'SIRET valide' do context 'SIRET valide avec infos diffusables' do
let(:siret) { '41816609600051' } let(:siret) { '41816609600051' }
subject { described_class.new(siret, procedure_id).to_params } subject { described_class.new(siret, procedure_id).to_params }
@ -33,6 +33,10 @@ describe ApiEntreprise::EtablissementAdapter do
expect(subject[:libelle_naf]).to eq('Conseil en systèmes et logiciels informatiques') expect(subject[:libelle_naf]).to eq('Conseil en systèmes et logiciels informatiques')
end end
it 'L\'entreprise contient bien un diffusable_commercialement qui vaut true' do
expect(subject[:diffusable_commercialement]).to eq(true)
end
context 'Concaténation lignes adresse' do context 'Concaténation lignes adresse' do
it 'L\'entreprise contient bien une adresse sur plusieurs lignes' do it 'L\'entreprise contient bien une adresse sur plusieurs lignes' do
expect(subject[:adresse]).to eq("OCTO TECHNOLOGY\r\n50 AVENUE DES CHAMPS ELYSEES\r\n75008 PARIS\r\nFRANCE") expect(subject[:adresse]).to eq("OCTO TECHNOLOGY\r\n50 AVENUE DES CHAMPS ELYSEES\r\n75008 PARIS\r\nFRANCE")
@ -70,6 +74,20 @@ describe ApiEntreprise::EtablissementAdapter do
end end
end end
context 'SIRET valide avec infos non diffusables' do
let(:siret) { '41816609600051' }
subject { described_class.new(siret, procedure_id).to_params }
before do
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*token=/)
.to_return(body: File.read('spec/fixtures/files/api_entreprise/etablissements_private.json', status: 200))
end
it 'L\'entreprise contient bien un diffusable_commercialement qui vaut false' do
expect(subject[:diffusable_commercialement]).to eq(false)
end
end
context 'when siret is not found' do context 'when siret is not found' do
let(:bad_siret) { 11_111_111_111_111 } let(:bad_siret) { 11_111_111_111_111 }
subject { described_class.new(bad_siret, 12).to_params } subject { described_class.new(bad_siret, 12).to_params }

View file

@ -59,6 +59,14 @@ describe Administrateur, type: :model do
expect(Administrateur.find_by(id: administrateur.id)).to be_nil expect(Administrateur.find_by(id: administrateur.id)).to be_nil
expect(service.reload.administrateur).to eq(autre_administrateur) expect(service.reload.administrateur).to eq(autre_administrateur)
end end
it "delete service if not associated to procedures" do
service_without_procedure = create(:service, administrateur: administrateur)
administrateur.delete_and_transfer_services
expect(Service.find_by(id: service_without_procedure.id)).to be_nil
expect(Administrateur.find_by(id: administrateur.id)).to be_nil
end
end end
# describe '#password_complexity' do # describe '#password_complexity' do

View file

@ -401,6 +401,8 @@ describe Instructeur, type: :model do
expect(instructeur.email_notification_data).to eq([ expect(instructeur.email_notification_data).to eq([
{ {
nb_en_construction: 1, nb_en_construction: 1,
nb_en_instruction: 0,
nb_accepted: 0,
nb_notification: 0, nb_notification: 0,
procedure_id: procedure_to_assign.id, procedure_id: procedure_to_assign.id,
procedure_libelle: procedure_to_assign.libelle procedure_libelle: procedure_to_assign.libelle
@ -420,6 +422,8 @@ describe Instructeur, type: :model do
expect(instructeur.email_notification_data).to eq([ expect(instructeur.email_notification_data).to eq([
{ {
nb_en_construction: 0, nb_en_construction: 0,
nb_en_instruction: 0,
nb_accepted: 0,
nb_notification: 3, nb_notification: 3,
procedure_id: procedure_to_assign.id, procedure_id: procedure_to_assign.id,
procedure_libelle: procedure_to_assign.libelle procedure_libelle: procedure_to_assign.libelle
@ -428,6 +432,75 @@ describe Instructeur, type: :model do
end end
end end
context 'when a declarated dossier in instruction exists' do
let!(:dossier) { create(:dossier, procedure: procedure_to_assign, state: Dossier.states.fetch(:en_construction)) }
before do
procedure_to_assign.update(declarative_with_state: "en_instruction")
DeclarativeProceduresJob.new.perform
dossier.reload
end
it { expect(procedure_to_assign.declarative_with_state).to eq("en_instruction") }
it { expect(dossier.state).to eq("en_instruction") }
it do
expect(instructeur.email_notification_data).to eq([
{
nb_en_construction: 0,
nb_en_instruction: 1,
nb_accepted: 0,
nb_notification: 0,
procedure_id: procedure_to_assign.id,
procedure_libelle: procedure_to_assign.libelle
}
])
end
end
context 'when a declarated dossier in accepte processed at today exists' do
let!(:dossier) { create(:dossier, procedure: procedure_to_assign, state: Dossier.states.fetch(:en_construction)) }
before do
procedure_to_assign.update(declarative_with_state: "accepte")
DeclarativeProceduresJob.new.perform
dossier.reload
end
it { expect(procedure_to_assign.declarative_with_state).to eq("accepte") }
it { expect(dossier.state).to eq("accepte") }
it do
expect(instructeur.email_notification_data).to eq([])
end
end
context 'when a declarated dossier in accepte processed at yesterday exists' do
let!(:dossier) { create(:dossier, procedure: procedure_to_assign, state: Dossier.states.fetch(:en_construction)) }
before do
procedure_to_assign.update(declarative_with_state: "accepte")
DeclarativeProceduresJob.new.perform
dossier.update(processed_at: Time.zone.yesterday.beginning_of_day)
dossier.reload
end
it { expect(procedure_to_assign.declarative_with_state).to eq("accepte") }
it { expect(dossier.state).to eq("accepte") }
it do
expect(instructeur.email_notification_data).to eq([
{
nb_en_construction: 0,
nb_en_instruction: 0,
nb_accepted: 1,
nb_notification: 0,
procedure_id: procedure_to_assign.id,
procedure_libelle: procedure_to_assign.libelle
}
])
end
end
context 'otherwise' do context 'otherwise' do
it { expect(instructeur.email_notification_data).to eq([]) } it { expect(instructeur.email_notification_data).to eq([]) }
end end

View file

@ -66,8 +66,8 @@ describe ApiEntrepriseService do
let(:entreprises_status) { 400 } let(:entreprises_status) { 400 }
let(:entreprises_body) { '' } let(:entreprises_body) { '' }
it 'should raise RestClient::RequestFailed' do it 'should raise ApiEntreprise::API::RequestFailed' do
expect { result }.to raise_error(RestClient::RequestFailed) expect { result }.to raise_error(ApiEntreprise::API::RequestFailed)
end end
end end
@ -75,8 +75,8 @@ describe ApiEntrepriseService do
let(:etablissements_status) { 400 } let(:etablissements_status) { 400 }
let(:etablissements_body) { '' } let(:etablissements_body) { '' }
it 'should raise RestClient::RequestFailed' do it 'should raise ApiEntreprise::API::RequestFailed' do
expect { result }.to raise_error(RestClient::RequestFailed) expect { result }.to raise_error(ApiEntreprise::API::RequestFailed)
end end
end end

View file

@ -47,6 +47,49 @@ describe NotificationService do
end end
end end
context 'when a declarative dossier in instruction exists on this procedure' do
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
before do
procedure.update(declarative_with_state: "en_instruction")
DeclarativeProceduresJob.new.perform
dossier.reload
end
it do
subject
expect(InstructeurMailer).to have_received(:send_notifications)
end
end
context 'when a declarative dossier in accepte on yesterday exists on this procedure' do
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
before do
procedure.update(declarative_with_state: "accepte")
DeclarativeProceduresJob.new.perform
dossier.update(processed_at: Time.zone.yesterday.beginning_of_day)
dossier.reload
end
it do
subject
expect(InstructeurMailer).to have_received(:send_notifications)
end
end
context 'when a declarative dossier in accepte on today exists on this procedure' do
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
before do
procedure.update(declarative_with_state: "accepte")
DeclarativeProceduresJob.new.perform
dossier.reload
end
it do
subject
expect(InstructeurMailer).not_to have_received(:send_notifications)
end
end
context 'when there is a notification on this procedure' do context 'when there is a notification on this procedure' do
before do before do
allow_any_instance_of(Instructeur).to receive(:notifications_for_procedure) allow_any_instance_of(Instructeur).to receive(:notifications_for_procedure)

View file

@ -16,6 +16,8 @@ describe 'instructeur_mailer/send_notifications.html.haml', type: :view do
procedure_libelle: 'une superbe démarche', procedure_libelle: 'une superbe démarche',
procedure_id: 213, procedure_id: 213,
nb_en_construction: 1, nb_en_construction: 1,
nb_en_instruction: 0,
nb_accepted: 0,
nb_notification: 0 nb_notification: 0
} }
] ]
@ -27,6 +29,50 @@ describe 'instructeur_mailer/send_notifications.html.haml', type: :view do
it { expect(rendered).not_to have_text('notification') } it { expect(rendered).not_to have_text('notification') }
end end
context 'when there is one declarated dossier in instruction' do
let(:data) do
[
{
procedure_libelle: 'une superbe démarche',
procedure_id: 213,
nb_en_construction: 0,
nb_en_instruction: 1,
nb_accepted: 0,
nb_notification: 0
}
]
end
it { expect(rendered).to have_link('une superbe démarche', href: procedure_url(213)) }
it { expect(rendered).to have_text('une superbe démarche') }
it { expect(rendered).to have_text('1 dossier') }
it { expect(rendered).not_to have_text('notification') }
it { expect(rendered).not_to have_text('construction') }
it { expect(rendered).not_to have_text('accepte') }
end
context 'when there is one declarated dossier in accepte' do
let(:data) do
[
{
procedure_libelle: 'une superbe démarche',
procedure_id: 213,
nb_en_construction: 0,
nb_en_instruction: 0,
nb_accepted: 1,
nb_notification: 0
}
]
end
it { expect(rendered).to have_link('une superbe démarche', href: procedure_url(213)) }
it { expect(rendered).to have_text('une superbe démarche') }
it { expect(rendered).to have_text('1 dossier') }
it { expect(rendered).not_to have_text('notification') }
it { expect(rendered).not_to have_text('construction') }
it { expect(rendered).not_to have_text('instruction') }
end
context 'when there is one notification' do context 'when there is one notification' do
let(:data) do let(:data) do
[ [
@ -34,6 +80,8 @@ describe 'instructeur_mailer/send_notifications.html.haml', type: :view do
procedure_libelle: 'une superbe démarche', procedure_libelle: 'une superbe démarche',
procedure_id: 213, procedure_id: 213,
nb_en_construction: 0, nb_en_construction: 0,
nb_en_instruction: 0,
nb_accepted: 0,
nb_notification: 1 nb_notification: 1
} }
] ]

View file

@ -12,4 +12,13 @@ describe 'shared/dossiers/identite_entreprise.html.haml', type: :view do
end end
end end
end end
context "for an entreprise with private infos" do
let(:etablissement) { create(:etablissement, :non_diffusable) }
it "displays only public infos" do
expect(rendered).to have_text(etablissement.entreprise_raison_sociale)
expect(rendered).not_to have_text(etablissement.entreprise.forme_juridique)
end
end
end end

View file

@ -29,6 +29,14 @@ describe 'users/dossiers/etablissement.html.haml', type: :view do
end end
end end
context 'etablissement avec infos non diffusables' do
let(:etablissement) { create(:etablissement, :with_exercices, :non_diffusable) }
it "affiche uniquement le nom de l'établissement si infos non diffusables" do
expect(rendered).to have_text(etablissement.entreprise_raison_sociale)
expect(rendered).not_to have_text(etablissement.entreprise.forme_juridique)
end
end
it 'prépare le footer' do it 'prépare le footer' do
expect(footer).to have_selector('footer') expect(footer).to have_selector('footer')
end end

View file

@ -1254,9 +1254,9 @@ acorn-walk@^6.1.1:
integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
acorn@^6.0.7, acorn@^6.2.1: acorn@^6.0.7, acorn@^6.2.1:
version "6.4.0" version "6.4.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474"
integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==
acorn@^7.1.0: acorn@^7.1.0:
version "7.1.0" version "7.1.0"