]> nos-oignons.net Git - gestion-adh.git/blob - lib/nos_oignons.rb
ee6fe7ebd2fc0a9ae8af14d6021f40f7c345f0bf
[gestion-adh.git] / lib / nos_oignons.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 'nos_oignons/git'
20 require 'nos_oignons/mailman'
21 require 'nos_oignons/member'
22 require 'nos_oignons/reminder'
23 require 'nos_oignons/reminder_db'
24
25 module NosOignons
26   BOARD_EMAIL = 'ca@nos-oignons.net'
27   ADVISORS_EMAIL = 'deontologie@nos-oignons.net'
28   MEMBER_MAILING_LIST = 'ag@nos-oignons.net'
29   CONTACT_INFO = <<-EOT.gsub(/^    /, '')
30     Identifiant SIREN 842 479 313
31     https://nos-oignons.net/
32     contact@nos-oignons.net
33     Téléphone : +33 9 72 42 96 04
34   EOT
35   POSTAL_ADDRESS = <<-EOT.gsub(/^    /, '')
36     Nos oignons
37     Centre UBIDOCA, 7585
38     78 allée Primavera
39     74370 Annecy
40     France
41   EOT
42
43   # The following class methods are all meant to be called as command-line scripts
44   class << self
45     def create_membership_fee_receipt!(member_id, amount)
46       member = NosOignons::Member.new(member_id)
47       member.create_receipt!(amount)
48     end
49
50     def list_emails!
51       NosOignons::Member.all.each do |member|
52         if member.up_to_date?
53           puts member.email
54         end
55       end
56     end
57
58     def update_ag_subscribers!
59       list = NosOignons::MEMBER_MAILING_LIST
60
61       current_members = NosOignons::Mailman.list_members(list)
62       uptodate_emails = NosOignons::Member.all.select(&:up_to_date?).collect(&:email)
63
64       # Who is not subscribed yet?
65       emails_to_add = uptodate_emails - current_members.collect(&:email)
66       emails_to_add.each do |email|
67         NosOignons::Mailman.susbcribe_email(list, email)
68       end
69
70       # Who should not be subscribed anymore?
71       current_members.each do |list_member|
72         unless uptodate_emails.include?(list_member.email)
73           list_member.unsubscribe!
74         end
75       end
76     end
77
78     def send_membership_reminders!
79       today = Time.now.to_date
80       reminders = NosOignons::Reminder.all.sort_by(&:days)
81       NosOignons::Member.all.select(&:up_to_date?).each do |member|
82         next if member.membership_fee_paid_on.year == (today + reminders.last.days).year
83         anniversary = Time.new(today.next_month.year, member.joined_on.month,
84                                member.joined_on.day).to_date
85         next if member.membership_fee_paid_on >= anniversary - reminders.last.days
86         reminders.each do |reminder|
87           next if (anniversary - today).to_i > reminder.days
88           next if member.reminded_on && (anniversary - member.reminded_on).to_i <= reminder.days
89
90           member.remind(reminder)
91           break
92         end
93       end
94     end
95
96     def send_member_emails_to_advisors!
97       uptodate_emails = NosOignons::Member.all.select(&:up_to_date?).collect(&:email)
98       subject = 'Adresses email des membres à jour de cotisation'
99       body = <<-END_OF_BODY.gsub(/^        /, '')
100         Cher comité de déontologie de Nos oignons,
101
102         Comme le prévoient les statuts l'article 12 des statuts de
103         l'association, vous devez être en mesure de pouvoir convoquer une
104         assemblée générale extraordinaire. Pour ce faire, voici donc la liste
105         des emails à jour de cotisation à la date d'aujourd'hui :
106
107         #{uptodate_emails.join("\n")}
108
109         Et merci encore de votre engagement auprès de Nos oignons !
110
111         -- 
112         Le robot du conseil d'administration
113
114                               GNU AGPLv3 © Nos oignons <contact@nos-oignons.net>
115                                git clone https://nos-oignons.net/gestion-adh.git
116       END_OF_BODY
117       mail = Mail.new :charset => 'utf-8',
118                       :from => NosOignons::BOARD_EMAIL,
119                       :to => NosOignons::ADVISORS_EMAIL,
120                       :subject => subject,
121                       :body => body
122       mail.deliver
123     end
124
125     def pre_commit_hook!
126       if system('git rev-parse --quiet --verify HEAD >/dev/null')
127         against = 'HEAD'
128       else
129         # Initial commit: diff against an empty tree object
130         against = '4b825dc642cb6eb9a060e54bf8d69288fbee4904'
131       end
132
133       IO.popen(['git', 'diff-index', '--cached', '--name-status', against]) do |io|
134         NosOignons::Git.handle_modified_files(io) do |file|
135           next unless file.start_with?("#{NosOignons::MEMBERS_DB_DIR}/")
136           begin
137             # Use empty ref to get the index
138             NosOignons::Member.read_from_git('', file)
139           rescue ArgumentError, Psych::SyntaxError
140             $stderr.puts "Désolé : #{file} n'a pas le bon format !"
141             exit 1
142           end
143         end
144       end
145     end
146
147     def pre_receive_hook!(stdin)
148       stdin.readlines.each do |ref_line|
149         old_value, new_value, ref_name = ref_line.rstrip.split(' ', 3)
150         IO.popen(['git', 'diff', '--name-status', "#{old_value}..#{new_value}"]) do |io|
151           NosOignons::Git.handle_modified_files(io) do |file|
152             next unless file.start_with?("#{NosOignons::MEMBERS_DB_DIR}/")
153             begin
154               NosOignons::Member.read_from_git(new_value, file)
155             rescue ArgumentError, Psych::SyntaxError
156               $stderr.puts "Désolé : #{file} n'a pas le bon format !"
157               exit 1
158             end
159           end
160         end
161       end
162     end
163   end
164 end