Browse Source

Added excel sheet to housing page

development
Godwin 8 years ago
parent
commit
9356aa2d31
  1. 5
      Gemfile
  2. 80
      app/assets/javascripts/housing.js
  3. 76
      app/controllers/conferences_controller.rb
  4. 116
      app/helpers/application_helper.rb
  5. 3
      app/views/conferences/admin/_housing.html.haml
  6. 10
      app/views/conferences/admin/_stats.html.haml
  7. 22
      app/views/conferences/stats.xlsx.haml
  8. 2
      config/locales/en.yml

5
Gemfile

@ -42,16 +42,13 @@ gem 'geocoder'
gem 'paper_trail', '~> 3.0.5'
gem 'sitemap_generator'
gem 'activerecord-session_store'
# gem 'paypal-express', '0.7.1'
gem 'sass-json-vars'
gem 'premailer-rails'
gem 'redcarpet'
gem 'sidekiq'
gem 'letter_opener'
gem 'launchy'
# gem 'axlsx'
# gem 'excelinator'
gem 'to_spreadsheet'#, :git => 'git://github.com/glebm/to_spreadsheet.git'
gem 'to_spreadsheet', :git => 'git://github.com/glebm/to_spreadsheet.git'
group :test do
gem 'rspec'

80
app/assets/javascripts/housing.js

@ -92,84 +92,4 @@
closeGuestSelector();
}
});
function closeOnTop() {
document.documentElement.removeAttribute('data-ontop');
document.getElementById('guest_id').value = '';
var target = document.querySelector('.on-top-target');
target.removeAttribute('style');
document.querySelector('body').removeAttribute('style');
forEachElement('.on-top-control', function(control) {
control.classList.remove('on-top-control');
});
}
forEachElement('#guests .guest', function(guest) {
var button = guest.querySelector('.set-host');
button.addEventListener('click', function(event) {
var target = document.querySelector('.on-top-target');
var body = document.querySelector('body');
// maintain our current height
body.setAttribute('style', 'height: ' + body.clientHeight + 'px');
document.documentElement.setAttribute('data-ontop', 'set-host');
guest.classList.add('on-top-control');
target.setAttribute('style', 'bottom: ' + guest.clientHeight + 'px');
document.getElementById('guest_id').value = guest.dataset.id;
});
});
forEachElement('#hosts .host', function(host) {
initHost(host);
});
function initHost(host) {
forEachElement('.place-guest', function(button) {
button.addEventListener('click', function(event) {
var guest_id = document.getElementById('guest_id').value;
if (guest_id) {
var guest = document.getElementById('guest-' + guest_id);
var form = document.getElementById('hosts');
var data = new FormData(form);
host.classList.add('requesting');
if (guest.dataset.affectedHosts) {
data.append('affected-hosts', guest.dataset.affectedHosts);
forEach(guest.dataset.affectedHosts.split(','), function(host_id) {
h = document.getElementById('host-' + host_id);
if (h) {
h.classList.add('requesting');
}
});
}
data.append('button', button.value);
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = JSON.parse(request.responseText);
for (var host_id in response.hosts) {
host_element = document.getElementById('host-' + host_id);
widget = response.hosts[host_id];
host_element.className = widget.class;
host_element.querySelector('.guests').innerHTML = widget.html;
initHost(host_element);
host_element.classList.remove('requesting');
}
for (var guest_id in response.affected_hosts) {
guest_element = document.getElementById('guest-' + guest_id);
if (guest_element) {
guest_element.setAttribute('data-affected-hosts', response.affected_hosts[guest_id].join(','));
}
}
}
}
}
request.open('POST', form.getAttribute('action'), true);
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
request.send(data);
}
});
}, host);
}
forEachElement('.on-top-close', function(button) {
button.addEventListener('click', closeOnTop);
});
})();

76
app/controllers/conferences_controller.rb

@ -288,7 +288,7 @@ class ConferencesController < ApplicationController
@organizations = Organization.all
if request.format.xlsx?
logger.info "Generating stats.xls"
logger.info "Generating organizations.xls"
@excel_data = {
columns: [:name, :street_address, :city, :subregion, :country, :postal_code, :email, :phone, :status],
keys: {
@ -439,6 +439,80 @@ class ConferencesController < ApplicationController
when :housing
# do a full analysis
analyze_housing
if request.format.xlsx?
logger.info "Generating housing.xls"
@excel_data = {
columns: [:name, :phone, :street_address, :email, :availability, :considerations, :empty, :empty, :empty, :guests],
keys: {
name: 'forms.labels.generic.name',
street_address: 'forms.labels.generic.street_address',
email: 'forms.labels.generic.email',
phone: 'forms.labels.generic.phone',
availability: 'articles.conference_registration.headings.host.availability',
considerations: 'articles.conference_registration.headings.host.considerations'
},
column_types: {
name: :bold,
guests: :table
},
data: [],
}
@hosts.each do | id, host |
data = (host.housing_data || {})
host_data = {
name: host.user.name,
street_address: data['address'],
email: host.user.email,
phone: data['phone'],
availability: data['availability'].present? && data['availability'][1].present? ? view_context.date_span(data['availability'][0].to_date, data['availability'][1].to_date) : '',
considerations: (data['considerations'].map { | consideration | view_context._"articles.conference_registration.host.considerations.#{consideration}" }).join(', '),
empty: '',
guests: {
columns: [:name, :area, :email, :arrival_departure, :allergies, :food, :companion, :city],
keys: {
name: 'forms.labels.generic.name',
area: 'articles.workshops.headings.space',
email: 'forms.labels.generic.email',
arrival_departure: 'articles.admin.housing.headings.arrival_departure',
companion: 'forms.labels.generic.companion',
city: 'forms.labels.generic.city',
food: 'forms.labels.generic.food',
allergies: 'forms.labels.generic.allergies'
},
column_types: {
name: :bold
},
data: []
}
}
@housing_data[id][:guests].each do | space, space_data |
space_data.each do | guest_id, guest_data |
guest = guest_data[:guest]
if guest.present?
companion = view_context.companion(guest)
host_data[:guests][:data] << {
name: guest.user.name,
area: (view_context._"forms.labels.generic.#{space}"),
email: guest.user.email,
arrival_departure: guest.arrival.present? && guest.departure.present? ? view_context.date_span(guest.arrival.to_date, guest.departure.to_date) : '',
companion: companion.present? ? (companion.is_a?(User) ? companion.name : (view_context._"articles.conference_registration.terms.registration_status.#{companion}")) : '',
city: guest.city,
food: (view_context._"articles.conference_registration.questions.food.#{guest.food}"),
allergies: guest.allergies
}
end
end
end
@excel_data[:data] << host_data
end
return respond_to do | format |
format.xlsx { render xlsx: :stats, filename: "housing" }
end
end
when :locations
@locations = EventLocation.where(:conference_id => @this_conference.id)
when :events

116
app/helpers/application_helper.rb

@ -1529,6 +1529,122 @@ module ApplicationHelper
end
end
def excel_table(excel_data)
format_xls 'table' do
workbook use_autowidth: true
format bg_color: '333333'
format 'td', font_name: 'Calibri', fg_color: '333333'
format 'th', font_name: 'Calibri', b: true, bg_color: '333333', fg_color: 'ffffff'
format 'th.sub-table', font_name: 'Calibri', b: true, bg_color: 'DDDDDD', fg_color: '333333'
format 'td.datetime', num_fmt: 22, font_name: 'Courier New', sz: 10, fg_color: '333333'
format 'td.date.day', num_fmt: 14, font_name: 'Courier New', sz: 10, fg_color: '333333'
format 'td.money', num_fmt: 2, font_name: 'Courier New', sz: 10, fg_color: '333333'
format 'td.bold', font_name: 'Calibri', fg_color: '333333', b: true
end
key = excel_data[:key] || 'excel.columns'
content_tag(:table) do
(content_tag(:thead) do
content_tag(:tr, excel_header_columns(excel_data))
end) +
content_tag(:tbody, excel_rows(excel_data))
end
end
def excel_header_columns(data, padding = {}, class_name = nil)
columns = ''
data[:columns].each do |column|
unless data[:column_types].present? && data[:column_types][column] == :table
# columns += content_tag(:th, _(data[:keys][column].present? ? data[:keys][column] : "#{key}.#{column.to_s}"), class: class_name)
columns += content_tag(:th, data[:keys][column].present? ? _(data[:keys][column]) : '', class: class_name)
end
end
pad_columns(columns, padding, :th)
end
def excel_empty_row(data, padding = {})
columns = ''
data[:columns].each do |column|
unless data[:column_types].present? && data[:column_types][column] == :table
columns += content_tag(:td)
end
end
content_tag(:tr, pad_columns(columns, padding))
end
def pad_columns(columns, padding, column_type = :td)
left = ''
for i in 1..(padding['left'] || 0)
left += content_tag(:td)
end
right = ''
for i in 1..(padding['right'] || 0)
right += content_tag(:td)
end
(left + columns + right).html_safe
end
def excel_columns(row, data, padding = {})
columns = ''
data[:columns].each do |column|
value = row[column].present? ? (_!row[column].to_s) : ''
class_name = nil
is_sub_table = false
if data[:column_types].present? && data[:column_types][column].present?
if data[:column_types][column] == :table
is_sub_table = true
else
class_name = data[:column_types][column]
end
end
columns += content_tag(:td, value, { class: class_name }) unless is_sub_table
end
pad_columns(columns, padding)
end
def excel_sub_tables(row, data, padding = {})
rows = ''
# shift the table right
new_padding = {
'left' => (padding['right'] || 0) + 1,
'right' => (padding['right'] || 0) - 1
}
data[:columns].each do |column|
if data[:column_types].present? && data[:column_types][column] == :table
puts row[column].to_json.to_s
rows += content_tag(:tr, excel_header_columns(row[column], new_padding, 'sub-table'))
rows += excel_rows(row[column], new_padding)
rows += excel_empty_row(row[column], new_padding)
end
end
rows.html_safe
end
def excel_rows(data, padding = {})
rows = ''
data[:data].each do |row|
rows += content_tag(:tr, excel_columns(row, data, padding)) +
excel_sub_tables(row, data, padding)
end
rows.html_safe
end
private
def _original_content(value, lang)
content_tag(:div, (

3
app/views/conferences/admin/_housing.html.haml

@ -5,3 +5,6 @@
= form_tag administration_update_path(@this_conference.slug, :housing), class: 'guest-dlg', id: 'guest-list-table' do
%h3 Select a Guest
#table
.actions
= link_to (_'links.download.Excel'), administration_step_path(@this_conference.slug, :housing, :format => :xlsx), class: [:button, :download]

10
app/views/conferences/admin/_stats.html.haml

@ -4,15 +4,15 @@
= data_set(:h4, 'articles.admin.stats.headings.incomplete_registrations') do
= ((@registration_count - @completed_registrations) || 0).to_s
= data_set(:h4, 'articles.admin.stats.headings.bikes') do
= (@completed_registrations || 0) > 0 ? "#{@bikes} (#{(@bikes / @completed_registrations.to_f).round(4) * 100.0}%)" : "0"
= (@completed_registrations || 0) > 0 ? "#{@bikes} (#{number_to_percentage(@bikes / @completed_registrations.to_f * 100.0)})" : "0"
= data_set(:h4, 'articles.admin.stats.headings.food.meat') do
= (@food[:all] || 0) > 0 ? "#{@food[:meat]} (#{(@food[:meat] / @food[:all].to_f).round(4) * 100.0}%)" : "0"
= (@food[:all] || 0) > 0 ? "#{@food[:meat]} (#{number_to_percentage(@food[:meat] / @food[:all].to_f * 100.0)})" : "0"
= data_set(:h4, 'articles.admin.stats.headings.food.vegetarian') do
= (@food[:all] || 0) > 0 ? "#{@food[:vegetarian]} (#{(@food[:vegetarian] / @food[:all].to_f).round(4) * 100.0}%)" : "0"
= (@food[:all] || 0) > 0 ? "#{@food[:vegetarian]} (#{number_to_percentage(@food[:vegetarian] / @food[:all].to_f * 100.0)})" : "0"
= data_set(:h4, 'articles.admin.stats.headings.food.vegan') do
= (@food[:all] || 0) > 0 ? "#{@food[:vegan]} (#{(@food[:vegan] / @food[:all].to_f).round(4) * 100.0}%)" : "0"
= (@food[:all] || 0) > 0 ? "#{@food[:vegan]} (#{number_to_percentage(@food[:vegan] / @food[:all].to_f * 100.0)})" : "0"
= data_set(:h4, 'articles.admin.stats.headings.donation_count') do
= (@completed_registrations || 0) > 0 ? "#{@donation_count} (#{(@donation_count / @completed_registrations.to_f).round(4) * 100.0}%)" : "0"
= (@completed_registrations || 0) > 0 ? "#{@donation_count} (#{number_to_percentage(@donation_count / @completed_registrations.to_f * 100.0)})" : "0"
= data_set(:h4, 'articles.admin.stats.headings.donation_total') do
= "$#{@donations || 0.00}"
.actions

22
app/views/conferences/stats.xlsx.haml

@ -1,21 +1 @@
- key = @excel_data[:key] || 'excel.columns'
%table
%thead
%tr
- @excel_data[:columns].each do |column|
%th=_(@excel_data[:keys][column].present? ? @excel_data[:keys][column] : "#{key}.#{column.to_s}")
%tbody
- @excel_data[:data].each do |row|
%tr
- @excel_data[:columns].each do |column|
%td{class: (@excel_data[:column_types].present? && @excel_data[:column_types][column].present?) ? @excel_data[:column_types][column] : nil}=(row[column].present? ? (_!row[column]) : '')
- format_xls 'table' do
- workbook use_autowidth: true
- format bg_color: '333333'
- format 'td', font_name: 'Calibri', fg_color: '333333'
- format 'th', font_name: 'Calibri', b: true, bg_color: '333333', fg_color: 'ffffff'
- format 'td.datetime', num_fmt: 22, font_name: 'Courier New', sz: 10, fg_color: '333333'
- format 'td.date.day', num_fmt: 14, font_name: 'Courier New', sz: 10, fg_color: '333333'
- format 'td.money', num_fmt: 2, font_name: 'Courier New', sz: 10, fg_color: '333333'
- format 'td.bold', font_name: 'Calibri', fg_color: '333333', b: true
= excel_table(@excel_data)

2
config/locales/en.yml

@ -1264,7 +1264,7 @@ en:
subregion: State / Province
country: Country
postal_code: Postal Code
status: Status,
status: Status
bike: Bike
food: Food
housing: Housing

Loading…
Cancel
Save