Skip to content

Commit

Permalink
Implement work report query builder (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nick Flückiger authored May 5, 2021
1 parent d77a3b2 commit 0d7e2a1
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 18 deletions.
14 changes: 6 additions & 8 deletions app/controllers/time_tracker_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ def start
if @current_timer_session
respond_with_error(error: :timer_already_present)
else
timer_session = SessionCreator.new(@current_user, timer_params).create
issue_connector = IssueConnector.new(timer_params[:issue_ids] || [], timer_session)
@timer_session = SessionCreator.new(@current_user, timer_params).create
issue_connector = IssueConnector.new(timer_params[:issue_ids] || [], @timer_session)
issue_connector.run
if timer_session.session_finished?
if @timer_session.session_finished?
handle_finished_timer_session
else
@timer_session = timer_session
render :start, layout: false
end
end
Expand All @@ -36,13 +35,12 @@ def update
private

def handle_finished_timer_session
if timer_session.valid?
time_splitter = TimeSplitter.new(timer_session)
if @timer_session.valid?
time_splitter = TimeSplitter.new(@timer_session)
time_splitter.create_time_entries
timer_session.update(finished: true)
@timer_session.update(finished: true)
render :stop, layout: true
else
@timer_session = timer_session
render :start, layout: false
end
end
Expand Down
10 changes: 10 additions & 0 deletions app/controllers/timer_sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ def index
.group_by { |entry| entry.timer_start&.to_date }
end

def report
work_report_query = WorkReportQuery.new(report_query_params)
result_url = WorkReportQueryBuilder.new(work_report_query).build_query
redirect_to result_url
end

def destroy
timer_session = TimerSession.find(params[:id])
TimerEntityCleaner.new(timer_session).run
Expand All @@ -33,4 +39,8 @@ def set_current_user
def set_current_timer_session
@current_timer_session = TimerSession.active_session(@current_user.id).first
end

def report_query_params
params.require(:work_report_query).permit(:date, :period)
end
end
8 changes: 8 additions & 0 deletions app/models/work_report_query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

class WorkReportQuery
include ActiveModel::Model
extend ActiveModel::Naming

attr_accessor :period, :date
end
48 changes: 44 additions & 4 deletions app/services/work_report_query_builder.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,52 @@
# frozen_string_literal: true

class WorkReportQueryBuilder
include Rails.application.routes.url_helpers

AVAILABLE_PERIODS = %i[day week month year].freeze
DATE_FORMAT_FOR_QUERY = '%Y-%m-%d'
COLUMNS_TO_QUERY = %w[project spent_on activity issue comments hours].freeze
BETWEEN_OPERATOR = '><'
FILTERS_TO_USE = ['spent_on', 'user_id', ''].freeze
QUERY_CURRENT_USER_SYMBOL = 'me'
FILTER_STATUS = '1'

def initialize(work_report_query)
@work_report_query = work_report_query
@date = Date.parse(@work_report_query.date)
end

def initialize(date, period: :week)
@date = date
@period = period
def build_query
date_range = build_date_range.map { |date| date.strftime(DATE_FORMAT_FOR_QUERY) }
build_report_query(date_range)
end

def build_report_query; end
private

def build_report_query(date_range)
time_entries_path(
set_filter: FILTER_STATUS, sort: 'spent_on:desc',
f: FILTERS_TO_USE,
op: { spent_on: BETWEEN_OPERATOR, user_id: '=' },
v: { spent_on: [date_range.first, date_range.last], user_id: [QUERY_CURRENT_USER_SYMBOL] },
c: COLUMNS_TO_QUERY, group_by: '', t: ['hours']
)
end

def valid?
AVAILABLE_PERIODS.include?(@work_report_query.period)
end

def build_date_range
case @work_report_query.period.to_sym
when :day
[@date, @date]
when :week
[@date.beginning_of_week, @date.end_of_week]
when :month
[@date.beginning_of_month, @date.end_of_month]
when :year
[@date.beginning_of_year, @date.end_of_year]
end
end
end
7 changes: 5 additions & 2 deletions app/views/timer_sessions/_entries_report_query.html.slim
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
.box
= form_for :entry_report_query do |f|
= f.date_field :date
- current_report_query = current_report || WorkReportQuery.new
= labelled_form_for(current_report_query, url: timer_sessions_report_path, method: :get) do |f|
= f.date_field :date, value: Time.zone.now.to_date
br
= f.select :period, %i[day week month year]
br
= f.submit :see_query
2 changes: 1 addition & 1 deletion app/views/timer_sessions/index.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
= render 'timer_container', timer_session: @current_timer_session
hr
div[data-timer-session-container]
= render 'entries_report_query'
= render 'entries_report_query', current_report: @current_report
hr
div[data-timer-sessions-list]
= render 'timer_sessions_list', timer_sessions_by_day: @timer_sessions
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
# See: http://guides.rubyonrails.org/routing.htm
resources :timer_sessions, only: %i[index edit update patch destroy]

get 'timer_sessions_report', to: 'timer_sessions#report', as: :timer_sessions_report

post 'time_tracker/start', to: 'time_tracker#start', as: :start_time_tracker
post 'time_tracker/stop', to: 'time_tracker#stop', as: :stop_time_tracker
post 'time_tracker/update', to: 'time_tracker#update', as: :update_time_tracker
6 changes: 3 additions & 3 deletions test/unit/display_date_format_builder_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@

class DisplayDateFormatBuilderTest < ActiveSupport::TestCase

test 'format_for_same_date' do
test 'format for same date' do
formatter = DisplayDateFormatBuilder.new(
Time.zone.local(2001, 2, 3, 4, 5, 6),
Time.zone.local(2001, 2, 3, 4, 5, 6)
)
assert_equal('04:05 - 04:05', formatter.format)
end

test 'format_for_date_with_same_year' do
test 'format for date with same year' do
formatter = DisplayDateFormatBuilder.new(
Time.zone.local(2001, 10, 3, 4, 5, 6),
Time.zone.local(2001, 2, 3, 4, 5, 6)
)
assert_equal('03.10 04:05 - 03.02 04:05', formatter.format)
end

test 'format_with_different_year' do
test 'format with different year' do
formatter = DisplayDateFormatBuilder.new(
Time.zone.local(2001, 10, 3, 4, 5, 6),
Time.zone.local(2002, 10, 3, 4, 5, 6)
Expand Down
59 changes: 59 additions & 0 deletions test/unit/work_report_query_builder_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require File.expand_path('../test_helper', __dir__)

class WorkReportQueryBuilderTest < ActiveSupport::TestCase
test 'build query for day report' do
work_report_query = WorkReportQuery.new(
date: Date.new(2021, 10, 30).to_s,
period: :day
)
expected_query = URI.decode("/time_entries?c%5B%5D=project&c%5B%5D=spent_on"+
"&c%5B%5D=activity&c%5B%5D=issue&c%5B%5D=comments"+
"&c%5B%5D=hours&f%5B%5D=spent_on&f%5B%5D=user_id"+
"&f%5B%5D=&group_by=&op%5Bspent_on%5D=%3E%3C&op%5Buser_id"+
"%5D=%3D&set_filter=1&sort=spent_on%3Adesc&t%5B%5D=hours&v%5Bspent_on"+
"%5D%5B%5D=2021-10-30&v%5Bspent_on%5D%5B%5D=2021-10-30&v%5Buser_id%5D%5B%5D=me")
assert_equal expected_query, URI.decode(WorkReportQueryBuilder.new(work_report_query).build_query)
end

test 'build query for week report' do
work_report_query = WorkReportQuery.new(
date: Date.new(2021, 10, 30).to_s,
period: :week
)
expected_query = URI.decode("/time_entries?c%5B%5D=project&c%5B%5D=spent_on"+
"&c%5B%5D=activity&c%5B%5D=issue&c%5B%5D=comments"+
"&c%5B%5D=hours&f%5B%5D=spent_on&f%5B%5D=user_id"+
"&f%5B%5D=&group_by=&op%5Bspent_on%5D=%3E%3C&op%5Buser_id"+
"%5D=%3D&set_filter=1&sort=spent_on%3Adesc&t%5B%5D=hours&v%5Bspent_on"+
"%5D%5B%5D=2021-10-25&v%5Bspent_on%5D%5B%5D=2021-10-31&v%5Buser_id%5D%5B%5D=me")
assert_equal expected_query, URI.decode(WorkReportQueryBuilder.new(work_report_query).build_query)
end

test 'build query for month report' do
work_report_query = WorkReportQuery.new(
date: Date.new(2021, 10, 30).to_s,
period: :month
)
expected_query = URI.decode("/time_entries?c%5B%5D=project&c%5B%5D=spent_on"+
"&c%5B%5D=activity&c%5B%5D=issue&c%5B%5D=comments"+
"&c%5B%5D=hours&f%5B%5D=spent_on&f%5B%5D=user_id"+
"&f%5B%5D=&group_by=&op%5Bspent_on%5D=%3E%3C&op%5Buser_id"+
"%5D=%3D&set_filter=1&sort=spent_on%3Adesc&t%5B%5D=hours&v%5Bspent_on"+
"%5D%5B%5D=2021-10-01&v%5Bspent_on%5D%5B%5D=2021-10-31&v%5Buser_id%5D%5B%5D=me")
assert_equal expected_query, URI.decode(WorkReportQueryBuilder.new(work_report_query).build_query)
end

test 'build query for year report' do
work_report_query = WorkReportQuery.new(
date: Date.new(2021, 10, 30).to_s,
period: :year
)
expected_query = URI.decode("/time_entries?c%5B%5D=project&c%5B%5D=spent_on"+
"&c%5B%5D=activity&c%5B%5D=issue&c%5B%5D=comments"+
"&c%5B%5D=hours&f%5B%5D=spent_on&f%5B%5D=user_id"+
"&f%5B%5D=&group_by=&op%5Bspent_on%5D=%3E%3C&op%5Buser_id"+
"%5D=%3D&set_filter=1&sort=spent_on%3Adesc&t%5B%5D=hours&v%5Bspent_on"+
"%5D%5B%5D=2021-01-01&v%5Bspent_on%5D%5B%5D=2021-12-31&v%5Buser_id%5D%5B%5D=me")
assert_equal expected_query, URI.decode(WorkReportQueryBuilder.new(work_report_query).build_query)
end
end

0 comments on commit 0d7e2a1

Please sign in to comment.