Class: Member
Constant Summary
collapse
- CURRENT =
:current
- LAPSED =
:lapsed
- PAST =
:past
- NONE =
:none
Constants included
from Ext::Uuid
Ext::Uuid::PREFIX
Class Method Summary
collapse
Instance Method Summary
collapse
#download_link_for
Methods included from Ext::Uuid
included, #set_uuid, uuid
included
Class Method Details
.find_by_membership(membership, person) ⇒ Object
128
129
130
|
# File 'app/models/member.rb', line 128
def self.find_by_membership(membership, person)
Member.find_by_email_and_organization_id(person.email, membership.organization)
end
|
.for(membership, person) ⇒ Object
- Creates a member for this membership if one does not already exist
- Attaches that member to the applicable person
- Invites that member if membership.send_email is true
- Generates a new qr code if this is a new member
- Generates a membership card if this is a new member
This method CANNOT be run in any synchronous flow
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
# File 'app/models/member.rb', line 145
def self.for(membership, person)
member = Member.find_by_membership(membership, person)
if member.nil?
member = Member.create!({:email => person.email,
:organization => membership.organization,
:person => person,
:password => SecureRandom.hex(32)}, :without_protection => true)
member.person.create_address if member.person.address.nil?
membership.member = member
membership.save
member.generate_qr_code
member.generate_pdf
member.invite! if membership.send_email
else
membership.member = member
membership.save
end
member
end
|
.generate_password ⇒ Object
113
114
115
|
# File 'app/models/member.rb', line 113
def self.generate_password
Devise.friendly_token
end
|
.states ⇒ Object
103
104
105
|
# File 'app/models/member.rb', line 103
def self.states
[CURRENT, LAPSED, PAST, NONE]
end
|
Instance Method Details
#active_for_authentication? ⇒ Boolean
124
125
126
|
# File 'app/models/member.rb', line 124
def active_for_authentication?
super && !suspended?
end
|
#attachments_for(action) ⇒ Object
returns an array of attachments in this format: [ [filename, file], [filename, file] ]
45
46
47
48
49
50
51
52
|
# File 'app/models/member.rb', line 45
def attachments_for(action)
case action.to_s
when "invitation_instructions"
[ ["membership_card.pdf", member_card_pdf] ]
else
[]
end
end
|
#count_memberships ⇒ Object
76
77
78
79
80
81
|
# File 'app/models/member.rb', line 76
def count_memberships
self.current_memberships_count = self.memberships.current.count
self.lapsed_memberships_count = self.memberships.lapsed.count
self.past_memberships_count = self.memberships.past.count
self.save
end
|
#current_membership_types ⇒ Object
61
62
63
|
# File 'app/models/member.rb', line 61
def current_membership_types
memberships.current.collect(&:membership_type)
end
|
#generate_pdf ⇒ Object
171
172
173
174
175
176
177
|
# File 'app/models/member.rb', line 171
def generate_pdf
pdf = PdfGeneration.new(self).generate
file = Tempfile.new(["#{self.id}", '.pdf'])
file << pdf.force_encoding("UTF-8")
self.pdf = file
self.save
end
|
#generate_qr_code ⇒ Object
179
180
181
182
183
184
185
186
187
188
189
190
|
# File 'app/models/member.rb', line 179
def generate_qr_code
file = Tempfile.new(['qr-code', '.png'])
Ticket::QRCode.new(self, nil).render(file)
self.qr_code = file
save
file.close
end
|
devise_invitable needs this otherwise it can't set the :from param in an email
33
34
35
36
37
38
39
40
|
# File 'app/models/member.rb', line 33
def (action)
case action.to_s
when "invitation_instructions"
{:from => self.organization.email}
else
{}
end
end
|
#member_card_pdf ⇒ Object
54
55
56
57
58
59
|
# File 'app/models/member.rb', line 54
def member_card_pdf
file = Tempfile.new(["member#{self.id}", '.pdf'])
self.pdf.copy_to_local_file(:original, file)
file.rewind
file.read
end
|
#member_through ⇒ Object
132
133
134
|
# File 'app/models/member.rb', line 132
def member_through
self.memberships.map{|membership| membership.ends_at}.max
end
|
#member_tickets_purchased_for(event) ⇒ Object
65
66
67
68
69
70
71
|
# File 'app/models/member.rb', line 65
def member_tickets_purchased_for(event)
Ticket.joins(:ticket_type)
.joins(:show => :event)
.where(:buyer_id => self.person.id)
.where('shows.event_id' => event.id)
.where('ticket_types.member_ticket = 1')
end
|
#set_member_number ⇒ Object
117
118
119
|
# File 'app/models/member.rb', line 117
def set_member_number
self.member_number = MemberNumberGenerator.next_number_for(self.organization)
end
|
#state ⇒ Object
Intentionally did not use a state machine for this for a few reasons
- I'm not all that happy with transitions
- Can't find another state machine that I like and is worth the cost of switching to
- This works just fine. I prefer calculating state on the fly here because we're couning the memberships
on this member anyway
- Determining a lapsed or past member is a touch more complicated than it sounds
A lapsed member is a member with lapsed memberships and no current memberships
It's that last bit that makes grabbing all last members quite difficult in SQL
Note that this method uses the cached values for current_memberships, lapsed_memberships, and past_memberships
96
97
98
99
100
101
|
# File 'app/models/member.rb', line 96
def state
return CURRENT if self.current_memberships_count > 0
return LAPSED if self.lapsed_memberships_count > 0
return PAST if self.past_memberships_count > 0
return NONE
end
|