spree_cm_commissioner 1.10.0.pre.pre1 → 1.10.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 +0 -2
- data/.gitignore +1 -2
- data/Gemfile.lock +1 -22
- 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/interactors/spree_cm_commissioner/vattanac_bank_initiator.rb +6 -25
- 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/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/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/trip_connection.rb +1 -0
- data/app/models/spree_cm_commissioner/trip_stop.rb +2 -2
- data/app/models/spree_cm_commissioner/variant_decorator.rb +20 -24
- data/app/models/spree_cm_commissioner/variant_options.rb +0 -14
- 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/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/services/spree_cm_commissioner/aes_encryption_service.rb +4 -6
- data/app/views/spree/admin/stock_managements/index.html.erb +5 -31
- data/config/routes.rb +2 -11
- 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/variant_factory.rb +6 -28
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +0 -34
- data/spree_cm_commissioner.gemspec +0 -5
- metadata +7 -71
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 634d4cd6a4373be586e59598dab82c2440eb292abe53abeeb1161e6bfca85da2
|
4
|
+
data.tar.gz: 3e0e4f5293ce46f30d227269baf174b7b8b3a32ac269a30b733f3e7ea1065aca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7830251cadb15def91fb9d7bc6c6c68dacb3af529d941f6c1d17364f3dd621c2e3539bf24d7d870d0b82e88f2309d78ab895de19219144192dd8924f1a1943b1
|
7
|
+
data.tar.gz: 64bbba3e3a8227f1788748ac27ee108d8f3ad93d89829336f53817556eb6a7e67fd4c43263ce6aa57e087df046139db1c9a665f57411634e1648d8dbd55b9f33
|
@@ -133,14 +133,12 @@ jobs:
|
|
133
133
|
bundle install --jobs 4 --retry 3
|
134
134
|
|
135
135
|
- name: Quality
|
136
|
-
if: github.event_name == 'pull_request'
|
137
136
|
env:
|
138
137
|
DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
|
139
138
|
run: |
|
140
139
|
bundle exec rubocop
|
141
140
|
|
142
141
|
- name: Security
|
143
|
-
if: github.event_name == 'pull_request'
|
144
142
|
env:
|
145
143
|
DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
|
146
144
|
run: |
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -34,7 +34,7 @@ GIT
|
|
34
34
|
PATH
|
35
35
|
remote: .
|
36
36
|
specs:
|
37
|
-
spree_cm_commissioner (1.10.0
|
37
|
+
spree_cm_commissioner (1.10.0)
|
38
38
|
activerecord-multi-tenant
|
39
39
|
activerecord_json_validator (~> 2.1, >= 2.1.3)
|
40
40
|
aws-sdk-cloudfront
|
@@ -42,7 +42,6 @@ PATH
|
|
42
42
|
aws-sdk-s3
|
43
43
|
blazer (~> 3.0.4)
|
44
44
|
byebug
|
45
|
-
connection_pool
|
46
45
|
counter_culture (~> 3.2)
|
47
46
|
dry-validation (~> 1.10)
|
48
47
|
elasticsearch (~> 8.5)
|
@@ -58,8 +57,6 @@ PATH
|
|
58
57
|
phonelib
|
59
58
|
premailer-rails
|
60
59
|
rails (~> 7.0.4)
|
61
|
-
redis
|
62
|
-
redis-rails
|
63
60
|
rqrcode (~> 2.0)
|
64
61
|
searchkick (~> 5.1)
|
65
62
|
simple_calendar (~> 2.4)
|
@@ -620,8 +617,6 @@ GEM
|
|
620
617
|
activesupport (>= 2.3.14)
|
621
618
|
racc (1.7.1)
|
622
619
|
rack (2.2.8)
|
623
|
-
rack-session (1.0.2)
|
624
|
-
rack (< 3)
|
625
620
|
rack-test (2.1.0)
|
626
621
|
rack (>= 1.3)
|
627
622
|
rails (7.0.8)
|
@@ -665,24 +660,8 @@ GEM
|
|
665
660
|
rbtree (0.4.6)
|
666
661
|
redis (5.0.7)
|
667
662
|
redis-client (>= 0.9.0)
|
668
|
-
redis-actionpack (5.5.0)
|
669
|
-
actionpack (>= 5)
|
670
|
-
redis-rack (>= 2.1.0, < 4)
|
671
|
-
redis-store (>= 1.1.0, < 2)
|
672
|
-
redis-activesupport (5.3.0)
|
673
|
-
activesupport (>= 3, < 8)
|
674
|
-
redis-store (>= 1.3, < 2)
|
675
663
|
redis-client (0.17.0)
|
676
664
|
connection_pool
|
677
|
-
redis-rack (3.0.0)
|
678
|
-
rack-session (>= 0.2.0)
|
679
|
-
redis-store (>= 1.2, < 2)
|
680
|
-
redis-rails (5.0.2)
|
681
|
-
redis-actionpack (>= 5.0, < 6)
|
682
|
-
redis-activesupport (>= 5.0, < 6)
|
683
|
-
redis-store (>= 1.2, < 2)
|
684
|
-
redis-store (1.11.0)
|
685
|
-
redis (>= 4, < 6)
|
686
665
|
regexp_parser (2.8.2)
|
687
666
|
representable (3.2.0)
|
688
667
|
declarative (< 0.1.0)
|
@@ -12,25 +12,9 @@ module Spree
|
|
12
12
|
def index
|
13
13
|
@variants = @product.variants.includes(:images, stock_items: :stock_location, option_values: :option_type)
|
14
14
|
@variants = [@product.master] if @variants.empty?
|
15
|
-
@stock_locations = (@variants.flat_map(&:stock_locations) + @product.vendor.stock_locations).uniq
|
16
|
-
|
17
|
-
load_inventories unless @product.permanent_stock?
|
18
|
-
end
|
19
|
-
|
20
|
-
def calendar
|
21
|
-
@year = params[:year].present? ? params[:year].to_i : Time.zone.today.year
|
22
15
|
|
23
|
-
|
24
|
-
to_date = Date.new(@year, 1, 1).end_of_year
|
25
|
-
|
26
|
-
@inventory_items = @product.inventory_items.includes(:variant).where(inventory_date: from_date..to_date).to_a
|
27
|
-
@events = SpreeCmCommissioner::CalendarEvent.from_inventory_items(@inventory_items)
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
16
|
+
@stock_locations = (@variants.flat_map(&:stock_locations) + @product.vendor.stock_locations).uniq
|
31
17
|
|
32
|
-
def load_inventories
|
33
|
-
@inventory_items = @product.inventory_items.group_by { |item| item.variant.id }
|
34
18
|
@reserved_stocks = Spree::LineItem
|
35
19
|
.complete
|
36
20
|
.where(variant_id: @variants.pluck(:id))
|
@@ -5,38 +5,55 @@ module Spree
|
|
5
5
|
class AccommodationsController < ::Spree::Api::V2::ResourceController
|
6
6
|
private
|
7
7
|
|
8
|
-
# override
|
9
8
|
def collection
|
10
|
-
@collection ||=
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
@collection ||= collection_finder.call(params: params).value
|
10
|
+
end
|
11
|
+
|
12
|
+
def paginated_collection
|
13
|
+
return @paginated_collection if defined?(@paginated_collection)
|
14
|
+
|
15
|
+
@paginated_collection = super
|
16
|
+
@paginated_collection = apply_service_availability(@paginated_collection)
|
17
17
|
end
|
18
18
|
|
19
|
-
# override
|
20
19
|
def resource
|
21
|
-
|
20
|
+
resource = resource_finder.call(params: params).value
|
21
|
+
raise ActiveRecord::RecordNotFound if resource.nil?
|
22
|
+
|
23
|
+
apply_service_availability(resource)
|
24
|
+
end
|
25
|
+
|
26
|
+
def apply_service_availability(resource)
|
27
|
+
SpreeCmCommissioner::ApplyServiceAvailability.call(calendarable: resource,
|
28
|
+
from_date: params[:from_date].to_date,
|
29
|
+
to_date: params[:to_date].to_date
|
30
|
+
).value
|
22
31
|
end
|
23
32
|
|
24
|
-
# override
|
25
33
|
def allowed_sort_attributes
|
26
34
|
super << :min_price << :max_price
|
27
35
|
end
|
28
36
|
|
29
|
-
|
37
|
+
def model_class
|
38
|
+
Spree::Vendor
|
39
|
+
end
|
40
|
+
|
30
41
|
def resource_serializer
|
31
42
|
Spree::V2::Storefront::AccommodationSerializer
|
32
43
|
end
|
33
44
|
|
34
|
-
# override
|
35
45
|
def collection_serializer
|
36
46
|
Spree::V2::Storefront::AccommodationSerializer
|
37
47
|
end
|
38
48
|
|
39
|
-
|
49
|
+
def collection_finder
|
50
|
+
SpreeCmCommissioner::AccommodationSearchDetail
|
51
|
+
end
|
52
|
+
|
53
|
+
def resource_finder
|
54
|
+
SpreeCmCommissioner::AccommodationSearchDetail
|
55
|
+
end
|
56
|
+
|
40
57
|
def required_schema
|
41
58
|
SpreeCmCommissioner::AccommodationRequestSchema
|
42
59
|
end
|
@@ -25,8 +25,10 @@ module SpreeCmCommissioner
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def verify_signature
|
28
|
+
public_key = ENV['VATTANAC_PUBLIC_KEY'].presence || Rails.application.credentials.vattanac.public_key
|
29
|
+
|
28
30
|
rsa_service = SpreeCmCommissioner::RsaService.new(
|
29
|
-
public_key:
|
31
|
+
public_key: public_key
|
30
32
|
)
|
31
33
|
|
32
34
|
return if rsa_service.verify(context.encrypted_data, context.signature)
|
@@ -35,6 +37,8 @@ module SpreeCmCommissioner
|
|
35
37
|
end
|
36
38
|
|
37
39
|
def decrypt_payload
|
40
|
+
aes_key = ENV['VATTANAC_AES_SECRET_KEY'].presence || Rails.application.credentials.vattanac.aes_secret_key
|
41
|
+
|
38
42
|
context.fail!(message: 'Invalid AES key length', status: :unprocessable_entity) unless aes_key
|
39
43
|
|
40
44
|
begin
|
@@ -95,41 +99,18 @@ module SpreeCmCommissioner
|
|
95
99
|
|
96
100
|
def construct_data
|
97
101
|
user = context.user
|
98
|
-
|
99
|
-
raw_data = {
|
102
|
+
context.data = {
|
100
103
|
sessionId: session_id,
|
101
104
|
name: user.full_name,
|
102
105
|
phone: user.phone_number,
|
103
106
|
email: user.email,
|
104
107
|
webUrl: "#{Spree::Store.default.formatted_url}/vattanac_bank_web_app?session_id=#{session_id}"
|
105
108
|
}
|
106
|
-
|
107
|
-
json_data = raw_data.to_json
|
108
|
-
|
109
|
-
encrypted_data = SpreeCmCommissioner::AesEncryptionService.encrypt(json_data, aes_key)
|
110
|
-
|
111
|
-
rsa_service = SpreeCmCommissioner::RsaService.new(private_key: bookmeplus_private_key)
|
112
|
-
|
113
|
-
signed_data = rsa_service.sign(encrypted_data)
|
114
|
-
|
115
|
-
context.data = signed_data
|
116
109
|
end
|
117
110
|
|
118
111
|
def session_id
|
119
112
|
payload = { user_id: context.user.id }
|
120
113
|
SpreeCmCommissioner::UserSessionJwtToken.encode(payload, context.user.reload.secure_token)
|
121
114
|
end
|
122
|
-
|
123
|
-
def aes_key
|
124
|
-
ENV['VATTANAC_AES_SECRET_KEY'].presence || Rails.application.credentials.vattanac.aes_secret_key
|
125
|
-
end
|
126
|
-
|
127
|
-
def bookmeplus_private_key
|
128
|
-
ENV['BOOKMEPLUS_PRIVATE_KEY'].presence || Rails.application.credentials.bookmeplus.private_key
|
129
|
-
end
|
130
|
-
|
131
|
-
def vattanac_public_key
|
132
|
-
ENV['VATTANAC_PUBLIC_KEY'].presence || Rails.application.credentials.vattanac.public_key
|
133
|
-
end
|
134
115
|
end
|
135
116
|
end
|
@@ -20,6 +20,7 @@ module SpreeCmCommissioner
|
|
20
20
|
vehicle_id
|
21
21
|
origin
|
22
22
|
destination
|
23
|
+
place_id
|
23
24
|
].freeze
|
24
25
|
|
25
26
|
RESERVED_OPTIONS = {
|
@@ -47,8 +48,8 @@ module SpreeCmCommissioner
|
|
47
48
|
'bib-display-prefix' => 'boolean',
|
48
49
|
'bib-pre-generation-on-create' => 'boolean',
|
49
50
|
'seat-number-positions' => 'array',
|
50
|
-
'origin' => '
|
51
|
-
'destination' => '
|
51
|
+
'origin' => 'place_id',
|
52
|
+
'destination' => 'place_id',
|
52
53
|
'departure-time' => 'time',
|
53
54
|
'vehicle' => 'vehicle_id',
|
54
55
|
'allow-seat-selection' => 'boolean'
|
@@ -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
|
@@ -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(
|
@@ -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
|
@@ -13,11 +13,11 @@ module SpreeCmCommissioner
|
|
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.vendor_stops.where(stop_id: stop_id, stop_type: stop_type).first_or_create if trip.present?
|
21
21
|
end
|
22
22
|
|
23
23
|
private
|
@@ -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,14 @@ 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
|
29
|
+
base.has_many :trip_stops, class_name: 'SpreeCmCommissioner::TripStop', foreign_key: :trip_id, dependent: :destroy
|
34
30
|
base.after_commit :sync_trip, if: -> { product.product_type == 'transit' }
|
31
|
+
base.accepts_nested_attributes_for :trip_stops, allow_destroy: true
|
35
32
|
end
|
36
33
|
|
37
34
|
def delivery_required?
|
@@ -47,24 +44,12 @@ module SpreeCmCommissioner
|
|
47
44
|
super || product.discontinued?
|
48
45
|
end
|
49
46
|
|
50
|
-
def
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
def default_inventory_item_exist?
|
55
|
-
inventory_items.exists?(inventory_date: nil)
|
47
|
+
def permanent_stock?
|
48
|
+
accommodation?
|
56
49
|
end
|
57
50
|
|
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
|
-
)
|
51
|
+
def event
|
52
|
+
taxons.event.first
|
68
53
|
end
|
69
54
|
|
70
55
|
# override
|
@@ -87,12 +72,23 @@ module SpreeCmCommissioner
|
|
87
72
|
end
|
88
73
|
|
89
74
|
# override
|
90
|
-
def in_stock?
|
91
|
-
|
75
|
+
def in_stock?
|
76
|
+
available_quantity.positive?
|
92
77
|
end
|
93
78
|
|
94
79
|
private
|
95
80
|
|
81
|
+
def total_purchases
|
82
|
+
Spree::LineItem.complete.where(variant_id: id).sum(:quantity).to_i
|
83
|
+
end
|
84
|
+
|
85
|
+
def available_quantity
|
86
|
+
stock_count = stock_items.sum(&:count_on_hand)
|
87
|
+
return stock_count if delivery_required?
|
88
|
+
|
89
|
+
stock_count - total_purchases
|
90
|
+
end
|
91
|
+
|
96
92
|
def update_vendor_price
|
97
93
|
return unless vendor.present? && product&.product_type == vendor&.primary_product_type
|
98
94
|
|
@@ -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
|