From fd42fafcb4a0a7787dcb2ab25f2facef6e8171d2 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 21 Nov 2019 18:52:07 +0100 Subject: [PATCH] [GraphQL]: informations du demandeur du dossier --- Gemfile.lock | 2 +- app/graphql/api/v2/schema.rb | 9 +- app/graphql/schema.graphql | 77 +++++++- app/graphql/types/champ_type.rb | 2 + .../types/champs/civilite_champ_type.rb | 7 + app/graphql/types/civilite.rb | 6 + app/graphql/types/demandeur_type.rb | 18 ++ app/graphql/types/dossier_type.rb | 10 ++ app/graphql/types/personne_morale_type.rb | 50 +++++- app/graphql/types/personne_physique_type.rb | 10 ++ .../api/v2/graphql_controller_spec.rb | 169 ++++++++++++------ 11 files changed, 305 insertions(+), 55 deletions(-) create mode 100644 app/graphql/types/champs/civilite_champ_type.rb create mode 100644 app/graphql/types/civilite.rb create mode 100644 app/graphql/types/demandeur_type.rb create mode 100644 app/graphql/types/personne_physique_type.rb diff --git a/Gemfile.lock b/Gemfile.lock index 3fccfeea8..423259e6f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -241,7 +241,7 @@ GEM graphiql-rails (1.7.0) railties sprockets-rails - graphql (1.9.10) + graphql (1.9.15) graphql-batch (0.4.1) graphql (>= 1.3, < 2) promise.rb (~> 0.7.2) diff --git a/app/graphql/api/v2/schema.rb b/app/graphql/api/v2/schema.rb index 390d60c44..26089ef11 100644 --- a/app/graphql/api/v2/schema.rb +++ b/app/graphql/api/v2/schema.rb @@ -26,6 +26,10 @@ class Api::V2::Schema < GraphQL::Schema Types::MessageType when Instructeur, User Types::ProfileType + when Individual + Types::PersonnePhysiqueType + when Etablissement + Types::PersonneMoraleType else raise GraphQL::ExecutionError.new("Unexpected object: #{obj}") end @@ -33,6 +37,7 @@ class Api::V2::Schema < GraphQL::Schema orphan_types Types::Champs::CarteChampType, Types::Champs::CheckboxChampType, + Types::Champs::CiviliteChampType, Types::Champs::DateChampType, Types::Champs::DecimalNumberChampType, Types::Champs::DossierLinkChampType, @@ -45,7 +50,9 @@ class Api::V2::Schema < GraphQL::Schema Types::Champs::TextChampType, Types::GeoAreas::ParcelleCadastraleType, Types::GeoAreas::QuartierPrioritaireType, - Types::GeoAreas::SelectionUtilisateurType + Types::GeoAreas::SelectionUtilisateurType, + Types::PersonneMoraleType, + Types::PersonnePhysiqueType def self.unauthorized_object(error) # Add a top-level error to the response instead of returning nil: diff --git a/app/graphql/schema.graphql b/app/graphql/schema.graphql index 6ab7884ec..5740b29ec 100644 --- a/app/graphql/schema.graphql +++ b/app/graphql/schema.graphql @@ -1,3 +1,12 @@ +type Association { + dateCreation: ISO8601Date! + dateDeclaration: ISO8601Date! + datePublication: ISO8601Date! + objet: String! + rna: String! + titre: String! +} + type Avis { attachmentUrl: URL dateQuestion: ISO8601DateTime! @@ -76,6 +85,33 @@ type CheckboxChamp implements Champ { value: Boolean! } +enum Civilite { + """ + Monsieur + """ + M + + """ + Madame + """ + Mme +} + +type CiviliteChamp implements Champ { + id: ID! + + """ + Libellé du champ. + """ + label: String! + + """ + La valeur du champ sous forme texte. + """ + stringValue: String + value: Civilite +} + """ GeoJSON coordinates """ @@ -157,6 +193,10 @@ type DecimalNumberChamp implements Champ { value: Float } +interface Demandeur { + id: ID! +} + """ Une demarche """ @@ -327,6 +367,7 @@ type Dossier { Date de traitement. """ dateTraitement: ISO8601DateTime + demandeur: Demandeur! id: ID! instructeurs: [Profile!]! messages: [Message!]! @@ -595,6 +636,22 @@ enum DossierState { sans_suite } +type Entreprise { + capitalSocial: Int! + codeEffectifEntreprise: String! + dateCreation: ISO8601Date! + formeJuridique: String! + formeJuridiqueCode: String! + inlineAdresse: String! + nom: String! + nomCommercial: String! + numeroTvaIntracommunautaire: String! + prenom: String! + raisonSociale: String! + siren: String! + siretSiegeSocial: String! +} + interface GeoArea { geometry: GeoJSON! id: ID! @@ -632,6 +689,11 @@ type GroupeInstructeur { label: String! } +""" +An ISO 8601-encoded date +""" +scalar ISO8601Date + """ An ISO 8601-encoded datetime """ @@ -775,21 +837,32 @@ type ParcelleCadastrale implements GeoArea { surfaceParcelle: Float! } -type PersonneMorale { +type PersonneMorale implements Demandeur { adresse: String! + association: Association codeInseeLocalite: String! codePostal: String! complementAdresse: String! + entreprise: Entreprise + id: ID! libelleNaf: String! localite: String! naf: String! nomVoie: String! numeroVoie: String! - siegeSocial: String! + siegeSocial: Boolean! siret: String! typeVoie: String! } +type PersonnePhysique implements Demandeur { + civilite: Civilite + dateDeNaissance: ISO8601Date + id: ID! + nom: String! + prenom: String! +} + type PieceJustificativeChamp implements Champ { id: ID! diff --git a/app/graphql/types/champ_type.rb b/app/graphql/types/champ_type.rb index 8383e409f..928e5f582 100644 --- a/app/graphql/types/champ_type.rb +++ b/app/graphql/types/champ_type.rb @@ -31,6 +31,8 @@ module Types Types::Champs::MultipleDropDownListChampType when ::Champs::LinkedDropDownListChamp Types::Champs::LinkedDropDownListChampType + when ::Champs::CiviliteChamp + Types::Champs::CiviliteChampType else Types::Champs::TextChampType end diff --git a/app/graphql/types/champs/civilite_champ_type.rb b/app/graphql/types/champs/civilite_champ_type.rb new file mode 100644 index 000000000..412daeeac --- /dev/null +++ b/app/graphql/types/champs/civilite_champ_type.rb @@ -0,0 +1,7 @@ +module Types::Champs + class CiviliteChampType < Types::BaseObject + implements Types::ChampType + + field :value, Types::Civilite, null: true + end +end diff --git a/app/graphql/types/civilite.rb b/app/graphql/types/civilite.rb new file mode 100644 index 000000000..562670651 --- /dev/null +++ b/app/graphql/types/civilite.rb @@ -0,0 +1,6 @@ +module Types + class Civilite < Types::BaseEnum + value("M", "Monsieur", value: Individual::GENDER_MALE) + value("Mme", "Madame", value: Individual::GENDER_FEMALE) + end +end diff --git a/app/graphql/types/demandeur_type.rb b/app/graphql/types/demandeur_type.rb new file mode 100644 index 000000000..9f5d01b3d --- /dev/null +++ b/app/graphql/types/demandeur_type.rb @@ -0,0 +1,18 @@ +module Types + module DemandeurType + include Types::BaseInterface + + global_id_field :id + + definition_methods do + def resolve_type(object, context) + case object + when Individual + Types::PersonnePhysiqueType + when Etablissement + Types::PersonneMoraleType + end + end + end + end +end diff --git a/app/graphql/types/dossier_type.rb b/app/graphql/types/dossier_type.rb index fa571275b..ac8961241 100644 --- a/app/graphql/types/dossier_type.rb +++ b/app/graphql/types/dossier_type.rb @@ -24,6 +24,8 @@ module Types { Extensions::Attachment => { attachment: :justificatif_motivation } } ] + field :demandeur, Types::DemandeurType, null: false + field :usager, Types::ProfileType, null: false field :instructeurs, [Types::ProfileType], null: false @@ -61,6 +63,14 @@ module Types Loaders::Association.for(object.class, :champs_private).load(object) end + def demandeur + if object.procedure.for_individual + Loaders::Association.for(object.class, :individual).load(object) + else + Loaders::Association.for(object.class, :etablissement).load(object) + end + end + def self.authorized?(object, context) authorized_demarche?(object.procedure, context) end diff --git a/app/graphql/types/personne_morale_type.rb b/app/graphql/types/personne_morale_type.rb index 999fafee3..6d15cf84e 100644 --- a/app/graphql/types/personne_morale_type.rb +++ b/app/graphql/types/personne_morale_type.rb @@ -1,7 +1,34 @@ module Types class PersonneMoraleType < Types::BaseObject + class EntrepriseType < Types::BaseObject + field :siren, String, null: false + field :capital_social, Int, null: false + field :numero_tva_intracommunautaire, String, null: false + field :forme_juridique, String, null: false + field :forme_juridique_code, String, null: false + field :nom_commercial, String, null: false + field :raison_sociale, String, null: false + field :siret_siege_social, String, null: false + field :code_effectif_entreprise, String, null: false + field :date_creation, GraphQL::Types::ISO8601Date, null: false + field :nom, String, null: false + field :prenom, String, null: false + field :inline_adresse, String, null: false + end + + class AssociationType < Types::BaseObject + field :rna, String, null: false + field :titre, String, null: false + field :objet, String, null: false + field :date_creation, GraphQL::Types::ISO8601Date, null: false + field :date_declaration, GraphQL::Types::ISO8601Date, null: false + field :date_publication, GraphQL::Types::ISO8601Date, null: false + end + + implements Types::DemandeurType + field :siret, String, null: false - field :siege_social, String, null: false + field :siege_social, Boolean, null: false field :naf, String, null: false field :libelle_naf, String, null: false field :adresse, String, null: false @@ -12,5 +39,26 @@ module Types field :code_postal, String, null: false field :localite, String, null: false field :code_insee_localite, String, null: false + field :entreprise, EntrepriseType, null: true + field :association, AssociationType, null: true + + def entreprise + if object.entreprise_siren.present? + object.entreprise + end + end + + def association + if object.association? + { + rna: object.association_rna, + titre: object.association_titre, + objet: object.association_objet, + date_creation: object.association_date_creation, + date_declaration: object.association_date_declaration, + date_publication: object.association_date_publication + } + end + end end end diff --git a/app/graphql/types/personne_physique_type.rb b/app/graphql/types/personne_physique_type.rb new file mode 100644 index 000000000..5074a04ca --- /dev/null +++ b/app/graphql/types/personne_physique_type.rb @@ -0,0 +1,10 @@ +module Types + class PersonnePhysiqueType < Types::BaseObject + implements Types::DemandeurType + + field :nom, String, null: false + field :prenom, String, null: false + field :civilite, Types::Civilite, null: true, method: :gender + field :date_de_naissance, GraphQL::Types::ISO8601Date, null: true, method: :birthdate + end +end diff --git a/spec/controllers/api/v2/graphql_controller_spec.rb b/spec/controllers/api/v2/graphql_controller_spec.rb index d87601827..982ea8bb7 100644 --- a/spec/controllers/api/v2/graphql_controller_spec.rb +++ b/spec/controllers/api/v2/graphql_controller_spec.rb @@ -3,18 +3,19 @@ require 'spec_helper' describe API::V2::GraphqlController do let(:admin) { create(:administrateur) } let(:token) { admin.renew_api_token } - let(:procedure) { create(:procedure, :with_all_champs, administrateurs: [admin]) } + let(:procedure) { create(:procedure, :published, :for_individual, :with_all_champs, administrateurs: [admin]) } let(:dossier) do dossier = create(:dossier, :en_construction, :with_all_champs, + :for_individual, procedure: procedure) create(:commentaire, dossier: dossier, email: 'test@test.com') dossier end - let(:dossier1) { create(:dossier, :en_construction, procedure: procedure, en_construction_at: 1.day.ago) } - let(:dossier2) { create(:dossier, :en_construction, procedure: procedure, en_construction_at: 3.days.ago) } - let!(:dossier_brouillon) { create(:dossier, procedure: procedure) } + let(:dossier1) { create(:dossier, :en_construction, :for_individual, procedure: procedure, en_construction_at: 1.day.ago) } + let(:dossier2) { create(:dossier, :en_construction, :for_individual, procedure: procedure, en_construction_at: 3.days.ago) } + let!(:dossier_brouillon) { create(:dossier, :for_individual, procedure: procedure) } let(:dossiers) { [dossier2, dossier1, dossier] } let(:instructeur) { create(:instructeur, followed_dossiers: dossiers) } @@ -79,7 +80,7 @@ describe API::V2::GraphqlController do number: procedure.id, title: procedure.libelle, description: procedure.description, - state: 'brouillon', + state: 'publiee', dateFermeture: nil, dateCreation: procedure.created_at.iso8601, dateDerniereModification: procedure.updated_at.iso8601, @@ -149,6 +150,15 @@ describe API::V2::GraphqlController do id email } + demandeur { + id + ... on PersonnePhysique { + nom + prenom + civilite + dateDeNaissance + } + } instructeurs { id email @@ -177,45 +187,104 @@ describe API::V2::GraphqlController do }" end - it "should be returned" do - expect(gql_errors).to eq(nil) - expect(gql_data).to eq(dossier: { - id: dossier.to_typed_id, - number: dossier.id, - state: 'en_construction', - dateDerniereModification: dossier.updated_at.iso8601, - datePassageEnConstruction: dossier.en_construction_at.iso8601, - datePassageEnInstruction: nil, - dateTraitement: nil, - motivation: nil, - motivationAttachmentUrl: nil, - usager: { - id: dossier.user.to_typed_id, - email: dossier.user.email - }, - instructeurs: [ - { - id: instructeur.to_typed_id, - email: instructeur.email + context "with individual" do + it "should be returned" do + expect(gql_errors).to eq(nil) + expect(gql_data).to eq(dossier: { + id: dossier.to_typed_id, + number: dossier.id, + state: 'en_construction', + dateDerniereModification: dossier.updated_at.iso8601, + datePassageEnConstruction: dossier.en_construction_at.iso8601, + datePassageEnInstruction: nil, + dateTraitement: nil, + motivation: nil, + motivationAttachmentUrl: nil, + usager: { + id: dossier.user.to_typed_id, + email: dossier.user.email + }, + instructeurs: [ + { + id: instructeur.to_typed_id, + email: instructeur.email + } + ], + demandeur: { + id: dossier.individual.to_typed_id, + nom: dossier.individual.nom, + prenom: dossier.individual.prenom, + civilite: 'M', + dateDeNaissance: '1991-11-01' + }, + messages: dossier.commentaires.map do |commentaire| + { + body: commentaire.body, + attachmentUrl: nil, + email: commentaire.email + } + end, + avis: [], + champs: dossier.champs.map do |champ| + { + id: champ.to_typed_id, + label: champ.libelle, + stringValue: champ.for_api_v2 + } + end + }) + expect(gql_data[:dossier][:champs][0][:id]).to eq(dossier.champs[0].type_de_champ.to_typed_id) + end + end + + context "with entreprise" do + let(:procedure) { create(:procedure, :published, administrateurs: [admin]) } + let(:dossier) { create(:dossier, :en_construction, :with_entreprise, procedure: procedure) } + + let(:query) do + "{ + dossier(number: #{dossier.id}) { + id + number + usager { + id + email + } + demandeur { + id + ... on PersonneMorale { + siret + siegeSocial + entreprise { + siren + dateCreation + } + } + } } - ], - messages: dossier.commentaires.map do |commentaire| - { - body: commentaire.body, - attachmentUrl: nil, - email: commentaire.email + }" + end + + it "should be returned" do + expect(gql_errors).to eq(nil) + expect(gql_data).to eq(dossier: { + id: dossier.to_typed_id, + number: dossier.id, + usager: { + id: dossier.user.to_typed_id, + email: dossier.user.email + }, + demandeur: { + id: dossier.etablissement.to_typed_id, + siret: dossier.etablissement.siret, + siegeSocial: dossier.etablissement.siege_social, + entreprise: { + siren: dossier.etablissement.entreprise_siren, + dateCreation: dossier.etablissement.entreprise_date_creation.iso8601 + } } - end, - avis: [], - champs: dossier.champs.map do |champ| - { - id: champ.to_typed_id, - label: champ.libelle, - stringValue: champ.for_api_v2 - } - end - }) - expect(gql_data[:dossier][:champs][0][:id]).to eq(dossier.champs[0].type_de_champ.to_typed_id) + }) + end end end @@ -296,7 +365,7 @@ describe API::V2::GraphqlController do end describe 'dossierPasserEnInstruction' do - let(:dossier) { create(:dossier, :en_construction, procedure: procedure) } + let(:dossier) { create(:dossier, :en_construction, :for_individual, procedure: procedure) } let(:query) do "mutation { dossierPasserEnInstruction(input: { @@ -331,7 +400,7 @@ describe API::V2::GraphqlController do end context 'validation error' do - let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) } + let(:dossier) { create(:dossier, :en_instruction, :for_individual, procedure: procedure) } it "should fail" do expect(gql_errors).to eq(nil) @@ -344,7 +413,7 @@ describe API::V2::GraphqlController do end describe 'dossierClasserSansSuite' do - let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) } + let(:dossier) { create(:dossier, :en_instruction, :for_individual, procedure: procedure) } let(:query) do "mutation { dossierClasserSansSuite(input: { @@ -380,7 +449,7 @@ describe API::V2::GraphqlController do end context 'validation error' do - let(:dossier) { create(:dossier, :accepte, procedure: procedure) } + let(:dossier) { create(:dossier, :accepte, :for_individual, procedure: procedure) } it "should fail" do expect(gql_errors).to eq(nil) @@ -393,7 +462,7 @@ describe API::V2::GraphqlController do end describe 'dossierRefuser' do - let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) } + let(:dossier) { create(:dossier, :en_instruction, :for_individual, procedure: procedure) } let(:query) do "mutation { dossierRefuser(input: { @@ -429,7 +498,7 @@ describe API::V2::GraphqlController do end context 'validation error' do - let(:dossier) { create(:dossier, :sans_suite, procedure: procedure) } + let(:dossier) { create(:dossier, :sans_suite, :for_individual, procedure: procedure) } it "should fail" do expect(gql_errors).to eq(nil) @@ -442,7 +511,7 @@ describe API::V2::GraphqlController do end describe 'dossierAccepter' do - let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) } + let(:dossier) { create(:dossier, :en_instruction, :for_individual, procedure: procedure) } let(:query) do "mutation { dossierAccepter(input: { @@ -511,7 +580,7 @@ describe API::V2::GraphqlController do end context 'validation error' do - let(:dossier) { create(:dossier, :refuse, procedure: procedure) } + let(:dossier) { create(:dossier, :refuse, :for_individual, procedure: procedure) } it "should fail" do expect(gql_errors).to eq(nil)