Conversation
keshavbiswa
left a comment
There was a problem hiding this comment.
LGTM! added minor comments.
app/services/report/group_by.rb
Outdated
| end | ||
|
|
||
| def process | ||
| return {} if group_by_field.blank? || !POSSIBLE_GROUP_BY_INPUTS.include?(group_by_field) |
There was a problem hiding this comment.
| return {} if group_by_field.blank? || !POSSIBLE_GROUP_BY_INPUTS.include?(group_by_field) | |
| return {} if group_by_field.blank? || POSSIBLE_GROUP_BY_INPUTS.exclude?(group_by_field) |
app/services/report/result.rb
Outdated
| # When we query ES, we get all matching timesheet entries as response even when we pass aggregation query. | ||
| # Those timesheet entries contains all required association but not the ones in aggregated data. | ||
| # So, in order to avoid queries for associated records, | ||
| # creating map of id -> timesheet entries from the general ES response and | ||
| # then using it for building final data by merging that with ids found in aggregation query. |
There was a problem hiding this comment.
Can you add these comments outside the method?
rohitjoshixyz
left a comment
There was a problem hiding this comment.
Code LGTM
I liked how you have split the code into services, making it very clean and easy to grasp.
I understand the PR was complex and needed a lot of research but we would also want to have specs for each service you added and a request spec for the controller action to make the code foolproof.
Could you please also attach a loom video demonstrating the functionality?
Overall good job Shalaka. Well done 👏
|
|
||
| scope :in_workspace, -> (company) { where(project_id: company&.project_ids) } | ||
|
|
||
| searchkick |
There was a problem hiding this comment.
For aggregations to work you have to have filterable is searchkick
searchable = %i[name]
filterable = %[created_at]
searchkick searchable: searchable, filterable: filterable
There was a problem hiding this comment.
Not really. With aggregation query which I am passing, aggregations are working fine
|
|
||
| searchkick | ||
|
|
||
| def search_data |
There was a problem hiding this comment.
Can we individually list all the attributes we want to index?
For example
def search_data
{
id: id.to_i,
name: name,
created_at: created_at.to_datetime
}
Reason for this is ES works on RAM, and unnecessary fields will clutter up the ES instance which becomes exponential over time.
There was a problem hiding this comment.
Okay, I was thinking of doing this but thought that fields are not that much so indexed everything. I will update code to index only required ones
| filters_where_clause = Report::Filters.process(params) | ||
| where_clause = current_company_project_ids_filter.merge(filters_where_clause) | ||
| TimesheetEntry.search(where: where_clause, includes: [:user, :project]) | ||
| group_by_clause = Report::GroupBy.process(params["group_by"]) |
There was a problem hiding this comment.
Not sure how GroupBy works, for grouping you can use aggregations, as in the SearchKick documentation:
Product.search("wingtips", where: {color: "brandy"}, aggs: [:size])
There was a problem hiding this comment.
using aggregation only which is defined in the service class
shalapatil
left a comment
There was a problem hiding this comment.
@rohitjoshixyz I can't add loom video as UI is broken and FE integration is required.
I am working on all the review comments now
rohitjoshixyz
left a comment
There was a problem hiding this comment.
Added few comments
|
|
||
| require "rails_helper" | ||
|
|
||
| RSpec.describe "service::reports#group_by", type: :model do |
There was a problem hiding this comment.
type should be service
| expect(reports["label"]).to eq("") | ||
| timesheet_ids_in_response = reports["entries"].pluck("id") | ||
| expect(reports["entries"].size).to eq(2) | ||
| # Timsheets should be in desceding order of work_date |
There was a problem hiding this comment.
Assert in separate it block instead of a comment
| @this_week_start_date = 0.weeks.ago.beginning_of_week | ||
| @this_week_end_date = 0.weeks.ago.end_of_week | ||
| @timesheet_entry1 = create(:timesheet_entry, project:, work_date: last_month_start_date) | ||
| @timesheet_entry2 = create(:timesheet_entry, project:, work_date: this_week_start_date) | ||
| @timesheet_entry3 = create(:timesheet_entry, project:, work_date: this_week_start_date) | ||
| @timesheet_entry2 = create(:timesheet_entry, project:, work_date: @this_week_start_date) | ||
| @timesheet_entry3 = create(:timesheet_entry, project:, work_date: @this_week_end_date) |
There was a problem hiding this comment.
Do not use @ variables, use let instead
| timesheet_ids_in_response = json_response["entries"].pluck("id") | ||
| expect(json_response["entries"].size).to eq(1) | ||
| reports = json_response["reports"].first | ||
| expect(reports["label"]).to eq("") |
There was a problem hiding this comment.
What are we asserting here?
There was a problem hiding this comment.
we want label empty when we grouping is not selected
app/services/report/group_by.rb
Outdated
| class GroupBy < ApplicationService | ||
| attr_reader :group_by_field | ||
|
|
||
| POSSIBLE_GROUP_BY_INPUTS = ["team_member", "client", "project", "week"] |
There was a problem hiding this comment.
| POSSIBLE_GROUP_BY_INPUTS = ["team_member", "client", "project", "week"] | |
| POSSIBLE_GROUP_BY_INPUTS = ["team_member", "client", "project", "week"].freeze |
Current Code Coverage Percent of this PR:84.72 %Files having coverage below 100%
|
rohitjoshixyz
left a comment
There was a problem hiding this comment.
@shalapatil please add specs for filters and results service in a follow up PR so that our code coverage doesn't drop, other than that code LGTM. I am fine with keeping the @ variables for that one spec. cc @akhilgkrishnan @keshavbiswa .
Let's push this to production 🔥 if others do not object.
* Index client_id to elasticsearch * Use client id directly for filtering * Add service class for creating group-by es query * Add service class for processing aggregated ES data * Consider group-by while showing reports * Return formatted date labels for grouping by week * Add sorting as desc order by work_date * Add default filter of this_month duration * Fix reports request tests * Add specs for group_by service class * Add request specs for group by but without any filters * Add specs for group by and filter combinations * Fix clients specs * Fix suggested changes
Notion card
Summary
https://www.notion.so/saeloun/Back-end-Groupby-on-Reports-Filter-150697fe97e14036aec0400e20be8e17
Preview
Type of change
Please delete options that are not relevant.
not work as expected)
How Has This Been Tested?
Checklist: