diff --git a/README.md b/README.md index c418d52463..7256c8b622 100644 --- a/README.md +++ b/README.md @@ -292,21 +292,6 @@ PaperTrail.request(controller_info: {reason: "some reason"}) do # do something end ``` - -## Runbook - -### Updating NPQ applications from manual validation - -This procedure is used after a batch from manual validation has been complete. The data also needs to be uploaded to the NPQ application as it uses a different database and there is no syncing procedure in place. - -1. Log in to a container instance -2. Save CSV data to disk via `vi` and remember the path -3. Start rails console -4. Instantiate service with `svc = Importers::NPQManualValidation.new(path_to_csv: Rails.root.join("batchX.csv"))` -5. Call service with `svc.call` -6. Exit rails console -7. Delete CSV as no longer needed - ## Monitoring, logging, and alerting ### Sentry We use [sentry.io](https://sentry.io/) for error tracking and performance monitoring. Ask a team member for access - this is done through digi-tools. diff --git a/app/components/admin/participants/npq_validation_status_tag.rb b/app/components/admin/participants/npq_validation_status_tag.rb deleted file mode 100644 index 4ff8ce2978..0000000000 --- a/app/components/admin/participants/npq_validation_status_tag.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -module Admin - module Participants - class NPQValidationStatusTag < BaseComponent - def initialize(profile:) - @profile = profile - end - - def call - govuk_tag(**tag_attributes) - end - - private - - attr_reader :profile - - def tag_attributes - return { text: "Not ready", colour: "grey" } unless profile.npq? - return { text: "Complete", colour: "green" } if profile.approved? - return { text: "Rejected", colour: "red" } if profile.rejected? - - { text: "Pending", colour: "yellow" } - end - end - end -end diff --git a/app/components/status_tags/admin_participant_status_tag.html.erb b/app/components/status_tags/admin_participant_status_tag.html.erb index f00564c6f1..003de9c8eb 100644 --- a/app/components/status_tags/admin_participant_status_tag.html.erb +++ b/app/components/status_tags/admin_participant_status_tag.html.erb @@ -1,5 +1 @@ -<% if participant_profile.npq? %> - <%= render Admin::Participants::NPQValidationStatusTag.new(profile: participant_profile) %> -<% else %> - <%= govuk_tag(text: label, colour:) %> -<% end %> +<%= govuk_tag(text: label, colour:) %> diff --git a/app/controllers/api/api_controller.rb b/app/controllers/api/api_controller.rb index 0e227e63a6..68b9993071 100644 --- a/app/controllers/api/api_controller.rb +++ b/app/controllers/api/api_controller.rb @@ -19,7 +19,6 @@ class ApiController < ActionController::API rescue_from Api::Errors::InvalidParticipantOutcomeError, with: :invalid_transition rescue_from Api::Errors::InvalidDatetimeError, with: :invalid_updated_since_response rescue_from Api::Errors::InvalidTrainingStatusError, with: :invalid_training_status_response - rescue_from Api::Errors::MissingNPQContractOrStatementError, with: :missing_npq_contract_or_statement_response rescue_from Pagy::VariableError, with: :invalid_pagination_response def append_info_to_payload(payload) @@ -70,9 +69,5 @@ def invalid_training_status_response(exception) def invalid_pagination_response(_exception) render json: { errors: Api::ParamErrorFactory.new(error: I18n.t(:bad_request), params: I18n.t(:invalid_page_parameters)).call }, status: :bad_request end - - def missing_npq_contract_or_statement_response(_exception) - render json: { errors: Api::ParamErrorFactory.new(error: I18n.t(:unprocessable_request), params: I18n.t(:missing_npq_contract_or_statement)).call }, status: :unprocessable_entity - end end end diff --git a/app/controllers/api/errors/missing_npq_contract_or_statement_error.rb b/app/controllers/api/errors/missing_npq_contract_or_statement_error.rb deleted file mode 100644 index c8849b7900..0000000000 --- a/app/controllers/api/errors/missing_npq_contract_or_statement_error.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -module Api - module Errors - class MissingNPQContractOrStatementError < StandardError; end - end -end diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 39361df504..b7aa073957 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -13,10 +13,6 @@ def all_emails_associated_with_a_user(user) ParticipantIdentity.where(user:).pluck(:email) end - def on_admin_npq_application_page? - request.path.starts_with?("/admin/npq/applications") - end - def html_list(values, bullets: false) return nil if values.empty? diff --git a/app/models/cohort.rb b/app/models/cohort.rb index 69c153650b..3529960f8b 100644 --- a/app/models/cohort.rb +++ b/app/models/cohort.rb @@ -7,7 +7,6 @@ class Cohort < ApplicationRecord INITIAL_COHORT_START_DATE = Date.new(2021, 9, 1) has_many :call_off_contracts - has_many :npq_contracts has_many :partnerships has_many :schedules, class_name: "Finance::Schedule::ECF" has_many :statements, class_name: "Finance::Statement" diff --git a/app/models/cpd_lead_provider.rb b/app/models/cpd_lead_provider.rb index e2f0e964bb..236904053c 100644 --- a/app/models/cpd_lead_provider.rb +++ b/app/models/cpd_lead_provider.rb @@ -4,7 +4,6 @@ class CpdLeadProvider < ApplicationRecord has_paper_trail has_one :lead_provider - has_one :npq_lead_provider has_many :participant_declarations has_many :statements, class_name: "Finance::Statement" has_many :ecf_statements, class_name: "Finance::Statement::ECF" diff --git a/app/models/finance/statement/npq.rb b/app/models/finance/statement/npq.rb index 98d04ac923..4178baeceb 100644 --- a/app/models/finance/statement/npq.rb +++ b/app/models/finance/statement/npq.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true class Finance::Statement::NPQ < Finance::Statement - has_one :npq_lead_provider, through: :cpd_lead_provider - STATEMENT_TYPE = "npq" def payable! diff --git a/app/models/npq_application.rb b/app/models/npq_application.rb deleted file mode 100644 index 3c60e4028a..0000000000 --- a/app/models/npq_application.rb +++ /dev/null @@ -1,150 +0,0 @@ -# frozen_string_literal: true - -class NPQApplication < ApplicationRecord - VALID_FUNDING_ELIGIBILITY_STATUS_CODES = %w[ - funded - no_institution - ineligible_establishment_type - ineligible_institution_type - previously_funded - not_new_headteacher_requesting_ehco - school_outside_catchment - early_years_outside_catchment - not_on_early_years_register - early_years_invalid_npq - marked_funded_by_policy - marked_ineligible_by_policy - ].freeze - - has_paper_trail only: %i[eligible_for_funding funded_place funding_eligiblity_status_code user_id npq_lead_provider_id npq_course_id created_at updated_at lead_provider_approval_status] - - self.ignored_columns = %w[user_id] - - has_one :school, class_name: "School", foreign_key: :urn, primary_key: :school_urn - has_one :profile, class_name: "ParticipantProfile::NPQ", foreign_key: :id, touch: true - belongs_to :participant_identity - belongs_to :npq_lead_provider - belongs_to :npq_course - belongs_to :cohort, optional: true - belongs_to :eligible_for_funding_updated_by, class_name: "User", optional: true - - UK_CATCHMENT_AREA = %w[jersey_guernsey_isle_of_man england northern_ireland scotland wales].freeze - - enum headteacher_status: { - no: "no", - yes_when_course_starts: "yes_when_course_starts", - yes_in_first_two_years: "yes_in_first_two_years", - yes_over_two_years: "yes_over_two_years", - yes_in_first_five_years: "yes_in_first_five_years", - yes_over_five_years: "yes_over_five_years", - } - - enum funding_choice: { - school: "school", - trust: "trust", - self: "self", - another: "another", - employer: "employer", - } - - enum lead_provider_approval_status: { - pending: "pending", - accepted: "accepted", - rejected: "rejected", - } - - scope :with_targeted_delivery_funding_eligibility, -> { where(targeted_delivery_funding_eligibility: true) } - scope :does_not_work_in_school, -> { where(works_in_school: false) } - scope :does_not_work_in_childcare, -> { where(works_in_childcare: false) } - scope :not_eligible_for_funding, -> { where(eligible_for_funding: false) } - scope :edge_case_statuses, lambda { - where(funding_eligiblity_status_code: %w[re_register - no_institution - referred_by_return_to_teaching_adviser - awaiting_more_information - marked_ineligible_by_policy - marked_funded_by_policy]) - } - scope :created_at_range, ->(start_date, end_date) { where(created_at: start_date..end_date) } - scope :referred_by_return_to_teaching_advisor, -> { where(referred_by_return_to_teaching_adviser: "yes") } - - validates :eligible_for_funding_before_type_cast, inclusion: { in: [true, false, "true", "false"] } - - delegate :start_year, to: :cohort, prefix: true, allow_nil: true - - delegate :user, to: :participant_identity - delegate :id, :full_name, :email, to: :user, prefix: true - - delegate :id, :name, to: :npq_course, prefix: true - delegate :id, :name, to: :npq_lead_provider, prefix: true - - self.filter_attributes += [:teacher_reference_number] - - # this builds upon #eligible_for_funding - # eligible_for_funding is solely based on what NPQ app knows - # eg school, course etc - # here we need to account for previous enrollments too - def eligible_for_dfe_funding(with_funded_place: false) - if previously_funded? - false - else - funding_eligibility(with_funded_place:) - end - end - - def ineligible_for_funding_reason - if previously_funded? - return "previously-funded" - end - - unless eligible_for_funding - "establishment-ineligible" - end - end - - def in_uk_catchment_area? - UK_CATCHMENT_AREA.include?(teacher_catchment) - end - - def latest_completed_participant_declaration - return unless profile - - profile.participant_declarations.npq.for_declaration("completed").billable_or_changeable.order(created_at: :desc).first - end - - def declared_as_billable? - profile.present? && profile.participant_declarations.billable.count.positive? - end - - def change_logs - v1 = versions.where_attribute_changes("eligible_for_funding") - v2 = versions.where_attribute_changes("funding_eligiblity_status_code") - - (v1 + v2) - .uniq - .sort { |a, b| b.created_at <=> a.created_at } - end - -private - - def previously_funded? - # This is an optimization used by the v3 NPQApplicationsQuery in order - # to speed up the bulk-retrieval of NPQ applications. - return transient_previously_funded if respond_to?(:transient_previously_funded) - - @previously_funded ||= participant_identity - .npq_applications - .where.not(id:) - .where(npq_course: npq_course.rebranded_alternative_courses) - .where(eligible_for_funding: true) - .where(funded_place: [nil, true]) - .accepted - .exists? - end - - def funding_eligibility(with_funded_place:) - return eligible_for_funding unless with_funded_place - - eligible_for_funding && (funded_place.nil? || funded_place) - end -end diff --git a/app/models/npq_contract.rb b/app/models/npq_contract.rb deleted file mode 100644 index bcbbfe3e32..0000000000 --- a/app/models/npq_contract.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -class NPQContract < ApplicationRecord - belongs_to :npq_lead_provider - belongs_to :cohort - belongs_to :npq_course, primary_key: :identifier, foreign_key: :course_identifier - - validates :number_of_payment_periods, - :output_payment_percentage, - :service_fee_installments, - :service_fee_percentage, numericality: { only_integer: true, greater_than_or_equal_to: 0 } - validates :per_participant, numericality: { greater_than: 0 } - validates :recruitment_target, numericality: { only_integer: true, greater_than: 0 } - validates :funding_cap, numericality: { only_integer: true, greater_than_or_equal_to: 0, allow_nil: true } - - def self.find_latest_by(npq_lead_provider:, npq_course:, cohort:) - statement = npq_lead_provider.next_output_fee_statement(cohort) - return unless statement - - where( - cohort_id: cohort.id, - npq_lead_provider_id: npq_lead_provider.id, - course_identifier: npq_course.identifier, - version: statement.contract_version, - ).first - end -end diff --git a/app/models/npq_course.rb b/app/models/npq_course.rb deleted file mode 100644 index 424c14559b..0000000000 --- a/app/models/npq_course.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -class NPQCourse < ApplicationRecord - has_many :npq_applications - - def self.identifiers - pluck(:identifier) - end - - def self.schedule_for(npq_course:, cohort: Cohort.current) - case npq_course.identifier - when *Finance::Schedule::NPQLeadership::IDENTIFIERS - Finance::Schedule::NPQLeadership.schedule_for(cohort:) - when *Finance::Schedule::NPQSpecialist::IDENTIFIERS - Finance::Schedule::NPQSpecialist.schedule_for(cohort:) - when *Finance::Schedule::NPQSupport::IDENTIFIERS - Finance::Schedule::NPQSupport.find_by!(cohort:) - when *Finance::Schedule::NPQEhco::IDENTIFIERS - Finance::Schedule::NPQEhco.schedule_for(cohort:) - else - raise ArgumentError, "Invalid course identifier" - end - end - - def rebranded_alternative_courses - case identifier - when "npq-additional-support-offer" - [self, NPQCourse.find_by(identifier: "npq-early-headship-coaching-offer")] - when "npq-early-headship-coaching-offer" - [self, NPQCourse.find_by(identifier: "npq-additional-support-offer")] - else - [self] - end - end -end diff --git a/app/models/npq_lead_provider.rb b/app/models/npq_lead_provider.rb deleted file mode 100644 index 810a147432..0000000000 --- a/app/models/npq_lead_provider.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -class NPQLeadProvider < ApplicationRecord - belongs_to :cpd_lead_provider, optional: true - - has_many :npq_applications - has_many :npq_participant_profiles, through: :npq_applications, source: :profile - has_many :npq_participants, through: :npq_participant_profiles, source: :user - has_many :npq_contracts - has_many :cohorts, through: :npq_contracts - has_many :statements, through: :cpd_lead_provider, class_name: "Finance::Statement::NPQ", source: :npq_statements - has_many :participant_declarations, class_name: "ParticipantDeclaration::NPQ", through: :cpd_lead_provider - - scope :name_order, -> { order("UPPER(name)") } - - def next_output_fee_statement(cohort) - statements.next_output_fee_statements.where(cohort:).first - end -end diff --git a/app/models/participant_declaration/npq.rb b/app/models/participant_declaration/npq.rb index 964381a164..d027fd1f8c 100644 --- a/app/models/participant_declaration/npq.rb +++ b/app/models/participant_declaration/npq.rb @@ -14,7 +14,6 @@ class ParticipantDeclaration::NPQ < ParticipantDeclaration "npq-senco" => "NPQSENCO", }.freeze - has_one :npq_application, through: :participant_profile has_many :statements, class_name: "Finance::Statement::NPQ", through: :statement_line_items has_many :outcomes, class_name: "ParticipantOutcome::NPQ", foreign_key: "participant_declaration_id" @@ -58,10 +57,7 @@ def npq? end def uplift_paid? - !%w[npq-additional-support-offer npq-early-headship-coaching-offer].include?(course_identifier) && - declaration_type == "started" && - %w[paid awaiting_clawback clawed_back].include?(state) && - participant_profile.npq_application.targeted_delivery_funding_eligibility + nil end def qualification_type diff --git a/app/models/participant_identity.rb b/app/models/participant_identity.rb index d5920894d3..cfed6fce11 100644 --- a/app/models/participant_identity.rb +++ b/app/models/participant_identity.rb @@ -8,7 +8,6 @@ class ParticipantIdentity < ApplicationRecord belongs_to :user, touch: true has_many :participant_profiles has_many :npq_participant_profiles, class_name: "ParticipantProfile::NPQ" - has_many :npq_applications has_many :induction_records, through: :participant_profiles validates :email, presence: true, uniqueness: true, notify_email: true diff --git a/app/models/participant_profile/npq.rb b/app/models/participant_profile/npq.rb index b2e45ccaaf..fd4d614e55 100644 --- a/app/models/participant_profile/npq.rb +++ b/app/models/participant_profile/npq.rb @@ -43,8 +43,6 @@ class ParticipantProfile::NPQ < ParticipantProfile belongs_to :school, optional: true belongs_to :npq_course, optional: true - has_one :npq_application, foreign_key: :id - has_many :participant_declarations, class_name: "ParticipantDeclaration::NPQ", foreign_key: :participant_profile_id self.validation_steps = %i[identity decision].freeze @@ -70,10 +68,6 @@ def participant_type :npq end - def fundable? - npq_application&.eligible_for_dfe_funding(with_funded_place: true) - end - def schedule_for(*) schedule end diff --git a/app/models/school.rb b/app/models/school.rb index 3b3c86f94d..0d78b38fa1 100644 --- a/app/models/school.rb +++ b/app/models/school.rb @@ -11,7 +11,6 @@ class School < ApplicationRecord belongs_to :network, optional: true - has_many :npq_applications, foreign_key: "school_urn", class_name: "NPQApplication" has_many :school_links, dependent: :destroy has_many :successor_links, -> { successor }, class_name: "SchoolLink" has_many :predecessor_links, -> { predecessor }, class_name: "SchoolLink" diff --git a/app/models/user.rb b/app/models/user.rb index 6730371e93..d0c52cb948 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -21,7 +21,6 @@ class User < ApplicationRecord has_many :delivery_partner_profiles, dependent: :destroy has_many :delivery_partners, through: :delivery_partner_profiles - has_many :updated_applications, class_name: "NPQApplication", foreign_key: "eligible_for_funding_updated_by_id", dependent: :nullify has_many :appropriate_body_profiles, dependent: :destroy has_many :appropriate_bodies, through: :appropriate_body_profiles @@ -36,8 +35,6 @@ class User < ApplicationRecord has_many :npq_profiles, through: :teacher_profile # end: TODO - has_many :npq_application_eligibility_imports, class_name: "NPQApplications::EligibilityImport" - has_many :participant_id_changes, -> { order(created_at: :desc) } auto_strip_attributes :full_name, nullify: false, squish: true @@ -66,13 +63,6 @@ def self.ransackable_associations(_auth_object = nil) %w[participant_identities participant_profiles schools lead_provider delivery_partner teacher_profile] end - # changed from has_many :npq_applications as these now live on participant_identities - # and it is possible that there are applications on one or more of the user's - # participant_identity records - def npq_applications - NPQApplication.joins(:participant_identity).where(participant_identity: { user_id: id }) - end - def admin? admin_profile.present? end @@ -122,7 +112,7 @@ def npq? end def npq_registered? - npq? || npq_applications.any? + npq? end def participant? @@ -172,7 +162,6 @@ def user_roles ("mentor" if mentor?), ("early_career_teacher" if early_career_teacher?), ("npq_participant" if npq?), - ("npq_applicant" if npq_applications.any? && !npq?), ("teacher" if teacher?), # presence of teacher profile, could include orphaned de-duped users ].compact end diff --git a/app/policies/npq_application_policy.rb b/app/policies/npq_application_policy.rb deleted file mode 100644 index 9d5231d129..0000000000 --- a/app/policies/npq_application_policy.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -class NPQApplicationPolicy < ApplicationPolicy - def new? - admin? - end - - def create? - admin? - end - - def show? - admin? - end - - def edit? - admin? - end - - def update? - admin? - end - - def invalid_payments_analysis? - admin? - end - - class Scope < Scope - def resolve - return scope.all if user.admin? - - scope.none - end - end -end diff --git a/app/serializers/archive/npq_application_serializer.rb b/app/serializers/archive/npq_application_serializer.rb deleted file mode 100644 index 00773d3111..0000000000 --- a/app/serializers/archive/npq_application_serializer.rb +++ /dev/null @@ -1,49 +0,0 @@ -# frozen_string_literal: true - -module Archive - class NPQApplicationSerializer - include JSONAPI::Serializer - - set_id :id - - attribute :participant_identity_id - attribute :npq_lead_provider_id - attribute :npq_course_id - attribute :date_of_birth - attribute :teacher_reference_number - attribute :teacher_reference_number_verified - attribute :school_urn - attribute :headteacher_status - attribute :active_alert - attribute :eligible_for_funding - attribute :funding_choice - attribute :nino - attribute :lead_provider_approval_status - attribute :school_ukprn - attribute :created_at - attribute :works_in_school - attribute :employer_name - attribute :employment_role - attribute :targeted_support_funding_eligibility - attribute :cohort_id - attribute :targeted_delivery_funding_eligibility - attribute :works_in_nursery - attribute :works_in_childcare - attribute :kind_of_nursery - attribute :private_childcare_provider_urn - attribute :funding_eligiblity_status_code - attribute :teacher_catchment - attribute :teacher_catchment_country - attribute :employment_type - attribute :teacher_catchment_iso_country_code - attribute :itt_provider - attribute :lead_mentor - attribute :notes - attribute :primary_establishment - attribute :number_of_pupils - attribute :tsf_primary_eligibility - attribute :tsf_primary_plus_eligibility - attribute :eligible_for_funding_updated_by_id - attribute :eligible_for_funding_updated_at - end -end diff --git a/app/serializers/archive/user_serializer.rb b/app/serializers/archive/user_serializer.rb index d1321b594b..93636f5391 100644 --- a/app/serializers/archive/user_serializer.rb +++ b/app/serializers/archive/user_serializer.rb @@ -27,9 +27,5 @@ class UserSerializer attribute :participant_profiles do |user| ParticipantProfileSerializer.new(user.participant_profiles).serializable_hash[:data] end - - attribute :npq_applications do |user| - NPQApplicationSerializer.new(user.npq_applications).serializable_hash[:data] - end end end diff --git a/app/serializers/finance/ecf/duplicate_serializer.rb b/app/serializers/finance/ecf/duplicate_serializer.rb index 9c14565965..a4b844c152 100644 --- a/app/serializers/finance/ecf/duplicate_serializer.rb +++ b/app/serializers/finance/ecf/duplicate_serializer.rb @@ -19,7 +19,6 @@ class DuplicateSerializer attribute :profile_duplicity, &:profile_duplicity attribute :notes, &:notes - attribute :npq_course_id, &:npq_course_id attribute :schedule_id, &:schedule_id attribute :school_id, &:school_id attribute :core_induction_programme_id, &:core_induction_programme_id diff --git a/app/serializers/finance/npq/assurance_report/csv_serializer.rb b/app/serializers/finance/npq/assurance_report/csv_serializer.rb deleted file mode 100644 index 69a2576e90..0000000000 --- a/app/serializers/finance/npq/assurance_report/csv_serializer.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -require "csv" - -module Finance - module NPQ - module AssuranceReport - class CsvSerializer - def initialize(scope, statement) - self.scope = scope - self.statement = statement - end - - def filename - "NPQ-Declarations-#{npq_lead_provider.name.gsub(/\W/, '')}-Cohort#{statement.cohort.start_year}-#{statement.name.gsub(/\W/, '')}.csv" - end - - def call - CSV.generate do |csv| - csv << csv_headers - - scope.each do |record| - csv << to_row(record) - end - end - end - - def csv_headers - [ - "Participant ID", - "Participant Name", - "TRN", - "Course Identifier", - "Schedule", - "Eligible For Funding", - ("Funded place" if FeatureFlag.active?(:npq_capping)), - "Lead Provider Name", - "School Urn", - "School Name", - "Training Status", - "Training Status Reason", - "Declaration ID", - "Declaration Status", - "Declaration Type", - "Declaration Date", - "Declaration Created At", - "Statement Name", - "Statement ID", - "Targeted Delivery Funding", - ].compact - end - - private - - attr_accessor :scope, :statement - - def to_row(record) - [ - record.participant_id, - record.participant_name, - record.trn, - record.course_identifier, - record.schedule, - record.eligible_for_funding, - record.npq_lead_provider_name, - record.school_urn, - record.school_name, - record.training_status, - record.training_status_reason, - record.declaration_id, - record.declaration_status, - record.declaration_type, - record.declaration_date.iso8601, - record.declaration_created_at.iso8601, - record.statement_name, - record.statement_id, - record.targeted_delivery_funding, - ].tap do |row| - row.insert(6, record.funded_place) if FeatureFlag.active?(:npq_capping) - end - end - - def npq_lead_provider - statement.npq_lead_provider - end - end - end - end -end diff --git a/app/services/importers/create_new_npq_cohort.rb b/app/services/importers/create_new_npq_cohort.rb deleted file mode 100644 index cced0e2507..0000000000 --- a/app/services/importers/create_new_npq_cohort.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -module Importers - class CreateNewNPQCohort - attr_reader :cohort_csv, :schedule_csv, :contract_csv, :statement_csv, :logger - - def initialize(cohort_csv:, schedule_csv:, contract_csv:, statement_csv:, logger: Rails.logger) - @cohort_csv = cohort_csv - @schedule_csv = schedule_csv - @contract_csv = contract_csv - @statement_csv = statement_csv - @logger = logger - end - - def call - logger.info "Running CreateCohort with: '#{cohort_csv}'" - CreateCohort.new(path_to_csv: cohort_csv).call - - logger.info "Running CreateSchedule with: '#{schedule_csv}'" - CreateSchedule.new(path_to_csv: schedule_csv).call - - logger.info "Running CreateNPQContract with: '#{contract_csv}'" - CreateNPQContract.new(path_to_csv: contract_csv).call - - logger.info "Running CreateStatement with: '#{statement_csv}'" - CreateStatement.new(path_to_csv: statement_csv).call - end - end -end diff --git a/app/services/importers/create_new_npq_course.rb b/app/services/importers/create_new_npq_course.rb deleted file mode 100644 index 3df307aa56..0000000000 --- a/app/services/importers/create_new_npq_course.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -module Importers - class CreateNewNPQCourse - def call - logger.info "CreateNewNPQCourse: Started!" - check_csvs! - - logger.info "Running CreateNPQCourse with: '#{npq_course_csv}'" - CreateNPQCourse.new(path_to_csv: npq_course_csv).call - - logger.info "Running CreateNPQContract with: '#{contract_csv}'" - CreateNPQContract.new(path_to_csv: contract_csv, set_to_latest_version: true).call - end - - private - - attr_reader :npq_course_csv, :contract_csv, :logger - - def initialize(npq_course_csv:, contract_csv:, logger: Rails.logger) - @npq_course_csv = npq_course_csv - @contract_csv = contract_csv - @logger = logger - end - - def check_csvs! - return if npq_course_csv.present? && contract_csv.present? - - raise "All scripts need to be present to create a new NPQ Course" - end - end -end diff --git a/app/services/importers/create_npq_contract.rb b/app/services/importers/create_npq_contract.rb deleted file mode 100644 index 2021154bb2..0000000000 --- a/app/services/importers/create_npq_contract.rb +++ /dev/null @@ -1,110 +0,0 @@ -# frozen_string_literal: true - -require "csv" - -module Importers - class CreateNPQContract - AVAILABLE_HEADERS = %w[ - provider_name - cohort_year - course_identifier - recruitment_target - per_participant - service_fee_installments - special_course - monthly_service_fee - funding_cap - ].freeze - - attr_reader :path_to_csv, :set_to_latest_version - - def initialize(path_to_csv:, set_to_latest_version: false) - @path_to_csv = path_to_csv - @set_to_latest_version = set_to_latest_version - end - - def call - check_headers - - ActiveRecord::Base.transaction do - rows.each do |row| - cohort = Cohort.find_by!(start_year: row["cohort_year"]) - cpd_lead_provider = CpdLeadProvider.find_by!(name: row["provider_name"]) - npq_lead_provider = cpd_lead_provider.npq_lead_provider - course = NPQCourse.find_by!(identifier: row["course_identifier"]) - version = Finance::Statement::NPQ.where(cohort:, cpd_lead_provider:).pluck(:contract_version).max if set_to_latest_version == true - - # We only create/update version 0.0.1 for initial values - # Manually create new version of contract if there are changes - contract = NPQContract.find_or_initialize_by( - cohort:, - version: version || "0.0.1", - npq_lead_provider:, - course_identifier: course.identifier, - ) - - contract.update!( - monthly_service_fee: row["monthly_service_fee"] || 0.0, - recruitment_target: row["recruitment_target"].to_i, - per_participant: row["per_participant"], - service_fee_installments: row["service_fee_installments"].to_i, - number_of_payment_periods: number_of_payment_periods_for(course:), - service_fee_percentage: service_fee_percentage_for(course:), - output_payment_percentage: output_payment_percentage_for(course:), - special_course: (row["special_course"].to_s.upcase == "TRUE"), - funding_cap: row["funding_cap"], - ) - end - end - end - - private - - def number_of_payment_periods_for(course:) - case course.identifier - when *Finance::Schedule::NPQLeadership::IDENTIFIERS - 4 - when *Finance::Schedule::NPQSpecialist::IDENTIFIERS - 3 - when *Finance::Schedule::NPQSupport::IDENTIFIERS - 4 - when *Finance::Schedule::NPQEhco::IDENTIFIERS - 4 - else - raise ArgumentError, "Invalid course identifier" - end - end - - def service_fee_percentage_for(course:) - case course.identifier - when *Finance::Schedule::NPQSupport::IDENTIFIERS - 0 - when *Finance::Schedule::NPQEhco::IDENTIFIERS - 0 - else - 40 - end - end - - def output_payment_percentage_for(course:) - case course.identifier - when *Finance::Schedule::NPQSupport::IDENTIFIERS - 100 - when *Finance::Schedule::NPQEhco::IDENTIFIERS - 100 - else - 60 - end - end - - def check_headers - unless rows.headers.all? { |h| h.in?(AVAILABLE_HEADERS) } - raise NameError, "Invalid headers" - end - end - - def rows - @rows ||= CSV.read(path_to_csv, headers: true, skip_blanks: true) - end - end -end diff --git a/app/services/importers/create_npq_course.rb b/app/services/importers/create_npq_course.rb deleted file mode 100644 index 16687efb56..0000000000 --- a/app/services/importers/create_npq_course.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: true - -require "csv" - -module Importers - class CreateNPQCourse < BaseService - def call - check_headers! - - logger.info "CreateNPQCourse: Started!" - - ActiveRecord::Base.transaction do - rows.each do |row| - create_npq_course(row) - end - end - - logger.info "CreateNPQCourse: Finished!" - end - - private - - attr_reader :path_to_csv, :logger - - def initialize(path_to_csv:, logger: Rails.logger) - @path_to_csv = path_to_csv - @logger = logger - end - - def create_npq_course(row) - NPQCourse.find_or_create_by!( - { - name: row["name"], - identifier: row["identifier"], - }, - ) - - logger.info "CreateNPQCourse: Course for identifier #{row['identifier']} successfully find_or_created" - end - - def check_headers! - unless %w[name identifier].all? { |header| rows.headers.include?(header) } - raise NameError, "Invalid headers" - end - end - - def rows - @rows ||= CSV.read(path_to_csv, headers: true) - end - end -end diff --git a/app/services/importers/create_statement.rb b/app/services/importers/create_statement.rb index 1bc10bc5ae..4e8e62c66a 100644 --- a/app/services/importers/create_statement.rb +++ b/app/services/importers/create_statement.rb @@ -17,7 +17,6 @@ def call ActiveRecord::Base.transaction do create_ecf_statements! - create_npq_statements! end logger.info "CreateStatement: Finished!" @@ -66,40 +65,6 @@ def create_ecf_statements! end end - def create_npq_statements! - npq_statements.each do |statement_data| - npq_lead_providers_with_contracts_for(cohort: statement_data.cohort).each do |npq_lead_provider| - cpd_lead_provider = npq_lead_provider.cpd_lead_provider - - logger.info "CreateStatement: Creating #{statement_data.cohort.start_year} cohort NPQ statements for #{cpd_lead_provider.name}" - - statement = Finance::Statement::NPQ.find_by( - name: statement_data.name, - cpd_lead_provider:, - cohort: statement_data.cohort, - ) - - next if statement - - contract_version = Finance::Statement::NPQ.where(cpd_lead_provider:, cohort: statement_data.cohort).order(payment_date: :desc).first&.contract_version - contract_version ||= "0.0.1" - - Finance::Statement::NPQ.create!( - name: statement_data.name, - cpd_lead_provider:, - deadline_date: statement_data.deadline_date, - payment_date: statement_data.payment_date, - cohort: statement_data.cohort, - output_fee: statement_data.output_fee, - type: class_for(statement_data, namespace: statement_data.type), - contract_version:, - ) - - logger.info "CreateStatement: #{statement_data.cohort.start_year} cohort NPQ statements for #{cpd_lead_provider.name} successfully created!" - end - end - end - def class_for(statment_data, namespace:) return namespace::Paid if statment_data[:payment_date] < Date.current return namespace::Payable if Date.current.between?(statment_data[:deadline_date], statment_data[:payment_date]) @@ -111,9 +76,7 @@ def statement_converter lambda do |value, field_info| case field_info.header when "type" - return Finance::Statement::ECF if value.downcase == "ecf" - - Finance::Statement::NPQ if value.downcase == "npq" + Finance::Statement::ECF if value.downcase == "ecf" when "deadline_date", "payment_date" Date.parse(value) when "output_fee" @@ -145,18 +108,9 @@ def ecf_statements @ecf_statements ||= rows.map { |hash| OpenStruct.new(hash) }.select { |row| row.type == Finance::Statement::ECF } end - def npq_statements - @npq_statements ||= rows.map { |hash| OpenStruct.new(hash) }.select { |row| row.type == Finance::Statement::NPQ } - end - def lead_providers_with_ecf_contracts_for(cohort:) @ecf_contracts ||= {} @ecf_contracts[cohort.id] ||= CallOffContract.includes(lead_provider: :cpd_lead_provider).where(cohort:).map(&:lead_provider) end - - def npq_lead_providers_with_contracts_for(cohort:) - @npq_contracts ||= {} - @npq_contracts[cohort.id] ||= NPQContract.includes(npq_lead_provider: :cpd_lead_provider).where(cohort:).map(&:npq_lead_provider) - end end end diff --git a/app/services/importers/npq_manual_validation.rb b/app/services/importers/npq_manual_validation.rb deleted file mode 100644 index 95beb9673c..0000000000 --- a/app/services/importers/npq_manual_validation.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -class Importers::NPQManualValidation - attr_reader :path_to_csv - - def initialize(path_to_csv:) - @path_to_csv = path_to_csv - end - - def call - check_headers - - rows.each do |row| - npq_application_id = row["application_ecf_id"] - trn = add_leading_zero(row["validated_trn"]) - - npq_application = NPQApplication.find_by(id: npq_application_id) - - puts "No NPQApplication found for #{npq_application_id}" if npq_application.nil? - next if npq_application.nil? - - puts "Updating TRN for NPQApplication: #{npq_application_id} with TRN: #{trn}" - npq_application.update!(teacher_reference_number: trn, teacher_reference_number_verified: true) - - teacher_profile = npq_application.profile.try(:teacher_profile) - next if teacher_profile.nil? - - puts "Updating TeacherProfile for NPQApplication: #{npq_application_id} with TRN: #{trn}" - teacher_profile.update!(trn:) - end - end - -private - - def add_leading_zero(trn) - trn.rjust(7, "0") - end - - def check_headers - unless rows.headers == %w[application_ecf_id validated_trn] - raise NameError, "Invalid headers" - end - end - - def rows - @rows ||= CSV.read(path_to_csv, headers: true) - end -end diff --git a/config/analytics.yml b/config/analytics.yml index 12cd47680b..f4904d9d04 100644 --- a/config/analytics.yml +++ b/config/analytics.yml @@ -92,48 +92,6 @@ - delivery_partner_id - mentor_user_id - cohort_id - :npq_applications: - - id - - npq_lead_provider_id - - npq_course_id - - teacher_reference_number - - teacher_reference_number_verified - - school_urn - - headteacher_status - - active_alert - - eligible_for_funding - - funding_choice - - lead_provider_approval_status - - school_ukprn - - created_at - - updated_at - - participant_identity_id - - works_in_school - - employer_name - - employment_role - - targeted_support_funding_eligibility - - cohort_id - - targeted_delivery_funding_eligibility - - works_in_nursery - - works_in_childcare - - kind_of_nursery - - private_childcare_provider_urn - - funding_eligiblity_status_code - - teacher_catchment - - teacher_catchment_country - - employment_type - - teacher_catchment_iso_country_code - - itt_provider - - lead_mentor - - notes - - primary_establishment - - number_of_pupils - - tsf_primary_eligibility - - tsf_primary_plus_eligibility - - eligible_for_funding_updated_by_id - - eligible_for_funding_updated_at - - funded_place - - referred_by_return_to_teaching_adviser :induction_records: - id - induction_programme_id @@ -223,19 +181,6 @@ - schedule_id - created_at - updated_at - :npq_lead_providers: - - id - - name - - created_at - - updated_at - - cpd_lead_provider_id - - vat_chargeable - :npq_courses: - - id - - name - - created_at - - updated_at - - identifier :local_authorities: - id - created_at diff --git a/config/analytics_blocklist.yml b/config/analytics_blocklist.yml index ef13521941..09881fbfe4 100644 --- a/config/analytics_blocklist.yml +++ b/config/analytics_blocklist.yml @@ -47,23 +47,6 @@ - primary_participant_profile_id - created_at - updated_at - :npq_application_exports: - - id - - start_date - - end_date - - user_id - - created_at - - updated_at - :npq_application_eligibility_imports: - - id - - user_id - - filename - - status - - updated_records - - import_errors - - processed_at - - created_at - - updated_at :statements: - original_value - contract_version @@ -250,28 +233,6 @@ - updated_at - output_payment_percentage - service_fee_percentage - :npq_contracts: - - id - - raw - - version - - npq_lead_provider_id - - recruitment_target - - course_identifier - - service_fee_installments - - service_fee_percentage - - per_participant - - number_of_payment_periods - - output_payment_percentage - - created_at - - updated_at - - cohort_id - - monthly_service_fee - - targeted_delivery_funding_per_participant - - special_course - - funding_cap - :npq_applications: - - date_of_birth - - nino :nomination_emails: - token :networks: diff --git a/config/seed_quantities.yml b/config/seed_quantities.yml index d23e660066..9ee4325bd7 100644 --- a/config/seed_quantities.yml +++ b/config/seed_quantities.yml @@ -4,34 +4,16 @@ # Add the following snippet to your .env file and adjust: # # SEED_LOCAL_AUTHORITIES=10 -# SEED_NPQ_APPLICATIONS_PENDING=10 -# SEED_NPQ_APPLICATION_WITH_DECLARATIONS=10 -# SEED_NPQ_APPLICATIONS_REJECTED=10 -# SEED_NPQ_APPLICATIONS_ASO=10 -# SEED_NPQ_APPLICATIONS_EHCO=10 -# SEED_NPQ_APPLICATIONS_SPECIALIST=10 -# SEED_NPQ_APPLICATIONS_LEADERSHIP=10 -# SEED_NPQ_APPLICATIONS_EDGE_CASES=10 # SEED_FIP_TO_FIP_TRANSFERS_KEEPING_ORIGINAL_PROVIDER=2 # SEED_FIP_TO_FIP_TRANSFERS_CHANGING_PROVIDER=2 # SEED_SCHOOL_INVITATIONS=10 -# SEED_NPQ_APPLICATIONS_ELIGIBLE_FOR_TRANSFER=10 # SEED_ECTS_BECOMING_MENTORS=10 --- default: &default local_authorities: 10 - npq_applications_pending: 10 - npq_application_with_declarations: 10 - npq_applications_rejected: 10 - npq_applications_aso: 10 - npq_applications_ehco: 10 - npq_applications_specialist: 10 - npq_applications_leadership: 10 fip_to_fip_transfers_keeping_original_provider: 2 fip_to_fip_transfers_changing_provider: 2 school_invitations: 10 - npq_applications_eligible_for_transfer: 10 - npq_applications_edge_cases: 25 ects_becoming_mentors: 10 development: @@ -46,31 +28,13 @@ migration: test: <<: *default local_authorities: 1 - npq_applications_pending: 1 - npq_application_with_declarations: 1 - npq_applications_rejected: 1 - npq_applications_aso: 1 - npq_applications_ehco: 1 - npq_applications_specialist: 1 - npq_applications_leadership: 1 school_invitations: 1 - npq_applications_eligible_for_transfer: 1 - npq_applications_edge_cases: 1 review: local_authorities: 3 - npq_applications_pending: 3 - npq_application_with_declarations: 3 - npq_applications_rejected: 3 - npq_applications_aso: 3 - npq_applications_ehco: 3 - npq_applications_specialist: 3 - npq_applications_leadership: 3 fip_to_fip_transfers_keeping_original_provider: 2 fip_to_fip_transfers_changing_provider: 2 school_invitations: 3 - npq_applications_eligible_for_transfer: 3 - npq_applications_edge_cases: 8 ects_becoming_mentors: 3 staging: diff --git a/db/data/npq_contracts/fake-2021.csv b/db/data/npq_contracts/fake-2021.csv deleted file mode 100644 index 8ba7f80076..0000000000 --- a/db/data/npq_contracts/fake-2021.csv +++ /dev/null @@ -1,78 +0,0 @@ -provider_name,cohort_year,course_identifier,recruitment_target,per_participant,service_fee_installments,special_course,monthly_service_fee,funding_cap -Ambition Institute,2021,npq-leading-teaching,1000,900,12,FALSE,0.0, -Ambition Institute,2021,npq-leading-behaviour-culture,1001,901,13,FALSE,0.0, -Ambition Institute,2021,npq-leading-teaching-development,1002,902,14,FALSE,0.0, -Ambition Institute,2021,npq-senior-leadership,1003,903,15,FALSE,0.0, -Ambition Institute,2021,npq-headship,1004,904,16,FALSE,0.0, -Ambition Institute,2021,npq-executive-leadership,1005,905,17,FALSE,0.0, -Ambition Institute,2021,npq-leading-literacy,1006,906,18,FALSE,0.0, -Ambition Institute,2021,npq-early-years-leadership,1007,907,19,FALSE,0.0, -Best Practice Network,2021,npq-leading-teaching,1008,908,20,FALSE,0.0, -Best Practice Network,2021,npq-leading-behaviour-culture,1009,909,21,FALSE,0.0, -Best Practice Network,2021,npq-leading-teaching-development,1010,910,22,FALSE,0.0, -Best Practice Network,2021,npq-senior-leadership,1011,911,23,FALSE,0.0, -Best Practice Network,2021,npq-headship,1012,912,24,FALSE,0.0, -Best Practice Network,2021,npq-executive-leadership,1013,913,25,FALSE,0.0, -Church of England,2021,npq-leading-teaching,1014,914,26,FALSE,0.0, -Church of England,2021,npq-leading-behaviour-culture,1015,915,27,FALSE,0.0, -Church of England,2021,npq-leading-teaching-development,1016,916,28,FALSE,0.0, -Church of England,2021,npq-senior-leadership,1017,917,29,FALSE,0.0, -Church of England,2021,npq-headship,1018,918,30,FALSE,0.0, -Church of England,2021,npq-executive-leadership,1019,919,31,FALSE,0.0, -Education Development Trust,2021,npq-leading-teaching,1020,920,32,FALSE,0.0, -Education Development Trust,2021,npq-leading-behaviour-culture,1021,921,33,FALSE,0.0, -Education Development Trust,2021,npq-leading-teaching-development,1022,922,34,FALSE,0.0, -Education Development Trust,2021,npq-senior-leadership,1023,923,35,FALSE,0.0, -Education Development Trust,2021,npq-headship,1024,924,36,FALSE,0.0, -Education Development Trust,2021,npq-executive-leadership,1025,925,37,FALSE,0.0, -Education Development Trust,2021,npq-leading-literacy,1026,926,38,FALSE,0.0, -Education Development Trust,2021,npq-early-years-leadership,1027,927,39,FALSE,0.0, -School-Led Network,2021,npq-leading-teaching,1028,928,40,FALSE,0.0, -School-Led Network,2021,npq-leading-behaviour-culture,1029,929,41,FALSE,0.0, -School-Led Network,2021,npq-leading-teaching-development,1030,930,42,FALSE,0.0, -School-Led Network,2021,npq-senior-leadership,1031,931,43,FALSE,0.0, -School-Led Network,2021,npq-headship,1032,932,44,FALSE,0.0, -School-Led Network,2021,npq-executive-leadership,1033,933,45,FALSE,0.0, -School-Led Network,2021,npq-leading-literacy,1034,934,46,FALSE,0.0, -School-Led Network,2021,npq-early-years-leadership,1035,935,47,FALSE,0.0, -LLSE,2021,npq-leading-teaching,1036,936,48,FALSE,0.0, -LLSE,2021,npq-leading-behaviour-culture,1037,937,49,FALSE,0.0, -LLSE,2021,npq-leading-teaching-development,1038,938,50,FALSE,0.0, -LLSE,2021,npq-senior-leadership,1039,939,51,FALSE,0.0, -LLSE,2021,npq-headship,1040,940,52,FALSE,0.0, -LLSE,2021,npq-executive-leadership,1041,941,53,FALSE,0.0, -LLSE,2021,npq-leading-literacy,1042,942,54,FALSE,0.0, -LLSE,2021,npq-early-years-leadership,1043,943,55,FALSE,0.0, -Teach First,2021,npq-leading-teaching,1044,944,56,FALSE,0.0, -Teach First,2021,npq-leading-behaviour-culture,1045,945,57,FALSE,0.0, -Teach First,2021,npq-leading-teaching-development,1046,946,58,FALSE,0.0, -Teach First,2021,npq-senior-leadership,1047,947,59,FALSE,0.0, -Teach First,2021,npq-headship,1048,948,60,FALSE,0.0, -Teach First,2021,npq-executive-leadership,1049,949,61,FALSE,0.0, -Teach First,2021,npq-leading-literacy,1050,950,62,FALSE,0.0, -Teach First,2021,npq-early-years-leadership,1051,951,63,FALSE,0.0, -Teacher Development Trust,2021,npq-leading-teaching,1052,952,64,FALSE,0.0, -Teacher Development Trust,2021,npq-leading-behaviour-culture,1053,953,65,FALSE,0.0, -Teacher Development Trust,2021,npq-leading-teaching-development,1054,954,66,FALSE,0.0, -Teacher Development Trust,2021,npq-senior-leadership,1055,955,67,FALSE,0.0, -Teacher Development Trust,2021,npq-headship,1056,956,68,FALSE,0.0, -Teacher Development Trust,2021,npq-executive-leadership,1057,957,69,FALSE,0.0, -Teacher Development Trust,2021,npq-leading-literacy,1058,958,70,FALSE,0.0, -Teacher Development Trust,2021,npq-early-years-leadership,1059,959,71,FALSE,0.0, -UCL Institute of Education,2021,npq-leading-teaching,1060,960,72,FALSE,0.0, -UCL Institute of Education,2021,npq-leading-behaviour-culture,1061,961,73,FALSE,0.0, -UCL Institute of Education,2021,npq-leading-teaching-development,1062,962,74,FALSE,0.0, -UCL Institute of Education,2021,npq-senior-leadership,1063,963,75,FALSE,0.0, -UCL Institute of Education,2021,npq-headship,1064,964,76,FALSE,0.0, -UCL Institute of Education,2021,npq-executive-leadership,1065,965,77,FALSE,0.0, -UCL Institute of Education,2021,npq-leading-literacy,1066,966,78,FALSE,0.0, -UCL Institute of Education,2021,npq-early-years-leadership,1067,967,79,FALSE,0.0, -Ambition Institute,2021,npq-early-headship-coaching-offer,300,800,0,FALSE,0.0, -Best Practice Network,2021,npq-early-headship-coaching-offer,300,800,0,FALSE,0.0, -Church of England,2021,npq-early-headship-coaching-offer,300,800,0,FALSE,0.0, -Education Development Trust,2021,npq-early-headship-coaching-offer,300,800,0,FALSE,0.0, -School-Led Network,2021,npq-early-headship-coaching-offer,300,800,0,FALSE,0.0, -LLSE,2021,npq-early-headship-coaching-offer,300,800,0,FALSE,0.0, -Teach First,2021,npq-early-headship-coaching-offer,300,800,0,FALSE,0.0, -Teacher Development Trust,2021,npq-early-headship-coaching-offer,300,800,0,FALSE,0.0, -UCL Institute of Education,2021,npq-early-headship-coaching-offer,300,800,0,FALSE,0.0, diff --git a/db/data/npq_contracts/fake-2022.csv b/db/data/npq_contracts/fake-2022.csv deleted file mode 100644 index dde6a0fada..0000000000 --- a/db/data/npq_contracts/fake-2022.csv +++ /dev/null @@ -1,87 +0,0 @@ -provider_name,cohort_year,course_identifier,recruitment_target,per_participant,service_fee_installments,special_course,monthly_service_fee,funding_cap -Ambition Institute,2022,npq-leading-teaching,1000,100,12,FALSE,0.0, -Ambition Institute,2022,npq-leading-behaviour-culture,1001,101,13,FALSE,0.0, -Ambition Institute,2022,npq-leading-teaching-development,1002,102,14,FALSE,0.0, -Ambition Institute,2022,npq-senior-leadership,1003,103,15,FALSE,0.0, -Ambition Institute,2022,npq-headship,1004,104,16,FALSE,0.0, -Ambition Institute,2022,npq-executive-leadership,1005,105,17,FALSE,0.0, -Ambition Institute,2022,npq-leading-literacy,1006,106,18,FALSE,0.0, -Ambition Institute,2022,npq-early-years-leadership,1007,107,19,FALSE,0.0, -Best Practice Network,2022,npq-leading-teaching,1008,108,20,FALSE,0.0, -Best Practice Network,2022,npq-leading-behaviour-culture,1009,109,21,FALSE,0.0, -Best Practice Network,2022,npq-leading-teaching-development,1010,110,22,FALSE,0.0, -Best Practice Network,2022,npq-senior-leadership,1011,111,23,FALSE,0.0, -Best Practice Network,2022,npq-headship,1012,112,24,FALSE,0.0, -Best Practice Network,2022,npq-executive-leadership,1013,113,25,FALSE,0.0, -Church of England,2022,npq-leading-teaching,1014,114,26,FALSE,0.0, -Church of England,2022,npq-leading-behaviour-culture,1015,115,27,FALSE,0.0, -Church of England,2022,npq-leading-teaching-development,1016,116,28,FALSE,0.0, -Church of England,2022,npq-senior-leadership,1017,117,29,FALSE,0.0, -Church of England,2022,npq-headship,1018,118,30,FALSE,0.0, -Church of England,2022,npq-executive-leadership,1019,119,31,FALSE,0.0, -Education Development Trust,2022,npq-leading-teaching,1020,120,32,FALSE,0.0, -Education Development Trust,2022,npq-leading-behaviour-culture,1021,121,33,FALSE,0.0, -Education Development Trust,2022,npq-leading-teaching-development,1022,122,34,FALSE,0.0, -Education Development Trust,2022,npq-senior-leadership,1023,123,35,FALSE,0.0, -Education Development Trust,2022,npq-headship,1024,124,36,FALSE,0.0, -Education Development Trust,2022,npq-executive-leadership,1025,125,37,FALSE,0.0, -Education Development Trust,2022,npq-leading-literacy,1026,126,38,FALSE,0.0, -Education Development Trust,2022,npq-early-years-leadership,1027,127,39,FALSE,0.0, -School-Led Network,2022,npq-leading-teaching,1028,128,40,FALSE,0.0, -School-Led Network,2022,npq-leading-behaviour-culture,1029,129,41,FALSE,0.0, -School-Led Network,2022,npq-leading-teaching-development,1030,130,42,FALSE,0.0, -School-Led Network,2022,npq-senior-leadership,1031,131,43,FALSE,0.0, -School-Led Network,2022,npq-headship,1032,132,44,FALSE,0.0, -School-Led Network,2022,npq-executive-leadership,1033,133,45,FALSE,0.0, -School-Led Network,2022,npq-leading-literacy,1034,134,46,FALSE,0.0, -School-Led Network,2022,npq-early-years-leadership,1035,135,47,FALSE,0.0, -LLSE,2022,npq-leading-teaching,1036,136,48,FALSE,0.0, -LLSE,2022,npq-leading-behaviour-culture,1037,137,49,FALSE,0.0, -LLSE,2022,npq-leading-teaching-development,1038,138,50,FALSE,0.0, -LLSE,2022,npq-senior-leadership,1039,139,51,FALSE,0.0, -LLSE,2022,npq-headship,1040,140,52,FALSE,0.0, -LLSE,2022,npq-executive-leadership,1041,141,53,FALSE,0.0, -LLSE,2022,npq-leading-literacy,1042,142,54,FALSE,0.0, -LLSE,2022,npq-early-years-leadership,1043,143,55,FALSE,0.0, -Teach First,2022,npq-leading-teaching,1044,144,56,FALSE,0.0, -Teach First,2022,npq-leading-behaviour-culture,1045,145,57,FALSE,0.0, -Teach First,2022,npq-leading-teaching-development,1046,146,58,FALSE,0.0, -Teach First,2022,npq-senior-leadership,1047,147,59,FALSE,0.0, -Teach First,2022,npq-headship,1048,148,60,FALSE,0.0, -Teach First,2022,npq-executive-leadership,1049,149,61,FALSE,0.0, -Teach First,2022,npq-leading-literacy,1050,150,62,FALSE,0.0, -Teach First,2022,npq-early-years-leadership,1051,151,63,FALSE,0.0, -Teacher Development Trust,2022,npq-leading-teaching,1052,152,64,FALSE,0.0, -Teacher Development Trust,2022,npq-leading-behaviour-culture,1053,153,65,FALSE,0.0, -Teacher Development Trust,2022,npq-leading-teaching-development,1054,154,66,FALSE,0.0, -Teacher Development Trust,2022,npq-senior-leadership,1055,155,67,FALSE,0.0, -Teacher Development Trust,2022,npq-headship,1056,156,68,FALSE,0.0, -Teacher Development Trust,2022,npq-executive-leadership,1057,157,69,FALSE,0.0, -Teacher Development Trust,2022,npq-leading-literacy,1058,158,70,FALSE,0.0, -Teacher Development Trust,2022,npq-early-years-leadership,1059,159,71,FALSE,0.0, -UCL Institute of Education,2022,npq-leading-teaching,1060,160,72,FALSE,0.0, -UCL Institute of Education,2022,npq-leading-behaviour-culture,1061,161,73,FALSE,0.0, -UCL Institute of Education,2022,npq-leading-teaching-development,1062,162,74,FALSE,0.0, -UCL Institute of Education,2022,npq-senior-leadership,1063,163,75,FALSE,0.0, -UCL Institute of Education,2022,npq-headship,1064,164,76,FALSE,0.0, -UCL Institute of Education,2022,npq-executive-leadership,1065,165,77,FALSE,0.0, -UCL Institute of Education,2022,npq-leading-literacy,1066,166,78,FALSE,0.0, -UCL Institute of Education,2022,npq-early-years-leadership,1067,167,79,FALSE,0.0, -Ambition Institute,2022,npq-early-headship-coaching-offer,1068,168,0,FALSE,0.0, -Best Practice Network,2022,npq-early-headship-coaching-offer,1069,169,0,FALSE,0.0, -Church of England,2022,npq-early-headship-coaching-offer,1070,170,0,FALSE,0.0, -Education Development Trust,2022,npq-early-headship-coaching-offer,1071,171,0,FALSE,0.0, -School-Led Network,2022,npq-early-headship-coaching-offer,1072,172,0,FALSE,0.0, -LLSE,2022,npq-early-headship-coaching-offer,1073,173,0,FALSE,0.0, -Teach First,2022,npq-early-headship-coaching-offer,1074,174,0,FALSE,0.0, -Teacher Development Trust,2022,npq-early-headship-coaching-offer,1075,175,0,FALSE,0.0, -UCL Institute of Education,2022,npq-early-headship-coaching-offer,1076,176,0,FALSE,0.0, -National Institute of Teaching,2022,npq-leading-teaching,100,800,24,FALSE,0.0, -National Institute of Teaching,2022,npq-leading-behaviour-culture,101,801,24,FALSE,0.0, -National Institute of Teaching,2022,npq-leading-teaching-development,102,802,24,FALSE,0.0, -National Institute of Teaching,2022,npq-senior-leadership,103,803,24,FALSE,0.0, -National Institute of Teaching,2022,npq-headship,104,804,24,FALSE,0.0, -National Institute of Teaching,2022,npq-executive-leadership,105,805,24,FALSE,0.0, -National Institute of Teaching,2022,npq-leading-literacy,106,806,24,FALSE,0.0, -National Institute of Teaching,2022,npq-early-years-leadership,107,807,24,FALSE,0.0, -National Institute of Teaching,2022,npq-early-headship-coaching-offer,1000,800,0,FALSE,0.0, diff --git a/db/data/npq_contracts/fake-2023.csv b/db/data/npq_contracts/fake-2023.csv deleted file mode 100644 index 17f908262a..0000000000 --- a/db/data/npq_contracts/fake-2023.csv +++ /dev/null @@ -1,97 +0,0 @@ -provider_name,cohort_year,course_identifier,recruitment_target,per_participant,service_fee_installments,special_course,monthly_service_fee,funding_cap -Ambition Institute,2023,npq-leading-teaching,1000,100,12,FALSE,0.0, -Ambition Institute,2023,npq-leading-behaviour-culture,1001,101,13,FALSE,0.0, -Ambition Institute,2023,npq-leading-teaching-development,1002,102,14,FALSE,0.0, -Ambition Institute,2023,npq-senior-leadership,1003,103,15,FALSE,0.0, -Ambition Institute,2023,npq-headship,1004,104,16,FALSE,0.0, -Ambition Institute,2023,npq-executive-leadership,1005,105,17,FALSE,0.0, -Ambition Institute,2023,npq-leading-literacy,1006,106,18,FALSE,0.0, -Ambition Institute,2023,npq-early-years-leadership,1007,107,19,FALSE,0.0, -Best Practice Network,2023,npq-leading-teaching,1008,108,20,FALSE,0.0, -Best Practice Network,2023,npq-leading-behaviour-culture,1009,109,21,FALSE,0.0, -Best Practice Network,2023,npq-leading-teaching-development,1010,110,22,FALSE,0.0, -Best Practice Network,2023,npq-senior-leadership,1011,111,23,FALSE,0.0, -Best Practice Network,2023,npq-headship,1012,112,24,FALSE,0.0, -Best Practice Network,2023,npq-executive-leadership,1013,113,25,FALSE,0.0, -Church of England,2023,npq-leading-teaching,1014,114,26,FALSE,0.0, -Church of England,2023,npq-leading-behaviour-culture,1015,115,27,FALSE,0.0, -Church of England,2023,npq-leading-teaching-development,1016,116,28,FALSE,0.0, -Church of England,2023,npq-senior-leadership,1017,117,29,FALSE,0.0, -Church of England,2023,npq-headship,1018,118,30,FALSE,0.0, -Church of England,2023,npq-executive-leadership,1019,119,31,FALSE,0.0, -Education Development Trust,2023,npq-leading-teaching,1020,120,32,FALSE,0.0, -Education Development Trust,2023,npq-leading-behaviour-culture,1021,121,33,FALSE,0.0, -Education Development Trust,2023,npq-leading-teaching-development,1022,122,34,FALSE,0.0, -Education Development Trust,2023,npq-senior-leadership,1023,123,35,FALSE,0.0, -Education Development Trust,2023,npq-headship,1024,124,36,FALSE,0.0, -Education Development Trust,2023,npq-executive-leadership,1025,125,37,FALSE,0.0, -Education Development Trust,2023,npq-leading-literacy,1026,126,38,FALSE,0.0, -Education Development Trust,2023,npq-early-years-leadership,1027,127,39,FALSE,0.0, -School-Led Network,2023,npq-leading-teaching,1028,128,40,FALSE,0.0, -School-Led Network,2023,npq-leading-behaviour-culture,1029,129,41,FALSE,0.0, -School-Led Network,2023,npq-leading-teaching-development,1030,130,42,FALSE,0.0, -School-Led Network,2023,npq-senior-leadership,1031,131,43,FALSE,0.0, -School-Led Network,2023,npq-headship,1032,132,44,FALSE,0.0, -School-Led Network,2023,npq-executive-leadership,1033,133,45,FALSE,0.0, -School-Led Network,2023,npq-leading-literacy,1034,134,46,FALSE,0.0, -School-Led Network,2023,npq-early-years-leadership,1035,135,47,FALSE,0.0, -LLSE,2023,npq-leading-teaching,1036,136,48,FALSE,0.0, -LLSE,2023,npq-leading-behaviour-culture,1037,137,49,FALSE,0.0, -LLSE,2023,npq-leading-teaching-development,1038,138,50,FALSE,0.0, -LLSE,2023,npq-senior-leadership,1039,139,51,FALSE,0.0, -LLSE,2023,npq-headship,1040,140,52,FALSE,0.0, -LLSE,2023,npq-executive-leadership,1041,141,53,FALSE,0.0, -LLSE,2023,npq-leading-literacy,1042,142,54,FALSE,0.0, -LLSE,2023,npq-early-years-leadership,1043,143,55,FALSE,0.0, -Teach First,2023,npq-leading-teaching,1044,144,56,FALSE,0.0, -Teach First,2023,npq-leading-behaviour-culture,1045,145,57,FALSE,0.0, -Teach First,2023,npq-leading-teaching-development,1046,146,58,FALSE,0.0, -Teach First,2023,npq-senior-leadership,1047,147,59,FALSE,0.0, -Teach First,2023,npq-headship,1048,148,60,FALSE,0.0, -Teach First,2023,npq-executive-leadership,1049,149,61,FALSE,0.0, -Teach First,2023,npq-leading-literacy,1050,150,62,FALSE,0.0, -Teach First,2023,npq-early-years-leadership,1051,151,63,FALSE,0.0, -Teacher Development Trust,2023,npq-leading-teaching,1052,152,64,FALSE,0.0, -Teacher Development Trust,2023,npq-leading-behaviour-culture,1053,153,65,FALSE,0.0, -Teacher Development Trust,2023,npq-leading-teaching-development,1054,154,66,FALSE,0.0, -Teacher Development Trust,2023,npq-senior-leadership,1055,155,67,FALSE,0.0, -Teacher Development Trust,2023,npq-headship,1056,156,68,FALSE,0.0, -Teacher Development Trust,2023,npq-executive-leadership,1057,157,69,FALSE,0.0, -Teacher Development Trust,2023,npq-leading-literacy,1058,158,70,FALSE,0.0, -Teacher Development Trust,2023,npq-early-years-leadership,1059,159,71,FALSE,0.0, -UCL Institute of Education,2023,npq-leading-teaching,1060,160,72,FALSE,0.0, -UCL Institute of Education,2023,npq-leading-behaviour-culture,1061,161,73,FALSE,0.0, -UCL Institute of Education,2023,npq-leading-teaching-development,1062,162,74,FALSE,0.0, -UCL Institute of Education,2023,npq-senior-leadership,1063,163,75,FALSE,0.0, -UCL Institute of Education,2023,npq-headship,1064,164,76,FALSE,0.0, -UCL Institute of Education,2023,npq-executive-leadership,1065,165,77,FALSE,0.0, -UCL Institute of Education,2023,npq-leading-literacy,1066,166,78,FALSE,0.0, -UCL Institute of Education,2023,npq-early-years-leadership,1067,167,79,FALSE,0.0, -Ambition Institute,2023,npq-early-headship-coaching-offer,1068,168,0,FALSE,0.0, -Best Practice Network,2023,npq-early-headship-coaching-offer,1069,169,0,FALSE,0.0, -Church of England,2023,npq-early-headship-coaching-offer,1070,170,0,FALSE,0.0, -Education Development Trust,2023,npq-early-headship-coaching-offer,1071,171,0,FALSE,0.0, -School-Led Network,2023,npq-early-headship-coaching-offer,1072,172,0,FALSE,0.0, -LLSE,2023,npq-early-headship-coaching-offer,1073,173,0,FALSE,0.0, -Teach First,2023,npq-early-headship-coaching-offer,1074,174,0,FALSE,0.0, -Teacher Development Trust,2023,npq-early-headship-coaching-offer,1075,175,0,FALSE,0.0, -UCL Institute of Education,2023,npq-early-headship-coaching-offer,1076,176,0,FALSE,0.0, -National Institute of Teaching,2023,npq-leading-teaching,100,800,24,FALSE,0.0, -National Institute of Teaching,2023,npq-leading-behaviour-culture,101,801,24,FALSE,0.0, -National Institute of Teaching,2023,npq-leading-teaching-development,102,802,24,FALSE,0.0, -National Institute of Teaching,2023,npq-senior-leadership,103,803,24,FALSE,0.0, -National Institute of Teaching,2023,npq-headship,104,804,24,FALSE,0.0, -National Institute of Teaching,2023,npq-executive-leadership,105,805,24,FALSE,0.0, -National Institute of Teaching,2023,npq-leading-literacy,106,806,24,FALSE,0.0, -National Institute of Teaching,2023,npq-early-years-leadership,107,807,24,FALSE,0.0, -National Institute of Teaching,2023,npq-early-headship-coaching-offer,1000,800,0,FALSE,0.0, -Ambition Institute,2023,npq-leading-primary-mathematics,1007,107,19,TRUE,0.0, -Best Practice Network,2023,npq-leading-primary-mathematics,1013,113,25,TRUE,0.0, -Church of England,2023,npq-leading-primary-mathematics,1019,119,31,TRUE,0.0, -Education Development Trust,2023,npq-leading-primary-mathematics,1027,127,39,TRUE,0.0, -School-Led Network,2023,npq-leading-primary-mathematics,1035,135,47,TRUE,0.0, -LLSE,2023,npq-leading-primary-mathematics,1043,143,55,TRUE,0.0, -Teach First,2023,npq-leading-primary-mathematics,1051,151,63,TRUE,0.0, -Teacher Development Trust,2023,npq-leading-primary-mathematics,1059,159,71,TRUE,0.0, -UCL Institute of Education,2023,npq-leading-primary-mathematics,1067,167,79,TRUE,0.0, -National Institute of Teaching,2023,npq-leading-primary-mathematics,1000,800,0,TRUE,0.0, diff --git a/db/data/npq_contracts/fake-2024.csv b/db/data/npq_contracts/fake-2024.csv deleted file mode 100644 index 4a0d3a4ea9..0000000000 --- a/db/data/npq_contracts/fake-2024.csv +++ /dev/null @@ -1,103 +0,0 @@ -provider_name,cohort_year,course_identifier,recruitment_target,per_participant,service_fee_installments,special_course,monthly_service_fee,funding_cap -Ambition Institute,2024,npq-leading-teaching,1000,100,12,FALSE,0,1 -Ambition Institute,2024,npq-leading-behaviour-culture,1001,101,13,FALSE,0,1 -Ambition Institute,2024,npq-leading-teaching-development,1002,102,14,FALSE,0,1 -Ambition Institute,2024,npq-senior-leadership,1003,103,15,FALSE,0,1 -Ambition Institute,2024,npq-headship,1004,104,16,FALSE,0,1 -Ambition Institute,2024,npq-executive-leadership,1005,105,17,FALSE,0,1 -Ambition Institute,2024,npq-leading-literacy,1006,106,18,FALSE,0,1 -Ambition Institute,2024,npq-early-years-leadership,1007,107,19,FALSE,0,1 -Ambition Institute,2024,npq-senco,450,902,19,FALSE,0,1 -Best Practice Network,2024,npq-leading-teaching,1008,108,20,FALSE,0,1 -Best Practice Network,2024,npq-leading-behaviour-culture,1009,109,21,FALSE,0,1 -Best Practice Network,2024,npq-leading-teaching-development,1010,110,22,FALSE,0,1 -Best Practice Network,2024,npq-senior-leadership,1011,111,23,FALSE,0,1 -Best Practice Network,2024,npq-headship,1012,112,24,FALSE,0,1 -Best Practice Network,2024,npq-executive-leadership,1013,113,25,FALSE,0,1 -Best Practice Network,2024,npq-senco,283,890,19,FALSE,0,1 -Church of England,2024,npq-leading-teaching,1014,114,26,FALSE,0,1 -Church of England,2024,npq-leading-behaviour-culture,1015,115,27,FALSE,0,1 -Church of England,2024,npq-leading-teaching-development,1016,116,28,FALSE,0,1 -Church of England,2024,npq-senior-leadership,1017,117,29,FALSE,0,1 -Church of England,2024,npq-headship,1018,118,30,FALSE,0,1 -Church of England,2024,npq-executive-leadership,1019,119,31,FALSE,0,1 -Church of England,2024,npq-senco,200,901,19,FALSE,0,1 -Education Development Trust,2024,npq-leading-teaching,1020,120,32,FALSE,0,1 -Education Development Trust,2024,npq-leading-behaviour-culture,1021,121,33,FALSE,0,1 -Education Development Trust,2024,npq-leading-teaching-development,1022,122,34,FALSE,0,1 -Education Development Trust,2024,npq-senior-leadership,1023,123,35,FALSE,0,1 -Education Development Trust,2024,npq-headship,1024,124,36,FALSE,0,1 -Education Development Trust,2024,npq-executive-leadership,1025,125,37,FALSE,0,1 -Education Development Trust,2024,npq-leading-literacy,1026,126,38,FALSE,0,1 -Education Development Trust,2024,npq-early-years-leadership,1027,127,39,FALSE,0,1 -School-Led Network,2024,npq-leading-teaching,1028,128,40,FALSE,0,1 -School-Led Network,2024,npq-leading-behaviour-culture,1029,129,41,FALSE,0,1 -School-Led Network,2024,npq-leading-teaching-development,1030,130,42,FALSE,0,1 -School-Led Network,2024,npq-senior-leadership,1031,131,43,FALSE,0,1 -School-Led Network,2024,npq-headship,1032,132,44,FALSE,0,1 -School-Led Network,2024,npq-executive-leadership,1033,133,45,FALSE,0,1 -School-Led Network,2024,npq-leading-literacy,1034,134,46,FALSE,0,1 -School-Led Network,2024,npq-early-years-leadership,1035,135,47,FALSE,0,1 -LLSE,2024,npq-leading-teaching,1036,136,48,FALSE,0,1 -LLSE,2024,npq-leading-behaviour-culture,1037,137,49,FALSE,0,1 -LLSE,2024,npq-leading-teaching-development,1038,138,50,FALSE,0,1 -LLSE,2024,npq-senior-leadership,1039,139,51,FALSE,0,1 -LLSE,2024,npq-headship,1040,140,52,FALSE,0,1 -LLSE,2024,npq-executive-leadership,1041,141,53,FALSE,0,1 -LLSE,2024,npq-leading-literacy,1042,142,54,FALSE,0,1 -LLSE,2024,npq-early-years-leadership,1043,143,55,FALSE,0,1 -Teach First,2024,npq-leading-teaching,1044,144,56,FALSE,0,1 -Teach First,2024,npq-leading-behaviour-culture,1045,145,57,FALSE,0,1 -Teach First,2024,npq-leading-teaching-development,1046,146,58,FALSE,0,1 -Teach First,2024,npq-senior-leadership,1047,147,59,FALSE,0,1 -Teach First,2024,npq-headship,1048,148,60,FALSE,0,1 -Teach First,2024,npq-executive-leadership,1049,149,61,FALSE,0,1 -Teach First,2024,npq-leading-literacy,1050,150,62,FALSE,0,1 -Teach First,2024,npq-early-years-leadership,1051,151,63,FALSE,0,1 -Teach First,2024,npq-senco,156,895,19,FALSE,0,1 -Teacher Development Trust,2024,npq-leading-teaching,1052,152,64,FALSE,0,1 -Teacher Development Trust,2024,npq-leading-behaviour-culture,1053,153,65,FALSE,0,1 -Teacher Development Trust,2024,npq-leading-teaching-development,1054,154,66,FALSE,0,1 -Teacher Development Trust,2024,npq-senior-leadership,1055,155,67,FALSE,0,1 -Teacher Development Trust,2024,npq-headship,1056,156,68,FALSE,0,1 -Teacher Development Trust,2024,npq-executive-leadership,1057,157,69,FALSE,0,1 -Teacher Development Trust,2024,npq-leading-literacy,1058,158,70,FALSE,0,1 -Teacher Development Trust,2024,npq-early-years-leadership,1059,159,71,FALSE,0,1 -UCL Institute of Education,2024,npq-leading-teaching,1060,160,72,FALSE,0,1 -UCL Institute of Education,2024,npq-leading-behaviour-culture,1061,161,73,FALSE,0,1 -UCL Institute of Education,2024,npq-leading-teaching-development,1062,162,74,FALSE,0,1 -UCL Institute of Education,2024,npq-senior-leadership,1063,163,75,FALSE,0,1 -UCL Institute of Education,2024,npq-headship,1064,164,76,FALSE,0,1 -UCL Institute of Education,2024,npq-executive-leadership,1065,165,77,FALSE,0,1 -UCL Institute of Education,2024,npq-leading-literacy,1066,166,78,FALSE,0,1 -UCL Institute of Education,2024,npq-early-years-leadership,1067,167,79,FALSE,0,1 -UCL Institute of Education,2024,npq-senco,125,902,19,FALSE,0,1 -Ambition Institute,2024,npq-early-headship-coaching-offer,1068,168,0,FALSE,0,1 -Best Practice Network,2024,npq-early-headship-coaching-offer,1069,169,0,FALSE,0,1 -Church of England,2024,npq-early-headship-coaching-offer,1070,170,0,FALSE,0,1 -Education Development Trust,2024,npq-early-headship-coaching-offer,1071,171,0,FALSE,0,1 -School-Led Network,2024,npq-early-headship-coaching-offer,1072,172,0,FALSE,0,1 -LLSE,2024,npq-early-headship-coaching-offer,1073,173,0,FALSE,0,1 -Teach First,2024,npq-early-headship-coaching-offer,1074,174,0,FALSE,0,1 -Teacher Development Trust,2024,npq-early-headship-coaching-offer,1075,175,0,FALSE,0,1 -UCL Institute of Education,2024,npq-early-headship-coaching-offer,1076,176,0,FALSE,0,1 -National Institute of Teaching,2024,npq-leading-teaching,100,800,24,FALSE,0,1 -National Institute of Teaching,2024,npq-leading-behaviour-culture,101,801,24,FALSE,0,1 -National Institute of Teaching,2024,npq-leading-teaching-development,102,802,24,FALSE,0,1 -National Institute of Teaching,2024,npq-senior-leadership,103,803,24,FALSE,0,1 -National Institute of Teaching,2024,npq-headship,104,804,24,FALSE,0,1 -National Institute of Teaching,2024,npq-executive-leadership,105,805,24,FALSE,0,1 -National Institute of Teaching,2024,npq-leading-literacy,106,806,24,FALSE,0,1 -National Institute of Teaching,2024,npq-early-years-leadership,107,807,24,FALSE,0,1 -National Institute of Teaching,2024,npq-early-headship-coaching-offer,1000,800,0,FALSE,0,1 -National Institute of Teaching,2024,npq-senco,150,902,19,FALSE,0,1 -Ambition Institute,2024,npq-leading-primary-mathematics,1007,107,19,TRUE,,1 -Best Practice Network,2024,npq-leading-primary-mathematics,1013,113,25,TRUE,,1 -Church of England,2024,npq-leading-primary-mathematics,1019,119,31,TRUE,,1 -Education Development Trust,2024,npq-leading-primary-mathematics,1027,127,39,TRUE,,1 -School-Led Network,2024,npq-leading-primary-mathematics,1035,135,47,TRUE,,1 -LLSE,2024,npq-leading-primary-mathematics,1043,143,55,TRUE,,1 -Teach First,2024,npq-leading-primary-mathematics,1051,151,63,TRUE,,1 -Teacher Development Trust,2024,npq-leading-primary-mathematics,1059,159,71,TRUE,,1 -UCL Institute of Education,2024,npq-leading-primary-mathematics,1067,167,79,TRUE,,1 -National Institute of Teaching,2024,npq-leading-primary-mathematics,1000,800,0,TRUE,,1 \ No newline at end of file diff --git a/db/data/statements/statements.csv b/db/data/statements/statements.csv index 8b84977724..e1b4b637c8 100644 --- a/db/data/statements/statements.csv +++ b/db/data/statements/statements.csv @@ -135,155 +135,3 @@ ecf,February 2027,2024,2027-1-31,2027-2-25,false ecf,March 2027,2024,2027-2-28,2027-3-25,false ecf,April 2027,2024,2027-3-31,2027-4-25,true ecf,May 2027,2024,2027-4-30,2027-5-25,false - -npq,January 2022,2021,2021-12-25,2022-1-25,true -npq,February 2022,2021,2022-1-25,2022-2-25,false -npq,March 2022,2021,2022-2-25,2022-3-25,true -npq,April 2022,2021,2022-3-25,2022-4-25,false -npq,May 2022,2021,2022-4-25,2022-5-25,false -npq,June 2022,2021,2022-5-25,2022-6-25,false -npq,July 2022,2021,2022-6-25,2022-7-25,true -npq,August 2022,2021,2022-7-25,2022-8-25,false -npq,September 2022,2021,2022-9-25,2022-9-25,false -npq,October 2022,2021,2022-10-25,2022-10-25,true -npq,November 2022,2021,2022-11-25,2022-11-25,false -npq,December 2022,2021,2022-12-25,2022-12-25,true -npq,January 2023,2021,2022-12-25,2023-1-25,true -npq,February 2023,2021,2023-1-25,2023-2-25,false -npq,March 2023,2021,2023-2-25,2023-3-25,true -npq,April 2023,2021,2023-3-25,2023-4-25,false -npq,May 2023,2021,2023-4-25,2023-5-25,false -npq,June 2023,2021,2023-5-25,2023-6-25,false -npq,July 2023,2021,2023-6-25,2023-7-25,true -npq,August 2023,2021,2023-7-25,2023-8-25,false -npq,September 2023,2021,2023-9-25,2023-9-25,false -npq,October 2023,2021,2023-10-25,2023-10-25,true -npq,November 2023,2021,2023-11-25,2023-11-25,false -npq,December 2023,2021,2023-12-25,2023-12-25,true -npq,January 2024,2021,2023-12-25,2024-1-25,true -npq,February 2024,2021,2024-1-25,2024-2-25,false -npq,March 2024,2021,2024-2-25,2024-3-25,true -npq,April 2024,2021,2024-3-25,2024-4-25,false -npq,May 2024,2021,2024-4-25,2024-5-25,false -npq,June 2024,2021,2024-5-25,2024-6-25,false -npq,July 2024,2021,2024-6-25,2024-7-25,true -npq,August 2024,2021,2024-7-25,2024-8-25,false -npq,September 2024,2021,2024-9-25,2024-9-25,false -npq,October 2024,2021,2024-10-25,2024-10-25,true -npq,November 2024,2021,2024-11-25,2024-11-25,false -npq,December 2024,2021,2024-12-25,2024-12-25,true -npq,January 2025,2021,2024-12-20,2025-01-25,true - -npq,January 2023,2022,2022-12-25,2023-1-25,true -npq,February 2023,2022,2023-1-25,2023-2-25,false -npq,March 2023,2022,2023-2-25,2023-3-25,true -npq,April 2023,2022,2023-3-25,2023-4-25,false -npq,May 2023,2022,2023-4-25,2023-5-25,false -npq,June 2023,2022,2023-5-25,2023-6-25,false -npq,July 2023,2022,2023-6-25,2023-7-25,true -npq,August 2023,2022,2023-7-25,2023-8-25,false -npq,September 2023,2022,2023-9-25,2023-9-25,false -npq,October 2023,2022,2023-10-25,2023-10-25,true -npq,November 2023,2022,2023-11-25,2023-11-25,false -npq,December 2023,2022,2023-12-25,2023-12-25,true -npq,January 2024,2022,2023-12-25,2024-1-25,true -npq,February 2024,2022,2024-1-25,2024-2-25,false -npq,March 2024,2022,2024-2-25,2024-3-25,true -npq,April 2024,2022,2024-3-25,2024-4-25,false -npq,May 2024,2022,2024-4-25,2024-5-25,false -npq,June 2024,2022,2024-5-25,2024-6-25,false -npq,July 2024,2022,2024-6-25,2024-7-25,true -npq,August 2024,2022,2024-7-25,2024-8-25,false -npq,September 2024,2022,2024-9-25,2024-9-25,false -npq,October 2024,2022,2024-10-25,2024-10-25,true -npq,November 2024,2022,2024-11-25,2024-11-25,false -npq,December 2024,2022,2024-12-25,2024-12-25,true -npq,January 2025,2022,2024-12-25,2025-1-25,true -npq,February 2025,2022,2025-1-25,2025-2-25,false -npq,March 2025,2022,2025-2-25,2025-3-25,true -npq,April 2025,2022,2025-3-25,2025-4-25,false -npq,May 2025,2022,2025-4-25,2025-5-25,false -npq,June 2025,2022,2025-5-25,2025-6-25,false -npq,July 2025,2022,2025-6-25,2025-7-25,true -npq,August 2025,2022,2025-7-25,2025-8-25,false -npq,September 2025,2022,2025-9-25,2025-9-25,false -npq,October 2025,2022,2025-10-25,2025-10-25,true -npq,November 2025,2022,2025-11-25,2025-11-25,false -npq,December 2025,2022,2025-12-25,2025-12-25,true -npq,January 2026,2022,2025-12-19,2026-01-25,true - -npq,March 2023,2023,2023-3-10,2023-4-25,true -npq,January 2024,2023,2023-12-25,2024-1-25,false -npq,February 2024,2023,2024-1-25,2024-2-25,true -npq,March 2024,2023,2024-2-25,2024-3-25,true -npq,April 2024,2023,2024-3-25,2024-4-25,false -npq,May 2024,2023,2024-4-25,2024-5-25,false -npq,June 2024,2023,2024-5-25,2024-6-25,true -npq,July 2024,2023,2024-6-25,2024-7-25,false -npq,August 2024,2023,2024-7-25,2024-8-25,true -npq,September 2024,2023,2024-8-25,2024-9-25,false -npq,October 2024,2023,2024-9-25,2024-10-25,false -npq,November 2024,2023,2024-10-25,2024-11-25,false -npq,December 2024,2023,2024-11-25,2024-12-25,true -npq,January 2025,2023,2024-12-25,2025-1-25,true -npq,February 2025,2023,2025-1-25,2025-2-25,false -npq,March 2025,2023,2025-2-25,2025-3-25,true -npq,April 2025,2023,2025-3-25,2025-4-25,false -npq,May 2025,2023,2025-4-25,2025-5-25,false -npq,June 2025,2023,2025-5-25,2025-6-25,false -npq,July 2025,2023,2025-6-25,2025-7-25,true -npq,August 2025,2023,2025-7-25,2025-8-25,false -npq,September 2025,2023,2025-8-25,2025-9-25,false -npq,October 2025,2023,2025-9-25,2025-10-25,true -npq,November 2025,2023,2025-10-25,2025-11-25,false -npq,December 2025,2023,2025-11-25,2025-12-25,true -npq,January 2026,2023,2025-12-25,2026-1-25,true -npq,February 2026,2023,2026-1-25,2026-2-25,false -npq,March 2026,2023,2026-2-25,2026-3-25,true -npq,April 2026,2023,2026-3-25,2026-4-25,false -npq,May 2026,2023,2026-4-25,2026-5-25,false -npq,June 2026,2023,2026-5-25,2026-6-25,false -npq,July 2026,2023,2026-6-25,2026-7-25,true -npq,August 2026,2023,2026-7-25,2026-8-25,false -npq,September 2026,2023,2026-8-25,2026-9-25,false -npq,October 2026,2023,2026-9-25,2026-10-25,true -npq,November 2026,2023,2026-10-25,2026-11-25,false -npq,December 2026,2023,2026-11-25,2026-12-25,true - -npq,March 2024,2024,2024-3-10,2024-4-25,true -npq,January 2025,2024,2024-12-25,2025-1-25,false -npq,February 2025,2024,2025-1-25,2025-2-25,true -npq,March 2025,2024,2025-2-25,2025-3-25,true -npq,April 2025,2024,2025-3-25,2025-4-25,false -npq,May 2025,2024,2025-4-25,2025-5-25,false -npq,June 2025,2024,2025-5-25,2025-6-25,true -npq,July 2025,2024,2025-6-25,2025-7-25,false -npq,August 2025,2024,2025-7-25,2025-8-25,true -npq,September 2025,2024,2025-8-25,2025-9-25,false -npq,October 2025,2024,2025-9-25,2025-10-25,false -npq,November 2025,2024,2025-10-25,2025-11-25,false -npq,December 2025,2024,2025-11-25,2025-12-25,true -npq,January 2026,2024,2025-12-25,2026-1-25,true -npq,February 2026,2024,2026-1-25,2026-2-25,false -npq,March 2026,2024,2026-2-25,2026-3-25,true -npq,April 2026,2024,2026-3-25,2026-4-25,false -npq,May 2026,2024,2026-4-25,2026-5-25,false -npq,June 2026,2024,2026-5-25,2026-6-25,false -npq,July 2026,2024,2026-6-25,2026-7-25,true -npq,August 2026,2024,2026-7-25,2026-8-25,false -npq,September 2026,2024,2026-8-25,2026-9-25,false -npq,October 2026,2024,2026-9-25,2026-10-25,true -npq,November 2026,2024,2026-10-25,2026-11-25,false -npq,December 2026,2024,2026-11-25,2026-12-25,true -npq,January 2027,2024,2026-12-25,2027-1-25,true -npq,February 2027,2024,2027-1-25,2027-2-25,false -npq,March 2027,2024,2027-2-25,2027-3-25,true -npq,April 2027,2024,2027-3-25,2027-4-25,false -npq,May 2027,2024,2027-4-25,2027-5-25,false -npq,June 2027,2024,2027-5-25,2027-6-25,false -npq,July 2027,2024,2027-6-25,2027-7-25,true -npq,August 2027,2024,2027-7-25,2027-8-25,false -npq,September 2027,2024,2027-8-25,2027-9-25,false -npq,October 2027,2024,2027-9-25,2027-10-25,true -npq,November 2027,2024,2027-10-25,2027-11-25,false -npq,December 2027,2024,2027-11-25,2027-12-25,true diff --git a/db/legacy_seeds/initial_seed.rb b/db/legacy_seeds/initial_seed.rb index a45cbd0495..d0046ee02e 100644 --- a/db/legacy_seeds/initial_seed.rb +++ b/db/legacy_seeds/initial_seed.rb @@ -40,39 +40,7 @@ .tap { |pp| pp.html = Rails.root.join("data/privacy_policy.html").read } .save! -[ - { name: "Ambition Institute", id: "9e35e998-c63b-4136-89c4-e9e18ddde0ea" }, - { name: "Best Practice Network", id: "57ba9e86-559f-4ff4-a6d2-4610c7259b67" }, - { name: "Church of England", id: "79cb41ca-cb6d-405c-b52c-b6f7c752388d" }, - { name: "Education Development Trust", id: "21e61f53-9b34-4384-a8f5-d8224dbf946d" }, - { name: "School-Led Network", id: "bc5e4e37-1d64-4149-a06b-ad10d3c55fd0" }, - { name: "LLSE", id: "230e67c0-071a-4a48-9673-9d043d456281" }, - { name: "Teacher Development Trust", id: "30fd937e-b93c-4f81-8fff-3c27544193f1" }, - { name: "Teach First", id: "a02ae582-f939-462f-90bc-cebf20fa8473" }, - { name: "UCL Institute of Education", id: "ef687b3d-c1c0-4566-a295-16d6fa5d0fa7" }, - { name: "National Institute of Teaching", id: "3ec607f2-7a3a-421f-9f1a-9aca8a634aeb" }, -].each do |hash| - NPQLeadProvider.find_or_create_by!(name: hash[:name], id: hash[:id]) -end - -[ - { name: "NPQ Leading Teaching (NPQLT)", id: "15c52ed8-06b5-426e-81a2-c2664978a0dc", identifier: "npq-leading-teaching" }, - { name: "NPQ Leading Behaviour and Culture (NPQLBC)", id: "7d47a0a6-fa74-4587-92cc-cd1e4548a2e5", identifier: "npq-leading-behaviour-culture" }, - { name: "NPQ Leading Teacher Development (NPQLTD)", id: "29fee78b-30ce-4b93-ba21-80be2fde286f", identifier: "npq-leading-teaching-development" }, - { name: "NPQ for Senior Leadership (NPQSL)", id: "a42736ad-3d0b-401d-aebe-354ef4c193ec", identifier: "npq-senior-leadership" }, - { name: "NPQ for Headship (NPQH)", id: "0f7d6578-a12c-4498-92a0-2ee0f18e0768", identifier: "npq-headship" }, - { name: "NPQ for Executive Leadership (NPQEL)", id: "aef853f2-9b48-4b6a-9d2a-91b295f5ca9a", identifier: "npq-executive-leadership" }, - { name: "Additional Support Offer for new headteachers", id: "7fbefdd4-dd2d-4a4f-8995-d59e525124b7", identifier: "npq-additional-support-offer" }, - { name: "The Early Headship Coaching Offer", id: "0222d1a8-a8e1-42e3-a040-2c585f6c194a", identifier: "npq-early-headship-coaching-offer" }, - { name: "NPQ Early Years Leadership (NPQEYL)", id: "66dff4af-a518-498f-9042-36a41f9e8aa7", identifier: "npq-early-years-leadership" }, - { name: "NPQ Leading Literacy (NPQLL)", id: "829fcd45-e39d-49a9-b309-26d26debfa90", identifier: "npq-leading-literacy" }, - { name: "NPQ for Leading Primary Mathematics (NPQLPM)", id: "7866f853-064f-44b4-9287-20b9993452d6", identifier: "npq-leading-primary-mathematics" }, - { name: "NPQ for Senco (NPQSENCO)", id: "84b7ffd9-c726-4915-bcac-05901d9629b8", identifier: "npq-senco" }, -].each do |hash| - NPQCourse.find_or_create_by!(name: hash[:name], id: hash[:id], identifier: hash[:identifier]) -end - -all_provider_names = (LeadProvider.pluck(:name) + NPQLeadProvider.pluck(:name)).uniq +all_provider_names = LeadProvider.distinct.pluck(:name) all_provider_names.each do |name| CpdLeadProvider.find_or_create_by!(name:) @@ -81,7 +49,3 @@ LeadProvider.find_each do |lp| lp.update!(cpd_lead_provider: CpdLeadProvider.find_by(name: lp.name)) end - -NPQLeadProvider.find_each do |lp| - lp.update!(cpd_lead_provider: CpdLeadProvider.find_by(name: lp.name)) -end diff --git a/db/migrate/20220530141418_add_national_institute_of_teaching_npq_lead_provider.rb b/db/migrate/20220530141418_add_national_institute_of_teaching_npq_lead_provider.rb index 03eeb05737..2655f89c23 100644 --- a/db/migrate/20220530141418_add_national_institute_of_teaching_npq_lead_provider.rb +++ b/db/migrate/20220530141418_add_national_institute_of_teaching_npq_lead_provider.rb @@ -2,12 +2,14 @@ class AddNationalInstituteOfTeachingNPQLeadProvider < ActiveRecord::Migration[6.1] def change - niot_name = "National Institute of Teaching" - niot_id = "3ec607f2-7a3a-421f-9f1a-9aca8a634aeb" - vat_chargeable = false + if defined?(NPQLeadProvider) + niot_name = "National Institute of Teaching" + niot_id = "3ec607f2-7a3a-421f-9f1a-9aca8a634aeb" + vat_chargeable = false - npq_lead_provider = NPQLeadProvider.find_or_create_by!(name: niot_name, id: niot_id, vat_chargeable:) - cpd_lead_provider = CpdLeadProvider.find_or_create_by!(name: niot_name) - npq_lead_provider.update!(cpd_lead_provider:) + npq_lead_provider = NPQLeadProvider.find_or_create_by!(name: niot_name, id: niot_id, vat_chargeable:) + cpd_lead_provider = CpdLeadProvider.find_or_create_by!(name: niot_name) + npq_lead_provider.update!(cpd_lead_provider:) + end end end diff --git a/db/migrate/20230821154316_update_leadership_learning_south_east_lead_provider_name_to_llse.rb b/db/migrate/20230821154316_update_leadership_learning_south_east_lead_provider_name_to_llse.rb index 6ba9a82e2b..c6ce0991c1 100644 --- a/db/migrate/20230821154316_update_leadership_learning_south_east_lead_provider_name_to_llse.rb +++ b/db/migrate/20230821154316_update_leadership_learning_south_east_lead_provider_name_to_llse.rb @@ -2,12 +2,12 @@ class UpdateLeadershipLearningSouthEastLeadProviderNameToLlse < ActiveRecord::Migration[7.0] def up - NPQLeadProvider.where(name: "Leadership Learning South East").update_all(name: "LLSE") + NPQLeadProvider.where(name: "Leadership Learning South East").update_all(name: "LLSE") if defined?(NPQLeadProvider) CpdLeadProvider.where(name: "Leadership Learning South East").update_all(name: "LLSE") end def down - NPQLeadProvider.where(name: "LLSE").update_all(name: "Leadership Learning South East") + NPQLeadProvider.where(name: "LLSE").update_all(name: "Leadership Learning South East") if defined?(NPQLeadProvider) CpdLeadProvider.where(name: "LLSE").update_all(name: "Leadership Learning South East") end end diff --git a/db/migrate/20241217132754_drop_table_npq_contracts.rb b/db/migrate/20241217132754_drop_table_npq_contracts.rb new file mode 100644 index 0000000000..8588ba02e5 --- /dev/null +++ b/db/migrate/20241217132754_drop_table_npq_contracts.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +class DropTableNPQContracts < ActiveRecord::Migration[7.1] + def up + drop_table :npq_contracts + end + + def down + create_table :npq_contracts, id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.jsonb :raw + t.string :version, default: "0.0.1" + t.uuid :npq_lead_provider_id, null: false + t.integer :recruitment_target + t.string :course_identifier + t.integer :service_fee_installments + t.integer :service_fee_percentage, default: 40 + t.decimal :per_participant + t.integer :number_of_payment_periods + t.integer :output_payment_percentage, default: 60 + t.datetime :created_at, null: false + t.datetime :updated_at, null: false + t.uuid :cohort_id, null: false + t.decimal :monthly_service_fee, default: "0.0" + t.decimal :targeted_delivery_funding_per_participant, default: "100.0" + t.boolean :special_course, default: false, null: false + t.integer :funding_cap + + t.index :cohort_id, name: "index_npq_contracts_on_cohort_id" + t.index :npq_lead_provider_id, name: "index_npq_contracts_on_npq_lead_provider_id" + end + end +end diff --git a/db/migrate/20241217150749_drop_table_npq_application_exports.rb b/db/migrate/20241217150749_drop_table_npq_application_exports.rb new file mode 100644 index 0000000000..0e7c04d510 --- /dev/null +++ b/db/migrate/20241217150749_drop_table_npq_application_exports.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class DropTableNPQApplicationExports < ActiveRecord::Migration[7.1] + def up + drop_table :npq_application_exports + end + + def down + create_table :npq_application_exports, id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.date :start_date, null: false + t.date :end_date, null: false + t.uuid :user_id, null: false + t.datetime :created_at, null: false + t.datetime :updated_at, null: false + + t.index :user_id, name: "index_npq_application_exports_on_user_id" + end + end +end diff --git a/db/migrate/20241217150952_drop_table_npq_applications.rb b/db/migrate/20241217150952_drop_table_npq_applications.rb new file mode 100644 index 0000000000..272616e298 --- /dev/null +++ b/db/migrate/20241217150952_drop_table_npq_applications.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +class DropTableNPQApplications < ActiveRecord::Migration[7.1] + def up + drop_table :npq_applications + end + + def down + create_table :npq_applications, id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.uuid :npq_lead_provider_id, null: false + t.uuid :npq_course_id, null: false + t.date :date_of_birth + t.text :teacher_reference_number + t.boolean :teacher_reference_number_verified, default: false + t.text :school_urn + t.text :headteacher_status + t.boolean :active_alert, default: false + t.boolean :eligible_for_funding, default: false, null: false + t.text :funding_choice + t.text :nino + t.text :lead_provider_approval_status, default: "pending", null: false + t.text :school_ukprn + t.datetime :created_at, null: false + t.datetime :updated_at, null: false + t.uuid :participant_identity_id + t.boolean :works_in_school + t.string :employer_name + t.string :employment_role + t.boolean :targeted_support_funding_eligibility, default: false + t.uuid :cohort_id + t.boolean :targeted_delivery_funding_eligibility, default: false + t.boolean :works_in_nursery + t.boolean :works_in_childcare + t.string :kind_of_nursery + t.string :private_childcare_provider_urn + t.string :funding_eligiblity_status_code + t.text :teacher_catchment + t.text :teacher_catchment_country + t.string :employment_type + t.string :teacher_catchment_iso_country_code, limit: 3 + t.string :itt_provider + t.boolean :lead_mentor, default: false + t.string :notes + t.boolean :primary_establishment, default: false + t.integer :number_of_pupils, default: 0 + t.boolean :tsf_primary_eligibility, default: false + t.boolean :tsf_primary_plus_eligibility, default: false + t.uuid :eligible_for_funding_updated_by_id + t.datetime :eligible_for_funding_updated_at + t.boolean :funded_place + t.string :referred_by_return_to_teaching_adviser + + t.index :cohort_id, name: "index_npq_applications_on_cohort_id" + t.index :npq_course_id, name: "index_npq_applications_on_npq_course_id" + t.index :npq_lead_provider_id, name: "index_npq_applications_on_npq_lead_provider_id" + t.index :participant_identity_id, name: "index_npq_applications_on_participant_identity_id" + end + end +end diff --git a/db/migrate/20241218162526_drop_table_npq_courses.rb b/db/migrate/20241218162526_drop_table_npq_courses.rb new file mode 100644 index 0000000000..7aaca91f18 --- /dev/null +++ b/db/migrate/20241218162526_drop_table_npq_courses.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class DropTableNPQCourses < ActiveRecord::Migration[7.1] + def up + if foreign_key_exists?(:participant_profiles, :npq_courses) + remove_foreign_key :participant_profiles, :npq_courses + end + + drop_table :npq_courses + end + + def down + create_table :npq_courses, id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.text :name, null: false + t.datetime :created_at, null: false + t.datetime :updated_at, null: false + t.text :identifier + end + + add_foreign_key :participant_profiles, :npq_courses + end +end diff --git a/db/migrate/20241218170200_drop_table_npq_lead_providers.rb b/db/migrate/20241218170200_drop_table_npq_lead_providers.rb new file mode 100644 index 0000000000..2ebb35fcf0 --- /dev/null +++ b/db/migrate/20241218170200_drop_table_npq_lead_providers.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class DropTableNPQLeadProviders < ActiveRecord::Migration[7.1] + def up + if foreign_key_exists?(:npq_lead_providers, :cpd_lead_providers) + remove_foreign_key :npq_lead_providers, :cpd_lead_providers + end + + drop_table :npq_lead_providers + end + + def down + create_table :npq_lead_providers, id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.text :name, null: false + t.datetime :created_at, null: false + t.datetime :updated_at, null: false + t.uuid :cpd_lead_provider_id + t.boolean :vat_chargeable, default: true + + t.index :cpd_lead_provider_id, name: "index_npq_lead_providers_on_cpd_lead_provider_id" + end + + add_foreign_key :npq_lead_providers, :cpd_lead_providers + end +end diff --git a/db/new_seeds/base/add_contracts.rb b/db/new_seeds/base/add_contracts.rb index 91abb57fbe..b8405e177e 100644 --- a/db/new_seeds/base/add_contracts.rb +++ b/db/new_seeds/base/add_contracts.rb @@ -1,7 +1,3 @@ # frozen_string_literal: true -Importers::CreateNPQContract.new(path_to_csv: Rails.root.join("db/data/npq_contracts/fake-2021.csv")).call -Importers::CreateNPQContract.new(path_to_csv: Rails.root.join("db/data/npq_contracts/fake-2022.csv")).call -Importers::CreateNPQContract.new(path_to_csv: Rails.root.join("db/data/npq_contracts/fake-2023.csv")).call -Importers::CreateNPQContract.new(path_to_csv: Rails.root.join("db/data/npq_contracts/fake-2024.csv")).call Importers::CreateCallOffContract.new.call diff --git a/db/new_seeds/base/add_lead_providers_and_cips.rb b/db/new_seeds/base/add_lead_providers_and_cips.rb index 4990a857bf..763be98f2f 100644 --- a/db/new_seeds/base/add_lead_providers_and_cips.rb +++ b/db/new_seeds/base/add_lead_providers_and_cips.rb @@ -37,13 +37,9 @@ ambition = FactoryBot.create(:seed_cpd_lead_provider, name: "Ambition Institute") best_practice_network = FactoryBot.create(:seed_cpd_lead_provider, name: "Best Practice Network") capita = FactoryBot.create(:seed_cpd_lead_provider, name: "Capita") -church_of_england = FactoryBot.create(:seed_cpd_lead_provider, name: "Church of England") education_development_trust = FactoryBot.create(:seed_cpd_lead_provider, name: "Education Development Trust") -llse = FactoryBot.create(:seed_cpd_lead_provider, name: "LLSE") -national_institute_of_teaching = FactoryBot.create(:seed_cpd_lead_provider, name: "National Institute of Teaching") -school_led_network = FactoryBot.create(:seed_cpd_lead_provider, name: "School-Led Network") +FactoryBot.create(:seed_cpd_lead_provider, name: "National Institute of Teaching") teach_first = FactoryBot.create(:seed_cpd_lead_provider, name: "Teach First") -teacher_development_trust = FactoryBot.create(:seed_cpd_lead_provider, name: "Teacher Development Trust") ucl_institute_of_education = FactoryBot.create(:seed_cpd_lead_provider, name: "UCL Institute of Education") # now create the relevant core_induction_programmes, lead providers and set up the relationships @@ -68,22 +64,3 @@ end end end - -# now for the NPQ lead providers, we're using some hardcoded ids here so (i assume) -# there's consistency for people testing various versions of the app across staging -# and review app environments; these uuids match prod - -{ - ambition => "9e35e998-c63b-4136-89c4-e9e18ddde0ea", - best_practice_network => "57ba9e86-559f-4ff4-a6d2-4610c7259b67", - church_of_england => "79cb41ca-cb6d-405c-b52c-b6f7c752388d", - education_development_trust => "21e61f53-9b34-4384-a8f5-d8224dbf946d", - llse => "230e67c0-071a-4a48-9673-9d043d456281", - national_institute_of_teaching => "3ec607f2-7a3a-421f-9f1a-9aca8a634aeb", - school_led_network => "bc5e4e37-1d64-4149-a06b-ad10d3c55fd0", - teach_first => "a02ae582-f939-462f-90bc-cebf20fa8473", - teacher_development_trust => "30fd937e-b93c-4f81-8fff-3c27544193f1", - ucl_institute_of_education => "ef687b3d-c1c0-4566-a295-16d6fa5d0fa7", -}.each do |cpd_lead_provider, id| - FactoryBot.create(:seed_npq_lead_provider, cpd_lead_provider:, id:, name: cpd_lead_provider.name) -end diff --git a/db/new_seeds/base/add_npq_courses.rb b/db/new_seeds/base/add_npq_courses.rb deleted file mode 100644 index 012d8425f4..0000000000 --- a/db/new_seeds/base/add_npq_courses.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true - -[ - { - id: "15c52ed8-06b5-426e-81a2-c2664978a0dc", - name: "NPQ Leading Teaching (NPQLT)", - identifier: "npq-leading-teaching", - }, - { - id: "7d47a0a6-fa74-4587-92cc-cd1e4548a2e5", - name: "NPQ Leading Behaviour and Culture (NPQLBC)", - identifier: "npq-leading-behaviour-culture", - }, - { - id: "29fee78b-30ce-4b93-ba21-80be2fde286f", - name: "NPQ Leading Teacher Development (NPQLTD)", - identifier: "npq-leading-teaching-development", - }, - { - id: "a42736ad-3d0b-401d-aebe-354ef4c193ec", - name: "NPQ for Senior Leadership (NPQSL)", - identifier: "npq-senior-leadership", - }, - { - id: "0f7d6578-a12c-4498-92a0-2ee0f18e0768", - name: "NPQ for Headship (NPQH)", - identifier: "npq-headship", - }, - { - id: "aef853f2-9b48-4b6a-9d2a-91b295f5ca9a", - name: "NPQ for Executive Leadership (NPQEL)", - identifier: "npq-executive-leadership", - }, - { - id: "7fbefdd4-dd2d-4a4f-8995-d59e525124b7", - name: "Additional Support Offer for new headteachers", - identifier: "npq-additional-support-offer", - }, - - { - id: "0222d1a8-a8e1-42e3-a040-2c585f6c194a", - name: "The Early Headship Coaching Offer", - identifier: "npq-early-headship-coaching-offer", - }, - { - id: "66dff4af-a518-498f-9042-36a41f9e8aa7", - name: "NPQ Early Years Leadership (NPQEYL)", - identifier: "npq-early-years-leadership", - }, - { - id: "829fcd45-e39d-49a9-b309-26d26debfa90", - name: "NPQ Leading Literacy (NPQLL)", - identifier: "npq-leading-literacy", - }, - { - id: "7866f853-064f-44b4-9287-20b9993452d6", - name: "NPQ Leading Primary Mathematics (NPQLPM)", - identifier: "npq-leading-primary-mathematics", - }, - { - id: "84b7ffd9-c726-4915-bcac-05901d9629b8", - name: "NPQ for Senco (NPQSENCO)", - identifier: "npq-senco", - }, -].each do |hash| - FactoryBot.create(:seed_npq_course, id: hash[:id], name: hash[:name], identifier: hash[:identifier]) -end diff --git a/db/new_seeds/base/add_npq_registrations.rb b/db/new_seeds/base/add_npq_registrations.rb deleted file mode 100644 index 9aa086ce57..0000000000 --- a/db/new_seeds/base/add_npq_registrations.rb +++ /dev/null @@ -1,107 +0,0 @@ -# frozen_string_literal: true - -npq_lead_providers = NPQLeadProvider.all -[Cohort.previous, Cohort.current, Cohort.next].map do |cohort| - # Create pending NPQ applications - seed_quantity(:npq_applications_pending).times do - NewSeeds::Scenarios::NPQ - .new( - lead_provider: npq_lead_providers.sample, - cohort:, - ) - .build - end - - # Create accepted NPQ applications with participant profiles - # and a declaration - seed_quantity(:npq_application_with_declarations).times do - NewSeeds::Scenarios::NPQ - .new( - lead_provider: npq_lead_providers.sample, - cohort:, - ) - .build - .accept_application - .add_declaration - end - - # Create rejected NPQ applications - seed_quantity(:npq_applications_rejected).times do - NewSeeds::Scenarios::NPQ - .new( - lead_provider: npq_lead_providers.sample, - cohort:, - ) - .build - .reject_application - end - - # Create pending NPQ applications to ASO NPQ course - seed_quantity(:npq_applications_aso).times do - NewSeeds::Scenarios::NPQ - .new( - lead_provider: npq_lead_providers.sample, - npq_course: NPQCourse.find_by(identifier: "npq-additional-support-offer"), - cohort:, - ) - .build - end - - # Create pending NPQ applications to EHCO NPQ course - seed_quantity(:npq_applications_ehco).times do - NewSeeds::Scenarios::NPQ - .new( - lead_provider: npq_lead_providers.sample, - npq_course: NPQCourse.find_by(identifier: "npq-early-headship-coaching-offer"), - cohort:, - ) - .build - end - - # Create NPQLeadership applications with participant profile and declaration - seed_quantity(:npq_applications_leadership).times do - NewSeeds::Scenarios::NPQ - .new( - lead_provider: npq_lead_providers.sample, - npq_course: NPQCourse.find_by(identifier: Finance::Schedule::NPQLeadership::IDENTIFIERS.sample), - cohort:, - ) - .build - .accept_application - end - - # Create NPQSpecialist applications with participant profile and declaration - seed_quantity(:npq_applications_specialist).times do - NewSeeds::Scenarios::NPQ - .new( - lead_provider: npq_lead_providers.sample, - npq_course: NPQCourse.find_by(identifier: Finance::Schedule::NPQSpecialist::IDENTIFIERS.sample), - cohort:, - ) - .build - .accept_application - end - - # Create NPQEhco applications with participant profile and declaration - seed_quantity(:npq_applications_ehco).times do - NewSeeds::Scenarios::NPQ - .new( - lead_provider: npq_lead_providers.sample, - npq_course: NPQCourse.find_by(identifier: Finance::Schedule::NPQEhco::IDENTIFIERS.sample), - cohort:, - ) - .build - .accept_application - end - - # Create edge case NPQ applications - seed_quantity(:npq_applications_edge_cases).times do - NewSeeds::Scenarios::NPQ - .new( - lead_provider: npq_lead_providers.sample, - cohort:, - ) - .build - .edge_cases - end -end diff --git a/db/new_seeds/run.rb b/db/new_seeds/run.rb index 6bd64344f8..74eb804433 100644 --- a/db/new_seeds/run.rb +++ b/db/new_seeds/run.rb @@ -27,13 +27,11 @@ def seed_quantity(key) "add_schedules.rb", "add_privacy_policy.rb", "add_lead_providers_and_cips.rb", - "add_npq_courses.rb", "add_contracts.rb", "add_statements.rb", "add_appropriate_bodies.rb", "add_schools_and_local_authorities.rb", "add_users.rb", - "add_npq_registrations.rb", "add_transfer_scenarios.rb", "add_mentor_scenarios.rb", "add_api_tokens.rb", diff --git a/db/new_seeds/scenarios/npq.rb b/db/new_seeds/scenarios/npq.rb deleted file mode 100644 index 2751ee68b2..0000000000 --- a/db/new_seeds/scenarios/npq.rb +++ /dev/null @@ -1,115 +0,0 @@ -# frozen_string_literal: true - -module NewSeeds - module Scenarios - class NPQ - attr_reader :user, :application, :participant_identity, :npq_lead_provider, :npq_course, :cohort, :declaration - - def initialize(user: nil, lead_provider: nil, npq_course: nil, cohort: nil) - @supplied_user = user - @supplied_lead_provider = lead_provider - @supplied_npq_course = npq_course - @supplied_cohort = cohort - end - - def build - @user = @supplied_user || FactoryBot.create(:seed_user, :valid) - @npq_lead_provider = @supplied_lead_provider || FactoryBot.create(:seed_npq_lead_provider, :valid) - @npq_course = @supplied_npq_course || FactoryBot.create(:seed_npq_course, :valid) - @cohort = @supplied_cohort || Cohort.current || FactoryBot.create(:seed_cohort, :valid) - - @participant_identity = user&.participant_identities&.sample || - FactoryBot.create(:seed_participant_identity, user:) - - @application = FactoryBot.create( - :seed_npq_application, - :valid, - participant_identity:, - npq_lead_provider:, - npq_course:, - cohort:, - ) - - self - end - - def accept_application - raise(StandardError, "no npq application, call #build first") if application.blank? - - FactoryBot.create(:seed_npq_participant_profile_state, :valid, participant_profile:) - - participant_profile.teacher_profile.update!(trn: application.teacher_reference_number) - application.update!(lead_provider_approval_status: "accepted") - - self - end - - def participant_profile - @participant_profile ||= - FactoryBot.create( - :seed_npq_participant_profile, - user:, - participant_identity:, - npq_application: application, - npq_course:, - school_urn: application.school_urn, - school_ukprn: application.school_ukprn, - schedule: NPQCourse.schedule_for(npq_course:, cohort:), - # it turns out that we don't find the NPQ application via the participant identity but - # instead by the `has_one` on participant profile. The id of the NPQ application needs - # to match the corresponding participant profile's id. - id: application.id, - ) - end - - def reject_application - raise(StandardError, "no npq application, call #build first") if application.blank? - - application.update!(lead_provider_approval_status: "rejected") - - self - end - - def edge_cases - employment_type = %w[hospital_school - other - local_authority_virtual_school - young_offender_institution - local_authority_supply_teacher] - employment_role = ["Head of Education", - "Vocational Leader", - "Online Teacher", - "Education manager", - "Tutor of English"] - employer_name = ["Learning Partnership West Independent School", - "Salford County Council", - "Havant and South Downs College", - "Independent Special School", - "Feltham Young Offenders Institution"] - application.update!(works_in_school: false, - works_in_childcare: false, - employment_type: employment_type.sample, - employment_role: employment_role.sample, - employer_name: employer_name.sample, - eligible_for_funding: false, - funding_eligiblity_status_code: "no_institution", - created_at: rand(60.years.ago.to_date..23.years.ago.to_date)) - end - - def add_declaration - raise(StandardError, "no participant_profile, call #accept_application first") if participant_profile.blank? - - @declaration = FactoryBot.create( - :seed_npq_participant_declaration, - user:, - participant_profile:, - course_identifier: npq_course.identifier, - cpd_lead_provider: npq_lead_provider.cpd_lead_provider, - cohort: participant_profile.schedule.cohort, - ) - - self - end - end - end -end diff --git a/db/schema.rb b/db/schema.rb index 8c1c1ba1e0..b64b14aea6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -691,102 +691,6 @@ t.index ["token"], name: "index_nomination_emails_on_token", unique: true end - create_table "npq_application_exports", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.date "start_date", null: false - t.date "end_date", null: false - t.uuid "user_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["user_id"], name: "index_npq_application_exports_on_user_id" - end - - create_table "npq_applications", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.uuid "npq_lead_provider_id", null: false - t.uuid "npq_course_id", null: false - t.date "date_of_birth" - t.text "teacher_reference_number" - t.boolean "teacher_reference_number_verified", default: false - t.text "school_urn" - t.text "headteacher_status" - t.boolean "active_alert", default: false - t.boolean "eligible_for_funding", default: false, null: false - t.text "funding_choice" - t.text "nino" - t.text "lead_provider_approval_status", default: "pending", null: false - t.text "school_ukprn" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.uuid "participant_identity_id" - t.boolean "works_in_school" - t.string "employer_name" - t.string "employment_role" - t.boolean "targeted_support_funding_eligibility", default: false - t.uuid "cohort_id" - t.boolean "targeted_delivery_funding_eligibility", default: false - t.boolean "works_in_nursery" - t.boolean "works_in_childcare" - t.string "kind_of_nursery" - t.string "private_childcare_provider_urn" - t.string "funding_eligiblity_status_code" - t.text "teacher_catchment" - t.text "teacher_catchment_country" - t.string "employment_type" - t.string "teacher_catchment_iso_country_code", limit: 3 - t.string "itt_provider" - t.boolean "lead_mentor", default: false - t.string "notes" - t.boolean "primary_establishment", default: false - t.integer "number_of_pupils", default: 0 - t.boolean "tsf_primary_eligibility", default: false - t.boolean "tsf_primary_plus_eligibility", default: false - t.uuid "eligible_for_funding_updated_by_id" - t.datetime "eligible_for_funding_updated_at" - t.boolean "funded_place" - t.string "referred_by_return_to_teaching_adviser" - t.index ["cohort_id"], name: "index_npq_applications_on_cohort_id" - t.index ["npq_course_id"], name: "index_npq_applications_on_npq_course_id" - t.index ["npq_lead_provider_id"], name: "index_npq_applications_on_npq_lead_provider_id" - t.index ["participant_identity_id"], name: "index_npq_applications_on_participant_identity_id" - end - - create_table "npq_contracts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.jsonb "raw" - t.string "version", default: "0.0.1" - t.uuid "npq_lead_provider_id", null: false - t.integer "recruitment_target" - t.string "course_identifier" - t.integer "service_fee_installments" - t.integer "service_fee_percentage", default: 40 - t.decimal "per_participant" - t.integer "number_of_payment_periods" - t.integer "output_payment_percentage", default: 60 - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.uuid "cohort_id", null: false - t.decimal "monthly_service_fee", default: "0.0" - t.decimal "targeted_delivery_funding_per_participant", default: "100.0" - t.boolean "special_course", default: false, null: false - t.integer "funding_cap" - t.index ["cohort_id"], name: "index_npq_contracts_on_cohort_id" - t.index ["npq_lead_provider_id"], name: "index_npq_contracts_on_npq_lead_provider_id" - end - - create_table "npq_courses", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.text "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.text "identifier" - end - - create_table "npq_lead_providers", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| - t.text "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.uuid "cpd_lead_provider_id" - t.boolean "vat_chargeable", default: true - t.index ["cpd_lead_provider_id"], name: "index_npq_lead_providers_on_cpd_lead_provider_id" - end - create_table "participant_appropriate_body_dqt_checks", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "participant_profile_id", null: false t.string "appropriate_body_name" @@ -1341,12 +1245,6 @@ add_foreign_key "milestones", "schedules" add_foreign_key "nomination_emails", "partnership_notification_emails" add_foreign_key "nomination_emails", "schools" - add_foreign_key "npq_application_exports", "users" - add_foreign_key "npq_applications", "npq_courses" - add_foreign_key "npq_applications", "npq_lead_providers" - add_foreign_key "npq_applications", "participant_identities" - add_foreign_key "npq_applications", "users", column: "eligible_for_funding_updated_by_id" - add_foreign_key "npq_lead_providers", "cpd_lead_providers" add_foreign_key "participant_bands", "call_off_contracts" add_foreign_key "participant_declaration_attempts", "participant_declarations" add_foreign_key "participant_declarations", "participant_declarations", column: "superseded_by_id" @@ -1363,7 +1261,6 @@ add_foreign_key "participant_profile_states", "participant_profiles" add_foreign_key "participant_profiles", "cohorts" add_foreign_key "participant_profiles", "core_induction_programmes" - add_foreign_key "participant_profiles", "npq_courses" add_foreign_key "participant_profiles", "participant_identities" add_foreign_key "participant_profiles", "participant_profiles", column: "mentor_profile_id" add_foreign_key "participant_profiles", "schedules" diff --git a/lib/tasks/one_offs.rake b/lib/tasks/one_offs.rake deleted file mode 100644 index f0d00d15b6..0000000000 --- a/lib/tasks/one_offs.rake +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -namespace :one_offs do - desc "backfill teacher catchement iso country code" - task backfill_teacher_catchment_iso_country_code: :environment do - uk_country = ISO3166::Country.find_country_by_any_name("United Kingdom") - - NPQApplication.where.not(teacher_catchment: [nil, "another"]).find_each do |npq_application| - next unless npq_application.in_uk_catchment_area? - - npq_application.update!( - teacher_catchment_iso_country_code: uk_country.alpha3, - teacher_catchment_country: uk_country.iso_short_name, - ) - end - - NPQApplication.where.not(teacher_catchment_country: nil).where(teacher_catchment: [nil, "another"]).find_each do |npq_application| - if (country = ISO3166::Country.find_country_by_any_name(npq_application.teacher_catchment_country)) - npq_application.update!(teacher_catchment_iso_country_code: country.alpha3) - else - Sentry.capture_message("Could not find the ISO3166 alpha3 code for #{npq_application.teacher_catchment_country}.", level: :warning) - end - end - end -end diff --git a/lib/tasks/oneoff/cleanup_itt_providers_npq_06_02_2023.rake b/lib/tasks/oneoff/cleanup_itt_providers_npq_06_02_2023.rake deleted file mode 100644 index 61d9473c9d..0000000000 --- a/lib/tasks/oneoff/cleanup_itt_providers_npq_06_02_2023.rake +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -# lib/tasks/read_csv.rake - -require "csv" - -# Namespace for tasks related to NPQ applications. -namespace :npq_applications do - # This task restores the ITT providers for NPQ applications. - # It reads a CSV file where each row contains an application ID and the corresponding ITT provider name. - # For each row, it finds the application with the given ID and updates its ITT provider. - # - # Usage: - # Run this task from the command line in your Rails application directory using: - # `rake npq_applications:restore_itt_providers['/path/to/your/file.csv']` - # - # @param file_path [String] the path to the CSV file - desc "Restore itt providers" - task :restore_itt_providers, [:file_path] => :environment do |_, args| - require "csv" - require "logger" - - logger = Logger.new(Rails.env.test? ? nil : $stdout) - file_path = args[:file_path] - - unless file_path && File.exist?(file_path) - raise ArgumentError, "File not found: #{file_path}" - end - - csv_data = CSV.read(file_path) - csv_data.each do |row| - application_id, itt_provider_name = row - - logger.info("Processing application: #{application_id}") - application = NPQApplication.find_by(id: application_id) - if application - application.update!(itt_provider: itt_provider_name) - logger.info("Application #{application_id} updated with ITT provider: #{itt_provider_name}") - else - logger.warn("Application not found! #{application_id}") - end - end - end -end diff --git a/lib/tasks/oneoff/data_cleanup/cleanup_applications.rake b/lib/tasks/oneoff/data_cleanup/cleanup_applications.rake deleted file mode 100644 index 39e3ffd18c..0000000000 --- a/lib/tasks/oneoff/data_cleanup/cleanup_applications.rake +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -require "rake" - -namespace :data_cleanup do - # Accepts a CSV of application IDs (without a header row) and a dry run - # flag. If the dry run flag is true, the changes will not be performed - # but the changes that would be made will be logged. Set dry run to false - # to commit the changes. - # - # Example usage (dry run): - # bundle exec rake 'npq_applications:bulk_change_to_pending[applications.csv,true]' - # - # Example usage (perform change): - # bundle exec rake 'npq_applications:bulk_change_to_pending[applications.csv,false]' - desc "Data Cleanup - Cleanup Application that exist in ECF not NPQ" - task :fix_applications_in_ecf_not_in_npq, %i[file dry_run] => :environment do |_task, args| - logger = Logger.new($stdout) - csv_file_path = args[:file] - dry_run = args[:dry_run] != "false" - - unless File.exist?(csv_file_path) - logger.error "File not found: #{csv_file_path}" - return - end - - npq_application_ids = CSV.read(csv_file_path, headers: false).flatten - - logger.info "Fixing #{npq_application_ids.size} NPQ applications not in NPQ#{' (dry run)' if dry_run}..." - - result = Oneoffs::NPQ::DataCleanup::FixApplicationsInECFNotInNPQ.new(npq_application_ids:).run!(dry_run:) - - logger.info JSON.pretty_generate(result) - end -end diff --git a/spec/components/admin/participants/npq_validation_status_tag_spec.rb b/spec/components/admin/participants/npq_validation_status_tag_spec.rb deleted file mode 100644 index e75bf12891..0000000000 --- a/spec/components/admin/participants/npq_validation_status_tag_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe Admin::Participants::NPQValidationStatusTag, type: :component do - let(:component) { described_class.new profile: participant_profile } - - let!(:participant_profile) { create :npq_participant_profile } - - subject { render_inline(component) } - - context "when profile is approved" do - before { allow(participant_profile).to receive(:approved?).and_return true } - - it { is_expected.to have_selector(".govuk-tag.govuk-tag--green", text: "Complete") } - end - - context "when profile is rejected" do - before { allow(participant_profile).to receive(:rejected?).and_return true } - - it { is_expected.to have_selector(".govuk-tag.govuk-tag--red", text: "Rejected") } - end - - context "when profile is neither rejected nor approved" do - it { is_expected.to have_selector(".govuk-tag.govuk-tag--yellow", text: "Pending") } - end -end diff --git a/spec/factories/cpd_lead_provider.rb b/spec/factories/cpd_lead_provider.rb index 22dec4e577..b0f8c1c7c0 100644 --- a/spec/factories/cpd_lead_provider.rb +++ b/spec/factories/cpd_lead_provider.rb @@ -9,11 +9,5 @@ create(:lead_provider, name: cpd_lead_provider.name, cpd_lead_provider:) end end - - trait :with_npq_lead_provider do - after(:create) do |cpd_lead_provider| - create(:npq_lead_provider, cpd_lead_provider:) - end - end end end diff --git a/spec/factories/finance/statements.rb b/spec/factories/finance/statements.rb index 35c29b7eaf..4249bdf761 100644 --- a/spec/factories/finance/statements.rb +++ b/spec/factories/finance/statements.rb @@ -9,7 +9,7 @@ contract_version { "1.0" } factory :npq_statement, class: "Finance::Statement::NPQ" do - cpd_lead_provider { association :cpd_lead_provider, :with_npq_lead_provider } + cpd_lead_provider { association :cpd_lead_provider } factory :npq_payable_statement, class: "Finance::Statement::NPQ::Payable" do payable end diff --git a/spec/factories/npq_contracts.rb b/spec/factories/npq_contracts.rb deleted file mode 100644 index 5820801ad8..0000000000 --- a/spec/factories/npq_contracts.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :npq_contract do - npq_lead_provider { build(:npq_lead_provider, cpd_lead_provider: build(:cpd_lead_provider, name: "NPQ Contract Test Lead Provider")) } - version { "1.0" } - service_fee_percentage { 40 } - output_payment_percentage { 60 } - per_participant { 800.00 } - number_of_payment_periods { 3 } - recruitment_target { 72 } - course_identifier { "npq-leading-teaching" } - service_fee_installments { 19 } - cohort { Cohort.current || create(:cohort, :current) } - targeted_delivery_funding_per_participant { 100.0 } - monthly_service_fee { 0.0 } - end - - trait :npq_leading_teaching do - course_identifier { "npq-leading-teaching" } - recruitment_target { 72 } - number_of_payment_periods { 3 } - service_fee_installments { 19 } - per_participant { 800.00 } - end - - trait :npq_leading_behaviour_culture do - course_identifier { "npq-leading-behaviour-culture" } - recruitment_target { 72 } - number_of_payment_periods { 3 } - per_participant { 810.00 } - service_fee_installments { 19 } - end - - trait :npq_leading_teaching_development do - course_identifier { "npq-leading-teaching-development" } - recruitment_target { 211 } - number_of_payment_periods { 3 } - per_participant { 820.00 } - service_fee_installments { 19 } - end - - trait :npq_senior_leadership do - course_identifier { "npq-senior-leadership" } - recruitment_target { 205 } - number_of_payment_periods { 4 } - per_participant { 830.00 } - service_fee_installments { 25 } - end - - trait :npq_headship do - course_identifier { "npq-headship" } - recruitment_target { 172 } - number_of_payment_periods { 4 } - per_participant { 840.00 } - service_fee_installments { 31 } - end - - trait :npq_executive_leadership do - course_identifier { "npq-executive-leadership" } - recruitment_target { 26 } - number_of_payment_periods { 4 } - per_participant { 850.00 } - service_fee_installments { 25 } - end - - trait :npq_leading_primary_mathematics do - course_identifier { "npq-leading-primary-mathematics" } - recruitment_target { 400 } - number_of_payment_periods { 3 } - per_participant { 902.00 } - service_fee_installments { 540 } - end - - trait :with_monthly_service_fee do - monthly_service_fee { 5432.10 } - end -end diff --git a/spec/factories/npq_courses.rb b/spec/factories/npq_courses.rb deleted file mode 100644 index 3314c29ed7..0000000000 --- a/spec/factories/npq_courses.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -require "finance/schedule" - -FactoryBot.define do - factory :npq_course do - sequence(:name) { |n| "NPQ Course #{n}" } - identifier { (Finance::Schedule::NPQLeadership::IDENTIFIERS + Finance::Schedule::NPQSpecialist::IDENTIFIERS).sample } - end - - factory :npq_leadership_course, class: "NPQCourse" do - sequence(:name) { |n| "NPQ Leadership Course #{n}" } - identifier { Finance::Schedule::NPQLeadership::IDENTIFIERS.sample } - end - - factory :npq_specialist_course, class: "NPQCourse" do - sequence(:name) { |n| "NPQ Specialist Course #{n}" } - identifier { Finance::Schedule::NPQSpecialist::IDENTIFIERS.sample } - end - - factory :npq_aso_course, class: "NPQCourse" do - sequence(:name) { |n| "NPQ ASO Course #{n}" } - identifier { Finance::Schedule::NPQSupport::IDENTIFIERS.sample } - end - - factory :npq_ehco_course, class: "NPQCourse" do - sequence(:name) { |n| "NPQ EHCO Course #{n}" } - identifier { Finance::Schedule::NPQEhco::IDENTIFIERS.sample } - end -end diff --git a/spec/factories/npq_lead_providers.rb b/spec/factories/npq_lead_providers.rb deleted file mode 100644 index 31794ed26c..0000000000 --- a/spec/factories/npq_lead_providers.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :npq_lead_provider do - cpd_lead_provider - - sequence(:name) { |n| "NPQ Lead Provider #{n}" } - end -end diff --git a/spec/factories/participant_profiles.rb b/spec/factories/participant_profiles.rb index 49266e6253..bbeeb302eb 100644 --- a/spec/factories/participant_profiles.rb +++ b/spec/factories/participant_profiles.rb @@ -30,20 +30,26 @@ end factory :npq_participant_profile, class: "ParticipantProfile::NPQ" do - transient do - npq_course { create(:npq_course) } - user { create(:user) } - npq_lead_provider { create(:cpd_lead_provider, :with_npq_lead_provider).npq_lead_provider } - trn { user.teacher_profile&.trn || sprintf("%07i", Random.random_number(9_999_999)) } - end - npq_application { create(:npq_application, *profile_traits, :accepted, user:, npq_lead_provider:, npq_course:, cohort:) } + user { create(:user) } + schedule { Finance::Schedule::NPQLeadership.default_for(cohort:) || create(:npq_schedule, cohort:) } + participant_identity { Identity::Create.call(user:, origin: :npq) } trait :eligible_for_funding do profile_traits { [:eligible_for_funding] } end initialize_with do - npq_application.profile + teacher_profile = user.teacher_profile || user.build_teacher_profile + + profile = ParticipantProfile::NPQ.create!( + schedule:, + teacher_profile:, + participant_identity:, + ).tap do |pp| + ParticipantProfileState.find_or_create_by(participant_profile: pp) + end + + profile end end diff --git a/spec/factories/seeds/npq_application_factory.rb b/spec/factories/seeds/npq_application_factory.rb deleted file mode 100644 index 292aa66b6b..0000000000 --- a/spec/factories/seeds/npq_application_factory.rb +++ /dev/null @@ -1,64 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory(:seed_npq_application, class: "NPQApplication") do - date_of_birth { Faker::Date.between(from: 70.years.ago, to: 21.years.ago) } - headteacher_status { NPQApplication.headteacher_statuses.keys.sample } - funding_choice { NPQApplication.funding_choices.keys.sample } - nino { SecureRandom.hex } - teacher_catchment { "england" } - works_in_school { true } - eligible_for_funding { true } - - trait(:with_participant_identity) do - association(:participant_identity, factory: %i[seed_participant_identity valid]) - end - - trait(:with_npq_lead_provider) do - association(:npq_lead_provider, factory: %i[seed_npq_lead_provider valid]) - end - - trait(:with_npq_course) do - association(:npq_course, factory: %i[seed_npq_course]) - end - - trait(:ineligible_for_funding) { false } - - trait(:company) do - works_in_school { false } - school_urn { nil } - school_ukprn { nil } - employer_name { Faker::Company.name } - employment_role { Faker::Company.profession.capitalize } - end - - trait(:childcare) do - works_in_school { false } - school_urn { nil } - school_ukprn { nil } - works_in_nursery { true } - works_in_childcare { true } - kind_of_nursery { "private_nursery" } - private_childcare_provider_urn { "EY#{SecureRandom.rand(100_000..999_999)}" } - end - - trait(:starting_in_2021) { cohort { create(:cohort, start_year: 2021) } } - trait(:starting_in_2022) { cohort { create(:cohort, start_year: 2022) } } - trait(:starting_in_2023) { cohort { create(:cohort, start_year: 2023) } } - - trait(:valid) do - with_participant_identity - with_npq_lead_provider - with_npq_course - starting_in_2022 - end - - after(:build) do |npqa| - if npqa.participant_identity&.persisted? - Rails.logger.debug("seeded an npq application for #{npqa.participant_identity.user.full_name}") - else - Rails.logger.debug("seeded an incomplete NPQ application") - end - end - end -end diff --git a/spec/factories/seeds/npq_course_factory.rb b/spec/factories/seeds/npq_course_factory.rb deleted file mode 100644 index 45cedf307a..0000000000 --- a/spec/factories/seeds/npq_course_factory.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory(:seed_npq_course, class: "NPQCourse") do - name { "NPQ Leading Teaching (#{SecureRandom.hex(6)})" } - identifier { Finance::Schedule::NPQLeadership::IDENTIFIERS.sample } - - trait(:valid) {} - - after(:build) do - Rails.logger.debug("Built an NPQ application") - end - end -end diff --git a/spec/factories/seeds/npq_lead_provider_factory.rb b/spec/factories/seeds/npq_lead_provider_factory.rb deleted file mode 100644 index 7cd65c564b..0000000000 --- a/spec/factories/seeds/npq_lead_provider_factory.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory(:seed_npq_lead_provider, class: "NPQLeadProvider") do - name { Faker::Company.name } - - trait(:with_cpd_lead_provider) { association(:cpd_lead_provider, factory: :seed_cpd_lead_provider) } - - trait(:valid) { with_cpd_lead_provider } - - after(:build) { |npqlp| Rails.logger.debug("seeded npq lead provider #{npqlp.name}") } - end -end diff --git a/spec/factories/services/npq/npq_application.rb b/spec/factories/services/npq/npq_application.rb deleted file mode 100644 index 0e082c0211..0000000000 --- a/spec/factories/services/npq/npq_application.rb +++ /dev/null @@ -1,104 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :npq_application do - transient do - user { create(:user) } - end - npq_course { create(:npq_course) } - npq_lead_provider { create(:cpd_lead_provider, :with_npq_lead_provider).npq_lead_provider } - headteacher_status { NPQApplication.headteacher_statuses.keys.sample } - funding_choice { NPQApplication.funding_choices.keys.sample } - works_in_school { true } - school_urn { rand(100_000..999_999).to_s } - school_ukprn { rand(10_000_000..99_999_999).to_s } - date_of_birth { rand(25..50).years.ago + rand(0..365).days } - teacher_reference_number { user.teacher_profile&.trn || rand(1_000_000..9_999_999).to_s } - teacher_reference_number_verified { true } - nino { SecureRandom.hex } - active_alert { false } - eligible_for_funding { false } - funding_eligiblity_status_code { :ineligible_establishment_type } - targeted_delivery_funding_eligibility { false } - teacher_catchment { "england" } - teacher_catchment_country { nil } - itt_provider { "University of Southampton" } - lead_mentor { true } - - association :cohort, factory: %i[cohort current] - - before(:create) do |npq_application, evaluator| - npq_application.participant_identity = Identity::Create.call(user: evaluator.user, origin: :npq) - end - - trait :funded do - eligible_for_funding { true } - funding_eligiblity_status_code { :funded } - end - - trait :funded_place do - funded_place { true } - end - - trait :no_funded_place do - funded_place { false } - end - - trait :eligible_for_funding do - funded - end - - trait :edge_case do - works_in_school { false } - works_in_childcare { false } - funding_eligiblity_status_code { "re_register" } - end - - trait :targeted_delivery_funding_eligibility do - targeted_delivery_funding_eligibility { true } - end - - trait :accepted do - after(:create) do |npq_application, evaluator| - npq_application.update!(lead_provider_approval_status: "accepted") - user = evaluator.user - teacher_profile = user.teacher_profile || user.build_teacher_profile - teacher_profile.update!(trn: npq_application.teacher_reference_number) - ParticipantProfile::NPQ.create!( - id: npq_application.id, - schedule: NPQCourse.schedule_for(npq_course: npq_application.npq_course, cohort: npq_application.cohort), - npq_course: npq_application.npq_course, - teacher_profile:, - school_urn: npq_application.school_urn, - school_ukprn: npq_application.school_ukprn, - participant_identity: npq_application.participant_identity, - ).tap do |pp| - ParticipantProfileState.find_or_create_by(participant_profile: pp) - end - npq_application.reload - end - end - - trait :eligible_for_funding do - eligible_for_funding { true } - end - - trait :not_in_school do - works_in_school { false } - school_urn { nil } - school_ukprn { nil } - employer_name { "Some Company Ltd" } - employment_role { "Director" } - end - - trait :in_private_childcare_provider do - works_in_school { false } - school_urn { nil } - school_ukprn { nil } - works_in_nursery { true } - works_in_childcare { true } - kind_of_nursery { "private_nursery" } - private_childcare_provider_urn { "EY#{rand(100_000..999_999)}" } - end - end -end diff --git a/spec/features/dedup/session_spec.rb b/spec/features/dedup/session_spec.rb index b406c0c82c..576e205313 100644 --- a/spec/features/dedup/session_spec.rb +++ b/spec/features/dedup/session_spec.rb @@ -4,7 +4,7 @@ RSpec.feature "Dedup: maintaining session after identity transfer", :js do let(:original_user) { create(:ect).user } - let(:target_user) { create(:npq_participant_profile).user } + let(:target_user) { create(:ect_participant_profile).user } before do Identity::Transfer.call(from_user: original_user, to_user: target_user) diff --git a/spec/features/participant_declarations/participant_declaration_steps.rb b/spec/features/participant_declarations/participant_declaration_steps.rb index 8da5d7ac41..1d329a78db 100644 --- a/spec/features/participant_declarations/participant_declaration_steps.rb +++ b/spec/features/participant_declarations/participant_declaration_steps.rb @@ -130,10 +130,6 @@ def then_second_declaration_is_not_created expect(ParticipantDeclaration.count).to eq(1) end - def and_the_npq_declaration_date_is_early - @declaration_date = @npq_application.reload.profile.schedule.milestones.where(declaration_type: "started").first.start_date - 1.day - end - def and_the_ect_declaration_date_is_early @declaration_date = @ect_profile.schedule.milestones.first.start_date - 1.day end diff --git a/spec/fixtures/files/api_reference/api_spec.json b/spec/fixtures/files/api_reference/api_spec.json index e4f9698e42..438169c736 100644 --- a/spec/fixtures/files/api_reference/api_spec.json +++ b/spec/fixtures/files/api_reference/api_spec.json @@ -622,12 +622,12 @@ } } }, - "/api/v3/npq-applications": { + "/api/v3/participants/npq/outcomes": { "get": { - "summary": "Retrieve multiple NPQ applications", - "operationId": "npq_applications", + "summary": "Note, this endpoint includes updated specifications.
List all participant NPQ outcomes", + "operationId": "participant_outcomes", "tags": [ - "NPQ applications" + "Participants Outcomes" ], "security": [ { @@ -641,13 +641,13 @@ "name": "filter", "in": "query", "schema": { - "$ref": "#/components/schemas/NPQApplicationsFilter" + "$ref": "#/components/schemas/NPQOutcomeFilter" }, "style": "deepObject", "explode": true, "required": false, - "description": "Refine NPQ applications to return.", - "example": "filter[cohort]=2021,2022&filter[participant_id]=7e5bcdbf-c818-4961-8da5-439cab1984e0,c2a7ef98-bbfc-48c5-8f02-d484071d2165&filter[updated_since]=2020-11-13T11:21:55Z" + "description": "Refine participant outcomes to return.", + "example": "filter[created_since]=2020-11-13T11:21:55Z" }, { "name": "page", @@ -659,28 +659,16 @@ "explode": true, "required": false, "example": "page[page]=1&page[per_page]=5", - "description": "Pagination options to navigate through the list of NPQ applications." - }, - { - "name": "sort", - "in": "query", - "schema": { - "$ref": "#/components/schemas/NPQApplicationsSort" - }, - "style": "form", - "explode": false, - "required": false, - "description": "Sort NPQ applications being returned.", - "example": "sort=-updated_at" + "description": "Pagination options to navigate through the list of participant NPQ outcomes." } ], "responses": { "200": { - "description": "A list of NPQ applications", + "description": "A list of participant outcomes", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/MultipleNPQApplicationsResponse" + "$ref": "#/components/schemas/NPQOutcomesResponse" } } } @@ -698,12 +686,12 @@ } } }, - "/api/v3/npq-applications/{id}": { + "/api/v3/participants/npq/{participant_id}/outcomes": { "get": { - "summary": "Get a single NPQ application", - "operationId": "npq_application", + "summary": "Retrieve NPQ outcomes for the specified participant", + "operationId": "npq_outcome_get", "tags": [ - "NPQ applications" + "outcomes" ], "security": [ { @@ -714,23 +702,24 @@ ], "parameters": [ { - "name": "id", + "name": "participant_id", + "description": "The unique ID of the participant", "in": "path", "required": true, - "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", - "description": "The ID of the NPQ application.", "schema": { - "type": "string" - } + "type": "string", + "format": "uuid" + }, + "example": "70885c85-f52b-45fe-b969-e09a93ffc6ee" } ], "responses": { "200": { - "description": "A single NPQ application", + "description": "Successfully return NPQ outcomes", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NPQApplicationResponse" + "$ref": "#/components/schemas/NPQOutcomesResponse" } } } @@ -744,26 +733,14 @@ } } } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundResponse" - } - } - } } } - } - }, - "/api/v3/npq-applications/{id}/accept": { + }, "post": { - "summary": "Accept an NPQ application", - "operationId": "npq_applications_accept", + "summary": "Submit an NPQ outcome", + "operationId": "npq_outcome_post", "tags": [ - "NPQ applications" + "outcomes" ], "security": [ { @@ -774,64 +751,33 @@ ], "parameters": [ { - "name": "id", + "name": "participant_id", + "description": "The unique ID of the participant", "in": "path", "required": true, - "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", - "description": "The ID of the NPQ application to accept.", "schema": { - "type": "string" - } + "type": "string", + "format": "uuid" + }, + "example": "70885c85-f52b-45fe-b969-e09a93ffc6ee" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NPQOutcomeRequest" + } + } + } + }, "responses": { "200": { - "description": "The NPQ application being accepted", + "description": "Successfully submit an NPQ outcome", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NPQApplicationResponse" - }, - "examples": { - "success": { - "value": { - "data": { - "id": "db3a7848-7308-4879-942a-c4a70ced400a", - "type": "npq_application", - "attributes": { - "participant_id": "7a8fef46-3c43-42c0-b3d5-1ba5904ba562", - "full_name": "Isabelle MacDonald", - "email": "isabelle.macdonald2@some-school.example.com", - "email_validated": true, - "teacher_reference_number": "1234567", - "teacher_reference_number_validated": true, - "works_in_school": true, - "employer_name": "Some Company Ltd", - "employment_role": "Director", - "school_urn": "106286", - "private_childcare_provider_urn": "EY944860", - "school_ukprn": "10079319", - "headteacher_status": "no", - "funding_choice": "trust", - "course_identifier": "npq-leading-teaching", - "status": "accepted", - "created_at": "2021-05-31T02:21:32.000Z", - "updated_at": "2021-05-31T02:22:32.000Z", - "ineligible_for_funding_reason": "establishment-ineligible", - "cohort": "2022", - "eligible_for_funding": true, - "funded_place": true, - "targeted_delivery_funding_eligibility": true, - "teacher_catchment": true, - "teacher_catchment_iso_country_code": "FRA", - "teacher_catchment_country": "France", - "itt_provider": "University of Southampton", - "lead_mentor": true, - "schedule_identifier": "npq-leadership-spring" - } - } - } - } + "$ref": "#/components/schemas/NPQOutcomeResponse" } } } @@ -845,45 +791,133 @@ } } } + } + } + } + }, + "/api/v3/participants/npq": { + "get": { + "summary": "Note, this endpoint includes updated specifications.
Retrieve multiple NPQ participants", + "operationId": "npq_participants", + "tags": [ + "NPQ participants" + ], + "security": [ + { + "bearerAuth": [ + + ] + } + ], + "parameters": [ + { + "name": "filter", + "in": "query", + "schema": { + "$ref": "#/components/schemas/NPQParticipantFilter" + }, + "style": "deepObject", + "explode": true, + "required": false, + "description": "Refine NPQ participants to return.", + "example": "filter[updated_since]=2020-11-13T11:21:55Z&filter[training_status]=active&filter[from_participant_id]=439ac4fe-a003-417f-9694-07c45b3482f8" }, - "404": { - "description": "Not Found", + { + "name": "page", + "in": "query", + "schema": { + "$ref": "#/components/schemas/Pagination" + }, + "style": "deepObject", + "explode": true, + "required": false, + "example": "page[page]=1&page[per_page]=5", + "description": "Pagination options to navigate through the list of NPQ participants." + }, + { + "name": "sort", + "in": "query", + "schema": { + "$ref": "#/components/schemas/NPQParticipantsSort" + }, + "style": "form", + "explode": false, + "required": false, + "description": "Sort NPQ participants being returned.", + "example": "sort=-updated_at" + } + ], + "responses": { + "200": { + "description": "A list of NPQ participants", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundResponse" + "$ref": "#/components/schemas/MultipleNPQParticipantsResponse" + }, + "examples": { + "success": { + "value": { + "data": [ + { + "id": "ac3d1243-7308-4879-942a-c4a70ced400a", + "type": "npq-participant", + "attributes": { + "full_name": "Isabelle MacDonald", + "teacher_reference_number": "1234567", + "updated_at": "2021-05-31T02:22:32.000Z", + "npq_enrolments": [ + { + "email": "isabelle.macdonald2@some-school.example.com", + "course_identifier": "npq-senior-leadership", + "schedule_identifier": "npq-leadership-autumn", + "cohort": "2021", + "npq_application_id": "db3a7848-7308-4879-942a-c4a70ced400a", + "eligible_for_funding": true, + "training_status": "active", + "school_urn": "123456", + "targeted_delivery_funding_eligibility": true, + "withdrawal": null, + "deferral": null, + "created_at": "2021-05-31T02:22:32.000Z", + "funded_place": true + } + ], + "participant_id_changes": [ + { + "from_participant_id": "23dd8d66-e11f-4139-9001-86b4f9abcb02", + "to_participant_id": "ac3d1243-7308-4879-942a-c4a70ced400a", + "changed_at": "2023-09-23T02:22:32.000Z" + } + ] + } + } + ] + } + } } } } }, - "422": { - "description": "Unprocessable Entity", + "401": { + "description": "Unauthorized", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NPQApplicationAcceptErrorResponse" + "$ref": "#/components/schemas/UnauthorisedResponse" } } } } - }, - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NPQApplicationAcceptRequest" - } - } - } } } }, - "/api/v3/npq-applications/{id}/reject": { - "post": { - "summary": "Reject an NPQ application", - "operationId": "npq_applications_reject", + "/api/v3/participants/npq/{id}": { + "get": { + "summary": "Note, this endpoint includes updated specifications.
Get a single NPQ participant", + "operationId": "npq_participant", "tags": [ - "NPQ applications" + "NPQ participants" ], "security": [ { @@ -897,8 +931,8 @@ "name": "id", "in": "path", "required": true, - "example": "14b1b4ab-fa81-4f7a-b4b5-f632412e8c5c", - "description": "The ID of the NPQ application to reject.", + "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", + "description": "The ID of the NPQ participant.", "schema": { "type": "string" } @@ -906,48 +940,46 @@ ], "responses": { "200": { - "description": "The NPQ application being rejected", + "description": "A single NPQ participant", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NPQApplicationResponse" + "$ref": "#/components/schemas/NPQParticipantResponse" }, "examples": { "success": { "value": { "data": { "id": "db3a7848-7308-4879-942a-c4a70ced400a", - "type": "npq_application", + "type": "npq-participant", "attributes": { - "participant_id": "7a8fef46-3c43-42c0-b3d5-1ba5904ba562", "full_name": "Isabelle MacDonald", - "email": "isabelle.macdonald2@some-school.example.com", - "email_validated": true, "teacher_reference_number": "1234567", - "teacher_reference_number_validated": true, - "works_in_school": true, - "employer_name": "Some Company Ltd", - "employment_role": "Director", - "school_urn": "106286", - "private_childcare_provider_urn": "EY944860", - "school_ukprn": "10079319", - "headteacher_status": "no", - "funding_choice": "trust", - "course_identifier": "npq-leading-teaching", - "status": "rejected", - "created_at": "2021-05-31T02:21:32.000Z", "updated_at": "2021-05-31T02:22:32.000Z", - "ineligible_for_funding_reason": "establishment-ineligible", - "cohort": "2022", - "eligible_for_funding": true, - "funded_place": true, - "targeted_delivery_funding_eligibility": true, - "teacher_catchment": true, - "teacher_catchment_iso_country_code": "FRA", - "teacher_catchment_country": "France", - "itt_provider": "University of Southampton", - "lead_mentor": true, - "schedule_identifier": "npq-leadership-spring" + "npq_enrolments": [ + { + "email": "isabelle.macdonald2@some-school.example.com", + "course_identifier": "npq-senior-leadership", + "schedule_identifier": "npq-leadership-autumn", + "cohort": "2021", + "npq_application_id": "db3a7848-7308-4879-942a-c4a70ced400a", + "eligible_for_funding": true, + "training_status": "deferred", + "school_urn": "123456", + "targeted_delivery_funding_eligibility": true, + "withdrawal": null, + "deferral": null, + "created_at": "2021-05-31T02:22:32.000Z", + "funded_place": true + } + ], + "participant_id_changes": [ + { + "from_participant_id": "23dd8d66-e11f-4139-9001-86b4f9abcb02", + "to_participant_id": "db3a7848-7308-4879-942a-c4a70ced400a", + "changed_at": "2023-09-23T02:22:32.000Z" + } + ] } } } @@ -975,26 +1007,16 @@ } } } - }, - "422": { - "description": "Unprocessable Entity", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NPQApplicationRejectErrorResponse" - } - } - } } } } }, - "/api/v3/npq-applications/{id}/change-funded-place": { + "/api/v3/participants/npq/{id}/change-schedule": { "put": { - "summary": "Change funded place", - "operationId": "npq_applications_change_funded_place", + "summary": "Note, this endpoint includes updated specifications.
Notify that an NPQ participant is changing training schedule", + "operationId": "npq_participant", "tags": [ - "NPQ applications" + "NPQ Participant" ], "security": [ { @@ -1003,119 +1025,34 @@ ] } ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", - "description": "The ID of the NPQ application to change funded place.", - "schema": { - "type": "string", - "format": "uuid" - } - } - ], - "responses": { - "200": { - "description": "The NPQ application being accepted", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NPQApplicationResponse" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorisedResponse" - } - } - } - }, - "404": { - "description": "Not Found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundResponse" - } - } - } - } - }, "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ChangeFundedPlaceRequest" + "$ref": "#/components/schemas/NPQParticipantChangeScheduleRequest" } } } - } - } - }, - "/api/v3/participants/npq/outcomes": { - "get": { - "summary": "Note, this endpoint includes updated specifications.
List all participant NPQ outcomes", - "operationId": "participant_outcomes", - "tags": [ - "Participants Outcomes" - ], - "security": [ - { - "bearerAuth": [ - - ] - } - ], + }, "parameters": [ { - "name": "filter", - "in": "query", - "schema": { - "$ref": "#/components/schemas/NPQOutcomeFilter" - }, - "style": "deepObject", - "explode": true, - "required": false, - "description": "Refine participant outcomes to return.", - "example": "filter[created_since]=2020-11-13T11:21:55Z" - }, - { - "name": "page", - "in": "query", + "name": "id", + "in": "path", + "required": true, + "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", + "description": "The ID of the participant", "schema": { - "$ref": "#/components/schemas/Pagination" - }, - "style": "deepObject", - "explode": true, - "required": false, - "example": "page[page]=1&page[per_page]=5", - "description": "Pagination options to navigate through the list of participant NPQ outcomes." + "type": "string" + } } ], "responses": { "200": { - "description": "A list of participant outcomes", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NPQOutcomesResponse" - } - } - } - }, - "401": { - "description": "Unauthorized", + "description": "The NPQ participant changing schedule", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UnauthorisedResponse" + "$ref": "#/components/schemas/NPQParticipantResponse" } } } @@ -1123,12 +1060,12 @@ } } }, - "/api/v3/participants/npq/{participant_id}/outcomes": { - "get": { - "summary": "Retrieve NPQ outcomes for the specified participant", - "operationId": "npq_outcome_get", + "/api/v3/participants/npq/{id}/defer": { + "put": { + "summary": "Note, this endpoint includes updated specifications.
Notify that an NPQ participant is taking a break from their course", + "operationId": "npq_participant", "tags": [ - "outcomes" + "NPQ Participant" ], "security": [ { @@ -1137,47 +1074,89 @@ ] } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NPQParticipantDeferRequest" + } + } + } + }, "parameters": [ { - "name": "participant_id", - "description": "The unique ID of the participant", + "name": "id", "in": "path", "required": true, + "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", + "description": "The ID of the participant to defer", "schema": { - "type": "string", - "format": "uuid" - }, - "example": "70885c85-f52b-45fe-b969-e09a93ffc6ee" + "type": "string" + } } ], "responses": { "200": { - "description": "Successfully return NPQ outcomes", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NPQOutcomesResponse" - } - } - } - }, - "401": { - "description": "Unauthorized", + "description": "The NPQ participant being deferred", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UnauthorisedResponse" + "$ref": "#/components/schemas/NPQParticipantResponse" + }, + "examples": { + "success": { + "value": { + "data": { + "id": "db3a7848-7308-4879-942a-c4a70ced400a", + "type": "npq-participant", + "attributes": { + "full_name": "Isabelle MacDonald", + "teacher_reference_number": "1234567", + "updated_at": "2021-05-31T02:22:32.000Z", + "npq_enrolments": [ + { + "email": "isabelle.macdonald2@some-school.example.com", + "course_identifier": "npq-senior-leadership", + "schedule_identifier": "npq-leadership-autumn", + "cohort": "2021", + "npq_application_id": "db3a7848-7308-4879-942a-c4a70ced400a", + "eligible_for_funding": true, + "training_status": "deferred", + "school_urn": "123456", + "targeted_delivery_funding_eligibility": true, + "withdrawal": null, + "deferral": { + "reason": "other", + "date": "2022-12-09T16:07:38Z" + }, + "created_at": "2021-05-31T02:22:32.000Z", + "funded_place": true + } + ], + "participant_id_changes": [ + { + "from_participant_id": "23dd8d66-e11f-4139-9001-86b4f9abcb02", + "to_participant_id": "db3a7848-7308-4879-942a-c4a70ced400a", + "changed_at": "2023-09-23T02:22:32.000Z" + } + ] + } + } + } + } } } } } } - }, - "post": { - "summary": "Submit an NPQ outcome", - "operationId": "npq_outcome_post", + } + }, + "/api/v3/participants/npq/{id}/resume": { + "put": { + "summary": "Note, this endpoint includes updated specifications.
Notify that an NPQ participant is resuming their course", + "operationId": "npq_participant", "tags": [ - "outcomes" + "NPQ Participant" ], "security": [ { @@ -1186,45 +1165,34 @@ ] } ], - "parameters": [ - { - "name": "participant_id", - "description": "The unique ID of the participant", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - }, - "example": "70885c85-f52b-45fe-b969-e09a93ffc6ee" - } - ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NPQOutcomeRequest" + "$ref": "#/components/schemas/NPQParticipantResumeRequest" } } } }, + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", + "description": "The ID of the participant to resume", + "schema": { + "type": "string" + } + } + ], "responses": { "200": { - "description": "Successfully submit an NPQ outcome", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NPQOutcomeResponse" - } - } - } - }, - "401": { - "description": "Unauthorized", + "description": "The NPQ participant being resumed", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UnauthorisedResponse" + "$ref": "#/components/schemas/NPQParticipantResponse" } } } @@ -1232,129 +1200,12 @@ } } }, - "/api/v3/participants/npq": { - "get": { - "summary": "Note, this endpoint includes updated specifications.
Retrieve multiple NPQ participants", + "/api/v3/participants/npq/{id}/withdraw": { + "put": { + "summary": "Note, this endpoint includes updated specifications.
Withdrawn a participant from a course", "operationId": "npq_participants", "tags": [ - "NPQ participants" - ], - "security": [ - { - "bearerAuth": [ - - ] - } - ], - "parameters": [ - { - "name": "filter", - "in": "query", - "schema": { - "$ref": "#/components/schemas/NPQParticipantFilter" - }, - "style": "deepObject", - "explode": true, - "required": false, - "description": "Refine NPQ participants to return.", - "example": "filter[updated_since]=2020-11-13T11:21:55Z&filter[training_status]=active&filter[from_participant_id]=439ac4fe-a003-417f-9694-07c45b3482f8" - }, - { - "name": "page", - "in": "query", - "schema": { - "$ref": "#/components/schemas/Pagination" - }, - "style": "deepObject", - "explode": true, - "required": false, - "example": "page[page]=1&page[per_page]=5", - "description": "Pagination options to navigate through the list of NPQ participants." - }, - { - "name": "sort", - "in": "query", - "schema": { - "$ref": "#/components/schemas/NPQParticipantsSort" - }, - "style": "form", - "explode": false, - "required": false, - "description": "Sort NPQ participants being returned.", - "example": "sort=-updated_at" - } - ], - "responses": { - "200": { - "description": "A list of NPQ participants", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MultipleNPQParticipantsResponse" - }, - "examples": { - "success": { - "value": { - "data": [ - { - "id": "ac3d1243-7308-4879-942a-c4a70ced400a", - "type": "npq-participant", - "attributes": { - "full_name": "Isabelle MacDonald", - "teacher_reference_number": "1234567", - "updated_at": "2021-05-31T02:22:32.000Z", - "npq_enrolments": [ - { - "email": "isabelle.macdonald2@some-school.example.com", - "course_identifier": "npq-senior-leadership", - "schedule_identifier": "npq-leadership-autumn", - "cohort": "2021", - "npq_application_id": "db3a7848-7308-4879-942a-c4a70ced400a", - "eligible_for_funding": true, - "training_status": "active", - "school_urn": "123456", - "targeted_delivery_funding_eligibility": true, - "withdrawal": null, - "deferral": null, - "created_at": "2021-05-31T02:22:32.000Z", - "funded_place": true - } - ], - "participant_id_changes": [ - { - "from_participant_id": "23dd8d66-e11f-4139-9001-86b4f9abcb02", - "to_participant_id": "ac3d1243-7308-4879-942a-c4a70ced400a", - "changed_at": "2023-09-23T02:22:32.000Z" - } - ] - } - } - ] - } - } - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorisedResponse" - } - } - } - } - } - } - }, - "/api/v3/participants/npq/{id}": { - "get": { - "summary": "Note, this endpoint includes updated specifications.
Get a single NPQ participant", - "operationId": "npq_participant", - "tags": [ - "NPQ participants" + "NPQ Participant" ], "security": [ { @@ -1363,13 +1214,22 @@ ] } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NPQParticipantWithdrawRequest" + } + } + } + }, "parameters": [ { "name": "id", "in": "path", "required": true, "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", - "description": "The ID of the NPQ participant.", + "description": "The ID of the participant to withdraw", "schema": { "type": "string" } @@ -1377,7 +1237,7 @@ ], "responses": { "200": { - "description": "A single NPQ participant", + "description": "The NPQ participant being withdrawn", "content": { "application/json": { "schema": { @@ -1401,10 +1261,13 @@ "cohort": "2021", "npq_application_id": "db3a7848-7308-4879-942a-c4a70ced400a", "eligible_for_funding": true, - "training_status": "deferred", + "training_status": "withdrawn", "school_urn": "123456", "targeted_delivery_funding_eligibility": true, - "withdrawal": null, + "withdrawal": { + "reason": "insufficient-capacity", + "date": "2022-12-09T16:07:38Z" + }, "deferral": null, "created_at": "2021-05-31T02:22:32.000Z", "funded_place": true @@ -1425,22 +1288,12 @@ } } }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorisedResponse" - } - } - } - }, - "404": { - "description": "Not Found", + "422": { + "description": "Unprocessable entity", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NotFoundResponse" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1448,12 +1301,12 @@ } } }, - "/api/v3/participants/npq/{id}/change-schedule": { - "put": { - "summary": "Note, this endpoint includes updated specifications.
Notify that an NPQ participant is changing training schedule", - "operationId": "npq_participant", + "/api/v3/participant-declarations": { + "get": { + "summary": "Note, this endpoint includes updated specifications.
List all participant declarations", + "operationId": "participant_declarations", "tags": [ - "NPQ Participant" + "Participant declarations" ], "security": [ { @@ -1462,47 +1315,112 @@ ] } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NPQParticipantChangeScheduleRequest" - } - } - } - }, "parameters": [ { - "name": "id", - "in": "path", - "required": true, - "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", - "description": "The ID of the participant", + "name": "filter", + "in": "query", "schema": { - "type": "string" - } + "$ref": "#/components/schemas/ParticipantDeclarationsFilter" + }, + "style": "deepObject", + "explode": true, + "required": false, + "description": "Refine participant declarations to return.", + "example": "filter[participant_id]=ab3a7848-1208-7679-942a-b4a70eed400a&filter[updated_since]=2020-11-13T11:21:55Z" + }, + { + "name": "page", + "in": "query", + "schema": { + "$ref": "#/components/schemas/Pagination" + }, + "style": "deepObject", + "explode": true, + "required": false, + "example": "page[page]=1&page[per_page]=5", + "description": "Pagination options to navigate through the list of participant declarations." } ], "responses": { "200": { - "description": "The NPQ participant changing schedule", + "description": "A list of participant declarations", + "content": { + "application/json": { + "examples": { + "success": { + "value": { + "data": [ + { + "id": "db3a7848-7308-4879-942a-c4a70ced400a", + "type": "participant-declaration", + "attributes": { + "participant_id": "08d78829-f864-417f-8a30-cb7655714e28", + "declaration_type": "started", + "declaration_date": "2020-11-13T11:21:55Z", + "course_identifier": "ecf-induction", + "state": "eligible", + "updated_at": "2020-11-13T11:21:55Z", + "created_at": "2020-11-13T11:21:55Z", + "delivery_partner_id": "99ca2223-8c1f-4ac8-985d-a0672e97694e", + "statement_id": "99ca2223-8c1f-4ac8-985d-a0672e97694e", + "clawback_statement_id": null, + "ineligible_for_funding_reason": null, + "mentor_id": "907f61ed-5770-4d38-b22c-1a4265939378", + "uplift_paid": true, + "evidence_held": "other", + "has_passed": null, + "lead_provider_name": "Example Institute" + } + }, + { + "id": "db3a7848-7308-4879-942a-c4a70ced400a", + "type": "participant-declaration", + "attributes": { + "participant_id": "bf3c6251-f2a0-4690-a859-0fbecc6ed151", + "declaration_type": "started", + "declaration_date": "2020-11-13T11:21:55Z", + "course_identifier": "ecf-mentor", + "state": "eligible", + "updated_at": "2020-11-13T11:21:55Z", + "created_at": "2020-11-13T11:21:55Z", + "delivery_partner_id": null, + "statement_id": "1cceffd7-0efd-432a-aedc-7be2d6cc72a2", + "clawback_statement_id": null, + "ineligible_for_funding_reason": null, + "mentor_id": null, + "uplift_paid": true, + "evidence_held": "other", + "has_passed": null, + "lead_provider_name": "Example Institute" + } + } + ] + } + } + }, + "schema": { + "$ref": "#/components/schemas/MultipleParticipantDeclarationsResponse" + } + } + } + }, + "401": { + "description": "Unauthorized", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NPQParticipantResponse" + "$ref": "#/components/schemas/UnauthorisedResponse" } } } } } - } - }, - "/api/v3/participants/npq/{id}/defer": { - "put": { - "summary": "Note, this endpoint includes updated specifications.
Notify that an NPQ participant is taking a break from their course", - "operationId": "npq_participant", + }, + "post": { + "summary": "Note, this endpoint includes updated specifications.
Declare a participant has reached a milestone. Idempotent endpoint - submitting exact copy of a request will return the same response body as submitting it the first time.", + "operationId": "participant_declaration_create", "tags": [ - "NPQ Participant" + "Participant declarations" ], "security": [ { @@ -1511,138 +1429,123 @@ ] } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NPQParticipantDeferRequest" - } - } - } - }, "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", - "description": "The ID of the participant to defer", - "schema": { - "type": "string" - } - } + ], "responses": { "200": { - "description": "The NPQ participant being deferred", + "description": "Successful", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/NPQParticipantResponse" - }, "examples": { - "success": { + "success_ecf": { "value": { "data": { "id": "db3a7848-7308-4879-942a-c4a70ced400a", - "type": "npq-participant", + "type": "participant-declaration", "attributes": { - "full_name": "Isabelle MacDonald", - "teacher_reference_number": "1234567", - "updated_at": "2021-05-31T02:22:32.000Z", - "npq_enrolments": [ - { - "email": "isabelle.macdonald2@some-school.example.com", - "course_identifier": "npq-senior-leadership", - "schedule_identifier": "npq-leadership-autumn", - "cohort": "2021", - "npq_application_id": "db3a7848-7308-4879-942a-c4a70ced400a", - "eligible_for_funding": true, - "training_status": "deferred", - "school_urn": "123456", - "targeted_delivery_funding_eligibility": true, - "withdrawal": null, - "deferral": { - "reason": "other", - "date": "2022-12-09T16:07:38Z" - }, - "created_at": "2021-05-31T02:22:32.000Z", - "funded_place": true - } - ], - "participant_id_changes": [ - { - "from_participant_id": "23dd8d66-e11f-4139-9001-86b4f9abcb02", - "to_participant_id": "db3a7848-7308-4879-942a-c4a70ced400a", - "changed_at": "2023-09-23T02:22:32.000Z" - } - ] + "participant_id": "08d78829-f864-417f-8a30-cb7655714e28", + "declaration_type": "started", + "declaration_date": "2020-11-13T11:21:55Z", + "course_identifier": "ecf-induction", + "state": "eligible", + "updated_at": "2020-11-13T11:21:55Z", + "created_at": "2020-11-13T11:21:55Z", + "delivery_partner_id": "99ca2223-8c1f-4ac8-985d-a0672e97694e", + "statement_id": "99ca2223-8c1f-4ac8-985d-a0672e97694e", + "clawback_statement_id": null, + "ineligible_for_funding_reason": null, + "mentor_id": "907f61ed-5770-4d38-b22c-1a4265939378", + "uplift_paid": true, + "evidence_held": "other", + "has_passed": null, + "lead_provider_name": "Example Institute" + } + } + } + }, + "success_npq": { + "value": { + "data": { + "id": "db3a7848-7308-4879-942a-c4a70ced400a", + "type": "participant-declaration", + "attributes": { + "participant_id": "bf3c6251-f2a0-4690-a859-0fbecc6ed151", + "declaration_type": "started", + "declaration_date": "2020-11-13T11:21:55Z", + "course_identifier": "npq-leading-teaching", + "state": "eligible", + "updated_at": "2020-11-13T11:21:55Z", + "created_at": "2020-11-13T11:21:55Z", + "delivery_partner_id": null, + "statement_id": "1cceffd7-0efd-432a-aedc-7be2d6cc72a2", + "clawback_statement_id": null, + "ineligible_for_funding_reason": null, + "mentor_id": null, + "uplift_paid": true, + "evidence_held": null, + "has_passed": null, + "lead_provider_name": "Example Institute" } } } } + }, + "schema": { + "$ref": "#/components/schemas/SingleParticipantDeclarationResponse" } } } - } - } - } - }, - "/api/v3/participants/npq/{id}/resume": { - "put": { - "summary": "Note, this endpoint includes updated specifications.
Notify that an NPQ participant is resuming their course", - "operationId": "npq_participant", - "tags": [ - "NPQ Participant" - ], - "security": [ - { - "bearerAuth": [ - - ] - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NPQParticipantResumeRequest" + }, + "422": { + "description": "Bad or Missing parameter", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } } } - } - }, - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", - "description": "The ID of the participant to resume", - "schema": { - "type": "string" + }, + "401": { + "description": "Unauthorized", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnauthorisedResponse" + } + } } - } - ], - "responses": { - "200": { - "description": "The NPQ participant being resumed", + }, + "400": { + "description": "Bad Request", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NPQParticipantResponse" + "$ref": "#/components/schemas/BadRequestResponse" } } } } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ParticipantDeclarationRequest" + } + } + }, + "required": true } } }, - "/api/v3/participants/npq/{id}/withdraw": { - "put": { - "summary": "Note, this endpoint includes updated specifications.
Withdrawn a participant from a course", - "operationId": "npq_participants", + "/api/v3/participant-declarations/{id}": { + "get": { + "summary": "Note, this endpoint includes updated specifications.
Get single participant declaration", + "operationId": "participant_declaration", "tags": [ - "NPQ Participant" + "Participant declarations" ], "security": [ { @@ -1651,235 +1554,30 @@ ] } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NPQParticipantWithdrawRequest" - } - } - } - }, "parameters": [ { "name": "id", "in": "path", "required": true, - "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", - "description": "The ID of the participant to withdraw", + "example": "9ed4612b-f8bd-44d9-b296-38ab103fadd2", + "description": "The ID of the participant declaration ID", "schema": { - "type": "string" + "type": "string", + "format": "uuid" } } ], "responses": { "200": { - "description": "The NPQ participant being withdrawn", + "description": "A single participant declaration", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/NPQParticipantResponse" - }, "examples": { - "success": { + "success_ecf": { "value": { "data": { "id": "db3a7848-7308-4879-942a-c4a70ced400a", - "type": "npq-participant", - "attributes": { - "full_name": "Isabelle MacDonald", - "teacher_reference_number": "1234567", - "updated_at": "2021-05-31T02:22:32.000Z", - "npq_enrolments": [ - { - "email": "isabelle.macdonald2@some-school.example.com", - "course_identifier": "npq-senior-leadership", - "schedule_identifier": "npq-leadership-autumn", - "cohort": "2021", - "npq_application_id": "db3a7848-7308-4879-942a-c4a70ced400a", - "eligible_for_funding": true, - "training_status": "withdrawn", - "school_urn": "123456", - "targeted_delivery_funding_eligibility": true, - "withdrawal": { - "reason": "insufficient-capacity", - "date": "2022-12-09T16:07:38Z" - }, - "deferral": null, - "created_at": "2021-05-31T02:22:32.000Z", - "funded_place": true - } - ], - "participant_id_changes": [ - { - "from_participant_id": "23dd8d66-e11f-4139-9001-86b4f9abcb02", - "to_participant_id": "db3a7848-7308-4879-942a-c4a70ced400a", - "changed_at": "2023-09-23T02:22:32.000Z" - } - ] - } - } - } - } - } - } - } - }, - "422": { - "description": "Unprocessable entity", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v3/participant-declarations": { - "get": { - "summary": "Note, this endpoint includes updated specifications.
List all participant declarations", - "operationId": "participant_declarations", - "tags": [ - "Participant declarations" - ], - "security": [ - { - "bearerAuth": [ - - ] - } - ], - "parameters": [ - { - "name": "filter", - "in": "query", - "schema": { - "$ref": "#/components/schemas/ParticipantDeclarationsFilter" - }, - "style": "deepObject", - "explode": true, - "required": false, - "description": "Refine participant declarations to return.", - "example": "filter[participant_id]=ab3a7848-1208-7679-942a-b4a70eed400a&filter[updated_since]=2020-11-13T11:21:55Z" - }, - { - "name": "page", - "in": "query", - "schema": { - "$ref": "#/components/schemas/Pagination" - }, - "style": "deepObject", - "explode": true, - "required": false, - "example": "page[page]=1&page[per_page]=5", - "description": "Pagination options to navigate through the list of participant declarations." - } - ], - "responses": { - "200": { - "description": "A list of participant declarations", - "content": { - "application/json": { - "examples": { - "success": { - "value": { - "data": [ - { - "id": "db3a7848-7308-4879-942a-c4a70ced400a", - "type": "participant-declaration", - "attributes": { - "participant_id": "08d78829-f864-417f-8a30-cb7655714e28", - "declaration_type": "started", - "declaration_date": "2020-11-13T11:21:55Z", - "course_identifier": "ecf-induction", - "state": "eligible", - "updated_at": "2020-11-13T11:21:55Z", - "created_at": "2020-11-13T11:21:55Z", - "delivery_partner_id": "99ca2223-8c1f-4ac8-985d-a0672e97694e", - "statement_id": "99ca2223-8c1f-4ac8-985d-a0672e97694e", - "clawback_statement_id": null, - "ineligible_for_funding_reason": null, - "mentor_id": "907f61ed-5770-4d38-b22c-1a4265939378", - "uplift_paid": true, - "evidence_held": "other", - "has_passed": null, - "lead_provider_name": "Example Institute" - } - }, - { - "id": "db3a7848-7308-4879-942a-c4a70ced400a", - "type": "participant-declaration", - "attributes": { - "participant_id": "bf3c6251-f2a0-4690-a859-0fbecc6ed151", - "declaration_type": "started", - "declaration_date": "2020-11-13T11:21:55Z", - "course_identifier": "ecf-mentor", - "state": "eligible", - "updated_at": "2020-11-13T11:21:55Z", - "created_at": "2020-11-13T11:21:55Z", - "delivery_partner_id": null, - "statement_id": "1cceffd7-0efd-432a-aedc-7be2d6cc72a2", - "clawback_statement_id": null, - "ineligible_for_funding_reason": null, - "mentor_id": null, - "uplift_paid": true, - "evidence_held": "other", - "has_passed": null, - "lead_provider_name": "Example Institute" - } - } - ] - } - } - }, - "schema": { - "$ref": "#/components/schemas/MultipleParticipantDeclarationsResponse" - } - } - } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorisedResponse" - } - } - } - } - } - }, - "post": { - "summary": "Note, this endpoint includes updated specifications.
Declare a participant has reached a milestone. Idempotent endpoint - submitting exact copy of a request will return the same response body as submitting it the first time.", - "operationId": "participant_declaration_create", - "tags": [ - "Participant declarations" - ], - "security": [ - { - "bearerAuth": [ - - ] - } - ], - "parameters": [ - - ], - "responses": { - "200": { - "description": "Successful", - "content": { - "application/json": { - "examples": { - "success_ecf": { - "value": { - "data": { - "id": "db3a7848-7308-4879-942a-c4a70ced400a", - "type": "participant-declaration", + "type": "participant-declaration", "attributes": { "participant_id": "08d78829-f864-417f-8a30-cb7655714e28", "declaration_type": "started", @@ -1934,16 +1632,6 @@ } } }, - "422": { - "description": "Bad or Missing parameter", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, "401": { "description": "Unauthorized", "content": { @@ -1954,33 +1642,23 @@ } } }, - "400": { - "description": "Bad Request", + "404": { + "description": "Not found", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BadRequestResponse" + "$ref": "#/components/schemas/NotFoundResponse" } } } } - }, - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ParticipantDeclarationRequest" - } - } - }, - "required": true } } }, - "/api/v3/participant-declarations/{id}": { - "get": { - "summary": "Note, this endpoint includes updated specifications.
Get single participant declaration", - "operationId": "participant_declaration", + "/api/v3/participant-declarations/{id}/void": { + "put": { + "summary": "Note, this endpoint includes updated specifications.
Void a declaration - it will not be soft-deleted", + "operationId": "participant_declaration_void", "tags": [ "Participant declarations" ], @@ -1996,8 +1674,8 @@ "name": "id", "in": "path", "required": true, - "example": "9ed4612b-f8bd-44d9-b296-38ab103fadd2", - "description": "The ID of the participant declaration ID", + "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", + "description": "The ID of the declaration to void", "schema": { "type": "string", "format": "uuid" @@ -2006,7 +1684,7 @@ ], "responses": { "200": { - "description": "A single participant declaration", + "description": "Successful", "content": { "application/json": { "examples": { @@ -2020,7 +1698,7 @@ "declaration_type": "started", "declaration_date": "2020-11-13T11:21:55Z", "course_identifier": "ecf-induction", - "state": "eligible", + "state": "voided", "updated_at": "2020-11-13T11:21:55Z", "created_at": "2020-11-13T11:21:55Z", "delivery_partner_id": "99ca2223-8c1f-4ac8-985d-a0672e97694e", @@ -2046,7 +1724,7 @@ "declaration_type": "started", "declaration_date": "2020-11-13T11:21:55Z", "course_identifier": "npq-leading-teaching", - "state": "eligible", + "state": "voided", "updated_at": "2020-11-13T11:21:55Z", "created_at": "2020-11-13T11:21:55Z", "delivery_partner_id": null, @@ -2068,36 +1746,16 @@ } } } - }, - "401": { - "description": "Unauthorized", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UnauthorisedResponse" - } - } - } - }, - "404": { - "description": "Not found", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NotFoundResponse" - } - } - } } } } }, - "/api/v3/participant-declarations/{id}/void": { - "put": { - "summary": "Note, this endpoint includes updated specifications.
Void a declaration - it will not be soft-deleted", - "operationId": "participant_declaration_void", + "/api/v3/participants/ecf": { + "get": { + "summary": "Note, this endpoint includes updated specifications.
Retrieve multiple participants, replaces /api/v3/participants", + "operationId": "participants", "tags": [ - "Participant declarations" + "ECF participants" ], "security": [ { @@ -2108,103 +1766,8 @@ ], "parameters": [ { - "name": "id", - "in": "path", - "required": true, - "example": "28c461ee-ffc0-4e56-96bd-788579a0ed75", - "description": "The ID of the declaration to void", - "schema": { - "type": "string", - "format": "uuid" - } - } - ], - "responses": { - "200": { - "description": "Successful", - "content": { - "application/json": { - "examples": { - "success_ecf": { - "value": { - "data": { - "id": "db3a7848-7308-4879-942a-c4a70ced400a", - "type": "participant-declaration", - "attributes": { - "participant_id": "08d78829-f864-417f-8a30-cb7655714e28", - "declaration_type": "started", - "declaration_date": "2020-11-13T11:21:55Z", - "course_identifier": "ecf-induction", - "state": "voided", - "updated_at": "2020-11-13T11:21:55Z", - "created_at": "2020-11-13T11:21:55Z", - "delivery_partner_id": "99ca2223-8c1f-4ac8-985d-a0672e97694e", - "statement_id": "99ca2223-8c1f-4ac8-985d-a0672e97694e", - "clawback_statement_id": null, - "ineligible_for_funding_reason": null, - "mentor_id": "907f61ed-5770-4d38-b22c-1a4265939378", - "uplift_paid": true, - "evidence_held": "other", - "has_passed": null, - "lead_provider_name": "Example Institute" - } - } - } - }, - "success_npq": { - "value": { - "data": { - "id": "db3a7848-7308-4879-942a-c4a70ced400a", - "type": "participant-declaration", - "attributes": { - "participant_id": "bf3c6251-f2a0-4690-a859-0fbecc6ed151", - "declaration_type": "started", - "declaration_date": "2020-11-13T11:21:55Z", - "course_identifier": "npq-leading-teaching", - "state": "voided", - "updated_at": "2020-11-13T11:21:55Z", - "created_at": "2020-11-13T11:21:55Z", - "delivery_partner_id": null, - "statement_id": "1cceffd7-0efd-432a-aedc-7be2d6cc72a2", - "clawback_statement_id": null, - "ineligible_for_funding_reason": null, - "mentor_id": null, - "uplift_paid": true, - "evidence_held": null, - "has_passed": null, - "lead_provider_name": "Example Institute" - } - } - } - } - }, - "schema": { - "$ref": "#/components/schemas/SingleParticipantDeclarationResponse" - } - } - } - } - } - } - }, - "/api/v3/participants/ecf": { - "get": { - "summary": "Note, this endpoint includes updated specifications.
Retrieve multiple participants, replaces /api/v3/participants", - "operationId": "participants", - "tags": [ - "ECF participants" - ], - "security": [ - { - "bearerAuth": [ - - ] - } - ], - "parameters": [ - { - "name": "filter", - "in": "query", + "name": "filter", + "in": "query", "schema": { "$ref": "#/components/schemas/ECFParticipantFilter" }, @@ -4959,58 +4522,6 @@ } } }, - "MultipleNPQApplicationsResponse": { - "description": "A list of NPQ applications", - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NPQApplication" - }, - "example": [ - { - "id": "db3a7848-7308-4879-942a-c4a70ced400a", - "type": "npq_application", - "attributes": { - "course_identifier": "npq-leading-teaching-development", - "email": "isabelle.macdonald2@some-school.example.com", - "email_validated": true, - "employer_name": null, - "employment_role": null, - "full_name": "Isabelle MacDonald", - "funding_choice": null, - "headteacher_status": null, - "ineligible_for_funding_reason": null, - "participant_id": "53847955-7cfg-41eb-a322-96c50adc742b", - "private_childcare_provider_urn": null, - "teacher_reference_number": "0743795", - "teacher_reference_number_validated": true, - "school_urn": "123456", - "school_ukprn": "12345678", - "status": "pending", - "works_in_school": true, - "created_at": "2022-07-06T10:47:24Z", - "updated_at": "2022-11-24T17:09:37Z", - "cohort": "2022", - "eligible_for_funding": true, - "funded_place": true, - "targeted_delivery_funding_eligibility": true, - "teacher_catchment": true, - "teacher_catchment_iso_country_code": "FRA", - "teacher_catchment_country": "France", - "itt_provider": "University of Southampton", - "lead_mentor": true, - "schedule_identifier": "npq-leadership-spring" - } - } - ] - } - } - }, "MultipleNPQParticipantsResponse": { "description": "A list of NPQ participants", "type": "object", @@ -5078,494 +4589,6 @@ } } }, - "NPQApplication": { - "description": "The details of an NPQ Application", - "type": "object", - "required": [ - "id", - "type", - "attributes" - ], - "properties": { - "id": { - "description": "The unique identifier of the NPQ Application record", - "type": "string", - "format": "uuid", - "example": "db3a7848-7308-4879-942a-c4a70ced400a" - }, - "type": { - "description": "The data type", - "type": "string", - "example": "npq_application", - "enum": [ - "npq_application" - ] - }, - "attributes": { - "$ref": "#/components/schemas/NPQApplicationAttributes" - } - } - }, - "NPQApplicationAcceptErrorResponse": { - "description": "A list of errors", - "type": "object", - "properties": { - "error": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/components/schemas/NPQApplicationAlreadyAccepted" - }, - { - "$ref": "#/components/schemas/NPQApplicationChangedFromRejected" - } - ] - } - } - } - }, - "NPQApplicationAlreadyAccepted": { - "description": "NPQ Application has already been accepted", - "type": "object", - "properties": { - "title": { - "description": "The title of the error", - "type": "string", - "enum": [ - "NPQ Application has already been accepted" - ], - "example": "NPQ Application has already been accepted" - }, - "detail": { - "description": "Additional info about the error", - "type": "string", - "example": "You cannot accept this NPQ application as it has already been accepted" - } - } - }, - "NPQApplicationChangedFromRejected": { - "description": "Once rejected an application cannot change state", - "type": "object", - "properties": { - "title": { - "description": "The title of the error", - "type": "string", - "enum": [ - "Once rejected an application cannot change state" - ], - "example": "Once rejected an application cannot change state" - }, - "detail": { - "description": "Additional info about the error", - "type": "string", - "example": "You cannot accept this NPQ application as it has already been rejected" - } - } - }, - "NPQApplicationAcceptAttributesRequest": { - "description": "The NPQ Application acceptance request", - "type": "object", - "properties": { - "funded_place": { - "description": "Whether the participant has a funded place", - "type": "boolean", - "example": true - }, - "schedule_identifier": { - "description": "The new schedule of the participant", - "type": "string", - "enum": [ - "npq-aso-march", - "npq-aso-june", - "npq-aso-november", - "npq-aso-december", - "npq-ehco-march", - "npq-ehco-june", - "npq-ehco-november", - "npq-ehco-december", - "npq-leadership-autumn", - "npq-leadership-spring", - "npq-specialist-autumn", - "npq-specialist-spring" - ], - "example": "npq-leadership-spring" - } - } - }, - "NPQApplicationAcceptDataRequest": { - "description": "The NPQ Application acceptance request attributes", - "type": "object", - "required": [ - "type", - "data" - ], - "properties": { - "type": { - "description": "The data type", - "type": "string", - "example": "npq-application-accept" - }, - "data": { - "$ref": "#/components/schemas/NPQApplicationAcceptAttributesRequest" - } - } - }, - "NPQApplicationAcceptRequest": { - "description": "The NPQ Application acceptance request", - "type": "object", - "properties": { - "data": { - "$ref": "#/components/schemas/NPQApplicationAcceptDataRequest" - } - }, - "example": { - "data": { - "type": "npq-application-accept", - "attributes": { - "schedule_identifier": "npq-leadership-spring", - "funded_place": true - } - } - } - }, - "NPQApplicationAttributes": { - "description": "The data attributes associated with an NPQ application", - "type": "object", - "required": [ - "participant_id", - "full_name", - "email", - "email_validated", - "teacher_reference_number", - "teacher_reference_number_validated", - "eligible_for_funding", - "course_identifier", - "status", - "created_at", - "updated_at" - ], - "properties": { - "participant_id": { - "description": "The unique identifier of this NPQ participant", - "type": "string", - "example": "7a8fef46-3c43-42c0-b3d5-1ba5904ba562", - "format": "uuid" - }, - "full_name": { - "description": "The full name of this NPQ participant", - "type": "string", - "example": "Isabelle MacDonald" - }, - "email": { - "description": "The email address registered for this NPQ participant", - "type": "string", - "example": "isabelle.macdonald2@some-school.example.com" - }, - "email_validated": { - "description": "Indicates whether the email address has been validated", - "type": "boolean", - "example": true - }, - "teacher_reference_number": { - "description": "The Teacher Reference Number (TRN) for this NPQ participant", - "type": "string", - "example": "1234567" - }, - "teacher_reference_number_validated": { - "description": "Indicates whether the Teacher Reference Number (TRN) has been validated", - "type": "boolean", - "example": true - }, - "works_in_school": { - "description": "Indicates whether the participant is currently employed by school", - "type": "boolean", - "example": true - }, - "employer_name": { - "description": "The name of current employer of the participant if not currently employed by school", - "type": "string", - "nullable": true, - "example": "Some Company Ltd" - }, - "employment_role": { - "description": "Participant's current role in the company they are employed in if not currently employed by school", - "type": "string", - "nullable": true, - "example": "Director" - }, - "school_urn": { - "description": "The Unique Reference Number (URN) of the school where this NPQ participant is employed", - "type": "string", - "example": "106286" - }, - "private_childcare_provider_urn": { - "description": "The Unique Reference Number (URN) of the private child care provider", - "type": "string", - "example": "EY944860", - "nullable": true - }, - "school_ukprn": { - "description": "The UK Provider Reference Number (UK Provider Reference Number) of the school where this NPQ participant is employed", - "type": "string", - "example": "10079319" - }, - "headteacher_status": { - "description": "Indicates whether this NPQ participant is or will be a head teacher", - "type": "string", - "example": "no", - "enum": [ - "no", - "yes_when_course_starts", - "yes_in_first_two_years", - "yes_over_two_years", - "yes_in_first_five_years", - "yes_over_five_years" - ] - }, - "eligible_for_funding": { - "description": "Indicates whether or not this participant is eligible for DfE funding", - "type": "boolean", - "example": true - }, - "funded_place": { - "description": "Indicates whether or not this participant's training is being funded by DfE", - "type": "boolean", - "example": true - }, - "funding_choice": { - "description": "Indicates how this NPQ participant has said they will funded their training", - "type": "string", - "example": "trust", - "enum": [ - "school", - "trust", - "self", - "another", - "employer" - ] - }, - "course_identifier": { - "description": "The NPQ course this NPQ application relates to", - "type": "string", - "example": "npq-leading-teaching", - "enum": [ - "npq-leading-teaching", - "npq-leading-behaviour-culture", - "npq-leading-teaching-development", - "npq-leading-literacy", - "npq-senior-leadership", - "npq-headship", - "npq-executive-leadership", - "npq-early-years-leadership", - "npq-additional-support-offer", - "npq-early-headship-coaching-offer", - "npq-leading-primary-mathematics", - "npq-senco" - ] - }, - "status": { - "description": "The current state of the NPQ application", - "type": "string", - "example": "pending", - "enum": [ - "pending", - "accepted", - "rejected" - ] - }, - "created_at": { - "description": "The date the application was created", - "type": "string", - "format": "date-time", - "example": "2021-05-31T02:21:32.000Z" - }, - "updated_at": { - "description": "The date the application was last updated", - "type": "string", - "format": "date-time", - "example": "2021-05-31T02:22:32.000Z" - }, - "ineligible_for_funding_reason": { - "description": "Indicates why this NPQ participant is not eligible for DfE funding", - "type": "string", - "nullable": true, - "example": "establishment-ineligible", - "enum": [ - "establishment-ineligible", - "previously-funded" - ] - }, - "cohort": { - "description": "Indicates which call-off contract would fund this participant's training. 2021 indicates a participant that has started, or will start, their training in the 2021/22 academic year. Once a provider accepts an application, they may change a participant's cohort up until the point of submitting a started declaration.", - "type": "string", - "nullable": false, - "example": "2022" - }, - "targeted_delivery_funding_eligibility": { - "description": "Whether or not this application is eligible for Targeted Delivery Funding uplift", - "nullable": false, - "type": "boolean", - "example": true - }, - "teacher_catchment": { - "description": "This field will indicate whether or not the participant is UK-based. ", - "nullable": true, - "type": "boolean", - "example": true - }, - "teacher_catchment_country": { - "nullable": true, - "type": "string", - "example": "France" - }, - "teacher_catchment_iso_country_code": { - "description": "This field identifies which non-UK country the participant has registered from.\nThe API uses ISO 3166 alpha-3 codes, three-letter codes published by the International Organization for Standardization (ISO) to represent countries, dependent territories, and special areas of geographical interest.\n", - "nullable": true, - "type": "string", - "example": "FRA" - }, - "lead_mentor": { - "description": "This field indicates whether the applicant is an ITT lead mentor.\n", - "nullable": true, - "type": "boolean", - "example": true - }, - "itt_provider": { - "description": "This field contains the legal name of the ITT accredited provider from the list of providers.\n", - "nullable": true, - "type": "string", - "example": "University of Southampton" - }, - "schedule_identifier": { - "description": "The new schedule of the participant", - "nullable": true, - "type": "string", - "example": "npq-leadership-spring", - "enum": [ - "npq-aso-march", - "npq-aso-june", - "npq-aso-november", - "npq-aso-december", - "npq-ehco-march", - "npq-ehco-june", - "npq-ehco-november", - "npq-ehco-december", - "npq-leadership-autumn", - "npq-leadership-spring", - "npq-specialist-autumn", - "npq-specialist-spring" - ] - } - } - }, - "NPQApplicationRejectErrorResponse": { - "description": "A list of errors", - "type": "object", - "properties": { - "error": { - "type": "array", - "items": { - "anyOf": [ - { - "$ref": "#/components/schemas/NPQApplicationAlreadyRejected" - }, - { - "$ref": "#/components/schemas/NPQApplicationChangedFromAccepted" - } - ] - } - } - } - }, - "NPQApplicationAlreadyRejected": { - "description": "NPQ Application has already been rejected", - "type": "object", - "properties": { - "title": { - "description": "The title of the error", - "type": "string", - "enum": [ - "NPQ Application has already been rejected" - ], - "example": "NPQ Application has already been rejected" - }, - "detail": { - "description": "Additional info about the error", - "type": "string", - "example": "You cannot reject this NPQ application as it has already been rejected" - } - } - }, - "NPQApplicationChangedFromAccepted": { - "description": "Once accepted an application cannot change state", - "type": "object", - "properties": { - "title": { - "description": "The title of the error", - "type": "string", - "enum": [ - "Once accepted an application cannot change state" - ], - "example": "Once accepted an application cannot change state" - }, - "detail": { - "description": "Additional info about the error", - "type": "string", - "example": "You cannot reject this NPQ application as it has already been accepted" - } - } - }, - "NPQApplicationResponse": { - "description": "An NPQ application", - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "$ref": "#/components/schemas/NPQApplication" - } - } - }, - "NPQApplicationsFilter": { - "description": "Filter NPQ applications to return more specific results", - "type": "object", - "properties": { - "updated_since": { - "description": "Return only records that have been updated since this date and time (ISO 8601 date format)", - "type": "string", - "example": "2021-05-13T11:21:55Z" - }, - "cohort": { - "description": "Return only NPQ applications from the specified cohort or cohorts. This is a comma delimited string of years.", - "type": "string", - "example": [ - 20212022 - ] - }, - "participant_id": { - "description": "Return only NPQ applications from the specified participant or participants. This is comma delimited string of participant IDs", - "type": "string", - "example": [ - "117f9f24-b610-4f8e-bf49-f253230cfc70,7bdfb2fc-23a1-486f-bfd5-db69d13866de" - ] - } - } - }, - "NPQApplicationsSort": { - "description": "Sort NPQ applications being returned", - "type": "array", - "items": { - "type": "string", - "enum": [ - "created_at", - "-created_at", - "updated_at", - "-updated_at" - ] - } - }, "NPQEnrolment": { "description": "The details of an NPQ Participant enrolment", "type": "object", diff --git a/spec/forms/choose_role_form_spec.rb b/spec/forms/choose_role_form_spec.rb index 77d0eaeac8..b1c8166b9c 100644 --- a/spec/forms/choose_role_form_spec.rb +++ b/spec/forms/choose_role_form_spec.rb @@ -273,22 +273,6 @@ def participant_start_path(_user) end describe "NPQ roles" do - describe "NPQ applicant" do - let(:user) { create(:seed_npq_application, :valid).user } - - it "has no role" do - expect(form.has_no_role).to be true - end - - it "only_one_role should be false" do - expect(form.only_one_role).to be false - end - - it "has correct role_options" do - expect(form.role_options).to be_empty - end - end - describe "NPQ participant" do let(:user) { create(:user, :npq) } diff --git a/spec/models/cohort_spec.rb b/spec/models/cohort_spec.rb index 4c0e3b4532..646f6469be 100644 --- a/spec/models/cohort_spec.rb +++ b/spec/models/cohort_spec.rb @@ -7,7 +7,6 @@ describe "associations" do it { is_expected.to have_many(:call_off_contracts) } - it { is_expected.to have_many(:npq_contracts) } it { is_expected.to have_many(:partnerships) } it { is_expected.to have_many(:schedules).class_name("Finance::Schedule::ECF") } it { is_expected.to have_many(:statements).class_name("Finance::Statement") } diff --git a/spec/models/cpd_lead_provider_spec.rb b/spec/models/cpd_lead_provider_spec.rb index fc2a2e7a39..9b70373f93 100644 --- a/spec/models/cpd_lead_provider_spec.rb +++ b/spec/models/cpd_lead_provider_spec.rb @@ -11,7 +11,6 @@ describe "associations" do it { is_expected.to have_one(:lead_provider) } - it { is_expected.to have_one(:npq_lead_provider) } it { is_expected.to have_many(:participant_declarations) } end end diff --git a/spec/models/delivery_partner_spec.rb b/spec/models/delivery_partner_spec.rb index 35d4137af8..4b6633b509 100644 --- a/spec/models/delivery_partner_spec.rb +++ b/spec/models/delivery_partner_spec.rb @@ -49,7 +49,7 @@ describe "participant_profiles" do let(:delivery_partner) { create(:delivery_partner) } - let(:lead_provider) { create(:cpd_lead_provider, :with_lead_provider, :with_npq_lead_provider).lead_provider } + let(:lead_provider) { create(:cpd_lead_provider, :with_lead_provider).lead_provider } let(:school_cohort) { create(:school_cohort, :with_induction_programme, delivery_partner:, lead_provider:) } it "should include active participants" do @@ -66,16 +66,11 @@ participant_profile = create(:mentor, school_cohort:, lead_provider:) expect(delivery_partner.ecf_participant_profiles).to include participant_profile end - - it "should not include NPQ participants" do - participant_profile = create(:npq_participant_profile, npq_lead_provider: lead_provider.cpd_lead_provider.npq_lead_provider) - expect(delivery_partner.ecf_participant_profiles).not_to include participant_profile - end end describe "active_ecf_participant_profiles" do let(:delivery_partner) { create(:delivery_partner) } - let(:lead_provider) { create(:cpd_lead_provider, :with_lead_provider, :with_npq_lead_provider).lead_provider } + let(:lead_provider) { create(:cpd_lead_provider, :with_lead_provider).lead_provider } let(:school_cohort) { create(:school_cohort, :with_induction_programme, delivery_partner:, lead_provider:) } it "should include active participants" do @@ -87,11 +82,6 @@ participant_profile = create(:ect, :withdrawn_record, school_cohort:, lead_provider:) expect(delivery_partner.active_ecf_participant_profiles).not_to include participant_profile end - - it "should not include NPQ participants" do - participant_profile = create(:npq_participant_profile, npq_lead_provider: lead_provider.cpd_lead_provider.npq_lead_provider) - expect(delivery_partner.active_ecf_participant_profiles).not_to include participant_profile - end end describe "soft delete" do diff --git a/spec/models/lead_provider_spec.rb b/spec/models/lead_provider_spec.rb index 4917cbaeec..702446eb4b 100644 --- a/spec/models/lead_provider_spec.rb +++ b/spec/models/lead_provider_spec.rb @@ -41,7 +41,7 @@ describe "participant_profiles" do let(:school) { partnership.school } - let(:cpd_lead_provider) { create(:cpd_lead_provider, :with_lead_provider, :with_npq_lead_provider) } + let(:cpd_lead_provider) { create(:cpd_lead_provider, :with_lead_provider) } let(:lead_provider) { cpd_lead_provider.lead_provider } let(:partnership) { create(:partnership, lead_provider:) } let(:school_cohort) { create(:school_cohort, school:) } @@ -60,11 +60,6 @@ participant_profile = create(:mentor, school_cohort:, lead_provider:) expect(lead_provider.ecf_participant_profiles).to include participant_profile end - - it "should not include NPQ participants" do - participant_profile = create(:npq_participant_profile, npq_lead_provider: cpd_lead_provider.npq_lead_provider) - expect(lead_provider.ecf_participant_profiles).not_to include participant_profile - end end describe "active_ecf_participant_profiles" do @@ -82,11 +77,6 @@ participant_profile = create(:ect_participant_profile, :withdrawn_record, school_cohort:) expect(lead_provider.active_ecf_participant_profiles).not_to include participant_profile end - - it "should not include NPQ participants" do - participant_profile = create(:npq_participant_profile, school:) - expect(lead_provider.active_ecf_participant_profiles).not_to include participant_profile - end end describe "#first_training_year" do diff --git a/spec/models/npq_application_spec.rb b/spec/models/npq_application_spec.rb deleted file mode 100644 index dd510e777c..0000000000 --- a/spec/models/npq_application_spec.rb +++ /dev/null @@ -1,122 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe NPQApplication, type: :model do - it { - is_expected.to define_enum_for(:headteacher_status).with_values( - no: "no", - yes_when_course_starts: "yes_when_course_starts", - yes_in_first_two_years: "yes_in_first_two_years", - yes_over_two_years: "yes_over_two_years", - yes_in_first_five_years: "yes_in_first_five_years", - yes_over_five_years: "yes_over_five_years", - ).backed_by_column_of_type(:text) - } - - describe "#latest_completed_participant_declaration" do - context "when participant_declaration not exist" do - let(:npq_application) { create(:npq_application) } - - it "returns nil" do - result = npq_application.latest_completed_participant_declaration - expect(result).to eq(nil) - end - end - end - - describe "Change logs for NPQ applications" do - before do - PaperTrail.config.enabled = true - end - - after do - PaperTrail.config.enabled = false - end - - describe "#change_log" do - subject do - create :npq_application, eligible_for_funding: false, funding_eligiblity_status_code: "marked_ineligible_by_policy", works_in_school: true - end - - it "returns a list of changes for `eligible_for_funding`" do - expect { subject.update!(eligible_for_funding: true) } - .to change { subject.change_logs.count }.by(1) - end - - it "returns a list of changes for `funding_eligiblity_status_code`" do - expect { subject.update!(funding_eligiblity_status_code: "re_register") } - .to change { subject.change_logs.count }.by(1) - end - - it "returns an empty list if any of the attributes is changed" do - expect { subject.update!(works_in_school: false) } - .to change { subject.change_logs.count }.by(0) - end - - it "returns a list of changes grouped" do - expect { subject.update!(eligible_for_funding: true, funding_eligiblity_status_code: "re_register") } - .to change { subject.change_logs.count }.by(1) - end - - it "sorts the changes by created_at" do - subject.update!(eligible_for_funding: true, funding_eligiblity_status_code: "re_register") - subject.update!(eligible_for_funding: false, funding_eligiblity_status_code: "marked_ineligible_by_policy") - subject.update!(eligible_for_funding: true) - subject.update!(eligible_for_funding: false) - - change_logs = subject.change_logs - created_ats = change_logs.map(&:created_at) - - expect(created_ats).to eq(created_ats.sort.reverse) - end - - it "return a list of Version objects" do - subject.update!(eligible_for_funding: true, funding_eligiblity_status_code: "re_register") - - expect(subject.change_logs).to all(satisfy { |change_log| change_log.is_a?(PaperTrail::Version) }) - end - end - - describe "changelog configuration via Papertrail" do - subject do - create(:npq_application, works_in_school: true) - end - - it "does not create an entry if attribute is not changed" do - expect { subject.update!(works_in_school: false) } - .to_not change { subject.versions.where_attribute_changes("eligible_for_funding").count } - end - - context "with changes on eligible_for_funding" do - before do - subject.update! eligible_for_funding: true - end - - it "creates an entry if attribute is changed" do - expect { subject.update!(eligible_for_funding: false) } - .to change { subject.versions.where_attribute_changes("eligible_for_funding").count }.by(1) - end - - it "does not create an entry if attribute is the same" do - expect { subject.update!(eligible_for_funding: true) } - .to_not change { subject.versions.where_attribute_changes("eligible_for_funding").count } - end - end - - context "with changes on funding_eligiblity_status_code" do - before do - subject.update! funding_eligiblity_status_code: "marked_ineligible_by_policy" - end - - it "creates an entry if attribute is changed" do - expect { subject.update!(funding_eligiblity_status_code: "re_register") } - .to change { subject.versions.where_attribute_changes("funding_eligiblity_status_code").count }.by(1) - end - - it "does not create an entry if attribute is the same" do - expect { subject.update!(funding_eligiblity_status_code: "marked_ineligible_by_policy") } - .to_not change { subject.versions.where_attribute_changes("funding_eligiblity_status_code").count } - end - end - end - end -end diff --git a/spec/models/npq_contract_spec.rb b/spec/models/npq_contract_spec.rb deleted file mode 100644 index cb16760b7c..0000000000 --- a/spec/models/npq_contract_spec.rb +++ /dev/null @@ -1,91 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe NPQContract do - it { is_expected.to belong_to(:cohort) } - - describe "associations" do - it { is_expected.to belong_to(:npq_lead_provider) } - it { is_expected.to belong_to(:cohort) } - it { is_expected.to belong_to(:npq_course).with_primary_key("identifier").with_foreign_key("course_identifier") } - end - - describe "validations" do - it { is_expected.to validate_numericality_of(:number_of_payment_periods).is_greater_than_or_equal_to(0).only_integer } - it { is_expected.to validate_numericality_of(:output_payment_percentage).is_greater_than_or_equal_to(0).only_integer } - it { is_expected.to validate_numericality_of(:service_fee_installments).is_greater_than_or_equal_to(0).only_integer } - it { is_expected.to validate_numericality_of(:service_fee_percentage).is_greater_than_or_equal_to(0).only_integer } - it { is_expected.to validate_numericality_of(:per_participant).is_greater_than(0) } - it { is_expected.to validate_numericality_of(:recruitment_target).is_greater_than(0).only_integer } - it { is_expected.to validate_numericality_of(:funding_cap).is_greater_than_or_equal_to(0).only_integer.allow_nil } - end - - describe ".find_latest_by" do - let(:cohort) { create(:cohort) } - let(:npq_application) { create(:npq_application, eligible_for_funding: true, npq_course:, npq_lead_provider:, cohort:) } - let(:npq_lead_provider) { create(:npq_lead_provider) } - let(:npq_course) { create(:npq_leadership_course, identifier: "npq-senior-leadership") } - let(:statement) do - create( - :npq_statement, - :next_output_fee, - cpd_lead_provider: npq_lead_provider.cpd_lead_provider, - cohort: npq_application.cohort, - ) - end - - let!(:npq_contract) do - create(:npq_contract, - npq_lead_provider:, - cohort: statement.cohort, - course_identifier: npq_course.identifier, - version: statement.contract_version, - funding_cap: 10) - end - - it "returns the latest NPQContract" do - contract = described_class.find_latest_by( - npq_lead_provider:, - npq_course:, - cohort:, - ) - - expect(contract).to eq(npq_contract) - end - - context "when cohort is different" do - it "returns `nil` if cohort is different" do - contract = described_class.find_latest_by( - npq_lead_provider:, - npq_course:, - cohort: create(:cohort), - ) - - expect(contract).to be_nil - end - end - - context "when npq_course is different" do - it "returns `nil` if npq_course is different" do - contract = described_class.find_latest_by( - npq_lead_provider:, - npq_course: create(:npq_leadership_course, identifier: "npq-headship"), - cohort:, - ) - - expect(contract).to be_nil - end - end - - it "returns `nil` if npq_lead_provider is different" do - contract = described_class.find_latest_by( - npq_lead_provider: create(:npq_lead_provider), - npq_course:, - cohort:, - ) - - expect(contract).to be_nil - end - end -end diff --git a/spec/models/npq_course_spec.rb b/spec/models/npq_course_spec.rb deleted file mode 100644 index 6e91998c39..0000000000 --- a/spec/models/npq_course_spec.rb +++ /dev/null @@ -1,61 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" -RSpec.describe NPQCourse do - describe "::schedule_for" do - let(:npq_course) { build(:npq_course, identifier:) } - let(:cohort) { Cohort.current } - - context "when a course is one of NPQCourse::LEADERSHIP_IDENTIFIER" do - let(:identifier) { Finance::Schedule::NPQLeadership::IDENTIFIERS.sample } - - it "returns the default NPQ leadership schedule" do - expect(described_class.schedule_for(npq_course:, cohort:)) - .to eq(Finance::Schedule::NPQLeadership.schedule_for(cohort:)) - end - - context "when requesting for next cohort" do - let(:next_cohort) { Cohort.next || create(:cohort, :next) } - - it "uses next cohort schedule" do - expect(described_class.schedule_for(npq_course:, cohort: next_cohort)).to eql(Finance::Schedule::NPQLeadership.schedule_for(cohort: next_cohort)) - end - end - end - - context "when a course is one of NPQCourse::SPECIALIST_IDENTIFIER" do - let(:identifier) { Finance::Schedule::NPQSpecialist::IDENTIFIERS.sample } - - it "returns the default NPQ specialist schedule" do - expect(described_class.schedule_for(npq_course:, cohort:)).to eq(Finance::Schedule::NPQSpecialist.schedule_for(cohort:)) - end - end - - context "when a course is Additional Support Offer" do - let(:identifier) { "npq-additional-support-offer" } - - it "returns the default NPQ support schedule" do - expect(described_class.schedule_for(npq_course:)).to eq(Finance::Schedule::NPQSupport.default) - end - end - - context "when a course is Early Headship Coaching Offer" do - let(:identifier) { "npq-early-headship-coaching-offer" } - - it "returns the default NPQ EHCO schedule" do - expected_schedule = Finance::Schedule::NPQEhco.schedule_for(cohort:) - - expect(described_class.schedule_for(npq_course:)).to eq(expected_schedule) - end - end - - context "with and unknown course identifier" do - let(:identifier) { "unknown-course-identifier" } - - it { - expect { described_class.schedule_for(npq_course:) } - .to raise_error(ArgumentError, "Invalid course identifier") - } - end - end -end diff --git a/spec/models/npq_lead_provider_spec.rb b/spec/models/npq_lead_provider_spec.rb deleted file mode 100644 index 0bafed8dfc..0000000000 --- a/spec/models/npq_lead_provider_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe NPQLeadProvider, type: :model do - it "can be created" do - expect { - described_class.create(name: "Test Lead Provider") - }.to change { described_class.count }.by(1) - end - - describe "associations" do - it { is_expected.to belong_to(:cpd_lead_provider).required(false) } - it { is_expected.to have_many(:statements).through(:cpd_lead_provider).class_name("Finance::Statement::NPQ").source(:npq_statements) } - end - - describe "scopes" do - describe "name_order" do - let!(:provider_one) { FactoryBot.create(:npq_lead_provider, name: "Lead Provider Example") } - let!(:provider_two) { FactoryBot.create(:npq_lead_provider, name: "Another Lead Provider Example") } - - it "returns all providers in name order" do - expect(described_class.name_order).to eq([provider_two, provider_one]) - end - end - end -end diff --git a/spec/models/participant_identity_spec.rb b/spec/models/participant_identity_spec.rb index cf9713ed02..35793a03c6 100644 --- a/spec/models/participant_identity_spec.rb +++ b/spec/models/participant_identity_spec.rb @@ -14,7 +14,6 @@ it { is_expected.to belong_to(:user) } it { is_expected.to have_many(:participant_profiles) } - it { is_expected.to have_many(:npq_applications) } it { is_expected.to define_enum_for(:origin).with_values( ecf: "ecf", diff --git a/spec/models/participant_profile/npq_spec.rb b/spec/models/participant_profile/npq_spec.rb index a98d718b54..7b374f3382 100644 --- a/spec/models/participant_profile/npq_spec.rb +++ b/spec/models/participant_profile/npq_spec.rb @@ -3,12 +3,10 @@ require "rails_helper" RSpec.describe ParticipantProfile::NPQ, type: :model do - let(:npq_application) { create(:npq_application, :accepted) } - let(:profile) { npq_application.profile } + let(:profile) { create(:npq_participant_profile) } + let(:cpd_lead_provider) { nil } describe "#withdrawn_for" do - let(:cpd_lead_provider) { subject.npq_application.npq_lead_provider.cpd_lead_provider } - context "when participant is not withdrawn" do subject { create(:npq_participant_profile) } @@ -19,8 +17,6 @@ end describe "#active_for" do - let(:cpd_lead_provider) { subject.npq_application.npq_lead_provider.cpd_lead_provider } - context "when participant is active" do subject { create(:npq_participant_profile) } @@ -31,8 +27,6 @@ end describe "#deferred_for" do - let(:cpd_lead_provider) { subject.npq_application.npq_lead_provider.cpd_lead_provider } - context "when participant is deferred" do subject { create(:npq_participant_profile, :deferred) } @@ -51,9 +45,7 @@ end describe "#record_to_serialize_for" do - let(:lead_provider) do - subject.npq_application.npq_lead_provider - end + let(:lead_provider) { nil } subject { create(:npq_participant_profile) } @@ -61,41 +53,4 @@ expect(subject.record_to_serialize_for(lead_provider:)).to eq(subject.user) end end - - describe "#fundable?" do - context "when it is eligible_for_funding" do - let(:npq_application) { create(:npq_application, :accepted, eligible_for_funding: true, funded_place: nil) } - subject { profile } - - it { is_expected.to be_fundable } - end - - context "when it is not eligible_for_funding" do - let(:npq_application) { create(:npq_application, :accepted, eligible_for_funding: false, funded_place: nil) } - subject { profile } - - it { is_expected.not_to be_fundable } - end - - context "when it is eligible_for_funding but has no funded place" do - let(:npq_application) { create(:npq_application, :accepted, eligible_for_funding: true, funded_place: false) } - subject { profile } - - it { is_expected.not_to be_fundable } - end - - context "when it is eligible_for_funding but and has a funded place" do - let(:npq_application) { create(:npq_application, :accepted, eligible_for_funding: true, funded_place: true) } - subject { profile } - - it { is_expected.to be_fundable } - end - - context "when it is not eligible_for_funding but and has a funded place" do - let(:npq_application) { create(:npq_application, :accepted, eligible_for_funding: false, funded_place: false) } - subject { profile } - - it { is_expected.not_to be_fundable } - end - end end diff --git a/spec/models/participant_profile_state_spec.rb b/spec/models/participant_profile_state_spec.rb index 4eb35f42b4..9597f06c14 100644 --- a/spec/models/participant_profile_state_spec.rb +++ b/spec/models/participant_profile_state_spec.rb @@ -3,7 +3,7 @@ require "rails_helper" RSpec.describe ParticipantProfileState, type: :model do - let(:participant_profile) { create(:npq_participant_profile) } + let(:participant_profile) { create(:ect_participant_profile) } subject(:participant_profile_state) { create(:participant_profile_state, participant_profile:) } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 029d7ce422..fcc7ade38c 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -143,7 +143,7 @@ end context "when there are transferred identity records" do - let(:identity2) { create(:participant_identity, :npq, email: "mary.e.jones@example.com") } + let(:identity2) { create(:participant_identity, email: "mary.e.jones@example.com") } before do identity2.update!(user:) @@ -443,14 +443,6 @@ expect(create(:user, :mentor).user_roles).to eq(%w[mentor teacher]) end - it "returns npq_participant role" do - expect(create(:user, :npq).user_roles).to eq(%w[npq_participant teacher]) - end - - it "returns npq_applicant role" do - expect(create(:seed_npq_application, :valid).user.user_roles).to eq(%w[npq_applicant]) - end - it "returns induction_coordinator and mentor roles" do expect(create(:user, :mentor, :induction_coordinator).user_roles).to match_array(%w[induction_coordinator mentor teacher]) end diff --git a/spec/policies/participant_profile/ecf_policy_spec.rb b/spec/policies/participant_profile/ecf_policy_spec.rb index 6edc5d9f50..617fede452 100644 --- a/spec/policies/participant_profile/ecf_policy_spec.rb +++ b/spec/policies/participant_profile/ecf_policy_spec.rb @@ -119,23 +119,6 @@ it { is_expected.to permit_action(:update_email) } end end - - context "with an NPQ application" do - before do - create(:npq_application, participant_identity: participant_profile.participant_identity) - end - - it { is_expected.to permit_action(:show) } - it { is_expected.to permit_action(:edit_mentor) } - it { is_expected.to permit_action(:update_mentor) } - it { is_expected.to forbid_action(:new_ect) } - it { is_expected.to forbid_action(:add_ect) } - it { is_expected.to permit_action(:withdraw_record) } - it { is_expected.to permit_action(:edit_name) } - it { is_expected.to permit_action(:update_name) } - it { is_expected.to permit_action(:edit_email) } - it { is_expected.to permit_action(:update_email) } - end end context "induction tutor at the correct school" do @@ -218,23 +201,6 @@ it { is_expected.to forbid_action(:update_email) } end - context "with an NPQ application" do - before do - create(:npq_application, participant_identity: participant_profile.participant_identity) - end - - it { is_expected.to permit_action(:show) } - it { is_expected.to permit_action(:edit_mentor) } - it { is_expected.to permit_action(:update_mentor) } - it { is_expected.to forbid_action(:new_ect) } - it { is_expected.to forbid_action(:add_ect) } - it { is_expected.to permit_action(:withdraw_record) } - it { is_expected.to forbid_action(:edit_name) } - it { is_expected.to forbid_action(:update_name) } - it { is_expected.to forbid_action(:edit_email) } - it { is_expected.to forbid_action(:update_email) } - end - context "with a mentor who is mentoring, but not training at the school" do let(:user) { create(:user, :induction_coordinator) } let(:participant_profile) { create(:mentor_participant_profile) } diff --git a/spec/policies/participant_profile_policy_spec.rb b/spec/policies/participant_profile_policy_spec.rb index b78020fcbe..0671d0f55c 100644 --- a/spec/policies/participant_profile_policy_spec.rb +++ b/spec/policies/participant_profile_policy_spec.rb @@ -11,11 +11,7 @@ let(:user) { create(:user, :admin) } it { is_expected.to permit_action(:show) } it { is_expected.to forbid_actions(%i[edit_cohort update_cohort]) } - - context "NPQ" do - let(:participant_profile) { create(:npq_participant_profile) } - it { is_expected.to forbid_action(:destroy) } - end + it { is_expected.to forbid_action(:destroy) } end context "not an admin" do diff --git a/spec/requests/api/v1/ecf_participants_spec.rb b/spec/requests/api/v1/ecf_participants_spec.rb index 0b7998c003..472c511b12 100644 --- a/spec/requests/api/v1/ecf_participants_spec.rb +++ b/spec/requests/api/v1/ecf_participants_spec.rb @@ -409,18 +409,6 @@ expect(response.status).to eq 403 end end - - context "when using LeadProviderApiToken with only NPQ access" do - let(:cpd_lead_provider) { create(:cpd_lead_provider, npq_lead_provider:, lead_provider: nil) } - let(:npq_lead_provider) { create(:npq_lead_provider) } - let(:token) { LeadProviderApiToken.create_with_random_token!(cpd_lead_provider:) } - - it "returns 403" do - default_headers[:Authorization] = bearer_token - get "/api/v1/participants/ecf" - expect(response.status).to eq 403 - end - end end describe "GET /api/v1/participants/ecf/:id" do diff --git a/spec/requests/api/v1/participants_spec.rb b/spec/requests/api/v1/participants_spec.rb index c38a51376b..bc51d7e75b 100644 --- a/spec/requests/api/v1/participants_spec.rb +++ b/spec/requests/api/v1/participants_spec.rb @@ -331,17 +331,5 @@ expect(response.status).to eq 403 end end - - context "when using LeadProviderApiToken with only NPQ access" do - let(:cpd_lead_provider) { create(:cpd_lead_provider, npq_lead_provider:, lead_provider: nil) } - let(:npq_lead_provider) { create(:npq_lead_provider) } - let(:token) { LeadProviderApiToken.create_with_random_token!(cpd_lead_provider:) } - - it "returns 403" do - default_headers[:Authorization] = bearer_token - get "/api/v1/participants" - expect(response.status).to eq 403 - end - end end end diff --git a/spec/requests/api/v2/ecf_participants_spec.rb b/spec/requests/api/v2/ecf_participants_spec.rb index b2e007b248..c0edf96c50 100644 --- a/spec/requests/api/v2/ecf_participants_spec.rb +++ b/spec/requests/api/v2/ecf_participants_spec.rb @@ -378,18 +378,6 @@ expect(response.status).to eq 403 end end - - context "when using LeadProviderApiToken with only NPQ access" do - let(:cpd_lead_provider) { create(:cpd_lead_provider, npq_lead_provider:, lead_provider: nil) } - let(:npq_lead_provider) { create(:npq_lead_provider) } - let(:token) { LeadProviderApiToken.create_with_random_token!(cpd_lead_provider:) } - - it "returns 403" do - default_headers[:Authorization] = bearer_token - get "/api/v2/participants/ecf" - expect(response.status).to eq 403 - end - end end describe "GET /api/v2/participants/ecf/:id" do diff --git a/spec/requests/api/v3/ecf/participants_spec.rb b/spec/requests/api/v3/ecf/participants_spec.rb index a8c3e84551..4816553abb 100644 --- a/spec/requests/api/v3/ecf/participants_spec.rb +++ b/spec/requests/api/v3/ecf/participants_spec.rb @@ -280,18 +280,6 @@ expect(response.status).to eq 403 end end - - context "when using LeadProviderApiToken with only NPQ access" do - let(:cpd_lead_provider) { create(:cpd_lead_provider, npq_lead_provider:, lead_provider: nil) } - let(:npq_lead_provider) { create(:npq_lead_provider) } - let(:token) { LeadProviderApiToken.create_with_random_token!(cpd_lead_provider:) } - - it "returns 403" do - default_headers[:Authorization] = bearer_token - get "/api/v3/participants/ecf" - expect(response.status).to eq 403 - end - end end describe "GET /api/v3/participants/ecf/:id" do diff --git a/spec/requests/finance/payment_breakdowns_spec.rb b/spec/requests/finance/payment_breakdowns_spec.rb index 68919f474a..b605765414 100644 --- a/spec/requests/finance/payment_breakdowns_spec.rb +++ b/spec/requests/finance/payment_breakdowns_spec.rb @@ -8,9 +8,8 @@ let(:cohort_2021) { Cohort.current || create(:cohort, :current) } let(:cohort_2022) { Cohort.next || create(:cohort, :next) } - let(:cpd_lead_provider) { create(:cpd_lead_provider, :with_lead_provider, :with_npq_lead_provider) } + let(:cpd_lead_provider) { create(:cpd_lead_provider, :with_lead_provider) } let(:lead_provider) { cpd_lead_provider.lead_provider } - let(:npq_lead_provider) { cpd_lead_provider.npq_lead_provider } before do sign_in user diff --git a/spec/seeds/seed_factories/npq_application_spec.rb b/spec/seeds/seed_factories/npq_application_spec.rb deleted file mode 100644 index 74c52a37f8..0000000000 --- a/spec/seeds/seed_factories/npq_application_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -require_relative "./shared_factory_examples" - -RSpec.describe("seed_npq_application") do - let(:factory_name) { :seed_npq_application } - - it_behaves_like("a seed factory") do - let(:factory_class) { NPQApplication } - end - - describe "traits" do - context "when company is set" do - let(:object) { create(factory_name, :company, :valid) } - - it("creates a valid object") { expect(object).to(be_valid) } - it("persists the object") { expect(object).to(be_persisted) } - it("sets works_in_school as false") { expect(object.works_in_school).to(be(false)) } - end - - context "when childcare is set" do - let(:object) { create(factory_name, :company, :valid) } - - it("creates a valid object") { expect(object).to(be_valid) } - it("persists the object") { expect(object).to(be_persisted) } - it("sets works_in_school as false") { expect(object.works_in_school).to(be(false)) } - end - end -end diff --git a/spec/seeds/seed_factories/npq_course_factory_spec.rb b/spec/seeds/seed_factories/npq_course_factory_spec.rb deleted file mode 100644 index e6d95177f9..0000000000 --- a/spec/seeds/seed_factories/npq_course_factory_spec.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -require_relative "./shared_factory_examples" - -RSpec.describe("seed_npq_course_factory") do - it_behaves_like("a seed factory") do - let(:factory_name) { :seed_npq_course } - let(:factory_class) { NPQCourse } - end -end diff --git a/spec/seeds/seed_factories/npq_lead_provider_factory_spec.rb b/spec/seeds/seed_factories/npq_lead_provider_factory_spec.rb deleted file mode 100644 index be8a0e7ac7..0000000000 --- a/spec/seeds/seed_factories/npq_lead_provider_factory_spec.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -require_relative "./shared_factory_examples" - -RSpec.describe("seed_npq_lead_provider_factory") do - it_behaves_like("a seed factory") do - let(:factory_name) { :seed_npq_lead_provider } - let(:factory_class) { NPQLeadProvider } - end -end diff --git a/spec/serializers/api/v3/ecf/transfer_serializer_spec.rb b/spec/serializers/api/v3/ecf/transfer_serializer_spec.rb index 34008c7a81..5cc3b54bc5 100644 --- a/spec/serializers/api/v3/ecf/transfer_serializer_spec.rb +++ b/spec/serializers/api/v3/ecf/transfer_serializer_spec.rb @@ -230,15 +230,6 @@ module ECF end end - context "with ECT and NPQ profiles" do - let(:npq_lead_provider) { create(:npq_lead_provider, cpd_lead_provider:) } - let!(:npq_application) { create(:npq_application, :accepted, :eligible_for_funding, npq_lead_provider:, user:) } - - it "only surfaces a single transfer" do - expect(subject.serializable_hash[:data][:attributes][:transfers].size).to eq(1) - end - end - context "with multiple transfers" do let!(:leaving_induction_record) do create(:induction_record, :leaving, :preferred_identity, induction_programme: leaving_induction_programme, start_date: leaving_start_date, end_date: leaving_end_date) diff --git a/spec/serializers/archive/npq_application_serializer_spec.rb b/spec/serializers/archive/npq_application_serializer_spec.rb deleted file mode 100644 index 2fb8f2f214..0000000000 --- a/spec/serializers/archive/npq_application_serializer_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe Archive::NPQApplicationSerializer do - let(:npq_application) { create(:seed_npq_application, :valid) } - - subject { described_class.new(npq_application) } - - describe "#serializable_hash" do - it "generates the correct hash" do - data = subject.serializable_hash[:data] - expect(data[:id]).to eq npq_application.id - expect(data[:type]).to eq :npq_application - - attrs = data[:attributes] - npq_application.attributes.except(*%w[id updated_at]).each do |k, v| - expect(attrs[k.to_sym]).to eq v - end - end - end -end diff --git a/spec/serializers/archive/user_serializer_spec.rb b/spec/serializers/archive/user_serializer_spec.rb index 84d56543a7..b67fd17faa 100644 --- a/spec/serializers/archive/user_serializer_spec.rb +++ b/spec/serializers/archive/user_serializer_spec.rb @@ -32,7 +32,6 @@ expect(attrs[:teacher_profile]).to eq Archive::TeacherProfileSerializer.new(user.teacher_profile).serializable_hash[:data] expect(attrs[:participant_identities]).to match_array Archive::ParticipantIdentitySerializer.new(user.participant_identities).serializable_hash[:data] expect(attrs[:participant_profiles]).to match_array Archive::ParticipantProfileSerializer.new(user.participant_profiles).serializable_hash[:data] - expect(attrs[:npq_applications]).to match_array Archive::NPQApplicationSerializer.new(user.npq_applications).serializable_hash[:data] end end end diff --git a/spec/serializers/finance/npq/assurance_report/csv_serializer_spec.rb b/spec/serializers/finance/npq/assurance_report/csv_serializer_spec.rb deleted file mode 100644 index 43f0982d9b..0000000000 --- a/spec/serializers/finance/npq/assurance_report/csv_serializer_spec.rb +++ /dev/null @@ -1,119 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe Finance::NPQ::AssuranceReport::CsvSerializer do - let(:record) { build_record } - - describe "attributes" do - let(:records) { [record] } - subject { described_class.new(records, double) } - - let(:rows) { subject.call.split("\n") } - let(:header) { rows.first.split(",") } - let(:data) { rows.second.split(",") } - - it "includes all attributes in the row" do - expect(data).to match_array( - [ - "123", - "John Doe", - "TRN123", - "course-id-123", - "schedule-123", - "eligible-true", - "provider-name", - "school-urn", - "school-name", - "active", - "active-reason", - "declaration-id-123", - "submitted", - "started", - "2022-02-01T12:00:00Z", - "2022-01-01T12:00:00Z", - "statement-name", - "satement-id-123", - "target-delivery-funding", - ], - ) - end - - describe "csv_headers" do - let(:expected_header) do - [ - "Participant ID", - "Participant Name", - "TRN", - "Course Identifier", - "Schedule", - "Eligible For Funding", - "Lead Provider Name", - "School Urn", - "School Name", - "Training Status", - "Training Status Reason", - "Declaration ID", - "Declaration Status", - "Declaration Type", - "Declaration Date", - "Declaration Created At", - "Statement Name", - "Statement ID", - "Targeted Delivery Funding", - ] - end - - context "when `npq_capping` Feature Flag is active" do - before { FeatureFlag.activate(:npq_capping) } - - it "includes Funded place in the header" do - expected_header.insert(6, "Funded place") - - expect(header).to eq(expected_header) - end - - it "includes `funded_place` attribute" do - expect(rows.second).to include("funded-true") - end - end - - context "when `npq_capping` Feature Flag is not active" do - before { FeatureFlag.deactivate(:npq_capping) } - - it "does not included Funded place in the header" do - expect(header).to eq(expected_header) - end - - it "does not include `funded_place` attribute" do - expect(rows.second).to_not include("funded-true") - end - end - end - end - - def build_record - double( - participant_id: "123", - participant_name: "John Doe", - trn: "TRN123", - course_identifier: "course-id-123", - schedule: "schedule-123", - eligible_for_funding: "eligible-true", - funded_place: "funded-true", - npq_lead_provider_name: "provider-name", - school_urn: "school-urn", - school_name: "school-name", - training_status: "active", - training_status_reason: "active-reason", - declaration_id: "declaration-id-123", - declaration_status: "submitted", - declaration_type: "started", - declaration_date: Time.zone.local(2022, 2, 1, 12, 0, 0), - declaration_created_at: Time.zone.local(2022, 1, 1, 12, 0, 0), - statement_name: "statement-name", - statement_id: "satement-id-123", - targeted_delivery_funding: "target-delivery-funding", - ) - end -end diff --git a/spec/services/archive/search_spec.rb b/spec/services/archive/search_spec.rb index f9c2abd634..d8eecf8063 100644 --- a/spec/services/archive/search_spec.rb +++ b/spec/services/archive/search_spec.rb @@ -119,8 +119,6 @@ end describe "matching by teacher reference number" do - let(:search_term) { user_1.npq_applications.first.teacher_reference_number } - let(:results) { search.call(search_term: "9876543") } it "returns matching participants" do diff --git a/spec/services/importers/create_new_npq_cohort_spec.rb b/spec/services/importers/create_new_npq_cohort_spec.rb deleted file mode 100644 index bd1a061a48..0000000000 --- a/spec/services/importers/create_new_npq_cohort_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -require "tempfile" - -RSpec.describe Importers::CreateNewNPQCohort do - describe "#call" do - let(:start_year) { Cohort.ordered_by_start_year.last.start_year + 1000 } - - let!(:cpd_lead_provider) { create(:cpd_lead_provider, :with_npq_lead_provider, name: "Koala Institute") } - let!(:npq_leadership_course) { create(:npq_leadership_course, identifier: "npq-headship") } - - let(:cohort_csv) do - csv = Tempfile.new("cohort_csv_data.csv") - csv.write "start-year,registration-start-date,academic-year-start-date,npq-registration-start-date,automatic-assignment-period-end-date,payments-frozen-at" - csv.write "\n" - 4.times.each do |n| - csv.write "#{start_year + n},#{start_year + n}/05/10,#{start_year}/09/01,#{start_year + 1}/03/31,," - csv.write "\n" - end - csv.close - csv.path - end - - let(:schedule_csv) do - csv = Tempfile.new("schedule_csv_data.csv") - csv.write "type,schedule-identifier,schedule-name,schedule-cohort-year,milestone-name,milestone-declaration-type,milestone-start-date,milestone-date,milestone-payment-date" - csv.write "\n" - csv.write "npq_leadership,npq-leadership-autumn,NPQ Leadership Autumn,#{start_year},Output 1 - Participant Start,started,01/11/#{start_year},01/11/#{start_year},01/11/#{start_year}" - csv.close - csv.path - end - - let(:contract_csv) do - csv = Tempfile.new("contract_csv_data.csv") - csv.write "provider_name,cohort_year,course_identifier,recruitment_target,per_participant,service_fee_installments,special_course" - csv.write "\n" - csv.write "#{cpd_lead_provider.name},#{start_year},npq-headship,321,654.87,14,FALSE" - csv.write "\n" - csv.close - csv.path - end - - let(:statement_csv) do - csv = Tempfile.new("statement_csv_data.csv") - csv.write "type,name,cohort,deadline_date,payment_date,output_fee" - csv.write "\n" - csv.write "npq,January #{start_year + 3},#{start_year},#{start_year}-12-25,#{start_year + 3}-1-25,false" - csv.write "\n" - csv.write "npq,February #{start_year + 3},#{start_year},#{start_year + 3}-1-25,#{start_year + 3}-2-25,true" - csv.write "\n" - csv.close - csv.path - end - - subject do - described_class.new(cohort_csv:, schedule_csv:, contract_csv:, statement_csv:) - end - - context "create new cohort" do - it "creates cohort" do - current_cohorts_count = Cohort.count - subject.call - expect(Cohort.count).to eql(current_cohorts_count + 4) - expect(Cohort.order(:start_year).last.start_year).to eq(start_year + 3) - end - - it "creates schedule" do - current_schedules_count = Finance::Schedule::NPQLeadership.count - subject.call - expect(Finance::Schedule::NPQLeadership.count).to eql(current_schedules_count + 1) - expect(Finance::Schedule::NPQLeadership.where(cohort: Cohort.find_by(start_year:)).first.name).to eql("NPQ Leadership Autumn") - end - - it "creates npq contract" do - expect(NPQContract.count).to eql(0) - subject.call - expect(NPQContract.count).to eql(1) - expect(NPQContract.first.course_identifier).to eql("npq-headship") - end - - it "creates statement" do - expect(Finance::Statement::NPQ.count).to eql(0) - subject.call - expect(Finance::Statement::NPQ.count).to eql(2) - expect(Finance::Statement::NPQ.order(:payment_date).first.name).to eql("January #{start_year + 3}") - end - end - end -end diff --git a/spec/services/importers/create_new_npq_course_spec.rb b/spec/services/importers/create_new_npq_course_spec.rb deleted file mode 100644 index 7537159e38..0000000000 --- a/spec/services/importers/create_new_npq_course_spec.rb +++ /dev/null @@ -1,50 +0,0 @@ -# frozen_string_literal: true - -require "tempfile" - -RSpec.describe Importers::CreateNewNPQCourse do - describe "#call" do - let(:start_year) { Cohort.ordered_by_start_year.last.start_year } - - let!(:cpd_lead_provider) { create(:cpd_lead_provider, :with_npq_lead_provider, name: "Koala Institute") } - let!(:npq_course) { create(:npq_course, identifier: "npq-leading-primary-mathematics") } - - let(:npq_course_csv) do - csv = Tempfile.new("npq_course_csv_data.csv") - csv.write "name,identifier" - csv.write "\n" - csv.write "#{npq_course.name},#{npq_course.identifier}," - csv.write "\n" - csv.close - csv.path - end - - let(:contract_csv) do - csv = Tempfile.new("contract_csv_data.csv") - csv.write "provider_name,cohort_year,course_identifier,recruitment_target,per_participant,service_fee_installments,special_course" - csv.write "\n" - csv.write "#{cpd_lead_provider.name},#{start_year},npq-leading-primary-mathematics,321,654.87,14,FALSE" - csv.write "\n" - csv.close - csv.path - end - - subject do - described_class.new(npq_course_csv:, contract_csv:) - end - - context "create new Course" do - it "creates course" do - subject.call - expect(NPQCourse.count).to eql(1) - end - - it "creates npq contract" do - expect(NPQContract.count).to eql(0) - subject.call - expect(NPQContract.count).to eql(1) - expect(NPQContract.first.course_identifier).to eql("npq-leading-primary-mathematics") - end - end - end -end diff --git a/spec/services/importers/create_npq_contract_spec.rb b/spec/services/importers/create_npq_contract_spec.rb deleted file mode 100644 index 5bf073319a..0000000000 --- a/spec/services/importers/create_npq_contract_spec.rb +++ /dev/null @@ -1,213 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe Importers::CreateNPQContract do - let(:csv) { Tempfile.new("data.csv") } - let(:path_to_csv) { csv.path } - let(:set_to_latest_version) { false } - - let!(:cpd_lead_provider) { create(:cpd_lead_provider, :with_npq_lead_provider, name: "Ambition Institute") } - let!(:npq_lead_provider) { cpd_lead_provider.npq_lead_provider } - let!(:cohort) { FactoryBot.create :cohort } - let!(:npq_specialist_course) { create(:npq_specialist_course, name: "NPQ Leading Teaching (npq-leading-teaching)", identifier: "npq-leading-teaching") } - let!(:npq_leadership_course) { create(:npq_leadership_course, name: "NPQ for Headship (npq-headship)", identifier: "npq-headship") } - let!(:npq_ehco_course) { create(:npq_ehco_course, name: "The Early Headship Coaching Offer", identifier: "npq-early-headship-coaching-offer") } - - subject { described_class.new(path_to_csv:, set_to_latest_version:) } - - describe "#call" do - context "when headers are incorrect" do - before do - csv.write "foo,bar" - csv.write "\n" - csv.close - end - - it "throws an error" do - expect { subject.call }.to raise_error(NameError) - end - end - - context "when new contract" do - let(:monthly_service_fee) { 12.34 } - - before do - csv.write "provider_name,cohort_year,course_identifier,recruitment_target,per_participant,service_fee_installments,special_course,monthly_service_fee" - csv.write "\n" - csv.write "Ambition Institute,#{cohort.start_year},npq-leading-teaching,123,456.78,13,TRUE,#{monthly_service_fee}" - csv.write "\n" - csv.close - end - - it "creates a new contract with correct values" do - expect { subject.call }.to change { NPQContract.count }.by(1) - - contract = NPQContract.last - - expect(contract.npq_lead_provider).to eql(npq_lead_provider) - expect(contract.recruitment_target).to eql(123) - expect(contract.course_identifier).to eql(npq_specialist_course.identifier) - expect(contract.service_fee_installments).to eql(13) - expect(contract.service_fee_percentage).to eql(40) - expect(contract.output_payment_percentage).to eql(60) - expect(contract.per_participant).to eql(456.78) - expect(contract.number_of_payment_periods).to eql(3) - expect(contract.cohort).to eql(cohort) - expect(contract.version).to eql("0.0.1") - expect(contract.monthly_service_fee).to eql(12.34) - expect(contract.special_course).to eql(true) - end - - context "when the monthly_service_fee is not specified" do - let(:monthly_service_fee) { nil } - - it "defaults it to 0.0" do - expect { subject.call }.to change { NPQContract.count }.by(1) - - contract = NPQContract.last - - expect(contract.monthly_service_fee).to be_zero - end - end - end - - context "when new version" do - let(:set_to_latest_version) { true } - let(:contract_version) { "0.0.3" } - let!(:statement) { create(:npq_statement, cpd_lead_provider:, cohort:, contract_version:) } - - before do - csv.write "provider_name,cohort_year,course_identifier,recruitment_target,per_participant,service_fee_installments,special_course" - csv.write "\n" - csv.write "Ambition Institute,#{cohort.start_year},npq-leading-teaching,123,456.78,13,false" - csv.write "\n" - csv.close - end - - it "creates/update contract with new version" do - expect { subject.call }.to change { NPQContract.count }.by(1) - - contract = NPQContract.last - - expect(contract.npq_lead_provider).to eql(npq_lead_provider) - expect(contract.recruitment_target).to eql(123) - expect(contract.course_identifier).to eql(npq_specialist_course.identifier) - expect(contract.service_fee_installments).to eql(13) - expect(contract.service_fee_percentage).to eql(40) - expect(contract.output_payment_percentage).to eql(60) - expect(contract.per_participant).to eql(456.78) - expect(contract.number_of_payment_periods).to eql(3) - expect(contract.cohort).to eql(cohort) - expect(contract.version).to eql(contract_version) - expect(contract.special_course).to eql(false) - end - end - - context "code is run more than once" do - before do - csv.write "provider_name,cohort_year,course_identifier,recruitment_target,per_participant,service_fee_installments,special_course" - csv.write "\n" - csv.write "Ambition Institute,#{cohort.start_year},npq-leading-teaching,123,456.78,13" - csv.write "\n" - csv.close - end - - it "is idempotent" do - expect { - subject.call - subject.call - }.to change { NPQContract.count }.by(1) - end - end - - context "when existing contract" do - before do - csv.write "provider_name,cohort_year,course_identifier,recruitment_target,per_participant,service_fee_installments,special_course" - csv.write "\n" - csv.write "Ambition Institute,#{cohort.start_year},npq-leading-teaching,123,456.78,13,TRUE" - csv.write "\n" - csv.close - - NPQContract.create!( - npq_lead_provider:, - cohort:, - course_identifier: npq_specialist_course.identifier, - recruitment_target: 100, - per_participant: 100, - service_fee_installments: 100, - number_of_payment_periods: 100, - special_course: false, - ) - end - - it "updates the contract" do - expect { - subject.call - }.not_to change { NPQContract.count } - - contract = NPQContract.last - - expect(contract.recruitment_target).to eql(123) - expect(contract.per_participant).to eql(456.78) - expect(contract.service_fee_installments).to eql(13) - expect(contract.number_of_payment_periods).to eql(3) - expect(contract.special_course).to eql(true) - end - end - - context "when a leadership course" do - before do - csv.write "provider_name,cohort_year,course_identifier,recruitment_target,per_participant,service_fee_installments,special_course" - csv.write "\n" - csv.write "Ambition Institute,#{cohort.start_year},npq-headship,321,654.87,14,true" - csv.write "\n" - csv.close - end - - it "creates a new contract with correct values" do - expect { subject.call }.to change { NPQContract.count }.by(1) - - contract = NPQContract.last - - expect(contract.npq_lead_provider).to eql(npq_lead_provider) - expect(contract.recruitment_target).to eql(321) - expect(contract.course_identifier).to eql(npq_leadership_course.identifier) - expect(contract.service_fee_installments).to eql(14) - expect(contract.service_fee_percentage).to eql(40) - expect(contract.output_payment_percentage).to eql(60) - expect(contract.per_participant).to eql(654.87) - expect(contract.number_of_payment_periods).to eql(4) - expect(contract.cohort).to eql(cohort) - expect(contract.special_course).to eql(true) - end - end - - context "when EHCO course" do - before do - csv.write "provider_name,cohort_year,course_identifier,recruitment_target,per_participant,service_fee_installments,special_course" - csv.write "\n" - csv.write "Ambition Institute,#{cohort.start_year},npq-early-headship-coaching-offer,789,111.22,15,FALSE" - csv.write "\n" - csv.close - end - - it "creates a new contract with correct values" do - expect { subject.call }.to change { NPQContract.count }.by(1) - - contract = NPQContract.last - - expect(contract.npq_lead_provider).to eql(npq_lead_provider) - expect(contract.recruitment_target).to eql(789) - expect(contract.course_identifier).to eql(npq_ehco_course.identifier) - expect(contract.service_fee_installments).to eql(15) - expect(contract.service_fee_percentage).to eql(0) - expect(contract.output_payment_percentage).to eql(100) - expect(contract.per_participant).to eql(111.22) - expect(contract.number_of_payment_periods).to eql(4) - expect(contract.cohort).to eql(cohort) - expect(contract.special_course).to eql(false) - end - end - end -end diff --git a/spec/services/importers/create_npq_course_spec.rb b/spec/services/importers/create_npq_course_spec.rb deleted file mode 100644 index 644f2ada2f..0000000000 --- a/spec/services/importers/create_npq_course_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -require "tempfile" - -RSpec.describe Importers::CreateNPQCourse do - let(:csv) { Tempfile.new("data.csv") } - let(:path_to_csv) { csv.path } - - subject(:importer) { described_class.new(path_to_csv:) } - - describe "#call" do - context "with new npq_courses" do - before do - csv.write "name,identifier" - csv.write "\n" - csv.write "NPQ Leading Teaching (NPQLT),npq-leading-teaching, " - csv.write "\n" - csv.write "NPQ for Senior Leadership (NPQSL),npq-senior-leadership," - csv.write "\n" - csv.write "NPQ for Leading Primary Mathematics (NPQLPM),npq-leading-primary-mathematics," - csv.write "\n" - csv.write "NPQ for Headship (NPQH),npq-headship," - csv.write "\n" - csv.close - end - - it "creates npq_course records" do - expect { importer.call }.to change { NPQCourse.count }.by(4) - end - - it "sets the correct identifier on the record" do - importer.call - - course = NPQCourse.find_by(name: "NPQ Leading Teaching (NPQLT)") - expect(course.identifier).to eq "npq-leading-teaching" - end - end - end -end diff --git a/spec/services/importers/create_statement_spec.rb b/spec/services/importers/create_statement_spec.rb index e431227aba..b5004a1520 100644 --- a/spec/services/importers/create_statement_spec.rb +++ b/spec/services/importers/create_statement_spec.rb @@ -5,11 +5,9 @@ RSpec.describe Importers::CreateStatement do let(:csv) { Tempfile.new("data.csv") } let(:path_to_csv) { csv.path } - let(:cpd_lead_provider) { create(:cpd_lead_provider, :with_lead_provider, :with_npq_lead_provider) } + let(:cpd_lead_provider) { create(:cpd_lead_provider, :with_lead_provider) } let(:lead_provider) { cpd_lead_provider.lead_provider } - let(:npq_lead_provider) { cpd_lead_provider.npq_lead_provider } let!(:cohort_2023) { create(:cohort, start_year: 2023) } - let(:npq_course) { create(:npq_course, identifier: "npq-leading-behaviour-culture") } subject(:importer) { described_class.new(path_to_csv:) } @@ -21,16 +19,11 @@ csv.write "\n" csv.write "ecf,February 2024,2023,2024-1-31,2024-2-25,false" csv.write "\n" - csv.write "npq,January 2024,2023,2023-12-25,2024-1-25,false" - csv.write "\n" - csv.write "npq,February 2024,2023,2024-1-25,2024-2-25,true" - csv.write "\n" csv.close end context "when contracts for the cohort exists" do let!(:ecf_contract) { create(:call_off_contract, lead_provider:, version: "0.0.1", cohort: cohort_2023) } - let!(:npq_contract) { create(:npq_contract, npq_course:, cohort: cohort_2023, npq_lead_provider:) } it "creates ECF statements idempotently" do expect { @@ -39,13 +32,6 @@ }.to change(Finance::Statement::ECF, :count).by(2) end - it "creates NPQ statements idempotently" do - expect { - importer.call - importer.call - }.to change(Finance::Statement::NPQ, :count).by(2) - end - it "populates statements correctly" do importer.call @@ -70,34 +56,11 @@ output_fee: false, ), ).to be_present - - expect( - Finance::Statement::NPQ.find_by( - name: "January 2024", - cohort: cohort_2023, - deadline_date: Date.new(2023, 12, 25), - payment_date: Date.new(2024, 1, 25), - contract_version: "0.0.1", - output_fee: false, - ), - ).to be_present - - expect( - Finance::Statement::NPQ.find_by( - name: "February 2024", - cohort: cohort_2023, - deadline_date: Date.new(2024, 1, 25), - payment_date: Date.new(2024, 2, 25), - contract_version: "0.0.1", - output_fee: true, - ), - ).to be_present end end context "when existing statements have newer version" do let!(:ecf_contract) { create(:call_off_contract, lead_provider:, version: "0.0.1", cohort: cohort_2023) } - let!(:npq_contract) { create(:npq_contract, npq_course:, cohort: cohort_2023, npq_lead_provider:) } before do statement_attributes = { @@ -109,11 +72,11 @@ cohort: cohort_2023, } - [Finance::Statement::ECF, Finance::Statement::NPQ].each do |statement_type| + [Finance::Statement::ECF].each do |statement_type| # Later version with different lead provider statement_type.create!( statement_attributes.merge({ - cpd_lead_provider: create(:cpd_lead_provider, :with_lead_provider, :with_npq_lead_provider), + cpd_lead_provider: create(:cpd_lead_provider, :with_lead_provider), contract_version: "0.0.8", }), ) @@ -141,13 +104,6 @@ contract_version: "0.0.5", }), ) - - # Latest, relevant NPQ statement - Finance::Statement::NPQ.create!( - statement_attributes.merge({ - contract_version: "0.0.6", - }), - ) end it "creates ECF statement with latest version" do @@ -162,19 +118,6 @@ expect(st.contract_version).to eql("0.0.5") end - - it "creates NPQ statement with latest version" do - importer.call - - st = Finance::Statement::NPQ.find_by( - name: "January 2024", - cohort: cohort_2023, - deadline_date: Date.new(2023, 12, 25), - payment_date: Date.new(2024, 1, 25), - ) - - expect(st.contract_version).to eql("0.0.6") - end end context "when contracts for the cohort does not exist" do @@ -183,12 +126,6 @@ importer.call }.not_to change(Finance::Statement::ECF, :count) end - - it "does not create any NPQ statement" do - expect { - importer.call - }.not_to change(Finance::Statement::NPQ, :count) - end end end end diff --git a/spec/services/importers/npq_manual_validation_spec.rb b/spec/services/importers/npq_manual_validation_spec.rb deleted file mode 100644 index fdc9f8dc1f..0000000000 --- a/spec/services/importers/npq_manual_validation_spec.rb +++ /dev/null @@ -1,79 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -RSpec.describe Importers::NPQManualValidation do - let(:npq_course) { create(:npq_course, identifier: "npq-senior-leadership") } - let(:npq_application) { create(:npq_application, :accepted, npq_course:, teacher_reference_number_verified: false) } - let(:file) { Tempfile.new("test.csv") } - let!(:teacher_profile) { npq_application.profile.teacher_profile } - let(:teacher_reference_number) { "7654321" } - - around do |example| - original_stdout = $stdout - $stdout = File.open(File::NULL, "w") - - example.run - - $stdout = original_stdout - end - - describe "#call" do - subject do - described_class.new(path_to_csv: file.path) - end - - context "with well formed csv" do - before do - file.write("application_ecf_id,validated_trn") - file.write("\n") - file.write("123,7654321") - file.write("\n") - file.write("#{npq_application.id},#{teacher_reference_number}") - file.rewind - end - - it "updates trn" do - expect { - subject.call - }.to change { npq_application.reload.teacher_reference_number }.to("7654321") - end - - it "updates the teacher profile trn" do - expect { - subject.call - }.to change { teacher_profile.reload.trn }.to("7654321") - end - - it "updates teacher_reference_number_verified to true" do - expect { - subject.call - }.to change { npq_application.reload.teacher_reference_number_verified }.to(true) - end - - context "when application trn is less than 7 digits" do - let(:teacher_reference_number) { "123456" } - - it "adds leading zero" do - expect { - subject.call - }.to change { npq_application.reload.teacher_reference_number }.to("0123456") - end - end - end - - context "with malformed csv" do - before do - file.write("application_id,trn") - file.write("\n") - file.rewind - end - - it "raises error" do - expect { - subject.call - }.to raise_error(NameError) - end - end - end -end diff --git a/spec/services/void_participant_declaration_spec.rb b/spec/services/void_participant_declaration_spec.rb index 5d6c9c328c..e946c3b443 100644 --- a/spec/services/void_participant_declaration_spec.rb +++ b/spec/services/void_participant_declaration_spec.rb @@ -3,7 +3,7 @@ require "rails_helper" RSpec.describe VoidParticipantDeclaration do - let(:cpd_lead_provider) { create(:cpd_lead_provider, :with_lead_provider, :with_npq_lead_provider) } + let(:cpd_lead_provider) { create(:cpd_lead_provider, :with_lead_provider) } let(:participant_profile) { create(:ect, :eligible_for_funding, lead_provider: cpd_lead_provider.lead_provider) } let(:lead_provider) { cpd_lead_provider.lead_provider } let(:school) { participant_profile.school_cohort.school } diff --git a/spec/support/archive_helper.rb b/spec/support/archive_helper.rb index 1144e432bd..0211acc4f8 100644 --- a/spec/support/archive_helper.rb +++ b/spec/support/archive_helper.rb @@ -36,7 +36,6 @@ def build_archived_ect(name: Faker::Name.name, id: SecureRandom.uuid, alt_id: Se "school_id" => "153ad0f7-cc8d-4b68-942f-f21a021ad0bf", }, }, - "npq_applications" => [], "induction_records" => [ { "id" => SecureRandom.uuid, diff --git a/spec/support/features/pages/admin_support/admin_support_participant_detail.rb b/spec/support/features/pages/admin_support/admin_support_participant_detail.rb index 8a030dc5a3..f70162662e 100644 --- a/spec/support/features/pages/admin_support/admin_support_participant_detail.rb +++ b/spec/support/features/pages/admin_support/admin_support_participant_detail.rb @@ -10,7 +10,7 @@ class AdminSupportParticipantDetail < ::Pages::BasePage def has_training_record_state?(validation_status) # TODO: get language from language files - element_has_content? self, "Training record state #{validation_status}" + element_has_content? self, "Training record state#{validation_status}" end def has_full_name?(full_name) diff --git a/spec/tasks/oneoff/cleanup_itt_providers_npq_06_02_2023_spec.rb b/spec/tasks/oneoff/cleanup_itt_providers_npq_06_02_2023_spec.rb deleted file mode 100644 index 6bee9a11bc..0000000000 --- a/spec/tasks/oneoff/cleanup_itt_providers_npq_06_02_2023_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "npq_applications:restore_itt_providers" do - before :all do - Rake.application.rake_require "tasks/oneoff/cleanup_itt_providers_npq_06_02_2023" - Rake::Task.define_task(:environment) - @csv_file_path = Rails.root.join("tmp/test.csv") - end - - describe "restore_itt_providers" do - it "should update the ITT provider for the application" do - application = create :npq_application, itt_provider: "Old Provider" - CSV.open(@csv_file_path, "w") { |csv| csv << [application.id, "New Provider"] } - - Rake::Task["npq_applications:restore_itt_providers"].reenable - Rake.application.invoke_task "npq_applications:restore_itt_providers[#{@csv_file_path}]" - - expect(application.reload.itt_provider).to eq "New Provider" - end - - after :all do - File.delete(@csv_file_path) if File.exist?(@csv_file_path) - end - end -end