]> nos-oignons.net Git - gestion-adh.git/blob - lib/nos_oignons/receipt.rb
c42333fa6d32556a9f32b741225434e89578ae2f
[gestion-adh.git] / lib / nos_oignons / receipt.rb
1 #-*- coding: utf-8 -*-
2 #
3 # Système de gestion des adhésions de Nos oignons
4 # Copyright © 2013-2014 Nos oignons <contact@nos-oignons.net>
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Affero General Public License as
8 # published by the Free Software Foundation, either version 3 of the
9 # License, or (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU Affero General Public License for more details.
15 #
16 # You should have received a copy of the GNU Affero General Public License
17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19 require 'prawn'
20 require 'prawn/measurement_extensions'
21
22 module NosOignons
23   class Receipt
24     attr_reader :member, :amount
25
26     def initialize(member, amount)
27       @member = member
28       unless member.up_to_date?
29         raise ArgumentError.new("membership fee has not been paid for this year")
30       end
31       @amount = amount
32       @now = Time.now
33     end
34
35     def filename
36       dir = ENV['NOS_OIGNONS_RECEIPTS_DIR'] || 'receipts'
37       "#{dir}/receipt-#{@member.member_id}-#{@member.membership_fee_paid_on.strftime("%Y-%m-%d")}.pdf"
38     end
39
40     WINDOW_LEFT = 110.mm
41     WINDOW_TOP = 50.mm
42     WINDOW_RIGHT = 25.mm
43     WINDOW_BOTTOM = 80.mm
44     WINDOW_WIDTH = 85.mm
45     BODY_LEFT = 25.mm
46     BODY_WIDTH = 210.mm - (BODY_LEFT * 2)
47     FOOTER_HEIGHT = 25.mm
48     DARK_LOGO_COLOR = '57075f'
49     FONT_PATH = File.expand_path("../../../share/fonts/OpenSans/OpenSans.ttf", __FILE__)
50     LOGO_PATH = File.expand_path("../../../share/images/nos-oignons.jpg", __FILE__)
51
52     def generate_header(pdf)
53       header_height = pdf.bounds.height / 6
54       pdf.bounding_box([0, pdf.cursor], :width => pdf.bounds.width, :height => header_height) do
55         logo_width = 2 * pdf.bounds.width / 3
56         pdf.bounding_box([0, pdf.bounds.top], :width => logo_width, :height => pdf.bounds.height) do
57           pdf.image LOGO_PATH, :width => pdf.bounds.width, :align => :center, :vposition => :center
58         end
59         pdf.bounding_box([logo_width, pdf.bounds.top], :width => pdf.bounds.width / 3, :height => pdf.bounds.height) do
60           pdf.text 'Nœuds de sortie Tor financés par la communauté', :align => :center, :valign => :center
61         end
62       end
63       pdf.bounding_box([WINDOW_LEFT - pdf.bounds.absolute_left, pdf.bounds.absolute_top - WINDOW_TOP], :width => WINDOW_WIDTH, :height => WINDOW_BOTTOM - WINDOW_TOP) do
64         pdf.text member.name + "\n" + (member.address || ''), :valign => :bottom
65       end
66     end
67
68     def generate_body(pdf)
69       body_height = pdf.cursor - (pdf.bounds.height / 6)
70       pdf.move_down 30
71       pdf.bounding_box([BODY_LEFT, pdf.cursor], :width => BODY_WIDTH, :height => body_height) do
72         pdf.font_size(16) do
73           pdf.pad(25) do
74             pdf.text "Objet : reçu de cotisation"
75           end
76           margin = pdf.bounds.width / 6
77           pdf.pad_bottom(30) do
78             pdf.bounding_box([WINDOW_LEFT - pdf.bounds.absolute_left, pdf.cursor], :width => WINDOW_WIDTH) do
79               pdf.text "Le #{@now.strftime("%d/%m/%Y")}"
80             end
81           end
82           pdf.text <<-EOT.gsub(/^            /, '').gsub(/\n/, ' ')
83             Nous avons bien enregistré la cotisation annuelle de #{member.name}
84             à l'association Nos oignons reçue à la date du
85             #{member.membership_fee_paid_on.strftime("%d/%m/%Y")} pour un montant
86             de #{amount}€.
87           EOT
88           pdf.pad_top(30) do
89             pdf.bounding_box([margin, pdf.cursor], :width => 5 * margin) do
90               pdf.text "Le Conseil d'Administration"
91             end
92           end
93         end
94       end
95     end
96
97     def generate_footer(pdf)
98       pdf.bounding_box([0, FOOTER_HEIGHT + pdf.bounds.bottom], :width => pdf.bounds.width, :height => FOOTER_HEIGHT) do
99         pdf.pad_bottom(5) do
100           pdf.stroke_color DARK_LOGO_COLOR
101           pdf.dash 5
102           pdf.stroke_horizontal_rule
103         end
104         pdf.font_size(10) do
105           pdf.column_box([0, pdf.cursor], :width => pdf.bounds.width, :columns => 2) do
106             pdf.text NosOignons::CONTACT_INFO, :align => :center, :valign => :center
107             pdf.bounds.move_past_bottom
108             pdf.text NosOignons::POSTAL_ADDRESS, :align => :center, :valign => :center
109           end
110         end
111       end
112     end
113
114     def create!
115       raise "File exists!" if File.exists?(filename)
116       Prawn::Document.generate(filename) do |pdf|
117         pdf.font(FONT_PATH) do
118           generate_header(pdf)
119           generate_body(pdf)
120           generate_footer(pdf)
121         end
122       end
123     end
124   end
125 end