Skip to content

Commit

Permalink
Fix relation rib-etab (#1113)
Browse files Browse the repository at this point in the history
- [x] Remove support banner
- [x] Change db constraint to have multiple active ribs (1 per etab)
- [x] Rewrite validator_spec using stubbing to avoid the factory
shenanigans
- [x] Make etab presence mandatory on Rib
- [x] Make sure another etab cant modify or archive other etab's ribs
- [x] Make display of classes rib dependent on current establishment
- [x] Make student show of rib dependent on current establishment
- [x] Fix tests
- [x] Fix mandate rib option display
  • Loading branch information
pskl authored Oct 3, 2024
1 parent 44142a4 commit 7ebeb55
Show file tree
Hide file tree
Showing 54 changed files with 377 additions and 281 deletions.
4 changes: 3 additions & 1 deletion app/apis/students_api/sygne/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ module Sygne
class Api < StudentsApi::Base
class << self
def establishment_students_endpoint(params)
base_url + format("etablissements/%s/eleves?statut=ST&etat-scolarisation=true", params[:uai])
base_url +
format("etablissements/%s/eleves?statut=ST&annee-scolaire=#{SchoolYear.current.start_year}&etat-scolarisation=true", # rubocop:disable Layout/LineLength
params[:uai])
end

def student_endpoint(params)
Expand Down
17 changes: 1 addition & 16 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ class ApplicationController < ActionController::Base
:log_user,
:redirect_asp_users!,
:check_maintenance,
:check_current_establishment,
:set_support_banner
:check_current_establishment

helper_method :current_establishment, :selected_school_year

Expand All @@ -27,10 +26,6 @@ def after_sign_out_path_for(resource_or_scope)
end
end

def set_support_banner
@show_support_banner = eligible_for_support?(current_establishment)
end

def check_maintenance
return if request.path == maintenance_path # or endless redirect

Expand Down Expand Up @@ -82,16 +77,6 @@ def redirect_asp_users!

private

def eligible_for_support?(establishment)
return false if establishment.nil?

supported_uais = ENV
.fetch("APLYPRO_DIRECT_SUPPORT_UAIS", "")
.split(",")

supported_uais.include?(establishment.uai)
end

def check_current_establishment
return unless user_signed_in?

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/ribs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def missing
def bulk_create
@ribs = bulk_ribs_params.map do |rib_params|
Student.find(rib_params["student_id"]).create_new_rib(
rib_params.except("student_id")
rib_params.except("student_id").merge("establishment_id" => current_establishment.id)
)
end
if @ribs.each(&:save).all?(&:valid?)
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/validations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def show
@pfmps = current_establishment.validatable_pfmps
.includes(schooling: :attributive_decision_attachment)
.where(schoolings: { classe: @classe })
.includes(student: :rib)
.includes(student: :ribs)
.order(:"students.last_name", :"pfmps.start_date")

@total_amount = @pfmps.sum(:amount)
Expand Down
2 changes: 1 addition & 1 deletion app/facades/classe_facade.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def nb_missing_ribs

def schoolings
@classe.schoolings
.includes(:attributive_decision_attachment, pfmps: :transitions, student: :rib)
.includes(:attributive_decision_attachment, pfmps: :transitions, student: :ribs)
.order("students.last_name", "students.first_name")
end

Expand Down
6 changes: 4 additions & 2 deletions app/facades/classes_facade.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ def nb_attributive_decisions_per_class

def nb_ribs_per_class
@nb_ribs_per_class ||= @classes
.joins(students: :rib)
.joins(students: :ribs)
.where(ribs: { archived_at: nil })
.reorder(nil)
.group(:"classes.id")
.count
.distinct
.count(:"students.id")
end

def nb_pfmps(class_id, state)
Expand Down
6 changes: 5 additions & 1 deletion app/facades/establishment_facade.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ def students_count
end

def ribs_count
@ribs_count ||= selected_classes.joins(students: :rib).distinct(:"students.id").count(:"ribs.id")
@ribs_count ||= selected_classes
.joins(students: :ribs)
.where(ribs: { archived_at: nil })
.distinct(:"students.id")
.count(:"students.id")
end

def pfmps_counts
Expand Down
5 changes: 4 additions & 1 deletion app/helpers/classes_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

module ClassesHelper
def ribs_progress_badge(schoolings)
count = schoolings.joins(student: :rib).count
count = schoolings.joins(student: :ribs)
.where(ribs: { archived_at: nil })
.distinct(:"students.id")
.count(:"students.id")
total = schoolings.size

progress_badge(count, total)
Expand Down
7 changes: 0 additions & 7 deletions app/javascript/controllers/hello_controller.js

This file was deleted.

4 changes: 3 additions & 1 deletion app/models/asp/payment_request_state_machine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ class PaymentRequestStateMachine
end

after_transition(from: :pending, to: :ready) do |payment_request, _|
payment_request.update!(rib: payment_request.pfmp.student.rib)
payment_request.update!(
rib: payment_request.pfmp.student.rib(payment_request.pfmp.classe.establishment)
)
end

guard_transition(to: :ready) do |payment_request|
Expand Down
7 changes: 3 additions & 4 deletions app/models/asp/payment_request_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def check_student
end

def check_rib
add_error(:missing_rib) and return if rib.blank?
add_error(:missing_rib) and return if rib.nil?

add_error(:rib) if rib.invalid?

Expand All @@ -41,8 +41,7 @@ def check_rib

def check_pfmp
add_error(:pfmp) unless pfmp.valid?

add_error(:pfmp_amount) unless pfmp.amount.positive?
add_error(:pfmp_amount) if pfmp.amount.nil? || pfmp.amount <= 0
end

def check_schooling
Expand Down Expand Up @@ -96,7 +95,7 @@ def student
end

def rib
@rib ||= student.rib
@rib ||= payment_request.rib || student.rib
end

def pfmp
Expand Down
7 changes: 6 additions & 1 deletion app/models/establishment.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# frozen_string_literal: true

class Establishment < ApplicationRecord # rubocop:disable Metrics/ClassLength
validates :uai, presence: true, uniqueness: true
validates :uai, presence: true, uniqueness: true, format: { with: -> { uai_regex } }

has_many :invitations, dependent: :nullify
has_many :ribs, dependent: :nullify

has_many :establishment_user_roles, dependent: :destroy

Expand Down Expand Up @@ -155,4 +156,8 @@ def ensure_confirmed_director_is_director

errors.add :confirmed_director, "is not a director"
end

def self.uai_regex
Rails.env.production? ? /\A\d{7}[A-Z]\z/m : /\A*.\z/m
end
end
2 changes: 1 addition & 1 deletion app/models/pfmp_state_machine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class PfmpStateMachine

guard_transition(to: :validated) do |pfmp|
pfmp.previous_pfmps.not_in_state(:validated).empty? &&
pfmp.student.rib.present? &&
pfmp.student.rib(pfmp.classe.establishment).present? &&
pfmp.schooling.attributive_decision.attached?
end

Expand Down
4 changes: 3 additions & 1 deletion app/models/rib.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
class Rib < ApplicationRecord
belongs_to :student

belongs_to :establishment, optional: true
belongs_to :establishment

enum :owner_type, { personal: 0, other_person: 1, moral_person: 2, mandate: 3 }

Expand Down Expand Up @@ -51,6 +51,8 @@ def archivable?
payment_requests.empty? || payment_requests.all?(&:terminated?)
end

# NOTE: this is used by the framework itself
# https://devdocs.io/rails~7.1/activerecord/core#method-i-readonly-3F
def readonly?
!archivable?
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/stats/indicator/ribs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Indicator
class Ribs < Ratio
def initialize
super(
subset: Student.joins(:rib),
subset: Student.with_rib,
all: Student.all
)
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/stats/indicator/sendable_amounts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class SendableAmounts < Sum
def initialize
super(
column: :amount,
all: Pfmp.joins(schooling: { student: :rib })
all: Pfmp.joins(schooling: { student: :ribs })
.merge(Pfmp.finished)
.merge(Pfmp.in_state(:validated))
.merge(Schooling.with_attributive_decisions)
Expand Down
12 changes: 7 additions & 5 deletions app/models/student.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ class Student < ApplicationRecord # rubocop:disable Metrics/ClassLength

has_many :ribs, dependent: :destroy

has_one :rib, -> { where(archived_at: nil) }, dependent: :destroy, inverse_of: :student

scope :without_ribs, -> { where.missing(:rib) }

scope :lives_in_france, -> { where(address_country_code: %w[100 99100]) }
scope :lives_abroad, -> { where.not(id: lives_in_france) }

Expand All @@ -38,7 +34,9 @@ class Student < ApplicationRecord # rubocop:disable Metrics/ClassLength

scope :with_biological_sex, -> { where(biological_sex: %i[male female]) }
scope :with_known_postal_code, -> { where.not(address_postal_code: nil) }
scope :with_rib, -> { joins(:rib) }

scope :without_ribs, -> { where.missing(:ribs) }
scope :with_rib, -> { joins(:ribs).distinct }

scope :with_known_birthplace, -> { where.not(birthplace_country_insee_code: nil) }
scope :with_valid_birthplace, lambda {
Expand Down Expand Up @@ -74,6 +72,10 @@ class Student < ApplicationRecord # rubocop:disable Metrics/ClassLength
:birthplace_country_insee_code,
:biological_sex

def rib(etab = establishment)
ribs.find_by(establishment: etab, archived_at: nil)
end

# NOTE: used in stats for column "Données d'élèves nécessaires présentes"
def self.asp_ready
with_ine
Expand Down
2 changes: 1 addition & 1 deletion app/services/asp/mappers/coord_paie_mapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class CoordPaieMapper
attr_reader :rib, :iban

def initialize(payment_request)
@rib = payment_request.student.rib
@rib = payment_request.rib || payment_request.student.rib
@iban = Bank::IBAN.new(rib.iban)
end

Expand Down
4 changes: 2 additions & 2 deletions app/views/classes/_students_table.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
- else
= dsfr_badge(status: :error) { "Manquante" }
%td
- if student.rib.present?
- if student.rib(current_establishment).present?
%p= dsfr_badge(status: :success) { "Saisies" }
= dsfr_link_to "Modifier les coordonnées bancaires", edit_student_rib_path(student, student.rib)
= dsfr_link_to "Modifier les coordonnées bancaires", edit_student_rib_path(student, student.rib(current_establishment))
- else
%p= dsfr_badge(status: :error) { "Non saisies" }
= dsfr_link_to "Saisir les coordonnées bancaires", new_student_rib_path(student)
Expand Down
1 change: 0 additions & 1 deletion app/views/layouts/application.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
%body
= render 'shared/skiplinks'
= render 'shared/analytics' if Rails.env.production?
= render 'shared/support_banner' if @show_support_banner
= render 'shared/header'
- unless @inhibit_nav
- if current_establishment
Expand Down
2 changes: 1 addition & 1 deletion app/views/ribs/_owner_type.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@
.fr-radio-group
%input{id: "radio-inline-4-#{student_id}", type: "radio", value: "mandate", name: field_name, checked: current_value == "mandate"}
%label.fr-label{for: "radio-inline-4-#{student_id}"}
= t("activerecord.attributes.rib.owner_type_mandate")
= t("activerecord.attributes.missing.owner_type_mandate")
.fr-messages-group{id: "radio-inline-messages-#{student_id}", "aria-live": "assertive"}
9 changes: 0 additions & 9 deletions app/views/shared/_support_banner.html.haml

This file was deleted.

15 changes: 7 additions & 8 deletions app/views/students/show.html.haml
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
%section.fr-pb-3w
%h2.fr-h4 Coordonnées bancaires

- if @student.rib.nil?
- if @student.rib(current_establishment).nil?
%p Aucune coordonnée bancaire enregistrée pour le moment.

= button_to "Saisir les coordonnées bancaires", new_student_rib_path(@student), class: 'fr-btn', disabled: [email protected]_classes_in_establishment?(current_establishment), method: :get
- else
%ul
%li
Titulaire du compte :
%span= @student.rib.name
%span= @student.rib(current_establishment).name
%li
IBAN :
%code= @student.rib.iban
%code= @student.rib(current_establishment).iban
%li
BIC :
%code= @student.rib.bic
%code= @student.rib(current_establishment).bic

.fr-col-md-7
- if @student.rib.readonly?
- if @student.rib(current_establishment).readonly?
= dsfr_alert(type: :warning, size: :sm, classes: 'fr-my-3w') do
%p Ces coordonnées bancaires ne sont pas modifiables car elles sont actuellement utilisées dans une ou plusieurs requêtes de paiement.

.fr-btns-group.fr-btns-group--inline
%li= button_to "Modifier les coordonnées bancaires", edit_student_rib_path(@student, @student.rib), class: 'fr-btn fr-btn--secondary', disabled: @student.rib.readonly?, method: :get
%li= button_to "Supprimer les coordonnées bancaires", confirm_deletion_student_rib_path(@student, @student.rib), class: 'fr-btn fr-btn--secondary', disabled: @student.rib.readonly?, method: :get
%li= button_to "Modifier les coordonnées bancaires", edit_student_rib_path(@student, @student.rib(current_establishment)), class: 'fr-btn fr-btn--secondary', disabled: @student.rib(current_establishment).readonly?, method: :get
%li= button_to "Supprimer les coordonnées bancaires", confirm_deletion_student_rib_path(@student, @student.rib(current_establishment)), class: 'fr-btn fr-btn--secondary', disabled: @student.rib(current_establishment).readonly?, method: :get

= render partial: 'pfmps/pfmp_student_table', locals: { schoolings: @schoolings }
2 changes: 1 addition & 1 deletion config/initializers/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Aplypro
VERSION = "1.18.3"
VERSION = "1.19.0"
end
3 changes: 2 additions & 1 deletion config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,13 @@ fr:
owner_type_personal: "Les coordonnées bancaires appartiennent à l'élève"
owner_type_other_person: "Les coordonnées bancaires appartiennent à un représentant légal ou à un tiers"
owner_type_moral_person: "Les coordonnées bancaires appartiennent à une personne morale (ex : association)"
owner_type_mandate: "Cas d'un élève majeur payé sur le compte d'un tiers (Je confirme, qu’en tant que chef.fe d’établissement responsable de la collecte et de la vérification des pièces justificatives relatives à l’identité de l’élève bénéficiaire, avoir pris connaissance des conditions associées à la prise en compte du mandat sous seing privé par l’Agence de services et de paiement.)"
owner_type_mandate: "Les coordonnées bancaires appartiennent à un élève majeur payé sur le compte d'un tiers"
missing :
owner_type: "Les coordonnées bancaires appartiennent à :"
owner_type_personal: "L'élève"
owner_type_other_person: "Un représentant légal ou à un tiers"
owner_type_moral_person: "Une personne morale"
owner_type_mandate: "Un élève majeur payé sur le compte d'un tiers"
establishment:
uai: "UAI"
name: "Nom"
Expand Down
10 changes: 10 additions & 0 deletions db/migrate/20240925092548_update_rib_unique_index.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class UpdateRibUniqueIndex < ActiveRecord::Migration[7.2]
def change
remove_index :ribs, name: "one_active_rib_per_student"

add_index :ribs, [:student_id, :establishment_id],
name: "one_active_rib_per_student_per_establishment",
unique: true,
where: "archived_at IS NULL"
end
end
4 changes: 2 additions & 2 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 7ebeb55

Please sign in to comment.