artfully_ose 1.2.0.pre.24 → 1.2.0.pre.26
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +9 -9
- data/app/assets/fonts/FontAwesome.otf +0 -0
- data/app/assets/fonts/fontawesome-webfont.eot +0 -0
- data/app/assets/fonts/fontawesome-webfont.svg +504 -0
- data/app/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/app/assets/fonts/fontawesome-webfont.woff +0 -0
- data/app/assets/javascripts/application.js +5 -0
- data/app/assets/javascripts/custom/people.js +68 -5
- data/app/assets/javascripts/sales-console.js +153 -0
- data/app/assets/javascripts/store/jquery.validate.additional-methods.js +476 -159
- data/app/assets/javascripts/store/jquery.validate.js +449 -406
- data/app/assets/stylesheets/application.sass +49 -0
- data/app/assets/stylesheets/font-awesome.css.scss +1566 -0
- data/app/concerns/cart_finder.rb +5 -0
- data/app/controllers/console_sales_controller.rb +182 -0
- data/app/controllers/events_controller.rb +1 -1
- data/app/controllers/events_pass_types_controller.rb +10 -0
- data/app/controllers/memberships_controller.rb +3 -3
- data/app/controllers/people_controller.rb +2 -1
- data/app/controllers/sales_controller.rb +51 -13
- data/app/controllers/shows_controller.rb +2 -2
- data/app/controllers/store/orders_controller.rb +0 -9
- data/app/helpers/artfully_ose_helper.rb +4 -2
- data/app/helpers/sales_helper.rb +29 -0
- data/app/models/cart.rb +6 -1
- data/app/models/checkout.rb +20 -13
- data/app/models/comp.rb +13 -16
- data/app/models/console_sale.rb +30 -0
- data/app/models/database_views/item_view.rb +3 -0
- data/app/models/job/checkout_processor.rb +10 -5
- data/app/models/kits/mailchimp_kit.rb +2 -1
- data/app/models/kits/passes_kit.rb +1 -1
- data/app/models/kits/scannable_tickets_kit.rb +3 -4
- data/app/models/membership.rb +18 -3
- data/app/models/membership_change.rb +1 -1
- data/app/models/membership_type.rb +2 -3
- data/app/models/order.rb +20 -17
- data/app/models/order_handler.rb +21 -0
- data/app/models/orders/comp_order.rb +1 -1
- data/app/models/parsed_row.rb +45 -2
- data/app/models/pass.rb +13 -0
- data/app/models/pass_type.rb +16 -0
- data/app/models/payment.rb +17 -0
- data/app/models/payments/cash_payment.rb +3 -1
- data/app/models/payments/check_payment.rb +33 -0
- data/app/models/payments/comp_payment.rb +3 -1
- data/app/models/payments/credit_card_payment.rb +8 -18
- data/app/models/person.rb +27 -3
- data/app/models/sale.rb +13 -10
- data/app/models/ticket.rb +1 -1
- data/app/views/console_sales/_aloha.html.haml +26 -0
- data/app/views/console_sales/_cart.html.haml +60 -0
- data/app/views/console_sales/_payment.html.haml +111 -0
- data/app/views/console_sales/_shows.html.haml +24 -0
- data/app/views/console_sales/new.html.haml +143 -0
- data/app/views/events/_day_date_show.html.haml +2 -2
- data/app/views/events/_ticket_type_fields.html.haml +1 -1
- data/app/views/events_pass_types/_form.html.haml +1 -1
- data/app/views/events_pass_types/index.html.haml +2 -1
- data/app/views/exchanges/new.html.haml +1 -1
- data/app/views/imports/people/_new.html.haml +12 -0
- data/app/views/kits/_list.html.haml +2 -1
- data/app/views/layouts/_menu.html.haml +0 -3
- data/app/views/membership_comps/create.html.haml +3 -1
- data/app/views/membership_types/_form.html.haml +0 -1
- data/app/views/orders/_item_table.haml +5 -3
- data/app/views/passes/index.html.haml +2 -2
- data/app/views/people/_edit_modal.html.haml +7 -0
- data/app/views/people/_work_with_menu.html.haml +4 -1
- data/app/views/people/show.html.haml +13 -4
- data/app/views/refunds/new.html.haml +1 -1
- data/app/views/sales/_boxoffice.html.haml +141 -0
- data/app/views/sales/_doorlist.html.haml +79 -0
- data/app/views/sales/new.html.haml +33 -125
- data/app/views/searches/show.html.haml +1 -1
- data/app/views/segments/show.html.haml +1 -1
- data/app/views/shows/_ticket_table.html.haml +1 -1
- data/app/views/shows/_work_with.html.haml +1 -1
- data/app/views/shows/index.html.haml +5 -6
- data/app/views/shows/show.html.haml +2 -2
- data/config/initializers/devise.rb +1 -1
- data/config/initializers/paperclip.rb +16 -0
- data/config/routes.rb +10 -1
- data/db/migrate/20140507184646_add_bday_attributes_to_person.rb +7 -0
- data/db/migrate/20140507201048_add_check_number_to_orders.rb +5 -0
- data/db/migrate/20140619194127_add_do_not_call_to_people.artfully_ose_engine.rb +5 -0
- data/db/migrate/20140623160543_add_index_to_items.rb +7 -0
- data/lib/artfully_ose/engine.rb +5 -4
- data/lib/artfully_ose/version.rb +1 -1
- data/spec/factories/person_factories.rb +3 -0
- metadata +43 -20
@@ -0,0 +1,29 @@
|
|
1
|
+
module SalesHelper
|
2
|
+
def door_list_sort(person)
|
3
|
+
result = if person.last_name.present?
|
4
|
+
person.last_name
|
5
|
+
elsif person.first_name.present?
|
6
|
+
person.first_name
|
7
|
+
else
|
8
|
+
person.email
|
9
|
+
end
|
10
|
+
|
11
|
+
result.downcase
|
12
|
+
end
|
13
|
+
|
14
|
+
def door_list_grouped_attribute(door_list_items, attr)
|
15
|
+
door_list_items.map {|d| d.send(attr)}.uniq.select {|n| n.present? }.to_sentence
|
16
|
+
end
|
17
|
+
|
18
|
+
def door_list_name_and_company(person)
|
19
|
+
result = []
|
20
|
+
result << content_tag(:strong, person.first_name) if person.first_name.present?
|
21
|
+
result << " #{person.last_name}" if person.last_name.present?
|
22
|
+
if person.company_name.present?
|
23
|
+
result << ", " if result.any?
|
24
|
+
result << person.company_name
|
25
|
+
end
|
26
|
+
|
27
|
+
safe_join(result)
|
28
|
+
end
|
29
|
+
end
|
data/app/models/cart.rb
CHANGED
@@ -34,6 +34,11 @@ class Cart < ActiveRecord::Base
|
|
34
34
|
|
35
35
|
delegate :empty?, :to => :items
|
36
36
|
|
37
|
+
#
|
38
|
+
# Note that this does return Item objects. It returns Tickets, Donations, Memberships, etc...
|
39
|
+
#
|
40
|
+
# TODO: Refactor this to another name to avoid confusion with Item
|
41
|
+
#
|
37
42
|
def items
|
38
43
|
self.tickets + self.donations + self.memberships + self.passes
|
39
44
|
end
|
@@ -133,7 +138,7 @@ class Cart < ActiveRecord::Base
|
|
133
138
|
end
|
134
139
|
|
135
140
|
def generate_donations
|
136
|
-
|
141
|
+
organizations.collect do |organization|
|
137
142
|
if organization.can?(:receive, Donation)
|
138
143
|
donation = Donation.new
|
139
144
|
donation.organization = organization
|
data/app/models/checkout.rb
CHANGED
@@ -2,23 +2,23 @@ class Checkout
|
|
2
2
|
include ActiveSupport::Callbacks
|
3
3
|
define_callbacks :payment
|
4
4
|
define_callbacks :order
|
5
|
-
|
5
|
+
|
6
6
|
include Ext::Callbacks::Checkout
|
7
7
|
include Ext::Preprocessor
|
8
|
-
|
9
|
-
attr_accessor :cart, :payment, :error
|
8
|
+
|
9
|
+
attr_accessor :cart, :payment, :error, :notes
|
10
10
|
attr_reader :order, :person
|
11
11
|
|
12
12
|
def self.for(cart, payment)
|
13
13
|
cart.checkout_class.new(cart, payment)
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def message
|
17
17
|
message = @error || @payment.errors.full_messages.to_sentence.downcase
|
18
18
|
message = message.gsub('customer', 'contact info')
|
19
19
|
message = message.gsub('credit card is', 'payment details are')
|
20
20
|
message = message[0].upcase + message[1..message.length] unless message.blank? #capitalize first word
|
21
|
-
|
21
|
+
|
22
22
|
if message.blank?
|
23
23
|
if @fafs_success == true
|
24
24
|
message = "We've processed your donation but could not reserve your tickets. Please check your information and try again or contact us to complete your purchase."
|
@@ -26,12 +26,13 @@ class Checkout
|
|
26
26
|
message = "We had a problem validating your payment. Wait a few moments and try again or contact us to complete your purchase."
|
27
27
|
end
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
message
|
31
31
|
end
|
32
32
|
|
33
|
-
def initialize(cart, payment)
|
33
|
+
def initialize(cart, payment, notes=nil)
|
34
34
|
@cart = cart
|
35
|
+
@notes = notes
|
35
36
|
@payment = payment
|
36
37
|
@customer = payment.customer
|
37
38
|
@payment.amount = @cart.total
|
@@ -48,7 +49,7 @@ class Checkout
|
|
48
49
|
unless (!!cart and !!payment and payment.valid?)
|
49
50
|
return false
|
50
51
|
end
|
51
|
-
|
52
|
+
|
52
53
|
true
|
53
54
|
end
|
54
55
|
|
@@ -77,7 +78,7 @@ class Checkout
|
|
77
78
|
void_payment if @payment_approved
|
78
79
|
raise e
|
79
80
|
end
|
80
|
-
|
81
|
+
|
81
82
|
capture_payment if @payment_approved
|
82
83
|
@payment_approved || false
|
83
84
|
end
|
@@ -85,7 +86,7 @@ class Checkout
|
|
85
86
|
def log(message)
|
86
87
|
Rails.logger.info "CHECKOUT: cart [#{cart.id}] #{message}"
|
87
88
|
end
|
88
|
-
|
89
|
+
|
89
90
|
def pay
|
90
91
|
log "authorizing"
|
91
92
|
options = {}
|
@@ -99,7 +100,7 @@ class Checkout
|
|
99
100
|
def capture_payment
|
100
101
|
log "capturing payment [#{@transaction_id}]"
|
101
102
|
payment.capture(@transaction_id, {})
|
102
|
-
log "payment captured"
|
103
|
+
log "payment captured"
|
103
104
|
end
|
104
105
|
|
105
106
|
def void_payment
|
@@ -108,6 +109,10 @@ class Checkout
|
|
108
109
|
log "payment voided"
|
109
110
|
end
|
110
111
|
|
112
|
+
def checkout_name
|
113
|
+
"checkout"
|
114
|
+
end
|
115
|
+
|
111
116
|
private
|
112
117
|
def create_sub_orders(order_timestamp)
|
113
118
|
created_orders = []
|
@@ -122,14 +127,14 @@ class Checkout
|
|
122
127
|
attributes[:organization] = organization
|
123
128
|
|
124
129
|
@person = Person.first_or_create(attributes)
|
125
|
-
CheckoutProcessor.process(@person, @customer, Address.from_payment(payment), payment.payment_phone_number, organization.time_zone)
|
130
|
+
CheckoutProcessor.process(@person, @customer, Address.from_payment(payment), payment.payment_phone_number, organization.time_zone, checkout_name)
|
126
131
|
@order = new_order(organization, order_timestamp, @person)
|
127
132
|
log(@order.save!)
|
128
133
|
log("Created order [#{@order.id}]")
|
129
134
|
|
130
135
|
created_orders << @order
|
131
136
|
end
|
132
|
-
|
137
|
+
|
133
138
|
created_orders
|
134
139
|
end
|
135
140
|
|
@@ -147,9 +152,11 @@ class Checkout
|
|
147
152
|
order.created_at = order_timestamp
|
148
153
|
order.person = @person
|
149
154
|
order.transaction_id = @payment.transaction_id
|
155
|
+
order.check_number = @payment.check_number if payment.kind_of?(CheckPayment)
|
150
156
|
order.special_instructions = @cart.special_instructions
|
151
157
|
order.payment_method = @payment.payment_method
|
152
158
|
order.per_item_processing_charge = @payment.per_item_processing_charge
|
159
|
+
order.notes = @notes
|
153
160
|
|
154
161
|
order << @cart.tickets.select { |ticket| ticket.organization_id == organization.id }
|
155
162
|
order << @cart.donations
|
data/app/models/comp.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Comp
|
2
|
-
include ActiveModel::Conversion
|
2
|
+
include ActiveModel::Conversion
|
3
3
|
include ActiveModel::Validations
|
4
4
|
extend ActiveModel::Naming
|
5
5
|
|
@@ -9,26 +9,27 @@ class Comp
|
|
9
9
|
attr_accessor :comped_count, :uncomped_count, :details
|
10
10
|
|
11
11
|
#tickets can be an array of tickets_ids or an array of tickets
|
12
|
-
def initialize(show, tickets_or_ids, memberships, recipient, benefactor)
|
12
|
+
def initialize(show, tickets_or_ids, memberships, recipient, benefactor, notes=nil)
|
13
13
|
@show = show
|
14
14
|
@tickets = []
|
15
15
|
@memberships = memberships
|
16
16
|
load_tickets(tickets_or_ids)
|
17
17
|
@recipient = Person.find(recipient) unless recipient.blank?
|
18
18
|
@benefactor = benefactor
|
19
|
+
@notes = notes
|
19
20
|
end
|
20
|
-
|
21
|
+
|
21
22
|
def valid_recipient_and_benefactor
|
22
23
|
if @recipient.nil?
|
23
24
|
errors.add(:base, "Please select a person to comp to or create a new person record")
|
24
25
|
return
|
25
26
|
end
|
26
|
-
|
27
|
+
|
27
28
|
if @benefactor.nil?
|
28
29
|
errors.add(:base, "Please select a benefactor")
|
29
30
|
return
|
30
31
|
end
|
31
|
-
|
32
|
+
|
32
33
|
unless @benefactor.current_organization.eql? @recipient.organization
|
33
34
|
errors.add(:base, "Recipient and benefactor are from different organizations")
|
34
35
|
end
|
@@ -44,7 +45,7 @@ class Comp
|
|
44
45
|
|
45
46
|
def submit
|
46
47
|
ActiveRecord::Base.transaction do
|
47
|
-
create_order(@tickets, @memberships, @recipient, @benefactor)
|
48
|
+
create_order(@tickets, @memberships, @recipient, @benefactor, @notes)
|
48
49
|
self.comped_count = tickets.size
|
49
50
|
self.uncomped_count = 0
|
50
51
|
end
|
@@ -58,15 +59,15 @@ class Comp
|
|
58
59
|
@tickets << t
|
59
60
|
end
|
60
61
|
end
|
61
|
-
|
62
|
-
def create_order(comped_tickets, comped_memberships, recipient, benefactor)
|
62
|
+
|
63
|
+
def create_order(comped_tickets, comped_memberships, recipient, benefactor, notes)
|
63
64
|
@order = CompOrder.new
|
64
65
|
@order << comped_tickets
|
65
66
|
@order << comped_memberships
|
66
67
|
@order.person = recipient
|
67
68
|
@order.organization = benefactor.current_organization
|
68
|
-
@order.details = order_details
|
69
|
-
@order.notes =
|
69
|
+
@order.details = order_details
|
70
|
+
@order.notes = @notes
|
70
71
|
@order.skip_email = true
|
71
72
|
@order.to_comp!
|
72
73
|
f = @order.save
|
@@ -74,10 +75,6 @@ class Comp
|
|
74
75
|
end
|
75
76
|
|
76
77
|
def order_details
|
77
|
-
"Comped by: #{@benefactor.email}"
|
78
|
-
end
|
79
|
-
|
80
|
-
def order_notes
|
81
|
-
"#{@notes}"
|
78
|
+
"Comped by: #{@benefactor.email}"
|
82
79
|
end
|
83
|
-
end
|
80
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ConsoleSale
|
2
|
+
class Checkout < ::Checkout
|
3
|
+
def order_class
|
4
|
+
ConsoleSale::Order
|
5
|
+
end
|
6
|
+
|
7
|
+
def checkout_name
|
8
|
+
"sales console"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Cart < ::Cart
|
13
|
+
def calculate_fees(obj)
|
14
|
+
FeeCalculator.apply(ConsoleSale::FeeStrategy.new).to(self)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Order < ::Order
|
19
|
+
def self.location
|
20
|
+
"Sales Console"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class FeeStrategy < ::FeeStrategy
|
25
|
+
def apply_to_cart(cart)
|
26
|
+
return if cart.is_a? BoxOffice::Cart
|
27
|
+
cart.items.each {|i| i.update_column(:service_fee, 0)}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -58,6 +58,7 @@ class ItemView < ActiveRecord::Base
|
|
58
58
|
person("Linked In Url") { |person| person.linked_in_url }
|
59
59
|
person("Tags") { |person| person.tags.join("|") }
|
60
60
|
person("Do Not Email") { |person| person.do_not_email }
|
61
|
+
person("Do Not Call") { |person| person.do_not_call }
|
61
62
|
person("Household Name") { |person| person.household && person.household.name }
|
62
63
|
end
|
63
64
|
|
@@ -100,6 +101,7 @@ class ItemView < ActiveRecord::Base
|
|
100
101
|
person("Linked In Url") { |person| person.linked_in_url }
|
101
102
|
person("Tags") { |person| person.tags.join("|") }
|
102
103
|
person("Do Not Email") { |person| person.do_not_email }
|
104
|
+
person("Do Not Call") { |person| person.do_not_call }
|
103
105
|
person("Household Name") { |person| person.household && person.household.name }
|
104
106
|
end
|
105
107
|
|
@@ -141,5 +143,6 @@ class ItemView < ActiveRecord::Base
|
|
141
143
|
person("Linked In Url") { |person| person.linked_in_url }
|
142
144
|
person("Tags") { |person| person.tags.join("|") }
|
143
145
|
person("Do Not Email") { |person| person.do_not_email }
|
146
|
+
person("Do Not Call") { |person| person.do_not_call }
|
144
147
|
end
|
145
148
|
end
|
@@ -7,20 +7,21 @@
|
|
7
7
|
#
|
8
8
|
# This class WILL NOT RUN ASYNC in test envs
|
9
9
|
#
|
10
|
-
class CheckoutProcessor < Struct.new(:person, :first_name, :last_name, :address_hash, :phone, :time_zone)
|
10
|
+
class CheckoutProcessor < Struct.new(:person, :first_name, :last_name, :address_hash, :phone, :time_zone, :checkout_name)
|
11
11
|
QUEUE = "checkout"
|
12
12
|
|
13
|
-
def initialize(person, customer, address, phone, time_zone)
|
13
|
+
def initialize(person, customer, address, phone, time_zone, checkout_name = "checkout")
|
14
14
|
self.person = person
|
15
15
|
self.first_name = customer.first_name
|
16
16
|
self.last_name = customer.last_name
|
17
17
|
self.address_hash = address.attributes.to_options unless address.nil?
|
18
18
|
self.phone = phone
|
19
19
|
self.time_zone = time_zone
|
20
|
+
self.checkout_name = checkout_name
|
20
21
|
end
|
21
22
|
|
22
|
-
def self.process(person, customer, address, phone, time_zone)
|
23
|
-
job = CheckoutProcessor.new(person, customer, address, phone, time_zone)
|
23
|
+
def self.process(person, customer, address, phone, time_zone, checkout_name)
|
24
|
+
job = CheckoutProcessor.new(person, customer, address, phone, time_zone, checkout_name)
|
24
25
|
|
25
26
|
if job.run_now?
|
26
27
|
job.perform
|
@@ -31,11 +32,15 @@ class CheckoutProcessor < Struct.new(:person, :first_name, :last_name, :address_
|
|
31
32
|
|
32
33
|
def perform
|
33
34
|
self.person.update_name(self.first_name, self.last_name)
|
34
|
-
self.person.update_address(self.address_hash, self.time_zone, nil,
|
35
|
+
self.person.update_address(self.address_hash, self.time_zone, nil, checkout_name) if address_exists?
|
35
36
|
self.person.add_phone_if_missing(self.phone)
|
36
37
|
end
|
37
38
|
|
38
39
|
def run_now?
|
39
40
|
Rails.env.test?
|
40
41
|
end
|
42
|
+
|
43
|
+
def address_exists?
|
44
|
+
self.address_hash.present? && self.address_hash.values.select{|values| values.present?}.any?
|
45
|
+
end
|
41
46
|
end
|
@@ -7,6 +7,7 @@ class MailchimpKit < Kit
|
|
7
7
|
|
8
8
|
state_machine do
|
9
9
|
state :cancelled, :enter => :kit_cancelled
|
10
|
+
event(:submit_for_approval) { transitions :from => :fresh, :to => :pending }
|
10
11
|
end
|
11
12
|
|
12
13
|
when_active do
|
@@ -312,7 +313,7 @@ class MailchimpKit < Kit
|
|
312
313
|
hear_action = HearAction.for_organization(organization)
|
313
314
|
hear_action.details = %{"#{data["subject"].truncate(25)}" delivered to #{list_name(list_id)} MailChimp list.}
|
314
315
|
hear_action.occurred_at = occurred_at
|
315
|
-
hear_action.subtype = "
|
316
|
+
hear_action.subtype = "Mailchimp (Sent)"
|
316
317
|
hear_action.person = person
|
317
318
|
hear_action.save
|
318
319
|
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
class ScannableTicketsKit < Kit
|
2
2
|
|
3
|
-
acts_as_kit
|
4
|
-
approve :unless => :no_bank_account?
|
5
|
-
|
3
|
+
acts_as_kit do
|
6
4
|
self.configurable = false
|
7
5
|
|
8
6
|
state_machine do
|
9
7
|
state :cancelled, :enter => :kit_cancelled
|
8
|
+
event(:submit_for_approval) { transitions :from => :fresh, :to => :pending }
|
10
9
|
end
|
11
10
|
|
12
11
|
when_active do |organization|
|
@@ -16,7 +15,7 @@ class ScannableTicketsKit < Kit
|
|
16
15
|
|
17
16
|
def friendly_name
|
18
17
|
"Scannable Tickets"
|
19
|
-
end
|
18
|
+
end
|
20
19
|
|
21
20
|
def pitch
|
22
21
|
"Your patrons will receive barcoded tickets that you can scan at the door."
|
data/app/models/membership.rb
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#
|
5
5
|
class Membership < ActiveRecord::Base
|
6
6
|
include Extendable
|
7
|
+
extend ActionView::Helpers::TextHelper
|
7
8
|
|
8
9
|
belongs_to :organization
|
9
10
|
belongs_to :member
|
@@ -20,9 +21,10 @@ class Membership < ActiveRecord::Base
|
|
20
21
|
# Make sure you're scoping when you use these.
|
21
22
|
# organization.memberships.lapsed
|
22
23
|
#
|
23
|
-
scope :
|
24
|
-
scope :
|
25
|
-
scope :
|
24
|
+
scope :expired, lambda { |time = Time.now| where("ends_at < ?", time) }
|
25
|
+
scope :current, lambda { |time = Time.now| where("ends_at > ?", time) }
|
26
|
+
scope :lapsed, lambda { |time = Time.now, since = (time - 1.year)| where("ends_at < ?", time).where("ends_at > ?", since.midnight) }
|
27
|
+
scope :past, lambda { |time = Time.now| where("ends_at < ?", time - 1.year) }
|
26
28
|
|
27
29
|
belongs_to :changed_membership, :class_name => "Membership"
|
28
30
|
has_one :changed_to, :class_name => "Membership", :foreign_key => "changed_membership_id"
|
@@ -64,6 +66,19 @@ class Membership < ActiveRecord::Base
|
|
64
66
|
self.membership_type.hide_fee? ? self.cart_price * MembershipType::SERVICE_FEE : 0
|
65
67
|
end
|
66
68
|
|
69
|
+
def self.to_sentence(memberships)
|
70
|
+
if memberships.any?
|
71
|
+
membership_types = memberships.collect(&:membership_type).uniq
|
72
|
+
if membership_types.length > 1
|
73
|
+
"multiple memberships"
|
74
|
+
else
|
75
|
+
pluralize(memberships.length, "#{memberships.first.membership_type.membershipize}")
|
76
|
+
end
|
77
|
+
else
|
78
|
+
"No memberships"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
67
82
|
def expired?
|
68
83
|
ends_at < Time.now
|
69
84
|
end
|