diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 8fa3ab5..2c014bb 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-03-29 19:02:54 UTC using RuboCop version 1.56.2. +# on 2024-03-29 19:48:59 UTC using RuboCop version 1.56.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -10,14 +10,19 @@ # Configuration parameters: AllowedParentClasses. Lint/MissingSuper: Exclude: - - 'app/services/time_off_creator.rb' + - 'app/services/time_off_builder.rb' -# Offense count: 8 +# Offense count: 9 # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: Max: 34 -# Offense count: 12 +# Offense count: 1 +# Configuration parameters: AllowedMethods, AllowedPatterns. +Metrics/CyclomaticComplexity: + Max: 8 + +# Offense count: 13 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: Max: 23 @@ -31,9 +36,9 @@ Style/OptionalBooleanParameter: - 'app/models/maintenance_contract_model.rb' - 'app/utils/analytics/finances/models/financial_statements_of_work.rb' -# Offense count: 8 +# Offense count: 10 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns. # URISchemes: http, https Layout/LineLength: - Max: 124 + Max: 130 diff --git a/app/controllers/time_offs_controller.rb b/app/controllers/time_offs_controller.rb index 8942cd7..89f772b 100644 --- a/app/controllers/time_offs_controller.rb +++ b/app/controllers/time_offs_controller.rb @@ -15,10 +15,10 @@ def create msg = success ? { id: time_off&.id } : 'The time of request creation failed' render json: msg, status: success ? :ok : :unprocessable_entity - rescue StandardError => e - logger.fatal "Error: TimeOffCreator: #{e.message}, Params: #{time_off_params}" - - render json: { message: e.message }, status: :internal_server_error + rescue StandardError => e + logger.fatal "Error: TimeOffCreator: #{e.message}, Params: #{time_off_params}" + + render json: { message: e.message }, status: :internal_server_error end def destroy diff --git a/app/models/time_entry.rb b/app/models/time_entry.rb index d6da173..16ba22c 100644 --- a/app/models/time_entry.rb +++ b/app/models/time_entry.rb @@ -31,6 +31,20 @@ class TimeEntry < ApplicationRecord validates :date, presence: true validates :date, uniqueness: { scope: %i[user_id statement_of_work_id] } + validate :assignment_must_exist_in_period scope :active_in_period, ->(start_date, end_date) { where('date <= ? AND date >= ?', end_date, start_date) } + + def assignment_must_exist_in_period + assignment_exists = Assignment.joins(:requirement) + .where(user_id:) + .where(requirements: { statement_of_work_id: }) + .exists?(['? >= assignments.start_date AND ? <= assignments.end_date', date, date]) + + # If not, add an error. + return if assignment_exists + + errors.add(:base, + 'There is no valid assignment for the user and statement of work in this period.') + end end diff --git a/spec/models/time_entry_spec.rb b/spec/models/time_entry_spec.rb index 7abb2ed..fa90c0b 100644 --- a/spec/models/time_entry_spec.rb +++ b/spec/models/time_entry_spec.rb @@ -35,4 +35,25 @@ it { should belong_to(:statement_of_work) } it { should belong_to(:user) } end + + context 'assignments' do + it 'is valid if there is an assignment active for the sow' do + start_date = Time.zone.today - 1.day + end_date = Time.zone.today + 1.day + + assignment = create(:assignment, start_date:, end_date:) + sow_id = assignment.requirement.statement_of_work.id + time_entry = TimeEntry.new(date: Time.zone.today, hours: 8, statement_of_work_id: sow_id, user_id: assignment.user.id) + + expect(time_entry).to be_valid + end + + it 'is invalid if there is no assignment active for the sow' do + user = create(:user) + sow = create(:statement_of_work) + time_entry = TimeEntry.new(date: Time.zone.today, hours: 8, statement_of_work_id: sow.id, user_id: user.id) + + expect(time_entry).not_to be_valid + end + end end