Skip to content

Commit

Permalink
add time entries sync
Browse files Browse the repository at this point in the history
  • Loading branch information
kaiomagalhaes committed Nov 9, 2023
1 parent 5a2634c commit 2d869e0
Show file tree
Hide file tree
Showing 9 changed files with 202 additions and 161 deletions.
17 changes: 15 additions & 2 deletions app/services/team_maker_project_creator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,25 @@ def call
return if data.project.nil?

create_requirements!(data.project_requirements)
create_time_entires!(data.time_entries)
create_time_entries!(data.time_entries)
create_time_off_entries!(data.time_offs)
end

private

def create_time_entires!(team_maker_project_time_entries)
def create_time_off_entries!(time_offs)
TimeOff.destroy_all
time_offs.each do |time_off|
time_off_type = TimeOffType.find_by(name: time_off.type)

user = User.find_by(email: time_off.resource)
next if user.nil? || time_off_type.nil?

TimeOff.create!(starts_at: time_off.starts_on, ends_at: time_off.ends_on, user:, time_off_type:)
end
end

def create_time_entries!(team_maker_project_time_entries)
statement_of_work.time_entries.destroy_all

team_maker_project_time_entries.each do |time_entry|
Expand Down
32 changes: 16 additions & 16 deletions app/utils/analytics/time_entries_analytics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ module Analytics
class TimeEntriesAnalytics
def initialize(statement_of_work, start_date, end_date)
@statement_of_work = statement_of_work
@start_date = start_date.to_datetime
@end_date = end_date.to_datetime
@start_date = start_date.to_datetime.beginning_of_day
@end_date = end_date.to_datetime.end_of_day
@worked_hours_cache = {} # Cache for memoization
end

# rubocop:disable Metrics/AbcSize
Expand Down Expand Up @@ -33,18 +34,19 @@ def data
labels: worked_hash.keys,
datasets: [
{ label: 'Worked', data: worked_hash.values },
{ label: 'Missing', data: missing_hash.values },
{ label: 'Paid time off', data: vacation_hash.values },
{ label: 'Sick leave', data: sick_leave_hash.values },
{ label: 'Over delivered', data: over_delivered_hash.values }
{ label: 'Over delivered', data: over_delivered_hash.values },
{ label: 'Missing', data: missing_hash.values }
]
}
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/AbcSize

def assignments
@assignments ||= Assignment.where(requirement: requirements).joins(:user).order('users.first_name')
@assignments ||= Assignment.where(requirement: requirements).joins(:user).order('users.first_name',
'users.last_name')
end

def requirements
Expand All @@ -69,13 +71,15 @@ def clean_worked_hours(assignment)
end

def worked_hours(assignment)
return @worked_hours_cache[assignment.id] if @worked_hours_cache.key?(assignment.id)

time_entries = TimeEntry.where(
statement_of_work: assignment.requirement.statement_of_work,
date: @start_date..@end_date,
date: (@start_date.beginning_of_day)..@end_date.end_of_day,
user: assignment.user
)

time_entries.sum(&:hours)
@worked_hours_cache[assignment.id] = time_entries.sum(&:hours)
end

def expected_hours(assignment)
Expand All @@ -93,7 +97,7 @@ def missing_hours(assignment)
end

def vacation_hours(assignment)
vacation_type = TimeOffType.find_by(name: TimeOffType::VACATION_TYPE)
vacation_type = TimeOffType.where(name: [TimeOffType::VACATION_TYPE, TimeOffType::ERRAND_TYPE])
paid_time_off_hours(assignment, vacation_type)
end

Expand All @@ -108,20 +112,16 @@ def paid_time_off_hours(assignment, time_off_type)
time_offs = time_offs_by_user_and_type(assignment.user, time_off_type)

time_offs.reduce(0) do |accumulator, time_off|
start_date = [time_off.starts_at, @start_date].max
end_date = [time_off.ends_at, @end_date].min
start_date = [time_off.starts_at, @start_date].max.to_time
end_date = [time_off.ends_at, @end_date].min.to_time
hours = 0

current_date = start_date
while current_date <= end_date
next(0) if current_date.saturday? || current_date.sunday?

if current_date == end_date
hours = 8
else
while current_date <= end_date
unless current_date.saturday? || current_date.sunday?
hours += [(end_date - current_date) / 3600, 8].min
end

current_date = current_date.next_day
end

Expand Down
6 changes: 6 additions & 0 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,9 @@
Permission.create(target: 'analytics', ability: 'view')
Permission.create(target: 'user', ability: 'change')
end

if TimeOffType.count.zero?
TimeOffType.create(name: 'vacation')
TimeOffType.create(name: 'sick leave')
TimeOffType.create(name: 'errand')
end

Large diffs are not rendered by default.

30 changes: 19 additions & 11 deletions spec/fixtures/vcr_cassettes/clients_team-maker_list.yml

Large diffs are not rendered by default.

Large diffs are not rendered by default.

48 changes: 42 additions & 6 deletions spec/services/team_maker_project_creator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

RSpec.describe TeamMakerProjectCreator, type: :service do
let(:project) do
FactoryBot.create(:project, id: 1)
FactoryBot.create(:project, id: 2)
end

let(:professions) do
Expand All @@ -25,6 +25,12 @@
FactoryBot.create(:user, email: '[email protected]')
end

before do
TimeOffType.create(name: 'vacation')
TimeOffType.create(name: 'sick leave')
TimeOffType.create(name: 'errand')
end

describe '#call' do
it 'creates the requirements' do
VCR.use_cassette('clients#team-maker#list') do
Expand All @@ -36,7 +42,7 @@
Project.all.each do |project|
TeamMakerProjectCreator.new(project).call
end
end.to change(Requirement, :count).by(9)
end.to change(Requirement, :count).by(8)
end
end

Expand All @@ -50,7 +56,7 @@
TeamMakerProjectCreator.new(project).call
TeamMakerProjectCreator.new(project).call
end
expect(Requirement.count).to eql(9)
expect(Requirement.count).to eql(8)
end
end

Expand All @@ -77,11 +83,41 @@
expect do
Project.all.each do |project|
TeamMakerProjectCreator.new(project).call
TeamMakerProjectCreator.new(project).call
end
end.to change(Assignment, :count).by(9)
end
end

it 'creates the assignments time off entries' do
VCR.use_cassette('clients#team-maker#list') do
project
professions
users

expect do
Project.all.each do |project|
TeamMakerProjectCreator.new(project).call
end
end.to change(TimeOff, :count).by(152)
end
end

it 'does not duplicate the time off entries' do
VCR.use_cassette('clients#team-maker#does-not-duplicate') do
project
professions
users

expect do
Project.all.each do |project|
TeamMakerProjectCreator.new(project).call
TeamMakerProjectCreator.new(project).call
end
end.to change(TimeOff, :count).by(152)
end
end

it 'creates the time entries' do
VCR.use_cassette('clients#team-maker#list') do
project
Expand All @@ -92,7 +128,7 @@
Project.all.each do |project|
TeamMakerProjectCreator.new(project).call
end
end.to change(TimeEntry, :count).by(352)
end.to change(TimeEntry, :count).by(405)
end
end

Expand All @@ -106,7 +142,7 @@
Project.all.each do |project|
TeamMakerProjectCreator.new(project).call
end
end.to change(TimeEntry, :count).by(352)
end.to change(TimeEntry, :count).by(405)
end
end

Expand All @@ -121,7 +157,7 @@
Project.all.each do |project|
TeamMakerProjectCreator.new(project).call
end
end.to change(Requirement, :count).by(9)
end.to change(Requirement, :count).by(8)
end
end
end
Expand Down
Loading

0 comments on commit 2d869e0

Please sign in to comment.