Skip to content

Commit

Permalink
Merge pull request #5593 from elasticspoon/filtered-reports-generation
Browse files Browse the repository at this point in the history
Filtered reports generation
  • Loading branch information
compwron authored Apr 15, 2024
2 parents b69071d + b449a47 commit f310e88
Show file tree
Hide file tree
Showing 23 changed files with 561 additions and 260 deletions.
6 changes: 6 additions & 0 deletions app/assets/stylesheets/base/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ $red: #dc3545;
$sidebar-inactive: #9AA4CA;
$sidebar-active: #365CF5;
$sidebar-dark: #1A2142;

:root {
--dark: #262d3f;
--gray: #5d657b;
--silver: #D9D9D9;
}
49 changes: 49 additions & 0 deletions app/assets/stylesheets/pages/casa_cases.scss
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,52 @@ body.casa_cases-show {
display: block;
}
}

#generate-docx-report-modal {
.dates-container {
display: flex;
}

.docx-report__modal-body {
display: flex;
flex-direction: column;
row-gap: 1rem;

}

.modal-footer {
[data-bs-dismiss="modal"] {
padding-block: 11px;
}
}
}

.generate-report-button {
display: flex;
flex-direction: row;
width: 100%;
border: solid 1px var(--silver);
padding: 1.2rem;
column-gap: 1.2rem;

&:hover {
border-color: black;
}

svg {
min-inline-size: 40px;
width: 40px;
height: auto;
}

div {
text-align: left;
h3 {
margin-block-end: .25rem;

}
p {

}
}
}
Empty file.
5 changes: 5 additions & 0 deletions app/assets/stylesheets/shared/typography.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// TODO check in css so tests can run without internet
@use "../base/variables.scss" as globals;
@import url(https://fonts.googleapis.com/css?family=Montserrat:400,700);

body {
Expand All @@ -13,12 +14,16 @@ option {
font-family: Inter;
font-size: 16px;
font-weight: 500;
line-height: 19px;
color: var(--dark);
}

.content-2 {
font-family: Inter;
font-size: 14px;
font-weight: 500;
line-height: 22px;
color: var(--gray)
}

.content-3 {
Expand Down
2 changes: 1 addition & 1 deletion app/components/modal/footer_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="modal-footer <%= @class %>">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Close</button>
<%= content %>
</div>
2 changes: 1 addition & 1 deletion app/components/modal/open_button_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<button type="button" class="btn <%= @class %>" data-bs-toggle="modal" data-bs-target="<%= "##{@target}" %>">
<button type="button" class="<%= @class %>" data-bs-toggle="modal" data-bs-target="<%= "##{@target}" %>">
<% if @icon %>
<i class="lni mr-10 lni-<%= @icon %>"></i>
<% end %>
Expand Down
15 changes: 11 additions & 4 deletions app/controllers/case_court_reports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ def show

def generate
authorize CaseCourtReport
casa_case = CasaCase.find_by(case_params)
casa_case = CasaCase.find_by(case_number: case_params[:case_number])

respond_to do |format|
format.json do
if casa_case
report_data = generate_report_to_string(casa_case, params[:time_zone])
report_data = generate_report_to_string(casa_case, date_range_params)
save_report(report_data, casa_case)

render json: {link: case_court_report_path(casa_case.case_number, format: "docx"), status: :ok}
Expand All @@ -53,6 +54,10 @@ def generate

private

def date_range_params
params.permit(:time_zone, case_court_report: %i[start_date end_date])
end

def case_params
params.require(:case_court_report).permit(:case_number)
end
Expand All @@ -69,15 +74,17 @@ def assigned_cases
end
end

def generate_report_to_string(casa_case, time_zone)
def generate_report_to_string(casa_case, time_range)
return unless casa_case

casa_case.casa_org.open_org_court_report_template do |template_docx_file|
args = {
volunteer_id: current_user.volunteer? ? current_user.id : casa_case.assigned_volunteers.first&.id,
case_id: casa_case.id,
path_to_template: template_docx_file.to_path,
time_zone: time_zone
time_zone: time_range[:time_zone],
start_date: time_range[:case_court_report][:start_date],
end_date: time_range[:case_court_report][:end_date]
}
context = CaseCourtReportContext.new(args).context
court_report = CaseCourtReport.new(path_to_template: template_docx_file.to_path, context: context)
Expand Down
6 changes: 6 additions & 0 deletions app/javascript/src/casa_case.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,24 @@ function copyOrdersFromCaseAction (id, caseNumber) {
}

function showBtn (el) {
if (!el) return
el.classList.remove('d-none')
}

function hideBtn (el) {
if (!el) return
el.classList.add('d-none')
}

function disableBtn (el) {
if (!el) return
el.disabled = true
el.classList.add('disabled')
el.setAttribute('aria-disabled', true)
}

function enableBtn (el) {
if (!el) return
el.disabled = false
el.classList.remove('disabled')
el.removeAttribute('aria-disabled')
Expand Down Expand Up @@ -101,6 +105,7 @@ function handleGenerateReport (e) {
body: JSON.stringify(formData)
}
showBtn(spinner)
hideBtn($('#btnGenerateReport .lni-download')[0])
window.fetch(url, options)
.then(response => {
return response.json()
Expand All @@ -113,6 +118,7 @@ function handleGenerateReport (e) {
return
}
hideBtn(spinner)
showBtn($('#btnGenerateReport .lni-download')[0])
enableBtn(generateBtn)
window.open(data.link, '_blank')
})
Expand Down
6 changes: 6 additions & 0 deletions app/models/casa_case.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ def most_recent_past_court_date
court_dates.where("date < ?", Date.today).order(:date).last
end

def formatted_latest_court_date
most_recent = most_recent_past_court_date&.date&.in_time_zone || Time.zone.now

most_recent.strftime(::DateHelper::RUBY_MONTH_DAY_YEAR_FORMAT)
end

def has_judge_name?
judge_name
end
Expand Down
31 changes: 21 additions & 10 deletions app/models/case_court_report_context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require "date"

class CaseCourtReportContext
attr_reader :report_path, :template
attr_reader :report_path, :template, :date_range

def initialize(args = {})
@casa_case = CasaCase.friendly.find(args[:case_id])
Expand All @@ -12,6 +12,7 @@ def initialize(args = {})
@path_to_template = args[:path_to_template]
@court_date = args[:court_date] || @casa_case.next_court_date
@case_court_orders = args[:case_court_orders] || @casa_case.case_court_orders
@date_range = calculate_date_range(args)
end

def context
Expand All @@ -35,8 +36,7 @@ def context
# - :dates [Array<String>]
# - :dates_by_medium_type [Array<String>]
def case_contacts
cccts = CaseContactContactType.includes(:case_contact, :contact_type).where("case_contacts.casa_case_id": @casa_case.id)
interviewees = filter_out_old_case_contacts(cccts)
interviewees = filtered_interviewees
return [] unless interviewees.size.positive?

CaseContactsContactDates.new(interviewees).contact_dates_details
Expand All @@ -56,13 +56,11 @@ def case_orders(orders)
end
end

def filter_out_old_case_contacts(interviewees)
most_recent_court_date = @casa_case.most_recent_past_court_date&.date
if most_recent_court_date
interviewees.where("occurred_at >= ?", most_recent_court_date)
else
interviewees
end
def filtered_interviewees
CaseContactContactType
.joins(:contact_type, case_contact: :casa_case)
.where("case_contacts.casa_case_id": @casa_case.id)
.where("case_contacts.occurred_at": @date_range)
end

def case_details
Expand All @@ -89,4 +87,17 @@ def org_address(path_to_template)
is_default_template = path_to_template.end_with?("default_report_template.docx")
@volunteer.casa_org.address if @volunteer && is_default_template
end

private

def calculate_date_range(args)
zone = args[:time_zone] ? ActiveSupport::TimeZone.new(args[:time_zone]) : Time.zone

start_date = @casa_case.most_recent_past_court_date&.date&.in_time_zone(zone)
start_date = zone.parse(args[:start_date]) if args[:start_date]&.present?

end_date = args[:end_date]&.present? ? zone.parse(args[:end_date]) : nil

start_date..end_date
end
end
56 changes: 56 additions & 0 deletions app/views/casa_cases/_generate_report_modal.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<%= form_with url: generate_case_court_reports_path, local: false do |form| %>
<% id = "generate-docx-report-modal" %>
<%= render(Modal::OpenButtonComponent.new(
target: id,
klass: "d-inline main-btn btn-hover btn-sm success-btn pull-right mb-2")) do %>
Generate Report
<% end %>
<%= render(Modal::GroupComponent.new(id: id)) do |component| %>
<% component.with_header(text: "Download Court Report as a .docx", id: id, klass: "content-1") %>
<% component.with_body do %>
<div class="docx-report__modal-body">
<p class="content-3 md-10">
To download a court report specify the date range.
</p>
<div class="input-style-1" id="case_select_body">
<%= form.hidden_field :case_number, value: @casa_case.case_number %>
<%= form.hidden_field :time_zone, id: "user-time-zone" %>
<h4 class="mb-10">Casa Case:</h4>
<p><%= @casa_case.decorate.court_report_select_option.first %></p>
</div>
<div class="dates-container">
<div class="field form-group mb-20">
<h6><label class="form-label" for="start_date">Starting From</label></h6>
<%= form.text_field :start_date,
value: @casa_case.formatted_latest_court_date,
data: { provide: "datepicker",
date_format: ::DateHelper::JQUERY_MONTH_DAY_YEAR_FORMAT },
class: "form-control" %>
</div>

<div class="field form-group mb-20">
<h6><label class="form-label" for="end_date">Ending At</label></h6>
<%= form.text_field :end_date,
value: Time.zone.now.strftime(::DateHelper::RUBY_MONTH_DAY_YEAR_FORMAT),
data: { provide: "datepicker",
date_format: ::DateHelper::JQUERY_MONTH_DAY_YEAR_FORMAT },
class: "form-control" %>
</div>
</div>
</div>
<% end %>
<% component.with_footer do %>
<%= button_tag type: :submit,
data: {
button_name: "Generate Report"
},
id: "btnGenerateReport",
class: "main-btn primary-btn btn-hover btn-sm",
onclick: "setTimeZone()" do %>
<i class="lni lni-download mr-10"></i>
<i id="spinner" class='fas fa-spin d-none mr-10'></i>
Generate Report
<% end %>
<% end %>
<% end %>
<% end %>
44 changes: 36 additions & 8 deletions app/views/casa_cases/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,7 @@
margin: false) %>
<% end %>
<% end %>
<%= form_with url: generate_case_court_reports_path, local: false, class: "d-inline" do |form| %>
<%= form.hidden_field :case_number, value: @casa_case.case_number %>
<%= button_tag "Generate Report", type: :submit,
data: {button_name: "Generate Report"},
id: "btnGenerateReport",
class: "main-btn success-btn btn-hover btn-sm pull-right mb-2" %>
<i id="spinner" class='fas fa-spin d-none pull-right'></i>
<% end %>
<%= render "casa_cases/generate_report_modal" %>
<% if @casa_case.casa_org.show_fund_request %>
<%= link_to("New Fund Request", new_casa_case_fund_request_path(@casa_case),
class: "btn btn-primary pull-left casa-case-button") %>
Expand Down Expand Up @@ -158,4 +151,39 @@ class: "btn btn-primary pull-left casa-case-button") %>
window.localStorage.removeItem('casa-contact-form')
}
});
const ELEMENTS = {
'caseSelect': '#case-selection',
'generateBtn': '#btnGenerateReport',
}
const showBtn = el => el.classList.remove('d-none')
const enableBtn = (el) => {
el.disabled = false
el.classList.remove('disabled')
el.removeAttribute('aria-disabled')
}

const handleSelect = (e) => {
const selectEl = e.target
const generateBtn = selectEl.form.querySelector(ELEMENTS.generateBtn)

// when selecting a case, reset buttons to initial state
enableBtn(generateBtn)
showBtn(generateBtn)
}

const bindElements = () => {
const caseSelectEl = document.querySelector(ELEMENTS.caseSelect)

if (caseSelectEl)
caseSelectEl.addEventListener('change', handleSelect)
}

const setTimeZone = () => {
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
document.getElementById("user-time-zone").value = timeZone
}

window.onload = function () {
bindElements()
}
</script>
Loading

0 comments on commit f310e88

Please sign in to comment.