spree_cm_commissioner 1.10.0.pre.pre → 1.10.0.pre.hotfix.pre.sms
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 +48 -26
- data/.gitignore +1 -2
- data/.vscode/settings.json +1 -1
- data/Gemfile.lock +1 -22
- data/app/controllers/spree/admin/cms_pages_controller_decorator.rb +32 -0
- data/app/controllers/spree/admin/stock_managements_controller.rb +1 -17
- data/app/controllers/spree/api/v2/storefront/accommodations_controller.rb +31 -14
- 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_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 +23 -0
- data/app/interactors/spree_cm_commissioner/existing_account_checker.rb +1 -1
- data/app/interactors/spree_cm_commissioner/pin_code_sender.rb +3 -3
- 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/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/vattanac_bank_initiator.rb +2 -2
- data/app/jobs/spree_cm_commissioner/telegram_debug_pin_code_sender_job.rb +3 -1
- data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +3 -2
- data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +0 -26
- 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/spree_cm_commissioner/cms_page_decorator.rb +9 -0
- data/app/models/spree_cm_commissioner/line_item_decorator.rb +0 -1
- data/app/models/spree_cm_commissioner/order_decorator.rb +0 -15
- data/app/models/spree_cm_commissioner/place.rb +11 -2
- data/app/models/spree_cm_commissioner/product_decorator.rb +0 -1
- 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/taxon_decorator.rb +11 -0
- data/app/models/spree_cm_commissioner/taxon_option_type.rb +8 -0
- data/app/models/spree_cm_commissioner/taxon_option_value.rb +8 -0
- data/app/models/spree_cm_commissioner/trip.rb +0 -11
- data/app/models/spree_cm_commissioner/trip_connection.rb +1 -0
- data/app/models/spree_cm_commissioner/trip_stop.rb +12 -5
- data/app/models/spree_cm_commissioner/variant_decorator.rb +28 -25
- data/app/models/spree_cm_commissioner/variant_options.rb +0 -14
- data/app/models/spree_cm_commissioner/vehicle.rb +0 -7
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +2 -1
- data/app/models/spree_cm_commissioner/vendor_stop.rb +2 -1
- data/app/overrides/spree/admin/cms_pages/_form/tenant_fields.html.erb.deface +7 -0
- data/app/overrides/spree/admin/cms_pages/index/cms_pages_tabs.html.erb.deface +21 -0
- 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/queries/spree_cm_commissioner/trip_query.rb +11 -11
- 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/queries/spree_cm_commissioner/vendor_stop_place_query.rb +54 -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/storefront/accommodation_serializer.rb +0 -2
- data/app/serializers/spree/v2/tenant/guest_serializer.rb +1 -0
- data/app/services/spree_cm_commissioner/aes_encryption_service.rb +6 -4
- data/app/services/spree_cm_commissioner/organizer/export_guest_csv_service.rb +2 -0
- data/app/services/spree_cm_commissioner/user_authenticator.rb +3 -1
- data/app/views/spree/admin/shared/_cms_pages_tabs.html.erb +20 -0
- data/app/views/spree/admin/stock_managements/index.html.erb +5 -31
- data/config/routes.rb +4 -11
- data/db/migrate/20250418072528_add_nested_set_columns_to_places.rb +10 -0
- data/db/migrate/20250430091742_create_cm_taxon_option_types.rb +9 -0
- data/db/migrate/20250430092928_create_cm_taxon_option_values.rb +9 -0
- data/db/migrate/20250506092929_add_trip_count_to_cm_vendor_stops.rb +5 -0
- data/db/migrate/20250512075319_add_tenant_id_to_spree_cms_pages.rb +6 -0
- data/docker-compose.yml +1 -1
- data/lib/generators/spree_cm_commissioner/install/install_generator.rb +2 -2
- 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/place_factory.rb +11 -1
- data/lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb +6 -28
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +0 -34
- data/lib/tasks/migrate_and_rebuild_place_hierarchy.rake +9 -0
- data/lib/tasks/update_orphan_root_places.rake +7 -0
- data/spree_cm_commissioner.gemspec +0 -5
- metadata +22 -69
- 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/inventory_item_syncer.rb +0 -25
- data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +0 -71
- data/app/jobs/spree_cm_commissioner/inventory_item_syncer_job.rb +0 -7
- 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 -37
- 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 -114
- data/app/models/spree_cm_commissioner/redis_stock/line_items_cached_inventory_items_builder.rb +0 -42
- 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/models/spree_cm_commissioner/stock_movement_decorator.rb +0 -34
- 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 -17
- data/app/views/spree/admin/stock_managements/calendar.html.erb +0 -32
- 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/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/generate_inventory_items.rake +0 -7
@@ -13,13 +13,10 @@ 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
|
|
18
17
|
state_machine.after_transition to: :resumed, do: :precalculate_conversion
|
19
|
-
state_machine.around_transition to: :resumed, do: :handle_unstock_in_redis
|
20
18
|
|
21
19
|
state_machine.after_transition to: :canceled, do: :precalculate_conversion
|
22
|
-
state_machine.after_transition to: :canceled, do: :restock_inventory_in_redis!
|
23
20
|
|
24
21
|
scope :accepted, -> { where(request_state: 'accepted') }
|
25
22
|
|
@@ -69,29 +66,6 @@ module SpreeCmCommissioner
|
|
69
66
|
end
|
70
67
|
end
|
71
68
|
|
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
69
|
def generate_bib_number
|
96
70
|
line_items.find_each(&:generate_remaining_guests)
|
97
71
|
|
@@ -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
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module CmsPageDecorator
|
3
|
+
def self.prepended(base)
|
4
|
+
base.multi_tenant :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)
|
@@ -9,7 +9,6 @@ module SpreeCmCommissioner
|
|
9
9
|
base.has_one :google_wallet, class_name: 'SpreeCmCommissioner::GoogleWallet', through: :product
|
10
10
|
|
11
11
|
base.has_many :option_types, through: :product
|
12
|
-
base.has_many :inventory_items, through: :variant
|
13
12
|
base.has_many :taxons, class_name: 'Spree::Taxon', through: :product
|
14
13
|
base.has_many :guests, class_name: 'SpreeCmCommissioner::Guest', dependent: :destroy
|
15
14
|
base.has_many :pending_guests, pending_guests_query, class_name: 'SpreeCmCommissioner::Guest', dependent: :destroy
|
@@ -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(
|
@@ -2,6 +2,8 @@ require_dependency 'spree_cm_commissioner'
|
|
2
2
|
|
3
3
|
module SpreeCmCommissioner
|
4
4
|
class Place < ApplicationRecord
|
5
|
+
acts_as_nested_set
|
6
|
+
|
5
7
|
validates :reference, presence: true, if: :validate_reference?
|
6
8
|
validates :lat, presence: true, if: :validate_lat?
|
7
9
|
validates :lon, presence: true, if: :validate_lon?
|
@@ -13,15 +15,22 @@ module SpreeCmCommissioner
|
|
13
15
|
|
14
16
|
has_many :product_places, class_name: 'SpreeCmCommissioner::ProductPlace', dependent: :destroy
|
15
17
|
has_many :products, through: :product_places
|
16
|
-
has_many :children, class_name: 'SpreeCmCommissioner::Place', foreign_key: :parent_id, dependent: :destroy
|
17
|
-
belongs_to :parent, class_name: 'SpreeCmCommissioner::Place', optional: true
|
18
18
|
|
19
|
+
has_many :children, -> { order(:lft) }, class_name: 'SpreeCmCommissioner::Place', foreign_key: :parent_id, dependent: :destroy
|
19
20
|
has_many :vendor_stops, class_name: 'SpreeCmCommissioner::VendorStop', dependent: :destroy
|
20
21
|
|
21
22
|
def self.ransackable_attributes(auth_object = nil)
|
22
23
|
super & %w[name code]
|
23
24
|
end
|
24
25
|
|
26
|
+
def full_path_name
|
27
|
+
self_and_ancestors.map(&:name).reverse.join(', ')
|
28
|
+
end
|
29
|
+
|
30
|
+
def path_ids
|
31
|
+
self_and_ancestors.map(&:id)
|
32
|
+
end
|
33
|
+
|
25
34
|
def validate_reference?
|
26
35
|
Spree::Store.default.code.exclude?('billing')
|
27
36
|
end
|
@@ -33,7 +33,6 @@ 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 :inventory_items, through: :variants
|
37
36
|
|
38
37
|
base.has_many :product_places, class_name: 'SpreeCmCommissioner::ProductPlace', dependent: :destroy
|
39
38
|
base.has_many :places, through: :product_places
|
@@ -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
|
@@ -57,6 +57,9 @@ module SpreeCmCommissioner
|
|
57
57
|
base.has_many :event_blazer_queries, class_name: 'SpreeCmCommissioner::TaxonBlazerQuery'
|
58
58
|
base.has_many :blazer_queries, through: :event_blazer_queries, class_name: 'Blazer::Query'
|
59
59
|
|
60
|
+
base.has_many :taxon_option_types, class_name: 'SpreeCmCommissioner::TaxonOptionType'
|
61
|
+
base.has_many :taxon_option_values, class_name: 'SpreeCmCommissioner::TaxonOptionValue'
|
62
|
+
|
60
63
|
def base.active_homepage_events
|
61
64
|
joins(:homepage_section_relatables)
|
62
65
|
.joins("INNER JOIN spree_taxons taxon ON taxon.id = cm_homepage_section_relatables.relatable_id
|
@@ -96,6 +99,14 @@ module SpreeCmCommissioner
|
|
96
99
|
.uniq
|
97
100
|
end
|
98
101
|
|
102
|
+
def selected_option_types
|
103
|
+
taxon_option_types.pluck(:option_type_id)
|
104
|
+
end
|
105
|
+
|
106
|
+
def selected_option_values
|
107
|
+
taxon_option_values.pluck(:option_value_id)
|
108
|
+
end
|
109
|
+
|
99
110
|
def event_url
|
100
111
|
"https://#{Spree::Store.default.url}/t/#{permalink}"
|
101
112
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require_dependency 'spree_cm_commissioner'
|
2
|
+
|
3
|
+
module SpreeCmCommissioner
|
4
|
+
class TaxonOptionType < ApplicationRecord
|
5
|
+
belongs_to :taxon, class_name: 'Spree::Taxon', dependent: :destroy
|
6
|
+
belongs_to :option_type, class_name: 'Spree::OptionType', dependent: :destroy
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require_dependency 'spree_cm_commissioner'
|
2
|
+
|
3
|
+
module SpreeCmCommissioner
|
4
|
+
class TaxonOptionValue < ApplicationRecord
|
5
|
+
belongs_to :taxon, class_name: 'Spree::Taxon', dependent: :destroy
|
6
|
+
belongs_to :option_value, class_name: 'Spree::OptionValue', dependent: :destroy
|
7
|
+
end
|
8
|
+
end
|
@@ -14,23 +14,12 @@ module SpreeCmCommissioner
|
|
14
14
|
validates :duration, numericality: { greater_than: 0 }
|
15
15
|
validate :origin_and_destination_cannot_be_the_same
|
16
16
|
|
17
|
-
has_many :trip_stops, class_name: 'SpreeCmCommissioner::TripStop', dependent: :destroy
|
18
|
-
|
19
|
-
after_commit :create_trip_stops
|
20
|
-
|
21
|
-
accepts_nested_attributes_for :trip_stops, allow_destroy: true
|
22
|
-
|
23
17
|
def convert_duration_to_seconds
|
24
18
|
return if hours.blank? && minutes.blank? && seconds.blank?
|
25
19
|
|
26
20
|
self.duration = (hours.to_i * 3600) + (minutes.to_i * 60) + seconds.to_i
|
27
21
|
end
|
28
22
|
|
29
|
-
def create_trip_stops
|
30
|
-
trip_stops.create(stop_type: :boarding, stop_id: origin_id)
|
31
|
-
trip_stops.create(stop_type: :drop_off, stop_id: destination_id)
|
32
|
-
end
|
33
|
-
|
34
23
|
def duration_in_hms
|
35
24
|
return { hours: 0, minutes: 0, seconds: 0 } if duration.nil?
|
36
25
|
|
@@ -8,22 +8,29 @@ module SpreeCmCommissioner
|
|
8
8
|
belongs_to :stop, class_name: 'SpreeCmCommissioner::Place'
|
9
9
|
|
10
10
|
before_validation :set_stop_name
|
11
|
-
|
12
|
-
|
11
|
+
after_destroy :decrement_trip_count
|
12
|
+
after_commit :create_vendor_stop
|
13
13
|
validates :stop_id, uniqueness: { scope: :trip_id }
|
14
14
|
|
15
15
|
def set_stop_name
|
16
|
-
self.stop_name = stop.name
|
16
|
+
self.stop_name = stop.name if stop.present?
|
17
17
|
end
|
18
18
|
|
19
19
|
def create_vendor_stop
|
20
|
-
vendor.vendor_stops.where(stop_id: stop_id, stop_type: stop_type).first_or_create
|
20
|
+
vendor_stop = vendor.vendor_stops.where(stop_id: stop_id, stop_type: stop_type).first_or_create
|
21
|
+
vendor_stop.update(trip_count: vendor_stop.trip_count.to_i + 1)
|
21
22
|
end
|
22
23
|
|
23
24
|
private
|
24
25
|
|
26
|
+
def decrement_trip_count
|
27
|
+
vendor.vendor_stops.where(stop_id: stop_id, stop_type: stop_type).find_each do |vendor_stop|
|
28
|
+
vendor_stop.update(trip_count: [vendor_stop.trip_count - 1, 0].max)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
25
32
|
def vendor
|
26
|
-
Spree::Product.find(trip
|
33
|
+
Spree::Product.find(trip&.product_id).vendor
|
27
34
|
end
|
28
35
|
end
|
29
36
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module SpreeCmCommissioner
|
2
2
|
module VariantDecorator
|
3
3
|
def self.prepended(base)
|
4
|
-
base.include SpreeCmCommissioner::ProductType
|
5
4
|
base.include SpreeCmCommissioner::ProductDelegation
|
6
5
|
base.include SpreeCmCommissioner::VariantOptionsConcern
|
7
6
|
|
@@ -22,16 +21,21 @@ module SpreeCmCommissioner
|
|
22
21
|
base.has_many :variant_guest_card_class, class_name: 'SpreeCmCommissioner::VariantGuestCardClass'
|
23
22
|
base.has_many :guest_card_classes, class_name: 'SpreeCmCommissioner::GuestCardClass', through: :variant_guest_card_class
|
24
23
|
|
25
|
-
base.has_many :inventory_items, class_name: 'SpreeCmCommissioner::InventoryItem'
|
26
|
-
|
27
24
|
base.scope :subscribable, -> { active.joins(:product).where(product: { subscribable: true, status: :active }) }
|
28
|
-
base.scope :with_permanent_stock, -> { joins(:product).where(product: { product_type: base::PERMANENT_STOCK_PRODUCT_TYPES }) }
|
29
|
-
base.scope :with_non_permanent_stock, -> { joins(:product).where.not(product: { product_type: base::PERMANENT_STOCK_PRODUCT_TYPES }) }
|
30
|
-
|
31
25
|
base.has_one :trip,
|
32
26
|
class_name: 'SpreeCmCommissioner::Trip'
|
27
|
+
base.has_many :trip_stops, class_name: 'SpreeCmCommissioner::TripStop', dependent: :destroy, foreign_key: :trip_id
|
33
28
|
base.accepts_nested_attributes_for :option_values
|
34
|
-
base.after_commit :sync_trip, if:
|
29
|
+
base.after_commit :sync_trip, if: :transit?
|
30
|
+
base.accepts_nested_attributes_for :trip_stops, allow_destroy: true
|
31
|
+
base.after_commit :create_trip_stops, if: :transit?
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_trip_stops
|
35
|
+
return if is_master?
|
36
|
+
|
37
|
+
trip_stops.find_or_create_by(stop_type: :boarding, stop_id: options.origin)
|
38
|
+
trip_stops.find_or_create_by(stop_type: :drop_off, stop_id: options.destination)
|
35
39
|
end
|
36
40
|
|
37
41
|
def delivery_required?
|
@@ -47,24 +51,12 @@ module SpreeCmCommissioner
|
|
47
51
|
super || product.discontinued?
|
48
52
|
end
|
49
53
|
|
50
|
-
def
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
def default_inventory_item_exist?
|
55
|
-
inventory_items.exists?(inventory_date: nil)
|
54
|
+
def permanent_stock?
|
55
|
+
accommodation?
|
56
56
|
end
|
57
57
|
|
58
|
-
def
|
59
|
-
|
60
|
-
return unless should_track_inventory?
|
61
|
-
return if default_inventory_item_exist?
|
62
|
-
|
63
|
-
inventory_items.create!(
|
64
|
-
product_type: product_type,
|
65
|
-
quantity_available: [0, quantity_available || total_on_hand].max,
|
66
|
-
max_capacity: [0, max_capacity || total_on_hand].max
|
67
|
-
)
|
58
|
+
def event
|
59
|
+
taxons.event.first
|
68
60
|
end
|
69
61
|
|
70
62
|
# override
|
@@ -87,12 +79,23 @@ module SpreeCmCommissioner
|
|
87
79
|
end
|
88
80
|
|
89
81
|
# override
|
90
|
-
def in_stock?
|
91
|
-
|
82
|
+
def in_stock?
|
83
|
+
available_quantity.positive?
|
92
84
|
end
|
93
85
|
|
94
86
|
private
|
95
87
|
|
88
|
+
def total_purchases
|
89
|
+
Spree::LineItem.complete.where(variant_id: id).sum(:quantity).to_i
|
90
|
+
end
|
91
|
+
|
92
|
+
def available_quantity
|
93
|
+
stock_count = stock_items.sum(&:count_on_hand)
|
94
|
+
return stock_count if delivery_required?
|
95
|
+
|
96
|
+
stock_count - total_purchases
|
97
|
+
end
|
98
|
+
|
96
99
|
def update_vendor_price
|
97
100
|
return unless vendor.present? && product&.product_type == vendor&.primary_product_type
|
98
101
|
|
@@ -166,19 +166,5 @@ module SpreeCmCommissioner
|
|
166
166
|
Time.zone.parse(time) if time.present?
|
167
167
|
end
|
168
168
|
end
|
169
|
-
|
170
|
-
def arrival_time
|
171
|
-
@arrival_time ||= departure_time + total_duration_in_minutes.minutes
|
172
|
-
end
|
173
|
-
|
174
|
-
def total_duration_in_minutes
|
175
|
-
total_duration_in_minutes = 0
|
176
|
-
|
177
|
-
total_duration_in_minutes += duration_in_hours * 60 if duration_in_hours.present?
|
178
|
-
total_duration_in_minutes += duration_in_minutes if duration_in_minutes.present?
|
179
|
-
total_duration_in_minutes += duration_in_seconds / 60 if duration_in_seconds.present?
|
180
|
-
|
181
|
-
total_duration_in_minutes
|
182
|
-
end
|
183
169
|
end
|
184
170
|
end
|
@@ -8,7 +8,6 @@ module SpreeCmCommissioner
|
|
8
8
|
has_one :primary_photo, -> { order(position: :asc) }, class_name: 'SpreeCmCommissioner::VehiclePhoto', as: :viewable, dependent: :destroy
|
9
9
|
belongs_to :vendor, class_name: 'Spree::Vendor'
|
10
10
|
|
11
|
-
before_save :set_attributes
|
12
11
|
after_commit :create_vehicle_option_value
|
13
12
|
|
14
13
|
has_many :vehicle_photo, class_name: 'SpreeCmCommissioner::VehiclePhoto', as: :viewable, dependent: :destroy
|
@@ -17,12 +16,6 @@ module SpreeCmCommissioner
|
|
17
16
|
validates :code, uniqueness: { scope: :vendor_id }, presence: true
|
18
17
|
validates :license_plate, uniqueness: {}, allow_blank: true
|
19
18
|
|
20
|
-
def set_attributes
|
21
|
-
self.route_type = vehicle_type.route_type
|
22
|
-
self.number_of_seats = vehicle_type.vehicle_seats_count
|
23
|
-
self.allow_seat_selection = vehicle_type.allow_seat_selection
|
24
|
-
end
|
25
|
-
|
26
19
|
def create_vehicle_option_value
|
27
20
|
SpreeCmCommissioner::VehicleOptionValueCreator.call(self)
|
28
21
|
end
|
@@ -79,7 +79,8 @@ module SpreeCmCommissioner
|
|
79
79
|
dependent: :destroy, inverse_of: :relatable
|
80
80
|
|
81
81
|
base.has_many :vehicle_types, class_name: 'SpreeCmCommissioner::VehicleType', dependent: :destroy
|
82
|
-
base.has_many :vehicles,
|
82
|
+
base.has_many :vehicles, class_name: 'SpreeCmCommissioner::Vehicle', dependent: :destroy
|
83
|
+
# base.has_many :vehicles, through: :vehicle_types, class_name: 'SpreeCmCommissioner::Vehicle', dependent: :destroy
|
83
84
|
|
84
85
|
base.validates :account_name, :account_number, presence: true, if: lambda {
|
85
86
|
payment_qrcode.present? && Spree::Store.default.code.include?('billing')
|
@@ -4,6 +4,7 @@ module SpreeCmCommissioner
|
|
4
4
|
belongs_to :vendor, class_name: 'Spree::Vendor'
|
5
5
|
belongs_to :stop, class_name: 'SpreeCmCommissioner::Place'
|
6
6
|
|
7
|
-
|
7
|
+
validates :trip_count, numericality: { greater_than_or_equal_to: 0 }
|
8
|
+
enum :stop_type, { boarding: 0, drop_off: 1 }
|
8
9
|
end
|
9
10
|
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<!-- insert_before "erb[loud]:contains('f.field_container :title')" -->
|
2
|
+
|
3
|
+
<%= f.field_container :tenant_id, class: ['col-12'] do %>
|
4
|
+
<%= f.label :tenant_id, raw(Spree.t(:tenant) + ' (optional)') %>
|
5
|
+
<%= f.collection_select :tenant_id, SpreeCmCommissioner::Tenant.all, :id, :name, { prompt: Spree.t('select_tenant') }, { class: 'form-control select2' } %>
|
6
|
+
<%= f.error_message_on :tenant_id %>
|
7
|
+
<% end %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<!-- insert_before "erb[silent]:contains('content_for :page_actions')" -->
|
2
|
+
|
3
|
+
<%= render partial: 'spree/admin/shared/cms_pages_tabs' %>
|
4
|
+
|
5
|
+
<% if params[:tab] == 'default' %>
|
6
|
+
<div class="alert alert-info mb-3">
|
7
|
+
<%= svg_icon name: "info-circle.svg", classes: 'mr-2', width: '16', height: '16' %>
|
8
|
+
CMS Pages for the default store. These pages are shared globally and are not tied to any specific tenant.
|
9
|
+
</div>
|
10
|
+
<% elsif params[:tab] == 'tenants' && params[:tenant_id].present? %>
|
11
|
+
<div class="alert alert-info mb-3">
|
12
|
+
<%= svg_icon name: "info-circle.svg", classes: 'mr-2', width: '16', height: '16' %>
|
13
|
+
CMS Pages for the tenant: <strong><%= SpreeCmCommissioner::Tenant.find(params[:tenant_id]).name %></strong>.
|
14
|
+
These pages are displayed only to users associated with this tenant.
|
15
|
+
</div>
|
16
|
+
<% elsif params[:tab] == 'tenants' %>
|
17
|
+
<div class="alert alert-info mb-3">
|
18
|
+
<%= svg_icon name: "info-circle.svg", classes: 'mr-2', width: '16', height: '16' %>
|
19
|
+
CMS Pages for all tenants. These pages are displayed only to users associated with specific tenants.
|
20
|
+
</div>
|
21
|
+
<% end %>
|
@@ -19,6 +19,9 @@
|
|
19
19
|
<th>
|
20
20
|
<%= sort_link @search, :phone_number, I18n.t('activerecord.attributes.spree/order.phone_number'), {}, {title: 'phone_number_title'} %>
|
21
21
|
</th>
|
22
|
+
<th>
|
23
|
+
<%= Spree.t(:tenant) %>
|
24
|
+
</th>
|
22
25
|
<th>
|
23
26
|
<%= sort_link @search, :created_at, Spree.t(:create_at), {}, {title: 'create_at_title'} %>
|
24
27
|
</th>
|