sis_core 1.0.2 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/sis/core/application_controller.rb +10 -2
  3. data/app/controllers/sis/core/menus_controller.rb +22 -0
  4. data/app/controllers/sis/core/users_controller.rb +71 -0
  5. data/app/models/sis/core/academic_programme.rb +17 -0
  6. data/app/models/sis/core/academic_year.rb +7 -0
  7. data/app/models/sis/core/applicant.rb +8 -1
  8. data/app/models/sis/core/application.rb +50 -0
  9. data/app/models/sis/core/application_document.rb +12 -0
  10. data/app/models/sis/core/application_module.rb +8 -0
  11. data/app/models/sis/core/application_setup.rb +23 -0
  12. data/app/models/sis/core/course.rb +10 -0
  13. data/app/models/sis/core/course_registration.rb +9 -0
  14. data/app/models/sis/core/document_requirement.rb +13 -0
  15. data/app/models/sis/core/{program_type.rb → document_type.rb} +1 -1
  16. data/app/models/sis/core/exam.rb +17 -0
  17. data/app/models/sis/core/exam_result.rb +25 -0
  18. data/app/models/sis/core/exam_setup.rb +15 -0
  19. data/app/models/sis/core/instructor.rb +6 -0
  20. data/app/models/sis/core/instructor_course.rb +8 -0
  21. data/app/models/sis/core/menu.rb +11 -0
  22. data/app/models/sis/core/programme.rb +7 -0
  23. data/app/models/sis/core/programme_level.rb +6 -0
  24. data/app/models/sis/core/programme_type.rb +6 -0
  25. data/app/models/sis/core/semester.rb +11 -0
  26. data/app/models/sis/core/student.rb +7 -0
  27. data/app/models/sis/core/user.rb +13 -0
  28. data/app/models/sis/core/user_role.rb +10 -0
  29. data/app/services/sis/core/user_service.rb +25 -0
  30. data/app/uploaders/sis/core/application_document_uploader.rb +51 -0
  31. data/app/uploaders/sis/core/photo_uploader.rb +51 -0
  32. data/config/routes.rb +6 -0
  33. data/db/migrate/20200105072142_create_sis_core_academic_years.rb +10 -0
  34. data/db/migrate/20200106072246_create_sis_core_semesters.rb +14 -0
  35. data/db/migrate/20200106130428_create_sis_core_programmes.rb +10 -0
  36. data/db/migrate/20200106132035_create_sis_core_academic_programmes.rb +21 -0
  37. data/db/migrate/20200106132521_create_sis_core_application_setups.rb +19 -0
  38. data/db/migrate/20200106133034_create_sis_core_document_requirements.rb +19 -0
  39. data/db/migrate/20200106133937_create_sis_core_applicants.rb +14 -2
  40. data/db/migrate/20200107094449_create_sis_core_applications.rb +24 -0
  41. data/db/migrate/20200107101638_create_sis_core_application_documents.rb +16 -0
  42. data/db/migrate/20200107302251_create_sis_core_exam_setups.rb +15 -0
  43. data/db/migrate/20200107333411_create_sis_core_exams.rb +17 -0
  44. data/db/migrate/20200107434658_create_sis_core_exam_results.rb +18 -0
  45. data/db/migrate/20200307033100_create_sis_core_courses.rb +19 -0
  46. data/db/migrate/20200307071511_create_sis_core_instructors.rb +10 -0
  47. data/db/migrate/20200307071736_create_sis_core_instructor_courses.rb +16 -0
  48. data/db/migrate/20200307072006_create_sis_core_students.rb +16 -0
  49. data/db/migrate/20200307072317_create_sis_core_course_registrations.rb +20 -0
  50. data/db/migrate/20200507114003_create_sis_core_users.rb +17 -0
  51. data/db/migrate/20200511165121_create_sis_core_application_modules.rb +15 -0
  52. data/db/migrate/20200511165241_create_sis_core_user_roles.rb +15 -0
  53. data/db/migrate/20200511165450_create_sis_core_menus.rb +18 -0
  54. data/lib/authorize_request.rb +18 -0
  55. data/lib/json_web_token.rb +12 -0
  56. data/lib/sis/core/engine.rb +2 -2
  57. data/lib/sis/core/version.rb +1 -1
  58. data/lib/sis_core.rb +5 -0
  59. data/spec/factories/sis/core/academic_programmes.rb +8 -0
  60. data/spec/factories/sis/core/academic_years.rb +6 -0
  61. data/spec/factories/sis/core/applicants.rb +9 -2
  62. data/spec/factories/sis/core/application_documents.rb +7 -0
  63. data/spec/factories/sis/core/application_modules.rb +6 -0
  64. data/spec/factories/sis/core/application_setups.rb +9 -0
  65. data/spec/factories/sis/core/applications.rb +11 -0
  66. data/spec/factories/sis/core/course_registrations.rb +7 -0
  67. data/spec/factories/sis/core/courses.rb +12 -0
  68. data/spec/factories/sis/core/document_requirements.rb +9 -0
  69. data/spec/factories/sis/core/document_types.rb +5 -0
  70. data/spec/factories/sis/core/exam_results.rb +8 -0
  71. data/spec/factories/sis/core/exam_setups.rb +8 -0
  72. data/spec/factories/sis/core/exams.rb +10 -0
  73. data/spec/factories/sis/core/instructor_courses.rb +6 -0
  74. data/spec/factories/sis/core/instructors.rb +6 -0
  75. data/spec/factories/sis/core/menus.rb +9 -0
  76. data/spec/factories/sis/core/programme_levels.rb +5 -0
  77. data/spec/factories/sis/core/programme_types.rb +5 -0
  78. data/spec/factories/sis/core/programmes.rb +6 -0
  79. data/spec/factories/sis/core/semesters.rb +7 -0
  80. data/spec/factories/sis/core/students.rb +9 -0
  81. data/spec/factories/sis/core/user_roles.rb +6 -0
  82. data/spec/factories/sis/core/users.rb +9 -0
  83. metadata +169 -22
  84. data/app/models/sis/core/attached_document.rb +0 -8
  85. data/app/models/sis/core/enrollment_application.rb +0 -9
  86. data/app/models/sis/core/program.rb +0 -9
  87. data/app/models/user.rb +0 -9
  88. data/config/initializers/devise_token_auth.rb +0 -55
  89. data/db/migrate/20200106001016_create_sis_core_field_of_studies.rb +0 -9
  90. data/db/migrate/20200106130428_create_sis_core_programs.rb +0 -10
  91. data/db/migrate/20200108092202_devise_token_auth_create_users.rb +0 -53
  92. data/db/migrate/20200108094449_create_sis_core_enrollment_applications.rb +0 -10
  93. data/db/migrate/20200108101638_create_sis_core_attached_documents.rb +0 -11
  94. data/spec/factories/sis/core/attached_documents.rb +0 -7
  95. data/spec/factories/sis/core/enrollment_applications.rb +0 -7
  96. data/spec/factories/sis/core/field_of_studies.rb +0 -6
  97. data/spec/factories/sis/core/program_types.rb +0 -5
  98. data/spec/factories/sis/core/programs.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9c5c35209b30494fac39af83105c8317aee1f412c3271b224479f5897ed67ad1
4
- data.tar.gz: 3c09e2a7dd305dbb39179ca09f219d3a25c96731cffd0fa85f0b9e65cd565e83
3
+ metadata.gz: 1d9b0264aef8769263ead6f9f8bcef7b789ca2a52ec27478a1646e0626e67ebb
4
+ data.tar.gz: f5c6909c614cd0ff7fdc75d922d22836c030be6a951e60cc4f640895f7e62bb2
5
5
  SHA512:
6
- metadata.gz: f26a6169dd2460db579620a70ffbc87c5c40a1dbe79cc184ecbb4909af063f422b033799e9cacc39619605c57d0d39eef4007acffb39c1ab11c5cf64edd5c47f
7
- data.tar.gz: 45f8515c2b6f5113fc76e70fa20f97bde6d3161e14f8116cbc7170d1f9667468dce31548c54959180d6cabec38bf7695aac9d77d2031e33d17ebb3744f625155
6
+ metadata.gz: 061ec28c7971d97981cd84d3662350d261c30fb5a5cfa845f7d9b7be7bcd06e341f4cb40976d48fa850b52adfcfb9cc29f1b78cf707b7fdfed52aa7a071bc16b
7
+ data.tar.gz: 9293603b43d28e10bbe8d79024fc1c5392bdd5c43e2b378fc1497acc36624c95d108d8fc138acb5839abb47e336c2adbed2fca576727a33caeecd8163fecbc42
@@ -1,7 +1,15 @@
1
1
  module Sis
2
2
  module Core
3
- class ApplicationController < ActionController::Base
4
- protect_from_forgery with: :exception
3
+ class ApplicationController < ActionController::API
4
+ before_action :authenticate_request
5
+ attr_reader :current_user
6
+
7
+ private
8
+
9
+ def authenticate_request
10
+ @current_user = AuthorizeRequest.user(request.headers)
11
+ render json: { error: 'Not Authorized' }, status: 401 unless @current_user
12
+ end
5
13
  end
6
14
  end
7
15
  end
@@ -0,0 +1,22 @@
1
+ module Sis
2
+ module Core
3
+ class MenusController < ApplicationController
4
+ skip_before_action :authenticate_request, only: [:menu]
5
+ def menu
6
+ app_module_id = ApplicationModule.find_by_code(params[:app_module]).id
7
+ user_roles = User.find(params[:user_id]).user_roles.where(application_module_id: app_module_id)
8
+ menus = []
9
+ user_roles.each do |role|
10
+ user_menus = role.menus.where(parent_id: nil, application_module_id: app_module_id)
11
+ user_menus.each do |user_menu|
12
+ children = user_menu.children.where(parent_id: user_menu.id, application_module_id: app_module_id)
13
+ children = children.map { |c| { label: c.text, icon: c.icon_cls, routerLink: [c.location] } }
14
+ menus.push({ label: user_menu.text, icon: user_menu.icon_cls, location: user_menu.location,
15
+ items: children })
16
+ end
17
+ end
18
+ render json: { success: true, data: menus }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,71 @@
1
+ module Sis
2
+ module Core
3
+ class UsersController < ApplicationController
4
+ skip_before_action :authenticate_request, only: %i[login sign_in generate_recovery_token reset_password]
5
+ before_action :set_user_service, only: %i[generate_recovery_token reset_password]
6
+ def sign_in
7
+ applicant = Applicant&.find_by_email(params[:email])
8
+ if Applicant&.find_by_email(params[:email]) && applicant.authenticate(params[:password])
9
+ token = JsonWebToken.encode({ id: applicant.id, first_name: applicant.first_name,
10
+ middle_name: applicant.middle_name, last_name: applicant.last_name,
11
+ email: applicant.email })
12
+ render json: { success: true, jwt: token }
13
+ else
14
+ render json: { success: false, errors: ['Invalid username or password !'] }
15
+ end
16
+ end
17
+
18
+ def create
19
+ user = User.new(user_params)
20
+ if user.save
21
+ render json: { success: true, data: user }
22
+ else
23
+ render json: { success: false, errors: user.errors }
24
+ end
25
+ end
26
+
27
+ def login
28
+ user = User.find_by_email(params[:email])
29
+ if User&.find_by_email(params[:email]) && user.authenticate(params[:password])
30
+ token = JsonWebToken.encode({ id: user.id, first_name: user.first_name, last_name: user.last_name })
31
+ render json: { success: true, jwt: token }
32
+ else
33
+ render json: { success: false, errors: ['Invalid username or password !'] }
34
+ end
35
+ end
36
+
37
+ def generate_recovery_token
38
+ user = User.where(email: params[:email], secret_question_answer: params[:secret_question_answer])
39
+ if user.count.positive?
40
+ user = user[0]
41
+ @service.generate_password_token(user)
42
+ render json: { success: true, token: user.reset_password_token, email: user.email }
43
+ else
44
+ render json: { success: false, errors: ['User not found !'] }
45
+ end
46
+ end
47
+
48
+ def reset_password
49
+ token = params[:token].to_s
50
+ user = User.find_by_reset_password_token(token)
51
+ if user && @service.password_token_valid?(user.id)
52
+ @service.reset_password(user.id, params[:password])
53
+ render json: { success: true }
54
+ else
55
+ render json: { success: false, errors: ['Link not valid or expired. Try generating a new link !'] }
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def user_params
62
+ params.require('user').permit(:id, :first_name, :last_name, :email, :password, :reset_password_token,
63
+ :reset_password_sent_at, :secret_question, :secret_question_answer)
64
+ end
65
+
66
+ def set_user_service
67
+ @service = UserService.new
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,17 @@
1
+ module Sis
2
+ module Core
3
+ class AcademicProgramme < ApplicationRecord
4
+ belongs_to :programme
5
+ belongs_to :programme_type
6
+ belongs_to :programme_level
7
+
8
+ delegate(:name, to: :programme, prefix: true, allow_nil: false)
9
+ delegate(:name, to: :programme_type, prefix: true, allow_nil: false)
10
+ delegate(:name, to: :programme_level, prefix: true, allow_nil: false)
11
+
12
+ def name
13
+ programme.name.to_s + ' ' + programme_level.name.to_s + ' ' + programme_type.name.to_s
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ module Sis
2
+ module Core
3
+ class AcademicYear < ApplicationRecord
4
+ validates :year, presence: true, uniqueness: { case_sensitive: false }
5
+ end
6
+ end
7
+ end
@@ -1,8 +1,15 @@
1
1
  module Sis
2
2
  module Core
3
3
  class Applicant < ApplicationRecord
4
- validates :first_name, :middle_name, :last_name, :email, :phone_number, presence: true
4
+ mount_base64_uploader :photo, PhotoUploader
5
+ validates :first_name, :middle_name, :last_name, :email, presence: true
5
6
  validates :email, uniqueness: true
7
+
8
+ has_secure_password
9
+
10
+ def full_name
11
+ first_name + ' ' + middle_name + ' ' + last_name
12
+ end
6
13
  end
7
14
  end
8
15
  end
@@ -0,0 +1,50 @@
1
+ module Sis
2
+ module Core
3
+ class Application < ApplicationRecord
4
+ include AASM
5
+
6
+ # Gender types
7
+ MALE = 'Male'.freeze
8
+ FEMALE = 'Female'.freeze
9
+
10
+ aasm column: :status do
11
+ state :draft, initial: true
12
+ state :submitted, :under_review, :accepted, :rejected, :selected_for_exam, :selected_for_admission
13
+
14
+ event :submit do
15
+ transitions from: :draft, to: :submitted
16
+ end
17
+
18
+ event :review do
19
+ transitions from: %i[submitted rejected accepted], to: :under_review
20
+ end
21
+
22
+ event :accept do
23
+ transitions from: :under_review, to: :accepted
24
+ end
25
+
26
+ event :reject do
27
+ transitions from: :under_review, to: :rejected
28
+ end
29
+
30
+ event :select_for_exam do
31
+ transitions from: :accepted, to: :selected_for_exam
32
+ end
33
+
34
+ event :select_for_admission do
35
+ transitions from: :selected_for_exam, to: :selected_for_admission
36
+ end
37
+ end
38
+
39
+ validates :status, presence: true
40
+ validates :payment_information, presence: true, if: :payment_made
41
+
42
+ belongs_to :applicant
43
+ belongs_to :academic_programme
44
+ belongs_to :application_setup
45
+
46
+ delegate(:name, to: :academic_programme, prefix: true, allow_nil: false)
47
+ delegate(:full_name, to: :applicant, prefix: true, allow_nil: false)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,12 @@
1
+ module Sis
2
+ module Core
3
+ class ApplicationDocument < ApplicationRecord
4
+ mount_base64_uploader :document, ApplicationDocumentUploader
5
+
6
+ belongs_to :application
7
+ belongs_to :document_requirement
8
+
9
+ delegate(:name, to: :document_requirement, prefix: true, allow_nil: false)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ module Sis
2
+ module Core
3
+ class ApplicationModule < ApplicationRecord
4
+ has_and_belongs_to_many :users
5
+ validates :code, :name, presence: true
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,23 @@
1
+ module Sis
2
+ module Core
3
+ class ApplicationSetup < ApplicationRecord
4
+ OPEN = 'Open'.freeze
5
+ CLOSED = 'Closed'.freeze
6
+
7
+ belongs_to :academic_programme
8
+ belongs_to :target_semester, class_name: 'Sis::Core::Semester'
9
+ has_many :document_requirements
10
+
11
+ validates :start_date, :end_date, :status, presence: true
12
+ validates :status, inclusion: [OPEN, CLOSED]
13
+
14
+ delegate(:name, to: :target_semester, prefix: true, allow_nil: false)
15
+ delegate(:name, to: :academic_programme, prefix: true, allow_nil: false)
16
+
17
+ def name
18
+ academic_programme.programme.name.to_s + ' ' + academic_programme.programme_level.name.to_s + ' ' +
19
+ academic_programme.programme_type.name.to_s
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ module Sis
2
+ module Core
3
+ class Course < ApplicationRecord
4
+ belongs_to :program
5
+
6
+ validates :code, :title, :description, :credit_hours, :ects, :lecture_hours, :lab_hours, presence: true
7
+ validates :code, uniqueness: true
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Sis
2
+ module Core
3
+ class CourseRegistration < ApplicationRecord
4
+ belongs_to :course
5
+ belongs_to :student
6
+ belongs_to :semester
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ module Sis
2
+ module Core
3
+ class DocumentRequirement < ApplicationRecord
4
+ belongs_to :document_type
5
+ belongs_to :application_setup
6
+
7
+ validates :original, :copy, presence: true
8
+
9
+ delegate(:name, to: :document_type, prefix: true, allow_nil: false)
10
+ delegate(:name, to: :application_setup, prefix: true, allow_nil: false)
11
+ end
12
+ end
13
+ end
@@ -1,6 +1,6 @@
1
1
  module Sis
2
2
  module Core
3
- class ProgramType < Lookup
3
+ class DocumentType < Lookup
4
4
  end
5
5
  end
6
6
  end
@@ -0,0 +1,17 @@
1
+ module Sis
2
+ module Core
3
+ class Exam < ApplicationRecord
4
+ belongs_to :exam_setup
5
+
6
+ validates :title, :start, :finish, :pass_point, :points, presence: true
7
+
8
+ before_validation :set_pass_point
9
+
10
+ def set_pass_point
11
+ self.pass_point = points / 2 unless pass_point || !points
12
+ end
13
+
14
+ delegate(:name, to: :exam_setup, prefix: true, allow_nil: false)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ module Sis
2
+ module Core
3
+ class ExamResult < ApplicationRecord
4
+ PASS = 'Pass'.freeze
5
+ FAIL = 'Fail'.freeze
6
+
7
+ belongs_to :exam
8
+ belongs_to :application
9
+
10
+ validates :points, presence: true
11
+ validates_uniqueness_of :application_id, scope: %i[exam_id]
12
+
13
+
14
+ before_validation :set_status
15
+
16
+ def set_status
17
+ self.status = if exam && exam.pass_point >= points
18
+ PASS
19
+ else
20
+ FAIL
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ module Sis
2
+ module Core
3
+ class ExamSetup < ApplicationRecord
4
+ belongs_to :application_setup
5
+
6
+ validates :date, :hours, :venue, presence: true
7
+
8
+ def name
9
+ application_setup.academic_programme.name
10
+ end
11
+
12
+ delegate(:name, to: :application_setup, prefix: true, allow_nil: false)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ module Sis
2
+ module Core
3
+ class Instructor < ApplicationRecord
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,8 @@
1
+ module Sis
2
+ module Core
3
+ class InstructorCourse < ApplicationRecord
4
+ belongs_to :instructor
5
+ belongs_to :course
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ module Sis
2
+ module Core
3
+ class Menu < ApplicationRecord
4
+ has_and_belongs_to_many :user_roles
5
+ belongs_to :application_module
6
+ belongs_to :parent, class_name: 'Sis::Core::Menu', optional: true
7
+ has_many :children, class_name: 'Sis::Core::Menu', foreign_key: 'parent_id'
8
+ validates :text, presence: true
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Sis
2
+ module Core
3
+ class Programme < ApplicationRecord
4
+ validates :code, :name, presence: true, uniqueness: true
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ module Sis
2
+ module Core
3
+ class ProgrammeLevel < Lookup
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Sis
2
+ module Core
3
+ class ProgrammeType < Lookup
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ module Sis
2
+ module Core
3
+ class Semester < ApplicationRecord
4
+ belongs_to :academic_year
5
+
6
+ validates :name, presence: true
7
+
8
+ delegate(:label, to: :academic_year, prefix: true, allow_nil: false)
9
+ end
10
+ end
11
+ end