Skip to content

Commit

Permalink
feat: a detailed csv of the organization is now available for downloa…
Browse files Browse the repository at this point in the history
…ding

A single CSV to allow easy linking. 3 attributes have also been removed from the other reports. Issue #596.
  • Loading branch information
franpb14 committed May 22, 2021
1 parent 059bbcb commit 79ac2f4
Show file tree
Hide file tree
Showing 12 changed files with 214 additions and 15 deletions.
8 changes: 7 additions & 1 deletion app/controllers/reports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@ def transfer_list
report_responder('Transfer', current_organization, @transfers)
end

def download_csv_detailed
download_report("Csv::Detailed", current_organization)
end

def download_all
filename = "#{current_organization.name.parameterize}_#{Date.today}.zip"
temp_file = Tempfile.new(filename)

begin
Zip::File.open(temp_file.path, Zip::File::CREATE) do |zipfile|
%w(Member Transfer Inquiry Offer).each do |report_class|
%w(Member Transfer Inquiry Offer Detailed).each do |report_class|
add_csv_to_zip(report_class, zipfile)
end
end
Expand Down Expand Up @@ -85,6 +89,8 @@ def add_csv_to_zip(report_class, zip)

report = if report_class.in? %w(Inquiry Offer)
get_report("Csv::Post", current_organization, collection, report_class.constantize)
elsif report_class == "Detailed"
get_report("Csv::#{report_class}", current_organization)
else
get_report("Csv::#{report_class}", current_organization, collection)
end
Expand Down
135 changes: 135 additions & 0 deletions app/decorators/report/detailed_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
class Report::DetailedDecorator
include TransfersHelper

def initialize(org)
@org = org
end

def name(extension)
"#{@org.name.parameterize}_"\
"#{Date.today}."\
"#{I18n.t('global.detailed')}_"\
".#{extension}"
end

def headers
["#{@org.name} #{I18n.t('global.detailed')}"]
end

def rows
make_table(Organization, organization_header, organization_row) +
make_table(User, member_headers, member_rows) +
make_table(Account, account_headers, account_rows) +
make_table(Post, post_headers, post_rows) +
make_table(Transfer, transfer_headers, transfer_rows)
end

private

def organization_header
make_headers(Organization, %w[reg_number_seq])
end

def organization_row
make_rows(Organization, %w[reg_number_seq], [@org])
end

def member_headers
excluded_users = %w[id encrypted_password reset_password_token reset_password_token
reset_password_sent_at current_sign_in_ip last_sign_in_ip confirmation_token
remember_created_at unconfirmed_email unlock_token locked_at notifications
push_notifications created_at updated_at active]
excluded_members = %w[user_id organization_id member_uid]

make_headers(Member, excluded_members) +
make_headers(User, excluded_users)
end

def member_rows
excluded_users = %w[id encrypted_password reset_password_token reset_password_token
reset_password_sent_at current_sign_in_ip last_sign_in_ip confirmation_token
remember_created_at unconfirmed_email unlock_token locked_at notifications
push_notifications created_at updated_at active]
user_rows = make_rows(User, excluded_users, @org.users)
@org.members.each_with_index.map do |member, ix|
[member.member_uid,
member.manager,
member.created_at,
member.updated_at,
member.entry_date,
member.active,
member.tag_list.to_s] + user_rows[ix]
end
end

def account_headers
make_headers(Account, %w[max_allowed_balance min_allowed_balance updated_at organization_id])
end

def account_rows
make_rows(Account, %w[max_allowed_balance min_allowed_balance updated_at organization_id],
Account.where(organization: @org))
end

def post_headers
make_headers(Post, %w[tsv])
end

def post_rows
make_rows(Post, %w[tsv], @org.posts.map)
end

def transfer_headers
headers = []
excluded = %w[operator_id updated_at created_at]
Transfer.columns.each { |col| headers << col.name if !excluded.include?(col.name) }
headers + [
I18n.t('statistics.all_transfers.from'),
"#{I18n.t('statistics.all_transfers.from')}_#{I18n.t('statistics.all_transfers.type')}",
I18n.t('statistics.all_transfers.to'),
"#{I18n.t('statistics.all_transfers.to')}_#{I18n.t('statistics.all_transfers.type')}",
I18n.t('statistics.all_transfers.quantity'),
I18n.t('statistics.all_transfers.date')
]
end

def transfer_rows
@org.all_transfers_with_accounts.map do |transfer|
[transfer.id,
transfer.post_id,
transfer.reason,
accounts_from_movements_id(transfer),
transfer.movements.first.amount.abs,
transfer.created_at.to_s].flatten
end
end

def make_table(table, header, rows)
[[table.model_name.human]] + [header] + rows
end

def make_headers(table, excluded)
table.columns.map { |col| table.human_attribute_name(col.name) if !excluded.include?(col.name) }.
grep(String)
end

def make_rows(table, excluded, collection)
collection.map do |single|
table.columns.map do |col|
get_value_column(col.name, single, excluded)
end.grep(String)
end
end

def get_value_column(col_name, single, excluded)
if col_name == 'tags'
single.tag_list.to_s
elsif col_name == 'accountable_id' && single.accountable_type == 'Member'
single.accountable.member_uid.to_s
elsif col_name == 'category_id'
single.category.to_s
elsif !excluded.include?(col_name)
single[col_name].to_s.truncate(60)
end
end
end
8 changes: 2 additions & 6 deletions app/decorators/report/member_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ def headers
User.human_attribute_name(:phone),
User.human_attribute_name(:alt_phone),
User.human_attribute_name(:created_at),
User.human_attribute_name(:last_sign_in_at),
User.human_attribute_name(:locale),
Account.human_attribute_name(:balance)
User.human_attribute_name(:last_sign_in_at)
]
end

Expand All @@ -34,9 +32,7 @@ def rows
member.user.phone,
member.user.alt_phone,
member.user.created_at.to_s,
member.user.last_sign_in_at.to_s,
member.user.locale,
member.account_balance.to_s
member.user.last_sign_in_at.to_s
]
end
end
Expand Down
2 changes: 0 additions & 2 deletions app/decorators/report/post_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ def name(extension)

def headers
[
"",
@type.model_name.human,
Post.human_attribute_name(:tag_list),
User.model_name.human,
Expand All @@ -30,7 +29,6 @@ def rows

posts.each do |post|
grouped_rows << [
post.id,
post.title,
post.tag_list.to_s,
"#{post.user} (#{post.member_uid})",
Expand Down
16 changes: 16 additions & 0 deletions app/helpers/transfers_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,20 @@ def accounts_from_movements(transfer, with_links: false)
end
end
end

def accounts_from_movements_id(transfer)
transfer.movements.sort_by(&:amount).map do |movement|
account = movement.account

if account.accountable.blank?
I18n.t('users.show.deleted_user')
elsif account.accountable_type == 'Organization'
[account.accountable.id, account.accountable_type]
elsif account.accountable.active
[account.accountable.member_uid, account.accountable_type]
else
I18n.t('users.show.inactive_user')
end
end
end
end
9 changes: 9 additions & 0 deletions app/services/report/csv/detailed.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Report
module Csv
class Detailed < Base
def initialize(org)
self.decorator = Report::DetailedDecorator.new(org)
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
<% end %>
</li>
<li class="divider" role="presentation"></li>
<li>
<%= link_to download_csv_detailed_report_path do %>
<%= glyph :download %>
<%= "CSV #{t 'global.detailed' }" %>
<% end %>
</li>
<li>
<%= link_to download_all_report_path do %>
<%= glyph :download %>
Expand Down
2 changes: 0 additions & 2 deletions app/views/reports/post_list.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<table class="table table-condensed table-bordered">
<thead>
<tr>
<th></th>
<th><%= @post_type.model_name.human %></th>
<th><%= Post.human_attribute_name :tag_list %></th>
<th><%= User.model_name.human %></th>
Expand All @@ -16,7 +15,6 @@
</tr>
<% ps.each do |post| %>
<tr>
<td><%= post.id %></td>
<td><strong><%= post.title %></strong></td>
<td><%= post.tag_list %></td>
<td><%= "#{post.user} (#{post.member_uid})" %></td>
Expand Down
4 changes: 0 additions & 4 deletions app/views/reports/user_list.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
<th><%= User.human_attribute_name :alt_phone %></th>
<th><%= User.human_attribute_name :created_at %></th>
<th><%= User.human_attribute_name :last_sign_in_at %></th>
<th><%= User.human_attribute_name :locale %></th>
<th><%= Account.human_attribute_name :balance %></th>
</tr>
</thead>
<tbody>
Expand All @@ -23,8 +21,6 @@
<td><%= member.user.alt_phone %></td>
<td><%= l(member.user.created_at, format: :long) %></td>
<td><%= l(member.user.last_sign_in_at, format: :long) if member.user.last_sign_in_at.present? %></td>
<td><%= member.user.locale %></td>
<td><%= member.account_balance %></td>
</tr>
<% end %>
</tbody>
Expand Down
2 changes: 2 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ en:
date: Data
delete: Delete
demote: Demote to normal user
detailed: detailed
edit: Update
enter_to_timebank: Enter to timebank
filter: Filter
Expand Down Expand Up @@ -450,6 +451,7 @@ en:
reason: Reason
to: To
transfers: All transfers
type: type
demographics:
by_ages: By ages
by_gender: By gender
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
get "offer_list" => :post_list, type: "offer"
get "inquiry_list" => :post_list, type: "inquiry"
get "transfer_list"
get "download_csv_detailed"
get "download_all"
end
end
Expand Down
36 changes: 36 additions & 0 deletions spec/decorators/report/detailed_decorator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
RSpec.describe Report::DetailedDecorator do
let (:member) { Fabricate(:member) }
let (:org) { member.organization }
let (:decorator) do
Report::DetailedDecorator.new(org)
end
let (:category) { Fabricate(:category) }
let (:transfer) { Fabricate(:transfer, source: org.account, destination: member.account) }
let! (:offer) do
Fabricate(:offer,
user: member.user,
organization: org,
category: category)
end

it "#name" do
expect(decorator.name(:csv)).to eq(
"#{org.name.parameterize}_"\
"#{I18n.t('global.detailed')}_"\
"#{Date.today}."\
"csv"
)
end

it "#headers" do
expect(decorator.headers).to eq(["#{org.name} #{I18n.t('global.detailed')}"])
end

it "#rows" do
expect(decorator.rows.to_s).to include(org.name)
expect(decorator.rows.to_s).to include(transfer.reason.to_s)
expect(decorator.rows.to_s).to include(offer.title)
expect(decorator.rows.to_s).to include(member.user.username)
expect(decorator.rows.to_s).to include(category.to_s)
end
end

0 comments on commit 79ac2f4

Please sign in to comment.