From 2207140dfc167a1a0cf8dafcc9abe852745f3852 Mon Sep 17 00:00:00 2001 From: gustavomendess Date: Mon, 8 Jan 2024 23:13:27 -0300 Subject: [PATCH 1/2] =?UTF-8?q?Cria=20possibilidade=20de=20criar=20avalia?= =?UTF-8?q?=C3=A7=C3=B5es=20conceituais=20em=20lote?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/javascripts/beta_function.js | 5 + .../views/conceptual_exams_in_batchs/new.js | 38 ++ .../conceptual_exams_in_batchs_controller.rb | 358 ++++++++++++++++++ app/enumerations/features.rb | 1 - app/helpers/conceptual_exam_helper.rb | 13 + .../conceptual_exams_in_batchs/base.rb | 36 ++ .../create_or_update_multiple.rb | 74 ++++ .../destroy_multiple.rb | 35 ++ app/services/features_access_levels.rb | 1 + .../_base_errors.html.erb | 11 + .../_conceptual_exam_value_fields.html.erb | 30 ++ .../conceptual_exams_in_batchs/_form.html.erb | 39 ++ .../_resources.html.erb | 43 +++ .../conceptual_exams_in_batchs/edit.html.erb | 3 + .../edit_multiple.html.erb | 67 ++++ .../conceptual_exams_in_batchs/index.html.erb | 53 +++ .../conceptual_exams_in_batchs/index.js.erb | 3 + .../conceptual_exams_in_batchs/new.html.erb | 8 + .../conceptual_exams_in_batchs/show.html.erb | 78 ++++ config/locales/navigation.yml | 1 + config/locales/rails.yml | 1 + config/locales/routes.yml | 1 + .../views/conceptual_exams_in_batchs.yml | 21 + config/navigation.yml | 4 + config/routes.rb | 8 + 25 files changed, 931 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/beta_function.js create mode 100644 app/assets/javascripts/views/conceptual_exams_in_batchs/new.js create mode 100644 app/controllers/conceptual_exams_in_batchs_controller.rb create mode 100644 app/services/conceptual_exams_in_batchs/base.rb create mode 100644 app/services/conceptual_exams_in_batchs/create_or_update_multiple.rb create mode 100644 app/services/conceptual_exams_in_batchs/destroy_multiple.rb create mode 100644 app/views/conceptual_exams_in_batchs/_base_errors.html.erb create mode 100644 app/views/conceptual_exams_in_batchs/_conceptual_exam_value_fields.html.erb create mode 100644 app/views/conceptual_exams_in_batchs/_form.html.erb create mode 100644 app/views/conceptual_exams_in_batchs/_resources.html.erb create mode 100644 app/views/conceptual_exams_in_batchs/edit.html.erb create mode 100644 app/views/conceptual_exams_in_batchs/edit_multiple.html.erb create mode 100644 app/views/conceptual_exams_in_batchs/index.html.erb create mode 100644 app/views/conceptual_exams_in_batchs/index.js.erb create mode 100644 app/views/conceptual_exams_in_batchs/new.html.erb create mode 100644 app/views/conceptual_exams_in_batchs/show.html.erb create mode 100644 config/locales/views/conceptual_exams_in_batchs.yml diff --git a/app/assets/javascripts/beta_function.js b/app/assets/javascripts/beta_function.js new file mode 100644 index 000000000..56a4dad42 --- /dev/null +++ b/app/assets/javascripts/beta_function.js @@ -0,0 +1,5 @@ +$(document).ready( function() { + let beta_title = 'Este recurso ainda está em processo de desenvolvimento e pode apresentar problemas' + let img_src = $('#image-beta').attr('src'); + $(".fa-file-text-o").closest('h2').after(``); +}) diff --git a/app/assets/javascripts/views/conceptual_exams_in_batchs/new.js b/app/assets/javascripts/views/conceptual_exams_in_batchs/new.js new file mode 100644 index 000000000..5b8b4b0cb --- /dev/null +++ b/app/assets/javascripts/views/conceptual_exams_in_batchs/new.js @@ -0,0 +1,38 @@ +$(function() { + 'use strict'; + const flashMessages = new FlashMessages(); + + $('#conceptual_exam_classroom_id').on('change', function () { + flashMessages.pop(''); + $('#conceptual_exam_step_id').select2('val', ''); + + populateSteps(); + }); + + function populateSteps() { + let classroom_id = $('#conceptual_exam_classroom_id').select2('val'); + + if (!_.isEmpty(classroom_id)) { + $.ajax({ + url: Routes.get_steps_conceptual_exams_in_batchs_pt_br_path({ + classroom_id: classroom_id, + format: 'json' + }), + success: handleFetchStepsSuccess, + error: handleFetchStepsError + }); + } + } + + function handleFetchStepsSuccess(data) { + let steps = _.map(data.conceptual_exams_in_batchs, function(step) { + return { id: step.table.id, name: step.table.name, text: step.table.text }; + }); + + $('#conceptual_exam_step_id').select2({ data: steps }) + } + + function handleFetchStepsError() { + flashMessages.error('Ocorreu um erro ao buscar as etapas da turma.'); + } +}); diff --git a/app/controllers/conceptual_exams_in_batchs_controller.rb b/app/controllers/conceptual_exams_in_batchs_controller.rb new file mode 100644 index 000000000..5250603d3 --- /dev/null +++ b/app/controllers/conceptual_exams_in_batchs_controller.rb @@ -0,0 +1,358 @@ +class ConceptualExamsInBatchsController < ApplicationController + has_scope :page, default: 1 + has_scope :per, default: 10 + + before_action :require_current_classroom + before_action :require_current_teacher + before_action :adjusted_period + before_action :require_allow_to_modify_prev_years, only: [:create, :update, :destroy_multiple] + before_action :require_specific_teacher + before_action :set_classroom_and_step, only: [:create, :create_or_update_multiple] + + def index + step_id = (params[:filter] || []).delete(:by_step) + status = (params[:filter] || []).delete(:by_status) + + @conceptual_exams = ConceptualExam.joins(:classroom) + .by_unity(current_unity) + .by_classroom(current_user_classroom) + .by_teacher(current_teacher_id) + + @status = conceptual_exams_status(@conceptual_exams) + + @conceptual_exams = apply_scopes(@conceptual_exams) + .group('conceptual_exams.classroom_id, conceptual_exams.step_number') + .select('conceptual_exams.classroom_id, conceptual_exams.step_number, count(*)') + + if step_id.present? + @conceptual_exams = @conceptual_exams.by_step_id(current_user_classroom, step_id) + params[:filter][:by_step] = step_id + end + + if status.present? + @conceptual_exams = @conceptual_exams.by_status(current_user_classroom, current_teacher_id, status) + params[:filter][:by_status] = status + end + + authorize @conceptual_exams + end + + def new + discipline_score_types = (teacher_differentiated_discipline_score_types + teacher_discipline_score_types).uniq + not_concept_score = discipline_score_types.none? { |discipline_score_type| + discipline_score_type == ScoreTypes::CONCEPT + } + + if not_concept_score + redirect_to( + conceptual_exams_path, + alert: I18n.t('conceptual_exams.new.current_discipline_does_not_have_conceptual_exam') + ) + end + + return if performed? + + @conceptual_exam = ConceptualExam.new( + unity_id: current_unity.id, + classroom_id: current_user_classroom.id, + recorded_at: Date.current + ).localized + + authorize @conceptual_exam + end + + def create + date_on_step = @steps_fetcher.step_belongs_to_date?(@step.id, resource_params[:recorded_at]) + is_school_day = @step.try(:school_calendar) + .school_day?( + resource_params[:recorded_at].to_date, + nil, + resource_params[:classroom_id], + resource_params[:discipline_id] + ) + + unless date_on_step && is_school_day + flash[:error] = I18n.t('errors.messages.not_school_term_day') + + return redirect_to new_conceptual_exams_in_batch_path + end + + @recorded_at = resource_params[:recorded_at] + @conceptual_exams = [] + errors = [] + + student_enrollments(@step.start_at, @step.end_at, @classroom).each do |student_enrollment| + @conceptual_exams << base_service.find_or_initialize_conceptual_exam( + student_enrollment.student_id, + resource_params[:recorded_at], + @classroom, + current_teacher_id, + current_user, + @step + ) + end + + @conceptual_exams.compact! + mark_exempted_disciplines + + @conceptual_exam_values = @conceptual_exams.map { |conceptual_exam| + conceptual_exam.assign_attributes(resource_params) unless conceptual_exam.persisted? + + conceptual_exam_value = conceptual_exam.conceptual_exam_values + .find_or_initialize_by(discipline_id: current_user_discipline.id) + + if !conceptual_exam.persisted? && conceptual_exam_value.invalid? + errors << conceptual_exam_value.errors + break + end + + conceptual_exam_value + } + + if errors.present? || @conceptual_exams.empty? + flash[:error] = t('conceptual_exams_in_batchs.messages.create_error') + + redirect_to new_conceptual_exams_in_batch_path + else + render :edit_multiple + end + end + + def create_or_update_multiple + conceptual_exams_creator = ConceptualExamsInBatchs::CreateOrUpdateMultiple.new( + resource_params, + current_teacher, + current_user, + @step + ) + + if conceptual_exams_creator.call! + flash[:success] = t('conceptual_exams_in_batchs.messages.create_success') + + redirect_to conceptual_exams_in_batchs_path + else + flash[:alert] = t('conceptual_exams_in_batchs.messages.create_error') + + redirect_to new_conceptual_exams_in_batch_path + end + end + + def destroy_multiple + conceptual_exams_destroyer = ConceptualExamsInBatchs::DestroyMultiple.new(params) + + if conceptual_exams_destroyer.call! + flash[:success] = t('conceptual_exams_in_batchs.messages.destroy_success') + else + flash[:error] = t('conceptual_exams_in_batchs.messages.destroy_error') + end + + redirect_to conceptual_exams_in_batchs_path + end + + def get_steps + return if params[:classroom_id].blank? + + render json: steps_to_select2(params[:classroom_id]) + end + + private + + def steps_to_select2(classroom_id) + steps_to_select2 = [] + classroom = Classroom.find(classroom_id) + steps = steps_fetcher(classroom).steps + + steps.each do |step| + steps_to_select2 << OpenStruct.new( + id: step.id, + name: (step.try(:name) || step.to_s), + text: (step.try(:text) || step.to_s) + ) + end + + steps_to_select2 + end + + def resource_params + params.require(:conceptual_exam).permit( + :unity_id, + :classroom_id, + :recorded_at, + :student_id, + :step_id, + conceptual_exam_values_attributes: [ + :student_id, + :id, + :discipline_id, + :value, + :exempted_discipline, + :_destroy + ] + ) + end + + def mark_exempted_disciplines + first_conceptual_exam = @conceptual_exams.first + + return if first_conceptual_exam.recorded_at.blank? || first_conceptual_exam.step.blank? + + @student_enrollments ||= student_enrollments(first_conceptual_exam.step.start_at, first_conceptual_exam.step.end_at, @classroom) + + @conceptual_exams.each do |conceptual_exam| + next unless (current_student_enrollment = @student_enrollments.find { |item| item[:student_id] == conceptual_exam.student_id }) + + exempted_disciplines = current_student_enrollment.exempted_disciplines + + conceptual_exam.conceptual_exam_values.each do |conceptual_exam_value| + conceptual_exam_value.exempted_discipline = student_exempted_from_discipline?(conceptual_exam_value.discipline_id, exempted_disciplines) + end + end + end + + def steps_fetcher(classroom) + @steps_fetcher ||= StepsFetcher.new(classroom) + end + + def student_enrollments(start_at, end_at, classroom) + step_student_enrollments = "#{start_at}_#{end_at}_student_enrollments_#{classroom}" + + Rails.cache.fetch(step_student_enrollments, expires_in: 10.minutes) do + StudentEnrollmentsList.new( + classroom: classroom, + discipline: current_user_discipline, + start_at: start_at, + end_at: end_at, + score_type: StudentEnrollmentScoreTypeFilters::CONCEPT, + search_type: :by_date_range, + period: @period + ).student_enrollments + end + end + + def old_values + @old_values ||= {} + + @conceptual_exams.each do |conceptual_exam| + next if conceptual_exam.classroom.nil? && conceptual_exam.student.nil? && conceptual_exam.step.nil? + + @old_values[conceptual_exam.id] ||= OldStepsConceptualValuesFetcher.new( + conceptual_exam.classroom, + conceptual_exam.student, + conceptual_exam.step + ).fetch + end + + @old_values.delete_if { |_key, value| value.empty? } + end + helper_method :old_values + + def steps_current_classroom + steps_fetcher(current_user_classroom).steps + end + helper_method :steps_current_classroom + + def classrooms_by_current_profile + Classroom.by_unity_and_teacher(current_unity, current_teacher_id).by_year(current_school_year) + end + helper_method :classrooms_by_current_profile + + def student_exempted_from_discipline?(discipline_id, exempted_disciplines) + exempted_disciplines.by_discipline(discipline_id) + .by_step_number(@conceptual_exams.first.step_number) + .any? + end + + def current_teacher_period + TeacherPeriodFetcher.new( + current_teacher.id, + current_user.current_classroom_id, + current_user.current_discipline_id + ).teacher_period + end + + def adjusted_period + teacher_period = current_teacher_period + @period = teacher_period != Periods::FULL.to_i ? teacher_period : nil + end + + def conceptual_exams_status(conceptual_exams) + steps = steps_fetcher(current_user_classroom).steps + cache_key = "#{steps.size}-steps-#{current_user_classroom.id}-#{current_teacher.id}" + + Rails.cache.fetch(cache_key, expires_in: 30.minutes) do + status = {} + + steps.each do |step| + builded_conceptual_exams = [] + + student_enrollments(step.start_at, step.end_at, current_user_classroom).each do |student_enrollment| + builded_conceptual_exams << base_service.find_or_initialize_conceptual_exam( + student_enrollment.student_id, + step.end_at, + current_user_classroom, + current_teacher_id, + current_user, + step + ) + end + + conceptual_exams_by_step = conceptual_exams.where(step_number: step.step_number) + + next if conceptual_exams_by_step.empty? + + conceptual_exams_by_step.each do |conceptual_exam| + conceptual_exam_value = conceptual_exam.conceptual_exam_values + .find_or_initialize_by(discipline_id: current_user_discipline.id) + + status[step.step_number] ||= [] + + status[step.step_number] << if conceptual_exam.persisted? && conceptual_exam_value.value.present? + true + else + false + end + end + + total_persisted_exams = conceptual_exams_by_step.size + total_builded_exams = builded_conceptual_exams.compact.size + + if (total_builded_exams > total_persisted_exams && total_persisted_exams != total_builded_exams) || + status[step.step_number].include?(false) + status[step.step_number] = ConceptualExamStatus::INCOMPLETE + else + status[step.step_number] = ConceptualExamStatus::COMPLETE + end + end + + status + end + end + + def require_specific_teacher + return unless current_teacher_discipline_classroom.allow_absence_by_discipline.zero? + + flash[:alert] = t('errors.general.require_specific_teacher') + + redirect_to root_path + end + + def current_teacher_discipline_classroom + cache_key = "#{current_user_classroom.id}_#{current_teacher.id}" + + Rails.cache.fetch(cache_key, expires_in: 30.minutes) do + TeacherDisciplineClassroom.by_classroom(current_user_classroom) + .by_teacher_id(current_teacher.id) + .first + end + end + + def base_service + @base_service ||= ConceptualExamsInBatchs::Base.new + end + + def set_classroom_and_step + @classroom = Classroom.find(resource_params[:classroom_id]) + @steps_fetcher = steps_fetcher(@classroom) + @step = @steps_fetcher.step_by_id(resource_params[:step_id]) + end +end diff --git a/app/enumerations/features.rb b/app/enumerations/features.rb index 914c906d9..039db1879 100644 --- a/app/enumerations/features.rb +++ b/app/enumerations/features.rb @@ -52,6 +52,5 @@ class Features < EnumerateIt::Base :daily_frequencies_in_batchs, :avaliation_recovery_lowest_notes - sort_by :translation end diff --git a/app/helpers/conceptual_exam_helper.rb b/app/helpers/conceptual_exam_helper.rb index c24c7c8d8..9b6033549 100644 --- a/app/helpers/conceptual_exam_helper.rb +++ b/app/helpers/conceptual_exam_helper.rb @@ -32,4 +32,17 @@ def ordered_conceptual_exam_values ] } end + + def any_conceptual_exam_with_exempted_student? + @conceptual_exams.any? do |conceptual_exam| + conceptual_exam.conceptual_exam_values.any? { |value| value.exempted_discipline.to_s == 'true' } + end + end + + def first_conceptual_exam_by_params(conceptual_exam, discipline_id) + ConceptualExam.where( + step_number: conceptual_exam.step_number, + classroom_id: conceptual_exam.classroom_id + ).by_discipline(discipline_id).first + end end diff --git a/app/services/conceptual_exams_in_batchs/base.rb b/app/services/conceptual_exams_in_batchs/base.rb new file mode 100644 index 000000000..f023bebfd --- /dev/null +++ b/app/services/conceptual_exams_in_batchs/base.rb @@ -0,0 +1,36 @@ +module ConceptualExamsInBatchs + class Base + def find_or_initialize_conceptual_exam(student_id, recorded_at, classroom, teacher_id, user, step) + conceptual_exam = find_conceptual_exam(student_id, step.id, classroom.id) + + return nil unless StudentEnrollment.by_student(student_id) + .by_classroom(classroom.id) + .by_date(recorded_at) + .exists? + + if conceptual_exam.blank? + conceptual_exam = ConceptualExam.new( + unity_id: classroom.unity_id, + classroom_id: classroom.id, + student_id: student_id, + recorded_at: recorded_at.to_date, + step_id: step.id.to_i, + step_number: step.step_number, + teacher_id: teacher_id, + current_user: user + ) + end + + conceptual_exam + end + + def find_conceptual_exam(student_id, step_id, classroom_id) + classroom = Classroom.find(classroom_id) + + ConceptualExam.by_classroom(classroom_id) + .by_step_id(classroom, step_id) + .by_student_id(student_id) + .first + end + end +end diff --git a/app/services/conceptual_exams_in_batchs/create_or_update_multiple.rb b/app/services/conceptual_exams_in_batchs/create_or_update_multiple.rb new file mode 100644 index 000000000..a46e75625 --- /dev/null +++ b/app/services/conceptual_exams_in_batchs/create_or_update_multiple.rb @@ -0,0 +1,74 @@ +module ConceptualExamsInBatchs + class CreateOrUpdateMultiple < Base + attr_reader :params, :teacher, :user, :step + + def initialize(params, teacher, user, step) + @params = params + @teacher = teacher + @user = user + @step = step + end + + def call! + any_changed = false + @classroom = Classroom.find(base_params[:classroom_id]) + + begin + ActiveRecord::Base.transaction do + params[:conceptual_exam_values_attributes].each do |_key, conceptual_exam_attributes| + conceptual_exam = find_or_initialize_conceptual_exam( + conceptual_exam_attributes[:student_id], + params[:recorded_at], + @classroom, + teacher.id, + user, + step + ) + + next if conceptual_exam.nil? + + conceptual_exam_value = conceptual_exam.conceptual_exam_values + .find_or_initialize_by( + discipline_id: conceptual_exam_attributes[:discipline_id] + ) + + conceptual_exam_value.assign_attributes(conceptual_exam_attributes.except(:student_id, :_destroy)) + + any_changed = true if conceptual_exam_value.changed? + + conceptual_exam_value.save! + end + end + end + + clear_status_cache if any_changed + + true + end + + private + + def base_params + params.permit( + :unity_id, + :classroom_id, + :recorded_at, + :student_id, + :step_id, + conceptual_exam_values_attributes: [ + :id, + :discipline_id, + :value, + :exempted_discipline, + :_destroy + ] + ) + end + + def clear_status_cache + cache_key = "#{StepsFetcher.new(@classroom).steps.size}-steps-#{@classroom.id}-#{@teacher.id}" + + Rails.cache.delete(cache_key) + end + end +end diff --git a/app/services/conceptual_exams_in_batchs/destroy_multiple.rb b/app/services/conceptual_exams_in_batchs/destroy_multiple.rb new file mode 100644 index 000000000..eaa302de3 --- /dev/null +++ b/app/services/conceptual_exams_in_batchs/destroy_multiple.rb @@ -0,0 +1,35 @@ +module ConceptualExamsInBatchs + class DestroyMultiple < Base + attr_reader :params + + def initialize(params) + @params = params + end + + def call! + conceptual_exams = ConceptualExam.where(step_number: conceptual_exam_params[:step_number], + classroom_id: conceptual_exam_params[:classroom_id]) + + return true if conceptual_exams.empty? + + begin + ActiveRecord::Base.transaction do + conceptual_exams.each do |conceptual_exam| + conceptual_exam_value = conceptual_exam.conceptual_exam_values + .find_by(discipline_id: conceptual_exam_params[:discipline_id]) + + conceptual_exam_value.destroy! + end + + conceptual_exams.destroy_all + end + end + end + + private + + def conceptual_exam_params + params.require(:conceptual_exam) + end + end +end diff --git a/app/services/features_access_levels.rb b/app/services/features_access_levels.rb index 99d0ce985..2d0c1f244 100644 --- a/app/services/features_access_levels.rb +++ b/app/services/features_access_levels.rb @@ -19,6 +19,7 @@ def self.teacher_features :avaliation_recovery_diary_records, :avaliations, :conceptual_exams, + :conceptual_exams_in_batchs, :daily_frequencies, :daily_notes, :descriptive_exams, diff --git a/app/views/conceptual_exams_in_batchs/_base_errors.html.erb b/app/views/conceptual_exams_in_batchs/_base_errors.html.erb new file mode 100644 index 000000000..de8b56744 --- /dev/null +++ b/app/views/conceptual_exams_in_batchs/_base_errors.html.erb @@ -0,0 +1,11 @@ +<% if f.object.errors[:base].present? %> +
+
+ + + <%= f.object.errors[:base].first %> +
+
+<% end %> diff --git a/app/views/conceptual_exams_in_batchs/_conceptual_exam_value_fields.html.erb b/app/views/conceptual_exams_in_batchs/_conceptual_exam_value_fields.html.erb new file mode 100644 index 000000000..57f711524 --- /dev/null +++ b/app/views/conceptual_exams_in_batchs/_conceptual_exam_value_fields.html.erb @@ -0,0 +1,30 @@ +<% record_class = (f.object.new_record? ? 'dynamic' : 'existing') %> +<% record_style = (f.object.marked_for_destruction? || f.object.marked_as_invisible? ? 'display: none;' : '') %> + + + <%= student.name %> + + <%= f.hidden_field :student_id, value: student.id %> + <%= f.hidden_field :id %> + <%= f.hidden_field :discipline_id %> + <%= f.hidden_field :exempted_discipline %> + <%= f.hidden_field :_destroy %> + + <%= conceptual_exam_value_student_name(f.object) %> + + + <% if old_values.present? %> + <% old_values[f.object.conceptual_exam_id].each do |step| %> + <%= step[:values]["#{f.object.discipline_id}"] || '-' %> + <% end %> + <% end %> + + + <%= f.input :value, as: :select2, + elements: f.object.decorator.data_for_select2, + label_html: { class: 'hidden' }, + wrapper_html: { style: 'margin-bottom: 0px;' }, + readonly: (f.object.exempted_discipline.to_s == 'true') %> + + + diff --git a/app/views/conceptual_exams_in_batchs/_form.html.erb b/app/views/conceptual_exams_in_batchs/_form.html.erb new file mode 100644 index 000000000..5362df664 --- /dev/null +++ b/app/views/conceptual_exams_in_batchs/_form.html.erb @@ -0,0 +1,39 @@ +<% content_for :js do %> + <%= javascript_include_tag 'beta_function' %> +<% end %> + +<%= simple_form_for @conceptual_exam, url: conceptual_exams_in_batchs_path, method: :post, + html: { class: 'smart-form' } do |f| %> + <%= f.error_notification %> + <%= image_tag "beta.png", class: 'hidden', id: 'image-beta' %> + <%= render 'base_errors', f: f %> + +
+
+
+ <%= f.input :unity_id, as: :select2_unity, user: current_user %> +
+ +
+ <%= f.input :classroom_id, as: :select2, elements: classrooms_by_current_profile, + label: t('lessons_boards.index.classroom'), placeholder: t('lessons_boards.index.classroom'), readonly: action_name != "new" %> +
+ +
+ <%= f.input :step_id, as: :select2, elements: steps_current_classroom, required: true, + readonly: @conceptual_exam.persisted? %> +
+
+ +
+
+ <%= f.input :recorded_at %> +
+
+
+ + +<% end %> diff --git a/app/views/conceptual_exams_in_batchs/_resources.html.erb b/app/views/conceptual_exams_in_batchs/_resources.html.erb new file mode 100644 index 000000000..4f99284e6 --- /dev/null +++ b/app/views/conceptual_exams_in_batchs/_resources.html.erb @@ -0,0 +1,43 @@ + + <% if @conceptual_exams.empty? %> + + <%= t('views.index.no_record_found')%> + + <% else %> + <% @conceptual_exams.each do |conceptual_exam| %> + + <%= conceptual_exam.classroom.unity %> + <%= conceptual_exam.classroom %> + <%= conceptual_exam.step %> + + <% conceptual_exam.teacher_id = current_teacher_id %> + + <%= ConceptualExamStatus.t(@status[conceptual_exam.step_number]) %> + + + + <%= link_to t('helpers.links.show_html'), '#', style: "width: 31%;", + class: 'btn btn-info apply_tooltip disabled', title: t('conceptual_exams.form.show') %> + <% params = { + conceptual_exam: + { + classroom_id: conceptual_exam.classroom_id, + step_id: conceptual_exam.step.id, + step_number: conceptual_exam.step.step_number, + recorded_at: first_conceptual_exam_by_params(conceptual_exam, current_user_discipline.id).recorded_at, + discipline_id: current_user_discipline.id + } + } + %> + <% if current_user.can_change?(:conceptual_exams) %> + <%= link_to t('helpers.links.edit_html'), conceptual_exams_in_batchs_path(params), method: :post, style: "width: 31%;", + class: 'btn btn-success apply_tooltip', title: t('conceptual_exams.form.edit') %> + <%= link_to t('helpers.links.destroy_html'), destroy_multiple_conceptual_exams_in_batchs_path(params), style: "width: 31%;", + class: 'btn btn-danger apply_tooltip', method: 'delete', title: t('conceptual_exams.form.destroy'), + data: { confirm: t('views.index.confirm') } %> + <% end %> + + + <% end %> + <% end %> + diff --git a/app/views/conceptual_exams_in_batchs/edit.html.erb b/app/views/conceptual_exams_in_batchs/edit.html.erb new file mode 100644 index 000000000..9ba7ceb8f --- /dev/null +++ b/app/views/conceptual_exams_in_batchs/edit.html.erb @@ -0,0 +1,3 @@ +
+ <%= render 'form' %> +
diff --git a/app/views/conceptual_exams_in_batchs/edit_multiple.html.erb b/app/views/conceptual_exams_in_batchs/edit_multiple.html.erb new file mode 100644 index 000000000..40ad26b94 --- /dev/null +++ b/app/views/conceptual_exams_in_batchs/edit_multiple.html.erb @@ -0,0 +1,67 @@ +<% content_for :js do %> + <%= javascript_include_tag 'beta_function' %> +<% end %> + +<%= simple_form_for @conceptual_exams.first, url: create_or_update_multiple_conceptual_exams_in_batchs_path, method: :put, + html: { class: 'smart-form conceptual_exam' } do |f| %> + <%= image_tag "beta.png", class: 'hidden', id: 'image-beta' %> + +
+ <% first_conceptual_exam = @conceptual_exams.first %> +
+
+ <%= f.input :unity_id, as: :select2_unity, user: current_user %> +
+ +
+ <%= f.input :classroom_id, as: :select2, elements: [first_conceptual_exam.classroom], readonly: true, + input_html: { value: first_conceptual_exam.classroom_id }, + label: t('lessons_boards.index.classroom') %> +
+ +
+ <%= f.input :step_id, as: :select2_step, classroom: first_conceptual_exam.classroom, readonly: true, + input_html: { value: first_conceptual_exam.step.id } %> +
+ +
+ <%= f.input :recorded_at, input_html: { value: I18n.l(first_conceptual_exam.recorded_at || @recorded_at) }, readonly: true %> +
+
+
+ +
+ + + + + <% if old_values.present? %> + <% more_old_values_position ||= old_values.max_by { |old_value| old_value.length }[0] %> + <% old_values[more_old_values_position].each do |old_value| %> + + <% end %> + <% end %> + + + + <% @conceptual_exam_values.each do |conceptual_exam_value| %> + <%= f.simple_fields_for :conceptual_exam_values, conceptual_exam_value do |conceptual_exam_value_form| %> + <%= render 'conceptual_exam_value_fields', f: conceptual_exam_value_form, student: conceptual_exam_value.conceptual_exam.student %> + <% end %> + <% end %> + + '> + + + + +
<%= ConceptualExam.human_attribute_name :student_id %><%= ConceptualExamValue.human_attribute_name :discipline %><%= old_value[:description] %><%= ConceptualExamValue.human_attribute_name :value %>
+ + <%= t('.exempted_students_from_discipline_legend') %> + +
+
+ <%= f.submit t('.save'), class: 'btn new-save-style' %> +
+
+<% end %> diff --git a/app/views/conceptual_exams_in_batchs/index.html.erb b/app/views/conceptual_exams_in_batchs/index.html.erb new file mode 100644 index 000000000..d8af86893 --- /dev/null +++ b/app/views/conceptual_exams_in_batchs/index.html.erb @@ -0,0 +1,53 @@ +<% content_for :js do %> + <%= javascript_include_tag 'beta_function' %> +<% end %> + +
+ <%= simple_form_for :filter, { url: conceptual_exams_in_batchs_path, method: :get, + html: { class: 'filterable_search_form' } } do |f| %> + <%= image_tag "beta.png", class: 'hidden', id: 'image-beta' %> +
+ + + + + + + + + + + + + + + + + + + + <%= render 'resources' %> + + + + +
+ <%= f.input :by_step, as: :select2_step, classroom: current_user_classroom, + label: false, placeholder: t('.by_step') %> + + <%= f.input :by_status, as: :select2, elements: ConceptualExamStatus.to_select.to_json, + label: false, placeholder: t('.by_status') %> + + <%= link_to t('.new_html'), new_conceptual_exams_in_batch_path, class: 'btn btn-primary pull-right' %> +
<%= ConceptualExam.human_attribute_name :unity_id %><%= ConceptualExam.human_attribute_name :classroom %><%= ConceptualExam.human_attribute_name :step %><%= ConceptualExam.human_attribute_name :status %>
+ + +
+ <%= paginate @conceptual_exams %> +
+
+
+ <% end %> +
diff --git a/app/views/conceptual_exams_in_batchs/index.js.erb b/app/views/conceptual_exams_in_batchs/index.js.erb new file mode 100644 index 000000000..803e724c8 --- /dev/null +++ b/app/views/conceptual_exams_in_batchs/index.js.erb @@ -0,0 +1,3 @@ +$('#resources-tbody').replaceWith('<%= escape_javascript(render('resources')) %>'); +$('#paginator .pagination').html('<%= escape_javascript(paginate(@conceptual_exams, remote: true).to_s) %>'); +$('#page_entries_info').html('<%= escape_javascript(page_entries_info(@conceptual_exams).to_s) %>'); diff --git a/app/views/conceptual_exams_in_batchs/new.html.erb b/app/views/conceptual_exams_in_batchs/new.html.erb new file mode 100644 index 000000000..65e12765c --- /dev/null +++ b/app/views/conceptual_exams_in_batchs/new.html.erb @@ -0,0 +1,8 @@ +<% content_for :js do %> + <%= javascript_include_tag 'views/conceptual_exams_in_batchs/new' %> +<% end %> + +
+ <%= render 'form' %> +
+ diff --git a/app/views/conceptual_exams_in_batchs/show.html.erb b/app/views/conceptual_exams_in_batchs/show.html.erb new file mode 100644 index 000000000..a576ee392 --- /dev/null +++ b/app/views/conceptual_exams_in_batchs/show.html.erb @@ -0,0 +1,78 @@ +<%= simple_form_for @conceptual_exam, html: { class: 'smart-form' } do |f| %> + <%= f.error_notification %> + + <%= render 'base_errors', f: f %> + +
+
+
+ <%= f.input :unity_id, as: :select2_unity, user: current_user %> +
+ +
+ <%= f.association :classroom, as: :select2_classroom, user: current_user, record: f.object %> +
+ +
+ <%= f.input :step_id, as: :select2_step, classroom: current_user_classroom, + readonly: @conceptual_exam.persisted?, required: true %> +
+
+ +
+
+ <%= f.input :recorded_at, readonly: true %> +
+ +
+ <%= f.association :student, as: :select2, elements: @students, + readonly: @conceptual_exam.persisted? %> +
+
+
+ +
+ + + + <% old_values.each do |step| %> + + <% end %> + + + + + + + + <% ordered_conceptual_exam_values.each do |knowledge_area, conceptual_exam_values| %> + <% if conceptual_exam_values.reject(&:marked_for_destruction?).reject(&:marked_as_invisible?).any? %> + + + + <% end %> + + <%= f.simple_fields_for :conceptual_exam_values, conceptual_exam_values do |conceptual_exam_value_form| %> + <%= render 'conceptual_exam_value_fields', f: conceptual_exam_value_form %> + <% end %> + <% end %> + + '> + + + + + +
<%= ConceptualExamValue.human_attribute_name :discipline %><%= step[:description] %><%= ConceptualExamValue.human_attribute_name :value %>
<%= t('.no_item_found') %>
<%= knowledge_area %>
+ + <%= t('.exempted_students_from_discipline_legend') %> + +
+
+ + +<% end %> diff --git a/config/locales/navigation.yml b/config/locales/navigation.yml index a04f580a6..91f137e2a 100644 --- a/config/locales/navigation.yml +++ b/config/locales/navigation.yml @@ -47,6 +47,7 @@ pt-BR: absence_justifications: "Justificativas de falta" observation_diary_records: "Diário de observações" conceptual_exams: "Diário de avaliações conceituais" + conceptual_exams_in_batchs: "Diário de avaliações conceituais em lote" descriptive_exams: "Avaliações descritivas" reports: "Relatórios" exam_record_report: "Registro de avaliações numéricas" diff --git a/config/locales/rails.yml b/config/locales/rails.yml index 69f15f920..71a36b4fc 100644 --- a/config/locales/rails.yml +++ b/config/locales/rails.yml @@ -5,6 +5,7 @@ pt-BR: require_current_year: 'É necessário vincular um ano ao perfil atual para acessar esse cadastro' require_current_classroom: "É necessário vincular uma turma ao perfil atual para acessar esse cadastro" require_current_teacher: "É necessário vincular um professor ao usuário atual para acessar esse cadastro" + require_specific_teacher: "Este recurso foi desenvolvido apenas para professores de áreas especificas" require_current_teacher_discipline_classrooms: "É necessário ter turmas vinculadas ao professor atual para acessar esta funcionalidade" school_calendar_steps_more_than_limit: "Verificamos que o calendário letivo da escola: %{unity}, possui uma quantidade de etapas acima do permitido." calendar_step_not_found: "Não foi localizada uma etapa para a data %{date}." diff --git a/config/locales/routes.yml b/config/locales/routes.yml index ec02f076a..273e785e4 100644 --- a/config/locales/routes.yml +++ b/config/locales/routes.yml @@ -27,6 +27,7 @@ pt-BR: absence_justifications: 'justificativas-de-falta' observation_diary_records: 'diario-de-observacoes' conceptual_exams: 'diario-de-avaliacoes-conceituais' + conceptual_exams_in_batchs: 'diario-de-avaliacoes-conceituais-em-lote' descriptive_exams: 'avaliacoes-descritivas' disabled_entity: 'acesso-suspenso' reports: 'relatorios' diff --git a/config/locales/views/conceptual_exams_in_batchs.yml b/config/locales/views/conceptual_exams_in_batchs.yml new file mode 100644 index 000000000..4fa0e2a61 --- /dev/null +++ b/config/locales/views/conceptual_exams_in_batchs.yml @@ -0,0 +1,21 @@ +pt-BR: + conceptual_exams_in_batchs: + messages: + create_success: 'Avaliações conceituais foram criadas ou atualizadas com sucesso!' + create_error: 'Ocorreu um erro ao criar as avaliações conceituais!' + destroy_success: 'Avaliações conceituais foram excluídas com sucesso!' + destroy_error: 'Ocorreu um erro ao excluír as avaliações conceituais!' + index: + new_html: " Novo lançamento" + by_classroom: 'Filtrar turma' + by_student_name: 'Filtrar aluno' + by_step: 'Filtrar etapa' + by_status: 'Filtrar situação' + + edit_multiple: + save: 'Salvar' + no_item_found: 'Nenhuma disciplina' + exempted_students_from_discipline_legend: '**** Disciplina dispensada para o aluno' + show: 'Visualizar' + edit: 'Editar' + destroy: 'Excluir' diff --git a/config/navigation.yml b/config/navigation.yml index c668422c4..ec83bb866 100644 --- a/config/navigation.yml +++ b/config/navigation.yml @@ -147,6 +147,10 @@ navigation: type: "conceptual_exams" path: "conceptual_exams_path" shortcut: true + - menu: + type: "conceptual_exams_in_batchs" + path: "conceptual_exams_in_batchs_path" + shortcut: true - menu: type: "descriptive_exams" path: "new_descriptive_exam_path" diff --git a/config/routes.rb b/config/routes.rb index 45c152d71..a536d55f0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -315,6 +315,14 @@ get :fetch_score_type end end + resources :conceptual_exams_in_batchs, concerns: :history do + collection do + get :edit_multiple + get :get_steps + put :create_or_update_multiple + delete :destroy_multiple + end + end resources :old_steps_conceptual_values, except: [:only] resources :descriptive_exams, only: [:new, :create, :edit, :show, :update], concerns: :history do collection do From 4d2fd5b751eb97ed244db78be2ae67e6440f3605 Mon Sep 17 00:00:00 2001 From: gustavomendess Date: Mon, 8 Jan 2024 23:36:45 -0300 Subject: [PATCH 2/2] =?UTF-8?q?Ajusta=20relat=C3=B3rio=20para=20mostrar=20?= =?UTF-8?q?dias=20letivos=20no=20per=C3=ADodo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../attendance_record_report_controller.rb | 3 ++- app/forms/attendance_record_report_form.rb | 16 ++++++++++++++++ app/reports/attendance_record_report.rb | 12 +++++++++--- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/app/controllers/attendance_record_report_controller.rb b/app/controllers/attendance_record_report_controller.rb index 8c1e55a09..a9aab451e 100644 --- a/app/controllers/attendance_record_report_controller.rb +++ b/app/controllers/attendance_record_report_controller.rb @@ -36,7 +36,8 @@ def report @attendance_record_report_form.second_teacher_signature, @attendance_record_report_form.students_frequencies_percentage, current_user, - resource_params[:classroom_id] + resource_params[:classroom_id], + @attendance_record_report_form.school_days ) send_pdf(t('routes.attendance_record'), attendance_record_report.render) else diff --git a/app/forms/attendance_record_report_form.rb b/app/forms/attendance_record_report_form.rb index 42960a4d5..5015b8e51 100644 --- a/app/forms/attendance_record_report_form.rb +++ b/app/forms/attendance_record_report_form.rb @@ -108,6 +108,22 @@ def students_frequencies_percentage percentage_by_student end + def school_days + school_days = 0 + + days = [*start_at.to_date..end_at.to_date] + + days.each do |day| + if global_absence? + school_days += 1 if SchoolDayChecker.new(school_calendar, day, nil, classroom_id, nil).school_day? + else + school_days += 1 if SchoolDayChecker.new(school_calendar, day, nil, classroom_id, discipline_id).school_day? + end + end + + @school_days ||= school_days + end + private def days_enrollment diff --git a/app/reports/attendance_record_report.rb b/app/reports/attendance_record_report.rb index 0aa0979b9..408891d54 100644 --- a/app/reports/attendance_record_report.rb +++ b/app/reports/attendance_record_report.rb @@ -18,7 +18,8 @@ def self.build( second_teacher_signature, students_frequencies_percentage, current_user, - classroom_id + classroom_id, + school_days ) new(:landscape) .build(entity_configuration, @@ -33,7 +34,8 @@ def self.build( second_teacher_signature, students_frequencies_percentage, current_user, - classroom_id) + classroom_id, + school_days) end @@ -50,7 +52,8 @@ def build( second_teacher_signature, students_frequencies_percentage, current_user, - classroom_id + classroom_id, + school_days ) @entity_configuration = entity_configuration @teacher = set_teacher(teacher, classroom_id, current_user) @@ -67,6 +70,7 @@ def build( @exists_legend_hybrid = false @exists_legend_remote = false @students_frequency_percentage = students_frequencies_percentage + @school_days = school_days self.legend = 'Legenda: N - Não enturmado, D - Dispensado da disciplina, FJ - Falta justificada' @@ -334,6 +338,8 @@ def daily_frequencies_table columns = @show_percentage_on_attendance ? 45 : 44 students_cells_slice << [{ content: "Aulas dadas: #{daily_frequencies.count}", colspan: columns, align: :center }] + students_cells_slice << + [{ content: "Dias letivos no período: #{@school_days}", colspan: columns, align: :center }] end data.concat(students_cells_slice)