diff --git a/app/controllers/api/v1/market_applications_controller.rb b/app/controllers/api/v1/market_applications_controller.rb index 5f2369adc..9bfa5f285 100644 --- a/app/controllers/api/v1/market_applications_controller.rb +++ b/app/controllers/api/v1/market_applications_controller.rb @@ -75,11 +75,8 @@ def success_response(market_application) end def application_url_for(market_application) - if market_application.application_mode_choice_required? - return Rails.application.routes.url_helpers.application_mode_candidate_market_application_url( - market_application.identifier - ) - end + target, step = market_application.next_required_wizard_step + return wizard_step_url(target, step) if target Rails.application.routes.url_helpers.step_candidate_market_application_url( market_application.identifier, @@ -87,6 +84,15 @@ def application_url_for(market_application) ) end + def wizard_step_url(market_application, step) + case step + when :application_mode + Rails.application.routes.url_helpers.application_mode_candidate_market_application_url(market_application.identifier) + when :grouping_legal_type + Rails.application.routes.url_helpers.grouping_legal_type_candidate_market_application_url(market_application.identifier) + end + end + def validate_application_completed return if @market_application.completed? diff --git a/app/controllers/candidate/application_modes_controller.rb b/app/controllers/candidate/application_modes_controller.rb index f5322d010..d7858a7ed 100644 --- a/app/controllers/candidate/application_modes_controller.rb +++ b/app/controllers/candidate/application_modes_controller.rb @@ -4,14 +4,15 @@ module Candidate class ApplicationModesController < Candidate::ApplicationController include Candidate::GroupementFeatureGuard include Candidate::MarketApplicationGuard + include Candidate::WizardRoutable prepend_before_action :find_market_application before_action :redirect_if_mode_already_chosen def show - @already_mandataire = already_mandataire_elsewhere? - @readonly = @market_application.application_mode.present? - @readonly_continue_path = next_step_path(@market_application) if @readonly + @already_mandataire = presenter.already_mandataire? + @readonly = presenter.readonly? + @readonly_continue_path = next_required_wizard_step_path(@market_application) if @readonly end def update @@ -22,7 +23,7 @@ def update return handle_success(result) if result.success? - @already_mandataire = already_mandataire_elsewhere? + @already_mandataire = presenter.already_mandataire? @errors = result.errors render :show, status: :unprocessable_content end @@ -39,27 +40,15 @@ def redirect_if_mode_already_chosen return if @market_application.application_mode.nil? return if action_name == 'show' && params[:readonly].present? - redirect_to next_step_path(@market_application) + redirect_to next_required_wizard_step_path(@market_application) end - def next_step_path(market_application) - if market_application.grouping_legal_type_choice_required? - grouping_legal_type_candidate_market_application_path(market_application.identifier) - else - company_identification_candidate_market_application_path(market_application.identifier) - end - end - - def already_mandataire_elsewhere? - Grouping - .joins(:mandataire_market_application) - .where(public_market: @market_application.public_market, market_applications: { siret: @market_application.siret }) - .where.not(market_applications: { id: @market_application.id }) - .exists? + def presenter + @presenter ||= Candidate::ApplicationModePresenter.new(@market_application) end def handle_success(result) - redirect_to next_step_path(result.market_application) + redirect_to next_required_wizard_step_path(result.market_application) end end end diff --git a/app/controllers/candidate/grouping_legal_types_controller.rb b/app/controllers/candidate/grouping_legal_types_controller.rb index 03da97a33..7e4bccc24 100644 --- a/app/controllers/candidate/grouping_legal_types_controller.rb +++ b/app/controllers/candidate/grouping_legal_types_controller.rb @@ -8,7 +8,9 @@ class GroupingLegalTypesController < Candidate::ApplicationController prepend_before_action :find_market_application before_action :redirect_unless_mandataire - def show; end + def show + @grouping = presenter.grouping + end def update result = Candidate::SetGroupingLegalType.call( @@ -18,6 +20,7 @@ def update return handle_success if result.success? + @grouping = presenter.grouping @errors = result.errors render :show, status: :unprocessable_content end @@ -31,12 +34,15 @@ def find_market_application end def redirect_unless_mandataire - @grouping = Grouping.joins(:mandataire_market_application).find_by(market_applications: { id: @market_application.id }) - return if @grouping + return if presenter.grouping redirect_to application_mode_candidate_market_application_path(@market_application.identifier) end + def presenter + @presenter ||= Candidate::GroupingLegalTypePresenter.new(@market_application) + end + def handle_success redirect_to company_identification_candidate_market_application_path(@market_application.identifier) end diff --git a/app/controllers/candidate/sessions_controller.rb b/app/controllers/candidate/sessions_controller.rb index cd84b3b17..c93c25713 100644 --- a/app/controllers/candidate/sessions_controller.rb +++ b/app/controllers/candidate/sessions_controller.rb @@ -2,6 +2,8 @@ module Candidate class SessionsController < Candidate::ApplicationController + include Candidate::WizardRoutable + skip_before_action :require_candidate_authentication def new @@ -38,23 +40,28 @@ def destroy def sign_in_candidate(user, market_application) reconnection = market_application.user_id.present? - market_application.update!(user:) unless reconnection + link_candidate_to_application(user, market_application) unless reconnection session[:user_id] = user.id session[:market_application_identifier] = market_application.identifier redirect_to first_step_path(market_application) end + def link_candidate_to_application(user, market_application) + counterpart = market_application.groupement_counterpart || market_application.solo_counterpart + market_application.update!(user:) + counterpart&.update!(user:) + end + def first_step_path(market_application) - if market_application.completed? - return deadline_passed_candidate_market_application_path(market_application.identifier) unless market_application.public_market.open? + return completed_application_path(market_application) if market_application.completed? - return candidate_sync_status_path(market_application.identifier) - end + next_required_wizard_step_path(market_application) + end - return application_mode_candidate_market_application_path(market_application.identifier) if market_application.application_mode_choice_required? - return grouping_legal_type_candidate_market_application_path(market_application.identifier) if market_application.grouping_legal_type_choice_required? + def completed_application_path(market_application) + return deadline_passed_candidate_market_application_path(market_application.identifier) unless market_application.public_market.open? - company_identification_candidate_market_application_path(market_application.identifier) + candidate_sync_status_path(market_application.identifier) end def handle_magic_link_sent(result) diff --git a/app/controllers/concerns/candidate/application_mode_guard.rb b/app/controllers/concerns/candidate/application_mode_guard.rb index 848431f76..d48198590 100644 --- a/app/controllers/concerns/candidate/application_mode_guard.rb +++ b/app/controllers/concerns/candidate/application_mode_guard.rb @@ -3,6 +3,7 @@ module Candidate module ApplicationModeGuard extend ActiveSupport::Concern + include Candidate::WizardRoutable included do before_action :redirect_to_application_mode_choice @@ -11,9 +12,9 @@ module ApplicationModeGuard private def redirect_to_application_mode_choice - return unless @market_application&.application_mode_choice_required? + return unless @market_application - redirect_to application_mode_candidate_market_application_path(@market_application.identifier) + redirect_to next_required_wizard_step_path(@market_application) if @market_application.next_required_wizard_step end end end diff --git a/app/controllers/concerns/candidate/wizard_routable.rb b/app/controllers/concerns/candidate/wizard_routable.rb new file mode 100644 index 000000000..d1e750e7a --- /dev/null +++ b/app/controllers/concerns/candidate/wizard_routable.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Candidate + module WizardRoutable + extend ActiveSupport::Concern + + private + + def wizard_step_path(market_application, step) + case step + when :application_mode + application_mode_candidate_market_application_path(market_application.identifier) + when :grouping_legal_type + grouping_legal_type_candidate_market_application_path(market_application.identifier) + end + end + + def next_required_wizard_step_path(market_application) + target, step = market_application.next_required_wizard_step + return company_identification_candidate_market_application_path(market_application.identifier) unless target + + wizard_step_path(target, step) + end + end +end diff --git a/app/models/market_application.rb b/app/models/market_application.rb index 36ee72eaf..6e29312d2 100644 --- a/app/models/market_application.rb +++ b/app/models/market_application.rb @@ -53,10 +53,34 @@ def application_mode_choice_required? end def grouping_legal_type_choice_required? + return false if completed? + FeatureFlags::Groupement.enabled? && groupement? && Grouping.joins(:mandataire_market_application).exists?(legal_type: nil, market_applications: { id: }) end + def groupement_counterpart + return nil if groupement? + + MarketApplication.where(public_market:, siret:, application_mode: :groupement, user_id:).where.not(id:).first + end + + def solo_counterpart + return nil if solo? + + MarketApplication.where(public_market:, siret:, application_mode: :solo, user_id:).where.not(id:).first + end + + def next_required_wizard_step + return nil unless FeatureFlags::Groupement.enabled? + return [self, :application_mode] if application_mode_choice_required? + + target = groupement_counterpart || self + return [target, :grouping_legal_type] if target.grouping_legal_type_choice_required? + + nil + end + def update_api_status(api_name, status:, fields_filled: 0) with_lock do updated_status = (api_fetch_status || {}).dup diff --git a/app/presenters/candidate/application_mode_presenter.rb b/app/presenters/candidate/application_mode_presenter.rb new file mode 100644 index 000000000..6812621f4 --- /dev/null +++ b/app/presenters/candidate/application_mode_presenter.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Candidate + class ApplicationModePresenter + def initialize(market_application) + @market_application = market_application + end + + def already_mandataire? + Grouping + .joins(:mandataire_market_application) + .where(public_market: market_application.public_market, market_applications: { siret: market_application.siret }) + .where.not(market_applications: { id: market_application.id }) + .exists? + end + + def readonly? + market_application.application_mode.present? + end + + private + + attr_reader :market_application + end +end diff --git a/app/presenters/candidate/grouping_legal_type_presenter.rb b/app/presenters/candidate/grouping_legal_type_presenter.rb new file mode 100644 index 000000000..549239d21 --- /dev/null +++ b/app/presenters/candidate/grouping_legal_type_presenter.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Candidate + class GroupingLegalTypePresenter + def initialize(market_application) + @market_application = market_application + end + + def grouping + return @grouping if defined?(@grouping) + + @grouping = Grouping.joins(:mandataire_market_application) + .find_by(market_applications: { id: market_application.id }) + end + + private + + attr_reader :market_application + end +end diff --git a/app/views/candidate/grouping_legal_types/show.html.erb b/app/views/candidate/grouping_legal_types/show.html.erb index 632a4385d..429402a60 100644 --- a/app/views/candidate/grouping_legal_types/show.html.erb +++ b/app/views/candidate/grouping_legal_types/show.html.erb @@ -2,7 +2,7 @@

<%= t('candidate.grouping_legal_types.step_current') %>

-

<%= t('candidate.grouping_legal_types.title') %>

+

<%= t('candidate.grouping_legal_types.title') %>