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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ba98474e53d7bb369512ec096ad8459a8baae5d2d77985462e99d48cd4d68820
|
|
4
|
+
data.tar.gz: 9588226b0da09b905292b7518b656ee4261d03ca1e6e55beb526a96ee3365e87
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f09ce118715100ba4d56d0b3c828c946277d632329c1b84e0517f1b513ec4cf64d055bceb6696983324b46f4df428ad0626f959dc961f1e73bdf22c4fac79b51
|
|
7
|
+
data.tar.gz: 72ca04d1fe1ab0f6741269127a90b9f005c7569b55b7e41e619fa3bce15564131414dacf36d619a4d44020a57e8e298581d42f0a06b7933a682343058a266e39
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
//= require map/map-control-button
|
|
2
2
|
//= require map/map-picker
|
|
3
3
|
//= require spree_cm_commissioner/routes
|
|
4
|
-
//= require spree_cm_commissioner/calendar
|
|
5
4
|
//= require spree_cm_commissioner/annual_calendar_form
|
|
6
5
|
//= require spree_cm_commissioner/tenant_payment_icon_fields
|
|
7
6
|
//= require spree_cm_commissioner/copy_to_clipboard
|
|
@@ -22,37 +22,6 @@ $day-background: theme-color("light");
|
|
|
22
22
|
@include hover {
|
|
23
23
|
background-color: darken($day-background, 5%);
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
.c-date-container {
|
|
27
|
-
display: flex;
|
|
28
|
-
flex-flow: column;
|
|
29
|
-
height: 100%;
|
|
30
|
-
|
|
31
|
-
.c-date {
|
|
32
|
-
padding: 6px;
|
|
33
|
-
cursor: pointer;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.c-events-container {
|
|
37
|
-
flex-grow: 1;
|
|
38
|
-
display: flex;
|
|
39
|
-
align-items: flex-end;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
.c-events {
|
|
43
|
-
display: flex;
|
|
44
|
-
align-items: flex-end;
|
|
45
|
-
|
|
46
|
-
.c-event {
|
|
47
|
-
width: 8px;
|
|
48
|
-
height: 8px;
|
|
49
|
-
border-radius: 4px;
|
|
50
|
-
background-color: theme-color("primary");
|
|
51
|
-
margin-right: 4px;
|
|
52
|
-
cursor: pointer;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
25
|
}
|
|
57
26
|
|
|
58
27
|
.wday-0 {
|
|
@@ -103,14 +72,6 @@ $day-background: theme-color("light");
|
|
|
103
72
|
// }
|
|
104
73
|
}
|
|
105
74
|
|
|
106
|
-
.c-month-calendar {
|
|
107
|
-
.simple-calendar {
|
|
108
|
-
table {
|
|
109
|
-
@extend .table-responsive-md;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
75
|
.c-annual-calendar {
|
|
115
76
|
@extend .row;
|
|
116
77
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
# The `cells` the Rates & Availability grid posts for its selection, shaped by the script's raCellData:
|
|
4
|
+
# { type: 'stock' | 'price', variant_id:, rate_plan_id: ('' for the variant's own prices), date: ('' for Base) }.
|
|
5
|
+
# They travel in a JSON body, as a selection across months can be thousands.
|
|
6
|
+
module RatesAvailabilityCells
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def selected_cells
|
|
12
|
+
@selected_cells ||= params.permit(cells: %i[type variant_id rate_plan_id date]).fetch(:cells, []).map { |cell| cell.to_h.symbolize_keys }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
module Admin
|
|
3
3
|
module BaseControllerDecorator
|
|
4
|
+
def self.prepended(base)
|
|
5
|
+
base.before_action :set_prepaid_current_actor
|
|
6
|
+
end
|
|
7
|
+
|
|
4
8
|
# even db in read only mode, authorizor still need to run Warden callbacks which will write to db
|
|
5
9
|
# this include update tracked fields such as sign_in_count, last_sign_in_at, etc.
|
|
6
10
|
def authorize!(*args)
|
|
@@ -40,6 +44,16 @@ module Spree
|
|
|
40
44
|
|
|
41
45
|
redirect_back fallback_location: admin_root_path
|
|
42
46
|
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
# See SpreeCmCommissioner::Current#actor -- lets StoreCreditEventDecorator's after_create
|
|
51
|
+
# mirror attribute an admin-triggered authorize/capture/void/credit event (refunds, voids)
|
|
52
|
+
# to whoever is signed in, without threading current_user through Spree core's own
|
|
53
|
+
# Payment/Refund/StoreCredit call chain.
|
|
54
|
+
def set_prepaid_current_actor
|
|
55
|
+
SpreeCmCommissioner::Current.actor = try_spree_current_user
|
|
56
|
+
end
|
|
43
57
|
end
|
|
44
58
|
end
|
|
45
59
|
end
|
|
@@ -2,7 +2,22 @@ module Spree
|
|
|
2
2
|
module Admin
|
|
3
3
|
class CustomerNotificationsController < Spree::Admin::ResourceController
|
|
4
4
|
def index
|
|
5
|
-
@
|
|
5
|
+
@search = model_class.ransack(params[:q])
|
|
6
|
+
@search.sorts = 'created_at desc' if @search.sorts.empty?
|
|
7
|
+
@notifications = @search.result.page(params[:page]).per(params[:per_page] || 25)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# POST /admin/customer_notifications/:id/clone
|
|
11
|
+
def clone
|
|
12
|
+
result = SpreeCmCommissioner::CustomerNotifications::Clone.call(customer_notification: @object)
|
|
13
|
+
|
|
14
|
+
if result.success?
|
|
15
|
+
flash[:success] = Spree.t(:customer_notification_cloned)
|
|
16
|
+
redirect_to edit_admin_customer_notification_url(result.value)
|
|
17
|
+
else
|
|
18
|
+
flash[:error] = Spree.t(:customer_notification_not_cloned, error: result.error.to_s)
|
|
19
|
+
redirect_to admin_customer_notifications_url
|
|
20
|
+
end
|
|
6
21
|
end
|
|
7
22
|
|
|
8
23
|
def model_class
|
|
@@ -43,7 +43,8 @@ module Spree
|
|
|
43
43
|
|
|
44
44
|
def edit
|
|
45
45
|
@kyc_fields = @object.line_item.kyc_fields
|
|
46
|
-
@
|
|
46
|
+
@check_ins = @object.check_ins.includes(:check_in_session, :check_in_by)
|
|
47
|
+
@eligible_check_in_sessions = @object.eligible_check_in_sessions.order(:position)
|
|
47
48
|
end
|
|
48
49
|
|
|
49
50
|
def check_in
|
|
@@ -35,6 +35,17 @@ module Spree
|
|
|
35
35
|
admin_integrations_url(options)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
# Builds the chosen subclass rather than the base Integration: `create` only assigns `type`
|
|
39
|
+
# afterwards, which changes the column but not the object's class, so the subclass's
|
|
40
|
+
# callbacks and attribute defaults would never run. `create` posts the type in the form;
|
|
41
|
+
# `new` gets it as ?type= when one is picked. With no type yet, or one that isn't an
|
|
42
|
+
# integration, it stays the base class (never constantized).
|
|
43
|
+
# override
|
|
44
|
+
def build_resource
|
|
45
|
+
type = params.dig(:spree_cm_commissioner_integration, :type).presence || params[:type]
|
|
46
|
+
SpreeCmCommissioner::Integration.types.include?(type) ? type.constantize.new : model_class.new
|
|
47
|
+
end
|
|
48
|
+
|
|
38
49
|
private
|
|
39
50
|
|
|
40
51
|
def permitted_resource_params
|
|
@@ -47,6 +58,7 @@ module Spree
|
|
|
47
58
|
:full_sync_interval_hours,
|
|
48
59
|
:tenant_id,
|
|
49
60
|
:vendor_id,
|
|
61
|
+
:oauth_application_id,
|
|
50
62
|
public_metadata: {},
|
|
51
63
|
private_metadata: {}
|
|
52
64
|
)
|
|
@@ -62,6 +74,7 @@ module Spree
|
|
|
62
74
|
@conflict_strategy_options ||= enum_to_options(SpreeCmCommissioner::Integration.conflict_strategies)
|
|
63
75
|
@tenants ||= SpreeCmCommissioner::Tenant.select(:id, :name).order(:name)
|
|
64
76
|
@vendors ||= Spree::Vendor.select(:id, :name).order(:name)
|
|
77
|
+
@oauth_applications ||= Spree::OauthApplication.select(:id, :name).order(:name)
|
|
65
78
|
end
|
|
66
79
|
|
|
67
80
|
def enum_to_options(enum_hash)
|
|
@@ -69,14 +82,10 @@ module Spree
|
|
|
69
82
|
end
|
|
70
83
|
|
|
71
84
|
def integration_type_options
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
return [[Spree.t(:type), 'SpreeCmCommissioner::Integration']] if files.blank?
|
|
85
|
+
types = SpreeCmCommissioner::Integration.types
|
|
86
|
+
return [[Spree.t(:type), 'SpreeCmCommissioner::Integration']] if types.blank?
|
|
75
87
|
|
|
76
|
-
|
|
77
|
-
class_name = "SpreeCmCommissioner::Integrations::#{File.basename(path, '.rb').camelize}"
|
|
78
|
-
[class_name, class_name]
|
|
79
|
-
end.sort_by(&:first)
|
|
88
|
+
types.map { |class_name| [class_name, class_name] }
|
|
80
89
|
end
|
|
81
90
|
end
|
|
82
91
|
end
|
|
@@ -1,73 +1,25 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
module Admin
|
|
3
3
|
class InventoryItemsController < StockManagementsController
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# GET /products/:slug/inventory_items/prices?inventory_item_ids=1,2,3
|
|
7
|
-
def prices
|
|
8
|
-
inventory_item_ids = params[:inventory_item_ids]
|
|
9
|
-
@inventory_items = @product.inventory_items.where(id: inventory_item_ids)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
# GET /products/:slug/inventory_items/stocks?inventory_item_ids=1,2,3
|
|
13
|
-
def stocks
|
|
14
|
-
inventory_item_ids = params[:inventory_item_ids]
|
|
15
|
-
@inventory_items = @product.inventory_items.where(id: inventory_item_ids)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# PATCH /products/:slug/inventory_items/bulk_update_prices
|
|
19
|
-
def bulk_update_prices # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
|
20
|
-
inventory_item_ids = params[:inventory_item_ids]
|
|
21
|
-
inventory_items = @product.inventory_items.where(id: inventory_item_ids)
|
|
22
|
-
|
|
23
|
-
inventory_items.each do |inventory_item|
|
|
24
|
-
params[:prices]&.values&.each do |price_params|
|
|
25
|
-
next if price_params[:price].empty?
|
|
4
|
+
include RatesAvailabilityCells
|
|
26
5
|
|
|
27
|
-
|
|
28
|
-
price.price = price_params[:price]
|
|
29
|
-
price.compare_at_price = price_params[:compare_at_price].empty? ? nil : price_params[:compare_at_price]
|
|
30
|
-
price.variant_id = inventory_item.variant_id
|
|
31
|
-
price.save! if (price.new_record? && price.price) || (!price.new_record? && price.changed?)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
flash[:success] = "Successfully updated prices for #{inventory_items.count} items"
|
|
36
|
-
redirect_back fallback_location: admin_product_stock_managements_path(@product)
|
|
37
|
-
end
|
|
6
|
+
DETAILS_PER_PAGE = 50
|
|
38
7
|
|
|
39
|
-
|
|
40
|
-
def bulk_update_stocks
|
|
41
|
-
inventory_item_ids = params[:inventory_item_ids]
|
|
42
|
-
inventory_items = @product.inventory_items.where(id: inventory_item_ids)
|
|
43
|
-
target_quantity = params[:quantity].to_i
|
|
44
|
-
|
|
45
|
-
if target_quantity.negative?
|
|
46
|
-
flash[:error] = "Target quantity (#{target_quantity}) must not be negative"
|
|
47
|
-
return redirect_back(fallback_location: admin_product_stock_managements_path(@product))
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
inventory_items.each do |inventory_item|
|
|
51
|
-
# Calculate the difference between target and current quantity
|
|
52
|
-
quantity_change = target_quantity - inventory_item.quantity_available
|
|
53
|
-
|
|
54
|
-
# Use adjust_quantity! to update max_capacity, quantity_available, and sync to Redis
|
|
55
|
-
inventory_item.adjust_quantity!(quantity_change)
|
|
56
|
-
end
|
|
8
|
+
before_action :load_parent
|
|
57
9
|
|
|
58
|
-
|
|
59
|
-
redirect_back fallback_location: admin_product_stock_managements_path(@product)
|
|
60
|
-
end
|
|
10
|
+
helper SpreeCmCommissioner::Admin::RatesAvailabilitiesHelper
|
|
61
11
|
|
|
62
|
-
#
|
|
12
|
+
# POST /products/:slug/inventory_items/details, JSON: { cells: [...], page: }
|
|
63
13
|
#
|
|
64
|
-
#
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
14
|
+
# The Rates & Availability grid's stock details modal: the counts of each selected variant and date, as stock
|
|
15
|
+
# managements shows them. POST, as cells travel in the body.
|
|
16
|
+
def details
|
|
17
|
+
inventory_items = selected_inventory_items.page(params[:page]).per(DETAILS_PER_PAGE)
|
|
18
|
+
cached = SpreeCmCommissioner::RedisStock::CachedInventoryItemsBuilder.new(inventory_items.to_a).call.index_by(&:inventory_item_id)
|
|
19
|
+
|
|
20
|
+
render partial: 'details', formats: [:html], locals: {
|
|
21
|
+
inventory_items: inventory_items, cached_inventory_items: cached, cells: selected_cells
|
|
22
|
+
}
|
|
71
23
|
end
|
|
72
24
|
|
|
73
25
|
# PATCH /products/:slug/inventory_items/bulk_reset?inventory_item_ids=1,2,3
|
|
@@ -89,6 +41,25 @@ module Spree
|
|
|
89
41
|
|
|
90
42
|
redirect_back fallback_location: admin_product_stock_managements_path(@product)
|
|
91
43
|
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
# Price cells count too: each names a variant and a date. A dated product's Base has no inventory item.
|
|
48
|
+
def selected_inventory_items
|
|
49
|
+
pairs = selected_cells.map { |cell| [cell[:variant_id].to_i, cell[:date].presence] }.uniq
|
|
50
|
+
return SpreeCmCommissioner::InventoryItem.none if pairs.empty?
|
|
51
|
+
|
|
52
|
+
# Joined to the exact pairs: variant and date lists alone would also match every other variant on those dates.
|
|
53
|
+
values = pairs.map { |variant_id, date| ActiveRecord::Base.sanitize_sql_array(['(?, ?::date)', variant_id, date]) }.join(', ')
|
|
54
|
+
selected = "JOIN (VALUES #{values}) AS selected(variant_id, inventory_date) ON selected.variant_id = cm_inventory_items.variant_id " \
|
|
55
|
+
'AND selected.inventory_date IS NOT DISTINCT FROM cm_inventory_items.inventory_date'
|
|
56
|
+
SpreeCmCommissioner::InventoryItem
|
|
57
|
+
.where(variant_id: @product.variants_including_master.select(:id))
|
|
58
|
+
.joins(selected)
|
|
59
|
+
.joins(:variant)
|
|
60
|
+
.order('spree_variants.position, cm_inventory_items.variant_id, cm_inventory_items.inventory_date')
|
|
61
|
+
.preload(variant: [:product, { option_values: :option_type }])
|
|
62
|
+
end
|
|
92
63
|
end
|
|
93
64
|
end
|
|
94
65
|
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
# Two read-only views over the prepaid ledger:
|
|
4
|
+
# - #index: platform-wide filterable browse (GET /admin/store_credit/transactions).
|
|
5
|
+
# - #show: a single ledger row's full detail (GET /admin/store_credit/transactions/:id),
|
|
6
|
+
# reached from both #index's row links and the per-user store_credits Transactions tab.
|
|
7
|
+
# Not nested under a user/store_credit -- PrepaidTransaction has a global id, and one
|
|
8
|
+
# detail page reached from two different listings is simpler than two near-identical ones.
|
|
9
|
+
# Currency, balance, admin, and reason/freeze metadata live here rather than cluttering
|
|
10
|
+
# either listing table.
|
|
11
|
+
class PrepaidTransactionsController < Spree::Admin::BaseController
|
|
12
|
+
TRANSACTIONS_PER_PAGE = 25
|
|
13
|
+
|
|
14
|
+
before_action :load_transaction, only: :show
|
|
15
|
+
|
|
16
|
+
# GET /admin/store_credit/transactions -- the admin/store_credit dashboard's own
|
|
17
|
+
# platform-wide ledger browse (see Spree::Admin::StoreCreditAdminController's other tabs and
|
|
18
|
+
# store_credit_admin/_tabs.html.erb), but its own route/controller rather than a #show?
|
|
19
|
+
# tab=transactions query param, so filters/pagination live in a real URL.
|
|
20
|
+
def index
|
|
21
|
+
@current_tab = 'transactions'
|
|
22
|
+
@tenants = SpreeCmCommissioner::Tenant.order(:name)
|
|
23
|
+
@current_tenant_id = params[:tenant_id].presence&.to_i
|
|
24
|
+
@store = Spree::Store.default
|
|
25
|
+
build_transactions_search
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def show; end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def load_transaction
|
|
33
|
+
@transaction = SpreeCmCommissioner::PrepaidTransaction.find(params[:id])
|
|
34
|
+
@user = @transaction.user
|
|
35
|
+
@store_credit = @transaction.store_credit
|
|
36
|
+
@reversed = SpreeCmCommissioner::PrepaidTransaction
|
|
37
|
+
.exists?(user: @user, transaction_type: 'reverse_top_up', idempotency_key: "admin_reverse:#{@transaction.id}")
|
|
38
|
+
@return_to = safe_return_to
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# So the back link on the detail page returns to the exact filtered/paginated Transactions
|
|
42
|
+
# tab state the admin came from, not a bare reset to page 1 -- only same-admin-namespace
|
|
43
|
+
# paths are honored, since this is attacker-controllable input (an admin could be tricked
|
|
44
|
+
# into following a crafted link) and open-redirecting out of /admin would be a phishing vector.
|
|
45
|
+
def safe_return_to
|
|
46
|
+
candidate = params[:return_to]
|
|
47
|
+
candidate if candidate.present? && candidate.start_with?('/admin/')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Individual ledger row search/browse -- scoped to whichever tenant the dashboard's own
|
|
51
|
+
# tenant selector has picked (tenant_id: nil => platform-issued, same convention as
|
|
52
|
+
# StoreCreditOverviewQuery), further filtered via Ransack (q[user_email_cont],
|
|
53
|
+
# q[currency_eq], q[transaction_type_eq], q[created_at_gteq]/[created_at_lteq], ...).
|
|
54
|
+
def build_transactions_search
|
|
55
|
+
params[:q] = {} if params[:q].blank?
|
|
56
|
+
@transactions_search = SpreeCmCommissioner::PrepaidTransaction.where(tenant_id: @current_tenant_id).ransack(params[:q])
|
|
57
|
+
@transactions = @transactions_search.result
|
|
58
|
+
.includes(:user, :order, :tenant, :admin, :store_credit)
|
|
59
|
+
.order(created_at: :desc)
|
|
60
|
+
.page(params[:page])
|
|
61
|
+
.per(TRANSACTIONS_PER_PAGE)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def model_class
|
|
65
|
+
SpreeCmCommissioner::PrepaidTransaction
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -14,6 +14,7 @@ module Spree
|
|
|
14
14
|
# partial reads these ivars — without this a rejected save is a 500 instead of a form.
|
|
15
15
|
before_action :load_stock_rows, only: %i[edit update]
|
|
16
16
|
before_action :load_assignable_roles, only: %i[new create edit update]
|
|
17
|
+
before_action :load_offline_product_ids, only: %i[new create edit update]
|
|
17
18
|
|
|
18
19
|
# GET /admin/private_sales
|
|
19
20
|
def index
|
|
@@ -45,6 +46,11 @@ module Spree
|
|
|
45
46
|
@assignable_roles = Spree::Role.non_vendor.order(:name)
|
|
46
47
|
end
|
|
47
48
|
|
|
49
|
+
# The product search only returns `name`, so the form labels offline products from this list.
|
|
50
|
+
def load_offline_product_ids
|
|
51
|
+
@offline_product_ids = Spree::Product.where(offline: true).pluck(:id)
|
|
52
|
+
end
|
|
53
|
+
|
|
48
54
|
def location_after_save
|
|
49
55
|
edit_admin_private_sale_path(@private_sale)
|
|
50
56
|
end
|
|
@@ -42,7 +42,8 @@ module Spree
|
|
|
42
42
|
|
|
43
43
|
def commission_for(product)
|
|
44
44
|
commission_rate = product.commission_rate || product.vendor&.commission_rate || 0
|
|
45
|
-
product
|
|
45
|
+
# A product can have no price in the store currency yet (e.g. a freshly created ticket).
|
|
46
|
+
(product.price || 0) * commission_rate / 100
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
# override
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
class ProductOptionTypesController < Spree::Admin::ResourceController
|
|
4
|
+
belongs_to 'spree/product', find_by: :slug
|
|
5
|
+
|
|
6
|
+
before_action :load_available_option_types, only: :index
|
|
7
|
+
before_action :ensure_not_used_by_variants, only: :destroy
|
|
8
|
+
|
|
9
|
+
# override: the base version finds ids across every product; scope them to this one.
|
|
10
|
+
def update_positions
|
|
11
|
+
ApplicationRecord.transaction do
|
|
12
|
+
params[:positions].each do |id, index|
|
|
13
|
+
parent.product_option_types.find(id).set_list_position(index)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
head :ok
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# One Save for the whole table instead of a submit per row. Only this product's rows are looked up,
|
|
21
|
+
# so ids belonging to another product are ignored.
|
|
22
|
+
def update_all
|
|
23
|
+
rows = parent.product_option_types.where(id: bulk_params.keys).index_by { |row| row.id.to_s }
|
|
24
|
+
|
|
25
|
+
ApplicationRecord.transaction do
|
|
26
|
+
bulk_params.each { |id, attributes| rows[id]&.update!(attributes) }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
flash[:success] = I18n.t('spree.admin.product_option_types.saved')
|
|
30
|
+
redirect_to collection_url
|
|
31
|
+
rescue ActiveRecord::RecordInvalid => e
|
|
32
|
+
flash[:error] = e.record.errors.full_messages.to_sentence
|
|
33
|
+
redirect_to collection_url
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
# override
|
|
39
|
+
def collection_actions
|
|
40
|
+
super + [:update_all]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# { "<product_option_type id>" => { hidden:, presentation: } }
|
|
44
|
+
def bulk_params
|
|
45
|
+
@bulk_params ||= params.fetch(:product_option_types, {}).to_unsafe_h.to_h do |id, attributes|
|
|
46
|
+
[id.to_s, ActionController::Parameters.new(attributes).permit(:hidden, :presentation)]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# override
|
|
51
|
+
def collection
|
|
52
|
+
parent.product_option_types.includes(:option_type).order(:position)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# override
|
|
56
|
+
def model_class
|
|
57
|
+
Spree::ProductOptionType
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# override: only create goes through the resource params; display settings are saved by #update_all.
|
|
61
|
+
def permitted_resource_params
|
|
62
|
+
params.require(:product_option_type).permit(:option_type_id)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def load_available_option_types
|
|
66
|
+
@available_option_types = Spree::OptionType.where(kind: %i[variant product])
|
|
67
|
+
.where.not(id: parent.option_type_ids)
|
|
68
|
+
.order(:presentation)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Removing an option type that variants still carry values for would leave those values orphaned
|
|
72
|
+
# from the product's option types, the same rule the dashboard's variant options page enforces.
|
|
73
|
+
def ensure_not_used_by_variants
|
|
74
|
+
used = parent.variants_including_master.joins(:option_values)
|
|
75
|
+
.exists?(spree_option_values: { option_type_id: @object.option_type_id })
|
|
76
|
+
return unless used
|
|
77
|
+
|
|
78
|
+
flash[:error] = I18n.t('spree.admin.product_option_types.still_used_by_variants', name: @object.display_presentation)
|
|
79
|
+
|
|
80
|
+
# link_to_delete removes over AJAX and only drops the row when the JS response carries a success flash.
|
|
81
|
+
respond_to do |format|
|
|
82
|
+
format.html { redirect_to collection_url }
|
|
83
|
+
format.js { render_js_for_destroy }
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
# A product's rate plans: the record (name, kind, adjustment, terms), not its prices, which the Rates &
|
|
4
|
+
# Availability grid edits. Forms open in a modal on that grid, so a save answers with no content and the
|
|
5
|
+
# grid reloads its rows, while an invalid form comes back as HTML to show in place.
|
|
6
|
+
class RatePlansController < Spree::Admin::BaseController
|
|
7
|
+
before_action :load_product
|
|
8
|
+
before_action :load_rate_plan, only: %i[edit update destroy]
|
|
9
|
+
|
|
10
|
+
helper SpreeCmCommissioner::Admin::RatesAvailabilitiesHelper
|
|
11
|
+
helper_method :rate_plan_option_types, :currencies
|
|
12
|
+
|
|
13
|
+
def new
|
|
14
|
+
variant = variants.find(params[:variant_id])
|
|
15
|
+
@rate_plan = variant.rate_plans.new(kind: :derived, adjustment_type: :percent)
|
|
16
|
+
render_form
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def edit
|
|
20
|
+
render_form
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Also creates it on each variant in `also_variant_ids`, with the same terms.
|
|
24
|
+
def create
|
|
25
|
+
variant = variants.find(params[:variant_id])
|
|
26
|
+
also_variants = variants.where(id: params[:also_variant_ids]).where.not(id: variant.id)
|
|
27
|
+
@rate_plan = variant.rate_plans.new
|
|
28
|
+
rate_plans = [@rate_plan] + also_variants.map { |also_variant| also_variant.rate_plans.new }
|
|
29
|
+
|
|
30
|
+
save(rate_plans, rate_plan_params.merge(kind: params.dig(:rate_plan, :kind)))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Kind stays as created: an independent rate plan has its own price rows, a derived one only date overrides.
|
|
34
|
+
def update
|
|
35
|
+
save([@rate_plan], rate_plan_params.merge(status: params.dig(:rate_plan, :status)).compact)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Only a rate plan never sold: line items keep theirs (`restrict_with_error`), so a sold one is archived.
|
|
39
|
+
def destroy
|
|
40
|
+
if @rate_plan.destroy
|
|
41
|
+
head :no_content
|
|
42
|
+
else
|
|
43
|
+
render json: { error: @rate_plan.errors.full_messages.to_sentence }, status: :unprocessable_entity
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# A dialog listing one variant's rate plans, archived too, as positions run across all of them.
|
|
48
|
+
def edit_order
|
|
49
|
+
@variant = variants.find(params[:variant_id])
|
|
50
|
+
render_order_form
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Saves the whole order at once, so a misclick in the dialog costs nothing until Save. `rate_plan_ids` must be
|
|
54
|
+
# exactly the variant's rate plans, or a plan added or deleted meanwhile would end up out of place.
|
|
55
|
+
def update_order
|
|
56
|
+
@variant = variants.find(params[:variant_id])
|
|
57
|
+
ids = Array(params[:rate_plan_ids]).map(&:to_i)
|
|
58
|
+
rate_plans = @variant.rate_plans.index_by(&:id)
|
|
59
|
+
|
|
60
|
+
return render_order_form(error: t('rates_availabilities.reorder_form.changed'), status: :conflict) unless ids.sort == rate_plans.keys.sort
|
|
61
|
+
|
|
62
|
+
# update_columns: acts_as_list would shift the others on every single save.
|
|
63
|
+
SpreeCmCommissioner::RatePlan.transaction do
|
|
64
|
+
ids.each.with_index(1) do |id, position|
|
|
65
|
+
rate_plans[id].update_columns(position: position, updated_at: Time.current) # rubocop:disable Rails/SkipsModelValidations
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
head :no_content
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def rate_plan_option_types
|
|
75
|
+
@rate_plan_option_types ||= Spree::OptionType.where(kind: :rate_plan).includes(:option_values).order(:position)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def currencies
|
|
79
|
+
supported_currencies_for_all_stores.map(&:iso_code)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def save(rate_plans, attributes)
|
|
83
|
+
result = SpreeCmCommissioner::RatePlans::Save.call(
|
|
84
|
+
rate_plans: rate_plans,
|
|
85
|
+
attributes: attributes,
|
|
86
|
+
option_value_ids: Array(params.dig(:rate_plan, :option_value_ids)),
|
|
87
|
+
starting_prices: params.fetch(:starting_prices, {}).permit(*currencies).to_h
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
return head :no_content if result.success?
|
|
91
|
+
|
|
92
|
+
render_form(error: result.error.to_s, status: :unprocessable_entity)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def render_form(error: nil, status: :ok)
|
|
96
|
+
render partial: 'form', locals: { rate_plan: @rate_plan, error: error }, status: status
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def render_order_form(error: nil, status: :ok)
|
|
100
|
+
rate_plans = @variant.rate_plans.includes(option_values: :option_type)
|
|
101
|
+
render partial: 'order_form', locals: { variant: @variant, rate_plans: rate_plans, error: error }, status: status
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def rate_plan_params
|
|
105
|
+
params.require(:rate_plan).permit(:name, :adjustment_type, :adjustment_value, :currency)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def load_product
|
|
109
|
+
@product = Spree::Product.find_by!(slug: params[:product_id])
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def load_rate_plan
|
|
113
|
+
@rate_plan = SpreeCmCommissioner::RatePlan.where(variant_id: variants.select(:id)).find(params[:id])
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def variants
|
|
117
|
+
Spree::Variant.where(product_id: @product.id)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def model_class
|
|
121
|
+
SpreeCmCommissioner::RatePlan
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|