Added excel sheet to housing page
This commit is contained in:
parent
2c976d40a4
commit
9356aa2d31
5
Gemfile
5
Gemfile
@ -42,16 +42,13 @@ gem 'geocoder'
|
|||||||
gem 'paper_trail', '~> 3.0.5'
|
gem 'paper_trail', '~> 3.0.5'
|
||||||
gem 'sitemap_generator'
|
gem 'sitemap_generator'
|
||||||
gem 'activerecord-session_store'
|
gem 'activerecord-session_store'
|
||||||
# gem 'paypal-express', '0.7.1'
|
|
||||||
gem 'sass-json-vars'
|
gem 'sass-json-vars'
|
||||||
gem 'premailer-rails'
|
gem 'premailer-rails'
|
||||||
gem 'redcarpet'
|
gem 'redcarpet'
|
||||||
gem 'sidekiq'
|
gem 'sidekiq'
|
||||||
gem 'letter_opener'
|
gem 'letter_opener'
|
||||||
gem 'launchy'
|
gem 'launchy'
|
||||||
# gem 'axlsx'
|
gem 'to_spreadsheet', :git => 'git://github.com/glebm/to_spreadsheet.git'
|
||||||
# gem 'excelinator'
|
|
||||||
gem 'to_spreadsheet'#, :git => 'git://github.com/glebm/to_spreadsheet.git'
|
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'rspec'
|
gem 'rspec'
|
||||||
|
@ -92,84 +92,4 @@
|
|||||||
closeGuestSelector();
|
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);
|
|
||||||
});
|
|
||||||
})();
|
})();
|
||||||
|
@ -288,7 +288,7 @@ class ConferencesController < ApplicationController
|
|||||||
@organizations = Organization.all
|
@organizations = Organization.all
|
||||||
|
|
||||||
if request.format.xlsx?
|
if request.format.xlsx?
|
||||||
logger.info "Generating stats.xls"
|
logger.info "Generating organizations.xls"
|
||||||
@excel_data = {
|
@excel_data = {
|
||||||
columns: [:name, :street_address, :city, :subregion, :country, :postal_code, :email, :phone, :status],
|
columns: [:name, :street_address, :city, :subregion, :country, :postal_code, :email, :phone, :status],
|
||||||
keys: {
|
keys: {
|
||||||
@ -439,6 +439,80 @@ class ConferencesController < ApplicationController
|
|||||||
when :housing
|
when :housing
|
||||||
# do a full analysis
|
# do a full analysis
|
||||||
analyze_housing
|
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
|
when :locations
|
||||||
@locations = EventLocation.where(:conference_id => @this_conference.id)
|
@locations = EventLocation.where(:conference_id => @this_conference.id)
|
||||||
when :events
|
when :events
|
||||||
|
@ -1529,6 +1529,122 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
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
|
private
|
||||||
def _original_content(value, lang)
|
def _original_content(value, lang)
|
||||||
content_tag(:div, (
|
content_tag(:div, (
|
||||||
|
@ -5,3 +5,6 @@
|
|||||||
= form_tag administration_update_path(@this_conference.slug, :housing), class: 'guest-dlg', id: 'guest-list-table' do
|
= form_tag administration_update_path(@this_conference.slug, :housing), class: 'guest-dlg', id: 'guest-list-table' do
|
||||||
%h3 Select a Guest
|
%h3 Select a Guest
|
||||||
#table
|
#table
|
||||||
|
.actions
|
||||||
|
= link_to (_'links.download.Excel'), administration_step_path(@this_conference.slug, :housing, :format => :xlsx), class: [:button, :download]
|
||||||
|
|
||||||
|
@ -4,15 +4,15 @@
|
|||||||
= data_set(:h4, 'articles.admin.stats.headings.incomplete_registrations') do
|
= data_set(:h4, 'articles.admin.stats.headings.incomplete_registrations') do
|
||||||
= ((@registration_count - @completed_registrations) || 0).to_s
|
= ((@registration_count - @completed_registrations) || 0).to_s
|
||||||
= data_set(:h4, 'articles.admin.stats.headings.bikes') do
|
= 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
|
= 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
|
= 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
|
= 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
|
= 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
|
= data_set(:h4, 'articles.admin.stats.headings.donation_total') do
|
||||||
= "$#{@donations || 0.00}"
|
= "$#{@donations || 0.00}"
|
||||||
.actions
|
.actions
|
||||||
|
@ -1,21 +1 @@
|
|||||||
- key = @excel_data[:key] || 'excel.columns'
|
= excel_table(@excel_data)
|
||||||
%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
|
|
||||||
|
@ -1264,7 +1264,7 @@ en:
|
|||||||
subregion: State / Province
|
subregion: State / Province
|
||||||
country: Country
|
country: Country
|
||||||
postal_code: Postal Code
|
postal_code: Postal Code
|
||||||
status: Status,
|
status: Status
|
||||||
bike: Bike
|
bike: Bike
|
||||||
food: Food
|
food: Food
|
||||||
housing: Housing
|
housing: Housing
|
||||||
|
Loading…
x
Reference in New Issue
Block a user