From aa2a5757ecff2146e727a174c543e25e47f7911f Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 16 Oct 2024 16:12:35 +1100 Subject: [PATCH 1/8] Move Customers report spec to own file --- .../admin/reports/customers_report_spec.rb | 25 +++++++++++++++++++ spec/system/admin/reports_spec.rb | 22 ---------------- 2 files changed, 25 insertions(+), 22 deletions(-) create mode 100644 spec/system/admin/reports/customers_report_spec.rb diff --git a/spec/system/admin/reports/customers_report_spec.rb b/spec/system/admin/reports/customers_report_spec.rb new file mode 100644 index 0000000000..7f5caaab46 --- /dev/null +++ b/spec/system/admin/reports/customers_report_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require "system_helper" + +RSpec.describe "Customers report" do + include AuthenticationHelper + + it "can be rendered" do + login_as_admin + visit admin_reports_path + + within "table.index" do + click_link "Customers" + end + run_report + + rows = find("table.report__table").all("thead tr") + table = rows.map { |r| r.all("th").map { |c| c.text.strip } } + expect(table.sort).to eq([ + ["First Name", "Last Name", "Billing Address", "Email", "Phone", "Hub", "Hub Address", + "Shipping Method", "Total Number of Orders", "Total incl. tax ($)", + "Last completed order date"] + ].sort) + end +end diff --git a/spec/system/admin/reports_spec.rb b/spec/system/admin/reports_spec.rb index 57d7dfff22..072c546646 100644 --- a/spec/system/admin/reports_spec.rb +++ b/spec/system/admin/reports_spec.rb @@ -151,28 +151,6 @@ RSpec.describe ' end end - describe "Can access Customers reports and generate customers report" do - before do - login_as_admin - visit admin_reports_path - end - - it "customers report" do - within "table.index" do - click_link "Customers" - end - run_report - - rows = find("table.report__table").all("thead tr") - table = rows.map { |r| r.all("th").map { |c| c.text.strip } } - expect(table.sort).to eq([ - ["First Name", "Last Name", "Billing Address", "Email", "Phone", "Hub", "Hub Address", - "Shipping Method", "Total Number of Orders", "Total incl. tax ($)", - "Last completed order date"] - ].sort) - end - end - describe "Order cycle management report" do before do login_as_admin From 3227922c7670b3f142a0dd79e0c464564ba7f0ea Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 16 Oct 2024 16:18:23 +1100 Subject: [PATCH 2/8] Use reports helper to DRY --- .../admin/reports/customers_report_spec.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/spec/system/admin/reports/customers_report_spec.rb b/spec/system/admin/reports/customers_report_spec.rb index 7f5caaab46..a9fc0746c8 100644 --- a/spec/system/admin/reports/customers_report_spec.rb +++ b/spec/system/admin/reports/customers_report_spec.rb @@ -14,12 +14,14 @@ RSpec.describe "Customers report" do end run_report - rows = find("table.report__table").all("thead tr") - table = rows.map { |r| r.all("th").map { |c| c.text.strip } } - expect(table.sort).to eq([ - ["First Name", "Last Name", "Billing Address", "Email", "Phone", "Hub", "Hub Address", - "Shipping Method", "Total Number of Orders", "Total incl. tax ($)", - "Last completed order date"] - ].sort) + expect(table_headers).to eq( + [ + [ + "First Name", "Last Name", "Billing Address", "Email", "Phone", + "Hub", "Hub Address", "Shipping Method", "Total Number of Orders", + "Total incl. tax ($)", "Last completed order date", + ] + ] + ) end end From aa7fffa5a2e32434136cf497fbfb2ca76d077799 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 16 Oct 2024 16:52:03 +1100 Subject: [PATCH 3/8] Filter reports by last 3 months by default The values are not shown on the screen and the user doesn't know which default dates are applied but the filtering works. --- .../admin/reports/_date_range_form.html.haml | 4 +-- .../admin/reports/customers_report_spec.rb | 25 ++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/app/views/admin/reports/_date_range_form.html.haml b/app/views/admin/reports/_date_range_form.html.haml index 040344e622..8ccd074626 100644 --- a/app/views/admin/reports/_date_range_form.html.haml +++ b/app/views/admin/reports/_date_range_form.html.haml @@ -1,8 +1,8 @@ -# Field used for ransack search. This date range is mostly used for Spree::Order -# so default field is 'completed_at' - field ||= 'completed_at' -- start_date ||= params[:q].try(:[], :completed_at_gt) -- end_date ||= params[:q].try(:[], :completed_at_lt) +- start_date ||= params[:q].try(:[], :completed_at_gt) || 3.months.ago.beginning_of_day +- end_date ||= params[:q].try(:[], :completed_at_lt) || Time.zone.tomorrow.beginning_of_day .row.date-range-filter .alpha.two.columns= label_tag nil, t(:date_range) diff --git a/spec/system/admin/reports/customers_report_spec.rb b/spec/system/admin/reports/customers_report_spec.rb index a9fc0746c8..bd51a0a949 100644 --- a/spec/system/admin/reports/customers_report_spec.rb +++ b/spec/system/admin/reports/customers_report_spec.rb @@ -5,8 +5,11 @@ require "system_helper" RSpec.describe "Customers report" do include AuthenticationHelper + let(:enterprise_user) { create(:enterprise_user) } + let(:distributor) { enterprise_user.enterprises[0] } + it "can be rendered" do - login_as_admin + login_as enterprise_user visit admin_reports_path within "table.index" do @@ -24,4 +27,24 @@ RSpec.describe "Customers report" do ] ) end + + it "displays filtered data by default" do + old_order = create( + :completed_order_with_totals, distributor:, completed_at: 4.months.ago + ) + new_order = create(:completed_order_with_totals, distributor:) + future_order = create( + :completed_order_with_totals, distributor:, completed_at: 1.day.from_now + ) + + login_as enterprise_user + visit admin_report_path(report_type: :customers) + run_report + + rows = find("table.report__table").all("tbody tr") + expect(rows.count).to eq 1 + expect(rows[0].all("td")[3].text).to eq new_order.email + expect(page).not_to have_content old_order.email + expect(page).not_to have_content future_order.email + end end From a13e5ced3d947ff29c45ab7496506034e58bc724 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 16 Oct 2024 17:07:51 +1100 Subject: [PATCH 4/8] Select default dates for Packing report, too --- app/views/admin/reports/_date_range_form.html.haml | 11 +++++++---- app/views/admin/reports/filters/_packing.html.haml | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/views/admin/reports/_date_range_form.html.haml b/app/views/admin/reports/_date_range_form.html.haml index 8ccd074626..27a344caa2 100644 --- a/app/views/admin/reports/_date_range_form.html.haml +++ b/app/views/admin/reports/_date_range_form.html.haml @@ -1,8 +1,11 @@ -# Field used for ransack search. This date range is mostly used for Spree::Order -# so default field is 'completed_at' - field ||= 'completed_at' -- start_date ||= params[:q].try(:[], :completed_at_gt) || 3.months.ago.beginning_of_day -- end_date ||= params[:q].try(:[], :completed_at_lt) || Time.zone.tomorrow.beginning_of_day +- start_field = "#{field}_gt" +- end_field = "#{field}_lt" +- query = params[:q].to_h +- start_date ||= query[start_field].presence || 3.months.ago.beginning_of_day +- end_date ||= query[end_field].presence || Time.zone.tomorrow.beginning_of_day .row.date-range-filter .alpha.two.columns= label_tag nil, t(:date_range) @@ -10,5 +13,5 @@ .field-block.omega.four.columns .date-range-fields{ data: { controller: "flatpickr", "flatpickr-mode-value": "range", "flatpickr-enable-time-value": true , "flatpickr-default-hour": 0 } } = text_field_tag nil, nil, class: "datepicker fullwidth", data: { "flatpickr-target": "instance", action: "flatpickr_clear@window->flatpickr#clear" } - = text_field_tag "q[#{field}_gt]", nil, data: { "flatpickr-target": "start" }, style: "display: none", value: start_date - = text_field_tag "q[#{field}_lt]", nil, data: { "flatpickr-target": "end" }, style: "display: none", value: end_date + = text_field_tag "q[#{start_field}]", nil, data: { "flatpickr-target": "start" }, style: "display: none", value: start_date + = text_field_tag "q[#{end_field}]", nil, data: { "flatpickr-target": "end" }, style: "display: none", value: end_date diff --git a/app/views/admin/reports/filters/_packing.html.haml b/app/views/admin/reports/filters/_packing.html.haml index a23fcd6a9b..d707512641 100755 --- a/app/views/admin/reports/filters/_packing.html.haml +++ b/app/views/admin/reports/filters/_packing.html.haml @@ -1,5 +1,5 @@ = render partial: 'admin/reports/date_range_form', - locals: { f: f, field: 'order_completed_at', start_date: params[:q].try(:[], :order_completed_at_gt), end_date: params[:q].try(:[], :order_completed_at_lt) } + locals: { f: f, field: 'order_completed_at' } .row .alpha.two.columns= label_tag nil, t(:report_hubs) @@ -14,4 +14,4 @@ .row .alpha.two.columns= label_tag nil, t(:report_customers_cycle) .omega.fourteen.columns - = select_tag("q[order_cycle_id_in]", options_for_select(report_order_cycle_options(@data.order_cycles), params.dig(:q, :order_cycle_id_in)), {class: "select2 fullwidth", multiple: true}) \ No newline at end of file + = select_tag("q[order_cycle_id_in]", options_for_select(report_order_cycle_options(@data.order_cycles), params.dig(:q, :order_cycle_id_in)), {class: "select2 fullwidth", multiple: true}) From ea8e9250770d0c7f70fdfa749883d33217d71e58 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 17 Oct 2024 08:59:15 +1100 Subject: [PATCH 5/8] Show default date range to user in date picker --- app/views/admin/reports/_date_range_form.html.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/admin/reports/_date_range_form.html.haml b/app/views/admin/reports/_date_range_form.html.haml index 27a344caa2..763047bdc8 100644 --- a/app/views/admin/reports/_date_range_form.html.haml +++ b/app/views/admin/reports/_date_range_form.html.haml @@ -4,14 +4,14 @@ - start_field = "#{field}_gt" - end_field = "#{field}_lt" - query = params[:q].to_h -- start_date ||= query[start_field].presence || 3.months.ago.beginning_of_day -- end_date ||= query[end_field].presence || Time.zone.tomorrow.beginning_of_day +- start_date ||= query[start_field].presence || 3.months.ago.beginning_of_day.strftime('%Y-%m-%d %H:%M') +- end_date ||= query[end_field].presence || Time.zone.tomorrow.beginning_of_day.strftime('%Y-%m-%d %H:%M') .row.date-range-filter .alpha.two.columns= label_tag nil, t(:date_range) .omega.fourteen.columns .field-block.omega.four.columns - .date-range-fields{ data: { controller: "flatpickr", "flatpickr-mode-value": "range", "flatpickr-enable-time-value": true , "flatpickr-default-hour": 0 } } + .date-range-fields{ data: { controller: "flatpickr", "flatpickr-mode-value": "range", "flatpickr-enable-time-value": true , "flatpickr-default-hour": 0, "flatpickr-default-date": [start_date, end_date] } } = text_field_tag nil, nil, class: "datepicker fullwidth", data: { "flatpickr-target": "instance", action: "flatpickr_clear@window->flatpickr#clear" } = text_field_tag "q[#{start_field}]", nil, data: { "flatpickr-target": "start" }, style: "display: none", value: start_date = text_field_tag "q[#{end_field}]", nil, data: { "flatpickr-target": "end" }, style: "display: none", value: end_date From b9a72381fce216d39d6cc0f4b70900ae6795c936 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 17 Oct 2024 13:12:14 +1100 Subject: [PATCH 6/8] Fix datepicker infinite loop The new default dates were not aligned with the assumption that the datepicker would open on the current date. The datepicker helper would try to navigate to the previous month or next month in relation to the reference date. Now with the wrong reference date, it would infinitely go into the past or future, not finding the right year and month. I chose a more robust approach of setting the year and month directly which the user can do as well. Then we don't need a reference date. --- spec/support/features/datepicker_helper.rb | 47 +++++++--------------- 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/spec/support/features/datepicker_helper.rb b/spec/support/features/datepicker_helper.rb index 03758c7c34..7222fa3c0e 100644 --- a/spec/support/features/datepicker_helper.rb +++ b/spec/support/features/datepicker_helper.rb @@ -12,13 +12,22 @@ module Features # Once the datepicker is open, # it simply consist to select the 'from' date and then the 'to' date select_date_from_datepicker(from) - select_date_from_datepicker(to, from) + select_date_from_datepicker(to) end - def select_date_from_datepicker(date, reference_date = Time.zone.today) - navigate_datepicker_to_month(date, reference_date) - find('.flatpickr-calendar.open .flatpickr-days .flatpickr-day:not(.prevMonthDay)', - text: date.strftime("%e").to_s.strip, exact_text: true, match: :first).click + def select_date_from_datepicker(date) + within ".flatpickr-calendar.open" do + # Unfortunately, flatpickr doesn't notice a change of year when we do + # + # fill_in "Year", with: date.year + # + # A working alternative is: + find(".cur-year").send_keys(date.year.to_s) + select date.strftime("%B"), from: "Month" + + aria_date = date.strftime("%B %-d, %Y") + find("[aria-label='#{aria_date}']").click + end end def select_datetime_from_datepicker(datetime) @@ -29,34 +38,6 @@ module Features find(".flatpickr-calendar.open .flatpickr-minute").set datetime.strftime("%M").to_s.strip end - def navigate_datepicker_to_month(date, reference_date) - month_and_year = date.strftime("%-m %Y") - - until datepicker_month_and_year == month_and_year.upcase - if date < reference_date - navigate_datepicker_to_previous_month - elsif date > reference_date - navigate_datepicker_to_next_month - end - end - end - - def navigate_datepicker_to_previous_month - find('.flatpickr-calendar.open .flatpickr-months .flatpickr-prev-month').click - end - - def navigate_datepicker_to_next_month - find('.flatpickr-calendar.open .flatpickr-months .flatpickr-next-month').click - end - - def datepicker_month_and_year - month = find(".flatpickr-calendar.open .flatpickr-current-month " \ - "select.flatpickr-monthDropdown-months").value.to_i + 1 - year = find(".flatpickr-calendar.open .flatpickr-current-month " \ - ".numInputWrapper .cur-year").value - "#{month} #{year}" - end - def pick_datetime(calendar_selector, datetime_selector) find(calendar_selector).click select_datetime_from_datepicker datetime_selector From 2b8487cc6df7ee1b5d4e36beadcf6b9b97d20100 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 17 Oct 2024 14:15:23 +1100 Subject: [PATCH 7/8] Parse given datetime for reports properly --- app/helpers/reports_helper.rb | 5 +++++ app/views/admin/reports/_date_range_form.html.haml | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/helpers/reports_helper.rb b/app/helpers/reports_helper.rb index 1f9bf91ed7..e8c38f0b73 100644 --- a/app/helpers/reports_helper.rb +++ b/app/helpers/reports_helper.rb @@ -58,4 +58,9 @@ module ReportsHelper .where(order_id: orders.map(&:id)) .pluck(:originator_id) end + + def datepicker_time(datetime) + datetime = Time.zone.parse(datetime) if datetime.is_a? String + datetime.strftime('%Y-%m-%d %H:%M') + end end diff --git a/app/views/admin/reports/_date_range_form.html.haml b/app/views/admin/reports/_date_range_form.html.haml index 763047bdc8..c8ffae0a4d 100644 --- a/app/views/admin/reports/_date_range_form.html.haml +++ b/app/views/admin/reports/_date_range_form.html.haml @@ -4,8 +4,8 @@ - start_field = "#{field}_gt" - end_field = "#{field}_lt" - query = params[:q].to_h -- start_date ||= query[start_field].presence || 3.months.ago.beginning_of_day.strftime('%Y-%m-%d %H:%M') -- end_date ||= query[end_field].presence || Time.zone.tomorrow.beginning_of_day.strftime('%Y-%m-%d %H:%M') +- start_date = datepicker_time(query[start_field].presence || 3.months.ago.beginning_of_day) +- end_date = datepicker_time(query[end_field].presence || Time.zone.tomorrow.beginning_of_day) .row.date-range-filter .alpha.two.columns= label_tag nil, t(:date_range) From 6c431d405256ea3696a24aba4b848a1045f4be18 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 17 Oct 2024 15:01:21 +1100 Subject: [PATCH 8/8] Fixup specs to use the new datepicker tools --- spec/support/features/datepicker_helper.rb | 6 ++++ spec/system/admin/order_cycles/edit_spec.rb | 35 ++++++--------------- spec/system/admin/order_cycles/list_spec.rb | 22 ++++--------- 3 files changed, 22 insertions(+), 41 deletions(-) diff --git a/spec/support/features/datepicker_helper.rb b/spec/support/features/datepicker_helper.rb index 7222fa3c0e..74444316a5 100644 --- a/spec/support/features/datepicker_helper.rb +++ b/spec/support/features/datepicker_helper.rb @@ -43,5 +43,11 @@ module Features select_datetime_from_datepicker datetime_selector find("body").send_keys(:escape) end + + def close_datepicker + within(".flatpickr-calendar.open") do + click_button "Close" + end + end end end diff --git a/spec/system/admin/order_cycles/edit_spec.rb b/spec/system/admin/order_cycles/edit_spec.rb index adb91dee0e..f6223edfad 100644 --- a/spec/system/admin/order_cycles/edit_spec.rb +++ b/spec/system/admin/order_cycles/edit_spec.rb @@ -41,11 +41,8 @@ RSpec.describe ' # change date range field value find('#order_cycle_orders_close_at').click - within(".flatpickr-calendar.open") do - expect(page).to have_selector '.shortcut-buttons-flatpickr-buttons' - select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") - find("button", text: "Close").click - end + select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") + close_datepicker expect(page).to have_content('You have unsaved changes') # click save to open warning modal @@ -66,11 +63,8 @@ RSpec.describe ' # change date range field value find('#order_cycle_orders_close_at').click - within(".flatpickr-calendar.open") do - expect(page).to have_selector '.shortcut-buttons-flatpickr-buttons' - select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") - find("button", text: "Close").click - end + select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") + close_datepicker # click save to open warning modal click_button('Save') @@ -102,11 +96,8 @@ RSpec.describe ' # Now change date range field value find('#order_cycle_orders_close_at').click - within(".flatpickr-calendar.open") do - expect(page).to have_selector '.shortcut-buttons-flatpickr-buttons' - select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") - find("button", text: "Close").click - end + select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") + close_datepicker expect(page).to have_content('You have unsaved changes') click_button('Save') @@ -137,11 +128,8 @@ RSpec.describe ' # change date range field value find('#order_cycle_orders_close_at').click - within(".flatpickr-calendar.open") do - expect(page).to have_selector '.shortcut-buttons-flatpickr-buttons' - select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") - find("button", text: "Close").click - end + select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") + close_datepicker expect(page).to have_content('You have unsaved changes') @@ -175,11 +163,8 @@ RSpec.describe ' # Now change date range field value find('#order_cycle_orders_close_at').click - within(".flatpickr-calendar.open") do - expect(page).to have_selector '.shortcut-buttons-flatpickr-buttons' - select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") - find("button", text: "Close").click - end + select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") + close_datepicker expect(page).to have_content('You have unsaved changes') sleep(2) diff --git a/spec/system/admin/order_cycles/list_spec.rb b/spec/system/admin/order_cycles/list_spec.rb index 0d16945a79..6e4b7fd22c 100644 --- a/spec/system/admin/order_cycles/list_spec.rb +++ b/spec/system/admin/order_cycles/list_spec.rb @@ -182,12 +182,8 @@ RSpec.describe ' find('input.datetimepicker', match: :first).click end - # Sets the value to test_value then looks for the close button and click it - within(".flatpickr-calendar.open") do - expect(page).to have_selector '.shortcut-buttons-flatpickr-buttons' - select_datetime_from_datepicker test_value - find("button", text: "Close").click - end + select_datetime_from_datepicker test_value + close_datepicker # Should no more have opened flatpickr expect(page).not_to have_selector '.flatpickr-calendar.open' @@ -213,11 +209,8 @@ RSpec.describe ' within("tr.order-cycle-#{order_cycle.id}") do find('input.datetimepicker', match: :first).click end - within(".flatpickr-calendar.open") do - expect(page).to have_selector '.shortcut-buttons-flatpickr-buttons' - select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") - find("button", text: "Close").click - end + select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") + close_datepicker expect(page).to have_content('You have unsaved changes') # click save to open warning modal @@ -237,11 +230,8 @@ RSpec.describe ' within("tr.order-cycle-#{order_cycle.id}") do find('input.datetimepicker', match: :first).click end - within(".flatpickr-calendar.open") do - expect(page).to have_selector '.shortcut-buttons-flatpickr-buttons' - select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") - find("button", text: "Close").click - end + select_datetime_from_datepicker Time.zone.parse("2024-03-30 00:00") + close_datepicker expect(page).to have_content('You have unsaved changes') click_button('Save')