From 001406a35ec70ed91a4e61b3f7d6d04ad565a426 Mon Sep 17 00:00:00 2001 From: adrian peralta Date: Thu, 8 Aug 2024 22:35:20 +0000 Subject: [PATCH] feat: #6 show past and future weeks based on company service id --- backend/app/controllers/weeks_controller.rb | 13 +- backend/app/services/week_service.rb | 68 +++++++++ backend/spec/services/week_service_spec.rb | 161 ++++++++++++++++++++ 3 files changed, 230 insertions(+), 12 deletions(-) create mode 100644 backend/app/services/week_service.rb create mode 100644 backend/spec/services/week_service_spec.rb diff --git a/backend/app/controllers/weeks_controller.rb b/backend/app/controllers/weeks_controller.rb index ec5280d..7079b96 100644 --- a/backend/app/controllers/weeks_controller.rb +++ b/backend/app/controllers/weeks_controller.rb @@ -1,16 +1,5 @@ class WeeksController < ApplicationController def index - @weeks_past = [{ - id: "2024-32", - label: "Semana 32 del 2024", - start_date: "05/08/2024", - end_date: "11/08/2024" - }] - @weeks_future = [{ - id: "2024-33", - label: "Semana 33 del 2024", - start_date: "12/08/2024", - end_date: "18/08/2024" - }] + @weeks = WeekService.generate_weeks_data(params[:company_service_id]) end end diff --git a/backend/app/services/week_service.rb b/backend/app/services/week_service.rb new file mode 100644 index 0000000..bc6da8f --- /dev/null +++ b/backend/app/services/week_service.rb @@ -0,0 +1,68 @@ +class WeekService + + def self.generate_weeks_data(company_service_id) + company_service = CompanyService.find(company_service_id) + start_date = company_service.contract_start_date.to_date + end_date = company_service.contract_end_date.to_date + + current_date = Date.today + past_weeks = [] + future_weeks = [] + + if date_in_contract?(start_date, end_date, current_date) + past_weeks = fetch_past(current_date, start_date) + future_weeks = fetch_future(current_date, end_date) + else + past_weeks = fetch_past(end_date, start_date) + end + { past: past_weeks, future: future_weeks } + end + + ## REFACTOR: make private, just validate based on 2 contracts + def self.date_in_contract?(start_date, end_date, date) + # service.contract_start_date <= date && date <= service.contract_end_date + (start_date..end_date).cover?(date) + end + + def self.week_identifier(date) + "#{date.year}-#{date.strftime('%W')}" + end + + def self.one_week(week_start, week_end) + { + id: week_identifier(week_start), + label: "Semana #{week_start.strftime('%W')} del #{week_start.year}", + start_date: week_start.strftime('%d/%m/%Y'), + end_date: week_end.strftime('%d/%m/%Y') + } + end + + def self.fetch_past(date, start_date_limit) + first_monday = start_date_limit.beginning_of_week + weeks = [] + mondays = [date.beginning_of_week] + while mondays.last > first_monday + week_start = mondays.last.last_week + week_end = week_start.end_of_week + weeks << one_week(week_start, week_end) + mondays << week_start + end + weeks + end + + def self.fetch_future(date, end_date_limit) + weeks = [] + week_start = date.beginning_of_week + 5.times do + week_end = week_start.end_of_week + + break if week_start > end_date_limit + weeks << one_week(week_start, week_end) + + week_start = week_start.next_week + end + + weeks + end + +end \ No newline at end of file diff --git a/backend/spec/services/week_service_spec.rb b/backend/spec/services/week_service_spec.rb new file mode 100644 index 0000000..ce83e4b --- /dev/null +++ b/backend/spec/services/week_service_spec.rb @@ -0,0 +1,161 @@ +require 'rails_helper' + +RSpec.describe WeekService, type: :service do + describe '.week_identifier' do + it 'returns the correct week identifier' do + date = Date.new(2024, 8, 5) # Lunes 5 de Agosto del 2024 + expected_identifier = "2024-32" + + result = WeekService.week_identifier(date) + + expect(result).to eq(expected_identifier) + end + end + + describe '.one_week' do + it 'returns the correct week structure' do + week_start = Date.new(2024, 8, 5) # Lunes 5 de Agosto del 2024 + week_end = week_start.end_of_week # Domingo 11 de Agosto del 2024 + + expected_week = { + id: "2024-32", + label: "Semana 32 del 2024", + start_date: "05/08/2024", + end_date: "11/08/2024" + } + + result = WeekService.one_week(week_start, week_end) + + expect(result).to eq(expected_week) + end + end + + describe '.fetch_past' do + it 'returns all past weeks until the contract start date' do + today = Date.new(2024, 8, 5) ## Lunes 5 de Agosto del 2024 + start_date_limit = Date.new(2024, 7, 15) # Lunes 15 de Julio del 2024 + + expected_past_weeks = [ + { + id: "2024-31", + label: "Semana 31 del 2024", + start_date: "29/07/2024", + end_date: "04/08/2024" + }, + { + id: "2024-30", + label: "Semana 30 del 2024", + start_date: "22/07/2024", + end_date: "28/07/2024" + }, + { + id: "2024-29", + label: "Semana 29 del 2024", + start_date: "15/07/2024", + end_date: "21/07/2024" + } + ] + + result = WeekService.fetch_past(today, start_date_limit) + + expect(result).to eq(expected_past_weeks) + end + end + describe '.fetch_future' do + context 'when there are enough weeks before the end_date_limit' do + it 'returns 5 weeks' do + date = Date.new(2024, 8, 15) # Jueves 15 de Agosto del 2024 + end_date_limit = Date.new(2024, 10, 31) # 31 de Octubre del 2024 + + expected_future_weeks = [ + { + id: "2024-33", + label: "Semana 33 del 2024", + start_date: "12/08/2024", + end_date: "18/08/2024" + }, + { + id: "2024-34", + label: "Semana 34 del 2024", + start_date: "19/08/2024", + end_date: "25/08/2024" + }, + { + id: "2024-35", + label: "Semana 35 del 2024", + start_date: "26/08/2024", + end_date: "01/09/2024" + }, + { + id: "2024-36", + label: "Semana 36 del 2024", + start_date: "02/09/2024", + end_date: "08/09/2024" + }, + { + id: "2024-37", + label: "Semana 37 del 2024", + start_date: "09/09/2024", + end_date: "15/09/2024" + } + ] + + result = WeekService.fetch_future(date, end_date_limit) + + expect(result).to eq(expected_future_weeks) + end + end + + context 'when the end_date_limit restricts the number of weeks' do + it 'returns only the weeks within the end_date_limit' do + date = Date.new(2024, 8, 15) # Jueves 15 de Agosto del 2024 + end_date_limit = Date.new(2024, 9, 1) # Domingo 1 de Setiembre del 2024 + + expected_future_weeks = [ + { + id: "2024-33", + label: "Semana 33 del 2024", + start_date: "12/08/2024", + end_date: "18/08/2024" + }, + { + id: "2024-34", + label: "Semana 34 del 2024", + start_date: "19/08/2024", + end_date: "25/08/2024" + }, + { + id: "2024-35", + label: "Semana 35 del 2024", + start_date: "26/08/2024", + end_date: "01/09/2024" + } + ] + + result = WeekService.fetch_future(date, end_date_limit) + + expect(result).to eq(expected_future_weeks) + end + end + + context 'when the end_date_limit is very close' do + it 'returns only one week if limit restricts it to 1 week' do + date = Date.new(2024, 8, 15) # Jueves 15 de Agosto del 2024 + end_date_limit = Date.new(2024, 8, 18) # Only allows for 1 week + + expected_future_weeks = [ + { + id: "2024-33", + label: "Semana 33 del 2024", + start_date: "12/08/2024", + end_date: "18/08/2024" + } + ] + + result = WeekService.fetch_future(date, end_date_limit) + + expect(result).to eq(expected_future_weeks) + end + end + end +end