parent
2e7b03e9ef
commit
2705ad1611
13 changed files with 252 additions and 68 deletions
@ -0,0 +1,38 @@ |
||||
module MemberFilter |
||||
extend ActiveSupport::Concern |
||||
|
||||
def filtered_members |
||||
members = Member.all.order(sort_params.merge(number: :asc)) |
||||
|
||||
filters = params.permit(:prefers_postal, :display_name, :email, :identification_number, status: [], category: []) |
||||
|
||||
Rails.logger.info filters |
||||
|
||||
status = filters.fetch(:status, []) - ['any', ''] |
||||
category = filters.fetch(:category, []) - ['any', ''] |
||||
|
||||
members = members.where(prefers_postal: true) if filters[:prefers_postal] == 'yes' |
||||
members = members.where(prefers_postal: false) if filters[:prefers_postal] == 'no' |
||||
members = members.where(status: status) if status != [] |
||||
members = members.where(category: category) if category != [] |
||||
|
||||
members.ransack( |
||||
display_name_i_cont: filters[:display_name], |
||||
email_i_cont: filters[:email], |
||||
identification_number_i_cont: filters[:identification_number], |
||||
).result |
||||
end |
||||
|
||||
def sort_params |
||||
field, direction = params.fetch(:sort, "").split(".") |
||||
|
||||
directions = %w[ asc desc ] |
||||
fields = %w[ number expires_on joined_on email status display_name ] |
||||
|
||||
if directions.include?(direction) && fields.include?(field) |
||||
{ field => direction } |
||||
else |
||||
{ number: :asc } |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,14 @@ |
||||
class LettersController < ApplicationController |
||||
before_action :require_login |
||||
|
||||
include MemberFilter |
||||
|
||||
# POST /letters |
||||
def create |
||||
members = filtered_members |
||||
|
||||
pdf = Letters.generate(params[:template], members) |
||||
|
||||
send_data pdf, filename: "members.pdf", type: "application/pdf" |
||||
end |
||||
end |
@ -0,0 +1,19 @@ |
||||
class NotificationsController < ApplicationController |
||||
before_action :require_login |
||||
before_action :set_notification |
||||
|
||||
# POST /notifications/1/deliver |
||||
def deliver |
||||
@notification.deliver! |
||||
|
||||
redirect_to @notification.member |
||||
end |
||||
|
||||
private |
||||
# Use callbacks to share common setup or constraints between actions. |
||||
def set_notification |
||||
@notification = Notification.find(params[:id]) |
||||
end |
||||
end |
||||
|
||||
|
@ -0,0 +1,68 @@ |
||||
require 'zip' |
||||
require 'nokogiri' |
||||
require 'combine_pdf' |
||||
|
||||
module Letters |
||||
def self.apply_template(io, params) |
||||
Zip::OutputStream.write_buffer do |out| |
||||
Zip::File.open(io) do |zip| |
||||
zip.each do |entry| |
||||
pp entry.name |
||||
out.put_next_entry(entry.name) |
||||
if entry.name == "content.xml" |
||||
out.write apply_template_xml(entry.get_input_stream.read, params) |
||||
elsif !entry.directory? |
||||
out.write entry.get_input_stream.read |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
def self.apply_template_xml(xml, params) |
||||
doc = Nokogiri::XML(xml) |
||||
|
||||
doc.xpath("//*[contains(text(), 'DISPLAY_NAME')]").each do |node| |
||||
node.content = node.content.gsub("DISPLAY_NAME", params["DISPLAY_NAME"]) |
||||
end |
||||
|
||||
address_lines = params['ADDRESS'].split("\n") |
||||
doc.xpath("//*[contains(text(), 'ADDRESS')]").each do |node| |
||||
newnodes = [node] + address_lines[1..].map do |line| |
||||
node.clone.tap do |c| |
||||
c.content = c.content.gsub("ADDRESS", line) |
||||
end |
||||
end |
||||
node.content = node.content.gsub("ADDRESS", address_lines.first) |
||||
|
||||
newnodes.each_cons(2) do |p, n| |
||||
p.add_next_sibling(n) |
||||
end |
||||
end |
||||
|
||||
doc.to_xml(save_with: 0) |
||||
end |
||||
|
||||
def self.generate(template, members) |
||||
Dir.mktmpdir do |directory| |
||||
members.each do |member| |
||||
odt = apply_template(template, { |
||||
"DISPLAY_NAME" => member.display_name, |
||||
"ADDRESS" => member.address, |
||||
}) |
||||
|
||||
File.open("#{directory}/#{member.number}.odt", "wb") { |out| out.write(odt.string) } |
||||
end |
||||
|
||||
`libreoffice --convert-to pdf --outdir #{directory} #{directory}/*.odt` |
||||
|
||||
pdf = CombinePDF.new |
||||
|
||||
Dir["#{directory}/*.pdf"].each do |file| |
||||
pdf << CombinePDF.load(file) |
||||
end |
||||
|
||||
pdf.to_pdf |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue