Merge pull request #5100 from betagouv/5088-bilans-bdf

[5088] instructeurs : affiche les bilans bdf sous forme de csv
This commit is contained in:
krichtof 2020-04-30 16:23:15 +02:00 committed by GitHub
commit 25e06feb98
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 210 additions and 3 deletions

View file

@ -31,6 +31,10 @@ module Instructeurs
render 'admin/attestation_templates/show', formats: [:pdf] render 'admin/attestation_templates/show', formats: [:pdf]
end end
def bilans_bdf
render csv: dossier.etablissement.entreprise_bilans_bdf_to_csv
end
def show def show
@demande_seen_at = current_instructeur.follows.find_by(dossier: dossier)&.demande_seen_at @demande_seen_at = current_instructeur.follows.find_by(dossier: dossier)&.demande_seen_at

View file

@ -7,6 +7,7 @@ class ApiEntreprise::API
EFFECTIFS_ANNUELS_RESOURCE_NAME = "effectifs_annuels_acoss_covid" EFFECTIFS_ANNUELS_RESOURCE_NAME = "effectifs_annuels_acoss_covid"
ATTESTATION_SOCIALE_RESOURCE_NAME = "attestations_sociales_acoss" ATTESTATION_SOCIALE_RESOURCE_NAME = "attestations_sociales_acoss"
ATTESTATION_FISCALE_RESOURCE_NAME = "attestations_fiscales_dgfip" ATTESTATION_FISCALE_RESOURCE_NAME = "attestations_fiscales_dgfip"
BILANS_BDF_RESOURCE_NAME = "bilans_entreprises_bdf"
TIMEOUT = 15 TIMEOUT = 15
@ -51,6 +52,11 @@ class ApiEntreprise::API
call(ATTESTATION_FISCALE_RESOURCE_NAME, siren, procedure_id, user_id) if procedure.api_entreprise_role?("attestations_fiscales") call(ATTESTATION_FISCALE_RESOURCE_NAME, siren, procedure_id, user_id) if procedure.api_entreprise_role?("attestations_fiscales")
end end
def self.bilans_bdf(siren, procedure_id)
procedure = Procedure.find(procedure_id)
call(BILANS_BDF_RESOURCE_NAME, siren, procedure_id) if procedure.api_entreprise_role?("bilans_entreprise_bdf")
end
private private
def self.call(resource_name, siret_or_siren, procedure_id, user_id = nil) def self.call(resource_name, siret_or_siren, procedure_id, user_id = nil)

View file

@ -0,0 +1,23 @@
class ApiEntreprise::BilansBdfAdapter < ApiEntreprise::Adapter
def initialize(siren, procedure_id)
@siren = siren
@procedure_id = procedure_id
end
private
def get_resource
ApiEntreprise::API.bilans_bdf(@siren, @procedure_id)
end
def process_params
if data_source[:bilans].present?
{
entreprise_bilans_bdf: data_source[:bilans],
entreprise_bilans_bdf_monnaie: data_source[:monnaie]
}
else
{}
end
end
end

View file

@ -138,6 +138,14 @@ class Etablissement < ApplicationRecord
upload_attestation(url, entreprise_attestation_fiscale) upload_attestation(url, entreprise_attestation_fiscale)
end end
def entreprise_bilans_bdf_to_csv
headers = entreprise_bilans_bdf.flat_map(&:keys).uniq
data = entreprise_bilans_bdf.map do |bilan|
headers.map { |h| bilan[h] }
end
SpreadsheetArchitect.to_csv(headers: headers, data: data)
end
private private
def dossier_id_for_export def dossier_id_for_export

View file

@ -46,6 +46,13 @@ class ApiEntrepriseService
etablissement_params.merge!(attestation_fiscale_params) etablissement_params.merge!(attestation_fiscale_params)
rescue ApiEntreprise::API::RequestFailed rescue ApiEntreprise::API::RequestFailed
end end
begin
bilans_bdf_params = ApiEntreprise::BilansBdfAdapter.new(entreprise_params[:entreprise_siren], procedure_id).to_params
etablissement_params.merge!(bilans_bdf_params)
rescue ApiEntreprise::API::RequestFailed
end
etablissement_params.merge(entreprise_params) etablissement_params.merge(entreprise_params)
end end
end end

View file

@ -78,6 +78,13 @@
%th.libelle Attestation fiscale %th.libelle Attestation fiscale
%td= link_to "Consulter l'attestation", url_for(etablissement.entreprise_attestation_fiscale) %td= link_to "Consulter l'attestation", url_for(etablissement.entreprise_attestation_fiscale)
- if etablissement.entreprise_bilans_bdf_to_csv.present?
%tr
%th.libelle
Bilans Banque de France
= "en #{etablissement.entreprise_bilans_bdf_monnaie}"
%td= link_to "Consulter les bilans", bilans_bdf_instructeur_dossier_path
- if etablissement.association? - if etablissement.association?
%tr %tr
%th.libelle Numéro RNA : %th.libelle Numéro RNA :

View file

@ -318,6 +318,7 @@ Rails.application.routes.draw do
get 'attestation' get 'attestation'
get 'geo_data' get 'geo_data'
get 'apercu_attestation' get 'apercu_attestation'
get 'bilans_bdf'
get 'messagerie' get 'messagerie'
get 'annotations-privees' => 'dossiers#annotations_privees' get 'annotations-privees' => 'dossiers#annotations_privees'
get 'avis' get 'avis'

View file

@ -0,0 +1,6 @@
class AddBilansBdfToEtablissements < ActiveRecord::Migration[5.2]
def change
add_column :etablissements, :entreprise_bilans_bdf, :jsonb
add_column :etablissements, :entreprise_bilans_bdf_monnaie, :string
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_04_23_171759) do ActiveRecord::Schema.define(version: 2020_04_29_191305) 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"
@ -316,6 +316,8 @@ ActiveRecord::Schema.define(version: 2020_04_23_171759) do
t.decimal "entreprise_effectif_mensuel" t.decimal "entreprise_effectif_mensuel"
t.decimal "entreprise_effectif_annuel" t.decimal "entreprise_effectif_annuel"
t.string "entreprise_effectif_annuel_annee" t.string "entreprise_effectif_annuel_annee"
t.jsonb "entreprise_bilans_bdf"
t.string "entreprise_bilans_bdf_monnaie"
t.index ["dossier_id"], name: "index_etablissements_on_dossier_id" t.index ["dossier_id"], name: "index_etablissements_on_dossier_id"
end end

View file

@ -227,6 +227,9 @@ describe Users::DossiersController, type: :controller do
let(:api_entreprise_attestation_fiscale_status) { 200 } let(:api_entreprise_attestation_fiscale_status) { 200 }
let(:api_entreprise_attestation_fiscale_body) { File.read('spec/fixtures/files/api_entreprise/attestation_fiscale.json') } let(:api_entreprise_attestation_fiscale_body) { File.read('spec/fixtures/files/api_entreprise/attestation_fiscale.json') }
let(:api_entreprise_bilans_bdf_status) { 200 }
let(:api_entreprise_bilans_bdf_body) { File.read('spec/fixtures/files/api_entreprise/bilans_entreprise_bdf.json') }
def stub_api_entreprise_requests def stub_api_entreprise_requests
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*token=/) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*token=/)
.to_return(status: api_etablissement_status, body: api_etablissement_body) .to_return(status: api_etablissement_status, body: api_etablissement_body)
@ -248,12 +251,15 @@ describe Users::DossiersController, type: :controller do
.to_return(body: api_entreprise_attestation_fiscale_body, status: api_entreprise_attestation_fiscale_status) .to_return(body: api_entreprise_attestation_fiscale_body, status: api_entreprise_attestation_fiscale_status)
stub_request(:get, "https://storage.entreprise.api.gouv.fr/siade/1569156756-f6b7779f99fa95cd60dc03c04fcb-attestation_fiscale_dgfip.pdf") stub_request(:get, "https://storage.entreprise.api.gouv.fr/siade/1569156756-f6b7779f99fa95cd60dc03c04fcb-attestation_fiscale_dgfip.pdf")
.to_return(body: "body attestation", status: 200) .to_return(body: "body attestation", status: 200)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/bilans_entreprises_bdf\/#{siren}?.*token=/)
.to_return(body: api_entreprise_bilans_bdf_body, status: api_entreprise_bilans_bdf_status)
end end
before do before do
sign_in(user) sign_in(user)
stub_api_entreprise_requests stub_api_entreprise_requests
allow_any_instance_of(Procedure).to receive(:api_entreprise_roles).and_return(["attestations_fiscales", "attestations_sociales"]) allow_any_instance_of(Procedure).to receive(:api_entreprise_roles)
.and_return(["attestations_fiscales", "attestations_sociales", "bilans_entreprise_bdf"])
end end
before { Timecop.freeze(Time.zone.local(2020, 3, 14)) } before { Timecop.freeze(Time.zone.local(2020, 3, 14)) }
after { Timecop.return } after { Timecop.return }
@ -351,6 +357,7 @@ describe Users::DossiersController, type: :controller do
expect(dossier.etablissement.entreprise_effectif_annuel).to be_present expect(dossier.etablissement.entreprise_effectif_annuel).to be_present
expect(dossier.etablissement.entreprise_attestation_sociale).to be_attached expect(dossier.etablissement.entreprise_attestation_sociale).to be_attached
expect(dossier.etablissement.entreprise_attestation_fiscale).to be_attached expect(dossier.etablissement.entreprise_attestation_fiscale).to be_attached
expect(dossier.etablissement.entreprise_bilans_bdf).to be_present
end end
end end
end end

View file

@ -0,0 +1,51 @@
{
"monnaie": "kEuros",
"bilans": [
{
"duree_exercice": "12",
"valeur_ajoutee_bdf": "7848792",
"resultat_exercice": "347126",
"capitaux_propres_et_assimiles": "5928663",
"total_provisions_pour_risques_et_charges": "1957919",
"dettes1_emprunts_obligataires_et_convertibles": "0",
"dettes2_autres_emprunts_obligataires": "6552306",
"total_dettes_stables": "6552306",
"emprunts_et_dettes_financieres_divers": "430634",
"groupes_et_associes": "0",
"besoin_en_fonds_de_roulement": "-721507",
"disponibilites": "1983051",
"total_passif": "18478051",
"evolution_valeur_ajoutee_bdf": "",
"evolution_resultat_exercice": "",
"evolution_capitaux_propres_et_assimiles": "",
"evolution_total_provisions_pour_risques_et_charges": "",
"evolution_dettes1_emprunts_obligataires_et_convertibles": "",
"evolution_dettes2_autres_emprunts_obligataires": "",
"evolution_emprunts_et_dettes_financieres_divers": "",
"evolution_groupes_et_associes": "",
"evolution_besoin_en_fonds_de_roulement": "",
"evolution_disponibilites": "",
"evolution_total_passif": "",
"chiffre_affaires_ht": "12030700",
"capacite_autofinancement": "891914",
"date_arret_exercice": "201512",
"dettes3_emprunts_et_dettes_aupres_des_etablissements_de_credit": "0",
"dettes4_maturite_a_un_an_au_plus": "0",
"autres_fonds_propres": "0",
"capital_social_inclus_dans_capitaux_propres_et_assimiles": "3800000",
"excedent_brut_exploitation": "-1876863",
"evolution_chiffre_affaires_ht": "",
"evolution_capacite_autofinancement": "",
"evolution_dettes3_emprunts_et_dettes_aupres_des_etablissements_de_credit": "",
"evolution_dettes4_maturite_a_un_an_au_plus": "",
"evolution_autres_fonds_propres": "",
"evolution_capital_social_inclus_dans_capitaux_propres_et_assimiles": "",
"evolution_excedent_brut_exploitation": "",
"evolution_fonds_roulement_net_global": "",
"evolution_ratio_fonds_roulement_net_global_sur_besoin_en_fonds_de_roulement": "",
"evolution_total_dettes_stables": "",
"fonds_roulement_net_global": "2464585",
"ratio_fonds_roulement_net_global_sur_besoin_en_fonds_de_roulement": "-"
}, "bilan 2", "bilan 3"
]
}

View file

@ -213,4 +213,31 @@ describe ApiEntreprise::API do
it { expect(subject).to eq(JSON.parse(body, symbolize_names: true)) } it { expect(subject).to eq(JSON.parse(body, symbolize_names: true)) }
end end
end end
describe '.bilans_bdf' do
let(:procedure) { create(:procedure, api_entreprise_token: token) }
let(:siren) { '418166096' }
let(:status) { 200 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/bilans_entreprise_bdf.json') }
before do
allow_any_instance_of(Procedure).to receive(:api_entreprise_roles).and_return(roles)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/bilans_entreprises_bdf\/#{siren}?.*token=#{token}/)
.to_return(body: body, status: status)
end
subject { described_class.bilans_bdf(siren, procedure.id) }
context 'when token not authorized' do
let(:roles) { ["entreprises"] }
it { expect(subject).to eq(nil) }
end
context 'when token is authorized' do
let(:roles) { ["bilans_entreprise_bdf"] }
it { expect(subject).to eq(JSON.parse(body, symbolize_names: true)) }
end
end
end end

View file

@ -0,0 +1,26 @@
describe ApiEntreprise::BilansBdfAdapter do
let(:siren) { '418166096' }
let(:procedure) { create(:procedure) }
let(:procedure_id) { procedure.id }
let(:adapter) { described_class.new(siren, procedure_id) }
subject { adapter.to_params }
before do
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/bilans_entreprises_bdf\/#{siren}?.*token=/)
.to_return(body: body, status: status)
allow_any_instance_of(Procedure).to receive(:api_entreprise_roles).and_return(["bilans_entreprise_bdf"])
end
context "when the SIREN is valid" do
let(:body) { File.read('spec/fixtures/files/api_entreprise/bilans_entreprise_bdf.json') }
let(:status) { 200 }
it '#to_params class est une Hash ?' do
expect(subject).to be_an_instance_of(Hash)
end
it "returns bilans bdf" do
expect(subject[:entreprise_bilans_bdf][0][:valeur_ajoutee_bdf]).to eq("7848792")
end
end
end

View file

@ -35,4 +35,28 @@ describe Etablissement do
end end
end end
end end
describe '.entreprise_bilans_bdf_to_csv' do
let(:etablissement) { build(:etablissement, entreprise_bilans_bdf: bilans) }
let(:bilans) do
[
{
"total_passif": "1200",
"chiffres_affaires_ht": "40000"
},
{
"total_passif": "0",
"evolution_total_dettes_stables": "30"
}
]
end
subject { etablissement.entreprise_bilans_bdf_to_csv.split("\n") }
it "build a csv with all keys" do
expect(subject[0].split(',').sort).to eq(["total_passif", "chiffres_affaires_ht", "evolution_total_dettes_stables"].sort)
expect(subject[1].split(',')).to eq(["1200", "40000"])
expect(subject[2].split(',')).to eq(["0", "", "30"])
end
end
end end

View file

@ -19,6 +19,8 @@ describe ApiEntrepriseService do
.to_return(body: attestation_sociale_body, status: attestation_sociale_status) .to_return(body: attestation_sociale_body, status: attestation_sociale_status)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/attestations_fiscales_dgfip\/#{siren}?.*token=/) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/attestations_fiscales_dgfip\/#{siren}?.*token=/)
.to_return(body: attestation_fiscale_body, status: attestation_fiscale_status) .to_return(body: attestation_fiscale_body, status: attestation_fiscale_status)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/bilans_entreprises_bdf\/#{siren}?.*token=/)
.to_return(body: bilans_bdf_body, status: bilans_bdf_status)
end end
before { Timecop.freeze(Time.zone.local(2020, 3, 14)) } before { Timecop.freeze(Time.zone.local(2020, 3, 14)) }
@ -52,6 +54,10 @@ describe ApiEntrepriseService do
let(:attestation_fiscale_body) { File.read('spec/fixtures/files/api_entreprise/attestation_fiscale.json') } let(:attestation_fiscale_body) { File.read('spec/fixtures/files/api_entreprise/attestation_fiscale.json') }
let(:attestation_fiscale_url) { "https://storage.entreprise.api.gouv.fr/siade/1569156756-f6b7779f99fa95cd60dc03c04fcb-attestation_fiscale_dgfip.pdf" } let(:attestation_fiscale_url) { "https://storage.entreprise.api.gouv.fr/siade/1569156756-f6b7779f99fa95cd60dc03c04fcb-attestation_fiscale_dgfip.pdf" }
let(:bilans_bdf_status) { 200 }
let(:bilans_bdf_body) { File.read('spec/fixtures/files/api_entreprise/bilans_entreprise_bdf.json') }
let(:bilans_bdf) { JSON.parse(bilans_bdf_body, symbolize_names: true)[:bilans] }
let(:exercices_status) { 200 } let(:exercices_status) { 200 }
let(:exercices_body) { File.read('spec/fixtures/files/api_entreprise/exercices.json') } let(:exercices_body) { File.read('spec/fixtures/files/api_entreprise/exercices.json') }
@ -62,7 +68,8 @@ describe ApiEntrepriseService do
let(:result) { ApiEntrepriseService.get_etablissement_params_for_siret(siret, procedure.id) } let(:result) { ApiEntrepriseService.get_etablissement_params_for_siret(siret, procedure.id) }
before do before do
allow_any_instance_of(Procedure).to receive(:api_entreprise_roles).and_return(["attestations_sociales", "attestations_fiscales"]) allow_any_instance_of(Procedure).to receive(:api_entreprise_roles)
.and_return(["attestations_sociales", "attestations_fiscales", "bilans_entreprise_bdf"])
end end
context 'when service is up' do context 'when service is up' do
@ -75,6 +82,7 @@ describe ApiEntrepriseService do
expect(result[:entreprise_effectif_annuel]).to eq(effectif_annuel) expect(result[:entreprise_effectif_annuel]).to eq(effectif_annuel)
expect(result[:entreprise_attestation_sociale_url]).to eq(attestation_sociale_url) expect(result[:entreprise_attestation_sociale_url]).to eq(attestation_sociale_url)
expect(result[:entreprise_attestation_fiscale_url]).to eq(attestation_fiscale_url) expect(result[:entreprise_attestation_fiscale_url]).to eq(attestation_fiscale_url)
expect(result[:entreprise_bilans_bdf]).to eq(bilans_bdf)
end end
end end