spree_cm_commissioner 2.13.5 → 2.14.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/Gemfile.lock +1 -1
- data/app/assets/javascripts/spree_cm_commissioner/backend.js +0 -1
- data/app/assets/stylesheets/spree_cm_commissioner/backend/calendar.scss +0 -39
- data/app/controllers/concerns/spree/admin/rates_availability_cells.rb +16 -0
- data/app/controllers/concerns/spree/api/v2/product_list_includes_decorator.rb +1 -0
- data/app/controllers/spree/admin/base_controller_decorator.rb +14 -0
- data/app/controllers/spree/admin/customer_notifications_controller.rb +16 -1
- data/app/controllers/spree/admin/guests_controller.rb +2 -1
- data/app/controllers/spree/admin/integrations_controller.rb +16 -7
- data/app/controllers/spree/admin/inventory_items_controller.rb +33 -62
- data/app/controllers/spree/admin/prepaid_transactions_controller.rb +69 -0
- data/app/controllers/spree/admin/private_sales_controller.rb +6 -0
- data/app/controllers/spree/admin/product_commissions_controller.rb +2 -1
- data/app/controllers/spree/admin/product_option_types_controller.rb +88 -0
- data/app/controllers/spree/admin/rate_plans_controller.rb +125 -0
- data/app/controllers/spree/admin/rates_availabilities_controller.rb +142 -0
- data/app/controllers/spree/admin/reschedule_policies_controller.rb +148 -0
- data/app/controllers/spree/admin/reschedule_requests_controller.rb +82 -0
- data/app/controllers/spree/admin/stock_managements_controller.rb +1 -53
- data/app/controllers/spree/admin/store_credit_admin_controller.rb +122 -0
- data/app/controllers/spree/admin/ticket_transfer_rules_controller.rb +7 -0
- data/app/controllers/spree/api/switch_cm/base_controller.rb +109 -0
- data/app/controllers/spree/api/switch_cm/tokens_controller.rb +68 -0
- data/app/controllers/spree/api/switch_cm/xml/availabilities_controller.rb +39 -0
- data/app/controllers/spree/api/switch_cm/xml/base_controller.rb +37 -0
- data/app/controllers/spree/api/switch_cm/xml/reservation_summaries_controller.rb +28 -0
- data/app/controllers/spree/api/switch_cm/xml/reservations_controller.rb +57 -0
- data/app/controllers/spree/api/switch_cm/xml/room_rate_availabilities_controller.rb +56 -0
- data/app/controllers/spree/api/switch_cm/xml/room_rates_controller.rb +45 -0
- data/app/controllers/spree/api/v2/operator/guests_controller.rb +1 -1
- data/app/controllers/spree/api/v2/platform/store_credits_controller_decorator.rb +35 -0
- data/app/controllers/spree/api/v2/storefront/accommodations/variants_controller.rb +31 -5
- data/app/controllers/spree/api/v2/storefront/account/prepaid_balances_controller.rb +52 -0
- data/app/controllers/spree/api/v2/storefront/account/prepaid_transactions_controller.rb +56 -0
- data/app/controllers/spree/api/v2/storefront/draft_orders_controller.rb +37 -0
- data/app/controllers/spree/api/v2/storefront/inventory_items_controller.rb +2 -2
- data/app/controllers/spree/api/v2/storefront/prepaid_config_controller.rb +22 -0
- data/app/controllers/spree/api/v2/storefront/reschedule_requests_controller.rb +156 -0
- data/app/controllers/spree/api/v2/storefront/transit/item_availabilities_controller.rb +66 -0
- data/app/controllers/spree/api/v2/tenant/account/prepaid_balances_controller.rb +51 -0
- data/app/controllers/spree/api/v2/tenant/account/prepaid_transactions_controller.rb +53 -0
- data/app/controllers/spree/api/v2/tenant/base_controller.rb +20 -0
- data/app/controllers/spree/api/v2/tenant/draft_orders_controller.rb +42 -0
- data/app/controllers/spree/api/v2/tenant/intercity_taxi/draft_orders_controller.rb +0 -1
- data/app/controllers/spree/api/v2/tenant/prepaid_config_controller.rb +29 -0
- data/app/controllers/spree_cm_commissioner/admin/store_credits_controller_decorator.rb +217 -0
- data/app/errors/spree_cm_commissioner/reschedule_policies/invalid_policyable_error.rb +8 -0
- data/app/errors/spree_cm_commissioner/reschedule_policies/not_reschedulable_error.rb +11 -0
- data/app/errors/spree_cm_commissioner/reschedule_requests/cancel_not_allowed_error.rb +6 -0
- data/app/errors/spree_cm_commissioner/reschedule_requests/complete_cash_payment_error.rb +6 -0
- data/app/errors/spree_cm_commissioner/reschedule_requests/eligibility_denied_error.rb +7 -0
- data/app/factory/spree_cm_commissioner/order_telegram_message_factory.rb +7 -3
- data/app/factory/spree_cm_commissioner/reschedule_telegram_message_factory.rb +141 -0
- data/app/finders/spree_cm_commissioner/accommodations/find.rb +10 -8
- data/app/finders/spree_cm_commissioner/accommodations/find_variant.rb +5 -11
- data/app/finders/spree_cm_commissioner/inventory_items/recently_changed_finder.rb +1 -1
- data/app/finders/spree_cm_commissioner/rates_availabilities/find_bookings.rb +116 -0
- data/app/helpers/spree/admin/base_helper_decorator.rb +12 -0
- data/app/helpers/spree/admin/reschedule_policies_helper.rb +35 -0
- data/app/helpers/spree/admin/reschedule_requests_helper.rb +79 -0
- data/app/helpers/spree_cm_commissioner/admin/inventory_items_helper.rb +36 -0
- data/app/helpers/spree_cm_commissioner/admin/rates_availabilities_helper.rb +247 -0
- data/app/interactors/spree_cm_commissioner/create_ticket.rb +1 -0
- data/app/interactors/spree_cm_commissioner/intercity_taxi_order_creator.rb +0 -1
- data/app/jobs/spree_cm_commissioner/audit_event_job.rb +29 -0
- data/app/jobs/spree_cm_commissioner/option_type_variants_public_metadata_updater_job.rb +1 -0
- data/app/jobs/spree_cm_commissioner/option_value_variants_public_metadata_updater_job.rb +1 -0
- data/app/jobs/spree_cm_commissioner/prepaid_reconciliation_cron_job.rb +9 -0
- data/app/jobs/spree_cm_commissioner/prepaid_reverse_top_up_job.rb +16 -0
- data/app/jobs/spree_cm_commissioner/prepaid_setup_types_job.rb +24 -0
- data/app/jobs/spree_cm_commissioner/prepaid_top_up_credit_job.rb +31 -0
- data/app/jobs/spree_cm_commissioner/product_variants_public_metadata_updater_job.rb +12 -0
- data/app/jobs/spree_cm_commissioner/reschedule_requests/approval_reminder_job.rb +17 -0
- data/app/jobs/spree_cm_commissioner/reschedule_requests/execute_job.rb +20 -0
- data/app/jobs/spree_cm_commissioner/reschedule_requests/expire_overdue_requests_job.rb +12 -0
- data/app/jobs/spree_cm_commissioner/reschedule_requests/expire_request_job.rb +15 -0
- data/app/jobs/spree_cm_commissioner/reschedule_requests/payment_reminder_job.rb +17 -0
- data/app/models/concerns/spree_cm_commissioner/audit_wrapper.rb +139 -0
- data/app/models/concerns/spree_cm_commissioner/integrations/inventory_sync_cachable.rb +9 -0
- data/app/models/concerns/spree_cm_commissioner/kyc_bitwise.rb +4 -0
- data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +1 -10
- data/app/models/concerns/spree_cm_commissioner/line_item_guests_concern.rb +33 -3
- data/app/models/concerns/spree_cm_commissioner/line_item_rate_plannable.rb +55 -0
- data/app/models/concerns/spree_cm_commissioner/line_item_transitable.rb +0 -16
- data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +24 -5
- data/app/models/concerns/spree_cm_commissioner/order_prepaid_payment.rb +15 -0
- data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +56 -8
- data/app/models/concerns/spree_cm_commissioner/product_type.rb +1 -1
- data/app/models/concerns/spree_cm_commissioner/rate_plan_options_concern.rb +62 -0
- data/app/models/concerns/spree_cm_commissioner/reschedule_request_state_machine.rb +332 -0
- data/app/models/concerns/spree_cm_commissioner/service_type.rb +1 -1
- data/app/models/concerns/spree_cm_commissioner/store_preference.rb +1 -0
- data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +6 -0
- data/app/models/concerns/spree_cm_commissioner/variant_metadata.rb +24 -0
- data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +12 -0
- data/app/models/concerns/spree_cm_commissioner/variant_rate_plannable.rb +81 -0
- data/app/models/concerns/spree_cm_commissioner/vehicle_kind.rb +1 -1
- data/app/models/spree/core/controller_helpers/currency_decorator.rb +70 -0
- data/app/models/spree_cm_commissioner/address_decorator.rb +2 -0
- data/app/models/spree_cm_commissioner/audit_event.rb +11 -0
- data/app/models/spree_cm_commissioner/configuration.rb +17 -15
- data/app/models/spree_cm_commissioner/currency_rate.rb +15 -0
- data/app/models/spree_cm_commissioner/current.rb +8 -0
- data/app/models/spree_cm_commissioner/customer_notification.rb +4 -1
- data/app/models/spree_cm_commissioner/exports/import_order_guests_csv.rb +154 -0
- data/app/models/spree_cm_commissioner/exports/operator_guest_json_gzip.rb +8 -2
- data/app/models/spree_cm_commissioner/guest.rb +22 -1
- data/app/models/spree_cm_commissioner/integration.rb +46 -0
- data/app/models/spree_cm_commissioner/integrations/book_me_bus_v1.rb +64 -0
- data/app/models/spree_cm_commissioner/integrations/larryta.rb +81 -0
- data/app/models/spree_cm_commissioner/integrations/stadium_x_v1.rb +4 -10
- data/app/models/spree_cm_commissioner/integrations/switch_cm.rb +96 -0
- data/app/models/spree_cm_commissioner/integrations/vireak_buntham.rb +82 -0
- data/app/models/spree_cm_commissioner/inventory_item.rb +44 -3
- data/app/models/spree_cm_commissioner/line_item_decorator.rb +11 -7
- data/app/models/spree_cm_commissioner/maintenance_tasks/cache_invalidation.rb +20 -4
- data/app/models/spree_cm_commissioner/maintenance_tasks/event.rb +3 -2
- data/app/models/spree_cm_commissioner/notification.rb +8 -0
- data/app/models/spree_cm_commissioner/option_type_decorator.rb +2 -1
- data/app/models/spree_cm_commissioner/option_value_decorator.rb +3 -0
- data/app/models/spree_cm_commissioner/option_value_rate_plan.rb +12 -0
- data/app/models/spree_cm_commissioner/order_decorator.rb +20 -2
- data/app/models/spree_cm_commissioner/payment_decorator.rb +31 -0
- data/app/models/spree_cm_commissioner/payment_method_store_credit_decorator.rb +81 -0
- data/app/models/spree_cm_commissioner/place.rb +2 -0
- data/app/models/spree_cm_commissioner/prepaid_config.rb +59 -0
- data/app/models/spree_cm_commissioner/prepaid_transaction.rb +102 -0
- data/app/models/spree_cm_commissioner/price_decorator.rb +13 -0
- data/app/models/spree_cm_commissioner/product_decorator.rb +24 -2
- data/app/models/spree_cm_commissioner/product_option_type_decorator.rb +42 -0
- data/app/models/spree_cm_commissioner/rate_plan.rb +139 -0
- data/app/models/spree_cm_commissioner/rate_plan_options.rb +36 -0
- data/app/models/spree_cm_commissioner/rate_restriction.rb +45 -0
- data/app/models/spree_cm_commissioner/reschedule_policy.rb +94 -0
- data/app/models/spree_cm_commissioner/reschedule_policy_assignment.rb +19 -0
- data/app/models/spree_cm_commissioner/reschedule_request.rb +227 -0
- data/app/models/spree_cm_commissioner/reschedule_requests/guest_selection.rb +80 -0
- data/app/models/spree_cm_commissioner/reschedule_snapshot.rb +65 -0
- data/app/models/spree_cm_commissioner/route.rb +1 -0
- data/app/models/spree_cm_commissioner/seat_layout.rb +1 -0
- data/app/models/spree_cm_commissioner/service_calendar.rb +4 -0
- data/app/models/spree_cm_commissioner/stock_item_decorator.rb +4 -0
- data/app/models/spree_cm_commissioner/store_credit_category_decorator.rb +23 -0
- data/app/models/spree_cm_commissioner/store_credit_decorator.rb +142 -0
- data/app/models/spree_cm_commissioner/store_credit_event_decorator.rb +94 -0
- data/app/models/spree_cm_commissioner/store_credit_type_decorator.rb +43 -0
- data/app/models/spree_cm_commissioner/store_decorator.rb +8 -0
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +5 -2
- data/app/models/spree_cm_commissioner/tenant.rb +37 -0
- data/app/models/spree_cm_commissioner/trip.rb +2 -1
- data/app/models/spree_cm_commissioner/trip_stop.rb +2 -0
- data/app/models/spree_cm_commissioner/user_decorator.rb +79 -0
- data/app/models/spree_cm_commissioner/variant_decorator.rb +45 -6
- data/app/models/spree_cm_commissioner/variant_options.rb +3 -2
- data/app/models/spree_cm_commissioner/vehicle.rb +3 -0
- data/app/models/spree_cm_commissioner/vehicle_type.rb +1 -0
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +54 -0
- data/app/models/spree_cm_commissioner/vendor_place.rb +2 -0
- data/app/notifications/spree_cm_commissioner/reschedule_approved_notification.rb +7 -0
- data/app/notifications/spree_cm_commissioner/reschedule_cancelled_notification.rb +7 -0
- data/app/notifications/spree_cm_commissioner/reschedule_completed_notification.rb +7 -0
- data/app/notifications/spree_cm_commissioner/reschedule_expired_notification.rb +7 -0
- data/app/notifications/spree_cm_commissioner/reschedule_failed_notification.rb +7 -0
- data/app/notifications/spree_cm_commissioner/reschedule_notification_base.rb +41 -0
- data/app/notifications/spree_cm_commissioner/reschedule_payment_reminder_notification.rb +15 -0
- data/app/notifications/spree_cm_commissioner/reschedule_rejected_notification.rb +7 -0
- data/app/notifications/spree_cm_commissioner/reschedule_requested_notification.rb +7 -0
- data/app/overrides/spree/admin/option_types/_form/checkbox.html.erb.deface +0 -8
- data/app/overrides/spree/admin/option_types/_form/name.html.erb.deface +1 -1
- data/app/overrides/spree/admin/products/_filters/vendor_filter.html.erb.deface +6 -0
- data/app/overrides/spree/admin/products/_form/offline.html.erb.deface +9 -0
- data/app/overrides/spree/admin/shared/_main_menu/sidebar_reschedule.html.erb.deface +9 -0
- data/app/overrides/spree/admin/shared/_main_menu/sidebar_store_credit.html.erb.deface +8 -0
- data/app/overrides/spree/admin/shared/_order_tabs/reschedule_requests.html.erb.deface +10 -0
- data/app/overrides/spree/admin/shared/_product_tabs/rates_availabilities.html.erb.deface +8 -0
- data/app/overrides/spree/admin/shared/_product_tabs/stock_managements.html.erb.deface +1 -1
- data/app/overrides/spree/admin/variants/index/discontinued_badge.html.erb.deface +13 -0
- data/app/overrides/spree/admin/variants/index/option_types_empty_state_link.html.erb.deface +3 -0
- data/app/overrides/spree/admin/variants/index/option_types_summary.html.erb.deface +24 -0
- data/app/presenters/spree/variants/visible_options_presenter.rb +34 -1
- data/app/presenters/spree_cm_commissioner/prepaid_balance_presenter.rb +16 -0
- data/app/queries/spree_cm_commissioner/multi_leg_trips_query.rb +40 -22
- data/app/queries/spree_cm_commissioner/single_leg_trips_query.rb +28 -14
- data/app/queries/spree_cm_commissioner/store_credit_overview_query.rb +75 -0
- data/app/queries/spree_cm_commissioner/user_store_credit_summary_query.rb +53 -0
- data/app/request_schemas/spree_cm_commissioner/intercity_taxi_draft_order_update_schema.rb +0 -1
- data/app/serializables/spree_cm_commissioner/item_availability_sync.rb +10 -0
- data/app/serializers/spree/v2/storefront/line_item_serializer_decorator.rb +2 -0
- data/app/serializers/spree/v2/storefront/option_type_serializer_decorator.rb +1 -1
- data/app/serializers/spree/v2/storefront/prepaid_balance_serializer.rb +15 -0
- data/app/serializers/spree/v2/storefront/prepaid_config_serializer.rb +11 -0
- data/app/serializers/spree/v2/storefront/prepaid_transaction_serializer.rb +17 -0
- data/app/serializers/spree/v2/storefront/product_option_type_serializer.rb +15 -0
- data/app/serializers/spree/v2/storefront/product_serializer_decorator.rb +15 -0
- data/app/serializers/spree/v2/storefront/user_serializer_decorator.rb +6 -0
- data/app/serializers/spree/v2/tenant/line_item_serializer.rb +1 -1
- data/app/serializers/spree/v2/tenant/option_type_serializer.rb +1 -1
- data/app/serializers/spree/v2/tenant/prepaid_balance_serializer.rb +15 -0
- data/app/serializers/spree/v2/tenant/prepaid_config_serializer.rb +16 -0
- data/app/serializers/spree/v2/tenant/prepaid_transaction_serializer.rb +16 -0
- data/app/serializers/spree_cm_commissioner/v2/operator/dynamic_field_option_serializer.rb +9 -0
- data/app/serializers/spree_cm_commissioner/v2/operator/dynamic_field_serializer.rb +11 -0
- data/app/serializers/spree_cm_commissioner/v2/operator/guest_dynamic_field_serializer.rb +14 -0
- data/app/serializers/spree_cm_commissioner/v2/operator/guest_serializer.rb +1 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/accommodation_variant_serializer.rb +44 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/cart_serializer_decorator.rb +2 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/inventory_item_serializer.rb +4 -4
- data/app/serializers/spree_cm_commissioner/v2/storefront/item_availability_sync_serializer.rb +10 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/rate_plan_serializer.rb +16 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/reschedule_request_serializer.rb +49 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/reschedule_snapshot_serializer.rb +24 -0
- data/app/services/spree_cm_commissioner/audit_logger.rb +59 -0
- data/app/services/spree_cm_commissioner/checkout/add_store_credit_payments.rb +96 -0
- data/app/services/spree_cm_commissioner/currency_converter/create.rb +27 -0
- data/app/services/spree_cm_commissioner/currency_rates/manage.rb +99 -0
- data/app/services/spree_cm_commissioner/customer_notifications/clone.rb +39 -0
- data/app/services/spree_cm_commissioner/google_maps_geocoder.rb +41 -0
- data/app/services/spree_cm_commissioner/imports/orders/create.rb +24 -11
- data/app/services/spree_cm_commissioner/integrations/base/sync_manager.rb +1 -2
- data/app/services/spree_cm_commissioner/integrations/base/sync_result.rb +11 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/external_client/client.rb +230 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/external_client/connection.rb +147 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/inventory/external_inventory_item_status.rb +52 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/inventory/external_inventory_items.rb +91 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/inventory/unstock_inventory.rb +188 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_inventory.rb +79 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_item_availability.rb +354 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_locations.rb +103 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_nationality_pricing.rb +93 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_product.rb +70 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_route_stops.rb +121 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_routes.rb +128 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_seat_layout.rb +412 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_service_calendars.rb +59 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_trip_stop.rb +224 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_trips.rb +769 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_variant.rb +69 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_vehicle_types.rb +92 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/time_parser.rb +19 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/base.rb +40 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/inventory_item_status.rb +148 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/location.rb +55 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/reservation_cart.rb +85 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/seat.rb +128 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/seat_layout.rb +386 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/stop.rb +84 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/trip.rb +237 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/wallet_payment.rb +48 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/sync_manager.rb +22 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/sync_strategies/full_sync_strategy.rb +116 -0
- data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/sync_strategies/incremental_sync_strategy.rb +63 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/external_client/client.rb +314 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/external_client/connection.rb +74 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/inventory/external_inventory_item_status.rb +53 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/inventory/external_inventory_items.rb +106 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/inventory/hold_seats.rb +143 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/inventory/release_seats.rb +90 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/inventory/unstock_inventory.rb +143 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_item_availability.rb +325 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_product.rb +72 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_routes.rb +142 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_seat_layout.rb +255 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_stock_item.rb +55 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_trip_stop.rb +171 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_trips.rb +397 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_variant.rb +63 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_vehicle_type.rb +79 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/resources/base.rb +39 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/resources/booking.rb +113 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/resources/booking_session.rb +43 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/resources/booking_transaction.rb +236 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/resources/direction.rb +71 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/resources/passenger.rb +48 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/resources/schedule.rb +150 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/resources/seat.rb +31 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/resources/seat_availability.rb +49 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/resources/seat_layout.rb +211 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/sync_manager.rb +17 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/sync_strategies/full_sync_strategy.rb +79 -0
- data/app/services/spree_cm_commissioner/integrations/larryta/sync_strategies/incremental_sync_strategy.rb +58 -0
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/external_client/client.rb +14 -15
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb +7 -4
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_zones.rb +6 -3
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_manager.rb +0 -3
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/full_sync_strategy.rb +1 -3
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/incremental_sync_strategy.rb +1 -3
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/webhook_sync_strategy.rb +1 -2
- data/app/services/spree_cm_commissioner/integrations/switch_cm/inventory/accept_push.rb +111 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/inventory/accommodation_lock.rb +43 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/inventory/apply_updates.rb +133 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/inventory/availability_snapshot.rb +127 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/inventory/inventory_update.rb +35 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/inventory/pushed_nights.rb +82 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/inventory/unseen_room_nights.rb +49 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/inventory/validate_updates.rb +153 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/reservations/feed.rb +209 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/reservations/mark_seen.rb +62 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/reservations/reservation.rb +171 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/room_catalog.rb +88 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/sync_manager.rb +16 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/sync_strategies/full_sync_strategy.rb +39 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/sync_strategies/incremental_sync_strategy.rb +51 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/xml/availability_parser.rb +103 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/xml/push_response.rb +45 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/xml/reservation_serializer.rb +83 -0
- data/app/services/spree_cm_commissioner/integrations/switch_cm/xml/response_builder.rb +19 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/external_client/client.rb +170 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/external_client/connection.rb +59 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/inventory/external_inventory_item_status.rb +48 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/inventory/external_inventory_items.rb +92 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/inventory/unstock_inventory.rb +230 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_item_availability.rb +270 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_locations.rb +96 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_nationality_pricing.rb +76 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_product.rb +69 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_routes.rb +110 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_seat_layout.rb +207 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_stock_item.rb +43 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_trip_stop.rb +192 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_trips.rb +377 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_variant.rb +56 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_vehicle_type.rb +51 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/base.rb +32 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/booking.rb +48 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/booking_transaction.rb +46 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/cell.rb +53 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/confirm_booking_request.rb +43 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/location.rb +37 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/schedule.rb +138 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/seat.rb +48 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/seat_layout.rb +79 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/sync_manager.rb +17 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/sync_strategies/full_sync_strategy.rb +87 -0
- data/app/services/spree_cm_commissioner/integrations/vireak_buntham/sync_strategies/incremental_sync_strategy.rb +53 -0
- data/app/services/spree_cm_commissioner/intercity_taxi_order/update.rb +1 -3
- data/app/services/spree_cm_commissioner/inventory_holds/release.rb +13 -0
- data/app/services/spree_cm_commissioner/inventory_items/bulk_adjust_quantities_by_variant.rb +4 -0
- data/app/services/spree_cm_commissioner/inventory_items/generate_permanent_item.rb +48 -0
- data/app/services/spree_cm_commissioner/inventory_items/reset.rb +4 -0
- data/app/services/spree_cm_commissioner/order_holds/hold.rb +17 -0
- data/app/services/spree_cm_commissioner/order_holds/release.rb +31 -0
- data/app/services/spree_cm_commissioner/place_resolver.rb +95 -0
- data/app/services/spree_cm_commissioner/prepaid/admin_credit.rb +44 -0
- data/app/services/spree_cm_commissioner/prepaid/check_top_up_limits.rb +47 -0
- data/app/services/spree_cm_commissioner/prepaid/freeze.rb +58 -0
- data/app/services/spree_cm_commissioner/prepaid/mutation.rb +78 -0
- data/app/services/spree_cm_commissioner/prepaid/reverse_order_top_up.rb +23 -0
- data/app/services/spree_cm_commissioner/prepaid/reverse_top_up.rb +53 -0
- data/app/services/spree_cm_commissioner/prepaid/top_up.rb +68 -0
- data/app/services/spree_cm_commissioner/prepaid/unfreeze.rb +47 -0
- data/app/services/spree_cm_commissioner/prepaid_metrics.rb +37 -0
- data/app/services/spree_cm_commissioner/prepaid_reconciliation_service.rb +71 -0
- data/app/services/spree_cm_commissioner/rate_plans/save.rb +65 -0
- data/app/services/spree_cm_commissioner/rates_availabilities/bulk_update.rb +225 -0
- data/app/services/spree_cm_commissioner/reschedule_policies/assign.rb +52 -0
- data/app/services/spree_cm_commissioner/reschedule_policies/create.rb +71 -0
- data/app/services/spree_cm_commissioner/reschedule_policies/exclude.rb +40 -0
- data/app/services/spree_cm_commissioner/reschedule_policies/resolve.rb +109 -0
- data/app/services/spree_cm_commissioner/reschedule_policies/unassign.rb +23 -0
- data/app/services/spree_cm_commissioner/reschedule_policies/update.rb +73 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/authorize_initiator.rb +79 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/build_request.rb +317 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/calculate_fee.rb +71 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/cancel.rb +55 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/check_eligibility.rb +243 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/collect_payment.rb +204 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/execute.rb +252 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/expire_overdue_requests.rb +28 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/expire_request.rb +24 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/guests/update_seats.rb +210 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/initiate.rb +255 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/issue_compensation.rb +67 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/issue_coupon.rb +90 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/issue_store_credit.rb +16 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/notifications/send_approval_reminder.rb +43 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/notifications/send_payment_reminder.rb +46 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/notifications/send_status_update.rb +42 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/seats/hold.rb +137 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/split_line_item.rb +91 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/telegram/notify_operations.rb +37 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/telegram/notify_vendor.rb +51 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/vendors/approve.rb +61 -0
- data/app/services/spree_cm_commissioner/reschedule_requests/vendors/reject.rb +58 -0
- data/app/services/spree_cm_commissioner/room_types/create.rb +87 -0
- data/app/services/spree_cm_commissioner/room_types/update_properties.rb +32 -0
- data/app/services/spree_cm_commissioner/room_types.rb +40 -0
- data/app/services/spree_cm_commissioner/route_prices/update_price_range.rb +3 -1
- data/app/services/spree_cm_commissioner/topup_draft_orders/create.rb +234 -0
- data/app/services/spree_cm_commissioner/trips/search.rb +14 -7
- data/app/services/spree_cm_commissioner/trips/service_calendars/create_or_update.rb +25 -14
- data/app/services/spree_cm_commissioner/trips/update_single_leg.rb +48 -7
- data/app/views/spree/admin/classifications/edit.html.erb +17 -2
- data/app/views/spree/admin/classifications/new.html.erb +18 -2
- data/app/views/spree/admin/customer_notifications/index.html.erb +45 -3
- data/app/views/spree/admin/guests/_check_in_status.html.erb +28 -22
- data/app/views/spree/admin/guests/edit.html.erb +29 -26
- data/app/views/spree/admin/integrations/_book_me_bus_v1_fields.html.erb +47 -0
- data/app/views/spree/admin/integrations/_form.html.erb +16 -0
- data/app/views/spree/admin/integrations/_larryta_fields.html.erb +58 -0
- data/app/views/spree/admin/integrations/_switch_cm_fields.html.erb +53 -0
- data/app/views/spree/admin/integrations/_vireak_buntham_fields.html.erb +75 -0
- data/app/views/spree/admin/integrations/index.html.erb +1 -1
- data/app/views/spree/admin/inventory_items/_details.html.erb +56 -0
- data/app/views/spree/admin/prepaid_transactions/index.html.erb +102 -0
- data/app/views/spree/admin/prepaid_transactions/show.html.erb +146 -0
- data/app/views/spree/admin/private_sales/_form.html.erb +24 -1
- data/app/views/spree/admin/private_sales/_stock.html.erb +6 -1
- data/app/views/spree/admin/product_commissions/index.html.erb +7 -2
- data/app/views/spree/admin/product_option_types/index.html.erb +79 -0
- data/app/views/spree/admin/rate_plans/_form.html.erb +134 -0
- data/app/views/spree/admin/rate_plans/_order_form.html.erb +37 -0
- data/app/views/spree/admin/rates_availabilities/_block.html.erb +34 -0
- data/app/views/spree/admin/rates_availabilities/_bookings.html.erb +52 -0
- data/app/views/spree/admin/rates_availabilities/_filters.html.erb +48 -0
- data/app/views/spree/admin/rates_availabilities/_legend.html.erb +27 -0
- data/app/views/spree/admin/rates_availabilities/_list_pages.html.erb +14 -0
- data/app/views/spree/admin/rates_availabilities/_modal_header.html.erb +11 -0
- data/app/views/spree/admin/rates_availabilities/_names.html.erb +62 -0
- data/app/views/spree/admin/rates_availabilities/_script.html.erb +676 -0
- data/app/views/spree/admin/rates_availabilities/_styles.html.erb +159 -0
- data/app/views/spree/admin/rates_availabilities/index.html.erb +112 -0
- data/app/views/spree/admin/reschedule_policies/_form.html.erb +65 -0
- data/app/views/spree/admin/reschedule_policies/edit.html.erb +11 -0
- data/app/views/spree/admin/reschedule_policies/index.html.erb +84 -0
- data/app/views/spree/admin/reschedule_policies/new.html.erb +11 -0
- data/app/views/spree/admin/reschedule_requests/_cancel_modal.html.erb +34 -0
- data/app/views/spree/admin/reschedule_requests/_search_form.html.erb +57 -0
- data/app/views/spree/admin/reschedule_requests/_tabs.html.erb +14 -0
- data/app/views/spree/admin/reschedule_requests/index.html.erb +64 -0
- data/app/views/spree/admin/reschedule_requests/show.html.erb +212 -0
- data/app/views/spree/admin/reschedule_requests/state_changes.html.erb +42 -0
- data/app/views/spree/admin/shared/_products.html.erb +3 -0
- data/app/views/spree/admin/shared/_reschedule_policies_tabs.html.erb +22 -0
- data/app/views/spree/admin/shared/_ticket_transfer_details.html.erb +3 -0
- data/app/views/spree/admin/shared/sub_menu/_homepage.html.erb +0 -1
- data/app/views/spree/admin/shared/sub_menu/_reschedule.html.erb +4 -0
- data/app/views/spree/admin/stock_managements/_header.html.erb +0 -14
- data/app/views/spree/admin/stock_managements/_inventory_item_stats.html.erb +28 -0
- data/app/views/spree/admin/stock_managements/index.html.erb +1 -56
- data/app/views/spree/admin/store_credit_admin/_tabs.html.erb +31 -0
- data/app/views/spree/admin/store_credit_admin/_tenant_selector.html.erb +17 -0
- data/app/views/spree/admin/store_credit_admin/show.html.erb +200 -0
- data/app/views/spree/admin/store_credits/index.html.erb +224 -0
- data/app/views/spree/admin/tenants/_form.html.erb +33 -0
- data/app/views/spree/admin/ticket_transfer_rules/_form.html.erb +28 -5
- data/config/initializers/spree_dependencies.rb +3 -0
- data/config/initializers/spree_permitted_attributes.rb +2 -0
- data/config/locales/en.yml +592 -3
- data/config/locales/km.yml +511 -4
- data/config/routes.rb +98 -18
- data/db/migrate/20260327143200_create_cm_audit_events.rb +21 -0
- data/db/migrate/20260410045815_create_cm_currency_rates.rb +23 -0
- data/db/migrate/20260411102139_add_metadata_to_cm_inventory_items.rb +6 -0
- data/db/migrate/20260506120000_create_cm_reschedule_policies.rb +38 -0
- data/db/migrate/20260506120001_create_cm_reschedule_requests.rb +67 -0
- data/db/migrate/20260506120002_add_reschedule_count_to_cm_guests.rb +5 -0
- data/db/migrate/20260521140000_create_cm_reschedule_snapshots.rb +38 -0
- data/db/migrate/20260522160000_create_cm_reschedule_policy_assignments.rb +17 -0
- data/db/migrate/20260722000001_create_cm_prepaid_transactions.rb +31 -0
- data/db/migrate/20260722000002_add_constraints_to_store_credits.rb +46 -0
- data/db/migrate/20260722000003_add_expires_at_to_store_credits.rb +6 -0
- data/db/migrate/20260722000004_add_issuer_tenant_id_to_spree_store_credits.rb +7 -0
- data/db/migrate/20260722000005_add_immutability_trigger_to_cm_prepaid_transactions.rb +36 -0
- data/db/migrate/20260918045558_add_prepaid_currency_columns_to_cm_tenants.rb +6 -0
- data/db/migrate/20260923090000_add_public_private_metadata_to_cm_prepaid_transactions.rb +36 -0
- data/db/migrate/20260928000000_add_oauth_application_id_to_cm_integrations.rb +5 -0
- data/db/migrate/20260929000000_create_cm_rate_plans.rb +22 -0
- data/db/migrate/20260929000001_add_rate_plan_to_spree_prices.rb +24 -0
- data/db/migrate/20260929000002_add_rate_plan_to_spree_line_items.rb +7 -0
- data/db/migrate/20260929000003_create_cm_option_value_rate_plans.rb +16 -0
- data/db/migrate/20261006073317_add_offline_to_spree_products.rb +6 -0
- data/db/migrate/20261009000000_create_cm_rate_restrictions.rb +29 -0
- data/db/migrate/20261013000001_add_hidden_and_presentation_to_spree_product_option_types.rb +6 -0
- data/db/migrate/20261013000002_move_hidden_from_spree_option_types_to_product_option_types.rb +36 -0
- data/db/migrate/20261016000001_add_index_to_spree_line_items_number.rb +8 -0
- data/lib/spree_cm_commissioner/booking_dates.rb +43 -0
- data/lib/spree_cm_commissioner/calendar_event.rb +0 -25
- data/lib/spree_cm_commissioner/rate.rb +74 -0
- data/lib/spree_cm_commissioner/rate_closings.rb +48 -0
- data/lib/spree_cm_commissioner/rates_availability_grid.rb +113 -0
- data/lib/spree_cm_commissioner/reschedule_policy_rules.rb +75 -0
- data/lib/spree_cm_commissioner/serializable_transaction.rb +38 -0
- data/lib/spree_cm_commissioner/stay_price.rb +30 -0
- data/lib/spree_cm_commissioner/stay_prices.rb +58 -0
- data/lib/spree_cm_commissioner/store_credit_currency_summary.rb +11 -0
- data/lib/spree_cm_commissioner/store_credit_summary.rb +11 -0
- data/lib/spree_cm_commissioner/test_helper/factories/integration_factory.rb +17 -0
- data/lib/spree_cm_commissioner/test_helper/factories/option_type_factory.rb +6 -0
- data/lib/spree_cm_commissioner/test_helper/factories/option_value_rate_plan_factory.rb +6 -0
- data/lib/spree_cm_commissioner/test_helper/factories/prepaid_transaction_factory.rb +12 -0
- data/lib/spree_cm_commissioner/test_helper/factories/rate_plan_factory.rb +14 -0
- data/lib/spree_cm_commissioner/test_helper/factories/reschedule_policy_assignment_factory.rb +7 -0
- data/lib/spree_cm_commissioner/test_helper/factories/reschedule_policy_factory.rb +59 -0
- data/lib/spree_cm_commissioner/test_helper/factories/reschedule_request_factory.rb +51 -0
- data/lib/spree_cm_commissioner/test_helper/factories/reschedule_snapshot_factory.rb +27 -0
- data/lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb +9 -0
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +10 -0
- data/lib/tasks/prepaid_reconciliation_cron_scheduler.rake +7 -0
- data/lib/tasks/prepaid_setup_types.rake +7 -0
- metadata +361 -32
- data/app/assets/javascripts/spree_cm_commissioner/calendar.js +0 -59
- data/app/controllers/spree/admin/calendars/base_controller.rb +0 -27
- data/app/controllers/spree/admin/calendars/orders_controller.rb +0 -27
- data/app/controllers/spree/admin/homepage_feed_controller.rb +0 -36
- data/app/controllers/spree/admin/metafields_controller.rb +0 -69
- data/app/models/concerns/spree_cm_commissioner/metafield.rb +0 -15
- data/app/models/spree_cm_commissioner/homepage_feed.rb +0 -4
- data/app/overrides/spree/admin/shared/_main_menu/sidebar_calendars.html.erb.deface +0 -5
- data/app/overrides/spree/admin/shared/_product_tabs/metafields.html.erb.deface +0 -15
- data/app/serializers/spree_cm_commissioner/v2/storefront/taxon_include_product_serializer.rb +0 -13
- data/app/serializers/spree_cm_commissioner/v2/storefront/vendor_include_product_serializer.rb +0 -14
- data/app/services/spree_cm_commissioner/feed/taxon_include_product.rb +0 -20
- data/app/services/spree_cm_commissioner/feed/taxon_product.rb +0 -54
- data/app/services/spree_cm_commissioner/feed/vendor_include_product.rb +0 -20
- data/app/services/spree_cm_commissioner/feed/vendor_product.rb +0 -52
- data/app/services/spree_cm_commissioner/homepage_data_loader.rb +0 -112
- data/app/services/spree_cm_commissioner/metafields/product_metadata_service.rb +0 -32
- data/app/views/shared/_calendar.html.erb +0 -27
- data/app/views/shared/calendar/_order_popover.html.erb +0 -18
- data/app/views/shared/calendar/_orders_sidebar.html.erb +0 -41
- data/app/views/spree/admin/calendars/orders/index.html.erb +0 -22
- data/app/views/spree/admin/homepage_feed/_form.html.erb +0 -24
- data/app/views/spree/admin/homepage_feed/edit.html.erb +0 -17
- data/app/views/spree/admin/inventory_items/prices.html.erb +0 -43
- data/app/views/spree/admin/inventory_items/stocks.html.erb +0 -34
- data/app/views/spree/admin/metafields/_private_metafields_form.html.erb +0 -71
- data/app/views/spree/admin/metafields/_public_metafields_form.html.erb +0 -64
- data/app/views/spree/admin/metafields/edit.html.erb +0 -27
- data/app/views/spree/admin/shared/sub_menu/_calendar.html.erb +0 -3
- data/app/views/spree/admin/stock_managements/calendar.html.erb +0 -310
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
# Stock, prices and sale status of a product's variants and their rate plans, per date.
|
|
4
|
+
# StockManagementsController keeps per-variant setup: stock locations, track inventory, purchases, resets.
|
|
5
|
+
class RatesAvailabilitiesController < Spree::Admin::BaseController
|
|
6
|
+
include RatesAvailabilityCells
|
|
7
|
+
|
|
8
|
+
MIN_DAYS_AHEAD = 14
|
|
9
|
+
MAX_BLOCK_DAYS = 62
|
|
10
|
+
VARIANTS_PER_PAGE = 25
|
|
11
|
+
BOOKINGS_PER_PAGE = 25
|
|
12
|
+
|
|
13
|
+
before_action :load_product
|
|
14
|
+
before_action :load_grid, only: %i[index dates]
|
|
15
|
+
|
|
16
|
+
helper SpreeCmCommissioner::Admin::RatesAvailabilitiesHelper
|
|
17
|
+
helper_method :filter_params
|
|
18
|
+
|
|
19
|
+
# GET /products/:product_id/rates_availabilities?from=¤cy=&option_value_ids[]=&archived=&page=
|
|
20
|
+
def index
|
|
21
|
+
@option_types = Spree::Variants::OptionTypesFinder.new(variant_ids: @product.variants.ids).execute.select(&:variant?)
|
|
22
|
+
@currencies = supported_currencies_for_all_stores.map(&:iso_code)
|
|
23
|
+
# A channel manager sets these variants' stock, prices and closings, so BulkUpdate skips them; the page says why.
|
|
24
|
+
@managing_integration = @product.vendor&.integration if @grid.variants.any?(&:inventory_external_wins?)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# GET /products/:product_id/rates_availabilities/dates?from=&to=&<index filters>
|
|
28
|
+
#
|
|
29
|
+
# The page adds this block next to the dates it already shows, so a range across months doesn't need a reload.
|
|
30
|
+
# It asks for whole months, so a month never spans two blocks.
|
|
31
|
+
def dates
|
|
32
|
+
render partial: 'block', locals: { grid: @grid }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# PATCH /products/:product_id/rates_availabilities/bulk_update, JSON: { bulk_action:, cells: [...], values: {...} }
|
|
36
|
+
#
|
|
37
|
+
# Answers with the counts, and the page then reloads its loaded dates.
|
|
38
|
+
def bulk_update
|
|
39
|
+
result = SpreeCmCommissioner::RatesAvailabilities::BulkUpdate.call(
|
|
40
|
+
product: @product,
|
|
41
|
+
store: current_store,
|
|
42
|
+
action: params[:bulk_action].to_s,
|
|
43
|
+
cells: selected_cells,
|
|
44
|
+
values: params.fetch(:values, {}).permit(:amount, :compare_at_amount, :quantity, :currency),
|
|
45
|
+
user: try_spree_current_user
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
if result.success?
|
|
49
|
+
render json: result.value
|
|
50
|
+
else
|
|
51
|
+
render json: { error: result.error.to_s }, status: :unprocessable_entity
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# POST /products/:product_id/rates_availabilities/bookings, JSON: { cells: [...], filter:, q:, page: }
|
|
56
|
+
#
|
|
57
|
+
# The bookings modal for the selected cells. POST, as cells travel in the body.
|
|
58
|
+
def bookings
|
|
59
|
+
finder = SpreeCmCommissioner::RatesAvailabilities::FindBookings.new(
|
|
60
|
+
product: @product,
|
|
61
|
+
cells: selected_cells,
|
|
62
|
+
filter: params[:filter].to_s,
|
|
63
|
+
query: params[:q]
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
line_items = finder.execute.page(params[:page]).per(BOOKINGS_PER_PAGE)
|
|
67
|
+
render partial: 'bookings', formats: [:html], locals: {
|
|
68
|
+
finder: finder,
|
|
69
|
+
line_items: line_items,
|
|
70
|
+
cells: selected_cells,
|
|
71
|
+
held_order_ids: finder.held_order_ids_among(line_items)
|
|
72
|
+
}
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def filter_params
|
|
78
|
+
params.permit(:currency, :archived, option_value_ids: []).to_h
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def load_product
|
|
82
|
+
@product = Spree::Product.find_by!(slug: params[:product_id])
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def load_grid
|
|
86
|
+
@include_archived = params[:archived] == '1'
|
|
87
|
+
@variants = variants.page(params[:page]).per(VARIANTS_PER_PAGE)
|
|
88
|
+
@currency = (params[:currency].presence || current_currency).upcase
|
|
89
|
+
@from = parse_date(params[:from]) || Time.zone.today
|
|
90
|
+
|
|
91
|
+
dates = @product.permanent_stock? ? date_window.to_a : []
|
|
92
|
+
|
|
93
|
+
@grid = SpreeCmCommissioner::RatesAvailabilityGrid.new(
|
|
94
|
+
variants: @variants.to_a,
|
|
95
|
+
dates: dates,
|
|
96
|
+
currency: @currency,
|
|
97
|
+
include_archived: @include_archived
|
|
98
|
+
)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def variants
|
|
102
|
+
rate_plans = @include_archived ? :rate_plans : :active_rate_plans
|
|
103
|
+
scope = @product.variants.exists? ? @product.variants : Spree::Variant.where(id: @product.master.id)
|
|
104
|
+
scope = scope.where(id: matching_variant_ids) if option_value_ids.present?
|
|
105
|
+
scope.includes(:stock_items, { rate_plans => { option_values: :option_type } }, { vendor: :integration }, option_values: :option_type)
|
|
106
|
+
.order(:position, :id)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def option_value_ids
|
|
110
|
+
@option_value_ids ||= Array(params[:option_value_ids]).compact_blank.map(&:to_i)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def matching_variant_ids
|
|
114
|
+
SpreeCmCommissioner::Variants::FindByOptionValueIds.new(product: @product, option_value_ids: option_value_ids).execute.ids
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# The first window is `from`'s month, plus the next one when fewer than MIN_DAYS_AHEAD days are left, so a
|
|
118
|
+
# late `from` still shows weeks ahead. Whole months, so the blocks added next to it are whole months too.
|
|
119
|
+
# Kept to about a month: every day is a column on every row, and a dated product can have many variants.
|
|
120
|
+
# The page scrolls to `from`.
|
|
121
|
+
def date_window
|
|
122
|
+
to = parse_date(params[:to])
|
|
123
|
+
return @from..[to, @from + (MAX_BLOCK_DAYS - 1)].min if to
|
|
124
|
+
|
|
125
|
+
last = @from.end_of_month
|
|
126
|
+
last = @from.next_month.end_of_month if (last - @from).to_i + 1 < MIN_DAYS_AHEAD
|
|
127
|
+
@from.beginning_of_month..last
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def parse_date(value)
|
|
131
|
+
Date.parse(value.to_s) if value.present?
|
|
132
|
+
rescue Date::Error
|
|
133
|
+
nil
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Same permission as the stock calendar this replaces.
|
|
137
|
+
def model_class
|
|
138
|
+
Spree::StockItem
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
# Platform-admin management of reschedule policies, built like the Payment
|
|
4
|
+
# Methods page: a scoped tab bar (Store / Vendors / Tenants) over the shared
|
|
5
|
+
# ReschedulePolicy table.
|
|
6
|
+
#
|
|
7
|
+
# - Store tab (default): platform policies (vendor_id nil). Full CRUD.
|
|
8
|
+
# - Vendors tab: every vendor policy, read-only.
|
|
9
|
+
# - Tenants tab: vendor policies whose vendor belongs to a tenant, read-only.
|
|
10
|
+
#
|
|
11
|
+
# Create/Update delegate to the existing ReschedulePolicies services (with
|
|
12
|
+
# vendor: nil), which own calculator building, typed rules, and the
|
|
13
|
+
# one-default-per-scope rule.
|
|
14
|
+
class ReschedulePoliciesController < BaseController
|
|
15
|
+
# Only these tabs switch the page into read-only vendor/tenant mode; any
|
|
16
|
+
# other value falls back to the store tab, in the controller and the view
|
|
17
|
+
# alike (see `current_tab`).
|
|
18
|
+
TABS = %w[vendors tenants].freeze
|
|
19
|
+
|
|
20
|
+
before_action :load_policy, only: %i[edit update destroy set_default]
|
|
21
|
+
|
|
22
|
+
helper_method :current_tab
|
|
23
|
+
|
|
24
|
+
def index
|
|
25
|
+
authorize! :manage, SpreeCmCommissioner::ReschedulePolicy
|
|
26
|
+
|
|
27
|
+
@search = collection.ransack(params[:q])
|
|
28
|
+
@reschedule_policies = @search.result
|
|
29
|
+
.order(default: :desc, name: :asc)
|
|
30
|
+
.page(params[:page])
|
|
31
|
+
.per(params[:per_page] || 20)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def new
|
|
35
|
+
authorize! :manage, SpreeCmCommissioner::ReschedulePolicy
|
|
36
|
+
@reschedule_policy = SpreeCmCommissioner::ReschedulePolicy.new(status: :active)
|
|
37
|
+
# Seed a calculator so the fee fields render; the form/services can swap it.
|
|
38
|
+
@reschedule_policy.calculator_type = 'Spree::Calculator::FlatRate'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def create
|
|
42
|
+
authorize! :manage, SpreeCmCommissioner::ReschedulePolicy
|
|
43
|
+
|
|
44
|
+
result = SpreeCmCommissioner::ReschedulePolicies::Create.call(vendor: nil, options: policy_params)
|
|
45
|
+
if result.success?
|
|
46
|
+
flash[:success] = Spree.t(:successfully_created, resource: reschedule_policy_name)
|
|
47
|
+
redirect_to admin_reschedule_policies_path
|
|
48
|
+
else
|
|
49
|
+
@reschedule_policy = result.value || SpreeCmCommissioner::ReschedulePolicy.new
|
|
50
|
+
flash.now[:error] = result.error&.value
|
|
51
|
+
render :new, status: :unprocessable_entity
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def update
|
|
56
|
+
result = SpreeCmCommissioner::ReschedulePolicies::Update.call(policy: @reschedule_policy, options: policy_params)
|
|
57
|
+
if result.success?
|
|
58
|
+
flash[:success] = Spree.t(:successfully_updated, resource: reschedule_policy_name)
|
|
59
|
+
redirect_to admin_reschedule_policies_path
|
|
60
|
+
else
|
|
61
|
+
flash.now[:error] = result.error&.value
|
|
62
|
+
render :edit, status: :unprocessable_entity
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def destroy
|
|
67
|
+
if @reschedule_policy.active?
|
|
68
|
+
# The reschedule flow resolves the store policy from the *active*
|
|
69
|
+
# store policies, so deleting this one would reject every reschedule.
|
|
70
|
+
flash[:error] = Spree.t('admin.reschedule_policies.cannot_delete_active')
|
|
71
|
+
elsif @reschedule_policy.destroy
|
|
72
|
+
flash[:success] = Spree.t(:successfully_removed, resource: reschedule_policy_name)
|
|
73
|
+
else
|
|
74
|
+
flash[:error] = @reschedule_policy.errors.full_messages.to_sentence
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
redirect_to admin_reschedule_policies_path
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Promote this store policy to the active default; the Update service
|
|
81
|
+
# demotes the current default in the same scope first.
|
|
82
|
+
def set_default
|
|
83
|
+
result = SpreeCmCommissioner::ReschedulePolicies::Update.call(
|
|
84
|
+
policy: @reschedule_policy, options: { default: true, status: :active }
|
|
85
|
+
)
|
|
86
|
+
flash[:success] = Spree.t(:successfully_updated, resource: reschedule_policy_name) if result.success?
|
|
87
|
+
flash[:error] = result.error&.value if result.failure?
|
|
88
|
+
redirect_to admin_reschedule_policies_path
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
# nil for the store tab (including unknown/blank `tab` values), otherwise
|
|
94
|
+
# the recognised tab name.
|
|
95
|
+
def current_tab
|
|
96
|
+
params[:tab] if TABS.include?(params[:tab])
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# All statuses are shown (draft/inactive included) so the admin can manage
|
|
100
|
+
# them, so the raw vendor_id/tenant_id filters are used, not the
|
|
101
|
+
# active-only `store_policies` / `vendor_policies` scopes.
|
|
102
|
+
def collection
|
|
103
|
+
base = SpreeCmCommissioner::ReschedulePolicy
|
|
104
|
+
case current_tab
|
|
105
|
+
when 'vendors'
|
|
106
|
+
base.where.not(vendor_id: nil).includes(:vendor)
|
|
107
|
+
when 'tenants'
|
|
108
|
+
base.where.not(vendor_id: nil).where.not(tenant_id: nil).includes(vendor: :tenant)
|
|
109
|
+
else
|
|
110
|
+
base.where(vendor_id: nil)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def load_policy
|
|
115
|
+
authorize! :manage, SpreeCmCommissioner::ReschedulePolicy
|
|
116
|
+
# Edits apply to store policies only; vendor/tenant policies are read-only here.
|
|
117
|
+
@reschedule_policy = SpreeCmCommissioner::ReschedulePolicy.where(vendor_id: nil).find(params[:id])
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Store policies only carry a fee calculator; the typed reschedule rules
|
|
121
|
+
# (cutoff, max-per-booking, vendor approval, ...) belong to vendor policies
|
|
122
|
+
# and are managed elsewhere, so they are not collected here.
|
|
123
|
+
def policy_params
|
|
124
|
+
params.require(:spree_cm_commissioner_reschedule_policy).permit(
|
|
125
|
+
:name,
|
|
126
|
+
:description,
|
|
127
|
+
:status,
|
|
128
|
+
:default,
|
|
129
|
+
:calculator_type,
|
|
130
|
+
calculator_attributes: calculator_attribute_keys
|
|
131
|
+
)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Only the preferences of the selected (whitelisted) calculator subclass
|
|
135
|
+
# are permitted, so preferences never land on the wrong calculator type.
|
|
136
|
+
def calculator_attribute_keys
|
|
137
|
+
type = params.dig(:spree_cm_commissioner_reschedule_policy, :calculator_type)
|
|
138
|
+
return [] unless %w[Spree::Calculator::FlatRate Spree::Calculator::PercentOnLineItem].include?(type)
|
|
139
|
+
|
|
140
|
+
type.constantize.new.defined_preferences.map { |preference| "preferred_#{preference}" }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def reschedule_policy_name
|
|
144
|
+
SpreeCmCommissioner::ReschedulePolicy.model_name.human
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
class RescheduleRequestsController < Spree::Admin::ResourceController
|
|
4
|
+
helper Spree::Admin::RescheduleRequestsHelper
|
|
5
|
+
|
|
6
|
+
def index
|
|
7
|
+
@search = model_class.includes(:order, :user, :vendor, :vendor_policy).ransack(params[:q])
|
|
8
|
+
@reschedule_requests = @search.result
|
|
9
|
+
.order(created_at: :desc)
|
|
10
|
+
.page(params[:page])
|
|
11
|
+
.per(params[:per_page] || Spree::Backend::Config[:admin_orders_per_page])
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def show
|
|
15
|
+
@reschedule_request = load_request
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def state_changes
|
|
19
|
+
@reschedule_request = model_class.find(params[:id])
|
|
20
|
+
@state_changes = @reschedule_request.state_changes.includes(:user).order(created_at: :desc)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def approve
|
|
24
|
+
run_service(
|
|
25
|
+
SpreeCmCommissioner::RescheduleRequests::Vendors::Approve,
|
|
26
|
+
approved_by: try_spree_current_user,
|
|
27
|
+
success_key: 'approved'
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def reject
|
|
32
|
+
run_service(
|
|
33
|
+
SpreeCmCommissioner::RescheduleRequests::Vendors::Reject,
|
|
34
|
+
rejected_by: try_spree_current_user,
|
|
35
|
+
success_key: 'rejected'
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def cancel
|
|
40
|
+
run_service(
|
|
41
|
+
SpreeCmCommissioner::RescheduleRequests::Cancel,
|
|
42
|
+
cancelled_by: try_spree_current_user,
|
|
43
|
+
reason: params[:cancellation_reason].presence,
|
|
44
|
+
success_key: 'cancelled'
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
# Each service takes the acting admin so audit rows record who acted
|
|
51
|
+
# rather than the request's customer.
|
|
52
|
+
def run_service(service, success_key:, **)
|
|
53
|
+
@reschedule_request = model_class.find(params[:id])
|
|
54
|
+
|
|
55
|
+
result = service.call(reschedule_request: @reschedule_request, **)
|
|
56
|
+
if result.success?
|
|
57
|
+
flash[:success] = t("spree.admin.reschedule_requests.#{success_key}")
|
|
58
|
+
else
|
|
59
|
+
flash[:error] = result.error&.value
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
redirect_to admin_reschedule_request_path(@reschedule_request)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def load_request
|
|
66
|
+
model_class.includes(
|
|
67
|
+
:order, :user, :vendor, :tenant, :vendor_policy, :store_policy,
|
|
68
|
+
previous_request_snapshots: %i[variant line_item],
|
|
69
|
+
new_request_snapshots: %i[variant line_item]
|
|
70
|
+
).find(params[:id])
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def model_class
|
|
74
|
+
SpreeCmCommissioner::RescheduleRequest
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def object_name
|
|
78
|
+
'spree_cm_commissioner_reschedule_request'
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -5,7 +5,7 @@ module Spree
|
|
|
5
5
|
|
|
6
6
|
before_action :load_parent
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
helper SpreeCmCommissioner::Admin::InventoryItemsHelper
|
|
9
9
|
|
|
10
10
|
def load_parent
|
|
11
11
|
@product = Spree::Product.find_by(slug: params[:product_id])
|
|
@@ -40,58 +40,6 @@ module Spree
|
|
|
40
40
|
redirect_back fallback_location: admin_product_stock_managements_path(@product)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
# GET /products/:slug/stock_managements/calendar?year=&selected_option_value_ids[]=
|
|
44
|
-
def calendar
|
|
45
|
-
@year = params[:year].present? ? params[:year].to_i : Time.zone.today.year
|
|
46
|
-
|
|
47
|
-
from_date = Date.new(@year, 1, 1).beginning_of_year
|
|
48
|
-
to_date = Date.new(@year, 1, 1).end_of_year
|
|
49
|
-
|
|
50
|
-
@variant_kind_option_types = Spree::Variants::OptionTypesFinder.new(variant_ids: @product.variants.ids)
|
|
51
|
-
.execute.select(&:variant?)
|
|
52
|
-
@selected_option_value_ids = Array(params[:selected_option_value_ids]).map(&:to_i)
|
|
53
|
-
|
|
54
|
-
inventory_items = @product.inventory_items.includes(:variant, :prices).where(
|
|
55
|
-
inventory_date: from_date..to_date
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
if @selected_option_value_ids.present?
|
|
59
|
-
variant_ids = SpreeCmCommissioner::Variants::FindByOptionValueIds.new(
|
|
60
|
-
product: @product, option_value_ids: @selected_option_value_ids
|
|
61
|
-
).execute.ids
|
|
62
|
-
inventory_items = inventory_items.where(variant_id: variant_ids)
|
|
63
|
-
@matched_variants_count = variant_ids.size
|
|
64
|
-
else
|
|
65
|
-
@matched_variants_count = @product.variants.count
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
@inventory_items = inventory_items.to_a
|
|
69
|
-
|
|
70
|
-
@cached_inventory_items = ::SpreeCmCommissioner::RedisStock::CachedInventoryItemsBuilder.new(@inventory_items)
|
|
71
|
-
.call
|
|
72
|
-
.index_by(&:inventory_item_id)
|
|
73
|
-
@events = SpreeCmCommissioner::CalendarEvent.from_inventory_items(@inventory_items)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def inventory_item_message(inventory_item, cached_inventory_item)
|
|
77
|
-
synced = inventory_item.quantity_available == cached_inventory_item.quantity_available
|
|
78
|
-
|
|
79
|
-
if synced
|
|
80
|
-
"Synced: Quantity available matches in both DB and Redis (#{cached_inventory_item.quantity_available})."
|
|
81
|
-
else
|
|
82
|
-
"Out of sync: Redis shows #{cached_inventory_item.quantity_available} available, which doesn't match the database."
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def inventory_item_hold_message(inventory_item, cached_inventory_item)
|
|
87
|
-
synced = inventory_item.quantity_on_hold == cached_inventory_item.quantity_on_hold
|
|
88
|
-
if synced
|
|
89
|
-
"Synced: Quantity on hold matches in both DB and Redis (#{cached_inventory_item.quantity_on_hold})."
|
|
90
|
-
else
|
|
91
|
-
"Out of sync: Redis shows #{cached_inventory_item.quantity_on_hold} on hold, which doesn't match the database."
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
43
|
private
|
|
96
44
|
|
|
97
45
|
def load_inventories
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
class StoreCreditAdminController < Spree::Admin::BaseController
|
|
4
|
+
TABS = %w[overview frozen_store_credits settings].freeze
|
|
5
|
+
|
|
6
|
+
def show
|
|
7
|
+
@current_tab = TABS.include?(params[:tab]) ? params[:tab] : 'overview'
|
|
8
|
+
@tenants = SpreeCmCommissioner::Tenant.order(:name)
|
|
9
|
+
@current_tenant_id = params[:tenant_id].presence&.to_i
|
|
10
|
+
store_credit_overview = SpreeCmCommissioner::StoreCreditOverviewQuery.new(issuer_tenant_id: @current_tenant_id)
|
|
11
|
+
@summary = store_credit_overview.call
|
|
12
|
+
@frozen_store_credits = store_credit_overview.frozen_store_credits
|
|
13
|
+
@config = SpreeCmCommissioner::Configuration.new
|
|
14
|
+
@store = Spree::Store.default
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Covers every prepaid_* Configuration preference editable from the Settings tab -- the
|
|
18
|
+
# currency rate table (keyed by Spree::Store.default#supported_currency_codes -- edit the
|
|
19
|
+
# currency list itself on the store's own admin settings page, not here) and the
|
|
20
|
+
# fraud/velocity limits (Configuration's comment on prepaid_max_topups_per_hour and
|
|
21
|
+
# friends). One form/action since nothing here is ever meaningfully saved independently.
|
|
22
|
+
SETTINGS_KEYS = %i[
|
|
23
|
+
prepaid_currency_rates prepaid_topup_min_amount prepaid_topup_max_amount
|
|
24
|
+
prepaid_max_topups_per_hour prepaid_max_topup_count_daily prepaid_daily_topup_limit
|
|
25
|
+
prepaid_max_balance
|
|
26
|
+
].freeze
|
|
27
|
+
|
|
28
|
+
def update_settings
|
|
29
|
+
config = SpreeCmCommissioner::Configuration.new
|
|
30
|
+
new_values = {
|
|
31
|
+
prepaid_currency_rates: permitted_currency_rates(config),
|
|
32
|
+
prepaid_topup_min_amount: params[:prepaid_topup_min_amount].to_d,
|
|
33
|
+
prepaid_topup_max_amount: params[:prepaid_topup_max_amount].to_d,
|
|
34
|
+
prepaid_max_topups_per_hour: params[:prepaid_max_topups_per_hour].to_i,
|
|
35
|
+
prepaid_max_topup_count_daily: params[:prepaid_max_topup_count_daily].to_i,
|
|
36
|
+
prepaid_daily_topup_limit: params[:prepaid_daily_topup_limit].to_d,
|
|
37
|
+
prepaid_max_balance: params[:prepaid_max_balance].to_d
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
error = invalid_settings_reason(new_values)
|
|
41
|
+
if error
|
|
42
|
+
flash[:error] = error
|
|
43
|
+
return redirect_to admin_store_credit_path(tab: 'settings')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
old_values = SETTINGS_KEYS.index_with { |key| config[key] }
|
|
47
|
+
SETTINGS_KEYS.each { |key| config[key] = new_values[key] }
|
|
48
|
+
|
|
49
|
+
log_settings_change(old_values, new_values)
|
|
50
|
+
|
|
51
|
+
flash[:success] = I18n.t('spree_cm_commissioner.store_credit_admin.settings_updated')
|
|
52
|
+
redirect_to admin_store_credit_path(tab: 'settings')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def run_reconciliation
|
|
56
|
+
report = SpreeCmCommissioner::PrepaidReconciliationService.run_daily
|
|
57
|
+
|
|
58
|
+
if report.drift_count.zero?
|
|
59
|
+
flash[:success] = I18n.t('spree_cm_commissioner.store_credit_admin.reconciliation_success', checked_count: report.checked_count)
|
|
60
|
+
else
|
|
61
|
+
flash[:error] = I18n.t(
|
|
62
|
+
'spree_cm_commissioner.store_credit_admin.reconciliation_drift',
|
|
63
|
+
checked_count: report.checked_count, drift_count: report.drift_count
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
redirect_back fallback_location: admin_store_credit_path
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
# Keyed by the store's current supported-currencies list, so a dropped currency's rate
|
|
73
|
+
# doesn't linger and a new one gets an explicit (fallback 1.0) entry.
|
|
74
|
+
def permitted_currency_rates(config)
|
|
75
|
+
currency_codes = Spree::Store.default.supported_currency_codes
|
|
76
|
+
submitted = params[:prepaid_currency_rates]
|
|
77
|
+
submitted = submitted.is_a?(ActionController::Parameters) ? submitted.permit(*currency_codes) : {}
|
|
78
|
+
|
|
79
|
+
currency_codes.index_with do |currency|
|
|
80
|
+
submitted[currency].presence&.to_f || config.prepaid_currency_rates[currency] || 1.0
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# These preferences are the only fraud/velocity ceiling enforced on store credit money-in
|
|
85
|
+
# (Prepaid::CheckTopUpLimits, Prepaid::TopUp) -- a negative value would be silently treated
|
|
86
|
+
# as "no limit" by comparisons like `amount > limit`, and a non-positive currency rate would
|
|
87
|
+
# corrupt every cross-currency conversion built on it.
|
|
88
|
+
def invalid_settings_reason(values)
|
|
89
|
+
%i[
|
|
90
|
+
prepaid_topup_min_amount prepaid_topup_max_amount prepaid_max_topups_per_hour
|
|
91
|
+
prepaid_max_topup_count_daily prepaid_daily_topup_limit prepaid_max_balance
|
|
92
|
+
].each do |key|
|
|
93
|
+
return "#{key} can't be negative" if values[key].negative?
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
if values[:prepaid_topup_min_amount] > values[:prepaid_topup_max_amount] && values[:prepaid_topup_max_amount].positive?
|
|
97
|
+
return 'prepaid_topup_min_amount cannot exceed prepaid_topup_max_amount'
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
values[:prepaid_currency_rates].each do |currency, rate|
|
|
101
|
+
return "currency rate for #{currency} must be positive" unless rate.positive?
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
nil
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# No dedicated audit-log model for Configuration preferences (they're key/value, not an
|
|
108
|
+
# ActiveRecord row PaperTrail can version) -- structured log line is the same pattern
|
|
109
|
+
# #run_reconciliation already uses ("-- see logs") for admin-triggered store credit actions.
|
|
110
|
+
def log_settings_change(old_values, new_values)
|
|
111
|
+
changed = SETTINGS_KEYS.each_with_object({}) do |key, diff|
|
|
112
|
+
diff[key] = { from: old_values[key], to: new_values[key] } if old_values[key] != new_values[key]
|
|
113
|
+
end
|
|
114
|
+
return if changed.empty?
|
|
115
|
+
|
|
116
|
+
Rails.logger.info(
|
|
117
|
+
"[store_credit_settings_change] admin_id=#{try_spree_current_user&.id} changes=#{changed}"
|
|
118
|
+
)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
module Admin
|
|
3
3
|
class TicketTransferRulesController < Spree::Admin::ResourceController
|
|
4
|
+
before_action :load_offline_product_ids, only: %i[new edit create update]
|
|
5
|
+
|
|
4
6
|
def index
|
|
5
7
|
@search = model_class.ransack(params[:q])
|
|
6
8
|
@ticket_transfer_rules = @search.result
|
|
@@ -11,6 +13,11 @@ module Spree
|
|
|
11
13
|
|
|
12
14
|
private
|
|
13
15
|
|
|
16
|
+
# The scope-target search only returns `name`, so the form labels offline products from this list.
|
|
17
|
+
def load_offline_product_ids
|
|
18
|
+
@offline_product_ids = Spree::Product.where(offline: true).pluck(:id)
|
|
19
|
+
end
|
|
20
|
+
|
|
14
21
|
def model_class
|
|
15
22
|
SpreeCmCommissioner::TicketTransferRule
|
|
16
23
|
end
|