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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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