Last active
April 9, 2020 08:31
-
-
Save Pepan/00b557ef5dc17c39b8073af7d3cf71b7 to your computer and use it in GitHub Desktop.
CSV hanlder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/csv_handler.rb | |
require 'csv' | |
module CsvHandler | |
class Generator | |
def self.perform | |
file = CSV.generate do |csv| | |
yield csv | |
end | |
file.html_safe | |
end | |
end | |
class Handler | |
def self.call (template) | |
%{ | |
CsvHandler::Generator.perform do |csv| | |
#{template.source} | |
end | |
} | |
end | |
end | |
end | |
# config/initializers/csv_handler.rb | |
ActionView::Template.register_template_handler :cbld, CsvHandler::Handler | |
# app/services/export/timesheet_details_service.rb | |
module Export | |
class TimesheetDetailsService | |
attr_reader :object, :time_range | |
def initialize(params) | |
@object = object_from params | |
@time_range = time_range_from params | |
end | |
def perform | |
@object.project_times.meaningful.where(day: @time_range).order(:day, :created_at) | |
end | |
private | |
def object_from(params) | |
Person.find params[:person_id] | |
rescue ActiveRecord::RecordNotFound | |
Project.find params[:project_id] | |
end | |
def time_range_from(params) | |
case params[:timeframe] | |
when 'Custom Range' | |
(params[:start_date].to_date..params[:end_date].to_date) | |
when 'This Week' | |
Date.today.all_week | |
when 'Last Week' | |
Date.today.last_week.all_week | |
when "#{I18n.l Date.today, format: :month} To Date" | |
(Date.today.beginning_of_month..Date.today) | |
when 'Entire Project' | |
((@object.plans.first.start_date - 4.months)..Date.today) | |
else # previous month | |
Date.today.prev_month.all_month | |
end | |
end | |
end | |
end | |
# app/controllers/export/timesheet_details_controller.rb | |
class Export::TimesheetDetailsController < ApplicationController | |
before_action :require_company_scope | |
before_action :verify_user | |
layout 'dashboard' | |
def create | |
@timesheet_details_service = Export::TimesheetDetailsService.new timesheet_params | |
@project_times = @timesheet_details_service.perform | |
headers['Content-Disposition'] = "attachment; filename=\"#{file_name_for @timesheet_details_service}\"" | |
headers['Content-Type'] ||= 'text/csv' | |
render @timesheet_details_service.object.class.name.underscore | |
end | |
private | |
def timesheet_params | |
params.permit(:project_id, :person_id, :timeframe, :start_date, :end_date) | |
end | |
def file_name_for(service) | |
case service.object | |
when Person | |
"Timesheet Detail Export #{service.object.name} #{service.time_range.begin.strftime('%m/%d/%Y')} to #{service.time_range.end.strftime('%m/%d/%Y')}.csv" | |
when Project | |
"Timesheet Detail Export #{service.object.client.name} #{service.object.name} #{service.object.code} #{service.time_range.begin.strftime('%m/%d/%Y')} to #{service.time_range.end.strftime('%m/%d/%Y')}.csv" | |
else | |
raise StandardError::ArgumentError, service.object.class.name | |
end | |
end | |
end | |
# app/views/export/timesheet_details/person.csv.cbld | |
csv << ['Date', 'Project', 'Project Code', 'Contract Type', 'Client', 'Role', 'Status ', 'Actual Hours', 'Project Billable Rate', 'Revenue Earned', 'Notes'] | |
@project_times.each do |project_time| | |
calculated_billing_rate = project_time.person.calculated_billing_rate(project_time.project_id) | |
csv << [ | |
project_time.day, | |
project_time.project.name, | |
project_time.project.code, | |
export_contract_type(project_time.project.plans.first.try(:contract_type)), | |
project_time.project.client.name, | |
project_time.person_role.name, | |
project_time.person.status_short_display, | |
(project_time.minutes / 60.0).round(2), | |
calculated_billing_rate.to_i, | |
((project_time.minutes / 60.0) * calculated_billing_rate.to_f).round(0), | |
project_time.notes | |
] | |
end | |
# app/views/export/timesheet_details/project.csv.cbld | |
csv << ['Date', 'Project Code', 'Person', 'Person ID', 'Role', 'Status', 'Tracked Time ', 'Project Billable Rate', 'Revenue Earned', 'Notes'] | |
@project_times.each do |project_time| | |
calculated_billing_rate = project_time.person.calculated_billing_rate(project_time.project_id) | |
csv << [ | |
project_time.day, | |
project_time.project.code, | |
project_time.person.name, | |
project_time.person_id, | |
project_time.project.person_roles(project_time.person_id).map(&:name).join(', '), | |
project_time.person.status_short_display, | |
(project_time.minutes / 60.0).round(2), | |
calculated_billing_rate.to_i, | |
((project_time.minutes / 60.0) * calculated_billing_rate.to_f).round(0), | |
project_time.notes | |
] | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment