spree_cm_commissioner 1.11.0.pre.pre4 → 1.13.0
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/.github/workflows/test_and_build_gem.yml +143 -12
- data/.gitignore +1 -2
- data/Gemfile.lock +1 -22
- data/Rakefile +4 -33
- data/app/controllers/spree/admin/cms_pages_controller_decorator.rb +32 -0
- data/app/controllers/spree/admin/product_places_controller.rb +2 -0
- data/app/controllers/spree/admin/stock_managements_controller.rb +1 -62
- data/app/controllers/spree/api/v2/organizer/invite_guests_controller.rb +70 -0
- data/app/controllers/spree/api/v2/storefront/accommodations_controller.rb +31 -14
- data/app/controllers/spree/api/v2/storefront/queue_cart/line_items_controller.rb +2 -2
- data/app/controllers/spree/api/v2/storefront/waiting_room_sessions_controller.rb +1 -0
- data/app/controllers/spree/api/v2/tenant/account_checker_controller.rb +1 -1
- data/app/controllers/spree/api/v2/tenant/account_recovers_controller.rb +2 -2
- data/app/controllers/spree/api/v2/tenant/cms_pages_controller.rb +41 -0
- data/app/controllers/spree/api/v2/tenant/reset_passwords_controller.rb +1 -1
- data/app/controllers/spree/api/v2/tenant/waiting_room_sessions_controller.rb +30 -0
- data/app/controllers/spree_cm_commissioner/admin/variants_controller_decorator.rb +17 -0
- data/app/controllers/spree_cm_commissioner/api/v2/storefront/cms_pages_controller_decorator.rb +18 -0
- data/app/interactors/spree_cm_commissioner/account_recover.rb +2 -2
- data/app/interactors/spree_cm_commissioner/create_event.rb +7 -26
- data/app/interactors/spree_cm_commissioner/create_ticket.rb +95 -0
- data/app/interactors/spree_cm_commissioner/event_line_items_date_syncer.rb +19 -0
- data/app/interactors/spree_cm_commissioner/existing_account_checker.rb +1 -1
- data/app/interactors/spree_cm_commissioner/order_importer/multi_guest.rb +31 -0
- data/app/interactors/spree_cm_commissioner/organizers_transactional_email_notifier.rb +27 -0
- data/app/interactors/spree_cm_commissioner/pin_code_sender.rb +3 -3
- data/app/interactors/spree_cm_commissioner/product_event_id_to_children_syncer.rb +15 -0
- data/app/interactors/spree_cm_commissioner/sms.rb +14 -0
- data/app/interactors/spree_cm_commissioner/telegram_debug_pin_code_sender.rb +2 -1
- data/app/interactors/spree_cm_commissioner/transactional_email_sender.rb +50 -0
- data/app/interactors/spree_cm_commissioner/user_forgotten_password_updater.rb +2 -1
- data/app/interactors/spree_cm_commissioner/user_password_authenticator.rb +4 -2
- data/app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb +7 -14
- data/app/interactors/spree_cm_commissioner/waiting_room_session_firebase_logger.rb +30 -0
- data/app/jobs/spree_cm_commissioner/ensure_event_for_product_line_item_guests_job.rb +13 -0
- data/app/jobs/spree_cm_commissioner/event_line_items_date_syncer_job.rb +8 -0
- data/app/jobs/spree_cm_commissioner/product_event_id_to_children_syncer_job.rb +8 -0
- data/app/jobs/spree_cm_commissioner/telegram_debug_pin_code_sender_job.rb +3 -1
- data/app/jobs/spree_cm_commissioner/waiting_room_session_firebase_logger_job.rb +13 -0
- data/app/mailers/spree_cm_commissioner/event_transactional_mailer.rb +23 -0
- data/app/mailers/spree_cm_commissioner/pin_code_mailer.rb +1 -0
- data/app/models/concerns/spree_cm_commissioner/kyc_bitwise.rb +2 -0
- data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +10 -6
- data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +13 -26
- data/app/models/concerns/spree_cm_commissioner/product_delegation.rb +4 -3
- data/app/models/concerns/spree_cm_commissioner/product_type.rb +0 -10
- data/app/models/concerns/spree_cm_commissioner/user_identity.rb +7 -4
- data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +8 -10
- data/app/models/spree_cm_commissioner/cms_page_decorator.rb +9 -0
- data/app/models/spree_cm_commissioner/event_ticket_google_wallet.rb +2 -2
- data/app/models/spree_cm_commissioner/guest.rb +1 -1
- data/app/models/spree_cm_commissioner/invite_guest.rb +23 -0
- data/app/models/spree_cm_commissioner/line_item_decorator.rb +10 -16
- data/app/models/spree_cm_commissioner/option_type_decorator.rb +6 -0
- data/app/models/spree_cm_commissioner/order_decorator.rb +0 -15
- data/app/models/spree_cm_commissioner/place.rb +1 -1
- data/app/models/spree_cm_commissioner/product_decorator.rb +17 -14
- data/app/models/spree_cm_commissioner/product_place.rb +1 -0
- data/app/models/spree_cm_commissioner/role_decorator.rb +3 -0
- data/app/models/spree_cm_commissioner/stock/availability_checker.rb +25 -27
- data/app/models/spree_cm_commissioner/stock/availability_validator_decorator.rb +1 -2
- data/app/models/spree_cm_commissioner/stock/line_item_availability_checker.rb +3 -3
- data/app/models/spree_cm_commissioner/stock_item_decorator.rb +0 -14
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +26 -3
- data/app/models/spree_cm_commissioner/transactional_email.rb +6 -0
- data/app/models/spree_cm_commissioner/user_decorator.rb +6 -0
- data/app/models/spree_cm_commissioner/variant_decorator.rb +27 -34
- data/app/models/spree_cm_commissioner/vehicle.rb +0 -7
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +9 -1
- data/app/overrides/spree/admin/cms_pages/_form/tenant_fields.html.erb.deface +9 -0
- data/app/overrides/spree/admin/cms_pages/index/cms_pages_tabs.html.erb.deface +21 -0
- data/app/overrides/spree/admin/taxons/_form/assets_form.html.erb.deface +2 -2
- data/app/overrides/spree/admin/taxons/_form/available_on.html.erb.deface +3 -1
- data/app/overrides/spree/admin/taxons/_form/background_color_and_foreground_color.html.erb.deface +3 -1
- data/app/overrides/spree/admin/taxons/_form/custom_redirect_url.html.erb.deface +3 -1
- data/app/overrides/spree/admin/taxons/_form/hide_video_banner.html.erb.deface +3 -1
- data/app/overrides/spree/admin/taxons/_form/purchasable_on_status.html.erb.deface +3 -1
- data/app/overrides/spree/admin/taxons/_form/show_badge_status.html.erb.deface +3 -1
- data/app/overrides/spree/admin/taxons/_form/to_date_form_date.html.erb.deface +3 -4
- data/app/overrides/spree/admin/users/_form/roles_fields.html.erb.deface +1 -1
- data/app/overrides/spree/admin/users/index/body.html.erb.deface +3 -0
- data/app/overrides/spree/admin/users/index/headers.html.erb.deface +3 -0
- data/app/overrides/spree/admin/variants/_form/kyc_field.html.erb.deface +40 -0
- data/app/overrides/spree/admin/variants/edit/variant_status.html.erb.deface +6 -3
- data/app/queries/spree_cm_commissioner/variant_availability/non_permanent_stock_query.rb +45 -0
- data/app/queries/spree_cm_commissioner/variant_availability/permanent_stock_query.rb +55 -0
- data/app/request_schemas/spree_cm_commissioner/accommodation_request_schema.rb +0 -3
- data/app/request_schemas/spree_cm_commissioner/application_request_schema.rb +1 -1
- data/app/serializers/spree/v2/organizer/invite_guest_serializer.rb +13 -0
- data/app/serializers/spree/v2/storefront/accommodation_serializer.rb +0 -2
- data/app/serializers/spree/v2/storefront/taxon_serializer_decorator.rb +2 -0
- data/app/serializers/spree/v2/tenant/waiting_room_session_serializer.rb +9 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/guest_serializer.rb +2 -1
- data/app/services/spree_cm_commissioner/user_authenticator.rb +3 -1
- data/app/services/spree_cm_commissioner/user_roles_assigner.rb +62 -0
- data/app/views/spree/admin/shared/_cms_pages_tabs.html.erb +20 -0
- data/app/views/spree/admin/shared/_taxon_tabs.html.erb +19 -19
- data/app/views/spree/admin/stock_managements/_variant_stock_items.html.erb +1 -3
- data/app/views/spree/admin/stock_managements/index.html.erb +5 -40
- data/app/views/spree/shared/_base_mailer_header.html.erb +10 -2
- data/app/views/spree_cm_commissioner/event_transactional_mailer/_event_banner.html.erb +3 -0
- data/app/views/spree_cm_commissioner/event_transactional_mailer/_mailer_stylesheets.html.erb +317 -0
- data/app/views/spree_cm_commissioner/event_transactional_mailer/_note.html.erb +8 -0
- data/app/views/spree_cm_commissioner/event_transactional_mailer/_share_button.html.erb +3 -0
- data/app/views/spree_cm_commissioner/event_transactional_mailer/send_to_organizer.html.erb +59 -0
- data/app/views/spree_cm_commissioner/event_transactional_mailer/send_to_participant.html.erb +52 -0
- data/app/views/spree_cm_commissioner/layouts/event_transactional_mailer.html.erb +14 -0
- data/config/initializers/spree_permitted_attributes.rb +0 -5
- data/config/locales/en.yml +36 -0
- data/config/locales/km.yml +2 -0
- data/config/routes.rb +6 -11
- data/db/migrate/20250422014417_create_spree_cm_commissioner_invite_guest.rb +21 -0
- data/db/migrate/20250509033437_create_spree_cm_commissioner_transactional_emails.rb +12 -0
- data/db/migrate/20250509075429_add_max_order_quantity_to_spree_product.rb +5 -0
- data/db/migrate/20250512075319_add_tenant_id_to_spree_cms_pages.rb +6 -0
- data/db/migrate/20250520042602_add_event_to_spree_products.rb +7 -0
- data/db/migrate/20250520044533_add_event_to_spree_line_items.rb +7 -0
- data/db/migrate/20250521024345_add_tenant_id_to_cm_waiting_room_sessions.rb +6 -0
- data/db/migrate/20250521095539_add_kyc_to_spree_variants.rb +5 -0
- data/docker-compose.yml +1 -1
- data/lib/generators/spree_cm_commissioner/install/install_generator.rb +3 -11
- data/lib/generators/spree_cm_commissioner/install/templates/app/javascript/{spree_dashboard/spree_cm_commissioner → spree_cm_commissioner}/utilities.js +0 -4
- data/lib/spree_cm_commissioner/calendar_event.rb +1 -11
- data/lib/spree_cm_commissioner/test_helper/factories/homepage_section_relatable_factory.rb +1 -1
- data/lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb +1 -1
- data/lib/spree_cm_commissioner/test_helper/factories/product_factory.rb +5 -18
- data/lib/spree_cm_commissioner/test_helper/factories/role.rb +7 -0
- data/lib/spree_cm_commissioner/test_helper/factories/stock_location_factory.rb +2 -2
- data/lib/spree_cm_commissioner/test_helper/factories/taxon_home_banner_factory.rb +5 -0
- data/lib/spree_cm_commissioner/test_helper/factories/transactional_email_factory.rb +6 -0
- data/lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb +6 -41
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +1 -1
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +0 -34
- data/lib/tasks/ensure_event_for_product_line_item_guests.rake +7 -0
- data/lib/tasks/update_invalid_self_root_places.rake +9 -0
- data/lib/tasks/update_orphan_root_places.rake +1 -0
- data/spree_cm_commissioner.gemspec +0 -5
- metadata +54 -82
- data/app/controllers/spree/api/v2/storefront/accommodations/variants_controller.rb +0 -42
- data/app/finders/spree_cm_commissioner/accommodations/find.rb +0 -40
- data/app/finders/spree_cm_commissioner/accommodations/find_variant.rb +0 -35
- data/app/interactors/spree_cm_commissioner/ensure_correct_product_type.rb +0 -40
- data/app/interactors/spree_cm_commissioner/inventory_item_syncer.rb +0 -25
- data/app/interactors/spree_cm_commissioner/stock/inventory_items_adjuster.rb +0 -13
- data/app/interactors/spree_cm_commissioner/stock/inventory_items_generator.rb +0 -15
- data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +0 -75
- data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +0 -24
- data/app/interactors/spree_cm_commissioner/user_roles_assigner.rb +0 -22
- data/app/jobs/spree_cm_commissioner/ensure_correct_product_type_job.rb +0 -7
- data/app/jobs/spree_cm_commissioner/inventory_item_syncer_job.rb +0 -7
- data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +0 -11
- data/app/jobs/spree_cm_commissioner/stock/inventory_items_generator_job.rb +0 -11
- data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +0 -9
- data/app/models/spree_cm_commissioner/inventory.rb +0 -11
- data/app/models/spree_cm_commissioner/inventory_item.rb +0 -56
- data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +0 -40
- data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +0 -126
- data/app/models/spree_cm_commissioner/redis_stock/line_items_cached_inventory_items_builder.rb +0 -36
- data/app/models/spree_cm_commissioner/redis_stock/variant_cached_inventory_items_builder.rb +0 -27
- data/app/models/spree_cm_commissioner/stock/order_availability_checker.rb +0 -44
- data/app/request_schemas/spree_cm_commissioner/variant_request_schema.rb +0 -19
- data/app/views/spree/admin/stock_managements/_events_popover.html.erb +0 -23
- data/app/views/spree/admin/stock_managements/calendar.html.erb +0 -35
- data/db/migrate/20250304293518_create_cm_inventory_items.rb +0 -21
- data/db/migrate/20250429094228_add_lock_version_to_cm_inventory_items.rb +0 -5
- data/db/migrate/20250502025848_add_index_to_spree_products.rb +0 -5
- data/db/migrate/20250502030001_add_product_type_to_spree_variants.rb +0 -5
- data/db/migrate/20250502030002_add_product_type_to_spree_line_items.rb +0 -5
- data/lib/spree_cm_commissioner/cached_inventory_item.rb +0 -23
- data/lib/spree_cm_commissioner/test_helper/factories/inventory_item_factory.rb +0 -9
- data/lib/tasks/create_default_non_permanent_inventory_items.rake +0 -16
- data/lib/tasks/ensure_correct_product_type.rake +0 -7
- data/lib/tasks/generate_inventory_items.rake +0 -7
@@ -3,6 +3,7 @@ module SpreeCmCommissioner
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
+
before_validation :set_event_id
|
6
7
|
before_validation :set_duration
|
7
8
|
end
|
8
9
|
|
@@ -42,15 +43,18 @@ module SpreeCmCommissioner
|
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
|
-
def event
|
46
|
-
taxons.event.first
|
47
|
-
end
|
48
|
-
|
49
46
|
private
|
50
47
|
|
48
|
+
def set_event_id
|
49
|
+
self.event_id ||= product.event_id
|
50
|
+
end
|
51
|
+
|
52
|
+
# Line item date now depends directly on the event date and variant date.
|
53
|
+
# No longer depend on the event section date.
|
54
|
+
# This keeps the setup simple for the organizer and consistent for users.
|
51
55
|
def set_duration
|
52
|
-
self.from_date ||= variant.start_date_time
|
53
|
-
self.to_date ||= variant.end_date_time
|
56
|
+
self.from_date ||= variant.start_date_time || event&.from_date
|
57
|
+
self.to_date ||= variant.end_date_time || event&.to_date
|
54
58
|
end
|
55
59
|
end
|
56
60
|
end
|
@@ -13,13 +13,11 @@ module SpreeCmCommissioner
|
|
13
13
|
state_machine.after_transition to: :complete, do: :notify_order_complete_telegram_notification_to_user, unless: :subscription?
|
14
14
|
state_machine.after_transition to: :complete, do: :send_order_complete_telegram_alert_to_vendors, unless: :need_confirmation?
|
15
15
|
state_machine.after_transition to: :complete, do: :send_order_complete_telegram_alert_to_store, unless: :need_confirmation?
|
16
|
-
state_machine.around_transition to: :complete, do: :handle_unstock_in_redis
|
17
16
|
|
17
|
+
state_machine.after_transition to: :complete, do: :send_transaction_email_to_user, if: :user_has_email?
|
18
18
|
state_machine.after_transition to: :resumed, do: :precalculate_conversion
|
19
|
-
state_machine.around_transition to: :resumed, do: :handle_unstock_in_redis
|
20
19
|
|
21
20
|
state_machine.after_transition to: :canceled, do: :precalculate_conversion
|
22
|
-
state_machine.after_transition to: :canceled, do: :restock_inventory_in_redis!
|
23
21
|
|
24
22
|
scope :accepted, -> { where(request_state: 'accepted') }
|
25
23
|
|
@@ -69,29 +67,6 @@ module SpreeCmCommissioner
|
|
69
67
|
end
|
70
68
|
end
|
71
69
|
|
72
|
-
def handle_unstock_in_redis
|
73
|
-
ActiveRecord::Base.transaction do
|
74
|
-
yield # Equal to block.call
|
75
|
-
|
76
|
-
# After the transition is complete, the following code will execute first before proceeding to other `after_transition` callbacks.
|
77
|
-
# This ensures that if `unstock_inventory_in_redis!` fails, the state will be rolled back,
|
78
|
-
# and neither the `finalize!` method nor any notifications will be triggered.
|
79
|
-
# The payment will be reversed in vPago gem, and `Spree::Checkout::Complete` will be called, which checks `order.reload.complete?`.
|
80
|
-
# This is critical because if the order state is complete, the payment will be marked as paid.
|
81
|
-
CmAppLogger.log(label: 'order_state_machine_before_unstock', data: { order_id: id, state: state })
|
82
|
-
unstock_inventory_in_redis!
|
83
|
-
# We rollback only order state, and we keep payment state as it is.
|
84
|
-
# We implement payment in vPago gem, and it will be reversed in the gem.
|
85
|
-
# Some bank has api for refund, but some don't have the api to refund yet. So we keep the payment state as it is and refund manually.
|
86
|
-
CmAppLogger.log(label: 'order_state_machine_after_unstock', data: { order_id: id, state: state })
|
87
|
-
end
|
88
|
-
rescue StandardError => e
|
89
|
-
CmAppLogger.log(label: 'order_state_machine',
|
90
|
-
data: { order_id: id, error: e.message, type: e.class.name, backtrace: e.backtrace.first(5).join("\n") }
|
91
|
-
)
|
92
|
-
raise e
|
93
|
-
end
|
94
|
-
|
95
70
|
def generate_bib_number
|
96
71
|
line_items.find_each(&:generate_remaining_guests)
|
97
72
|
|
@@ -119,6 +94,18 @@ module SpreeCmCommissioner
|
|
119
94
|
end
|
120
95
|
end
|
121
96
|
|
97
|
+
def send_transaction_email_to_user
|
98
|
+
line_items.each do |line_item|
|
99
|
+
next if line_item.event.nil?
|
100
|
+
|
101
|
+
SpreeCmCommissioner::EventTransactionalMailer.send_to_participant(line_item.event_id, user.id).deliver_later
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def user_has_email?
|
106
|
+
user.present? && user.email.present?
|
107
|
+
end
|
108
|
+
|
122
109
|
# allow authorized user to accept all requested line items
|
123
110
|
def accepted_by(user)
|
124
111
|
transaction do
|
@@ -3,11 +3,12 @@ module SpreeCmCommissioner
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
delegate :
|
6
|
+
delegate :product_type,
|
7
|
+
:subscribable?,
|
7
8
|
:allowed_upload_later?,
|
8
|
-
:need_confirmation?, :need_confirmation,
|
9
|
+
:need_confirmation?, :need_confirmation,
|
9
10
|
:allow_anonymous_booking,
|
10
|
-
:
|
11
|
+
:accommodation?, :service?, :ecommerce?,
|
11
12
|
:allow_self_check_in,
|
12
13
|
:allow_self_check_in?,
|
13
14
|
:required_self_check_in_location,
|
@@ -6,20 +6,10 @@ module SpreeCmCommissioner
|
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
8
|
PRODUCT_TYPES = %i[accommodation service ecommerce transit].freeze
|
9
|
-
PERMANENT_STOCK_PRODUCT_TYPES = %w[accommodation service transit].freeze
|
10
|
-
PRE_INVENTORY_DAYS = { 'transit' => 90, 'accommodation' => 365, 'service' => 30 }.freeze
|
11
9
|
|
12
10
|
included do
|
13
11
|
enum product_type: PRODUCT_TYPES if table_exists? && column_names.include?('product_type')
|
14
12
|
enum primary_product_type: PRODUCT_TYPES if table_exists? && column_names.include?('primary_product_type')
|
15
13
|
end
|
16
|
-
|
17
|
-
def permanent_stock?
|
18
|
-
PERMANENT_STOCK_PRODUCT_TYPES.include?(product_type)
|
19
|
-
end
|
20
|
-
|
21
|
-
def pre_inventory_days
|
22
|
-
PRE_INVENTORY_DAYS[product_type]
|
23
|
-
end
|
24
14
|
end
|
25
15
|
end
|
@@ -25,18 +25,21 @@ module SpreeCmCommissioner
|
|
25
25
|
end
|
26
26
|
|
27
27
|
class_methods do
|
28
|
-
def find_user_by_login(login)
|
28
|
+
def find_user_by_login(login, tenant_id)
|
29
29
|
return nil if login.blank?
|
30
30
|
|
31
31
|
login = login.downcase
|
32
32
|
parser = PhoneNumberParser.call(phone_number: login)
|
33
33
|
|
34
|
+
scope = Spree.user_class.all
|
35
|
+
scope = scope.where(tenant_id: tenant_id) if tenant_id.present?
|
36
|
+
|
34
37
|
if parser.intel_phone_number.present?
|
35
|
-
find_by(intel_phone_number: parser.intel_phone_number)
|
38
|
+
scope.find_by(intel_phone_number: parser.intel_phone_number)
|
36
39
|
elsif login =~ URI::MailTo::EMAIL_REGEXP
|
37
|
-
find_by(email: login)
|
40
|
+
scope.find_by(email: login)
|
38
41
|
else
|
39
|
-
find_by(login: login)
|
42
|
+
scope.find_by(login: login)
|
40
43
|
end
|
41
44
|
end
|
42
45
|
end
|
@@ -6,6 +6,8 @@ module SpreeCmCommissioner
|
|
6
6
|
before_save :set_options_to_public_metadata
|
7
7
|
|
8
8
|
delegate :location,
|
9
|
+
:start_date,
|
10
|
+
:start_time,
|
9
11
|
:reminder_in_hours,
|
10
12
|
:duration_in_hours,
|
11
13
|
:duration_in_minutes,
|
@@ -48,6 +50,8 @@ module SpreeCmCommissioner
|
|
48
50
|
option_values.detect { |o| o.option_type.name.downcase.strip == option_type_name.downcase.strip }.try(:name)
|
49
51
|
end
|
50
52
|
|
53
|
+
# No need to fallback to event start date to avoid n+1.
|
54
|
+
# To get end_time duration of event, include event when needed instead.
|
51
55
|
def start_date_time
|
52
56
|
return nil if start_date.blank?
|
53
57
|
return start_date if start_time.blank?
|
@@ -55,6 +59,8 @@ module SpreeCmCommissioner
|
|
55
59
|
start_date.change(hour: start_time.hour, min: start_time.min, sec: start_time.sec)
|
56
60
|
end
|
57
61
|
|
62
|
+
# No need to fallback to event end date to avoid n+1.
|
63
|
+
# To get end_time duration of event, include event when needed instead.
|
58
64
|
def end_date_time
|
59
65
|
return nil if end_date.blank?
|
60
66
|
return end_date if end_time.blank?
|
@@ -62,24 +68,16 @@ module SpreeCmCommissioner
|
|
62
68
|
end_date.change(hour: end_time.hour, min: end_time.min, sec: end_time.sec)
|
63
69
|
end
|
64
70
|
|
65
|
-
def start_date
|
66
|
-
options.start_date || event&.from_date
|
67
|
-
end
|
68
|
-
|
69
71
|
def end_date
|
70
72
|
return start_date + options.total_duration_in_seconds.seconds if start_date.present? && options.total_duration_in_seconds.positive?
|
71
73
|
|
72
|
-
options.end_date
|
73
|
-
end
|
74
|
-
|
75
|
-
def start_time
|
76
|
-
options.start_time || event&.from_date
|
74
|
+
options.end_date
|
77
75
|
end
|
78
76
|
|
79
77
|
def end_time
|
80
78
|
return start_time + options.total_duration_in_seconds.seconds if start_time.present? && options.total_duration_in_seconds.positive?
|
81
79
|
|
82
|
-
options.end_time
|
80
|
+
options.end_time
|
83
81
|
end
|
84
82
|
|
85
83
|
def post_paid?
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module CmsPageDecorator
|
3
|
+
def self.prepended(base)
|
4
|
+
base.belongs_to :tenant, class_name: 'SpreeCmCommissioner::Tenant'
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
Spree::CmsPage.prepend(SpreeCmCommissioner::CmsPageDecorator) unless Spree::CmsPage.included_modules.include?(SpreeCmCommissioner::CmsPageDecorator)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class InviteGuest < SpreeCmCommissioner::Base
|
3
|
+
enum invite_type: { invite: 0, open: 1, sponsor: 2 }
|
4
|
+
enum claimed_status: { active: 0, claimed: 1, revoked: 2 }
|
5
|
+
|
6
|
+
belongs_to :variant, class_name: 'Spree::Variant'
|
7
|
+
belongs_to :order, class_name: 'Spree::Order'
|
8
|
+
belongs_to :event, class_name: 'Spree::Taxon'
|
9
|
+
|
10
|
+
self.whitelisted_ransackable_attributes = %w[claimed_status]
|
11
|
+
|
12
|
+
def expired?
|
13
|
+
expiration_date.present? && expiration_date < Time.current
|
14
|
+
end
|
15
|
+
|
16
|
+
def fully_claimed?
|
17
|
+
return false unless order.present? && order.line_items.any?
|
18
|
+
|
19
|
+
line_item = order.line_items.first
|
20
|
+
line_item.guests.count >= order.line_items.first.number_of_guests
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,19 +1,15 @@
|
|
1
1
|
module SpreeCmCommissioner
|
2
2
|
module LineItemDecorator
|
3
|
-
def self.prepended(base) # rubocop:disable Metrics/MethodLength
|
3
|
+
def self.prepended(base) # rubocop:disable Metrics/MethodLength
|
4
4
|
include_modules(base)
|
5
5
|
|
6
6
|
base.belongs_to :accepter, class_name: 'Spree::User', optional: true
|
7
7
|
base.belongs_to :rejecter, class_name: 'Spree::User', optional: true
|
8
|
+
base.belongs_to :event, class_name: 'Spree::Taxon', optional: true, inverse_of: :line_items
|
8
9
|
|
9
10
|
base.has_one :google_wallet, class_name: 'SpreeCmCommissioner::GoogleWallet', through: :product
|
10
11
|
|
11
12
|
base.has_many :option_types, through: :product
|
12
|
-
|
13
|
-
base.has_many :inventory_items, lambda { |line_item|
|
14
|
-
where(inventory_date: nil).or(where(inventory_date: line_item.date_range))
|
15
|
-
}, through: :variant
|
16
|
-
|
17
13
|
base.has_many :taxons, class_name: 'Spree::Taxon', through: :product
|
18
14
|
base.has_many :guests, class_name: 'SpreeCmCommissioner::Guest', dependent: :destroy
|
19
15
|
base.has_many :pending_guests, pending_guests_query, class_name: 'SpreeCmCommissioner::Guest', dependent: :destroy
|
@@ -26,15 +22,16 @@ module SpreeCmCommissioner
|
|
26
22
|
base.validate :validate_seats_reservation, if: :transit?
|
27
23
|
|
28
24
|
base.before_create :add_due_date, if: :subscription?
|
29
|
-
base.before_save -> { self.product_type = variant.product_type }, if: -> { product_type.nil? }
|
30
25
|
|
31
26
|
base.validate :ensure_not_exceed_max_quantity_per_order, if: -> { variant&.max_quantity_per_order.present? }
|
32
27
|
|
33
28
|
base.whitelisted_ransackable_associations |= %w[guests order]
|
34
29
|
base.whitelisted_ransackable_attributes |= %w[number to_date from_date vendor_id]
|
35
30
|
|
36
|
-
base.delegate :delivery_required?, :high_demand,
|
31
|
+
base.delegate :delivery_required?, :permanent_stock?, :high_demand, :transit?,
|
37
32
|
to: :variant
|
33
|
+
base.delegate :discontinue_on, :product_type, :accommodation?, :service?, :ecommerce?, :need_confirmation,
|
34
|
+
to: :product
|
38
35
|
|
39
36
|
base.accepts_nested_attributes_for :guests, allow_destroy: true
|
40
37
|
base.accepts_nested_attributes_for :line_item_seats, allow_destroy: true
|
@@ -45,10 +42,6 @@ module SpreeCmCommissioner
|
|
45
42
|
json_api_columns << :vendor_id
|
46
43
|
end
|
47
44
|
|
48
|
-
def discontinue_on
|
49
|
-
variant.discontinue_on || product.discontinue_on
|
50
|
-
end
|
51
|
-
|
52
45
|
def base.search_by_qr_data!(data)
|
53
46
|
matches = data.match(/(R\d+)-([A-Za-z0-9_\-]+)-(L\d+)/)&.captures
|
54
47
|
|
@@ -67,11 +60,14 @@ module SpreeCmCommissioner
|
|
67
60
|
base.include SpreeCmCommissioner::LineItemDurationable
|
68
61
|
base.include SpreeCmCommissioner::LineItemsFilterScope
|
69
62
|
base.include SpreeCmCommissioner::LineItemGuestsConcern
|
70
|
-
base.include SpreeCmCommissioner::ProductType
|
71
63
|
base.include SpreeCmCommissioner::ProductDelegation
|
72
64
|
base.include SpreeCmCommissioner::KycBitwise
|
73
65
|
end
|
74
66
|
|
67
|
+
def kyc
|
68
|
+
variant.kyc || product.kyc
|
69
|
+
end
|
70
|
+
|
75
71
|
def self.pending_guests_query
|
76
72
|
lambda {
|
77
73
|
left_outer_joins(:id_card)
|
@@ -183,7 +179,7 @@ module SpreeCmCommissioner
|
|
183
179
|
|
184
180
|
# override
|
185
181
|
def sufficient_stock?
|
186
|
-
return transit_sufficient_stock? if transit
|
182
|
+
return transit_sufficient_stock? if variant.product.product_type == 'transit'
|
187
183
|
|
188
184
|
SpreeCmCommissioner::Stock::LineItemAvailabilityChecker.new(self).can_supply?(quantity)
|
189
185
|
end
|
@@ -239,8 +235,6 @@ module SpreeCmCommissioner
|
|
239
235
|
end
|
240
236
|
|
241
237
|
def validate_seats_reservation
|
242
|
-
return if reservation_trip.blank?
|
243
|
-
|
244
238
|
if reservation_trip.allow_seat_selection && !selected_seats_available?
|
245
239
|
errors.add(:base, :some_seats_are_booked, message: 'Some seats are already booked')
|
246
240
|
elsif !reservation_trip.allow_seat_selection && !seat_quantity_available?(reservation_trip)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module SpreeCmCommissioner
|
2
2
|
module OptionTypeDecorator
|
3
|
+
RULES_OPTION_TYPE_NAME = 'rules'.freeze
|
4
|
+
|
3
5
|
def self.prepended(base)
|
4
6
|
base.include SpreeCmCommissioner::ParameterizeName
|
5
7
|
base.include SpreeCmCommissioner::OptionTypeAttrType
|
@@ -24,6 +26,10 @@ module SpreeCmCommissioner
|
|
24
26
|
name: 'vehicle'
|
25
27
|
).first_or_create
|
26
28
|
end
|
29
|
+
|
30
|
+
def base.rules_option_type
|
31
|
+
Spree::OptionType.find_by(name: RULES_OPTION_TYPE_NAME)
|
32
|
+
end
|
27
33
|
end
|
28
34
|
|
29
35
|
private
|
@@ -58,13 +58,6 @@ module SpreeCmCommissioner
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
# override
|
62
|
-
# spree use this method to check stock availability & consider whether :order can continue to next state.
|
63
|
-
def insufficient_stock_lines
|
64
|
-
checker = SpreeCmCommissioner::Stock::OrderAvailabilityChecker.new(self)
|
65
|
-
checker.insufficient_stock_lines
|
66
|
-
end
|
67
|
-
|
68
61
|
def ticket_seller_user?
|
69
62
|
return false if user.nil?
|
70
63
|
|
@@ -201,14 +194,6 @@ module SpreeCmCommissioner
|
|
201
194
|
|
202
195
|
private
|
203
196
|
|
204
|
-
def unstock_inventory_in_redis!
|
205
|
-
SpreeCmCommissioner::RedisStock::InventoryUpdater.new(line_item_ids).unstock!
|
206
|
-
end
|
207
|
-
|
208
|
-
def restock_inventory_in_redis!
|
209
|
-
SpreeCmCommissioner::RedisStock::InventoryUpdater.new(line_item_ids).restock!
|
210
|
-
end
|
211
|
-
|
212
197
|
# override :spree_api
|
213
198
|
def webhook_payload_body
|
214
199
|
resource_serializer.new(
|
@@ -17,7 +17,7 @@ module SpreeCmCommissioner
|
|
17
17
|
has_many :products, through: :product_places
|
18
18
|
|
19
19
|
has_many :children, -> { order(:lft) }, class_name: 'SpreeCmCommissioner::Place', foreign_key: :parent_id, dependent: :destroy
|
20
|
-
has_many :vendor_stops, class_name: 'SpreeCmCommissioner::VendorStop', dependent: :destroy
|
20
|
+
has_many :vendor_stops, class_name: 'SpreeCmCommissioner::VendorStop', dependent: :destroy, foreign_key: :stop_id
|
21
21
|
|
22
22
|
def self.ransackable_attributes(auth_object = nil)
|
23
23
|
super & %w[name code]
|
@@ -33,7 +33,7 @@ module SpreeCmCommissioner
|
|
33
33
|
base.has_one :google_wallet, class_name: 'SpreeCmCommissioner::GoogleWallet', dependent: :destroy
|
34
34
|
|
35
35
|
base.has_many :complete_line_items, through: :classifications, source: :line_items
|
36
|
-
base.has_many :
|
36
|
+
base.has_many :guests, through: :line_items
|
37
37
|
|
38
38
|
base.has_many :product_places, class_name: 'SpreeCmCommissioner::ProductPlace', dependent: :destroy
|
39
39
|
base.has_many :places, through: :product_places
|
@@ -44,6 +44,8 @@ module SpreeCmCommissioner
|
|
44
44
|
|
45
45
|
base.has_one :trip, class_name: 'SpreeCmCommissioner::Trip', dependent: :destroy
|
46
46
|
|
47
|
+
base.belongs_to :event, class_name: 'Spree::Taxon', optional: true
|
48
|
+
|
47
49
|
base.scope :min_price, lambda { |vendor|
|
48
50
|
joins(:prices_including_master)
|
49
51
|
.where(vendor_id: vendor.id, product_type: vendor.primary_product_type)
|
@@ -57,14 +59,18 @@ module SpreeCmCommissioner
|
|
57
59
|
}
|
58
60
|
base.scope :subscribable, -> { where(subscribable: 1) }
|
59
61
|
|
62
|
+
base.before_validation :set_event_id
|
63
|
+
|
60
64
|
base.validate :validate_event_taxons, if: -> { taxons.event.present? }
|
65
|
+
|
61
66
|
base.validate :validate_product_date, if: -> { available_on.present? && discontinue_on.present? }
|
62
|
-
|
67
|
+
|
63
68
|
base.validates :commission_rate, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 100 }, allow_nil: true
|
64
69
|
|
65
70
|
base.whitelisted_ransackable_attributes = %w[description name slug discontinue_on status vendor_id short_name route_type]
|
66
71
|
|
67
72
|
base.after_update :update_variants_vendor_id, if: :saved_change_to_vendor_id?
|
73
|
+
base.after_update :sync_event_id_to_children, if: :saved_change_to_event_id?
|
68
74
|
|
69
75
|
base.enum purchasable_on: { both: 0, web: 1, app: 2 }
|
70
76
|
|
@@ -74,10 +80,6 @@ module SpreeCmCommissioner
|
|
74
80
|
base.before_save :set_tenant
|
75
81
|
end
|
76
82
|
|
77
|
-
def associated_event
|
78
|
-
taxons.event.first&.parent
|
79
|
-
end
|
80
|
-
|
81
83
|
def ticket_url
|
82
84
|
"#{Spree::Store.default.formatted_url}/tickets/#{slug}"
|
83
85
|
end
|
@@ -88,13 +90,21 @@ module SpreeCmCommissioner
|
|
88
90
|
self.tenant_id = vendor&.tenant_id
|
89
91
|
end
|
90
92
|
|
93
|
+
def set_event_id
|
94
|
+
self.event_id = taxons.select(&:event?).first&.parent_id
|
95
|
+
end
|
96
|
+
|
91
97
|
def update_variants_vendor_id
|
92
98
|
variants_including_master.find_each { |variant| variant.update!(vendor_id: vendor_id) }
|
93
99
|
end
|
94
100
|
|
101
|
+
def sync_event_id_to_children
|
102
|
+
::SpreeCmCommissioner::ProductEventIdToChildrenSyncerJob.perform_later(id)
|
103
|
+
end
|
104
|
+
|
95
105
|
def validate_event_taxons
|
96
106
|
errors.add(:taxons, 'Event Taxon can\'t not be more than 1') if taxons.event.size > 1
|
97
|
-
errors.add(:taxons, 'Must add event date to taxon') if
|
107
|
+
errors.add(:taxons, 'Must add event date to taxon') if event.from_date.nil? || event.to_date.nil?
|
98
108
|
end
|
99
109
|
|
100
110
|
def validate_product_date
|
@@ -102,13 +112,6 @@ module SpreeCmCommissioner
|
|
102
112
|
|
103
113
|
errors.add(:discontinue_on, 'must be after the available on date')
|
104
114
|
end
|
105
|
-
|
106
|
-
def product_type_unchanged
|
107
|
-
return if product_type_was.nil?
|
108
|
-
return unless product_type_changed?
|
109
|
-
|
110
|
-
errors.add(:product_type, 'cannot be changed once set')
|
111
|
-
end
|
112
115
|
end
|
113
116
|
end
|
114
117
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module SpreeCmCommissioner
|
2
2
|
class ProductPlace < Base
|
3
3
|
self.inheritance_column = '_type_disabled'
|
4
|
+
acts_as_list column: :position
|
4
5
|
|
5
6
|
belongs_to :product, class_name: 'Spree::Product', optional: false
|
6
7
|
belongs_to :place, class_name: 'SpreeCmCommissioner::Place', optional: false
|
@@ -7,6 +7,9 @@ module SpreeCmCommissioner
|
|
7
7
|
base.belongs_to :vendor, optional: true
|
8
8
|
|
9
9
|
base.scope :non_vendor, -> { where(vendor_id: nil) }
|
10
|
+
base.scope :filter_by_vendor, lambda { |vendor|
|
11
|
+
where(vendor_id: vendor)
|
12
|
+
}
|
10
13
|
|
11
14
|
base.accepts_nested_attributes_for :role_permissions, allow_destroy: true
|
12
15
|
|
@@ -1,49 +1,47 @@
|
|
1
1
|
module SpreeCmCommissioner
|
2
2
|
module Stock
|
3
3
|
class AvailabilityChecker
|
4
|
-
attr_reader :variant, :
|
4
|
+
attr_reader :variant, :error_message
|
5
5
|
|
6
|
-
def initialize(variant
|
6
|
+
def initialize(variant)
|
7
7
|
@variant = variant
|
8
|
-
@options = options
|
9
8
|
@error_message = nil
|
10
9
|
end
|
11
10
|
|
12
|
-
def can_supply?(quantity = 1)
|
11
|
+
def can_supply?(quantity = 1, options = {})
|
13
12
|
return false unless variant.available?
|
14
13
|
return true unless variant.should_track_inventory?
|
15
14
|
return true if variant.backorderable?
|
16
15
|
return true if variant.need_confirmation?
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def variant_available?(quantity = 1)
|
22
|
-
return false if cached_inventory_items.empty?
|
23
|
-
|
24
|
-
cached_inventory_items.all? do |cached_inventory_item|
|
25
|
-
cached_inventory_item.active? && cached_inventory_item.quantity_available >= quantity
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def cached_inventory_items
|
30
|
-
return @cached_inventory_items if defined?(@cached_inventory_items)
|
17
|
+
# when delivery required, shipment will dynamically add / remove unit from stock item.
|
18
|
+
# so we can directly check can_supply with stock items directly.
|
19
|
+
return variant.stock_items.sum(:count_on_hand) >= quantity if variant.delivery_required?
|
31
20
|
|
32
21
|
if variant.permanent_stock?
|
33
|
-
|
34
|
-
|
35
|
-
@cached_inventory_items = builder_klass.new(
|
36
|
-
variant_id: variant.id,
|
37
|
-
from_date: options[:from_date].to_date,
|
38
|
-
to_date: options[:to_date].to_date
|
39
|
-
).call
|
22
|
+
permanent_stock_variant_available?(quantity, options)
|
40
23
|
else
|
41
|
-
|
24
|
+
variant_available?(quantity, options)
|
42
25
|
end
|
43
26
|
end
|
44
27
|
|
45
|
-
def
|
46
|
-
|
28
|
+
def variant_available?(quantity = 1, options = {})
|
29
|
+
query = SpreeCmCommissioner::VariantAvailability::NonPermanentStockQuery.new(
|
30
|
+
variant: variant,
|
31
|
+
except_line_item_id: options[:except_line_item_id]
|
32
|
+
)
|
33
|
+
result = query.available?(quantity)
|
34
|
+
@error_message = query.error_message unless result
|
35
|
+
result
|
36
|
+
end
|
37
|
+
|
38
|
+
def permanent_stock_variant_available?(quantity = 1, options = {})
|
39
|
+
SpreeCmCommissioner::VariantAvailability::PermanentStockQuery.new(
|
40
|
+
variant: variant,
|
41
|
+
from_date: options[:from_date].to_date,
|
42
|
+
to_date: options[:to_date].to_date,
|
43
|
+
except_line_item_id: options[:except_line_item_id]
|
44
|
+
).available?(quantity)
|
47
45
|
end
|
48
46
|
end
|
49
47
|
end
|
@@ -3,8 +3,7 @@ module SpreeCmCommissioner
|
|
3
3
|
module AvailabilityValidatorDecorator
|
4
4
|
# override
|
5
5
|
def item_available?(line_item, quantity)
|
6
|
-
SpreeCmCommissioner::Stock::LineItemAvailabilityChecker.new(line_item)
|
7
|
-
.can_supply?(quantity)
|
6
|
+
SpreeCmCommissioner::Stock::LineItemAvailabilityChecker.new(line_item).can_supply?(quantity)
|
8
7
|
end
|
9
8
|
end
|
10
9
|
end
|
@@ -8,14 +8,14 @@ module SpreeCmCommissioner
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def can_supply?(quantity)
|
11
|
-
|
12
|
-
.can_supply?(quantity)
|
11
|
+
AvailabilityChecker.new(line_item.variant).can_supply?(quantity, options)
|
13
12
|
end
|
14
13
|
|
15
14
|
def options
|
16
15
|
{
|
17
16
|
from_date: line_item.from_date,
|
18
|
-
to_date: line_item.to_date
|
17
|
+
to_date: line_item.to_date,
|
18
|
+
except_line_item_id: line_item.id
|
19
19
|
}
|
20
20
|
end
|
21
21
|
end
|