artfully_ose 1.2.0.pre.4 → 1.2.0.pre.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +8 -8
  2. data/app/assets/images/household-default-avatar.png +0 -0
  3. data/app/assets/images/person-default-avatar.psd +0 -0
  4. data/app/assets/javascripts/angular-resource.min.js +11 -0
  5. data/app/assets/javascripts/angular.min.js +178 -0
  6. data/app/assets/javascripts/application.js +43 -4
  7. data/app/assets/javascripts/store/store.js +5 -4
  8. data/app/assets/stylesheets/application.sass +6 -0
  9. data/app/assets/stylesheets/bootstrap-overrides.css +12 -2
  10. data/app/assets/stylesheets/sass/store.sass +42 -7
  11. data/app/controllers/artfully_ose_controller.rb +2 -7
  12. data/app/controllers/events_controller.rb +3 -21
  13. data/app/controllers/memberships_controller.rb +1 -0
  14. data/app/controllers/organizations_controller.rb +3 -3
  15. data/app/controllers/store/events_controller.rb +2 -0
  16. data/app/helpers/artfully_ose_helper.rb +6 -0
  17. data/app/models/action.rb +1 -1
  18. data/app/models/event.rb +5 -7
  19. data/app/models/kit.rb +1 -3
  20. data/app/models/membership.rb +3 -3
  21. data/app/models/membership_award.rb +1 -0
  22. data/app/models/note.rb +1 -1
  23. data/app/models/order_handler.rb +1 -2
  24. data/app/models/organization.rb +7 -8
  25. data/app/models/user.rb +16 -4
  26. data/app/models/user_membership.rb +4 -3
  27. data/app/views/imports/people/_new.html.haml +5 -5
  28. data/app/views/layouts/_flash.html.haml +1 -1
  29. data/app/views/layouts/application.html.haml +2 -2
  30. data/app/views/layouts/devise_layout.html.haml +2 -2
  31. data/app/views/membership_awards/confirm.html.haml +48 -2
  32. data/app/views/membership_awards/new.html.haml +12 -7
  33. data/app/views/memberships/index.html.haml +98 -38
  34. data/app/views/organizations/_connection_form.html.haml +1 -1
  35. data/app/views/organizations/_form.html.haml +52 -20
  36. data/app/views/organizations/edit.html.haml +2 -2
  37. data/app/views/producer_mailer/donation_kit_notification.html.haml +8 -0
  38. data/app/views/producer_mailer/donation_kit_notification.text.erb +8 -0
  39. data/app/views/producer_mailer/mailchimp_kit_initial_sync_notification.html.haml +21 -0
  40. data/app/views/producer_mailer/ticket_offer_accepted.html.haml +7 -0
  41. data/app/views/producer_mailer/ticket_offer_accepted.text.erb +7 -0
  42. data/app/views/producer_mailer/ticket_offer_rejected.html.haml +11 -0
  43. data/app/views/producer_mailer/ticket_offer_rejected.text.erb +13 -0
  44. data/app/views/shared/_error_messages.html.haml +1 -1
  45. data/app/views/store/events/_venue.html.haml +7 -0
  46. data/app/views/store/events/show.html.haml +6 -11
  47. data/app/views/store/events/single_show.html.haml +41 -0
  48. data/app/views/store/shared/_donate_form.html.haml +1 -1
  49. data/app/views/store/shows/_show.html.haml +37 -29
  50. data/app/views/user_memberships/_list.html.haml +1 -3
  51. data/app/views/users/invitations/edit.html.haml +57 -8
  52. data/app/views/users/mailer/invitation_instructions.html.haml +14 -0
  53. data/app/views/users/passwords/edit.html.haml +2 -2
  54. data/app/views/users/registrations/edit.html.erb +3 -3
  55. data/app/views/users/sessions/new.html.haml +2 -2
  56. data/config/initializers/devise.rb +0 -3
  57. data/config/locales/devise.en.yml +1 -1
  58. data/config/routes.rb +4 -2
  59. data/db/migrate/20130411162346_add_country_zip_state_phone_number_discipline_to_organizations.rb +9 -0
  60. data/db/migrate/20130412184415_add_first_name_and_last_name_to_users.rb +6 -0
  61. data/lib/artfully_ose/version.rb +1 -1
  62. metadata +17 -17
  63. data/app/views/users/mailer/invitation_instructions.html.erb +0 -8
@@ -23,7 +23,7 @@ class EventsController < ArtfullyOseController
23
23
 
24
24
  def index
25
25
  authorize! :view, Event
26
- @events = current_organization.events.includes(:shows, :venue).order('updated_at DESC')
26
+ @events = current_organization.events.includes(:shows, :tickets).order('updated_at DESC')
27
27
  end
28
28
 
29
29
  def show
@@ -52,7 +52,7 @@ class EventsController < ArtfullyOseController
52
52
  def edit
53
53
  authorize! :edit, @event
54
54
  end
55
-
55
+
56
56
  def image
57
57
  authorize! :edit, @event
58
58
  end
@@ -103,28 +103,10 @@ class EventsController < ArtfullyOseController
103
103
 
104
104
  def wp_plugin
105
105
  end
106
-
107
- def prices
108
- end
109
106
 
110
- def temp_discounts_index
111
- find_event
107
+ def prices
112
108
  end
113
109
 
114
- def temp_discount_form
115
- find_event
116
-
117
- @discount = TempDiscount.new
118
- @discount.promotion_type = 'two-for-one'
119
-
120
- @event.charts.collect(&:sections).flatten.each do |section|
121
- @discount.discount_sections.new(
122
- :section => section,
123
- :price => section.price
124
- )
125
- end
126
- end
127
-
128
110
  def messages
129
111
  end
130
112
 
@@ -3,6 +3,7 @@ class MembershipsController < ArtfullyOseController
3
3
 
4
4
  def index
5
5
  @person = Person.find(params[:person_id])
6
+ @membership_types = current_organization.membership_types
6
7
  end
7
8
 
8
9
  def bulk_update
@@ -22,7 +22,7 @@ class OrganizationsController < ArtfullyOseController
22
22
  flash[:error] = "You can only join one organization at this time."
23
23
  redirect_to organizations_url
24
24
  end
25
-
25
+
26
26
  if Organization.all.length > 0
27
27
  flash[:error] = "There is already an organization created for this installation."
28
28
  end
@@ -35,7 +35,7 @@ class OrganizationsController < ArtfullyOseController
35
35
  flash[:error] = "There is already an organization created for this installation."
36
36
  redirect_to new_organization_path and return
37
37
  end
38
-
38
+
39
39
  @organization = Organization.new(params[:organization])
40
40
 
41
41
  if @organization.save
@@ -61,5 +61,5 @@ class OrganizationsController < ArtfullyOseController
61
61
  else
62
62
  render :show
63
63
  end
64
- end
64
+ end
65
65
  end
@@ -2,9 +2,11 @@ class Store::EventsController < Store::StoreController
2
2
  def show
3
3
  session[:last_event_id] = params[:id]
4
4
  @event = Event.storefront_find(params[:id], current_member)
5
+ render (@event.single_show? ? :single_show : :show)
5
6
  end
6
7
 
7
8
  def index
8
9
  @events = Event.for_storefront(@store_organization, current_member)
10
+ @events = []
9
11
  end
10
12
  end
@@ -42,6 +42,12 @@ module ArtfullyOseHelper
42
42
  "#{time_ago_in_words(t)} #{qualifier}"
43
43
  end
44
44
 
45
+ def clean_full_error_messages(errors)
46
+ string = errors.full_messages.collect {|m| m.downcase.gsub(/.*organization/, 'organization')}.to_sentence
47
+ string = string.slice(0,1).capitalize + string.slice(1..-1)
48
+ string = string + "."
49
+ end
50
+
45
51
  #
46
52
  # For use with the nav-pills to select an intem based on a current selection
47
53
  # Will protect against nil by using try on the object
@@ -1,7 +1,7 @@
1
1
  class Action < ActiveRecord::Base
2
2
  include OhNoes::Destroy
3
3
 
4
- belongs_to :person
4
+ belongs_to :person, touch: true
5
5
  belongs_to :creator, :class_name => "User", :foreign_key => "creator_id"
6
6
  belongs_to :organization
7
7
  belongs_to :subject, :polymorphic => true
@@ -68,16 +68,14 @@ class Event < ActiveRecord::Base
68
68
  update_attribute(:deleted_at, Time.now)
69
69
  end
70
70
 
71
- def self.for_storefront(organization, member = nil)
72
- event_rel = Event.joins(:shows).where(:organization_id => organization.id).where('shows.datetime > ?', DateTime.now).group(:event_id).public
73
- event_rel = event_rel.where(:members_only => false) if member.nil?
74
- event_rel.all
71
+ def single_show?
72
+ shows.length == 1
75
73
  end
76
74
 
77
- def self.storefront_find(id, member = nil)
78
- event_rel = Event.includes(:venue, :shows => [:chart => [:sections => :ticket_types]])
75
+ def self.for_storefront(member = nil)
76
+ event_rel = Event.joins(:shows).where(:organization_id => organization.id).where('shows.datetime > ?', DateTime.now).group(:event_id).public
79
77
  event_rel = event_rel.where(:members_only => false) if member.nil?
80
- event_rel.find(id)
78
+ event_rel.all
81
79
  end
82
80
 
83
81
  def destroyable?
@@ -28,8 +28,6 @@ class Kit < ActiveRecord::Base
28
28
  event(:activate_without_pending) { transitions :from => [:fresh, :pending, :cancelled], :to => :activated }
29
29
  end
30
30
 
31
-
32
-
33
31
  if self.requires_approval
34
32
  state_machine do
35
33
  event(:submit_for_approval) { transitions :from => :fresh, :to => :pending }
@@ -39,7 +37,7 @@ class Kit < ActiveRecord::Base
39
37
  class_eval(&block)
40
38
  self
41
39
  end
42
-
40
+
43
41
  def self.activate(options)
44
42
  activation_requirements[:unless] << options.delete(:unless) if options.has_key?(:unless)
45
43
  activation_requirements[:if] << options.delete(:if) if options.has_key?(:if)
@@ -20,7 +20,7 @@ class Membership < ActiveRecord::Base
20
20
  membership_award.people.each do |people|
21
21
  Rails.logger.debug(" MEMBERSHIP FOR #{people}")
22
22
  membership = Membership.for(membership_award.membership_type)
23
- membership.ends_at = membership_Award.ends_at
23
+ membership.ends_at = membership_award.ends_at
24
24
  membership.sold_price = membership_award.sold_price
25
25
 
26
26
  # create order
@@ -38,7 +38,7 @@ class Membership < ActiveRecord::Base
38
38
  end
39
39
 
40
40
  def cart_price
41
- price
41
+ price
42
42
  end
43
43
 
44
44
  def self.realized_fee
@@ -61,4 +61,4 @@ class Membership < ActiveRecord::Base
61
61
  self.membership_type.name
62
62
  end
63
63
 
64
- end
64
+ end
@@ -11,6 +11,7 @@ class MembershipAward
11
11
  :ends_at,
12
12
  :message,
13
13
  :send_email,
14
+ :notes,
14
15
  :sold_price
15
16
 
16
17
  def persisted?
@@ -1,7 +1,7 @@
1
1
  class Note < ActiveRecord::Base
2
2
  attr_accessible :occurred_at, :text
3
3
 
4
- belongs_to :person
4
+ belongs_to :person, touch: true
5
5
  belongs_to :user
6
6
  belongs_to :organization
7
7
  end
@@ -37,7 +37,6 @@ class OrderHandler
37
37
  @discount = nil
38
38
  self.cart.tickets.each do |ticket|
39
39
  @discount = Discount.find_by_code_and_event_id(params[:discount].upcase, ticket.show.event.id)
40
- Rails.logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #{@discount}")
41
40
  unless @discount.nil?
42
41
  @discount.apply_discount_to_cart(self.cart)
43
42
  break
@@ -64,7 +63,7 @@ class OrderHandler
64
63
  if params[:donation_amount]
65
64
  self.cart.clear_donations
66
65
  if params[:donation_amount].to_i == 0
67
- flash[:error] = "Please enter a donation amount."
66
+ self.error = "Please enter a donation amount."
68
67
  return
69
68
  end
70
69
 
@@ -3,9 +3,9 @@ class Organization < ActiveRecord::Base
3
3
  include Valuation::LifetimeFees
4
4
  include Ext::Resellable::Organization
5
5
  include Ext::Integrations::Organization
6
-
7
- attr_accessible :name, :time_zone, :ein, :legal_organization_name, :email, :receive_daily_sales_report
8
-
6
+
7
+ attr_accessible :name, :time_zone, :ein, :legal_organization_name, :email, :receive_daily_sales_report, :country, :state, :zip, :phone_number, :website, :discipline
8
+
9
9
  has_many :events
10
10
  has_many :charts
11
11
  has_many :shows
@@ -29,7 +29,7 @@ class Organization < ActiveRecord::Base
29
29
 
30
30
  has_many :imports
31
31
 
32
- validates_presence_of :name, :email
32
+ validates_presence_of :name, :email, :time_zone, :country, :state, :zip, :phone_number, :discipline
33
33
  validates :ein, :presence => true, :if => :updating_tax_info
34
34
  validates :legal_organization_name, :presence => true, :if => :updating_tax_info
35
35
 
@@ -40,7 +40,6 @@ class Organization < ActiveRecord::Base
40
40
  self.id
41
41
  end
42
42
 
43
-
44
43
  #
45
44
  # We aren't interested in FAFS donations, so override lifetime_orders
46
45
  # to only include Artfully orders see: Valuation::LifetimeValue
@@ -56,7 +55,7 @@ class Organization < ActiveRecord::Base
56
55
  # But those methods have not been added to a release yet.
57
56
  #
58
57
  def tags_for(tagged_association)
59
-
58
+
60
59
  #Yak
61
60
  begin
62
61
  self.send(tagged_association.to_sym)
@@ -65,7 +64,7 @@ class Organization < ActiveRecord::Base
65
64
  end
66
65
 
67
66
  table_name = Kernel.const_get(tagged_association.to_s.classify).table_name
68
-
67
+
69
68
  ActsAsTaggableOn::Tag.joins("INNER JOIN taggings ON tags.id = taggings.tag_id")
70
69
  .joins("INNER JOIN #{table_name} ON #{table_name}.id = taggings.taggable_id")
71
70
  .joins("INNER JOIN organizations ON organizations.id = #{table_name}.organization_id")
@@ -128,7 +127,7 @@ class Organization < ActiveRecord::Base
128
127
  def has_kit?(name)
129
128
  kits.where(:state => "activated").map(&:class).map(&:name).include?(name.to_s.camelize + "Kit")
130
129
  end
131
-
130
+
132
131
  private
133
132
 
134
133
  def check_for_duplicates(kit)
@@ -11,6 +11,8 @@
11
11
  has_many :user_memberships
12
12
  has_many :organizations, :through => :user_memberships
13
13
 
14
+ accepts_nested_attributes_for :user_memberships
15
+
14
16
  scope :logged_in_more_than_once, where("users.sign_in_count > 1")
15
17
 
16
18
  def self.generate_password
@@ -18,20 +20,20 @@
18
20
  end
19
21
 
20
22
  # Setup accessible (or protected) attributes for your model
21
- attr_accessible :email, :password, :password_confirmation, :remember_me, :user_agreement, :newsletter_emails
23
+ attr_accessible :email, :password, :password_confirmation, :remember_me, :user_agreement, :newsletter_emails, :first_name, :last_name, :user_memberships_attributes
22
24
 
23
25
  def is_in_organization?
24
- @is_in_organization ||= user_memberships.any?
26
+ !!(user_memberships.any? && ! user_memberships.first.organization.new_record?)
25
27
  end
26
28
 
27
29
  def current_organization
28
- @current_organization ||= (is_in_organization? ? user_memberships.first.organization : Organization.new)
30
+ is_in_organization? ? user_memberships.first.organization : Organization.new
29
31
  end
30
32
 
31
33
  def membership_in(organization)
32
34
  user_memberships.where(:organization_id => organization.id).limit(1).first
33
35
  end
34
-
36
+
35
37
  def self.like(query = "")
36
38
  return if query.blank?
37
39
  q = "%#{query}%"
@@ -44,4 +46,14 @@
44
46
  def active_for_authentication?
45
47
  super && !suspended?
46
48
  end
49
+
50
+ def to_s
51
+ if first_name.present? || last_name.present?
52
+ [first_name, last_name].reject(&:blank?).join(" ")
53
+ elsif email.present?
54
+ email.to_s
55
+ else
56
+ "No Name ##{id}"
57
+ end
58
+ end
47
59
  end
@@ -1,10 +1,11 @@
1
1
  class UserMembership < ActiveRecord::Base
2
-
3
2
  # Be careful here! :user needs to come out of this if we ever support update action on memberships controller
4
- attr_accessible :user
5
-
3
+ attr_accessible :user, :organization_attributes
4
+
6
5
  belongs_to :user
7
6
  belongs_to :organization
8
7
 
8
+ accepts_nested_attributes_for :organization
9
+
9
10
  validates :user_id, :uniqueness => {:scope => :organization_id}
10
11
  end
@@ -19,10 +19,10 @@
19
19
  %td.field-slim Email
20
20
  %td="The email address of the person. People records in Artful.ly have unique email addresses, so if you're importing an email address that has already been assigned to a person, we'll merge the data for you. #{link_to "Read more", "#merging", {'data-toggle' => 'modal'}}".html_safe
21
21
  %tr
22
- %td.field-slim First
22
+ %td.field-slim First Name
23
23
  %td The first name of the person.
24
24
  %tr
25
- %td.field-slim Last
25
+ %td.field-slim Last Name
26
26
  %td The last name of the person.
27
27
  %tr
28
28
  %td.field-slim Company Name
@@ -36,7 +36,7 @@
36
36
  %td.field-slim Salutation
37
37
  %td The person's salutation (Mr., Mrs., etc...)
38
38
  %tr
39
- %td.field-slim Middle
39
+ %td.field-slim Middle Name
40
40
  %td The person's middle name
41
41
  %tr
42
42
  %td.field-slim Suffix
@@ -45,10 +45,10 @@
45
45
  %td.field-slim Title
46
46
  %td The person's title in the company
47
47
  %tr
48
- %td.field-slim Address1
48
+ %td.field-slim Address 1
49
49
  %td First line of the person's address
50
50
  %tr
51
- %td.field-slim Address2
51
+ %td.field-slim Address 2
52
52
  %td Second line of the person's address
53
53
  %tr
54
54
  %td.field-slim City
@@ -2,4 +2,4 @@
2
2
  - if flash[type]
3
3
  .flash{ "data-alert" => "alert", :class => [bootstrapped_type(type), type, 'alert'] }
4
4
  .close{ "data-dismiss" => "alert"} &times;
5
- = flash[type]
5
+ = flash[type]
@@ -1,5 +1,5 @@
1
- !!!
2
- %html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en", "ng-app" => "artfully"}
1
+ !!! 5
2
+ %html{:lang => "en", "ng-app" => "artfully"}
3
3
  %head
4
4
  %title= "#{yield :title} : #{t 'artfully.page_title'}"
5
5
  :plain
@@ -1,5 +1,5 @@
1
- !!!
2
- %html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en"}
1
+ !!! 5
2
+ %html{:lang => "en", "ng-app" => "artfully"}
3
3
  %head
4
4
  %title= "#{yield :title} : Artful.ly"
5
5
  %link{ :rel => "shortcut icon", :href => "/favicon.ico", :type => "image/x-icon"}
@@ -31,10 +31,44 @@
31
31
  %td Email Preview
32
32
  %td=link_to "Preview Now", "#email-preview", 'data-toggle' => 'modal'
33
33
 
34
+ - if @membership_award.people.length == 1
35
+ %h3 Payment
36
+ .row-fluid
37
+ .span5
38
+ #payment-controls.controls
39
+ %label.radio
40
+ = radio_button_tag(:payment_method, :cash, true, :class => 'payment-method', :humanized_value => 'Cash')
41
+ Cash
42
+ %label.radio
43
+ = radio_button_tag(:payment_method, :comp, false, :class => 'payment-method', :disabled => 'true', :humanized_value => 'Comp')
44
+ Comp
45
+ %label.radio
46
+ = radio_button_tag(:payment_method, :credit_card_manual, false, :class => 'payment-method', :humanized_value => 'Credit card')
47
+ Credit
48
+ .span7
49
+ #payment-info.hidden.well
50
+ .control-group
51
+ = label_tag("credit_card[cardholder_name]", "Name on Card")
52
+ .controls= text_field_tag("credit_card[name]", params[:cardholder_name])
53
+ .control-group
54
+ = label_tag("credit_card[card_number]", "Card Number")
55
+ .controls= text_field_tag("credit_card[number]", params[:card_number])
56
+ .control-group
57
+ = label_tag("credit_card[expiration_date]", "Expiration Date")
58
+ .date_field.controls
59
+ = select_tag("credit_card[month]", options_for_select(1..12, params["month"]), :class => 'input-small inline')
60
+ = select_tag("credit_card[year]", options_for_select(Time.now.year..Time.now.year + 10, params["year"]), :class => 'input-small inline')
61
+
34
62
  %h3 What Happens Now?
35
- %p These people will become members of your organization.
63
+ %p
64
+ =check_mark
65
+ These people will become members of your organization.
66
+ %p
67
+ =check_mark
68
+ The credit card you provided will be charged .
36
69
  -if @membership_award.send_email
37
70
  %p
71
+ =check_mark
38
72
  They will get an email to setup an account with your orgnaization if they have not already done so.
39
73
  =link_to "Click here to see a preview of this email", "#email-preview", 'data-toggle' => 'modal'
40
74
 
@@ -56,4 +90,16 @@
56
90
  .modal-body
57
91
  =@membership_award.message
58
92
  .modal-footer
59
- %button.btn{'data-dismiss'=>'modal'} Close
93
+ %button.btn{'data-dismiss'=>'modal'} Close
94
+
95
+ -content_for :custom_js do
96
+ :javascript
97
+ $(".payment-method").change(function(){
98
+ if($(this).attr('value') != 'credit_card_manual'){
99
+ $("#payment-info").addClass("hidden");
100
+ $("#credit_card_number").val("")
101
+ $("#credit_card_name").val("")
102
+ } else {
103
+ $("#payment-info").removeClass("hidden");
104
+ }
105
+ });