diff --git a/Gemfile b/Gemfile index 6e29c213f..c7115be76 100644 --- a/Gemfile +++ b/Gemfile @@ -67,6 +67,12 @@ group :development, :test do gem 'simplecov', require: false end +group :test do + gem 'capybara' + gem 'chromedriver-helper' + gem 'selenium-webdriver' +end + group :development do gem 'bullet' gem 'fit-commit' diff --git a/Gemfile.lock b/Gemfile.lock index b23ace7a5..e1d6f0115 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -49,6 +49,8 @@ GEM nokogiri ancestry (3.0.2) activerecord (>= 3.2.0) + archive-zip (0.11.0) + io-like (~> 0.3.0) arel (9.0.0) ast (2.4.0) aws-eventstream (1.0.1) @@ -83,7 +85,19 @@ GEM bundler (~> 1.2) thor (~> 0.18) byebug (10.0.2) + capybara (3.8.2) + addressable + mini_mime (>= 0.1.3) + nokogiri (~> 1.8) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + xpath (~> 3.1) chartkick (3.0.1) + childprocess (0.9.0) + ffi (~> 1.0, >= 1.0.11) + chromedriver-helper (2.1.0) + archive-zip (~> 0.10) + nokogiri (~> 1.8) cocoon (1.2.11) codacy-coverage (2.1.0) simplecov @@ -143,6 +157,7 @@ GEM image_processing (1.7.0) mini_magick (~> 4.0) ruby-vips (>= 2.0.13, < 3) + io-like (0.3.0) jaro_winkler (1.5.1) jbuilder (2.7.0) activesupport (>= 4.2.0) @@ -253,6 +268,7 @@ GEM ruby-vips (2.0.13) ffi (~> 1.9) ruby_dep (1.5.0) + rubyzip (1.2.2) sass (3.6.0) sass-listen (~> 4.0.0) sass-listen (4.0.0) @@ -276,6 +292,9 @@ GEM nokogiri (>= 1.8.1) nori (~> 2.4) wasabi (~> 3.4) + selenium-webdriver (3.14.0) + childprocess (~> 0.5) + rubyzip (~> 1.2) sidekiq (5.2.2) connection_pool (~> 2.2, >= 2.2.2) rack-protection (>= 1.5.0) @@ -334,6 +353,8 @@ GEM websocket-driver (0.7.0) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.3) + xpath (3.1.0) + nokogiri (~> 1.8) PLATFORMS ruby @@ -347,7 +368,9 @@ DEPENDENCIES bullet bundler-audit byebug + capybara chartkick + chromedriver-helper cocoon codacy-coverage coffee-rails (~> 4.2) @@ -375,6 +398,7 @@ DEPENDENCIES ruby-progressbar sassc-rails savon (~> 2.12.0) + selenium-webdriver sidekiq simple_form simplecov diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index b555b4912..7d9c1e040 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -4,4 +4,5 @@ *= require coreui *= require toastr/build/toastr.min *= require select2/dist/css/select2.min + *= require custom/select2 */ diff --git a/app/assets/stylesheets/custom/select2.css b/app/assets/stylesheets/custom/select2.css new file mode 100644 index 000000000..d0f9442a9 --- /dev/null +++ b/app/assets/stylesheets/custom/select2.css @@ -0,0 +1,3 @@ +.select2 { + width: 100% !important; /* csslint allow: known-properties, important */ +} \ No newline at end of file diff --git a/app/controllers/account/duties_controller.rb b/app/controllers/account/duties_controller.rb index 296d20ff9..beaa5d1e3 100644 --- a/app/controllers/account/duties_controller.rb +++ b/app/controllers/account/duties_controller.rb @@ -21,7 +21,11 @@ def update end def destroy - @duty.destroy ? redirect_to(@user, notice: t('.success')) : redirect_with('warning') + if @duty.destroy + redirect_to(@user, notice: t('.success')) + else + redirect_to(users_path(@user), alert: t('.warning')) + end end private diff --git a/app/controllers/account/employees_controller.rb b/app/controllers/account/employees_controller.rb index 266fded8f..f08988924 100644 --- a/app/controllers/account/employees_controller.rb +++ b/app/controllers/account/employees_controller.rb @@ -21,7 +21,11 @@ def update end def destroy - @employee.destroy ? redirect_to(@user, notice: t('.success')) : redirect_with('warning') + if @employee.destroy + redirect_to(@user, notice: t('.success')) + else + redirect_to(users_path(@user), alert: t('.warning')) + end end private diff --git a/app/controllers/account/positions_controller.rb b/app/controllers/account/positions_controller.rb index 53ef2f030..bd0d1bcc2 100644 --- a/app/controllers/account/positions_controller.rb +++ b/app/controllers/account/positions_controller.rb @@ -22,7 +22,11 @@ def update end def destroy - @position.destroy ? redirect_to(@user, notice: t('.success')) : redirect_with('warning') + if @position.destroy + redirect_to(@user, notice: t('.success')) + else + redirect_to(users_path(@user), alert: t('.warning')) + end end private diff --git a/app/controllers/concerns/reference_resource.rb b/app/controllers/concerns/reference_resource.rb index e74958867..96e8adf67 100644 --- a/app/controllers/concerns/reference_resource.rb +++ b/app/controllers/concerns/reference_resource.rb @@ -11,7 +11,7 @@ module ReferenceResource before_action :set_resource, only: %i[edit update destroy] def index - value = pagy_by_search(@model_name.order(:code)) + value = pagy_by_search(@model_name.order(:name)) instance_variable_set("@#{controller_name}", value) end diff --git a/app/controllers/course_management/course_group_types_controller.rb b/app/controllers/course_management/course_group_types_controller.rb index a18d67583..ca8176819 100644 --- a/app/controllers/course_management/course_group_types_controller.rb +++ b/app/controllers/course_management/course_group_types_controller.rb @@ -7,7 +7,7 @@ class CourseGroupTypesController < ApplicationController before_action :set_course_group_type, only: %i[edit update destroy] def index - @course_group_types = pagy_by_search(CourseGroupType.all) + @course_group_types = pagy_by_search(CourseGroupType.order(:name)) end def new @@ -26,7 +26,11 @@ def update end def destroy - @course_group_type.destroy ? redirect_with('success') : redirect_with('warning') + if @course_group_type.destroy + redirect_with('success') + else + redirect_to(course_group_types_path, alert: t('.warning')) + end end private diff --git a/app/controllers/course_management/courses_controller.rb b/app/controllers/course_management/courses_controller.rb index 27b27cbae..537bc8f61 100644 --- a/app/controllers/course_management/courses_controller.rb +++ b/app/controllers/course_management/courses_controller.rb @@ -7,7 +7,7 @@ class CoursesController < ApplicationController before_action :set_course, only: %i[show edit update destroy] def index - courses = Course.includes(:unit) + courses = Course.includes(:unit, :language) .dynamic_search(search_params(Course)) @pagy, @courses = pagy(courses) end diff --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb index 43312eb85..fccc1351f 100644 --- a/app/controllers/documents_controller.rb +++ b/app/controllers/documents_controller.rb @@ -6,7 +6,7 @@ class DocumentsController < ApplicationController before_action :set_document, only: %i[edit update destroy show] def index - @pagy, @documents = pagy(Document.all) + @pagy, @documents = pagy(Document.order(:name)) end def show; end @@ -27,7 +27,11 @@ def update end def destroy - @document.destroy ? redirect_to(documents_path, notice: t('.success')) : redirect_with('warning') + if @document.destroy + redirect_to(documents_path, notice: t('.success')) + else + redirect_to(documents_path, alert: t('.warning')) + end end private diff --git a/app/controllers/references/cities_controller.rb b/app/controllers/references/cities_controller.rb index 599fe1991..27e688ef2 100644 --- a/app/controllers/references/cities_controller.rb +++ b/app/controllers/references/cities_controller.rb @@ -27,7 +27,11 @@ def update end def destroy - @city.destroy ? redirect_to(@country, notice: t('.success')) : redirect_with('warning') + if @city.destroy + redirect_to(@country, notice: t('.success')) + else + redirect_to(@country, alert: t('.warning')) + end end private diff --git a/app/controllers/references/countries_controller.rb b/app/controllers/references/countries_controller.rb index 8c37507e0..e62c2a319 100644 --- a/app/controllers/references/countries_controller.rb +++ b/app/controllers/references/countries_controller.rb @@ -30,7 +30,11 @@ def update end def destroy - @country.destroy ? redirect_to(countries_path, notice: t('.success')) : redirect_with('warning') + if @country.destroy + redirect_to(countries_path, notice: t('.success')) + else + redirect_to(countries_path, alert: t('.warning')) + end end private diff --git a/app/controllers/references/districts_controller.rb b/app/controllers/references/districts_controller.rb index e64a5757a..48076a4ea 100644 --- a/app/controllers/references/districts_controller.rb +++ b/app/controllers/references/districts_controller.rb @@ -21,7 +21,11 @@ def update end def destroy - @district.destroy ? redirect_to([@city.country, @city], notice: t('.success')) : redirect_with('warning') + if @district.destroy + redirect_to([@city.country, @city], notice: t('.success')) + else + redirect_to([@city.country, @city], alert: t('.warning')) + end end private diff --git a/app/controllers/references/home_controller.rb b/app/controllers/references/home_controller.rb new file mode 100644 index 000000000..695b629a0 --- /dev/null +++ b/app/controllers/references/home_controller.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module References + class HomeController < ApplicationController + def index; end + end +end diff --git a/app/controllers/references/languages_controller.rb b/app/controllers/references/languages_controller.rb index 9a278c0e7..6dc30ed19 100644 --- a/app/controllers/references/languages_controller.rb +++ b/app/controllers/references/languages_controller.rb @@ -26,7 +26,11 @@ def update end def destroy - @language.destroy ? redirect_to(languages_path, notice: t('.success')) : redirect_with('warning') + if @language.destroy + redirect_to(languages_path, notice: t('.success')) + else + redirect_to(languages_path, alert: t('.warning')) + end end private diff --git a/app/controllers/registration_documents_controller.rb b/app/controllers/registration_documents_controller.rb index 23fc3334c..d26b33f26 100644 --- a/app/controllers/registration_documents_controller.rb +++ b/app/controllers/registration_documents_controller.rb @@ -26,7 +26,11 @@ def update end def destroy - @registration_document.destroy ? redirect_to(@unit, notice: t('.success')) : redirect_with('warning') + if @registration_document.destroy + redirect_to(@unit, notice: t('.success')) + else + redirect_to(@unit, alert: t('.warning')) + end end private diff --git a/app/controllers/student_management/prospective_students_controller.rb b/app/controllers/student_management/prospective_students_controller.rb index d5b654df3..5a66f1d0a 100644 --- a/app/controllers/student_management/prospective_students_controller.rb +++ b/app/controllers/student_management/prospective_students_controller.rb @@ -4,23 +4,45 @@ module StudentManagement class ProspectiveStudentsController < ApplicationController include PagyBackendWithHelpers - before_action :set_prospective_student, only: %i[show] + before_action :set_prospective_student, only: %i[show register] + before_action :can_register?, only: :register def index - prospective_students = ProspectiveStudent.includes(:unit).dynamic_search(search_params(ProspectiveStudent)) + prospective_students = ProspectiveStudent.includes(:unit, :student_entrance_type) + .dynamic_search(search_params(ProspectiveStudent)) @pagy, @prospective_students = pagy(prospective_students) end def show; end - private + def register + prospective_student = ProspectiveStudentService.new(@prospective_student) + user = prospective_student.create_user - def redirect_with(message) - redirect_to prospective_students_path, flash: { info: t(".#{message}") } + if user.save + student = prospective_student.create_student + student.save ? redirect_with_success : redirect_with_warning('.warning') + else + redirect_with_warning('.warning') + end end + private + def set_prospective_student @prospective_student = ProspectiveStudent.find(params[:id]) end + + def can_register? + redirect_with_warning('.can_not_register') unless @prospective_student.can_temporarily_register? + end + + def redirect_with_success + redirect_to(prospective_students_path, flash: { notice: t('.success') }) + end + + def redirect_with_warning(message) + redirect_to(prospective_students_path, flash: { alert: t(".#{message}") }) + end end end diff --git a/app/controllers/units_controller.rb b/app/controllers/units_controller.rb index 983ac0d02..ce8c3ae2e 100644 --- a/app/controllers/units_controller.rb +++ b/app/controllers/units_controller.rb @@ -30,7 +30,11 @@ def update end def destroy - @unit.destroy ? redirect_to(units_path, notice: t('.success')) : redirect_with('warning') + if @unit.destroy + redirect_to(units_path, notice: t('.success')) + else + redirect_to(units_path, alert: t('.warning')) + end end def courses diff --git a/app/jobs/osym/import_prospective_students_job.rb b/app/jobs/osym/import_prospective_students_job.rb index 90e9de590..c699862ca 100644 --- a/app/jobs/osym/import_prospective_students_job.rb +++ b/app/jobs/osym/import_prospective_students_job.rb @@ -73,7 +73,8 @@ def perform military_status_date: parse_date(military_status_date), obs_status: obs_status.eql?('0') ? true : false, obs_status_date: parse_date(obs_status_date), - obs_registered_program: obs_registered_program + obs_registered_program: obs_registered_program, + student_entrance_type: StudentEntranceType.find_by(code: 1) # TODO: will be dynamic in the future ) progress_bar.increment end diff --git a/app/models/academic_calendar.rb b/app/models/academic_calendar.rb index 6c7435ed9..3d451f891 100644 --- a/app/models/academic_calendar.rb +++ b/app/models/academic_calendar.rb @@ -1,6 +1,14 @@ # frozen_string_literal: true class AcademicCalendar < ApplicationRecord + # search + include PgSearch + pg_search_scope( + :search, + against: %i[name], + using: { tsearch: { prefix: true } } + ) + # relations belongs_to :academic_term belongs_to :calendar_type diff --git a/app/models/concerns/dynamic_search.rb b/app/models/concerns/dynamic_search.rb index 74ba73bc0..b6aa5087d 100644 --- a/app/models/concerns/dynamic_search.rb +++ b/app/models/concerns/dynamic_search.rb @@ -16,9 +16,10 @@ def dynamic_search_keys def dynamic_search(params = {}) raise ArgumentError, 'parameter must be Hash' unless [ActionController::Parameters, Hash].include?(params.class) - return search(params[:term]) if params[:term].present? - dynamic_where(params) + results = dynamic_where(params) + + params[:term].present? ? results.search(params[:term]) : results end private diff --git a/app/models/language.rb b/app/models/language.rb index b8e79baa1..0cc4f0a1d 100644 --- a/app/models/language.rb +++ b/app/models/language.rb @@ -5,7 +5,7 @@ class Language < ApplicationRecord include PgSearch pg_search_scope( :search, - against: %i[name iso yoksis_code], + against: %i[name iso], using: { tsearch: { prefix: true } } ) diff --git a/app/models/prospective_student.rb b/app/models/prospective_student.rb index 0c8473f96..b3450ecdc 100644 --- a/app/models/prospective_student.rb +++ b/app/models/prospective_student.rb @@ -11,13 +11,14 @@ class ProspectiveStudent < ApplicationRecord using: { tsearch: { prefix: true } } ) - search_keys :meb_status, :military_status, :obs_status, :unit_id + search_keys :meb_status, :military_status, :obs_status, :unit_id, :student_entrance_type_id # relations belongs_to :unit belongs_to :language, optional: true belongs_to :student_disability_type, optional: true belongs_to :high_school_type, optional: true + belongs_to :student_entrance_type # validations validates :id_number, presence: true, uniqueness: { scope: %i[unit_id exam_score] } @@ -39,4 +40,13 @@ class ProspectiveStudent < ApplicationRecord enum nationality: { turkish: 1, kktc: 2, foreign: 3 } enum placement_type: { general: 1, additional_score: 2 } enum additional_score: { handicapped: 1 } + + # custom methods + def can_permanently_register? + military_status && obs_status && meb_status + end + + def can_temporarily_register? + military_status + end end diff --git a/app/models/student_entrance_type.rb b/app/models/student_entrance_type.rb index d7a1364e7..af54c1d51 100644 --- a/app/models/student_entrance_type.rb +++ b/app/models/student_entrance_type.rb @@ -3,4 +3,6 @@ class StudentEntranceType < ApplicationRecord include ReferenceValidations include ReferenceCallbacks + + has_many :prospective_students, dependent: :destroy end diff --git a/app/services/prospective_student_service.rb b/app/services/prospective_student_service.rb new file mode 100644 index 000000000..ce1779545 --- /dev/null +++ b/app/services/prospective_student_service.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class ProspectiveStudentService + def initialize(prospective_student) + @prospective_student = prospective_student + end + + def create_user + User.new( + id_number: @prospective_student.id_number, + email: @prospective_student.email, + password: @prospective_student.id_number, + password_confirmation: @prospective_student.id_number + ) + end + + def create_student + Student.new( + user: User.find_by(id_number: @prospective_student.id_number), + unit: @prospective_student.unit, + permanently_registered: @prospective_student.can_permanently_register? ? true : false, + student_number: @prospective_student.id_number # must be generated + ) + end +end diff --git a/app/views/account/employees/_form.html.erb b/app/views/account/employees/_form.html.erb index 181e6d7c0..c30f8fe8b 100644 --- a/app/views/account/employees/_form.html.erb +++ b/app/views/account/employees/_form.html.erb @@ -16,7 +16,7 @@ <%= f.input :title_id, collection: Title.all, required: true %>
<%= t('.meb_status') %> | <%= t('.military_status') %> | <%= t('.obs_status') %> | +<%= t('.student_entrance_type') %> | <%= t('actions') %> | <%= prospective_student.meb_status ? t('.graduated') : t('.not_graduated_or_unknown') %> | <%= prospective_student.military_status ? t('.unproblematic') : t('.must_see_recruiting_office') %> | <%= prospective_student.obs_status ? t('.unproblematic') : t('.student_in_a_different_unit') %> | +<%= prospective_student.student_entrance_type.name %> | <%= link_to_show(prospective_student_path(prospective_student)) %> | diff --git a/app/views/student_management/prospective_students/show.html.erb b/app/views/student_management/prospective_students/show.html.erb index fa59cf473..c018f96d8 100644 --- a/app/views/student_management/prospective_students/show.html.erb +++ b/app/views/student_management/prospective_students/show.html.erb @@ -1,4 +1,78 @@
---|
<%= t('.student_entrance_type') %> | +<%= @prospective_student.student_entrance_type.name %> | +
<%= t('.unit') %> | + <% unit = @prospective_student.unit %> +<%= unit.name %> / <%= unit.parent.name %> / <%= unit.parent.try(:parent).try(:name) %> | +
<%= t('.meb_status') %> | +<%= @prospective_student.meb_status ? t('.graduated') : t('.not_graduated_or_unknown') %> | +
<%= t('.last_update') %>: <%= as_date_and_time(@prospective_student.meb_status_date) %> | +|
<%= t('.military_status') %> | +<%= @prospective_student.military_status ? t('.unproblematic') : t('.must_see_recruiting_office') %> | +
<%= t('.last_update') %>: <%= as_date_and_time(@prospective_student.military_status_date) %> | +|
<%= t('.obs_status') %> | +<%= @prospective_student.obs_status ? t('.unproblematic') : t('.student_in_a_different_unit') %> | +
+ <%= t('.last_update') %>: <%= as_date_and_time(@prospective_student.obs_status_date) %>
+ <% if @prospective_student.obs_registered_program %>
+ + <%= t('.registered_to', program: @prospective_student.obs_registered_program) %> + <% end %> + |
+ |
<%= registration_document.document.name %> | +<%= check_box("post", "validated") %> | + +
<%= t('.unit') %> | - <% unit = @prospective_student.unit %> -<%= unit.name %> / <%= unit.parent.name %> / <%= unit.parent.try(:parent).name %> | -
<%= t('.state_of_education') %> | <%= @prospective_student.state_of_education %> |
<%= t('.meb_status') %> | -- <%= @prospective_student.meb_status ? t('.graduated') : t('.not_graduated_or_unknown') %> | -
<%= t('.meb_status_date') %> | -<%= @prospective_student.meb_status_date %> | -
<%= t('.military_status') %> | -<%= @prospective_student.military_status ? t('.unproblematic') : t('.must_see_recruiting_office') %> | -
<%= t('.military_status_date') %> | -<%= @prospective_student.military_status_date %> | -
<%= t('.obs_status') %> | -<%= @prospective_student.obs_status ? t('.unproblematic') : t('.student_in_a_different_unit') %> | -
<%= t('.obs_status_date') %> | -<%= @prospective_student.obs_status_date %> | -
<%= t('.obs_registered_program') %> | -<%= @prospective_student.obs_registered_program %> | -
<%= t('activerecord.attributes.identity.name') %> | +<%= t('activerecord.attributes.identity.type') %> |
<%= fa_icon('gavel', text: t('activerecord.enums.identity.types.formal')) if identity.formal? %>
diff --git a/app/views/users/_search.html.erb b/app/views/users/_search.html.erb
deleted file mode 100644
index f0b909f1a..000000000
--- a/app/views/users/_search.html.erb
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb
index 0d0baeffa..4bc7426c0 100644
--- a/app/views/users/index.html.erb
+++ b/app/views/users/index.html.erb
@@ -9,7 +9,9 @@
<%= fa_icon 'align-justify', text: t('.card_header') %>
-
-
-
- - - <%= t('smart_search') %> - --
-
-
- <%= form_tag users_path, method: :get do %>
-
-
- <%= text_field_tag 'term', params[:term], placeholder: t('.smart_search_placeholder'), class: 'form-control' %>
-
- <%= submit_tag t('search'), class: 'btn btn-primary' %>
- <% end %>
-
- <%= render 'search' %>
+ <%= render 'components/smart_search_form',
+ path: users_path,
+ placeholder: t('.smart_search_placeholder') %>
|