effective_events 0.11.3 → 0.12.1
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.
- checksums.yaml +4 -4
- data/app/controllers/effective/event_registrations_controller.rb +1 -1
- data/app/datatables/admin/effective_event_registrants_datatable.rb +6 -3
- data/app/datatables/admin/effective_event_tickets_datatable.rb +11 -2
- data/app/datatables/admin/effective_events_datatable.rb +2 -0
- data/app/datatables/effective_event_registrants_datatable.rb +17 -3
- data/app/helpers/effective_events_helper.rb +34 -1
- data/app/models/concerns/effective_events_event_registration.rb +52 -10
- data/app/models/effective/event.rb +9 -7
- data/app/models/effective/event_registrant.rb +84 -18
- data/app/models/effective/event_ticket.rb +43 -13
- data/app/views/admin/event_tickets/_form.html.haml +44 -8
- data/app/views/admin/events/_form_event.html.haml +19 -13
- data/app/views/effective/event_registrants/_fields.html.haml +23 -8
- data/app/views/effective/event_registrants/_fields_member_only.html.haml +6 -0
- data/app/views/effective/event_registrants/_fields_member_or_non_member.html.haml +20 -0
- data/app/views/effective/event_registrants/_fields_questions.html.haml +11 -0
- data/app/views/effective/event_registrants/_fields_regular.html.haml +8 -0
- data/app/views/effective/event_registrations/_orders.html.haml +1 -1
- data/app/views/effective/event_registrations/checkout.html.haml +2 -2
- data/app/views/effective/event_registrations/complete.html.haml +18 -0
- data/app/views/effective/event_registrations/submitted.html.haml +2 -5
- data/app/views/effective/events/show.html.haml +2 -10
- data/db/migrate/101_create_effective_events.rb +19 -0
- data/db/seeds.rb +3 -0
- data/lib/effective_events/version.rb +1 -1
- metadata +7 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 69908c02fe6132b7fdb44a6007367c9545722c35209a8dc49e8929b995a10c55
         | 
| 4 | 
            +
              data.tar.gz: 5595e00deceeee4a58ffb8a198ee6b95d4698708d307385822401ba224826238
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: b28faed7b1f567228d0e91f54232e16c9f243c41480f8ec90282ac333d735db98c11de910105a887e92931968d6070a4558b324cbe6cfc89d64fc77bc9a3b798
         | 
| 7 | 
            +
              data.tar.gz: e487ba970da311a13f9a70faa8162941e8f00862b1d44de6ef7536fa0849ba15dcef34f4293b631aca82a7d1e1669a07b7adb3c11f48f562bb4e3c54828d8446
         | 
| @@ -16,7 +16,7 @@ module Effective | |
| 16 16 | 
             
                # If the event is no longer registerable, do not let them continue
         | 
| 17 17 | 
             
                def redirect_unless_registerable
         | 
| 18 18 | 
             
                  return if resource.blank?
         | 
| 19 | 
            -
                  return if resource. | 
| 19 | 
            +
                  return if resource.was_submitted?
         | 
| 20 20 | 
             
                  return if resource.event.blank?
         | 
| 21 21 | 
             
                  return if resource.event.registerable?
         | 
| 22 22 | 
             
                  return if resource.submit_order&.deferred?
         | 
| @@ -26,12 +26,15 @@ module Admin | |
| 26 26 |  | 
| 27 27 | 
             
                  col :purchased_order, visible: false
         | 
| 28 28 |  | 
| 29 | 
            +
                  col :user, label: 'Member'
         | 
| 29 30 | 
             
                  col :first_name
         | 
| 30 31 | 
             
                  col :last_name
         | 
| 31 32 | 
             
                  col :email
         | 
| 32 | 
            -
                  col :company
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                  col : | 
| 33 | 
            +
                  col :company, visible: false
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  col :response1
         | 
| 36 | 
            +
                  col :response2
         | 
| 37 | 
            +
                  col :response3
         | 
| 35 38 |  | 
| 36 39 | 
             
                  actions_col
         | 
| 37 40 | 
             
                end
         | 
| @@ -16,8 +16,11 @@ module Admin | |
| 16 16 | 
             
                  col :event
         | 
| 17 17 |  | 
| 18 18 | 
             
                  col :title
         | 
| 19 | 
            +
                  col :category, visible: false
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  col :early_bird_price, as: :price, visible: event.early_bird_end_at.present?
         | 
| 19 22 | 
             
                  col :regular_price, as: :price
         | 
| 20 | 
            -
                  col : | 
| 23 | 
            +
                  col :member_price, as: :price
         | 
| 21 24 |  | 
| 22 25 | 
             
                  col :capacity_to_s, label: 'Capacity' do |ticket|
         | 
| 23 26 | 
             
                    if ticket.capacity.present?
         | 
| @@ -25,6 +28,8 @@ module Admin | |
| 25 28 | 
             
                    end
         | 
| 26 29 | 
             
                  end
         | 
| 27 30 |  | 
| 31 | 
            +
                  col :category, visible: false
         | 
| 32 | 
            +
             | 
| 28 33 | 
             
                  col :registered_event_registrants_count, label: 'Registered' do |event|
         | 
| 29 34 | 
             
                    event.event_registrants.registered.unarchived.count
         | 
| 30 35 | 
             
                  end
         | 
| @@ -33,8 +38,12 @@ module Admin | |
| 33 38 | 
             
                    event.event_registrants.purchased.unarchived.count
         | 
| 34 39 | 
             
                  end
         | 
| 35 40 |  | 
| 36 | 
            -
                  col :capacity, visible: false
         | 
| 37 41 | 
             
                  col :capacity_available, visible: false
         | 
| 42 | 
            +
                  col :capacity, label: 'Capacity Total', visible: false
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  col :question1, visible: false
         | 
| 45 | 
            +
                  col :question2, visible: false
         | 
| 46 | 
            +
                  col :question3, visible: false
         | 
| 38 47 |  | 
| 39 48 | 
             
                  actions_col
         | 
| 40 49 | 
             
                end
         | 
| @@ -4,7 +4,13 @@ class EffectiveEventRegistrantsDatatable < Effective::Datatable | |
| 4 4 | 
             
              datatable do
         | 
| 5 5 |  | 
| 6 6 | 
             
                col :name do |er|
         | 
| 7 | 
            -
                   | 
| 7 | 
            +
                  if er.first_name.present?
         | 
| 8 | 
            +
                    "#{er.first_name} #{er.last_name}<br><small>#{mail_to(er.email)}</small>"
         | 
| 9 | 
            +
                  elsif er.owner.present?
         | 
| 10 | 
            +
                    er.owner.to_s + ' - GUEST'
         | 
| 11 | 
            +
                  else
         | 
| 12 | 
            +
                    'Unknown'
         | 
| 13 | 
            +
                  end
         | 
| 8 14 | 
             
                end
         | 
| 9 15 |  | 
| 10 16 | 
             
                col :event_ticket, search: :string, label: 'Ticket' do |er|
         | 
| @@ -14,13 +20,21 @@ class EffectiveEventRegistrantsDatatable < Effective::Datatable | |
| 14 20 | 
             
                  ].compact.join('<br>').html_safe
         | 
| 15 21 | 
             
                end
         | 
| 16 22 |  | 
| 23 | 
            +
                col :user, label: 'Member', visible: false
         | 
| 17 24 | 
             
                col :first_name, visible: false
         | 
| 18 25 | 
             
                col :last_name, visible: false
         | 
| 19 26 | 
             
                col :email, visible: false
         | 
| 20 27 | 
             
                col :company, visible: false
         | 
| 21 | 
            -
                col :number, visible: false, label: 'Designations'
         | 
| 22 28 |  | 
| 23 | 
            -
                col : | 
| 29 | 
            +
                col :response1, visible: false
         | 
| 30 | 
            +
                col :response2, visible: false
         | 
| 31 | 
            +
                col :response3, visible: false
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                col :details do |registrant|
         | 
| 34 | 
            +
                  [registrant.response1.presence, registrant.response2.presence, registrant.response3.presence].compact.map do |response|
         | 
| 35 | 
            +
                    content_tag(:div, response)
         | 
| 36 | 
            +
                  end.join.html_safe
         | 
| 37 | 
            +
                end
         | 
| 24 38 |  | 
| 25 39 | 
             
                col :price, as: :price
         | 
| 26 40 |  | 
| @@ -7,16 +7,37 @@ module EffectiveEventsHelper | |
| 7 7 | 
             
                end
         | 
| 8 8 | 
             
              end
         | 
| 9 9 |  | 
| 10 | 
            +
              def effective_events_ticket_price(event, ticket)
         | 
| 11 | 
            +
                raise('expected an Effective::Event') unless event.kind_of?(Effective::Event)
         | 
| 12 | 
            +
                raise('expected an Effective::EventTicket') unless ticket.kind_of?(Effective::EventTicket)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                prices = [
         | 
| 15 | 
            +
                  (ticket.early_bird_price if event.early_bird?), 
         | 
| 16 | 
            +
                  (ticket.regular_price if ticket.regular? || ticket.member_or_non_member?),
         | 
| 17 | 
            +
                  (ticket.member_price if ticket.member_only? || ticket.member_or_non_member?)
         | 
| 18 | 
            +
                ].compact.sort.uniq
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                if prices.length > 1
         | 
| 21 | 
            +
                  "#{(prices.first == 0 ? '$0' : price_to_currency(prices.first))} to #{(prices.last == 0 ? '$0' : price_to_currency(prices.last))}"
         | 
| 22 | 
            +
                else
         | 
| 23 | 
            +
                  (prices.first == 0 ? '$0' : price_to_currency(prices.first))
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 10 27 | 
             
              def effective_events_event_tickets_collection(event, namespace = nil)
         | 
| 11 28 | 
             
                raise('expected an Effective::Event') unless event.kind_of?(Effective::Event)
         | 
| 12 29 |  | 
| 13 30 | 
             
                # Allow an admin to assign archived tickets
         | 
| 14 31 | 
             
                authorized = (namespace == :admin)
         | 
| 32 | 
            +
                member = current_user.try(:is_any?, :member)
         | 
| 33 | 
            +
             | 
| 15 34 | 
             
                tickets = (authorized ? event.event_tickets : event.event_tickets.reject(&:archived?))
         | 
| 35 | 
            +
                tickets = tickets.reject { |ticket| ticket.member_only? } unless (authorized || member)
         | 
| 16 36 |  | 
| 17 37 | 
             
                tickets.map do |ticket|
         | 
| 18 38 | 
             
                  title = ticket.to_s
         | 
| 19 | 
            -
                  price = ( | 
| 39 | 
            +
                  price = effective_events_ticket_price(event, ticket)
         | 
| 40 | 
            +
             | 
| 20 41 | 
             
                  remaining = (ticket.capacity.present? ? "#{ticket.capacity_available} remaining" : nil)
         | 
| 21 42 |  | 
| 22 43 | 
             
                  label = [title, price, remaining].compact.join(' - ')
         | 
| @@ -44,4 +65,16 @@ module EffectiveEventsHelper | |
| 44 65 | 
             
                  [label, product.to_param, disabled].compact
         | 
| 45 66 | 
             
                end
         | 
| 46 67 | 
             
              end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
              def effective_events_event_tickets_user_hint
         | 
| 70 | 
            +
                url = if current_user.class.try(:effective_memberships_organization_user?)
         | 
| 71 | 
            +
                  organization = current_user.membership_organizations.first || current_user.organizations.first
         | 
| 72 | 
            +
                  effective_memberships.edit_organization_path(organization, anchor: 'tab-representatives') if organization
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
                
         | 
| 75 | 
            +
                return if url.blank?
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                "Can't find the person you need? <a href='#{url}' target='blank'>Click here</a> to add them to your organization."
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
             | 
| 47 80 | 
             
            end
         | 
| @@ -23,7 +23,8 @@ module EffectiveEventsEventRegistration | |
| 23 23 |  | 
| 24 24 | 
             
                acts_as_statused(
         | 
| 25 25 | 
             
                  :draft,      # Just Started
         | 
| 26 | 
            -
                  :submitted | 
| 26 | 
            +
                  :submitted,  # Order has been submitted with a deferred payment processor.
         | 
| 27 | 
            +
                  :completed   # All done. Order purchased.
         | 
| 27 28 | 
             
                )
         | 
| 28 29 |  | 
| 29 30 | 
             
                acts_as_wizard(
         | 
| @@ -33,7 +34,8 @@ module EffectiveEventsEventRegistration | |
| 33 34 | 
             
                  summary: 'Review',
         | 
| 34 35 | 
             
                  billing: 'Billing Address',
         | 
| 35 36 | 
             
                  checkout: 'Checkout',
         | 
| 36 | 
            -
                  submitted: 'Submitted'
         | 
| 37 | 
            +
                  submitted: 'Submitted',
         | 
| 38 | 
            +
                  complete: 'Completed'
         | 
| 37 39 | 
             
                )
         | 
| 38 40 |  | 
| 39 41 | 
             
                acts_as_purchasable_wizard
         | 
| @@ -70,6 +72,7 @@ module EffectiveEventsEventRegistration | |
| 70 72 |  | 
| 71 73 | 
             
                  # Dates
         | 
| 72 74 | 
             
                  submitted_at           :datetime
         | 
| 75 | 
            +
                  completed_at           :datetime
         | 
| 73 76 |  | 
| 74 77 | 
             
                  # Acts as Wizard
         | 
| 75 78 | 
             
                  wizard_steps           :text, permitted: false
         | 
| @@ -85,9 +88,9 @@ module EffectiveEventsEventRegistration | |
| 85 88 | 
             
                }
         | 
| 86 89 |  | 
| 87 90 | 
             
                scope :sorted, -> { order(:id) }
         | 
| 88 | 
            -
             | 
| 89 | 
            -
                scope :in_progress, -> { where | 
| 90 | 
            -
                scope :done, -> { where(status:  | 
| 91 | 
            +
                
         | 
| 92 | 
            +
                scope :in_progress, -> { where(status: [:draft, :submitted]) }
         | 
| 93 | 
            +
                scope :done, -> { where(status: :completed) }
         | 
| 91 94 |  | 
| 92 95 | 
             
                scope :for, -> (user) { where(owner: user) }
         | 
| 93 96 |  | 
| @@ -119,6 +122,16 @@ module EffectiveEventsEventRegistration | |
| 119 122 | 
             
                  end
         | 
| 120 123 | 
             
                end
         | 
| 121 124 |  | 
| 125 | 
            +
                # If we're submitted. Try to move to completed.
         | 
| 126 | 
            +
                before_save(if: -> { submitted? }) { try_completed! }
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                def can_visit_step?(step)
         | 
| 129 | 
            +
                  return false if step == :complete && !completed?
         | 
| 130 | 
            +
                  return true if step == :complete && completed?
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                  can_revisit_completed_steps(step)
         | 
| 133 | 
            +
                end
         | 
| 134 | 
            +
             | 
| 122 135 | 
             
                def required_steps
         | 
| 123 136 | 
             
                  return self.class.test_required_steps if Rails.env.test? && self.class.test_required_steps.present?
         | 
| 124 137 | 
             
                  event&.event_products.present? ? wizard_step_keys : (wizard_step_keys - [:addons])
         | 
| @@ -137,6 +150,14 @@ module EffectiveEventsEventRegistration | |
| 137 150 | 
             
                  end
         | 
| 138 151 | 
             
                end
         | 
| 139 152 |  | 
| 153 | 
            +
                # When the submit_order is deferred or purchased, we call submit!
         | 
| 154 | 
            +
                # When the order is a deferred payment processor, we continue to the :submitted step
         | 
| 155 | 
            +
                # When the order is a regular processor, the before_save will call complete! and we continue to the :complete step
         | 
| 156 | 
            +
                # Purchasing the order later on will automatically call 
         | 
| 157 | 
            +
                def submit_wizard_on_deferred_order?
         | 
| 158 | 
            +
                  true
         | 
| 159 | 
            +
                end
         | 
| 160 | 
            +
             | 
| 140 161 | 
             
                def after_submit_purchased!
         | 
| 141 162 | 
             
                  notifications = event.event_notifications.select(&:registrant_purchased?)
         | 
| 142 163 | 
             
                  notifications.each { |notification| notification.notify!(event_registrants: event_registrants) }
         | 
| @@ -149,11 +170,29 @@ module EffectiveEventsEventRegistration | |
| 149 170 | 
             
              end
         | 
| 150 171 |  | 
| 151 172 | 
             
              def in_progress?
         | 
| 152 | 
            -
                draft?
         | 
| 173 | 
            +
                draft? || submitted?
         | 
| 153 174 | 
             
              end
         | 
| 154 175 |  | 
| 155 176 | 
             
              def done?
         | 
| 156 | 
            -
                 | 
| 177 | 
            +
                completed?
         | 
| 178 | 
            +
              end
         | 
| 179 | 
            +
             | 
| 180 | 
            +
              def try_completed!
         | 
| 181 | 
            +
                return false unless submitted?
         | 
| 182 | 
            +
                return false unless submit_order&.purchased?
         | 
| 183 | 
            +
                complete!
         | 
| 184 | 
            +
              end
         | 
| 185 | 
            +
             | 
| 186 | 
            +
              def complete!
         | 
| 187 | 
            +
                raise('event registration must be submitted to complete!') unless submitted?
         | 
| 188 | 
            +
                raise('expected a purchased order') unless submit_order&.purchased?
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                wizard_steps[:checkout] ||= Time.zone.now
         | 
| 191 | 
            +
                wizard_steps[:submitted] ||= Time.zone.now
         | 
| 192 | 
            +
                wizard_steps[:complete] = Time.zone.now
         | 
| 193 | 
            +
             | 
| 194 | 
            +
                completed!
         | 
| 195 | 
            +
                true
         | 
| 157 196 | 
             
              end
         | 
| 158 197 |  | 
| 159 198 | 
             
              # Find or build
         | 
| @@ -178,7 +217,6 @@ module EffectiveEventsEventRegistration | |
| 178 217 | 
             
                    last_name: owner.try(:last_name),
         | 
| 179 218 | 
             
                    email: owner.try(:email),
         | 
| 180 219 | 
             
                    company: owner.try(:company),
         | 
| 181 | 
            -
                    number: owner.try(:membership).try(:number) || owner.try(:number)
         | 
| 182 220 | 
             
                  )
         | 
| 183 221 | 
             
                end
         | 
| 184 222 |  | 
| @@ -203,7 +241,9 @@ module EffectiveEventsEventRegistration | |
| 203 241 | 
             
              def unavailable_event_tickets
         | 
| 204 242 | 
             
                unavailable = []
         | 
| 205 243 |  | 
| 206 | 
            -
                present_event_registrants. | 
| 244 | 
            +
                changed_event_registrants = present_event_registrants.select { |er| er.new_record? || er.event_ticket_id_changed? }
         | 
| 245 | 
            +
             | 
| 246 | 
            +
                changed_event_registrants.map(&:event_ticket).group_by { |t| t }.each do |event_ticket, event_tickets|
         | 
| 207 247 | 
             
                  unavailable << event_ticket unless event.event_ticket_available?(event_ticket, quantity: event_tickets.length)
         | 
| 208 248 | 
             
                end
         | 
| 209 249 |  | 
| @@ -213,7 +253,9 @@ module EffectiveEventsEventRegistration | |
| 213 253 | 
             
              def unavailable_event_products
         | 
| 214 254 | 
             
                unavailable = []
         | 
| 215 255 |  | 
| 216 | 
            -
                present_event_addons. | 
| 256 | 
            +
                changed_event_products = present_event_addons.select { |er| er.new_record? || er.event_product_id_changed? }
         | 
| 257 | 
            +
             | 
| 258 | 
            +
                changed_event_products.map(&:event_product).group_by { |p| p }.each do |event_product, event_products|
         | 
| 217 259 | 
             
                  unavailable << event_product unless event.event_product_available?(event_product, quantity: event_products.length)
         | 
| 218 260 | 
             
                end
         | 
| 219 261 |  | 
| @@ -66,6 +66,8 @@ module Effective | |
| 66 66 | 
             
                  external_registration       :boolean
         | 
| 67 67 | 
             
                  external_registration_url   :string
         | 
| 68 68 |  | 
| 69 | 
            +
                  allow_blank_registrants     :boolean
         | 
| 70 | 
            +
             | 
| 69 71 | 
             
                  # Access
         | 
| 70 72 | 
             
                  roles_mask             :integer
         | 
| 71 73 | 
             
                  authenticate_user      :boolean
         | 
| @@ -82,7 +84,7 @@ module Effective | |
| 82 84 | 
             
                }
         | 
| 83 85 |  | 
| 84 86 | 
             
                scope :published, -> { where(draft: false).where(arel_table[:published_at].lt(Time.zone.now)) }
         | 
| 85 | 
            -
                scope :unpublished, -> { where(draft: true).where(arel_table[:published_at].gteq(Time.zone.now)) }
         | 
| 87 | 
            +
                scope :unpublished, -> { where(draft: true).or(where(arel_table[:published_at].gteq(Time.zone.now))) }
         | 
| 86 88 |  | 
| 87 89 | 
             
                scope :upcoming, -> { where(arel_table[:end_at].gt(Time.zone.now)) }
         | 
| 88 90 | 
             
                scope :past, -> { where(arel_table[:end_at].lteq(Time.zone.now)) }
         | 
| @@ -134,27 +136,27 @@ module Effective | |
| 134 136 | 
             
                validates :registration_end_at, presence: true, unless: -> { external_registration? }
         | 
| 135 137 |  | 
| 136 138 | 
             
                validate(if: -> { start_at && end_at }) do
         | 
| 137 | 
            -
                   | 
| 139 | 
            +
                  errors.add(:end_at, 'must be after start date') unless start_at < end_at
         | 
| 138 140 | 
             
                end
         | 
| 139 141 |  | 
| 140 142 | 
             
                validate(if: -> { start_at && registration_start_at }) do
         | 
| 141 | 
            -
                   | 
| 143 | 
            +
                  errors.add(:registration_start_at, 'must be before start date') unless registration_start_at < start_at
         | 
| 142 144 | 
             
                end
         | 
| 143 145 |  | 
| 144 146 | 
             
                validate(if: -> { registration_start_at && registration_end_at }) do
         | 
| 145 | 
            -
                   | 
| 147 | 
            +
                  errors.add(:registration_end_at, 'must be after start registration date') unless registration_start_at < registration_end_at
         | 
| 146 148 | 
             
                end
         | 
| 147 149 |  | 
| 148 150 | 
             
                validate(if: -> { start_at && early_bird_end_at }) do
         | 
| 149 | 
            -
                   | 
| 151 | 
            +
                  errors.add(:early_bird_end_at, 'must be before start date') unless early_bird_end_at < start_at
         | 
| 150 152 | 
             
                end
         | 
| 151 153 |  | 
| 152 154 | 
             
                validate(if: -> { file.attached? }) do
         | 
| 153 | 
            -
                   | 
| 155 | 
            +
                  errors.add(:file, 'must be an image') unless file.image?
         | 
| 154 156 | 
             
                end
         | 
| 155 157 |  | 
| 156 158 | 
             
                validate(if: -> { category.present? }) do
         | 
| 157 | 
            -
                   | 
| 159 | 
            +
                  errors.add(:category, 'is not included in the list') unless EffectiveEvents.categories.include?(category)
         | 
| 158 160 | 
             
                end
         | 
| 159 161 |  | 
| 160 162 | 
             
                def to_s
         | 
| @@ -20,21 +20,33 @@ module Effective | |
| 20 20 | 
             
                # This fee when checked out through the event registration
         | 
| 21 21 | 
             
                belongs_to :event_registration, polymorphic: true, optional: true
         | 
| 22 22 |  | 
| 23 | 
            +
                # Required for member-only tickets. The user attending.
         | 
| 24 | 
            +
                belongs_to :user, polymorphic: true, optional: true
         | 
| 25 | 
            +
             | 
| 23 26 | 
             
                effective_resource do
         | 
| 24 | 
            -
                  first_name | 
| 25 | 
            -
                  last_name | 
| 26 | 
            -
                  email | 
| 27 | 
            +
                  first_name            :string
         | 
| 28 | 
            +
                  last_name             :string
         | 
| 29 | 
            +
                  email                 :string
         | 
| 30 | 
            +
                  company               :string
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  blank_registrant      :boolean
         | 
| 33 | 
            +
                  member_registrant     :boolean
         | 
| 27 34 |  | 
| 28 | 
            -
                   | 
| 29 | 
            -
                   | 
| 30 | 
            -
                   | 
| 35 | 
            +
                  # Question Responses
         | 
| 36 | 
            +
                  question1             :text
         | 
| 37 | 
            +
                  question2             :text
         | 
| 38 | 
            +
                  question3             :text
         | 
| 31 39 |  | 
| 32 | 
            -
                  archived | 
| 40 | 
            +
                  archived              :boolean
         | 
| 33 41 |  | 
| 34 42 | 
             
                  # Acts as Purchasable
         | 
| 35 | 
            -
                  price | 
| 36 | 
            -
                  qb_item_name | 
| 37 | 
            -
                  tax_exempt | 
| 43 | 
            +
                  price                 :integer
         | 
| 44 | 
            +
                  qb_item_name          :string
         | 
| 45 | 
            +
                  tax_exempt            :boolean
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  # Historical. Not used anymore. TO BE DELETED.
         | 
| 48 | 
            +
                  number                :string
         | 
| 49 | 
            +
                  notes                 :text
         | 
| 38 50 |  | 
| 39 51 | 
             
                  timestamps
         | 
| 40 52 | 
             
                end
         | 
| @@ -43,17 +55,44 @@ module Effective | |
| 43 55 | 
             
                scope :deep, -> { includes(:event, :event_ticket) }
         | 
| 44 56 | 
             
                scope :registered, -> { purchased_or_deferred.unarchived }
         | 
| 45 57 |  | 
| 46 | 
            -
                validates :first_name, presence: true
         | 
| 47 | 
            -
                validates :last_name, presence: true
         | 
| 48 | 
            -
                validates :email, presence: true, email: true
         | 
| 49 | 
            -
             | 
| 50 58 | 
             
                before_validation(if: -> { event_registration.present? }) do
         | 
| 51 59 | 
             
                  self.event ||= event_registration.event
         | 
| 52 60 | 
             
                  self.owner ||= event_registration.owner
         | 
| 53 61 | 
             
                end
         | 
| 54 62 |  | 
| 55 | 
            -
                before_validation(if: -> {  | 
| 56 | 
            -
                  assign_attributes( | 
| 63 | 
            +
                before_validation(if: -> { blank_registrant? }) do
         | 
| 64 | 
            +
                  assign_attributes(user: nil, first_name: nil, last_name: nil, email: nil)
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                before_validation(if: -> { user.present? }) do
         | 
| 68 | 
            +
                  assign_attributes(first_name: user.first_name, last_name: user.last_name, email: user.email)
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                before_validation(if: -> { event_ticket.present? }, unless: -> { purchased? }) do
         | 
| 72 | 
            +
                  assign_price()
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                validates :user_id, uniqueness: { scope: [:event_id], allow_blank: true, message: 'is already registered for this event' }
         | 
| 76 | 
            +
                validates :price, presence: true, numericality: { greater_than_or_equal_to: 0 }
         | 
| 77 | 
            +
                validates :email, email: true
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                # Member Only Ticket
         | 
| 80 | 
            +
                with_options(if: -> { event_ticket&.member_only? }, unless: -> { blank_registrant? }) do
         | 
| 81 | 
            +
                  validates :user_id, presence: { message: 'Please select a member' }
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                # Regular Ticket
         | 
| 85 | 
            +
                with_options(if: -> { event_ticket&.regular? }, unless: -> { blank_registrant? }) do
         | 
| 86 | 
            +
                  validates :first_name, presence: true
         | 
| 87 | 
            +
                  validates :last_name, presence: true
         | 
| 88 | 
            +
                  validates :email, presence: true
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                with_options(if: -> { event_ticket&.member_or_non_member? && !blank_registrant? }) do
         | 
| 92 | 
            +
                  validates :user_id, presence: { message: 'Please select a member' }, unless: -> { first_name.present? || last_name.present? || email.present? }
         | 
| 93 | 
            +
                  validates :first_name, presence: true, unless: -> { user.present? }
         | 
| 94 | 
            +
                  validates :last_name, presence: true, unless: -> { user.present? }
         | 
| 95 | 
            +
                  validates :email, presence: true, unless: -> { user.present? }
         | 
| 57 96 | 
             
                end
         | 
| 58 97 |  | 
| 59 98 | 
             
                def to_s
         | 
| @@ -65,11 +104,15 @@ module Effective | |
| 65 104 | 
             
                end
         | 
| 66 105 |  | 
| 67 106 | 
             
                def name
         | 
| 68 | 
            -
                  "#{first_name} #{last_name}"
         | 
| 107 | 
            +
                  first_name.present? ? "#{first_name} #{last_name}" : "GUEST"
         | 
| 69 108 | 
             
                end
         | 
| 70 109 |  | 
| 71 110 | 
             
                def last_first_name
         | 
| 72 | 
            -
                  "#{last_name}, #{first_name}"
         | 
| 111 | 
            +
                  first_name.present? ? "#{last_name}, #{first_name}" : "GUEST"
         | 
| 112 | 
            +
                end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                def member_present?
         | 
| 115 | 
            +
                  user&.is?(:member) || (blank_registrant? && member_registrant?)
         | 
| 73 116 | 
             
                end
         | 
| 74 117 |  | 
| 75 118 | 
             
                def tax_exempt
         | 
| @@ -92,5 +135,28 @@ module Effective | |
| 92 135 | 
             
                  true
         | 
| 93 136 | 
             
                end
         | 
| 94 137 |  | 
| 138 | 
            +
                private
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                def assign_price
         | 
| 141 | 
            +
                  raise('is already purchased') if purchased?
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                  raise('expected an event') if event.blank?
         | 
| 144 | 
            +
                  raise('expected an event ticket') if event_ticket.blank?
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                  price = if event.early_bird?
         | 
| 147 | 
            +
                    event_ticket.early_bird_price # Early Bird Pricing
         | 
| 148 | 
            +
                  elsif event_ticket.regular?
         | 
| 149 | 
            +
                    event_ticket.regular_price
         | 
| 150 | 
            +
                  elsif event_ticket.member_only?
         | 
| 151 | 
            +
                    event_ticket.member_price
         | 
| 152 | 
            +
                  elsif event_ticket.member_or_non_member?
         | 
| 153 | 
            +
                    (member_present? ? event_ticket.member_price : event_ticket.regular_price)
         | 
| 154 | 
            +
                  else
         | 
| 155 | 
            +
                    raise("Unexpected event ticket price calculation")
         | 
| 156 | 
            +
                  end
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                  assign_attributes(price: price)
         | 
| 159 | 
            +
                end
         | 
| 160 | 
            +
             | 
| 95 161 | 
             
              end
         | 
| 96 162 | 
             
            end
         | 
| @@ -16,19 +16,29 @@ module Effective | |
| 16 16 |  | 
| 17 17 | 
             
                has_rich_text :body
         | 
| 18 18 |  | 
| 19 | 
            +
                CATEGORIES = ['Regular', 'Member Only', 'Member or Non-Member']
         | 
| 20 | 
            +
             | 
| 19 21 | 
             
                effective_resource do
         | 
| 20 | 
            -
                  title | 
| 21 | 
            -
                  capacity | 
| 22 | 
            +
                  title                       :string
         | 
| 23 | 
            +
                  capacity                    :integer
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  category                    :string
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  # Questions
         | 
| 28 | 
            +
                  question1                   :text
         | 
| 29 | 
            +
                  question2                   :text
         | 
| 30 | 
            +
                  question3                   :text
         | 
| 22 31 |  | 
| 23 32 | 
             
                  # Pricing
         | 
| 24 | 
            -
                   | 
| 25 | 
            -
                   | 
| 33 | 
            +
                  early_bird_price            :integer
         | 
| 34 | 
            +
                  member_price                :integer
         | 
| 35 | 
            +
                  regular_price               :integer
         | 
| 26 36 |  | 
| 27 | 
            -
                  qb_item_name | 
| 28 | 
            -
                  tax_exempt | 
| 37 | 
            +
                  qb_item_name                :string
         | 
| 38 | 
            +
                  tax_exempt                  :boolean
         | 
| 29 39 |  | 
| 30 | 
            -
                  position | 
| 31 | 
            -
                  archived | 
| 40 | 
            +
                  position                    :integer
         | 
| 41 | 
            +
                  archived                    :boolean
         | 
| 32 42 |  | 
| 33 43 | 
             
                  timestamps
         | 
| 34 44 | 
             
                end
         | 
| @@ -37,21 +47,26 @@ module Effective | |
| 37 47 | 
             
                scope :deep, -> { with_rich_text_body.includes(:event, :purchased_event_registrants) }
         | 
| 38 48 |  | 
| 39 49 | 
             
                before_validation(if: -> { event.present? }) do
         | 
| 50 | 
            +
                  self.category ||= CATEGORIES.first
         | 
| 40 51 | 
             
                  self.position ||= (event.event_tickets.map(&:position).compact.max || -1) + 1
         | 
| 41 52 | 
             
                end
         | 
| 42 53 |  | 
| 43 54 | 
             
                validates :title, presence: true, uniqueness: { scope: [:event_id] }
         | 
| 44 | 
            -
                validates : | 
| 55 | 
            +
                validates :category, presence: true
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                validates :regular_price, presence: true, if: -> { member_or_non_member? || regular? }
         | 
| 58 | 
            +
                validates :regular_price, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                validates :member_price, presence: true, if: -> { member_or_non_member? || member_only? }
         | 
| 61 | 
            +
                validates :member_price, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
         | 
| 62 | 
            +
             | 
| 45 63 | 
             
                validates :early_bird_price, presence: true, if: -> { event&.early_bird_end_at.present? }
         | 
| 64 | 
            +
                validates :early_bird_price, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
         | 
| 46 65 |  | 
| 47 66 | 
             
                def to_s
         | 
| 48 67 | 
             
                  title.presence || 'New Event Ticket'
         | 
| 49 68 | 
             
                end
         | 
| 50 69 |  | 
| 51 | 
            -
                def price
         | 
| 52 | 
            -
                  event.early_bird? ? early_bird_price : regular_price
         | 
| 53 | 
            -
                end
         | 
| 54 | 
            -
             | 
| 55 70 | 
             
                def capacity_available
         | 
| 56 71 | 
             
                  return nil if capacity.blank?
         | 
| 57 72 | 
             
                  [(capacity - registered_event_registrants_count), 0].max
         | 
| @@ -65,5 +80,20 @@ module Effective | |
| 65 80 | 
             
                  purchased_event_registrants.length
         | 
| 66 81 | 
             
                end
         | 
| 67 82 |  | 
| 83 | 
            +
                def questions
         | 
| 84 | 
            +
                  [question1.presence, question2.presence, question3.presence].compact
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                def regular?
         | 
| 88 | 
            +
                  category == 'Regular'
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                def member_only?
         | 
| 92 | 
            +
                  category == 'Member Only'
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                def member_or_non_member?
         | 
| 96 | 
            +
                  category == 'Member or Non-Member'
         | 
| 97 | 
            +
                end
         | 
| 68 98 | 
             
              end
         | 
| 69 99 | 
             
            end
         | 
| @@ -1,16 +1,52 @@ | |
| 1 1 | 
             
            = effective_form_with(model: [:admin, event_ticket], engine: true) do |f|
         | 
| 2 2 | 
             
              = f.hidden_field :event_id
         | 
| 3 3 |  | 
| 4 | 
            -
              =  | 
| 5 | 
            -
             | 
| 4 | 
            +
              = card(et(Effective::EventTicket)) do
         | 
| 5 | 
            +
                = f.text_field :title
         | 
| 6 6 |  | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 7 | 
            +
                .row
         | 
| 8 | 
            +
                  .col= f.select :category, Effective::EventTicket::CATEGORIES, hint: "Determines who can purchase this ticket at which price. Also determines if the dropdown of all members is displayed to the purchaser."
         | 
| 9 | 
            +
                  .col= f.number_field :capacity, hint: "The number of registrations will be limited to capacity.<br>Leave blank for unlimited capacity."
         | 
| 10 10 |  | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 11 | 
            +
                = f.show_if(:category, 'Regular') do
         | 
| 12 | 
            +
                  .alert.alert-info.mb-4
         | 
| 13 | 
            +
                    %strong Regular Ticket:
         | 
| 14 | 
            +
                    Anyone will be able to purchase this ticket. They will be asked for a first name, last name and email. Will not display the dropdown list of all members. Only the regular price applies.
         | 
| 13 15 |  | 
| 14 | 
            -
             | 
| 16 | 
            +
                = f.show_if(:category, 'Member Only') do
         | 
| 17 | 
            +
                  .alert.alert-info.mb-4
         | 
| 18 | 
            +
                    %strong Member Only Ticket:
         | 
| 19 | 
            +
                    Only members will be able to purchase this ticket. They must select a member from the dropdown list of all members. Only the member price applies.
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                = f.show_if(:category, 'Member or Non-Member') do
         | 
| 22 | 
            +
                  .alert.alert-info.mb-4
         | 
| 23 | 
            +
                    %strong Member or Non-Member Ticket:
         | 
| 24 | 
            +
                    Anyone will be able to purchase this ticket. They can select a member from the dropdown list of all members to receive the member pricing.
         | 
| 25 | 
            +
                    Or, they can enter a first name, last name and email to receive the regular pricing.
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                .row
         | 
| 28 | 
            +
                  .col-md-6
         | 
| 29 | 
            +
                    - if f.object.event&.early_bird_end_at.present?
         | 
| 30 | 
            +
                      = f.price_field :early_bird_price, hint: 'A price of $0 will allow a checkout for free. Leave blank for no early bird price.'
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                    = f.show_if_any(:category, ['Regular', 'Member or Non-Member']) do
         | 
| 33 | 
            +
                      = f.price_field :regular_price, hint: 'A price of $0 will allow a checkout for free.'
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    = f.show_if_any(:category, ['Member Only', 'Member or Non-Member']) do
         | 
| 36 | 
            +
                      = f.price_field :member_price, hint: 'A price of $0 will allow a checkout for free when selecting a member.'
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                .row
         | 
| 39 | 
            +
                  - if defined?(EffectiveQbSync)
         | 
| 40 | 
            +
                    .col= f.text_field :qb_item_name, label: 'QuickBooks item name'
         | 
| 41 | 
            +
                  .col= f.check_box :tax_exempt
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                = f.check_box :archived, label: 'Archive this ticket. It will be unavailable for purchase.'
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              = card('Questions') do
         | 
| 46 | 
            +
                %p Add upto 3 questions
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                = f.text_field :question1, label: 'Question 1'
         | 
| 49 | 
            +
                = f.text_field :question2, label: 'Question 2'
         | 
| 50 | 
            +
                = f.text_field :question3, label: 'Question 3'
         | 
| 15 51 |  | 
| 16 52 | 
             
              = effective_submit(f)
         | 
| @@ -1,30 +1,36 @@ | |
| 1 1 | 
             
            = effective_form_with(model: [:admin, event], engine: true) do |f|
         | 
| 2 2 | 
             
              = f.text_field :title, label: "Title"
         | 
| 3 3 |  | 
| 4 | 
            -
              - categories = EffectiveEvents.categories
         | 
| 5 | 
            -
              - if categories.present?
         | 
| 6 | 
            -
                = f.select :category, categories, hint: 'optional category'
         | 
| 7 | 
            -
             | 
| 8 | 
            -
              - if event.class.respond_to?(:acts_as_tagged?)
         | 
| 9 | 
            -
                = render 'effective/tags/fields', f: f
         | 
| 10 | 
            -
             | 
| 11 | 
            -
              = f.datetime_field :published_at, label: 'Publish date', hint: 'When should this be displayed on the website.'
         | 
| 12 | 
            -
              = f.check_box :draft, hint: 'Save this event as a draft. It will not be accessible on the website.'
         | 
| 13 | 
            -
             | 
| 14 4 | 
             
              - if f.object.persisted? || f.object.errors.include?(:slug)
         | 
| 15 5 | 
             
                - current_url = (effective_events.event_url(f.object) rescue nil)
         | 
| 16 6 | 
             
                = f.text_field :slug, hint: "The slug controls this event's internet address. Be careful, changing the slug will break links that other websites may have to the old address.<br>#{('This event is currently reachable via ' + link_to(current_url.gsub(f.object.slug, '<strong>' + f.object.slug + '</strong>').html_safe, current_url)) if current_url }".html_safe
         | 
| 17 7 |  | 
| 18 | 
            -
               | 
| 19 | 
            -
             | 
| 8 | 
            +
              .row
         | 
| 9 | 
            +
                .col
         | 
| 10 | 
            +
                  - categories = EffectiveEvents.categories
         | 
| 11 | 
            +
                  - if categories.present?
         | 
| 12 | 
            +
                    = f.select :category, categories, hint: 'optional category'
         | 
| 13 | 
            +
                .col
         | 
| 14 | 
            +
                  - if event.class.respond_to?(:acts_as_tagged?)
         | 
| 15 | 
            +
                    = render 'effective/tags/fields', f: f
         | 
| 20 16 |  | 
| 21 | 
            -
               | 
| 17 | 
            +
              = f.check_box :draft, hint: 'Save this event as a draft. It will not be accessible on the website.'
         | 
| 18 | 
            +
              .row
         | 
| 19 | 
            +
                .col-md-6= f.datetime_field :published_at, label: 'Publish date', hint: 'When should this be displayed on the website.'
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              .row
         | 
| 22 | 
            +
                .col-md-6= f.datetime_field :start_at, label: "Event Start"
         | 
| 23 | 
            +
                .col-md-6= f.datetime_field :end_at, label: "Event End"
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              %h2 Registration
         | 
| 22 26 | 
             
              %p The online registration and purchase for this event will be available between:
         | 
| 23 27 | 
             
              = f.datetime_field :registration_start_at, label: "Registration Start"
         | 
| 24 28 | 
             
              = f.datetime_field :registration_end_at, label: "Registration End"
         | 
| 25 29 | 
             
              = f.datetime_field :early_bird_end_at, label: "Early Bird End",
         | 
| 26 30 | 
             
                hint: 'Event tickets can be purchased for early bird pricing before this date. Afterwards regular pricing applies.'
         | 
| 27 31 |  | 
| 32 | 
            +
              = f.check_box :allow_blank_registrants, label: "Yes, allow blank ticket registrations", hint: "Allow event tickets to be purchased without adding a name. The purchaser may return to add names later."
         | 
| 33 | 
            +
             | 
| 28 34 | 
             
              = f.check_box :external_registration, label: "Yes, the registration for this event is handled by another website"
         | 
| 29 35 |  | 
| 30 36 | 
             
              = f.show_if(:external_registration, true) do
         | 
| @@ -8,13 +8,28 @@ | |
| 8 8 | 
             
                - if f.object.purchased? && namespace == :admin
         | 
| 9 9 | 
             
                  = f.select :event_ticket_id, effective_events_event_tickets_collection(event, namespace), label: 'Change Ticket', hint: 'Admin only. Change the purchased ticket. This will not create charges, alter the original order, or consider ticket capacity.'
         | 
| 10 10 |  | 
| 11 | 
            -
                . | 
| 12 | 
            -
                   | 
| 13 | 
            -
                  .col-lg= f.text_field :last_name
         | 
| 14 | 
            -
                  .col-lg= f.text_field :number, label: 'Professional Designations', hint: 'member or registrant number'
         | 
| 11 | 
            +
                - event.event_tickets.each do |ticket|
         | 
| 12 | 
            +
                  - next if ticket.member_only? && !current_user&.is?(:member)
         | 
| 15 13 |  | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 14 | 
            +
                  = f.show_if(:event_ticket_id, ticket.id) do
         | 
| 15 | 
            +
                    - if event.allow_blank_registrants? && (f.object.new_record? || f.object.blank_registrant?)
         | 
| 16 | 
            +
                      = f.check_box :blank_registrant, label: "I will return and add this ticket's information later"
         | 
| 17 | 
            +
                    - else
         | 
| 18 | 
            +
                      = f.hidden_field :blank_registrant, value: false
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    - if ticket.member_or_non_member?
         | 
| 21 | 
            +
                      = f.show_if(:blank_registrant, true, nested: true) do 
         | 
| 22 | 
            +
                        = f.check_box :member_registrant, label: 'Yes, this ticket will be for a member'
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    = f.show_if(:blank_registrant, false, nested: true) do
         | 
| 25 | 
            +
                      - if ticket.regular?
         | 
| 26 | 
            +
                        = render('effective/event_registrants/fields_regular', f: f)
         | 
| 27 | 
            +
                      - elsif ticket.member_only?
         | 
| 28 | 
            +
                        = render('effective/event_registrants/fields_member_only', f: f)
         | 
| 29 | 
            +
                      - elsif ticket.member_or_non_member?
         | 
| 30 | 
            +
                        = render('effective/event_registrants/fields_member_or_non_member', f: f)
         | 
| 31 | 
            +
                      - else
         | 
| 32 | 
            +
                        - raise("Unexpected ticket category: #{ticket.category || 'nil'}")
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                      = render('effective/event_registrants/fields_questions', f: f, ticket: ticket)
         | 
| 19 35 |  | 
| 20 | 
            -
                = f.text_area :notes, label: 'Dietary restrictions or other notes'
         | 
| @@ -0,0 +1,6 @@ | |
| 1 | 
            +
            - # Choose member
         | 
| 2 | 
            +
            - klass = (f.object.user || current_user).class
         | 
| 3 | 
            +
            - ajax_url = (@select2_users_ajax_path || effective_memberships.member_users_membership_select2_ajax_index_path) unless Rails.env.test?
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            = f.hidden_field :user_type, value: klass.name
         | 
| 6 | 
            +
            = f.select :user_id, klass.all, ajax_url: ajax_url, label: 'Member', required: true, hint: effective_events_event_tickets_user_hint()
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            - # Choose member
         | 
| 2 | 
            +
            - klass = (f.object.user || current_user).class
         | 
| 3 | 
            +
            - ajax_url = (@select2_users_ajax_path || effective_memberships.member_users_membership_select2_ajax_index_path) unless Rails.env.test?
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            = f.hidden_field :user_type, value: klass.name
         | 
| 6 | 
            +
            = f.select :user_id, klass.all, ajax_url: ajax_url, label: 'Member', hint: effective_events_event_tickets_user_hint()
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            = f.show_if(:user_id, '', nested: true) do
         | 
| 9 | 
            +
              %p.text-center - or -
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              - # Choose non-member
         | 
| 12 | 
            +
              .row
         | 
| 13 | 
            +
                .col-md= f.text_field :first_name
         | 
| 14 | 
            +
                .col-md= f.text_field :last_name
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              .row
         | 
| 17 | 
            +
                .col-md= f.email_field :email
         | 
| 18 | 
            +
                .col-md= f.text_field :company
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              %hr
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            - if ticket.questions.present?
         | 
| 2 | 
            +
              %p Please answer the following questions (optional):
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              - if ticket.question1.present?
         | 
| 5 | 
            +
                = f.text_field :response1, label: ticket.question1
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              - if ticket.question2.present?
         | 
| 8 | 
            +
                = f.text_field :response2, label: ticket.question2
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              - if ticket.question3.present?
         | 
| 11 | 
            +
                = f.text_field :response3, label: ticket.question3
         | 
| @@ -4,7 +4,7 @@ | |
| 4 4 | 
             
              - if resource.submit_order.deferred?
         | 
| 5 5 | 
             
                .card
         | 
| 6 6 | 
             
                  .card-body
         | 
| 7 | 
            -
                    = render_checkout_step2(resource.submit_order, purchased_url: wizard_path(: | 
| 7 | 
            +
                    = render_checkout_step2(resource.submit_order, purchased_url: wizard_path(:complete), deferred_url: wizard_path(:submitted), declined_url: wizard_path(:checkout))
         | 
| 8 8 | 
             
              - elsif resource.event.registerable? == false
         | 
| 9 9 | 
             
                .alert.alert-danger Your selected event is no longer available for registration.
         | 
| 10 10 | 
             
              - elsif resource.unavailable_event_tickets.present?
         | 
| @@ -14,5 +14,5 @@ | |
| 14 14 | 
             
              - else
         | 
| 15 15 | 
             
                .card
         | 
| 16 16 | 
             
                  .card-body
         | 
| 17 | 
            -
                    = render_checkout_step2(resource.submit_order, purchased_url: wizard_path(: | 
| 17 | 
            +
                    = render_checkout_step2(resource.submit_order, purchased_url: wizard_path(:complete), deferred_url: wizard_path(:submitted), declined_url: wizard_path(:checkout))
         | 
| 18 18 |  | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            = render 'layout' do
         | 
| 2 | 
            +
              = render 'effective/event_registrations/content', resource: resource
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              - raise('expected a completed event_registration') unless resource.completed?
         | 
| 5 | 
            +
              - raise('expected a purchased event_registration submit_order') unless resource.submit_order&.purchased?
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              .alert.alert-warning.mb-4
         | 
| 8 | 
            +
                Successfully paid on #{resource.submit_order.purchased_at.strftime('%F')}.
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              .mb-4
         | 
| 11 | 
            +
                = link_to "Return to Dashboard", return_to_dashboard_path, class: 'btn btn-lg btn-primary btn-block'
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              = render 'effective/event_registrations/summary', event_registration: resource
         | 
| 14 | 
            +
              = render 'effective/event_registrations/event_registration', event_registration: resource
         | 
| 15 | 
            +
              = render 'effective/event_registrations/orders', event_registration: resource
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              = link_to "Return to Dashboard", return_to_dashboard_path, class: 'btn btn-lg btn-primary btn-block'
         | 
| 18 | 
            +
             | 
| @@ -1,11 +1,8 @@ | |
| 1 1 | 
             
            = render 'layout' do
         | 
| 2 2 | 
             
              = render 'effective/event_registrations/content', resource: resource
         | 
| 3 3 |  | 
| 4 | 
            -
              - raise('expected a submitted event_registration') unless resource. | 
| 5 | 
            -
              - raise('expected a  | 
| 6 | 
            -
             | 
| 7 | 
            -
              .alert.alert-warning.mb-4
         | 
| 8 | 
            -
                Successfully paid on #{resource.submit_order.purchased_at.strftime('%F')}.
         | 
| 4 | 
            +
              - raise('expected a submitted event_registration') unless resource.submitted?
         | 
| 5 | 
            +
              - raise('expected a deffered event_registration submit_order') unless resource.submit_order&.deferred?
         | 
| 9 6 |  | 
| 10 7 | 
             
              .mb-4
         | 
| 11 8 | 
             
                = link_to "Return to Dashboard", return_to_dashboard_path, class: 'btn btn-lg btn-primary btn-block'
         | 
| @@ -40,7 +40,7 @@ | |
| 40 40 | 
             
                          %br
         | 
| 41 41 | 
             
                          = @event.registration_end_at.strftime("%b %d, %Y %I:%M%P")
         | 
| 42 42 |  | 
| 43 | 
            -
                    - if @event.event_tickets.present? | 
| 43 | 
            +
                    - if @event.event_tickets.present?
         | 
| 44 44 | 
             
                      %ul.list-unstyled
         | 
| 45 45 | 
             
                        - if @event.event_tickets.present?
         | 
| 46 46 | 
             
                          %li
         | 
| @@ -48,15 +48,7 @@ | |
| 48 48 | 
             
                            %br
         | 
| 49 49 | 
             
                            %ul
         | 
| 50 50 | 
             
                              - @event.event_tickets.each do |ticket|
         | 
| 51 | 
            -
                                %li= "#{ticket} (#{ | 
| 52 | 
            -
             | 
| 53 | 
            -
                        -# - if @event.event_products.present?
         | 
| 54 | 
            -
                        -#   %li
         | 
| 55 | 
            -
                        -#     %label Add-ons
         | 
| 56 | 
            -
                        -#     %br
         | 
| 57 | 
            -
                        -#     %ul
         | 
| 58 | 
            -
                        -#       - @event.event_products.each do |product|
         | 
| 59 | 
            -
                        -#         %li= "#{product} (#{price_to_currency(product.price)})"
         | 
| 51 | 
            +
                                %li= "#{ticket} (#{effective_events_ticket_price(@event, ticket)})"
         | 
| 60 52 |  | 
| 61 53 | 
             
                    %hr
         | 
| 62 54 |  | 
| @@ -22,6 +22,8 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0] | |
| 22 22 | 
             
                  t.boolean :external_registration, default: false
         | 
| 23 23 | 
             
                  t.string :external_registration_url
         | 
| 24 24 |  | 
| 25 | 
            +
                  t.boolean :allow_blank_registrants, default: false
         | 
| 26 | 
            +
             | 
| 25 27 | 
             
                  t.integer :roles_mask
         | 
| 26 28 | 
             
                  t.boolean :authenticate_user, default: false
         | 
| 27 29 |  | 
| @@ -36,10 +38,16 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0] | |
| 36 38 |  | 
| 37 39 | 
             
                  t.string :title
         | 
| 38 40 | 
             
                  t.integer :capacity
         | 
| 41 | 
            +
                  t.string :category
         | 
| 39 42 |  | 
| 40 43 | 
             
                  t.integer :regular_price
         | 
| 44 | 
            +
                  t.integer :member_price
         | 
| 41 45 | 
             
                  t.integer :early_bird_price
         | 
| 42 46 |  | 
| 47 | 
            +
                  t.text :question1
         | 
| 48 | 
            +
                  t.text :question2
         | 
| 49 | 
            +
                  t.text :question3
         | 
| 50 | 
            +
             | 
| 43 51 | 
             
                  t.string :qb_item_name
         | 
| 44 52 | 
             
                  t.boolean :tax_exempt, default: false
         | 
| 45 53 |  | 
| @@ -59,6 +67,9 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0] | |
| 59 67 | 
             
                  t.integer :event_registration_id
         | 
| 60 68 | 
             
                  t.string :event_registration_type
         | 
| 61 69 |  | 
| 70 | 
            +
                  t.integer :user_id
         | 
| 71 | 
            +
                  t.string :user_type
         | 
| 72 | 
            +
             | 
| 62 73 | 
             
                  t.string :first_name
         | 
| 63 74 | 
             
                  t.string :last_name
         | 
| 64 75 | 
             
                  t.string :email
         | 
| @@ -67,6 +78,13 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0] | |
| 67 78 | 
             
                  t.string :number
         | 
| 68 79 | 
             
                  t.text :notes
         | 
| 69 80 |  | 
| 81 | 
            +
                  t.boolean :blank_registrant, default: false
         | 
| 82 | 
            +
                  t.boolean :member_registrant, default: false
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  t.text :response1
         | 
| 85 | 
            +
                  t.text :response2
         | 
| 86 | 
            +
                  t.text :response3
         | 
| 87 | 
            +
             | 
| 70 88 | 
             
                  t.integer :purchased_order_id
         | 
| 71 89 | 
             
                  t.integer :price
         | 
| 72 90 |  | 
| @@ -136,6 +154,7 @@ class CreateEffectiveEvents < ActiveRecord::Migration[6.0] | |
| 136 154 |  | 
| 137 155 | 
             
                  # Dates
         | 
| 138 156 | 
             
                  t.datetime :submitted_at
         | 
| 157 | 
            +
                  t.datetime :completed_at
         | 
| 139 158 |  | 
| 140 159 | 
             
                  t.datetime :updated_at
         | 
| 141 160 | 
             
                  t.datetime :created_at
         | 
    
        data/db/seeds.rb
    CHANGED
    
    | @@ -27,6 +27,7 @@ event.event_tickets.create!( | |
| 27 27 | 
             
              capacity: 10,
         | 
| 28 28 | 
             
              regular_price: 100_00,
         | 
| 29 29 | 
             
              early_bird_price: 50_00,
         | 
| 30 | 
            +
              member_price: 75_00,
         | 
| 30 31 | 
             
              qb_item_name: 'Tickets'
         | 
| 31 32 | 
             
            )
         | 
| 32 33 |  | 
| @@ -35,6 +36,7 @@ event.event_tickets.create!( | |
| 35 36 | 
             
              capacity: 20,
         | 
| 36 37 | 
             
              regular_price: 200_00,
         | 
| 37 38 | 
             
              early_bird_price: 150_00,
         | 
| 39 | 
            +
              member_price: 75_00,
         | 
| 38 40 | 
             
              qb_item_name: 'Tickets'
         | 
| 39 41 | 
             
            )
         | 
| 40 42 |  | 
| @@ -43,6 +45,7 @@ event.event_tickets.create!( | |
| 43 45 | 
             
              capacity: nil,
         | 
| 44 46 | 
             
              regular_price: 200_00,
         | 
| 45 47 | 
             
              early_bird_price: 150_00,
         | 
| 48 | 
            +
              member_price: 75_00,
         | 
| 46 49 | 
             
              qb_item_name: 'Tickets'
         | 
| 47 50 | 
             
            )
         | 
| 48 51 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: effective_events
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.12.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Code and Effect
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2024- | 
| 11 | 
            +
            date: 2024-05-24 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rails
         | 
| @@ -267,6 +267,10 @@ files: | |
| 267 267 | 
             
            - app/views/admin/events/_form_event_registration_content.html.haml
         | 
| 268 268 | 
             
            - app/views/effective/event_addons/_fields.html.haml
         | 
| 269 269 | 
             
            - app/views/effective/event_registrants/_fields.html.haml
         | 
| 270 | 
            +
            - app/views/effective/event_registrants/_fields_member_only.html.haml
         | 
| 271 | 
            +
            - app/views/effective/event_registrants/_fields_member_or_non_member.html.haml
         | 
| 272 | 
            +
            - app/views/effective/event_registrants/_fields_questions.html.haml
         | 
| 273 | 
            +
            - app/views/effective/event_registrants/_fields_regular.html.haml
         | 
| 270 274 | 
             
            - app/views/effective/event_registrations/_addons.html.haml
         | 
| 271 275 | 
             
            - app/views/effective/event_registrations/_content.html.haml
         | 
| 272 276 | 
             
            - app/views/effective/event_registrations/_dashboard.html.haml
         | 
| @@ -278,6 +282,7 @@ files: | |
| 278 282 | 
             
            - app/views/effective/event_registrations/addons.html.haml
         | 
| 279 283 | 
             
            - app/views/effective/event_registrations/billing.html.haml
         | 
| 280 284 | 
             
            - app/views/effective/event_registrations/checkout.html.haml
         | 
| 285 | 
            +
            - app/views/effective/event_registrations/complete.html.haml
         | 
| 281 286 | 
             
            - app/views/effective/event_registrations/start.html.haml
         | 
| 282 287 | 
             
            - app/views/effective/event_registrations/submitted.html.haml
         | 
| 283 288 | 
             
            - app/views/effective/event_registrations/summary.html.haml
         |