artfully_ose 1.2.0.pre.5 → 1.2.0.pre.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +8 -8
  2. data/app/assets/stylesheets/sass/box-office.sass +2 -1
  3. data/app/assets/stylesheets/sass/store.sass +6 -0
  4. data/app/controllers/sales_controller.rb +3 -4
  5. data/app/controllers/shows_controller.rb +8 -7
  6. data/app/controllers/store/events_controller.rb +0 -1
  7. data/app/controllers/users/sessions_controller.rb +3 -0
  8. data/app/helpers/link_helper.rb +1 -1
  9. data/app/models/carts/cart_finder.rb +19 -7
  10. data/app/models/event.rb +8 -2
  11. data/app/models/member.rb +43 -4
  12. data/app/models/membership.rb +15 -2
  13. data/app/models/sale.rb +1 -0
  14. data/app/models/search.rb +25 -3
  15. data/app/models/show.rb +9 -0
  16. data/app/models/ticket.rb +3 -0
  17. data/app/models/user.rb +2 -2
  18. data/app/views/events/_menu.html.haml +2 -2
  19. data/app/views/events/_share_and_sell.haml +1 -1
  20. data/app/views/events/image.html.haml +1 -0
  21. data/app/views/events/show.html.haml +3 -1
  22. data/app/views/layouts/storefront.html.haml +2 -0
  23. data/app/views/members/index/index.html.haml +3 -3
  24. data/app/views/searches/_form.html.haml +33 -33
  25. data/app/views/shows/_controls.html.haml +2 -18
  26. data/app/views/shows/index.html.haml +20 -15
  27. data/app/views/store/events/_venue.html.haml +3 -1
  28. data/app/views/store/events/single_show.html.haml +1 -2
  29. data/config/locales/en.yml +4 -2
  30. data/config/routes.rb +2 -2
  31. data/db/migrate/20131002191646_create_show_stats_view.rb +16 -0
  32. data/db/migrate/20131007141421_add_counters_to_member.rb +7 -0
  33. data/db/migrate/20131007144456_remove_expires_at_from_membership.rb +6 -0
  34. data/lib/artfully_ose/version.rb +1 -1
  35. metadata +6 -2
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OTNiMTJkMGJiNWE1NzAxNTExYWVhMDljYzBkMjAxNmEyMzM3NjU4OQ==
4
+ ZWQ0MjYyODBmMjg3NzRjZTczNzY1N2U1MDM0NTNiNzU3N2ZlYTZhNw==
5
5
  data.tar.gz: !binary |-
6
- Yjk2N2QzZmY2YjY0NjBiMzUyZDdmMjUwMzBhMTRhMWM1ODA2ZDQ0YQ==
6
+ MjkwZmFiMmY3Njg0ZmQxMDU3YzBkZDYyMDEyOWJjYzhkNzFlOWJjMg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- YzljNTZhZTUyZWNiNzFhNzE5YTc5MjIyYTVhZmE2ZTdjNmYzZGI3MWJlZjkx
10
- ZmMxZWNkYzgwYTY2YmVjM2IyMjQ0ODJkYWM2MDc0NzhiZTgzYzI1ZGY2NGVi
11
- YjRlODk1MGJmZWEzOTY1M2U4NDUzNTEwNWRkYzRlYzJmODIxOTE=
9
+ OWMyYWMwZjU4MDc4N2Q5ZjJjM2M2NzU2OTYzZmZlODY2M2ZjY2FmMDcwMTRj
10
+ Y2Q5NTMyNGRjYjQxZmEyNWExOGE2NjlkMDZkNTYzMWZjYTUwMTFjNGEyY2Y0
11
+ OGVkZTkzYjBjNTIwMjA0ZjkxOWU5YzEzNDVmYTYxNGE4MTJlMjc=
12
12
  data.tar.gz: !binary |-
13
- Y2IyYWFmMzBhNzE5YTJhMDY1ZjcyMTA2ZThhMDBhN2Q1ZDQzN2M2Mzc0ZTM5
14
- MDI2NjNmNjAzZWZiNjYwZWEwMjY0MTNkMjdiNDkzZWM5YmVkNDk5Y2U5NzUz
15
- YzY2OTIxNjFkNWE5YTAxNDdmZTU1NGI2ZDczZWZkY2UxNTFhODI=
13
+ NDNiYmFmMWIwNmM5ZmZhODE3MzljNTZiMDllMWZlZTZiYWM2NmUxZDg1Zjc4
14
+ MjI5ODM0OGNkMDJhNWQ0YmNmOGQzOTU0M2U3NTkxODJlOTA3YjkzNGY1ZDI3
15
+ N2UwNDBlNjZiOTA1NmJlZWNmNDMyNjI0OTFjZDVkYThmYjUxN2E=
@@ -17,8 +17,9 @@
17
17
 
18
18
  #total
19
19
  .price
20
- font-size: 28px
20
+ font-size: 38px
21
21
  font-weight: bold
22
+ padding-top: 10px
22
23
 
23
24
  ul.ui-autocomplete
24
25
  li.ui-menu-item
@@ -508,3 +508,9 @@ tr.no-border
508
508
  padding-top: 13px
509
509
 
510
510
  .event-image
511
+ img
512
+ max-width: 290px
513
+
514
+ #poster-modal
515
+ .modal-body
516
+ text-align: center
@@ -9,14 +9,14 @@ class SalesController < ArtfullyOseController
9
9
 
10
10
  def new
11
11
  @person = Person.new
12
- @sale = Sale.new(@show, @show.chart.ticket_types.box_office, current_cart.becomes(BoxOffice::Cart), {})
12
+ @sale = Sale.new(@show, @show.chart.ticket_types.box_office, current_box_office_cart, {})
13
13
  @tickets_remaining = tickets_remaining
14
14
  setup_defaults
15
15
  end
16
16
 
17
17
  def create
18
- current_cart.becomes(BoxOffice::Cart).clear!
19
- @sale = Sale.new(@show, @show.chart.ticket_types.box_office, current_cart.becomes(BoxOffice::Cart), params[:quantities])
18
+ current_box_office_cart.clear!
19
+ @sale = Sale.new(@show, @show.chart.ticket_types.box_office, current_box_office_cart, params[:quantities])
20
20
  if checking_out?
21
21
  if @sale.sell(payment)
22
22
  @sale.message = "Sold #{self.class.helpers.pluralize(@sale.tickets.length, 'ticket')}. Order total was #{self.class.helpers.number_as_cents @sale.cart.total}"
@@ -25,7 +25,6 @@ class SalesController < ArtfullyOseController
25
25
 
26
26
  unless @sale.errors.empty?
27
27
  @sale.error = "#{@sale.errors.full_messages.to_sentence.capitalize}."
28
- ExpireTicketJob.new(@sale.cart.tickets).perform
29
28
  end
30
29
 
31
30
  render :json => @sale.as_json
@@ -1,16 +1,17 @@
1
1
  class ShowsController < ArtfullyOseController
2
2
  before_filter :find_event, :only => [ :index, :calendar, :show, :new, :edit, :duplicate ]
3
3
  before_filter :check_for_charts, :only => [ :index, :new ]
4
- before_filter :upcoming_shows, :only => [ :index, :show ]
5
4
 
6
5
  rescue_from CanCan::AccessDenied do |exception|
7
6
  flash[:alert] = exception.message
8
- redirect_to event_url(@show.event)
7
+ redirect_to event_url(@event)
9
8
  end
10
9
 
11
10
  def index
12
11
  authorize! :manage, @event
13
- @shows = Show.where(:event_id => @event.id).includes(:tickets, :chart, :event => :venue).order('datetime ASC')
12
+ shows_rel = Show.where(:event_id => @event.id)
13
+ shows_rel = shows_rel.where('datetime > ?', Time.now - 2.days) unless all?
14
+ @shows = shows_rel.includes(:show_stats_view, :event).order('datetime ASC').paginate(:page => params[:page], :per_page => 20)
14
15
  end
15
16
 
16
17
  def new
@@ -191,12 +192,12 @@ class ShowsController < ArtfullyOseController
191
192
  end
192
193
 
193
194
  private
194
- def find_event
195
- @event = Event.includes(:shows => [:event => :venue]).find(params[:event_id])
195
+ def all?
196
+ @all ||= (params[:range].present? && params[:range] == :all)
196
197
  end
197
198
 
198
- def upcoming_shows
199
- @upcoming = @event.upcoming_shows
199
+ def find_event
200
+ @event = Event.includes(:shows => [:event => :venue]).find(params[:event_id])
200
201
  end
201
202
 
202
203
  def with_confirmation
@@ -7,6 +7,5 @@ class Store::EventsController < Store::StoreController
7
7
 
8
8
  def index
9
9
  @events = Event.for_storefront(@store_organization, current_member)
10
- @events = []
11
10
  end
12
11
  end
@@ -0,0 +1,3 @@
1
+ class Users::SessionsController < Devise::SessionsController
2
+ layout 'devise_layout'
3
+ end
@@ -3,7 +3,7 @@ module LinkHelper
3
3
  "active" if content_for(:_active_section) == section.to_s || content_for(:_active_sub_section) == section.to_s
4
4
  end
5
5
 
6
- def in?(section)
6
+ def in_section?(section)
7
7
  "in" if content_for(:_active_section) == section.to_s || content_for(:_active_sub_section) == section.to_s
8
8
  end
9
9
 
@@ -9,17 +9,21 @@ module CartFinder
9
9
  c.helper_method :current_cart
10
10
  end
11
11
 
12
- def current_cart
13
- (!session_cart || session_cart.approved?) ? create_new_cart : session_cart
12
+ def current_box_office_cart
13
+ current_cart(BoxOffice::Cart)
14
14
  end
15
15
 
16
- def session_cart
17
- @current_cart ||= Cart.find_by_id(session[:cart_id])
16
+ def current_cart(klass = Cart)
17
+ (!session_cart(klass) || session_cart(klass).approved?) ? create_new_cart(klass) : session_cart(klass)
18
18
  end
19
19
 
20
- def create_new_cart
21
- @current_cart = Cart.create
22
- session[:cart_id] = @current_cart ? @current_cart.id : nil
20
+ def session_cart(klass = Cart)
21
+ @current_cart ||= Cart.find_by_id(session[session_key(klass)])
22
+ end
23
+
24
+ def create_new_cart(klass = Cart)
25
+ @current_cart = klass.create
26
+ session[session_key(klass)] = @current_cart ? @current_cart.id : nil
23
27
  @current_cart
24
28
  end
25
29
 
@@ -30,4 +34,12 @@ module CartFinder
30
34
  def current_cart=(cart)
31
35
  @current_cart = cart
32
36
  end
37
+
38
+ def cart_name(klass = Cart)
39
+ klass.name.gsub("::","").underscore
40
+ end
41
+
42
+ def session_key(klass)
43
+ (cart_name(klass) + "_id").to_sym
44
+ end
33
45
  end
data/app/models/event.rb CHANGED
@@ -72,11 +72,17 @@ class Event < ActiveRecord::Base
72
72
  shows.length == 1
73
73
  end
74
74
 
75
- def self.for_storefront(member = nil)
75
+ def self.for_storefront(organization, member = nil)
76
76
  event_rel = Event.joins(:shows).where(:organization_id => organization.id).where('shows.datetime > ?', DateTime.now).group(:event_id).public
77
77
  event_rel = event_rel.where(:members_only => false) if member.nil?
78
78
  event_rel.all
79
79
  end
80
+
81
+ def self.storefront_find(id, member = nil)
82
+ event_rel = Event.includes(:venue, :shows => [:chart => [:sections => :ticket_types]])
83
+ event_rel = event_rel.where(:members_only => false) if member.nil?
84
+ event_rel.find(id)
85
+ end
80
86
 
81
87
  def destroyable?
82
88
  items.blank?
@@ -144,7 +150,7 @@ class Event < ActiveRecord::Base
144
150
  end
145
151
 
146
152
  def as_full_calendar_json
147
- shows.collect do |p|
153
+ shows.includes(:event).collect do |p|
148
154
  { :title => '',
149
155
  :start => p.datetime_local_to_event,
150
156
  :allDay => false,
data/app/models/member.rb CHANGED
@@ -12,6 +12,15 @@ class Member < ActiveRecord::Base
12
12
 
13
13
  before_create :set_member_number
14
14
 
15
+ CURRENT = :current
16
+ LAPSED = :lapsed
17
+ PAST = :past
18
+ NONE = :none
19
+
20
+ scope CURRENT, where("current_memberships_count > 0")
21
+ scope LAPSED, where("lapsed_memberships_count > 0").where("current_memberships_count = 0")
22
+ scope PAST, where("past_memberships_count > 0").where("lapsed_memberships_count = 0").where("current_memberships_count = 0")
23
+
15
24
  #
16
25
  # devise_invitable needs this otherwise it can't set the :from param in an email
17
26
  #
@@ -24,12 +33,42 @@ class Member < ActiveRecord::Base
24
33
  end
25
34
  end
26
35
 
27
- def self.generate_password
28
- Devise.friendly_token
36
+ #
37
+ # This is always run DJ'd
38
+ #
39
+ def count_memberships
40
+ self.current_memberships_count = self.memberships.current.count
41
+ self.lapsed_memberships_count = self.memberships.lapsed.count
42
+ self.past_memberships_count = self.memberships.past.count
43
+ self.save
29
44
  end
45
+ handle_asynchronously :count_memberships
30
46
 
31
- def active_memberships
32
- memberships.select{ |m| m.starts_at < DateTime.now && m.ends_at > DateTime.now }
47
+ #
48
+ # Intentionally did not use a state machine for this for a few reasons
49
+ # 1) I'm not all that happy with transitions
50
+ # 2) Can't find another statre machine that I like and is worth the cost of switching to
51
+ # 3) This works just fine. I prefer calculating state on the fly here because we're couning the memberships
52
+ # on this member anyway
53
+ # 4) Determining a lapsed or past member is a touch more complicated than it sounds
54
+ # A lapsed member is a member with lapsed memberships *and no current memberships*
55
+ # It's that last bit that makes grabbing all last members quite difficult in SQL
56
+ #
57
+ # Note that this method uses the cached values for current_memberships, lapsed_memberships, and past_memberships
58
+ #
59
+ def state
60
+ return CURRENT if self.current_memberships_count > 0
61
+ return LAPSED if self.lapsed_memberships_count > 0
62
+ return PAST if self.past_memberships_count > 0
63
+ return NONE
64
+ end
65
+
66
+ def self.states
67
+ [CURRENT, LAPSED, PAST, NONE]
68
+ end
69
+
70
+ def self.generate_password
71
+ Devise.friendly_token
33
72
  end
34
73
 
35
74
  def set_member_number
@@ -5,6 +5,16 @@ class Membership < ActiveRecord::Base
5
5
  belongs_to :membership_type
6
6
  has_many :items, :as => :product
7
7
 
8
+ # Same callbacks that fire before Rails' built-in counter_cache
9
+ #Except before_destroy is replaced with after_destroy
10
+ after_create :update_member_counters
11
+ after_destroy :update_member_counters
12
+ after_update :update_member_counters
13
+
14
+ scope :current, lambda { |time = Time.now| where("ends_at > ?", time) }
15
+ scope :lapsed, lambda { |time = Time.now| where("ends_at < ?", time).where("ends_at > ?", time - 1.year) }
16
+ scope :past, lambda { |time = Time.now| where("ends_at < ?", time - 1.year) }
17
+
8
18
  def self.for(membership_type)
9
19
  new.tap do |membership|
10
20
  membership.membership_type = membership_type
@@ -15,10 +25,13 @@ class Membership < ActiveRecord::Base
15
25
  end
16
26
  end
17
27
 
28
+ def update_member_counters
29
+ self.member.count_memberships
30
+ end
31
+
18
32
  # TODO: DJ this. Could be thousands of people.
19
33
  def self.for_award(membership_award)
20
34
  membership_award.people.each do |people|
21
- Rails.logger.debug(" MEMBERSHIP FOR #{people}")
22
35
  membership = Membership.for(membership_award.membership_type)
23
36
  membership.ends_at = membership_award.ends_at
24
37
  membership.sold_price = membership_award.sold_price
@@ -28,6 +41,7 @@ class Membership < ActiveRecord::Base
28
41
  end
29
42
  end
30
43
 
44
+
31
45
  def adjust_expiration_to(new_ends_at)
32
46
  self.ends_at = new_ends_at
33
47
  self.save
@@ -60,5 +74,4 @@ class Membership < ActiveRecord::Base
60
74
  def order_summary_description
61
75
  self.membership_type.name
62
76
  end
63
-
64
77
  end
data/app/models/sale.rb CHANGED
@@ -69,6 +69,7 @@ class Sale
69
69
  @comp = Comp.new(tickets.first.show, tickets, payment.customer, payment.benefactor)
70
70
  @comp.submit
71
71
  @buyer = @comp.recipient
72
+ self.cart.approve!
72
73
  true
73
74
  end
74
75
 
data/app/models/search.rb CHANGED
@@ -12,7 +12,7 @@ class Search < ActiveRecord::Base
12
12
  :min_donations_date, :max_donations_date, :discount_code,
13
13
  :membership_status, :passholder, :membership_type_id, :membership_type
14
14
 
15
- attr_accessor :membership_status, :passholder
15
+ attr_accessor :passholder
16
16
 
17
17
  def length
18
18
  people.length
@@ -77,6 +77,16 @@ class Search < ActiveRecord::Base
77
77
  conditions << string
78
78
  end
79
79
 
80
+ if membership_status.present?
81
+ state_str = (membership_status == "None") ? "not" : membership_status.downcase
82
+ conditions << "Are #{state_str} members"
83
+ end
84
+
85
+ if membership_type_id.present?
86
+ people = people.joins(:member => [:memberships => [:membership_type]])
87
+ people = people.where('membership_types.id = ?', membership_type_id)
88
+ end
89
+
80
90
  String.new.tap do |s|
81
91
  if conditions.blank?
82
92
  if person_type == "Company"
@@ -143,9 +153,21 @@ class Search < ActiveRecord::Base
143
153
  people = people.having("SUM(items.price + items.nongift_amount) <= ?", max_donations_amount * 100.0) unless max_donations_amount.blank?
144
154
  end
145
155
 
146
- unless membership_type_id.blank?
156
+ ### MEMBERSHIP ##
157
+
158
+ if membership_status.present?
159
+ #Necessary because we need a left join for the "Not" condition to work
160
+ people = people.joins('left join members on members.person_id = people.id')
161
+
162
+ people = people.merge(Member.current) if membership_status == "Current"
163
+ people = people.merge(Member.lapsed) if membership_status == "Lapsed"
164
+ people = people.merge(Member.past) if membership_status == "Past"
165
+ people = people.where("members.id is null") if membership_status == "Not"
166
+ end
167
+
168
+ if membership_type_id.present?
147
169
  people = people.joins(:member => [:memberships => [:membership_type]])
148
- .where('membership_types.id = ?', membership_type_id)
170
+ people = people.where('membership_types.id = ?', membership_type_id)
149
171
  end
150
172
 
151
173
  people.select(column_names).uniq
data/app/models/show.rb CHANGED
@@ -17,6 +17,12 @@ class Show < ActiveRecord::Base
17
17
  has_many :settlements
18
18
  has_many :items
19
19
  has_many :ticket_types
20
+
21
+ #
22
+ # Because we need to use alias, you'll need to .includes(:show_stats_view) instead of .includes(:stats)
23
+ #
24
+ has_one :show_stats_view
25
+ alias :stats :show_stats_view
20
26
 
21
27
  before_destroy :destroyable?
22
28
  after_create :update_ticket_types
@@ -187,6 +193,9 @@ class Show < ActiveRecord::Base
187
193
  settleables
188
194
  end
189
195
 
196
+ #
197
+ # Horribly inefficient. Don't use with a list of shows.
198
+ #
190
199
  def destroyable?
191
200
  (tickets_comped + tickets_sold).empty? && items.empty?
192
201
  end
data/app/models/ticket.rb CHANGED
@@ -42,6 +42,9 @@
42
42
  scope :uncommitted, where("state != 'sold'").where("state != 'comped'")
43
43
 
44
44
  state_machine do
45
+ #
46
+ # show_stats_view depends on these states
47
+ #
45
48
  state :off_sale
46
49
  state :on_sale
47
50
  state :sold
data/app/models/user.rb CHANGED
@@ -23,11 +23,11 @@
23
23
  attr_accessible :email, :password, :password_confirmation, :remember_me, :user_agreement, :newsletter_emails, :first_name, :last_name, :user_memberships_attributes
24
24
 
25
25
  def is_in_organization?
26
- !!(user_memberships.any? && ! user_memberships.first.organization.new_record?)
26
+ @is_in_organization ||= !!(user_memberships.any? && ! user_memberships.first.organization.new_record?)
27
27
  end
28
28
 
29
29
  def current_organization
30
- is_in_organization? ? user_memberships.first.organization : Organization.new
30
+ @current_organization ||= is_in_organization? ? user_memberships.first.organization : Organization.new
31
31
  end
32
32
 
33
33
  def membership_in(organization)
@@ -5,7 +5,7 @@
5
5
  .accordion-group
6
6
  .accordion-heading
7
7
  = link_to "Event Details", '#collapseEventDetails', :class => 'accordion-toggle', 'data-toggle' => 'collapse', 'data-parent'=>'#event-accordion'
8
- #collapseEventDetails.accordion-body.collapse{:class => in?(:details)}
8
+ #collapseEventDetails.accordion-body.collapse{:class => in_section?(:details)}
9
9
  .accordion-inner
10
10
  %ul.accordion-menu
11
11
  = active_link_to 'About', edit_event_path(@event)
@@ -16,7 +16,7 @@
16
16
  .accordion-group
17
17
  .accordion-heading
18
18
  = link_to 'Shows', "#collapseShowList", :class => 'accordion-toggle', 'data-toggle' => 'collapse', 'data-parent'=>'#event-accordion'
19
- #collapseShowList.accordion-body.collapse{:class => in?(:shows)}
19
+ #collapseShowList.accordion-body.collapse{:class => in_section?(:shows)}
20
20
  .accordion-inner
21
21
  %ul.accordion-menu
22
22
  %li.add
@@ -1,7 +1,7 @@
1
1
  .accordion-group
2
2
  .accordion-heading
3
3
  = link_to 'Share & Sell', "#collapseShareSell", :class => 'accordion-toggle', 'data-toggle' => 'collapse', 'data-parent'=>'#event-accordion'
4
- #collapseShareSell.accordion-body.collapse{:class => in?(:share)}
4
+ #collapseShareSell.accordion-body.collapse{:class => in_section?(:share)}
5
5
  .accordion-inner
6
6
  %ul.accordion-menu
7
7
  = active_link_to 'Storefront', storefront_link_event_path(event)
@@ -19,6 +19,7 @@
19
19
  ="Spruce up this event with an image! This image will be displayed on both #{link_to "your Storefront", store_event_url(@event)} (where patrons will purchase tickets) and within your Artful.ly management pages.".html_safe
20
20
  %ul{:style => "list-style-type: circle;"}
21
21
  %li Image size is limited to 1 MB
22
+ %li We recommend your image be at least 300 pixels wide
22
23
  %li Only .jpg, .jpeg, .gif, and .png file formats are supported
23
24
  %li Your image will be displayed with equal height and width
24
25
  %li You can come back to this page to change the image at any time
@@ -38,7 +38,9 @@
38
38
  =link_to 'Add venue address', edit_event_venue_path(@event)
39
39
  .span6
40
40
  %strong=@event.venue.name
41
- %div=@event.venue.street_as_string
41
+ %div=@event.venue.address1
42
+ -unless @event.venue.address2.blank?
43
+ %div=@event.venue.address2
42
44
  %div=@event.venue.city_state_zip_as_string
43
45
  - if @event.destroyable?
44
46
  .row-fluid
@@ -21,6 +21,8 @@
21
21
  %ul.dropdown-menu
22
22
  %li= link_to "My Membership", members_root_path
23
23
  %li= link_to "Sign Out", destroy_member_session_path
24
+ -else
25
+ %li= link_to "Member Login", new_member_session_path
24
26
 
25
27
 
26
28
  .content.container
@@ -12,13 +12,13 @@
12
12
  %td TODO
13
13
  %tr
14
14
  %td Member Through
15
- %td=l current_member.active_memberships.first.ends_at, :format => :date
15
+ %td=l current_member.memberships.current.first.ends_at, :format => :date
16
16
  %tr
17
17
  %td Membership
18
- %td=current_member.active_memberships.first.membership_type.name
18
+ %td=current_member.memberships.current.first.membership_type.name
19
19
  %tr
20
20
  %td Memberhsips
21
- %td=current_member.active_memberships.length
21
+ %td=current_member.memberships.current.count
22
22
  %tr
23
23
  %td Auto-renewal
24
24
  %td
@@ -83,42 +83,42 @@
83
83
  = f.number_field :zip, in: 00001..99999, placeholder: "Zipcode", class: "input-small"
84
84
  = f.select :state, options_for_select(sorted_us_state_names, selected: search.state), {include_blank: "State"}, {class: "input-medium"}
85
85
 
86
- / %h4 Membership
87
- / .accordion#accordion3
88
- / .accordion-group
89
- / .accordion-heading
90
- / %a.accordion-toggle{"data-toggle"=>"collapse","data-parent"=>"#accordion3",:href=>"#collapseSeven"}
91
- / Status
92
- / #collapseSeven.accordion-body.collapse
93
- / .accordion-inner
94
- / = f.select :membership_status, ["Current", "Lapsed", "Past", "Never"], include_blank: ""
86
+ %h4 Membership
87
+ .accordion#accordion3
88
+ .accordion-group
89
+ .accordion-heading
90
+ %a.accordion-toggle{"data-toggle"=>"collapse","data-parent"=>"#accordion3",:href=>"#collapseSeven"}
91
+ Status
92
+ #collapseSeven.accordion-body.collapse
93
+ .accordion-inner
94
+ = f.select :membership_status, Member.states.collect(&:capitalize), include_blank: ""
95
95
 
96
- / .accordion-group
97
- / .accordion-heading
98
- / %a.accordion-toggle{"data-toggle"=>"collapse","data-parent"=>"#accordion3",:href=>"#collapseEight"}
99
- / Type
100
- / #collapseEight.accordion-body.collapse
101
- / .accordion-inner
102
- / = f.select :membership_type_id, options_from_collection_for_select(@membership_types, 'id', 'name', @search.membership_type), include_blank: ""
96
+ .accordion-group
97
+ .accordion-heading
98
+ %a.accordion-toggle{"data-toggle"=>"collapse","data-parent"=>"#accordion3",:href=>"#collapseEight"}
99
+ Type
100
+ #collapseEight.accordion-body.collapse
101
+ .accordion-inner
102
+ = f.select :membership_type_id, options_from_collection_for_select(@membership_types, 'id', 'name', @search.membership_type), include_blank: ""
103
103
 
104
- / .accordion-group
105
- / .accordion-heading
106
- / %a.accordion-toggle{"data-toggle"=>"collapse","data-parent"=>"#accordion3",:href=>"#collapseNine"}
107
- / Start/End
108
- / #collapseNine.accordion-body.collapse
109
- / .accordion-inner
110
- / = date_field_tag "search[min_donations_date]", search.min_donations_date.try(:strftime, "%F"), max: Time.now.strftime("%F")
111
- / %span.range-separator to
112
- / = date_field_tag "search[max_donations_date]", search.max_donations_date.try(:strftime, "%F"), max: Time.now.strftime("%F")
104
+ / .accordion-group
105
+ / .accordion-heading
106
+ / %a.accordion-toggle{"data-toggle"=>"collapse","data-parent"=>"#accordion3",:href=>"#collapseNine"}
107
+ / Start/End
108
+ / #collapseNine.accordion-body.collapse
109
+ / .accordion-inner
110
+ / = date_field_tag "search[min_donations_date]", search.min_donations_date.try(:strftime, "%F"), max: Time.now.strftime("%F")
111
+ / %span.range-separator to
112
+ / = date_field_tag "search[max_donations_date]", search.max_donations_date.try(:strftime, "%F"), max: Time.now.strftime("%F")
113
113
 
114
- / .accordion-group
115
- / .accordion-heading
116
- / %a.accordion-toggle{"data-toggle"=>"collapse","data-parent"=>"#accordion3",:href=>"#collapseTen"}
117
- / Year
118
- / #collapseTen.accordion-body.collapse
119
- / .accordion-inner
120
- / = f.select :membership_status, ["2013", "2012", "2010", "2009"], include_blank: ""
114
+ / .accordion-group
115
+ / .accordion-heading
116
+ / %a.accordion-toggle{"data-toggle"=>"collapse","data-parent"=>"#accordion3",:href=>"#collapseTen"}
117
+ / Year
118
+ / #collapseTen.accordion-body.collapse
119
+ / .accordion-inner
120
+ / = f.select :membership_status, ["2013", "2012", "2010", "2009"], include_blank: ""
121
121
 
122
122
  .control
123
- = f.submit "Search", :class => 'btn'
123
+ = f.submit "Search", :id => "advanced-search-submit", :class => 'btn'
124
124
  = link_to "Simple Search", people_path
@@ -1,27 +1,11 @@
1
1
 
2
2
  - if not show.played?
3
- = form_tag built_event_shows_path(@event), :remote => true, :'data-type' => :json, :class => "sprited pending" do
4
- = hidden_field_tag :show_id, show.id
5
- = submit_tag "Create Tickets", :class => [ 'btn', 'btn-mini' ]
6
-
7
- = form_tag on_sale_event_shows_path(@event), :remote => true, :'data-type' => :json, :class => "sprited built" do
8
- = hidden_field_tag :show_id, show.id
9
- = submit_tag "Put On Sale", :class => [ 'btn', 'btn-mini' ]
10
- .confirmation.dialog
11
- %p= "You are about to put all tickets for the #{l show.datetime_local_to_event} showing of #{show.event.name} on sale and make it public."
12
-
13
3
  = form_tag unpublished_event_show_path(show.event, show), :remote => true, :'data-type' => :json, :class => "sprited published", :id => "show_#{show.id}" do
14
4
  = submit_tag "Unpublish", :class => [ 'btn', 'btn-mini' ]
15
5
  .confirmation.dialog
16
- %p= "You are unpublishing the #{l show.datetime_local_to_event} showing of #{show.event.name}."
6
+ %p= "You are unpublishing the #{l show.stats.datetime_local_to_event} show."
17
7
 
18
8
  = form_tag published_event_show_path(show.event, show), :remote => true, :'data-type' => :json, :class => "sprited built unpublished" do
19
9
  = submit_tag "Publish", :class => [ 'btn', 'btn-mini' ]
20
10
  .confirmation.dialog
21
- %p= "You are publishing the #{l show.datetime_local_to_event} showing of #{show.event.name}."
22
-
23
- = form_tag event_show_path(@event, show), :method => :delete, :remote => true, :'data-type' => :json, :class => "sprited destroyable" do
24
- = hidden_field_tag :show_id, show.id
25
- = submit_tag "Delete", :class => [ 'btn', 'btn-mini', 'btn-danger' ]
26
- .confirmation.dialog
27
- %p= "Are you sure you want to delete this show? Any tickets that have been created will also be deleted."
11
+ %p= "You are publishing the #{l show.stats.datetime_local_to_event} show."
@@ -9,31 +9,36 @@
9
9
  .span9
10
10
  = render "shared/error_messages", :target => @event
11
11
  .row-fluid
12
- .span3
13
- %h3 Shows List
14
- .span9
15
- =icon_link_to("Add", new_event_show_path(@event, @show), 'icon-plus-sign', 'btn', '')
12
+ .span12
13
+ .btn-group.pull-right
14
+ =link_to "Upcoming", event_shows_path(@event), :class => "btn #{"active" if !@all}"
15
+ =link_to "All", all_event_shows_path(@event), :class => "btn #{"active" if @all}"
16
16
  %table.table
17
17
  %thead
18
- %th Date/Time
18
+ %th{:colspan => 2} Date/Time
19
19
  %th
20
- %th On sale
21
- %th Sold
22
- %th Comped
20
+ %th.right On sale
21
+ %th.right Sold
22
+ %th.right Comped
23
23
  %tbody
24
24
  -if @shows.empty?
25
25
  %tr
26
- %td{:colspan => 5}
26
+ %td{:colspan => 6}
27
27
  .no-image.full
28
28
  #text
29
- =link_to 'You have no shows scheduled. Add one now.', new_event_show_path(@event, @show)
29
+ =link_to 'You have no upcoming shows scheduled.', new_event_show_path(@event, @show)
30
30
  -@shows.each do |show|
31
- %tr.sprited-container{ :class => [show.state, show.destroyable? ? "destroyable" : "" ] }
31
+ %tr.sprited-container{ :class => [show.state] }
32
32
  %td
33
- =link_to l(show.datetime_local_to_event, :format => :short), event_show_path(@event, show), :title => 'show-datetime'
33
+ =link_to l(show.stats.datetime_local_to_event, :format => :abbreviated_day), event_show_path(@event, show), :title => 'show-datetime'
34
+ %td
35
+ =link_to l(show.stats.datetime_local_to_event, :format => :short), event_show_path(@event, show), :title => 'show-datetime'
34
36
  %td{:style => 'text-align:right'}
35
37
  =render :partial => "shows/controls", :locals => { :show => show }
36
- %td.available_value= show.glance.available_total
37
- %td.gross_value= show.glance.sold_total
38
- %td.comped_value= show.glance.comped_total
38
+
39
+ %td.right.available_value= show.stats.on_sale
40
+ %td.right.gross_value= show.stats.sold
41
+ %td.right.comped_value= show.stats.comped
42
+
43
+ =will_paginate @shows
39
44
 
@@ -3,5 +3,7 @@
3
3
  =link_to image_tag("https://maps.google.com/maps/api/staticmap?size=140x140&maptype=roadmap&markers=color:red|#{event.venue.address_as_url_query}&sensor=false&zoom=15"), "https://maps.google.com/maps?q=#{event.venue.address_as_url_query.html_safe}&z=15"
4
4
  %div
5
5
  %strong=event.venue.name
6
- %div=event.venue.street_as_string
6
+ %div=event.venue.address1
7
+ -unless event.venue.address2.blank?
8
+ %div=event.venue.address2
7
9
  %div=event.venue.city_state_zip_as_string
@@ -7,9 +7,8 @@
7
7
 
8
8
  #event-header.side-section
9
9
  %h1#logo= @event.name
10
- %h4= @event.shows.first.show_time
11
10
  %h4= @event.producer
12
- %h4= @event.venue.city_state_zip_as_string
11
+ %h4= @event.shows.first.show_time
13
12
 
14
13
  #about-event.side-section
15
14
  #description
@@ -22,13 +22,15 @@
22
22
  time:
23
23
  formats:
24
24
  default: "%B %d, %Y %I:%M %p"
25
- short: "%m/%d/%Y %I:%M %p"
25
+ short: "%m/%d/%Y %l:%M %p"
26
26
  slashed_date: "%m/%d/%Y"
27
27
  day_time: "%a, %b %d %l:%M %P"
28
28
  day_time_at: "%a, %b %d at %I:%M %P"
29
29
  date: "%B %d, %Y"
30
30
  long_date: "%B %d, %Y %I:%M %p"
31
- long_with_day: "%A, %b %d %Y %I:%M %p"
31
+ long_with_day: "%A, %b %d %Y %l:%M %p"
32
+ long_with_abbrviated_day: "%a, %b %d %Y %l:%M %p"
33
+ abbreviated_day: "%a"
32
34
  time: "%I:%M %p"
33
35
  day: "%A"
34
36
  date_for_input: "%Y-%m-%d"
data/config/routes.rb CHANGED
@@ -85,8 +85,6 @@ Rails.application.routes.draw do
85
85
  end
86
86
  end
87
87
 
88
- resources :memberships, :only => :index
89
-
90
88
  def people_actions
91
89
  resources :actions
92
90
  resources :memberships do
@@ -166,6 +164,8 @@ Rails.application.routes.draw do
166
164
  post :built
167
165
  post :on_sale
168
166
  get :calendar
167
+ get :all, :to => :index, :range => :all
168
+ get :upcoming
169
169
  end
170
170
  end
171
171
  resource :venue, :only => [:edit, :update]
@@ -0,0 +1,16 @@
1
+ class CreateShowStatsView < ActiveRecord::Migration
2
+ def change
3
+ execute "CREATE OR REPLACE VIEW show_stats_view as select " +
4
+ "shows.id, shows.id as show_id, shows.event_id as event_id, shows.organization_id as organization_id, shows.datetime, shows.state as state, count(tickets.id) as capacity, venues.time_zone as time_zone, " +
5
+ "SUM(CASE WHEN tickets.state='sold' then 1 else 0 end) as sold, " +
6
+ "SUM(CASE WHEN tickets.state='comped' then 1 else 0 end) as comped, " +
7
+ "SUM(CASE WHEN tickets.state='on_sale' then 1 else 0 end) as on_sale, " +
8
+ "SUM(CASE WHEN tickets.state='off_sale' then 1 else 0 end) as off_sale, " +
9
+ "SUM(CASE WHEN tickets.state='on_sale' or tickets.state='off_sale' then 1 else 0 end) as 'open' " +
10
+ "from shows " +
11
+ "left join tickets on shows.id = tickets.show_id " +
12
+ "left join events on shows.event_id = events.id " +
13
+ "left join venues on events.venue_id = venues.id " +
14
+ "group by shows.id"
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ class AddCountersToMember < ActiveRecord::Migration
2
+ def change
3
+ add_column :members, :current_memberships_count, :integer, :default => 0
4
+ add_column :members, :lapsed_memberships_count, :integer, :default => 0
5
+ add_column :members, :past_memberships_count, :integer, :default => 0
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ class RemoveExpiresAtFromMembership < ActiveRecord::Migration
2
+ def change
3
+ #Use ends_at instead
4
+ remove_column :memberships, :expires_at
5
+ end
6
+ end
@@ -1,3 +1,3 @@
1
1
  module ArtfullyOse
2
- VERSION = "1.2.0.pre.5"
2
+ VERSION = "1.2.0.pre.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: artfully_ose
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0.pre.5
4
+ version: 1.2.0.pre.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artful.ly
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-01 00:00:00.000000000 Z
11
+ date: 2013-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -1902,6 +1902,7 @@ files:
1902
1902
  - app/controllers/ticket_types_controller.rb
1903
1903
  - app/controllers/tickets_controller.rb
1904
1904
  - app/controllers/user_memberships_controller.rb
1905
+ - app/controllers/users/sessions_controller.rb
1905
1906
  - app/controllers/venues_controller.rb
1906
1907
  - app/helpers/artfully_ose_helper.rb
1907
1908
  - app/helpers/devise_helper.rb
@@ -2385,6 +2386,9 @@ files:
2385
2386
  - db/migrate/20130827190839_add_fee_to_tickets_and_donations.rb
2386
2387
  - db/migrate/20130829015011_migrate_fees_to_items.rb
2387
2388
  - db/migrate/20130917165559_add_service_fee_to_memberships.rb
2389
+ - db/migrate/20131002191646_create_show_stats_view.rb
2390
+ - db/migrate/20131007141421_add_counters_to_member.rb
2391
+ - db/migrate/20131007144456_remove_expires_at_from_membership.rb
2388
2392
  - lib/artfully_ose/common_abilities.rb
2389
2393
  - lib/artfully_ose/core_ext.rb
2390
2394
  - lib/artfully_ose/engine.rb