spree_cm_commissioner 2.0.3.pre.pre.pre7 → 2.1.0.pre.pre1
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 +16 -2
- data/.gitignore +2 -1
- data/Gemfile.lock +39 -4
- data/Rakefile +33 -4
- data/app/assets/stylesheets/spree_cm_commissioner/backend/calendar.scss +8 -11
- data/app/controllers/spree/admin/inventory_items_controller.rb +83 -0
- data/app/controllers/spree/admin/locations_controller.rb +62 -0
- data/app/controllers/spree/admin/stock_managements_controller.rb +63 -1
- data/app/controllers/spree/api/v2/platform/places_controller.rb +4 -1
- data/app/controllers/spree/api/v2/storefront/accommodations/variants_controller.rb +42 -0
- data/app/controllers/spree/api/v2/storefront/accommodations_controller.rb +14 -31
- data/app/controllers/spree/api/v2/storefront/dynamic_fields_controller.rb +1 -1
- data/app/controllers/spree/api/v2/storefront/guests_controller.rb +26 -18
- data/app/controllers/spree/api/v2/storefront/inventory_items_controller.rb +57 -0
- data/app/controllers/spree/api/v2/storefront/queue_cart/line_items_controller.rb +2 -2
- data/app/controllers/spree/api/v2/storefront/transit/draft_orders_controller.rb +46 -0
- data/app/controllers/spree/api/v2/storefront/trip_places_controller.rb +29 -0
- data/app/controllers/spree/api/v2/storefront/trip_search_controller.rb +62 -0
- data/app/controllers/spree/api/v2/storefront/trips_controller.rb +24 -0
- data/app/finders/spree_cm_commissioner/accommodations/find.rb +37 -0
- data/app/finders/spree_cm_commissioner/accommodations/find_variant.rb +32 -0
- data/app/interactors/spree_cm_commissioner/billing_address_creator.rb +33 -0
- data/app/interactors/spree_cm_commissioner/customer_notification_sender.rb +7 -2
- data/app/interactors/spree_cm_commissioner/ensure_correct_product_type.rb +40 -0
- data/app/interactors/spree_cm_commissioner/fetch_facebook_user_data.rb +45 -0
- data/app/interactors/spree_cm_commissioner/google_places_fetcher.rb +1 -0
- data/app/interactors/spree_cm_commissioner/intercity_taxi_order_creator.rb +106 -0
- data/app/interactors/spree_cm_commissioner/inventory_item_syncer.rb +25 -0
- data/app/interactors/spree_cm_commissioner/stock/inventory_item_resetter.rb +44 -0
- data/app/interactors/spree_cm_commissioner/stock/inventory_items_adjuster.rb +13 -0
- data/app/interactors/spree_cm_commissioner/stock/inventory_items_generator.rb +15 -0
- data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +75 -0
- data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +32 -0
- data/app/interactors/spree_cm_commissioner/taxi_trip_creator.rb +66 -0
- data/app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb +136 -0
- data/app/interactors/spree_cm_commissioner/trip_clone_creator.rb +155 -0
- data/app/interactors/spree_cm_commissioner/user_fb_token_authenticator.rb +37 -0
- data/app/interactors/spree_cm_commissioner/user_fb_token_checker.rb +20 -0
- data/app/interactors/spree_cm_commissioner/user_identity_checker.rb +8 -8
- data/app/interactors/spree_cm_commissioner/user_registration_with_fb_token.rb +62 -0
- data/app/interactors/spree_cm_commissioner/variant_block_updater.rb +62 -0
- data/app/interactors/spree_cm_commissioner/vehicle_updater.rb +41 -0
- data/app/jobs/spree_cm_commissioner/application_job.rb +20 -0
- data/app/jobs/spree_cm_commissioner/application_unique_job.rb +20 -0
- data/app/jobs/spree_cm_commissioner/ensure_correct_product_type_job.rb +7 -0
- data/app/jobs/spree_cm_commissioner/inventory_item_syncer_job.rb +7 -0
- data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +11 -0
- data/app/jobs/spree_cm_commissioner/stock/inventory_items_generator_job.rb +11 -0
- data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +9 -0
- data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +18 -15
- data/app/models/concerns/spree_cm_commissioner/line_item_guests_concern.rb +29 -15
- data/app/models/concerns/spree_cm_commissioner/line_item_transitable.rb +144 -0
- data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +3 -12
- data/app/models/concerns/spree_cm_commissioner/order_seatable.rb +44 -0
- data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +39 -0
- data/app/models/concerns/spree_cm_commissioner/product_delegation.rb +1 -3
- data/app/models/concerns/spree_cm_commissioner/product_type.rb +10 -0
- data/app/models/concerns/spree_cm_commissioner/route_type.rb +1 -1
- data/app/models/concerns/spree_cm_commissioner/user_identity.rb +12 -4
- data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +1 -0
- data/app/models/concerns/spree_cm_commissioner/vehicle_type.rb +11 -0
- data/app/models/spree_cm_commissioner/address_decorator.rb +36 -2
- data/app/models/spree_cm_commissioner/block.rb +43 -0
- data/app/models/spree_cm_commissioner/customer_notification.rb +6 -1
- data/app/models/spree_cm_commissioner/dynamic_field.rb +2 -0
- data/app/models/spree_cm_commissioner/guest.rb +39 -0
- data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +4 -0
- data/app/models/spree_cm_commissioner/inventory.rb +11 -0
- data/app/models/spree_cm_commissioner/inventory_item.rb +82 -0
- data/app/models/spree_cm_commissioner/line_item_decorator.rb +47 -78
- data/app/models/spree_cm_commissioner/notification_taxon.rb +1 -1
- data/app/models/spree_cm_commissioner/option_type_decorator.rb +1 -11
- data/app/models/spree_cm_commissioner/order/address_book_decorator.rb +30 -12
- data/app/models/spree_cm_commissioner/order_decorator.rb +38 -1
- data/app/models/spree_cm_commissioner/place.rb +3 -4
- data/app/models/spree_cm_commissioner/price_decorator.rb +9 -0
- data/app/models/spree_cm_commissioner/product_decorator.rb +13 -10
- data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +41 -0
- data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +126 -0
- data/app/models/spree_cm_commissioner/redis_stock/line_items_cached_inventory_items_builder.rb +36 -0
- data/app/models/spree_cm_commissioner/redis_stock/variant_cached_inventory_items_builder.rb +25 -0
- data/app/models/spree_cm_commissioner/reserved_block.rb +31 -0
- data/app/models/spree_cm_commissioner/saved_guest.rb +21 -0
- data/app/models/spree_cm_commissioner/seat_layout.rb +20 -0
- data/app/models/spree_cm_commissioner/seat_section.rb +16 -0
- data/app/models/spree_cm_commissioner/seats/blocks_canceler.rb +30 -0
- data/app/models/spree_cm_commissioner/seats/blocks_holder.rb +53 -0
- data/app/models/spree_cm_commissioner/seats/blocks_reserver.rb +49 -0
- data/app/models/spree_cm_commissioner/seats/errors/blocks_are_on_hold_by_other_guest.rb +4 -0
- data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_other_guest.rb +4 -0
- data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_same_guest.rb +4 -0
- data/app/models/spree_cm_commissioner/seats/errors/unable_to_save_reserved_block_record.rb +4 -0
- data/app/models/spree_cm_commissioner/service_calendar.rb +0 -2
- data/app/models/spree_cm_commissioner/state_decorator.rb +0 -1
- data/app/models/spree_cm_commissioner/stock/availability_checker.rb +26 -25
- data/app/models/spree_cm_commissioner/stock/availability_validator_decorator.rb +2 -1
- data/app/models/spree_cm_commissioner/stock/line_item_availability_checker.rb +3 -3
- data/app/models/spree_cm_commissioner/stock/order_availability_checker.rb +44 -0
- data/app/models/spree_cm_commissioner/stock_item_decorator.rb +17 -0
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +7 -1
- data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +0 -6
- data/app/models/spree_cm_commissioner/trip.rb +19 -10
- data/app/models/spree_cm_commissioner/trip_connection.rb +5 -5
- data/app/models/spree_cm_commissioner/trip_stop.rb +10 -21
- data/app/models/spree_cm_commissioner/variant_block.rb +17 -0
- data/app/models/spree_cm_commissioner/variant_decorator.rb +37 -47
- data/app/models/spree_cm_commissioner/variant_options.rb +4 -23
- data/app/models/spree_cm_commissioner/vehicle.rb +12 -15
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +14 -14
- data/app/models/spree_cm_commissioner/vendor_place.rb +13 -3
- data/app/overrides/spree/admin/shared/sub_menu/_configuration/locations_tab.html.erb.deface +5 -0
- data/app/queries/spree_cm_commissioner/trip_query.rb +110 -131
- data/app/request_schemas/spree_cm_commissioner/accommodation_request_schema.rb +3 -0
- data/app/request_schemas/spree_cm_commissioner/application_request_schema.rb +1 -1
- data/app/request_schemas/spree_cm_commissioner/inventory_item_schema.rb +8 -0
- data/app/request_schemas/spree_cm_commissioner/trip_search_request_schema.rb +20 -0
- data/app/request_schemas/spree_cm_commissioner/variant_request_schema.rb +19 -0
- data/app/serializers/spree/v2/storefront/accommodation_serializer.rb +2 -0
- data/app/serializers/spree/v2/storefront/cart_serializer_decorator.rb +1 -0
- data/app/serializers/spree/v2/storefront/line_item_serializer_decorator.rb +3 -1
- data/app/serializers/spree/v2/storefront/user_serializer_decorator.rb +1 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/amenity_serializer.rb +15 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/block_serializer.rb +11 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/guest_serializer.rb +5 -1
- data/app/serializers/spree_cm_commissioner/v2/storefront/inventory_item_serializer.rb +42 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/reserved_block_serializer.rb +9 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/saved_guest_serializer.rb +21 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/seat_layout_serializer.rb +12 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/seat_section_serializer.rb +11 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_place_serializer.rb +10 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_query_result_serializer.rb +14 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_result_serializer.rb +17 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_serializer.rb +20 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_stop_serializer.rb +11 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_variant_serializer.rb +12 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_vehicle_serializer.rb +16 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_vendor_serializer.rb +16 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/variant_block_serializer.rb +9 -0
- data/app/services/spree_cm_commissioner/transit/legs_builder_service.rb +46 -0
- data/app/services/spree_cm_commissioner/user_authenticator.rb +10 -1
- data/app/views/shared/_map.html.erb +5 -4
- data/app/views/spree/admin/customer_notifications/_form.html.erb +3 -3
- data/app/views/spree/admin/inventory_items/show.html.erb +72 -0
- data/app/views/spree/admin/locations/_form.html.erb +133 -0
- data/app/views/spree/admin/locations/edit.html.erb +11 -0
- data/app/views/spree/admin/locations/index.html.erb +67 -0
- data/app/views/spree/admin/locations/new.html.erb +11 -0
- data/app/views/spree/admin/stock_managements/_variant_stock_items.html.erb +7 -2
- data/app/views/spree/admin/stock_managements/calendar.html.erb +56 -0
- data/app/views/spree/admin/stock_managements/index.html.erb +55 -6
- data/config/initializers/paper_trail.rb +1 -0
- data/config/initializers/spree_permitted_attributes.rb +24 -4
- data/config/locales/en.yml +2 -0
- data/config/routes.rb +32 -2
- data/db/migrate/20240202080634_update_counter_cache_of_vehicle_type.rb +3 -1
- data/db/migrate/20250122000000_move_route_type_from_vehicles_to_trips.rb +7 -0
- data/db/migrate/20250304293518_create_cm_inventory_items.rb +21 -0
- data/db/migrate/20250428092706_add_active_to_cm_customer_notifications.rb +7 -0
- data/db/migrate/20250428103550_remove_tenant_id_and_vendor_id_from_cm_customer_notifications.rb +9 -0
- data/db/migrate/20250429094228_add_lock_version_to_cm_inventory_items.rb +5 -0
- data/db/migrate/20250502025848_add_index_to_spree_products.rb +5 -0
- data/db/migrate/20250502030001_add_product_type_to_spree_variants.rb +5 -0
- data/db/migrate/20250502030002_add_product_type_to_spree_line_items.rb +5 -0
- data/db/migrate/20250603035256_add_inventory_item_to_spree_prices.rb +7 -0
- data/db/migrate/20250619073724_drop_table_cm_line_item_seats.rb +5 -0
- data/db/migrate/20250619073812_drop_table_cm_vehicle_seats.rb +5 -0
- data/db/migrate/20250619073844_drop_table_cm_vehicle_types.rb +9 -0
- data/db/migrate/20250619073957_drop_table_cm_option_value_vehicle_types.rb +5 -0
- data/db/migrate/20250619082354_remove_unnecessary_fields_from_cm_places.rb +9 -0
- data/db/migrate/20250619082736_remove_route_type_from_spree_products.rb +5 -0
- data/db/migrate/20250619083055_remove_unnecessary_fields_from_spree_taxons.rb +5 -0
- data/db/migrate/20250620083055_remove_variant_id_from_cm_trips.rb +5 -0
- data/db/migrate/20250620090000_update_cm_trip_connections_to_use_cm_trips.rb +6 -0
- data/db/migrate/20250620090001_create_cm_seat_layouts.rb +17 -0
- data/db/migrate/20250620090002_create_cm_seat_sections.rb +18 -0
- data/db/migrate/20250620090003_create_cm_blocks.rb +18 -0
- data/db/migrate/20250624091005_create_cm_reserved_blocks.rb +29 -0
- data/db/migrate/20250626083642_create_cm_variant_blocks.rb +24 -0
- data/db/migrate/20250627023314_add_block_id_to_cm_guests.rb +13 -0
- data/db/migrate/20250716022821_add_location_reference_to_cm_vendor_places.rb +5 -0
- data/db/migrate/20250716031743_drop_table_cm_vendor_stops.rb +5 -0
- data/db/migrate/20250717023824_add_vendor_reference_to_cm_trips.rb +5 -0
- data/db/migrate/20250717041414_add_location_place_reference_to_cm_trip_stops.rb +5 -0
- data/db/migrate/20250717042539_rename_cm_trip_stops_stop_id_column_to_stop_place_id.rb +7 -0
- data/db/migrate/20250717042707_rename_cm_trips_origin_and_destination_to_origin_place_and_destination_place.rb +11 -0
- data/db/migrate/20250721080738_add_vehicle_type_to_cm_vehicles.rb +7 -0
- data/db/migrate/20250725092713_add_block_type_to_cm_blocks.rb +5 -0
- data/db/migrate/20250731062816_add_departure_time_and_arrival_time_to_trip_stop.rb +6 -0
- data/db/migrate/20250807033035_create_spree_cm_commissioner_saved_guests.rb +23 -0
- data/db/migrate/20250807040000_generate_pickup_time_integer_option_values.rb +71 -0
- data/db/migrate/20250808054835_add_saved_guest_reference_to_cm_blocks.rb +5 -0
- data/docker-compose.yml +1 -1
- data/lib/cm_app_logger.rb +17 -1
- data/lib/generators/spree_cm_commissioner/install/install_generator.rb +14 -11
- data/lib/generators/spree_cm_commissioner/install/templates/app/javascript/{spree_cm_commissioner → spree_dashboard/spree_cm_commissioner}/utilities.js +4 -0
- data/lib/spree_cm_commissioner/cached_inventory_item.rb +23 -0
- data/lib/spree_cm_commissioner/calendar_event.rb +11 -1
- data/lib/spree_cm_commissioner/test_helper/factories/block_factory.rb +16 -0
- data/lib/spree_cm_commissioner/test_helper/factories/guest_factory.rb +10 -0
- data/lib/spree_cm_commissioner/test_helper/factories/homepage_section_relatable_factory.rb +1 -1
- data/lib/spree_cm_commissioner/test_helper/factories/inventory_item_factory.rb +20 -0
- data/lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb +1 -1
- data/lib/spree_cm_commissioner/test_helper/factories/option_type_factory.rb +6 -30
- data/lib/spree_cm_commissioner/test_helper/factories/order_factory.rb +0 -36
- data/lib/spree_cm_commissioner/test_helper/factories/product_factory.rb +18 -34
- data/lib/spree_cm_commissioner/test_helper/factories/reserved_block_factory.rb +27 -0
- data/lib/spree_cm_commissioner/test_helper/factories/saved_guest_factory.rb +8 -0
- data/lib/spree_cm_commissioner/test_helper/factories/seat_layout_factory.rb +11 -0
- data/lib/spree_cm_commissioner/test_helper/factories/seat_section_factory.rb +16 -0
- data/lib/spree_cm_commissioner/test_helper/factories/stock_location_factory.rb +2 -2
- data/lib/spree_cm_commissioner/test_helper/factories/trip_connection_factory.rb +6 -0
- data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +11 -3
- data/lib/spree_cm_commissioner/test_helper/factories/trip_stop_factory.rb +13 -0
- data/lib/spree_cm_commissioner/test_helper/factories/variant_block_factory.rb +7 -0
- data/lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb +41 -19
- data/lib/spree_cm_commissioner/test_helper/factories/vehicle_factory.rb +1 -1
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +6 -1
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +13 -1
- data/lib/spree_cm_commissioner/transit/leg.rb +37 -0
- data/lib/spree_cm_commissioner/transit/seat_selection.rb +27 -0
- data/lib/spree_cm_commissioner/trip_query_result.rb +50 -0
- data/lib/spree_cm_commissioner/trip_result.rb +19 -10
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +37 -1
- data/lib/tasks/create_default_non_permanent_inventory_items.rake +16 -0
- data/lib/tasks/ensure_correct_product_type.rake +7 -0
- data/lib/tasks/generate_inventory_items.rake +7 -0
- data/spree_cm_commissioner.gemspec +7 -0
- metadata +195 -26
- data/app/controllers/concerns/spree_cm_commissioner/transit/taxon_bitwise.rb +0 -44
- data/app/finders/spree_cm_commissioner/line_items/find_by_variant_decorator.rb +0 -20
- data/app/models/spree_cm_commissioner/branch.rb +0 -12
- data/app/models/spree_cm_commissioner/line_item_seat.rb +0 -10
- data/app/models/spree_cm_commissioner/option_value_vehicle_type.rb +0 -8
- data/app/models/spree_cm_commissioner/stop.rb +0 -23
- data/app/models/spree_cm_commissioner/vehicle_seat.rb +0 -11
- data/app/models/spree_cm_commissioner/vehicle_type.rb +0 -76
- data/app/models/spree_cm_commissioner/vendor_stop.rb +0 -10
- data/app/queries/spree_cm_commissioner/trip_search_query.rb +0 -76
- data/app/queries/spree_cm_commissioner/variant_availability/non_permanent_stock_query.rb +0 -45
- data/app/queries/spree_cm_commissioner/variant_availability/permanent_stock_query.rb +0 -55
- data/app/queries/spree_cm_commissioner/vendor_stop_place_query.rb +0 -54
- data/app/services/spree_cm_commissioner/vehicle_option_value_creator.rb +0 -11
- data/lib/spree_cm_commissioner/test_helper/factories/branch_factory.rb +0 -12
- data/lib/spree_cm_commissioner/test_helper/factories/departure_time_option_type_factory.rb +0 -8
- data/lib/spree_cm_commissioner/test_helper/factories/duration_option_type_factory.rb +0 -8
- data/lib/spree_cm_commissioner/test_helper/factories/line_item_seat_factory.rb +0 -7
- data/lib/spree_cm_commissioner/test_helper/factories/stop_factory.rb +0 -14
- data/lib/spree_cm_commissioner/test_helper/factories/transit_place_factory.rb +0 -8
- data/lib/spree_cm_commissioner/test_helper/factories/vehicle_option_type_factory.rb +0 -8
- data/lib/spree_cm_commissioner/test_helper/factories/vehicle_type_factory.rb +0 -96
- data/lib/spree_cm_commissioner/trip_seat_layout_result.rb +0 -11
@@ -0,0 +1,44 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module Stock
|
3
|
+
class InventoryItemResetter < BaseInteractor
|
4
|
+
delegate :inventory_item, to: :context
|
5
|
+
|
6
|
+
def call
|
7
|
+
max_capacity = variant_total_inventory
|
8
|
+
total_purchases = variant_total_purchases
|
9
|
+
quantity_available = [max_capacity - total_purchases, 0].max
|
10
|
+
|
11
|
+
updated = inventory_item.update(max_capacity: max_capacity, quantity_available: quantity_available)
|
12
|
+
return context.fail!(message: 'Failed to update inventory item', errors: inventory_item.errors.full_messages) unless updated
|
13
|
+
|
14
|
+
clear_inventory_cache
|
15
|
+
end
|
16
|
+
|
17
|
+
def variant_total_inventory
|
18
|
+
# for shipment, total_on_hand is not orignal stock. shipment does subtract the stock.
|
19
|
+
# to get desire result, we need to add to total_purchase.
|
20
|
+
if inventory_item.variant.delivery_required?
|
21
|
+
inventory_item.variant.total_on_hand.to_i + variant_total_purchases
|
22
|
+
else
|
23
|
+
inventory_item.variant.total_on_hand.to_i
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def variant_total_purchases
|
28
|
+
scope = inventory_item.variant.complete_line_items
|
29
|
+
|
30
|
+
if inventory_item.permanent_stock?
|
31
|
+
scope.where('? BETWEEN from_date AND to_date', inventory_item.inventory_date).sum(:quantity).to_i
|
32
|
+
else
|
33
|
+
scope.sum(:quantity).to_i
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def clear_inventory_cache
|
38
|
+
SpreeCmCommissioner.redis_pool.with do |redis|
|
39
|
+
redis.del(inventory_item.redis_key)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module Stock
|
3
|
+
class InventoryItemsAdjuster < BaseInteractor
|
4
|
+
delegate :variant, :quantity, to: :context
|
5
|
+
|
6
|
+
def call
|
7
|
+
variant.inventory_items.active.find_each do |inventory_item|
|
8
|
+
inventory_item.adjust_quantity!(quantity)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module Stock
|
3
|
+
class InventoryItemsGenerator < BaseInteractor
|
4
|
+
delegate :variant, to: :context
|
5
|
+
|
6
|
+
def call
|
7
|
+
if variant.permanent_stock?
|
8
|
+
SpreeCmCommissioner::Stock::PermanentInventoryItemsGenerator.call(variant_ids: [variant.id])
|
9
|
+
else
|
10
|
+
variant.create_default_non_permanent_inventory_item! unless variant.default_inventory_item_exist?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module Stock
|
3
|
+
class PermanentInventoryItemsGenerator < BaseInteractor
|
4
|
+
delegate :variant_ids, to: :context
|
5
|
+
|
6
|
+
def variants_per_batch = 1000
|
7
|
+
|
8
|
+
def pre_inventory_days_for(variant)
|
9
|
+
context.pre_inventory_days || variant.pre_inventory_days
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
variants.in_batches(of: variants_per_batch) do |batch|
|
14
|
+
generate_inventory_items_for_batch(batch)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def generate_inventory_items_for_batch(batch)
|
21
|
+
total_on_hand_by_variant = total_on_hand_for(batch)
|
22
|
+
batch.each do |variant|
|
23
|
+
count_on_hand = total_on_hand_by_variant[variant.id] || 0
|
24
|
+
generate_inventory_items_for_variant(variant, count_on_hand)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def generate_inventory_items_for_variant(variant, count_on_hand)
|
29
|
+
inventory_dates_for(variant).each do |inventory_date|
|
30
|
+
next if inventory_exist?(variant, inventory_date)
|
31
|
+
|
32
|
+
create_inventory_item(variant, inventory_date, count_on_hand)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def inventory_dates_for(variant)
|
37
|
+
start_date = Time.zone.tomorrow
|
38
|
+
end_date = Time.zone.today + pre_inventory_days_for(variant)
|
39
|
+
|
40
|
+
(start_date..end_date)
|
41
|
+
end
|
42
|
+
|
43
|
+
def inventory_exist?(variant, inventory_date)
|
44
|
+
variant.inventory_items.exists?(inventory_date: inventory_date)
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_inventory_item(variant, inventory_date, count_on_hand)
|
48
|
+
variant.inventory_items.create!(
|
49
|
+
inventory_date: inventory_date,
|
50
|
+
quantity_available: count_on_hand,
|
51
|
+
max_capacity: count_on_hand,
|
52
|
+
product_type: variant.product_type
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns a hash: { variant_id => total_on_hand, ... }
|
57
|
+
def total_on_hand_for(variants)
|
58
|
+
variant_ids = variants.pluck(:id)
|
59
|
+
|
60
|
+
Spree::StockItem
|
61
|
+
.joins(:stock_location)
|
62
|
+
.where(deleted_at: nil, variant_id: variant_ids)
|
63
|
+
.where(spree_stock_locations: { active: true })
|
64
|
+
.group(:variant_id)
|
65
|
+
.sum(:count_on_hand)
|
66
|
+
end
|
67
|
+
|
68
|
+
def variants
|
69
|
+
scope = Spree::Variant.active.with_permanent_stock.where(is_master: false)
|
70
|
+
scope = scope.where(id: variant_ids) if variant_ids.present?
|
71
|
+
scope
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module Stock
|
3
|
+
class StockMovementCreator < BaseInteractor
|
4
|
+
delegate :variant_id, :stock_location_id, :current_store, :stock_movement_params, to: :context
|
5
|
+
|
6
|
+
def call
|
7
|
+
variant = current_store.variants.find(variant_id)
|
8
|
+
|
9
|
+
return context.fail!(message: Spree.t(:doesnt_track_inventory)) unless variant.track_inventory?
|
10
|
+
|
11
|
+
stock_location = Spree::StockLocation.find(stock_location_id)
|
12
|
+
stock_movement = stock_location.stock_movements.build(stock_movement_params)
|
13
|
+
stock_movement.stock_item = stock_location.set_up_stock_item(variant)
|
14
|
+
|
15
|
+
if stock_movement.save
|
16
|
+
adjust_inventory_items_async(variant_id, stock_movement.quantity)
|
17
|
+
context.stock_movement = stock_movement
|
18
|
+
else
|
19
|
+
context.fail!(message: stock_movement.errors.full_messages.join(', '))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def adjust_inventory_items_async(variant_id, quantity)
|
26
|
+
CmAppLogger.log(label: "#{self.class.name}#adjust_inventory_items_async", data: { variant_id: variant_id, quantity: quantity }) do
|
27
|
+
SpreeCmCommissioner::Stock::InventoryItemsAdjusterJob.perform_later(variant_id: variant_id, quantity: quantity)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class TaxiTripCreator < BaseInteractor
|
3
|
+
delegate :trip_params, to: :context
|
4
|
+
|
5
|
+
def call
|
6
|
+
ActiveRecord::Base.transaction do
|
7
|
+
create_trip_with_product
|
8
|
+
create_variant
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def create_trip_with_product
|
15
|
+
trip = SpreeCmCommissioner::Trip.new(trip_params)
|
16
|
+
|
17
|
+
if trip.save
|
18
|
+
context.trip = trip
|
19
|
+
context.product = trip.product
|
20
|
+
assign_option_type_to_product
|
21
|
+
context.product.save
|
22
|
+
else
|
23
|
+
context.fail!(error: "Failed to create taxi trip: #{trip.errors.full_messages.join(', ')}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_variant
|
28
|
+
variant = context.product.variants.new(
|
29
|
+
price: trip_params['product_attributes']['price'],
|
30
|
+
sku: "TRIP-#{context.formatted_name}-#{Time.current.to_i}",
|
31
|
+
option_value_ids: option_value_ids
|
32
|
+
)
|
33
|
+
|
34
|
+
if variant.save
|
35
|
+
context.variant = variant
|
36
|
+
create_stock_item_for_variant(variant)
|
37
|
+
else
|
38
|
+
context.fail!(error: "Failed to create taxi trip variant: #{variant.errors.full_messages.join(', ')}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_stock_item_for_variant(variant)
|
43
|
+
stock_location = context.product.vendor.stock_location
|
44
|
+
if stock_location.present?
|
45
|
+
Spree::StockItem.find_or_create_by!(variant: variant, stock_location: stock_location) do |item|
|
46
|
+
item.count_on_hand = 1
|
47
|
+
end
|
48
|
+
else
|
49
|
+
context.fail!(error: 'Vendor does not have an active stock location.')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def assign_option_type_to_product
|
54
|
+
option_type = Spree::OptionType.find_by(name: 'intercity-taxi')
|
55
|
+
return unless option_type
|
56
|
+
|
57
|
+
context.product.option_types << option_type
|
58
|
+
end
|
59
|
+
|
60
|
+
def option_value_ids
|
61
|
+
context.product.option_types.flat_map do |option_type|
|
62
|
+
option_type.option_values.pluck(:id)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# DraftOrderCreator creates a new order for a entire journey, including outbound and (if present) inbound directions.
|
2
|
+
#
|
3
|
+
# Attributes:
|
4
|
+
# - outbound_date: [Date] The date of outbound transit
|
5
|
+
# - inbound_date: [Date] The date of inbound transit
|
6
|
+
# - outbound_legs: [Array<SpreeCmCommissioner::Transit::Leg>] Outbound transit legs (one for direct, multiple for connecting)
|
7
|
+
# - inbound_legs: [Array<SpreeCmCommissioner::Transit::Leg>] Inbound transit legs (one for direct, multiple for connecting)
|
8
|
+
# - user: [User] The user for whom the order is being created
|
9
|
+
#
|
10
|
+
# Each line item is built with precise from_date and to_date based on legs and trip stop times.
|
11
|
+
# Each line item has guests built corresponding to seat selection blocks.
|
12
|
+
#
|
13
|
+
# Note: inbound_legs and inbound_date are optional; the order may represent a one-way (outbound only) journey.
|
14
|
+
module SpreeCmCommissioner
|
15
|
+
module Transit
|
16
|
+
class DraftOrderCreator < BaseInteractor
|
17
|
+
delegate :outbound_date,
|
18
|
+
:inbound_date,
|
19
|
+
:outbound_legs,
|
20
|
+
:inbound_legs,
|
21
|
+
:user, to: :context
|
22
|
+
|
23
|
+
def call
|
24
|
+
return context.fail!(message: 'Outbound legs are missing') if outbound_legs.blank?
|
25
|
+
|
26
|
+
begin
|
27
|
+
context.order = create_order!
|
28
|
+
rescue StandardError => e
|
29
|
+
context.fail!(message: e.message)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_order!
|
34
|
+
order = Spree::Order.new(state: 'cart', use_billing: true, user: user)
|
35
|
+
|
36
|
+
outbound_line_items = build_line_items_for_legs!(order: order, legs: outbound_legs, initial_date: outbound_date)
|
37
|
+
inbound_line_items = inbound_legs.blank? ? [] : build_line_items_for_legs!(order: order, legs: inbound_legs, initial_date: inbound_date)
|
38
|
+
|
39
|
+
outbound_qty = outbound_line_items.sum(&:quantity)
|
40
|
+
inbound_qty = inbound_line_items.sum(&:quantity)
|
41
|
+
|
42
|
+
raise StandardError, 'Outbound & inbound line item quantities do not match' if inbound_line_items.any? && outbound_qty != inbound_qty
|
43
|
+
raise StandardError, order.errors.full_messages.to_sentence unless order.save
|
44
|
+
|
45
|
+
order.update_with_updater!
|
46
|
+
order
|
47
|
+
end
|
48
|
+
|
49
|
+
# Build line items for each leg, using the previous leg's to_date as the next leg's date,
|
50
|
+
# or the initial date for the first leg.
|
51
|
+
def build_line_items_for_legs!(order:, legs:, initial_date:)
|
52
|
+
all_line_items = []
|
53
|
+
current_leg_date = initial_date
|
54
|
+
|
55
|
+
legs.each do |leg|
|
56
|
+
leg_line_items = build_line_items_for!(leg, order, current_leg_date)
|
57
|
+
leg_line_items = insert_saved_guests_per_line_items_leg(leg_line_items)
|
58
|
+
|
59
|
+
all_line_items.concat(leg_line_items)
|
60
|
+
current_leg_date = leg_line_items.last.to_date.to_date if leg_line_items.any?
|
61
|
+
end
|
62
|
+
|
63
|
+
all_line_items
|
64
|
+
end
|
65
|
+
|
66
|
+
def build_line_items_for!(leg, order, date)
|
67
|
+
trip = SpreeCmCommissioner::Trip.find(leg.trip_id)
|
68
|
+
trip_stops = trip.trip_stops.where(id: [leg.boarding_trip_stop_id, leg.drop_off_trip_stop_id]).index_by(&:id)
|
69
|
+
|
70
|
+
from_date, to_date = calculate_line_item_duration!(
|
71
|
+
date: date,
|
72
|
+
departure_time: trip_stops[leg.boarding_trip_stop_id].departure_time,
|
73
|
+
arrival_time: trip_stops[leg.drop_off_trip_stop_id].arrival_time
|
74
|
+
)
|
75
|
+
|
76
|
+
leg.seat_selections.group_by(&:variant_id).map do |variant_id, seat_selections|
|
77
|
+
line_item = order.line_items.new(
|
78
|
+
product_type: :transit,
|
79
|
+
from_date: from_date,
|
80
|
+
to_date: to_date,
|
81
|
+
variant_id: variant_id,
|
82
|
+
quantity: seat_selections.sum(&:quantity),
|
83
|
+
private_metadata: {
|
84
|
+
direction: leg.direction,
|
85
|
+
trip_id: leg.trip_id.to_s,
|
86
|
+
boarding_trip_stop_id: leg.boarding_trip_stop_id.to_s,
|
87
|
+
drop_off_trip_stop_id: leg.drop_off_trip_stop_id.to_s
|
88
|
+
}
|
89
|
+
)
|
90
|
+
|
91
|
+
build_guests_for!(line_item, seat_selections)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def build_guests_for!(line_item, seat_selections)
|
96
|
+
block_ids = seat_selections.flat_map(&:block_ids)
|
97
|
+
|
98
|
+
if block_ids.any? && block_ids.size != line_item.quantity
|
99
|
+
raise StandardError, "Number of blocks (#{block_ids.size}) does not match quantity (#{line_item.quantity})"
|
100
|
+
end
|
101
|
+
|
102
|
+
Array.new(line_item.quantity) do |index|
|
103
|
+
line_item.guests.new(block_id: block_ids[index])
|
104
|
+
end
|
105
|
+
|
106
|
+
line_item
|
107
|
+
end
|
108
|
+
|
109
|
+
def insert_saved_guests_per_line_items_leg(line_items)
|
110
|
+
line_items.flat_map(&:guests).each_with_index do |guest, index|
|
111
|
+
context.saved_guests ||= []
|
112
|
+
context.saved_guests << SpreeCmCommissioner::SavedGuest.new if context.saved_guests[index].blank?
|
113
|
+
|
114
|
+
guest.saved_guest = context.saved_guests[index]
|
115
|
+
end
|
116
|
+
|
117
|
+
line_items
|
118
|
+
end
|
119
|
+
|
120
|
+
def calculate_line_item_duration!(date:, departure_time:, arrival_time:)
|
121
|
+
raise StandardError, 'Departure or arrival time in trip stop is missing' if departure_time.blank? || arrival_time.blank?
|
122
|
+
raise StandardError, 'Arrival time cannot be before departure time' if arrival_time < departure_time
|
123
|
+
|
124
|
+
trip_duration_in_seconds = arrival_time - departure_time
|
125
|
+
|
126
|
+
# The input `date` is in local time (e.g., 10-10-2022).
|
127
|
+
# Combine it with the departure_time in Rails default timezone so that
|
128
|
+
# the resulting from_date stays on the intended local calendar day when stored in UTC.
|
129
|
+
from_date = Time.zone.local(date.year, date.month, date.day, departure_time.hour, departure_time.min, departure_time.sec)
|
130
|
+
to_date = from_date + trip_duration_in_seconds.seconds
|
131
|
+
|
132
|
+
[from_date, to_date]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class TripCloneCreator < BaseInteractor
|
3
|
+
delegate :vendor, :params, :original_trip, :places, :current_store, :current_vendor, to: :context
|
4
|
+
|
5
|
+
def call
|
6
|
+
ActiveRecord::Base.transaction do
|
7
|
+
cloned_product = create_cloned_product(original_trip.product)
|
8
|
+
cloned_trip = create_cloned_trip(original_trip, cloned_product)
|
9
|
+
|
10
|
+
departure_time_from_stops(cloned_trip)
|
11
|
+
calculate_trip_duration(cloned_trip)
|
12
|
+
|
13
|
+
cloned_trip.save!
|
14
|
+
context.cloned_trip = cloned_trip
|
15
|
+
clone_variants(original_trip, cloned_trip)
|
16
|
+
end
|
17
|
+
rescue StandardError => e
|
18
|
+
context.fail!(message: e.message)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Product cloning
|
24
|
+
def create_cloned_product(original_product)
|
25
|
+
return nil unless original_product
|
26
|
+
|
27
|
+
cloned_product = duplicate_product(original_product)
|
28
|
+
assign_vendor_attributes(cloned_product)
|
29
|
+
|
30
|
+
cloned_product.save!
|
31
|
+
cloned_product
|
32
|
+
end
|
33
|
+
|
34
|
+
def duplicate_product(original_product)
|
35
|
+
cloned = original_product.dup
|
36
|
+
%i[variants product_properties classifications option_types].each do |assoc|
|
37
|
+
cloned.public_send("#{assoc}=", [])
|
38
|
+
end
|
39
|
+
cloned
|
40
|
+
end
|
41
|
+
|
42
|
+
def assign_vendor_attributes(cloned_product)
|
43
|
+
cloned_product.vendor_id = vendor.id
|
44
|
+
cloned_product.store_ids = [current_store.id]
|
45
|
+
cloned_product.product_type = :transit
|
46
|
+
cloned_product.status = :active
|
47
|
+
cloned_product.price = original_trip.product.price if original_trip.product.price.present?
|
48
|
+
cloned_product.option_types = original_trip.product.option_types if original_trip.product.option_types.any?
|
49
|
+
|
50
|
+
return unless params[:product_attributes]
|
51
|
+
|
52
|
+
product_attributes = params[:product_attributes].dup
|
53
|
+
product_attributes[:name] ||= original_trip.product.name.to_s
|
54
|
+
cloned_product.assign_attributes(product_attributes)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Trip cloning
|
58
|
+
def create_cloned_trip(original_trip, cloned_product)
|
59
|
+
cloned_trip = build_cloned_trip(original_trip, cloned_product)
|
60
|
+
cloned_trip.trip_stops = clone_trip_stops(original_trip)
|
61
|
+
cloned_trip
|
62
|
+
end
|
63
|
+
|
64
|
+
def build_cloned_trip(original_trip, cloned_product)
|
65
|
+
cloned = original_trip.dup
|
66
|
+
cloned.product = cloned_product
|
67
|
+
cloned.vendor_id = vendor.id
|
68
|
+
cloned.assign_attributes(params.except(:product_attributes, :trip_stops_attributes))
|
69
|
+
cloned
|
70
|
+
end
|
71
|
+
|
72
|
+
def clone_trip_stops(original_trip)
|
73
|
+
original_trip.trip_stops.map.with_index do |stop, index|
|
74
|
+
clone_trip_stop(stop, index)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def clone_trip_stop(stop, index)
|
79
|
+
cloned_stop = stop.dup
|
80
|
+
cloned_stop.id = nil
|
81
|
+
cloned_stop.trip_id = nil
|
82
|
+
|
83
|
+
apply_trip_stop_params(cloned_stop, index)
|
84
|
+
validate_trip_stop!(cloned_stop)
|
85
|
+
|
86
|
+
cloned_stop
|
87
|
+
end
|
88
|
+
|
89
|
+
def apply_trip_stop_params(cloned_stop, index)
|
90
|
+
stop_params = params.dig(:trip_stops_attributes, index.to_s)
|
91
|
+
return unless stop_params
|
92
|
+
|
93
|
+
cloned_stop.departure_time = parse_time(stop_params[:departure_time])
|
94
|
+
cloned_stop.arrival_time = parse_time(stop_params[:arrival_time])
|
95
|
+
cloned_stop.stop_type = stop_params[:stop_type].presence
|
96
|
+
cloned_stop.location_place_id = stop_params[:location_place_id].presence
|
97
|
+
end
|
98
|
+
|
99
|
+
def parse_time(value)
|
100
|
+
Time.zone.parse(value) if value.present?
|
101
|
+
end
|
102
|
+
|
103
|
+
def validate_trip_stop!(cloned_stop)
|
104
|
+
return if cloned_stop.departure_time.present?
|
105
|
+
|
106
|
+
raise StandardError, "Departure time can't be blank for stop #{cloned_stop.stop_name}"
|
107
|
+
end
|
108
|
+
|
109
|
+
# Clone Variants
|
110
|
+
def clone_variants(original_trip, cloned_trip)
|
111
|
+
original_trip.product.variants.each do |variant|
|
112
|
+
new_variant = cloned_trip.product.variants.create!(
|
113
|
+
price: variant.price,
|
114
|
+
option_value_ids: variant.option_value_ids,
|
115
|
+
sku: ''
|
116
|
+
)
|
117
|
+
clone_variant_blocks(variant, new_variant)
|
118
|
+
end
|
119
|
+
rescue StandardError => e
|
120
|
+
raise StandardError, "Failed to clone variants: #{e.message}"
|
121
|
+
end
|
122
|
+
|
123
|
+
# clone variant_block (seat)
|
124
|
+
def clone_variant_blocks(origin_variant, new_variant)
|
125
|
+
block_data = {
|
126
|
+
block_ids: origin_variant.block_ids || []
|
127
|
+
}
|
128
|
+
|
129
|
+
context = SpreeCmCommissioner::VariantBlockUpdater.call(
|
130
|
+
variant: new_variant,
|
131
|
+
current_store: current_store,
|
132
|
+
data: block_data,
|
133
|
+
stock_location: current_vendor.stock_locations.first
|
134
|
+
)
|
135
|
+
|
136
|
+
raise StandardError, "Failed to update variant blocks: #{context.message}" unless context.success?
|
137
|
+
rescue StandardError => e
|
138
|
+
raise StandardError, "Failed to clone variant blocks: #{e.message}"
|
139
|
+
end
|
140
|
+
|
141
|
+
# Helpers
|
142
|
+
def departure_time_from_stops(trip)
|
143
|
+
first_departure = trip.trip_stops.first&.departure_time
|
144
|
+
trip.departure_time = first_departure if first_departure
|
145
|
+
end
|
146
|
+
|
147
|
+
def calculate_trip_duration(trip)
|
148
|
+
departures = trip.trip_stops.filter_map(&:departure_time)
|
149
|
+
arrivals = trip.trip_stops.filter_map(&:arrival_time)
|
150
|
+
return if departures.empty? || arrivals.empty?
|
151
|
+
|
152
|
+
trip.duration = (arrivals.max - departures.min).to_i
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class UserFbTokenAuthenticator < BaseInteractor
|
3
|
+
delegate :fb_access_token, :tenant_id, to: :context
|
4
|
+
|
5
|
+
# :fb_access_token, :tenant_id (optional)
|
6
|
+
def call
|
7
|
+
context.fail!(message: 'fb_access_token_missing') unless fb_access_token
|
8
|
+
|
9
|
+
context.user = if checker.user.nil?
|
10
|
+
register_user
|
11
|
+
else
|
12
|
+
checker.user
|
13
|
+
end
|
14
|
+
|
15
|
+
context.fail!(message: 'account_temporarily_deleted') if context.user.soft_deleted?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def checker
|
21
|
+
@checker ||= SpreeCmCommissioner::UserFbTokenChecker.call(
|
22
|
+
fb_access_token: fb_access_token,
|
23
|
+
tenant_id: tenant_id
|
24
|
+
)
|
25
|
+
@checker
|
26
|
+
end
|
27
|
+
|
28
|
+
def register_user
|
29
|
+
register_context = SpreeCmCommissioner::UserRegistrationWithFbToken.call(
|
30
|
+
provider: checker.provider,
|
31
|
+
tenant_id: tenant_id
|
32
|
+
)
|
33
|
+
|
34
|
+
register_context.user
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class UserFbTokenChecker < BaseInteractor
|
3
|
+
delegate :tenant_id, :fb_access_token, to: :context
|
4
|
+
|
5
|
+
def call
|
6
|
+
fb_data = SpreeCmCommissioner::FetchFacebookUserData.call(fb_access_token: fb_access_token)
|
7
|
+
context.fail!(message: fb_data.message) if fb_data.failure?
|
8
|
+
|
9
|
+
context.provider = fb_data.provider
|
10
|
+
|
11
|
+
identity_checker = SpreeCmCommissioner::UserIdentityChecker.call(
|
12
|
+
identity_type: context.provider[:identity_type],
|
13
|
+
sub: context.provider[:sub],
|
14
|
+
tenant_id: tenant_id
|
15
|
+
)
|
16
|
+
|
17
|
+
context.user = identity_checker.success? ? identity_checker.user : nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,28 +1,28 @@
|
|
1
1
|
module SpreeCmCommissioner
|
2
2
|
class UserIdentityChecker < BaseInteractor
|
3
|
+
delegate :identity_type, :sub, :tenant_id, to: :context
|
4
|
+
|
3
5
|
# expects:
|
4
6
|
# context.identity_type
|
5
7
|
# context.sub
|
6
8
|
# context.tenant_id (optional)
|
7
|
-
|
8
9
|
def call
|
9
10
|
load_user
|
10
11
|
|
11
12
|
return unless context.user.nil?
|
12
13
|
|
13
|
-
error_message = I18n.t('user_identity_provider.not_found', identity_type:
|
14
|
+
error_message = I18n.t('user_identity_provider.not_found', identity_type: identity_type)
|
14
15
|
context.fail!(message: error_message)
|
15
16
|
end
|
16
17
|
|
17
18
|
def load_user
|
18
|
-
return if
|
19
|
+
return if sub.blank? || identity_type.blank?
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
.first
|
21
|
+
user_identity_providers = UserIdentityProvider.joins(:user)
|
22
|
+
.where(identity_type: identity_type, sub: sub)
|
23
|
+
.where(spree_users: { tenant_id: tenant_id })
|
24
24
|
|
25
|
-
context.user =
|
25
|
+
context.user = user_identity_providers.first&.user
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|