next_sgad 0.1.3

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 (212) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +34 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/config/next_sgad_manifest.js +2 -0
  6. data/app/assets/javascripts/next_sgad/activities.js +2 -0
  7. data/app/assets/javascripts/next_sgad/application.js +108 -0
  8. data/app/assets/javascripts/next_sgad/assessments.js +2 -0
  9. data/app/assets/javascripts/next_sgad/attendances.js +2 -0
  10. data/app/assets/javascripts/next_sgad/configurations.js +2 -0
  11. data/app/assets/javascripts/next_sgad/departments.js +2 -0
  12. data/app/assets/javascripts/next_sgad/employee_goals.js +2 -0
  13. data/app/assets/javascripts/next_sgad/employees.js +2 -0
  14. data/app/assets/javascripts/next_sgad/functions.js +7 -0
  15. data/app/assets/javascripts/next_sgad/goals.js +2 -0
  16. data/app/assets/javascripts/next_sgad/jquery.orgchart.min.js +2 -0
  17. data/app/assets/javascripts/next_sgad/justifications.js +2 -0
  18. data/app/assets/javascripts/next_sgad/positions.js +2 -0
  19. data/app/assets/javascripts/next_sgad/results.js +2 -0
  20. data/app/assets/stylesheets/next_sgad/activities.css +4 -0
  21. data/app/assets/stylesheets/next_sgad/application.css +77 -0
  22. data/app/assets/stylesheets/next_sgad/assessments.css +4 -0
  23. data/app/assets/stylesheets/next_sgad/attendances.css +4 -0
  24. data/app/assets/stylesheets/next_sgad/configurations.css +4 -0
  25. data/app/assets/stylesheets/next_sgad/departments.css +4 -0
  26. data/app/assets/stylesheets/next_sgad/employee_goals.css +4 -0
  27. data/app/assets/stylesheets/next_sgad/employees.css +4 -0
  28. data/app/assets/stylesheets/next_sgad/functions.css +4 -0
  29. data/app/assets/stylesheets/next_sgad/goals.css +4 -0
  30. data/app/assets/stylesheets/next_sgad/jquery.orgchart.min.css +2 -0
  31. data/app/assets/stylesheets/next_sgad/justifications.css +4 -0
  32. data/app/assets/stylesheets/next_sgad/positions.css +4 -0
  33. data/app/assets/stylesheets/next_sgad/results.css +4 -0
  34. data/app/controllers/next_sgad/activities_controller.rb +63 -0
  35. data/app/controllers/next_sgad/application_controller.rb +5 -0
  36. data/app/controllers/next_sgad/assessments_controller.rb +62 -0
  37. data/app/controllers/next_sgad/attendances_controller.rb +62 -0
  38. data/app/controllers/next_sgad/configurations_controller.rb +62 -0
  39. data/app/controllers/next_sgad/departments_controller.rb +62 -0
  40. data/app/controllers/next_sgad/employee_goals_controller.rb +62 -0
  41. data/app/controllers/next_sgad/employees_controller.rb +62 -0
  42. data/app/controllers/next_sgad/functions_controller.rb +62 -0
  43. data/app/controllers/next_sgad/goals_controller.rb +62 -0
  44. data/app/controllers/next_sgad/justifications_controller.rb +62 -0
  45. data/app/controllers/next_sgad/positions_controller.rb +78 -0
  46. data/app/controllers/next_sgad/results_controller.rb +62 -0
  47. data/app/helpers/next_sgad/activities_helper.rb +4 -0
  48. data/app/helpers/next_sgad/application_helper.rb +4 -0
  49. data/app/helpers/next_sgad/assessments_helper.rb +4 -0
  50. data/app/helpers/next_sgad/attendances_helper.rb +4 -0
  51. data/app/helpers/next_sgad/configurations_helper.rb +4 -0
  52. data/app/helpers/next_sgad/departments_helper.rb +4 -0
  53. data/app/helpers/next_sgad/employee_goals_helper.rb +4 -0
  54. data/app/helpers/next_sgad/employees_helper.rb +4 -0
  55. data/app/helpers/next_sgad/functions_helper.rb +4 -0
  56. data/app/helpers/next_sgad/goals_helper.rb +4 -0
  57. data/app/helpers/next_sgad/justifications_helper.rb +4 -0
  58. data/app/helpers/next_sgad/positions_helper.rb +55 -0
  59. data/app/helpers/next_sgad/results_helper.rb +4 -0
  60. data/app/jobs/next_sgad/application_job.rb +4 -0
  61. data/app/mailers/next_sgad/application_mailer.rb +6 -0
  62. data/app/models/next_sgad/activity.rb +4 -0
  63. data/app/models/next_sgad/application_record.rb +18 -0
  64. data/app/models/next_sgad/assessment.rb +128 -0
  65. data/app/models/next_sgad/attendance.rb +70 -0
  66. data/app/models/next_sgad/configuration.rb +4 -0
  67. data/app/models/next_sgad/department.rb +20 -0
  68. data/app/models/next_sgad/employee.rb +28 -0
  69. data/app/models/next_sgad/employee_goal.rb +36 -0
  70. data/app/models/next_sgad/function.rb +8 -0
  71. data/app/models/next_sgad/goal.rb +37 -0
  72. data/app/models/next_sgad/justification.rb +47 -0
  73. data/app/models/next_sgad/position.rb +36 -0
  74. data/app/models/next_sgad/result.rb +27 -0
  75. data/app/models/next_sgad/setting.rb +13 -0
  76. data/app/views/layouts/next_sgad/application.html.erb +14 -0
  77. data/app/views/next_sgad/activities/_form.html.erb +27 -0
  78. data/app/views/next_sgad/activities/edit.html.erb +6 -0
  79. data/app/views/next_sgad/activities/index.html.erb +29 -0
  80. data/app/views/next_sgad/activities/new.html.erb +5 -0
  81. data/app/views/next_sgad/activities/show.html.erb +14 -0
  82. data/app/views/next_sgad/assessments/_form.html.erb +27 -0
  83. data/app/views/next_sgad/assessments/edit.html.erb +6 -0
  84. data/app/views/next_sgad/assessments/index.html.erb +29 -0
  85. data/app/views/next_sgad/assessments/new.html.erb +5 -0
  86. data/app/views/next_sgad/assessments/show.html.erb +14 -0
  87. data/app/views/next_sgad/attendances/_form.html.erb +37 -0
  88. data/app/views/next_sgad/attendances/edit.html.erb +6 -0
  89. data/app/views/next_sgad/attendances/index.html.erb +33 -0
  90. data/app/views/next_sgad/attendances/new.html.erb +5 -0
  91. data/app/views/next_sgad/attendances/show.html.erb +24 -0
  92. data/app/views/next_sgad/configurations/_form.html.erb +32 -0
  93. data/app/views/next_sgad/configurations/edit.html.erb +6 -0
  94. data/app/views/next_sgad/configurations/index.html.erb +31 -0
  95. data/app/views/next_sgad/configurations/new.html.erb +5 -0
  96. data/app/views/next_sgad/configurations/show.html.erb +19 -0
  97. data/app/views/next_sgad/departments/_form.html.erb +32 -0
  98. data/app/views/next_sgad/departments/edit.html.erb +6 -0
  99. data/app/views/next_sgad/departments/index.html.erb +33 -0
  100. data/app/views/next_sgad/departments/new.html.erb +5 -0
  101. data/app/views/next_sgad/departments/show.html.erb +24 -0
  102. data/app/views/next_sgad/employee_goals/_form.html.erb +42 -0
  103. data/app/views/next_sgad/employee_goals/edit.html.erb +6 -0
  104. data/app/views/next_sgad/employee_goals/index.html.erb +35 -0
  105. data/app/views/next_sgad/employee_goals/new.html.erb +5 -0
  106. data/app/views/next_sgad/employee_goals/show.html.erb +29 -0
  107. data/app/views/next_sgad/employees/_form.html.erb +27 -0
  108. data/app/views/next_sgad/employees/_organigrama.html.erb +7 -0
  109. data/app/views/next_sgad/employees/edit.html.erb +6 -0
  110. data/app/views/next_sgad/employees/index.html.erb +31 -0
  111. data/app/views/next_sgad/employees/new.html.erb +5 -0
  112. data/app/views/next_sgad/employees/show.html.erb +19 -0
  113. data/app/views/next_sgad/functions/_form.html.erb +22 -0
  114. data/app/views/next_sgad/functions/edit.html.erb +6 -0
  115. data/app/views/next_sgad/functions/index.html.erb +27 -0
  116. data/app/views/next_sgad/functions/new.html.erb +5 -0
  117. data/app/views/next_sgad/functions/show.html.erb +9 -0
  118. data/app/views/next_sgad/goals/_form.html.erb +62 -0
  119. data/app/views/next_sgad/goals/edit.html.erb +6 -0
  120. data/app/views/next_sgad/goals/index.html.erb +41 -0
  121. data/app/views/next_sgad/goals/new.html.erb +5 -0
  122. data/app/views/next_sgad/goals/show.html.erb +49 -0
  123. data/app/views/next_sgad/justifications/_form.html.erb +22 -0
  124. data/app/views/next_sgad/justifications/edit.html.erb +6 -0
  125. data/app/views/next_sgad/justifications/index.html.erb +27 -0
  126. data/app/views/next_sgad/justifications/new.html.erb +5 -0
  127. data/app/views/next_sgad/justifications/show.html.erb +9 -0
  128. data/app/views/next_sgad/positions/_form.html.erb +43 -0
  129. data/app/views/next_sgad/positions/edit.html.erb +6 -0
  130. data/app/views/next_sgad/positions/index.html.erb +94 -0
  131. data/app/views/next_sgad/positions/new.html.erb +5 -0
  132. data/app/views/next_sgad/positions/organigram.html.erb +1 -0
  133. data/app/views/next_sgad/positions/show.html.erb +34 -0
  134. data/app/views/next_sgad/results/_form.html.erb +37 -0
  135. data/app/views/next_sgad/results/edit.html.erb +6 -0
  136. data/app/views/next_sgad/results/index.html.erb +33 -0
  137. data/app/views/next_sgad/results/new.html.erb +5 -0
  138. data/app/views/next_sgad/results/show.html.erb +24 -0
  139. data/config/initializers/core_extentions.rb +1 -0
  140. data/config/initializers/initializer.rb +1 -0
  141. data/config/initializers/m.rb +1 -0
  142. data/config/initializers/semper.rb +1 -0
  143. data/config/routes.rb +16 -0
  144. data/db/migrate/20171014174705_create_next_sgad_departments.rb +11 -0
  145. data/db/migrate/20171014175212_create_next_sgad_employees.rb +11 -0
  146. data/db/migrate/20171014175507_create_next_sgad_positions.rb +13 -0
  147. data/db/migrate/20171014183337_create_next_sgad_configurations.rb +11 -0
  148. data/db/migrate/20171015073528_add_next_sgad_department_to_department.rb +6 -0
  149. data/db/migrate/20171019142918_remove_table_configurations.rb +5 -0
  150. data/db/migrate/20171019143336_create_next_sgad_settings.rb +11 -0
  151. data/db/migrate/20171022113005_add_paygrade_to_next_sgad_employee.rb +6 -0
  152. data/db/migrate/20171024154422_create_next_sgad_assessments.rb +10 -0
  153. data/db/migrate/20171024172007_create_next_sgad_goals.rb +18 -0
  154. data/db/migrate/20171024181227_create_next_sgad_employee_goals.rb +16 -0
  155. data/db/migrate/20171024192907_corrects_references.rb +8 -0
  156. data/db/migrate/20171024193750_copies_info_from_old_references.rb +8 -0
  157. data/db/migrate/20171025093224_change_column_year_from_assessments.rb +6 -0
  158. data/db/migrate/20171025134655_add_goal_type_to_employee_goals.rb +8 -0
  159. data/db/migrate/20171025135319_addname_to_next_sgad_employee_goals.rb +5 -0
  160. data/db/migrate/20171025153545_add_position_reference_to_goals.rb +4 -0
  161. data/db/migrate/20171026055530_add_position_to_next_sgad_goals.rb +5 -0
  162. data/db/migrate/20171026060110_add_position_to_next_sgad_employee.rb +5 -0
  163. data/db/migrate/20171026060351_copies_posiiton_id_to_employees.rb +9 -0
  164. data/db/migrate/20171026061315_remove_old_reference_columns.rb +8 -0
  165. data/db/migrate/20171026115447_add_description_to_next_sgad_goals.rb +6 -0
  166. data/db/migrate/20171026142240_add_position_to_next_sgad_employee_goals.rb +5 -0
  167. data/db/migrate/20171027210543_create_next_sgad_functions.rb +9 -0
  168. data/db/migrate/20171027210912_add_function_to_next_sgad_positions.rb +5 -0
  169. data/db/migrate/20171027213833_create_join_table_goal_position.rb +8 -0
  170. data/db/migrate/20171027221550_create_join_table_employee_position.rb +8 -0
  171. data/db/migrate/20171027223737_add_efective_to_next_sgad_positions.rb +5 -0
  172. data/db/migrate/20171027230032_remove_position_from_next_sgad_employee.rb +6 -0
  173. data/db/migrate/20171027230033_clear_data.rb +7 -0
  174. data/db/migrate/20171028061909_add_description_to_next_sgad_functions.rb +5 -0
  175. data/db/migrate/20171028140106_add_percentages_to_next_sagad_assessments.rb +6 -0
  176. data/db/migrate/20171029074321_rename_paygrade_and_level_from_employee.rb +7 -0
  177. data/db/migrate/20171029103212_add_email_to_next_sgad_employee.rb +5 -0
  178. data/db/migrate/20171029154047_add_coment_to_next_sgad_employee_goals.rb +6 -0
  179. data/db/migrate/20171029160044_add_amount_to_next_sgad_employee_goals.rb +5 -0
  180. data/db/migrate/20171101112232_change_self_assessment_from_next_sgad_employee_goals.rb +13 -0
  181. data/db/migrate/20171106113735_add_first_name_to_next_sgad_employees.rb +24 -0
  182. data/db/migrate/20171110103155_add_number_to_next_sgad_functions.rb +5 -0
  183. data/db/migrate/20171111081148_create_next_sgad_justifications.rb +9 -0
  184. data/db/migrate/20171111093506_create_next_sgad_attendances.rb +13 -0
  185. data/db/migrate/20171111093524_add_references_to_justifications_and_attendences.rb +10 -0
  186. data/db/migrate/20171111094154_create_join_table_attendance_justification.rb +8 -0
  187. data/db/migrate/20171111121753_create_next_sgad_results.rb +13 -0
  188. data/db/migrate/20171111121935_resolts_relationship.rb +9 -0
  189. data/db/migrate/20171112004221_add_attendance_percentage_to_next_sgad_assessment.rb +14 -0
  190. data/db/migrate/20171112121440_add_status_to_next_sgad_justifications.rb +7 -0
  191. data/db/migrate/20171112172436_add_department_to_attendances.rb +6 -0
  192. data/db/migrate/20171113125224_add_configuration_columns_to_nexts_sgad_assessment.rb +18 -0
  193. data/db/migrate/20171113143825_add_max_number_of_absences_for_five_to_next_sgad_assessments.rb +9 -0
  194. data/db/migrate/20171114135601_change_column_status_from_result.rb +6 -0
  195. data/db/migrate/20171115085324_create_next_sgad_activities.rb +10 -0
  196. data/db/migrate/20171115110522_add_column_nature_and_value_to_results.rb +7 -0
  197. data/db/migrate/20171115111821_remove_unused_columns.rb +19 -0
  198. data/db/migrate/20171115140048_corrects_status.rb +6 -0
  199. data/db/migrate/20171115160122_add_justification_status_to_next_sgad_attendances.rb +5 -0
  200. data/db/migrate/20171115161157_migrate_fill_justification_columns.rb +7 -0
  201. data/lib/concerns/models/employee.rb +25 -0
  202. data/lib/generators/initializer/USAGE +8 -0
  203. data/lib/generators/initializer/initializer_generator.rb +6 -0
  204. data/lib/generators/initializer/templates/initializer.rb +1 -0
  205. data/lib/generators/initializer_generator.rb +6 -0
  206. data/lib/generators/views/USAGE +8 -0
  207. data/lib/generators/views/views_generator.rb +3 -0
  208. data/lib/next_sgad/engine.rb +13 -0
  209. data/lib/next_sgad/version.rb +3 -0
  210. data/lib/next_sgad.rb +5 -0
  211. data/lib/tasks/next_sgad_tasks.rake +4 -0
  212. metadata +268 -0
@@ -0,0 +1,70 @@
1
+ module NextSgad
2
+ class Attendance < ApplicationRecord
3
+ belongs_to :position, optional: true
4
+ belongs_to :assessment, optional: true
5
+ belongs_to :employee
6
+ belongs_to :department, optional: true
7
+ has_and_belongs_to_many :justifications, association_foreign_key: :next_sgad_justification_id, foreign_key: :next_sgad_attendance_id
8
+ enum status: {four_hours_late: -4, three_hours_late: -3, two_hours_late: -2, one_hour_late: -1, presence: 0, absence: 1, vacation: 2, authorized_leave: 3}
9
+ enum justification_status: {unjustified: -1, pending: 0, accepted: 1, denied: 2}
10
+ validates :status, :date ,:employee_id, presence: true
11
+ validate :assessment_date
12
+ before_create :check_employee_data
13
+
14
+ # get all attendances with state absence or late
15
+ def self.all_absence
16
+ where(status: [-4,-3,-2,-1,1])
17
+ end
18
+
19
+ # get attendances with justification
20
+ def self.with_justification
21
+ where(justification_status: [0,1,2])
22
+ end
23
+
24
+ def self.without_justification
25
+ where(status: [-4,-3,-2,-1,1]).where(justification_status: -1)
26
+ end
27
+
28
+ # true if an attendace has justification
29
+ def has_justification?
30
+ pending? || accepted? || denied?
31
+ end
32
+
33
+ def justification
34
+ justifications.last
35
+ end
36
+
37
+ private
38
+ def assessment_date
39
+
40
+ if date.blank?
41
+ errors.add(:date, 'Escolha uma data')
42
+ end
43
+
44
+ if status.blank?
45
+ errors.add(:status, 'Escolha o estado da presença')
46
+ end
47
+
48
+ return unless date.present?
49
+
50
+ if NextSgad::Attendance.where.not(id: self.id).where(employee_id: self.employee_id).where("extract(day from date) = '#{self.date.day}'").where("extract(month from date) = '#{self.date.month}'").where("extract(year from date) = '#{self.date.year}'").present?
51
+ errors.add(:date, 'Já tem foi registado para este dia')
52
+ end
53
+
54
+ if NextSgad::Assessment.find_by(year: date.year).nil?
55
+ errors.add(:date, "Não tem Avaliação para o ano de #{self.date.year}")
56
+ end
57
+
58
+ if new_record? && date.to_date > DateTime.now.to_date
59
+ errors.add(:date, "Não pode marcar preenças adiantadas")
60
+ end
61
+ # TODO See translation from plugins
62
+ end
63
+
64
+ def check_employee_data
65
+ return unless employee_id.present?
66
+ self.position_id = employee.efective_position&.id
67
+ self.department_id = position&.department&.id
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,4 @@
1
+ module NextSgad
2
+ class Configuration < ApplicationRecord
3
+ end
4
+ end
@@ -0,0 +1,20 @@
1
+ module NextSgad
2
+ class Department < ApplicationRecord
3
+ belongs_to :department, optional: true
4
+ has_many :departments
5
+ has_many :attendances
6
+ has_many :justifications
7
+
8
+ INITIAL_LETTER = "D"
9
+ validates_presence_of :name
10
+ validates_uniqueness_of :name
11
+ validate :parent_department
12
+ before_save :create_number, on: :create
13
+
14
+ def parent_department
15
+ if department_id.present? && NextSgad::Department.find_by(id: department_id).nil?
16
+ errors.add(:department_id, :no_department_found_with_this_number.ts)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ module NextSgad
2
+ class Employee < ApplicationRecord
3
+ # belongs_to :position
4
+ has_many :employee_goals, dependent: :destroy
5
+ has_and_belongs_to_many :positions, association_foreign_key: :next_sgad_position_id, foreign_key: :next_sgad_employee_id
6
+ has_one :efective_position, class_name: NextSgad::Position.name, foreign_key: :efective_id
7
+
8
+ def full_name
9
+ "#{first_name} #{middle_name} #{last_name}"
10
+ end
11
+
12
+ def first_and_last_name
13
+ "#{first_name} #{last_name}"
14
+ end
15
+
16
+ def full_abbr_name
17
+ "#{first_name} #{middle_name.to_s.split(' ').map{|name| "#{name.first.upcase}." if name.present?}.compact.join(' ')} #{last_name}"
18
+ end
19
+
20
+ def name_and_number
21
+ "#{number} - #{first_name} #{last_name}"
22
+ end
23
+
24
+ INITIAL_LETTER = "E"
25
+ before_save :create_number, on: :create
26
+ validates_presence_of :first_name, :last_name
27
+ end
28
+ end
@@ -0,0 +1,36 @@
1
+ module NextSgad
2
+ class EmployeeGoal < ApplicationRecord
3
+ belongs_to :goal
4
+ belongs_to :employee
5
+ belongs_to :assessment
6
+ belongs_to :position
7
+ has_many :results
8
+
9
+ enum status: NextSgad::Assessment.statuses
10
+ enum goal_type: NextSgad::Goal.goal_types
11
+ enum unit: NextSgad::Goal.units
12
+ enum nature: NextSgad::Goal.natures
13
+
14
+ validates :goal_id, uniqueness: {scope: [:employee_id]}
15
+ validates :self_assessment, :supervisor_assessment, :final_assessment, numericality: {greater_than_or_equal_to: 0, less_than_or_equal_to: 5}
16
+
17
+ before_save :calcular_self_assessment
18
+
19
+ def calcular_self_assessment
20
+ return unless self.numeric?
21
+ v = (amount.to_f/target.to_f)*5
22
+ value_amount = v >= 5 ? 5 : v
23
+ self.self_assessment = value_amount
24
+ self.supervisor_assessment = value_amount
25
+ self.final_assessment = value_amount
26
+ end
27
+
28
+
29
+ def update_amount
30
+ return unless self.numeric?
31
+ update_columns(amount: results.where(state: 0).sum(&:result_value))
32
+ calcular_self_assessment
33
+ save
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,8 @@
1
+ module NextSgad
2
+ class Function < ApplicationRecord
3
+ INITIAL_LETTER = "F"
4
+ validates_presence_of :name
5
+ validates_uniqueness_of :name
6
+ before_save :create_number, on: :create
7
+ end
8
+ end
@@ -0,0 +1,37 @@
1
+ module NextSgad
2
+ class Goal < ApplicationRecord
3
+ belongs_to :assessment
4
+ has_many :employee_goals, dependent: :destroy
5
+ has_and_belongs_to_many :positions, association_foreign_key: :next_sgad_position_id, foreign_key: :next_sgad_goal_id
6
+
7
+ enum goal_type: {skill: 0, objective: 1}
8
+ enum status: NextSgad::Assessment.statuses
9
+ enum unit: {contracts: 0, currency: 1, clients: 2}
10
+ enum nature: {numeric: 0, objective_base: 1}
11
+
12
+ validates_presence_of :name, :assessment_id, :status, :nature, :goal_type
13
+ validates :target, numericality: {greater_than: 0, message: 'Deve ser Maior do que 0'}, if:->(goal){goal.numeric?}
14
+ #validates :name, uniqueness: {scope: [:assessment_id]}
15
+ after_create :create_employee_goals
16
+
17
+ private
18
+ def create_employee_goals
19
+ positions.each do |position|
20
+ next if position.efective_id.nil?
21
+ eg = NextSgad::EmployeeGoal.new
22
+ eg.status = status
23
+ eg.goal_type = goal_type
24
+ eg.name = name
25
+ eg.unit = unit
26
+ eg.nature = nature
27
+ eg.target = target
28
+ eg.assessment_id = assessment_id
29
+ eg.goal_id = id
30
+ eg.employee_id = position.efective_id
31
+ eg.position_id = position.id
32
+ eg.save
33
+ end
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,47 @@
1
+ module NextSgad
2
+ class Justification < ApplicationRecord
3
+ # belongs_to :position
4
+ # belongs_to :assessment
5
+ belongs_to :employee
6
+ # belongs_to :department
7
+ has_and_belongs_to_many :attendances, association_foreign_key: :next_sgad_attendance_id, foreign_key: :next_sgad_justification_id
8
+ enum status: {pending: 0, accepted: 1, denied: 2}
9
+ attr_accessor :dates
10
+
11
+ # Aproves the justification
12
+ def aprove
13
+ # 1 stands for aproved therefore justified
14
+ update(status: 1)
15
+ end
16
+
17
+ # Disaproves the justification
18
+ def disaprove
19
+ # 2 stands for unjustified or disaproved
20
+ update(status: 2)
21
+ end
22
+
23
+ validates_presence_of :employee_id, :attendance_ids
24
+ validate :validate_attendances_uniqueness, on: :create
25
+ before_destroy :change_attendances_status_before_destroy
26
+ after_save :after_save_update_justifications
27
+
28
+ private
29
+ # chek if an attendance olready has a justification it return an error
30
+ def validate_attendances_uniqueness
31
+ attendances.each do |attendance|
32
+ next if attendance.justification_ids.blank?
33
+ errors.add(:attendance_ids, "a falta de #{attendance.date.month}/#{attendance.date.year} já tem justificativo.")
34
+ end
35
+ end
36
+
37
+ def change_attendances_status_before_destroy
38
+ # -1 stands for unjustified
39
+ attendances.update_all(justification_status: -1)
40
+
41
+ end
42
+
43
+ def after_save_update_justifications
44
+ attendances.where.not(justification_status: status).update_all(justification_status: status)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,36 @@
1
+ module NextSgad
2
+ class Position < ApplicationRecord
3
+ belongs_to :department, optional: true
4
+ belongs_to :position, optional: true
5
+ belongs_to :function
6
+ belongs_to :efective, optional: true, class_name: NextSgad::Employee.name
7
+ has_many :positions
8
+ has_many :attendances
9
+ # has_many :goals
10
+ has_many :employee_goals
11
+ has_and_belongs_to_many :goals, association_foreign_key: :next_sgad_goal_id, foreign_key: :next_sgad_position_id
12
+ has_and_belongs_to_many :employees, association_foreign_key: :next_sgad_employee_id, foreign_key: :next_sgad_position_id
13
+
14
+ def self.ocupied
15
+ self.where.not(efective_id: nil)
16
+ end
17
+
18
+ def name_and_number
19
+ "#{number} - #{name}"
20
+ end
21
+
22
+ INITIAL_LETTER = "P"
23
+
24
+ # validates :department_id, presence: false
25
+ validates_uniqueness_of :efective_id
26
+ before_save :create_number, on: :create
27
+ before_save :saves_employees
28
+
29
+ private
30
+ def saves_employees
31
+ self.employee_ids << efective_id
32
+ self.employee_ids = self.employee_ids.compact.uniq
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ module NextSgad
2
+ class Result < ApplicationRecord
3
+ belongs_to :employee_goal
4
+ belongs_to :employee
5
+ belongs_to :assessment
6
+ belongs_to :goal
7
+
8
+ enum state: {result_valid: 0, result_invalid: 1}
9
+ enum result_nature: {numeric: 0, objective_base: 1}
10
+
11
+
12
+ # enum result_type: NextSgad::Goal.goal_types
13
+
14
+ def increase_amount
15
+ employee_goal = self.employee_goal
16
+ employee_goal.amount = employee_goal.amount + self.result_value
17
+ employee_goal.save
18
+ end
19
+
20
+ def change_status
21
+ self.state = self.result_valid? ? 1 : 0
22
+ self.save
23
+ end
24
+
25
+
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ module NextSgad
2
+ require 'singleton'
3
+ class Setting < ApplicationRecord
4
+ include Singleton
5
+ #
6
+ # This class can't be instantiated... accessing the singleton is done using the 'instance' method
7
+ # such as: NextSgad::Setting.instance
8
+ #
9
+ # in the same matter the 'add' method is done by calling it on the instance
10
+ # such as: NextSgad::Setting.instance.add "is_active", true
11
+ #
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Next sgad</title>
5
+ <%= stylesheet_link_tag "next_sgad/application", media: "all" %>
6
+ <%= javascript_include_tag "next_sgad/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,27 @@
1
+ <%= form_with(model: activity, local: true) do |form| %>
2
+ <% if activity.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(activity.errors.count, "error") %> prohibited this activity from being saved:</h2>
5
+
6
+ <ul>
7
+ <% activity.errors.full_messages.each do |message| %>
8
+ <li><%= message %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= form.label :created_by %>
16
+ <%= form.text_field :created_by, id: :activity_created_by %>
17
+ </div>
18
+
19
+ <div class="field">
20
+ <%= form.label :description %>
21
+ <%= form.text_field :description, id: :activity_description %>
22
+ </div>
23
+
24
+ <div class="actions">
25
+ <%= form.submit %>
26
+ </div>
27
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing Activity</h1>
2
+
3
+ <%= render 'form', activity: @activity %>
4
+
5
+ <%= link_to 'Show', @activity %> |
6
+ <%= link_to 'Back', activities_path %>
@@ -0,0 +1,29 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <h1>Activities</h1>
4
+
5
+ <table>
6
+ <thead>
7
+ <tr>
8
+ <th>Created by</th>
9
+ <th>Description</th>
10
+ <th colspan="3"></th>
11
+ </tr>
12
+ </thead>
13
+
14
+ <tbody>
15
+ <% @activities.each do |activity| %>
16
+ <tr>
17
+ <td><%= activity.created_by %></td>
18
+ <td><%= activity.description %></td>
19
+ <td><%= link_to 'Show', activity %></td>
20
+ <td><%= link_to 'Edit', edit_activity_path(activity) %></td>
21
+ <td><%= link_to 'Destroy', activity, method: :delete, data: { confirm: 'Are you sure?' } %></td>
22
+ </tr>
23
+ <% end %>
24
+ </tbody>
25
+ </table>
26
+
27
+ <br>
28
+
29
+ <%= link_to 'New Activity', new_activity_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New Activity</h1>
2
+
3
+ <%= render 'form', activity: @activity %>
4
+
5
+ <%= link_to 'Back', activities_path %>
@@ -0,0 +1,14 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <p>
4
+ <strong>Created by:</strong>
5
+ <%= @activity.created_by %>
6
+ </p>
7
+
8
+ <p>
9
+ <strong>Description:</strong>
10
+ <%= @activity.description %>
11
+ </p>
12
+
13
+ <%= link_to 'Edit', edit_activity_path(@activity) %> |
14
+ <%= link_to 'Back', activities_path %>
@@ -0,0 +1,27 @@
1
+ <%= form_with(model: assessment, local: true) do |form| %>
2
+ <% if assessment.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(assessment.errors.count, "error") %> prohibited this assessment from being saved:</h2>
5
+
6
+ <ul>
7
+ <% assessment.errors.full_messages.each do |message| %>
8
+ <li><%= message %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= form.label :year %>
16
+ <%= form.text_field :year, id: :assessment_year %>
17
+ </div>
18
+
19
+ <div class="field">
20
+ <%= form.label :status %>
21
+ <%= form.number_field :status, id: :assessment_status %>
22
+ </div>
23
+
24
+ <div class="actions">
25
+ <%= form.submit %>
26
+ </div>
27
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing Assessment</h1>
2
+
3
+ <%= render 'form', assessment: @assessment %>
4
+
5
+ <%= link_to 'Show', @assessment %> |
6
+ <%= link_to 'Back', assessments_path %>
@@ -0,0 +1,29 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <h1>Assessments</h1>
4
+
5
+ <table>
6
+ <thead>
7
+ <tr>
8
+ <th>Year</th>
9
+ <th>State</th>
10
+ <th colspan="3"></th>
11
+ </tr>
12
+ </thead>
13
+
14
+ <tbody>
15
+ <% @assessments.each do |assessment| %>
16
+ <tr>
17
+ <td><%= assessment.year %></td>
18
+ <td><%= assessment.status %></td>
19
+ <td><%= link_to 'Show', assessment %></td>
20
+ <td><%= link_to 'Edit', edit_assessment_path(assessment) %></td>
21
+ <td><%= link_to 'Destroy', assessment, method: :delete, data: { confirm: 'Are you sure?' } %></td>
22
+ </tr>
23
+ <% end %>
24
+ </tbody>
25
+ </table>
26
+
27
+ <br>
28
+
29
+ <%= link_to 'New Assessment', new_assessment_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New Assessment</h1>
2
+
3
+ <%= render 'form', assessment: @assessment %>
4
+
5
+ <%= link_to 'Back', assessments_path %>
@@ -0,0 +1,14 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <p>
4
+ <strong>Year:</strong>
5
+ <%= @assessment.year %>
6
+ </p>
7
+
8
+ <p>
9
+ <strong>State:</strong>
10
+ <%= @assessment.status %>
11
+ </p>
12
+
13
+ <%= link_to 'Edit', edit_assessment_path(@assessment) %> |
14
+ <%= link_to 'Back', assessments_path %>
@@ -0,0 +1,37 @@
1
+ <%= form_with(model: attendance, local: true) do |form| %>
2
+ <% if attendance.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(attendance.errors.count, "error") %> prohibited this attendance from being saved:</h2>
5
+
6
+ <ul>
7
+ <% attendance.errors.full_messages.each do |message| %>
8
+ <li><%= message %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= form.label :date %>
16
+ <%= form.datetime_select :date, id: :attendance_date %>
17
+ </div>
18
+
19
+ <div class="field">
20
+ <%= form.label :status %>
21
+ <%= form.number_field :status, id: :attendance_status %>
22
+ </div>
23
+
24
+ <div class="field">
25
+ <%= form.label :employee_note %>
26
+ <%= form.text_area :employee_note, id: :attendance_employee_note %>
27
+ </div>
28
+
29
+ <div class="field">
30
+ <%= form.label :supervisor_note %>
31
+ <%= form.text_area :supervisor_note, id: :attendance_supervisor_note %>
32
+ </div>
33
+
34
+ <div class="actions">
35
+ <%= form.submit %>
36
+ </div>
37
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing Attendance</h1>
2
+
3
+ <%= render 'form', attendance: @attendance %>
4
+
5
+ <%= link_to 'Show', @attendance %> |
6
+ <%= link_to 'Back', attendances_path %>
@@ -0,0 +1,33 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <h1>Attendances</h1>
4
+
5
+ <table>
6
+ <thead>
7
+ <tr>
8
+ <th>Date</th>
9
+ <th>Status</th>
10
+ <th>Employee note</th>
11
+ <th>Supervisor note</th>
12
+ <th colspan="3"></th>
13
+ </tr>
14
+ </thead>
15
+
16
+ <tbody>
17
+ <% @attendances.each do |attendance| %>
18
+ <tr>
19
+ <td><%= attendance.date %></td>
20
+ <td><%= attendance.status %></td>
21
+ <td><%= attendance.employee_note %></td>
22
+ <td><%= attendance.supervisor_note %></td>
23
+ <td><%= link_to 'Show', attendance %></td>
24
+ <td><%= link_to 'Edit', edit_attendance_path(attendance) %></td>
25
+ <td><%= link_to 'Destroy', attendance, method: :delete, data: { confirm: 'Are you sure?' } %></td>
26
+ </tr>
27
+ <% end %>
28
+ </tbody>
29
+ </table>
30
+
31
+ <br>
32
+
33
+ <%= link_to 'New Attendance', new_attendance_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New Attendance</h1>
2
+
3
+ <%= render 'form', attendance: @attendance %>
4
+
5
+ <%= link_to 'Back', attendances_path %>
@@ -0,0 +1,24 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <p>
4
+ <strong>Date:</strong>
5
+ <%= @attendance.date %>
6
+ </p>
7
+
8
+ <p>
9
+ <strong>Status:</strong>
10
+ <%= @attendance.status %>
11
+ </p>
12
+
13
+ <p>
14
+ <strong>Employee note:</strong>
15
+ <%= @attendance.employee_note %>
16
+ </p>
17
+
18
+ <p>
19
+ <strong>Supervisor note:</strong>
20
+ <%= @attendance.supervisor_note %>
21
+ </p>
22
+
23
+ <%= link_to 'Edit', edit_attendance_path(@attendance) %> |
24
+ <%= link_to 'Back', attendances_path %>