Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple fixes on API Impot Particulier #606

Merged
merged 9 commits into from
Dec 16, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def create
private

def extract_authorization_request
@authorization_request = AuthorizationRequest.find(params[:authorization_request_id])
@authorization_request = AuthorizationRequest.find(params[:authorization_request_id]).decorate
end

def authorize_authorization_request_archive
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ def create

private

def extract_authorization_request
@authorization_request = AuthorizationRequest.find(params[:authorization_request_id]).decorate
end

def authorize_authorization_request_archive
authorize [:instruction, @authorization_request], :archive?
end
Expand Down
2 changes: 1 addition & 1 deletion app/decorators/authorization_request_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def display_stage_footer?
object.latest_authorization.request_as_validated.definition.next_stage?
end

def stage_already_started?
def next_stage_already_started?
display_stage_footer? &&
!object.validated?
end
Expand Down
7 changes: 6 additions & 1 deletion app/models/authorization_definition/stage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ def next_stage?
end

def previous_stages
@previouses || []
(@previouses || []).map do |previous|
{
definition: AuthorizationDefinition.find(previous[:id]),
form: AuthorizationRequestForm.find(previous[:form_id]),
}
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -32,40 +32,34 @@ module DGFIPExtensions::APIImpotParticulierScopes
validate :at_least_one_revenue_year_has_been_selected, if: -> { need_complete_validation?(:scopes) && !specific_requirements? }
validate :revenue_years_scopes_compatibility, if: -> { need_complete_validation?(:scopes) && !specific_requirements? }
validate :scopes_compatibility, if: -> { need_complete_validation?(:scopes) && !specific_requirements? }
validate :specific_requirements_document_presence, if: -> { specific_requirements? && need_complete_validation?(:scopes) }
validates :specific_requirements_document, presence: true, if: -> { specific_requirements? && need_complete_validation?(:scopes) }
end

private

def at_least_one_revenue_year_has_been_selected
return if scopes.intersect?(MANDATORY_REVENUE_YEARS)

errors.add(:scopes, :invalid, message: 'sont invalides : Vous devez cocher au moins une année de revenus souhaitée avant de continuer')
errors.add(:scopes, :at_least_one_revenue_year_has_been_selected)
end

def revenue_years_scopes_compatibility
return unless scopes.include?('dgfip_annee_n_moins_2_si_indispo_n_moins_1')
return unless scopes.intersect?(%w[dgfip_annee_n_moins_1 dgfip_annee_n_moins_2 dgfip_annee_n_moins_3])

errors.add(:scopes, :invalid, message: "sont invalides : Vous ne pouvez pas sélectionner la donnée 'avant dernière année de revenu, si la dernière année de revenu est indisponible' avec d'autres années de revenus")
errors.add(:scopes, :revenue_years_scopes_compatibility)
end

def scopes_compatibility
return unless scope_exists_in_each_arrays?(*INCOMPATIBLE_SCOPES)

errors.add(:scopes, :invalid, message: 'sont invalides : Des données incompatibles entre elles ont été cochées. Pour connaître les modalités d’appel et de réponse de l’API Impôt particulier ainsi que les données proposées, vous pouvez consulter le guide de présentation de cette API dans la rubrique « Les données nécessaires > Comment choisir les données »')
errors.add(:scopes, :scopes_compatibility)
end

def scope_exists_in_each_arrays?(array_1, array_2)
scopes.intersect?(array_1) && scopes.intersect?(array_2)
end

def specific_requirements_document_presence
return if specific_requirements_document.present?

errors.add(:specific_requirements_document, message: 'est manquant : vous devez ajoutez un fichier avant de passer à l’étape suivante')
end

def specific_requirements?
specific_requirements == '1'
end
Expand Down
6 changes: 6 additions & 0 deletions app/views/archive_authorization_requests/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
<p>
<%= t('.disclaimer').html_safe %>
</p>

<% if @authorization_request.next_stage_already_started? %>
<div class="fr-alert fr-alert--warning">
<%= t('.disclaimer_next_stage') %>
</div>
<% end %>
</div>

<div class="fr-modal__footer">
Expand Down
2 changes: 1 addition & 1 deletion app/views/authorization_requests/blocks/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<div class="fr-col-12">
<ul class="fr-btns-group fr-btns-group--inline fr-btns-group--icon-left fr-btns-group--between">
<li>
<%= link_to t('authorization_request_forms.form.back'), :back, class: %w(fr-btn fr-btn--secondary fr-icon-arrow-left-s-line-double fr-btn--icon-left fr-mb-0) %>
<%= link_to t('authorization_request_forms.form.back'), summary_authorization_request_form_path(form_uid: @authorization_request.form.uid, id: @authorization_request.id), class: %w(fr-btn fr-btn--secondary fr-icon-arrow-left-s-line-double fr-btn--icon-left fr-mb-0) %>
</li>
<li>
<%= f.button t('authorization_request_forms.form.save'), type: :submit, name: :save, id: :save_authorization_request, class: %w(fr-btn fr-btn--primary fr-icon-save-line fr-btn--icon-left fr-mb-0) %>
Expand Down
6 changes: 3 additions & 3 deletions app/views/dashboard/card/_stage_footer.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
<div class="footer__content">
<div class="fr-mb-3v">
<p class="footer__title fr-text-title--blue-france fr-text--md font-weight-700 fr-m-0">
<% if authorization_request.stage_already_started? %>
<% if authorization_request.next_stage_already_started? %>
<%= t('.next_stage_title_production') %>
<% else %>
<%= t('.next_stage_title') %>
<% end %>
</p>

<p class="fr-text--sm fr-mb-0">
<% if authorization_request.stage_already_started? %>
<% if authorization_request.next_stage_already_started? %>
<%= t('.next_stage_subtitle_production') %>
<% else %>
<%= t('.next_stage_subtitle') %>
Expand All @@ -20,7 +20,7 @@
</div>

<div class="footer__badge_action">
<% if authorization_request.stage_already_started? %>
<% if authorization_request.next_stage_already_started? %>
<div class="fr-mb-3v flex-wrap flew-grow fr-grid-row--top flex-end__content">
<%= authorization_request_stage_badge(authorization_request) %>
<span class="fr-ml-2v"><%= authorization_request_status_badge(authorization_request) %></span>
Expand Down
8 changes: 8 additions & 0 deletions config/locales/activerecord.fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ fr:
comparison: doit être supérieure à la date de début
france_connect_authorization_id:
inclusion: n'est pas incluse dans la liste des habilitations validées de votre organization
authorization_request/api_impot_particulier_sandbox: &api_impot_particulier_errors
attributes:
scopes:
scopes_compatibility: 'sont invalides : Des données incompatibles entre elles ont été cochées. Pour connaître les modalités d’appel et de réponse de l’API Impôt particulier ainsi que les données proposées, vous pouvez consulter la documentation dans la rubrique "mode de fonctionnement de l’API Impôt Particulier"'
revenue_years_scopes_compatibility: "sont invalides : Vous ne pouvez pas sélectionner la donnée 'avant dernière année de revenu, si la dernière année de revenu est indisponible' avec d'autres années de revenus"
at_least_one_revenue_year_has_been_selected: 'sont invalides : Vous devez cocher au moins une année de revenus souhaitée avant de continuer'
authorization_request/api_impot_particulier: *api_impot_particulier_errors

ransack:
attributes:
authorization_request:
Expand Down
12 changes: 2 additions & 10 deletions config/locales/authorization_request_forms.fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ fr:
volumetrie_appels_par_minute:
label: Quelle limitation de débit souhaitez- vous pour votre téléservice ?
volumetrie_justification:
label: Pour quels motifs souhaitez-vous un débit plus grand que le minimum ?
label: Pour quels motifs souhaitez-vous un débit plus grand que le minimum ? <span class="fr-ml-1w fr-text-error">*</span>
volumetrie_approximative:
hint: Nombre de démarches ou dossiers traités dans l'année

Expand Down Expand Up @@ -706,24 +706,16 @@ fr:
<a href="/cgus/dgfip/presentation_de_l_api_impot_particulier_v2.8.pdf", target="_blank">Voir la documentation de l’API Impôt particulier</a>
groups:
'Années sur lesquelles porte votre demande': |
Le calendrier de basculement des millésimes est détaillé dans la documentation accessible via la rubrique « Comment choisir les données ? ».
</br></br>
En cochant la case <strong>Avant-dernière année de revenu, si la dernière année de revenu est indisponible</strong>,
En cochant la case <strong>Avant-dernière année de revenu, si la dernière année de revenu est indisponible</strong>,
vous optez pour récupérer les informations de l’avant-dernière année, lorsque celles de la dernière année ne sont pas disponibles.
Cette option n’est pas possible si vous souhaitez des données fournies uniquement par la ressource facture /avis IR.
</br>
Pour plus de précisions, consulter la documentation présente dans la rubrique « Comment choisir les données ? »
'Situation du foyer fiscal': |
En cochant la case <strong>Données fiscales au 31/12 en cas de décès d'un contribuable marié ou pacsé</strong>,
vous optez pour récupérer les données fiscales de la période après décès d’un contribuable marié ou pacsé (à défaut aucune donnée fiscale n’est transmise).
Cette option n’est pas possible si vous souhaitez des données fournies uniquement par la ressource facture /avis IR.
</br>
Pour plus de précisions, consulter la documentation présente dans la rubrique « Comment choisir les données ? »
'Agrégats fiscaux': |
<strong>Montant de l’impôt sur les revenus soumis au barème</strong> :
Cette donnée n’intègre pas la taxation des revenus au taux effectif ou au taux proportionnel. Une expression de besoin spécifique est à réaliser si, après échanges avec DGFiP, ces types de taxation sont nécessaires.
</br>
Pour plus de précisions, consulter la documentation présente dans la rubrique « Comment choisir les données ? »

specific_requirements:
content: |
Expand Down
4 changes: 3 additions & 1 deletion config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ fr:
editor_with_sandbox:
title: Travaillez-vous avec un éditeur qui a déjà accès au bac à sable de cette API ?
subtitle: Si votre éditeur a déjà accès au bac à sable, vous serez redirigé directement vers une demande d'accès à l'environnement de production.
options:
options:
- label: Oui mon éditeur a déjà accès au bac à sable
value: true
- label: Non, nous n'avons pas encore accès au bac à sable
Expand Down Expand Up @@ -421,6 +421,8 @@ fr:
title: Suppression de la demande d'habilitation %{authorization_request_name}
disclaimer: |
<strong>Cette action est irréversible</strong>. Veuillez vérifier que nous ne supprimez pas une demande légitime.
disclaimer_next_stage:
Cette demande d'autorisation est associée à au moins une demande précédente déjà validée, archiver cette demande archivera aussi toutes les demandes associées validées.
cancel: Annuler
archive: Supprimer la demande d'habilitation
create:
Expand Down
6 changes: 6 additions & 0 deletions features/archiver_habilitation.feature
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,9 @@ Fonctionnalité: Supprimer une habilitation
Et il y a un message de succès contenant "a été supprimée"
Et un webhook avec l'évènement "archive" est envoyé

Scénario: Si je veux supprimer une de mes habilitations ayant une étape précédente, il y a un message d'alerte explicitant que cela archive l'entiéreté de la demande
Quand j'ai 1 demande d'habilitation "API Impôt Particulier" à l'étape "Production" en brouillon
Et que je me rends sur cette demande d'habilitation
Et que je clique sur "Supprimer"
Et debug
Alors il y a un message d'attention contenant "archiver cette demande archivera aussi toutes les demandes associées validées"
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Fonctionnalité: Soumission d'une demande d'habilitation API Impôts Particulier

* je renseigne le cadre légal
* je clique sur "Suivant"

* je choisis "Via le numéro fiscal (SPI)"
* je clique sur "Suivant"

Expand Down Expand Up @@ -47,7 +47,7 @@ Fonctionnalité: Soumission d'une demande d'habilitation API Impôts Particulier
* je clique sur "Suivant"

Alors la page contient "Une erreur est survenue lors de la sauvegarde de la demande d'habilitation"
Et la page contient "Les données sont invalides : Des données incompatibles entre elles ont été cochées. Pour connaître les modalités d’appel et de réponse de l’API Impôt particulier ainsi que les données proposées, vous pouvez consulter le guide de présentation de cette API dans la rubrique « Les données nécessaires > Comment choisir les données"
Et la page contient "Les données sont invalides : Des données incompatibles entre elles ont été cochées"

@javascript
Scénario: Je soumets une demande d'habilitation sans scopes mais je joins un fichier d'expression de besoin spécifique.
Expand All @@ -63,4 +63,4 @@ Fonctionnalité: Soumission d'une demande d'habilitation API Impôts Particulier
* je clique sur "Suivant"

Alors la page contient "Une erreur est survenue lors de la sauvegarde de la demande d'habilitation"
Et la page contient "Document de l'expression de besoin spécifique est manquant : vous devez ajoutez un fichier avant de passer à l’étape suivante"
Et la page contient "Document de l'expression de besoin spécifique doit être rempli(e)"
31 changes: 28 additions & 3 deletions spec/factories/authorization_requests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,17 @@
end
end

trait :has_previous_authorization_validated do
after(:create) do |authorization_request|
authorization_request.authorizations << Authorization.create!(
request: authorization_request,
applicant: authorization_request.applicant,
authorization_request_class: authorization_request.definition.stage.previous_stages[0][:definition].authorization_request_class,
data: authorization_request.data.presence || { 'what' => 'ever' },
)
end
end

trait :with_basic_infos do
after(:build) do |authorization_request, evaluator|
if authorization_request.need_complete_validation? || evaluator.fill_all_attributes
Expand Down Expand Up @@ -399,7 +410,7 @@
with_cadre_juridique
end

trait :api_impot_particulier do
trait :api_impot_particulier_common do
type { 'AuthorizationRequest::APIImpotParticulier' }

transient do
Expand All @@ -421,12 +432,20 @@
with_volumetrie
end

trait :api_impot_particulier do
api_impot_particulier_common

has_previous_authorization_validated
end

trait :api_impot_particulier_production do
api_impot_particulier
api_impot_particulier_common

has_previous_authorization_validated
end

trait :api_impot_particulier_production_avec_editeur do
api_impot_particulier
api_impot_particulier_common

form_uid { 'api-impot-particulier-production-avec-editeur' }
end
Expand Down Expand Up @@ -522,6 +541,8 @@

form_uid { 'api-hermes-production' }

has_previous_authorization_validated

with_basic_infos
with_personal_data
with_cadre_juridique
Expand All @@ -545,6 +566,8 @@

form_uid { 'api-e-contacts-production' }

has_previous_authorization_validated

with_basic_infos
with_personal_data
with_cadre_juridique
Expand All @@ -568,6 +591,8 @@

form_uid { 'api-opale-production' }

has_previous_authorization_validated

with_basic_infos
with_personal_data
with_cadre_juridique
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@

it 'does render an error message for specific requirements' do
authorization_request.valid?
expect(authorization_request.errors[:specific_requirements_document]).to include('est manquant : vous devez ajoutez un fichier avant de passer à l’étape suivante')
expect(authorization_request.errors[:specific_requirements_document]).to include('doit être rempli(e)')
end
end

Expand Down Expand Up @@ -294,7 +294,7 @@

it 'does render an error message for specific requirements' do
authorization_request.valid?
expect(authorization_request.errors[:specific_requirements_document]).to include('est manquant : vous devez ajoutez un fichier avant de passer à l’étape suivante')
expect(authorization_request.errors[:specific_requirements_document]).to include('doit être rempli(e)')
end
end
end
Expand Down
8 changes: 8 additions & 0 deletions spec/models/authorization_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@
expect(authorization_request).to be_validated
expect(authorization_request.latest_authorization).to be_a(Authorization)
end

describe 'with an authorization definition which has a previous stage, in whatever stage' do
it 'creates an authorization to one of the previous stage' do
authorization_request = create(:authorization_request, :api_impot_particulier_production, :draft)

expect(authorization_request.latest_authorization.authorization_request_class).to eq('AuthorizationRequest::APIImpotParticulierSandbox')
end
end
end

describe '#access_link' do
Expand Down
Loading