spree_core 5.6.1 → 6.0.0.beta2
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/LICENSE +30 -0
- data/README.md +2 -3
- data/app/finders/spree/line_items/find_by_variant.rb +5 -3
- data/app/finders/spree/sellers/panel_url.rb +47 -0
- data/app/finders/spree/stores/dashboard_url.rb +76 -0
- data/app/helpers/spree/images_helper.rb +1 -1
- data/app/jobs/spree/carts/reap_expired_job.rb +43 -0
- data/app/jobs/spree/collections/regenerate_time_based_job.rb +18 -0
- data/app/jobs/spree/data_requests/process_job.rb +42 -0
- data/app/jobs/spree/events/subscriber_job.rb +1 -1
- data/app/jobs/spree/images/migrate_product_media_job.rb +80 -0
- data/app/jobs/spree/images/save_from_url_job.rb +70 -13
- data/app/jobs/spree/imports/create_categories_job.rb +23 -14
- data/app/jobs/spree/imports/create_rows_job.rb +3 -62
- data/app/jobs/spree/imports/process_group_job.rb +1 -1
- data/app/jobs/spree/imports/process_job.rb +164 -0
- data/app/jobs/spree/imports/process_rows_job.rb +4 -71
- data/app/jobs/spree/orders/finalize_stale_drafts_job.rb +29 -0
- data/app/jobs/spree/payments/handle_webhook_job.rb +1 -1
- data/app/jobs/spree/price_lists/sync_currencies_job.rb +42 -0
- data/app/jobs/spree/product_types/apply_to_products_job.rb +74 -0
- data/app/jobs/spree/products/auto_match_collections_job.rb +14 -0
- data/app/jobs/spree/products/auto_match_taxons_job.rb +6 -7
- data/app/jobs/spree/products/refresh_metrics_job.rb +1 -1
- data/app/jobs/spree/products/touch_categories_job.rb +15 -0
- data/app/jobs/spree/products/touch_taxons_job.rb +7 -6
- data/app/jobs/spree/sample_data/load_job.rb +13 -0
- data/app/jobs/spree/seller_payouts/sweep_due_job.rb +57 -0
- data/app/jobs/spree/seller_payouts/sweep_seller_job.rb +70 -0
- data/app/jobs/spree/seller_transfers/execute_pending_due_job.rb +56 -0
- data/app/jobs/spree/seller_transfers/execute_pending_job.rb +52 -0
- data/app/jobs/spree/shipping_labels/store_file_job.rb +17 -0
- data/app/jobs/spree/stock_locations/stock_items/create_job.rb +7 -5
- data/app/jobs/spree/stock_locations/stock_levels/create_job.rb +13 -0
- data/app/jobs/spree/stock_reservations/expire_job.rb +1 -1
- data/app/jobs/spree/tax_identifiers/validate_job.rb +14 -0
- data/app/jobs/spree/variants/remove_line_item_job.rb +29 -1
- data/app/mailers/spree/admin_user_mailer.rb +6 -35
- data/app/mailers/spree/base_mailer.rb +1 -20
- data/app/mailers/spree/invitation_mailer.rb +1 -1
- data/app/mailers/spree/seller_user_mailer.rb +47 -0
- data/app/models/concerns/spree/account_lockout.rb +38 -0
- data/app/models/concerns/spree/acted_by.rb +210 -0
- data/app/models/concerns/spree/actor.rb +51 -0
- data/app/models/concerns/spree/admin_user_methods.rb +53 -42
- data/app/models/concerns/spree/calculated_adjustments.rb +8 -14
- data/app/models/concerns/spree/calculator/currency_amounts.rb +43 -0
- data/app/models/concerns/spree/capture_method.rb +33 -0
- data/app/models/concerns/spree/custom_field_filterable.rb +163 -0
- data/app/models/concerns/spree/customer_methods.rb +421 -0
- data/app/models/concerns/spree/deprecated_customer_alias.rb +22 -0
- data/app/models/concerns/spree/derived_number.rb +66 -0
- data/app/models/concerns/spree/has_address_book.rb +89 -0
- data/app/models/concerns/spree/has_custom_fields.rb +360 -0
- data/app/models/concerns/spree/has_external_references.rb +95 -0
- data/app/models/concerns/spree/has_iso_geography.rb +71 -0
- data/app/models/concerns/spree/has_library_media.rb +94 -0
- data/app/models/concerns/spree/has_list_position.rb +15 -0
- data/app/models/concerns/spree/has_number.rb +139 -0
- data/app/models/concerns/spree/has_status.rb +76 -0
- data/app/models/concerns/spree/has_tracking_carrier.rb +18 -0
- data/app/models/concerns/spree/instruments_gateway_calls.rb +20 -0
- data/app/models/concerns/spree/integration_backed_provider.rb +89 -0
- data/app/models/concerns/spree/integrations_concern.rb +15 -2
- data/app/models/concerns/spree/label_translatable.rb +37 -0
- data/app/models/concerns/spree/marketplace/order_group.rb +35 -0
- data/app/models/concerns/spree/metadata.rb +18 -22
- data/app/models/concerns/spree/named_type.rb +11 -1
- data/app/models/concerns/spree/parameterizable_name.rb +5 -5
- data/app/models/concerns/spree/password_policy.rb +37 -0
- data/app/models/concerns/spree/payment_session_transitions.rb +93 -0
- data/app/models/concerns/spree/payment_source_concern.rb +1 -1
- data/app/models/concerns/spree/personal_data_matching.rb +120 -0
- data/app/models/concerns/spree/preference_schema.rb +120 -19
- data/app/models/concerns/spree/prefixed_id.rb +25 -3
- data/app/models/concerns/spree/presentation_translatable.rb +4 -37
- data/app/models/concerns/spree/product_scopes.rb +51 -191
- data/app/models/concerns/spree/provider_failure_policy.rb +44 -0
- data/app/models/concerns/spree/publishable.rb +7 -7
- data/app/models/concerns/spree/purchase/addresses.rb +258 -0
- data/app/models/concerns/spree/purchase/channel.rb +19 -0
- data/app/models/concerns/spree/purchase/checkout_steps.rb +68 -0
- data/app/models/concerns/spree/purchase/company.rb +96 -0
- data/app/models/concerns/spree/purchase/currency.rb +29 -0
- data/app/models/concerns/spree/purchase/digital_items.rb +60 -0
- data/app/models/concerns/spree/purchase/freight.rb +52 -0
- data/app/models/concerns/spree/purchase/gift_cards.rb +70 -0
- data/app/models/concerns/spree/purchase/lifecycle.rb +53 -0
- data/app/models/concerns/spree/purchase/line_item_currencies.rb +38 -0
- data/app/models/concerns/spree/purchase/line_item_lookup.rb +25 -0
- data/app/models/concerns/spree/purchase/locale.rb +30 -0
- data/app/models/concerns/spree/purchase/market.rb +29 -0
- data/app/models/concerns/spree/purchase/payment_processing.rb +93 -0
- data/app/models/concerns/spree/purchase/purchase_order.rb +94 -0
- data/app/models/concerns/spree/purchase/quantity_rules.rb +136 -0
- data/app/models/concerns/spree/purchase/store_credits.rb +100 -0
- data/app/models/concerns/spree/purchase/taxation.rb +146 -0
- data/app/models/concerns/spree/purchase/totals.rb +116 -0
- data/app/models/concerns/spree/purchase/validations.rb +45 -0
- data/app/models/concerns/spree/receivable.rb +103 -0
- data/app/models/concerns/spree/receivable_item.rb +78 -0
- data/app/models/concerns/spree/refund_methods.rb +19 -0
- data/app/models/concerns/spree/sanitizable_rich_text.rb +109 -0
- data/app/models/concerns/spree/search_indexable.rb +5 -2
- data/app/models/concerns/spree/single_store_resource.rb +3 -1
- data/app/models/concerns/spree/store_data_sources.rb +75 -0
- data/app/models/concerns/spree/store_preferences.rb +49 -0
- data/app/models/concerns/spree/stores/markets.rb +75 -28
- data/app/models/concerns/spree/stores/setup.rb +10 -0
- data/app/models/concerns/spree/translatable_resource.rb +25 -6
- data/app/models/concerns/spree/typed_adjustment_line.rb +55 -0
- data/app/models/concerns/spree/user_address.rb +13 -3
- data/app/models/concerns/spree/user_management.rb +18 -6
- data/app/models/concerns/spree/user_methods.rb +5 -330
- data/app/models/concerns/spree/user_payment_source.rb +1 -1
- data/app/models/concerns/spree/user_roles.rb +18 -11
- data/app/models/concerns/spree/validates_store_uniqueness.rb +53 -0
- data/app/models/concerns/spree/vat_price_calculation.rb +58 -6
- data/app/models/concerns/spree/webhook_payload_redaction.rb +1 -1
- data/app/models/spree/ability.rb +147 -43
- data/app/models/spree/address.rb +387 -118
- data/app/models/spree/adjusters/base.rb +26 -0
- data/app/models/spree/adjusters/largest_remainder.rb +24 -0
- data/app/models/spree/adjusters/promotion.rb +253 -0
- data/app/models/spree/admin_user.rb +26 -0
- data/app/models/spree/allowed_origin.rb +1 -1
- data/app/models/spree/api_key.rb +34 -31
- data/app/models/spree/asset.rb +14 -211
- data/app/models/spree/authentication/strategies/base_strategy.rb +54 -3
- data/app/models/spree/authentication/strategies/email_password_strategy.rb +11 -3
- data/app/models/spree/authentication/strategies/oidc_strategy.rb +330 -0
- data/app/models/spree/authentication/strategy_registry.rb +83 -0
- data/app/models/spree/base.rb +83 -12
- data/app/models/spree/base_analytics_event_handler.rb +1 -1
- data/app/models/spree/calculator/shipping/digital_delivery.rb +5 -2
- data/app/models/spree/calculator/shipping/flat_rate.rb +10 -5
- data/app/models/spree/calculator/shipping/flexi_rate.rb +6 -0
- data/app/models/spree/calculator/shipping/per_item.rb +8 -3
- data/app/models/spree/calculator/shipping/price_sack.rb +6 -0
- data/app/models/spree/calculator/tiered_flat_rate.rb +5 -1
- data/app/models/spree/calculator.rb +10 -0
- data/app/models/spree/cart.rb +285 -0
- data/app/models/spree/carts/item_warning.rb +28 -0
- data/app/models/spree/carts/resolved_item.rb +37 -0
- data/app/models/spree/catalog.rb +503 -0
- data/app/models/spree/catalog_assignment.rb +41 -0
- data/app/models/spree/catalog_order_minimum.rb +26 -0
- data/app/models/spree/catalog_price.rb +100 -0
- data/app/models/spree/catalog_price_tier.rb +36 -0
- data/app/models/spree/catalog_product.rb +23 -0
- data/app/models/spree/catalog_quantity_rule.rb +46 -0
- data/app/models/spree/catalogs/product_term.rb +43 -0
- data/app/models/spree/category.rb +430 -12
- data/app/models/spree/channel/gating.rb +1 -2
- data/app/models/spree/channel.rb +38 -4
- data/app/models/spree/channel_stock_location.rb +8 -0
- data/app/models/spree/claim.rb +69 -0
- data/app/models/spree/claim_line_item.rb +46 -0
- data/app/models/spree/claim_reason.rb +24 -0
- data/app/models/spree/classification.rb +7 -49
- data/app/models/spree/collection.rb +269 -0
- data/app/models/spree/collection_rule.rb +58 -0
- data/app/models/spree/collection_rules/available_on.rb +21 -0
- data/app/models/spree/collection_rules/sale.rb +18 -0
- data/app/models/spree/collection_rules/tag.rb +21 -0
- data/app/models/spree/commission_line.rb +85 -0
- data/app/models/spree/commission_rate.rb +370 -0
- data/app/models/spree/commission_rate_value.rb +47 -0
- data/app/models/spree/commission_rule.rb +77 -0
- data/app/models/spree/commission_rule_product.rb +19 -0
- data/app/models/spree/commission_rules/category_rule.rb +33 -0
- data/app/models/spree/commission_rules/item_total_rule.rb +31 -0
- data/app/models/spree/commission_rules/product_rule.rb +55 -0
- data/app/models/spree/commission_rules/seller_rule.rb +33 -0
- data/app/models/spree/commission_tax.rb +51 -0
- data/app/models/spree/commissions/context.rb +71 -0
- data/app/models/spree/company.rb +347 -0
- data/app/models/spree/company_invitation.rb +81 -0
- data/app/models/spree/company_membership.rb +25 -0
- data/app/models/spree/consent_record.rb +125 -0
- data/app/models/spree/country.rb +128 -52
- data/app/models/spree/coupon_code.rb +18 -5
- data/app/models/spree/credit_card.rb +10 -9
- data/app/models/spree/current.rb +152 -18
- data/app/models/spree/custom_field.rb +160 -7
- data/app/models/spree/custom_field_definition/search_capabilities.rb +98 -0
- data/app/models/spree/custom_field_definition.rb +219 -5
- data/app/models/spree/custom_fields/boolean.rb +15 -0
- data/app/models/spree/custom_fields/json.rb +38 -0
- data/app/models/spree/custom_fields/long_text.rb +11 -0
- data/app/models/spree/custom_fields/number.rb +23 -0
- data/app/models/spree/custom_fields/rich_text.rb +23 -0
- data/app/models/spree/custom_fields/short_text.rb +15 -0
- data/app/models/spree/customer.rb +34 -0
- data/app/models/spree/customer_group.rb +12 -12
- data/app/models/spree/customer_group_user.rb +6 -4
- data/app/models/spree/data_feed.rb +1 -1
- data/app/models/spree/data_request.rb +98 -0
- data/app/models/spree/delivery.rb +169 -0
- data/app/models/spree/delivery_method.rb +566 -0
- data/app/models/spree/delivery_method_rule.rb +55 -0
- data/app/models/spree/delivery_method_rule_product.rb +8 -0
- data/app/models/spree/delivery_method_rules/channel_rule.rb +41 -0
- data/app/models/spree/delivery_method_rules/company_rule.rb +24 -0
- data/app/models/spree/delivery_method_rules/excluded_products_rule.rb +48 -0
- data/app/models/spree/delivery_method_rules/item_total_rule.rb +19 -0
- data/app/models/spree/delivery_method_rules/volume_rule.rb +35 -0
- data/app/models/spree/delivery_method_rules/weight_rule.rb +19 -0
- data/app/models/spree/delivery_method_service.rb +24 -0
- data/app/models/spree/delivery_method_stock_location.rb +11 -0
- data/app/models/spree/delivery_origin_group.rb +73 -0
- data/app/models/spree/delivery_origin_group_location.rb +9 -0
- data/app/models/spree/delivery_profile.rb +141 -0
- data/app/models/spree/delivery_profiles/digital.rb +20 -0
- data/app/models/spree/delivery_profiles/shipping.rb +12 -0
- data/app/models/spree/delivery_rate.rb +164 -0
- data/app/models/spree/delivery_rate_provider/base.rb +120 -0
- data/app/models/spree/delivery_rate_provider/estimate.rb +44 -0
- data/app/models/spree/delivery_rate_provider/freight.rb +41 -0
- data/app/models/spree/delivery_rate_provider/internal.rb +28 -0
- data/app/models/spree/delivery_rate_provider/service_catalog.rb +48 -0
- data/app/models/spree/delivery_zone.rb +64 -0
- data/app/models/spree/delivery_zone_member.rb +98 -0
- data/app/models/spree/digital.rb +12 -16
- data/app/models/spree/digital_asset.rb +144 -0
- data/app/models/spree/digital_asset_provider/base.rb +95 -0
- data/app/models/spree/digital_asset_provider/file.rb +20 -0
- data/app/models/spree/digital_delivery.rb +28 -0
- data/app/models/spree/digital_link.rb +31 -11
- data/app/models/spree/discount.rb +51 -0
- data/app/models/spree/event.rb +6 -6
- data/app/models/spree/exchange.rb +50 -44
- data/app/models/spree/exchange_line_item.rb +52 -0
- data/app/models/spree/export.rb +128 -21
- data/app/models/spree/exports/customers.rb +2 -2
- data/app/models/spree/exports/gift_cards.rb +2 -2
- data/app/models/spree/exports/newsletter_subscribers.rb +2 -2
- data/app/models/spree/exports/orders.rb +35 -5
- data/app/models/spree/exports/price_list_prices.rb +107 -0
- data/app/models/spree/exports/products.rb +4 -4
- data/app/models/spree/exports/purchase_orders.rb +39 -0
- data/app/models/spree/exports/report.rb +95 -0
- data/app/models/spree/external_reference.rb +77 -0
- data/app/models/spree/external_video.rb +117 -0
- data/app/models/spree/fee.rb +40 -0
- data/app/models/spree/freight_summary/line.rb +257 -0
- data/app/models/spree/freight_summary.rb +180 -0
- data/app/models/spree/fulfillment/custom_events.rb +96 -0
- data/app/models/spree/fulfillment.rb +973 -0
- data/app/models/spree/fulfillment_changer.rb +170 -0
- data/app/models/spree/fulfillment_item.rb +148 -0
- data/app/models/spree/fulfillment_provider/base.rb +130 -0
- data/app/models/spree/fulfillment_provider/digital.rb +44 -0
- data/app/models/spree/fulfillment_provider/manual.rb +15 -0
- data/app/models/spree/fulfillment_provider/pickup.rb +38 -0
- data/app/models/spree/fulfillment_provider/pickup_point.rb +24 -0
- data/app/models/spree/fulfilment_changer.rb +3 -164
- data/app/models/spree/gateway/bogus.rb +5 -4
- data/app/models/spree/gateway/custom_payment_source_method.rb +5 -5
- data/app/models/spree/gateway.rb +2 -2
- data/app/models/spree/gateway_customer.rb +12 -4
- data/app/models/spree/gift_card.rb +140 -48
- data/app/models/spree/gift_card_batch.rb +2 -2
- data/app/models/spree/import.rb +136 -98
- data/app/models/spree/import_mapping.rb +1 -1
- data/app/models/spree/import_row.rb +35 -31
- data/app/models/spree/import_schemas/price_list_prices.rb +13 -0
- data/app/models/spree/import_schemas/products.rb +8 -1
- data/app/models/spree/import_schemas/purchase_orders.rb +19 -0
- data/app/models/spree/imports/price_list_prices.rb +72 -0
- data/app/models/spree/imports/purchase_orders.rb +28 -0
- data/app/models/spree/integration.rb +128 -5
- data/app/models/spree/inventory_provider/base.rb +30 -0
- data/app/models/spree/inventory_provider/internal.rb +22 -0
- data/app/models/spree/inventory_unit.rb +3 -139
- data/app/models/spree/invitation.rb +53 -47
- data/app/models/spree/label_purchase.rb +29 -0
- data/app/models/spree/line_item.rb +240 -106
- data/app/models/spree/market.rb +106 -15
- data/app/models/spree/market_country.rb +10 -5
- data/app/models/spree/media.rb +497 -0
- data/app/models/spree/media_usage_reference.rb +27 -0
- data/app/models/spree/metafield.rb +14 -102
- data/app/models/spree/metafield_definition.rb +11 -128
- data/app/models/spree/metafields.rb +32 -0
- data/app/models/spree/newsletter_subscriber.rb +10 -9
- data/app/models/spree/number_generators/base.rb +56 -0
- data/app/models/spree/number_generators/random.rb +23 -0
- data/app/models/spree/number_generators/sequential.rb +88 -0
- data/app/models/spree/number_sequence.rb +86 -0
- data/app/models/spree/option_type.rb +18 -32
- data/app/models/spree/option_type_product_type.rb +8 -0
- data/app/models/spree/option_value.rb +19 -13
- data/app/models/spree/option_value_variant.rb +0 -1
- data/app/models/spree/order.rb +681 -576
- data/app/models/spree/order_cancellation_reason.rb +25 -0
- data/app/models/spree/order_group.rb +244 -0
- data/app/models/spree/order_inventory.rb +42 -33
- data/app/models/spree/order_merger.rb +11 -6
- data/app/models/spree/order_promotion.rb +32 -6
- data/app/models/spree/order_routing/has_strategy_preference.rb +1 -2
- data/app/models/spree/order_routing/rules/minimize_splits.rb +6 -6
- data/app/models/spree/order_routing/strategy/rules.rb +12 -8
- data/app/models/spree/order_routing_rule.rb +5 -15
- data/app/models/spree/order_updater.rb +131 -163
- data/app/models/spree/package_type.rb +191 -0
- data/app/models/spree/payment/custom_events.rb +52 -5
- data/app/models/spree/payment/gateway_options.rb +20 -5
- data/app/models/spree/payment/processing.rb +95 -116
- data/app/models/spree/payment.rb +299 -123
- data/app/models/spree/payment_method/check.rb +4 -3
- data/app/models/spree/payment_method/session_instrumentation.rb +34 -0
- data/app/models/spree/payment_method/store_credit.rb +4 -2
- data/app/models/spree/payment_method.rb +106 -9
- data/app/models/spree/payment_session.rb +150 -53
- data/app/models/spree/payment_setup_session.rb +4 -37
- data/app/models/spree/payment_source.rb +5 -4
- data/app/models/spree/payment_split.rb +90 -0
- data/app/models/spree/payout_provider/base.rb +218 -0
- data/app/models/spree/payout_provider/system.rb +36 -0
- data/app/models/spree/permission_sets.rb +17 -0
- data/app/models/spree/pickup_point_option.rb +28 -0
- data/app/models/spree/pickup_point_provider/base.rb +24 -0
- data/app/models/spree/policy.rb +12 -11
- data/app/models/spree/price.rb +91 -5
- data/app/models/spree/price_adjustment_tier.rb +63 -0
- data/app/models/spree/price_history.rb +1 -1
- data/app/models/spree/price_list.rb +266 -142
- data/app/models/spree/price_rule.rb +51 -7
- data/app/models/spree/price_rules/channel_rule.rb +3 -0
- data/app/models/spree/price_rules/customer_group_rule.rb +10 -1
- data/app/models/spree/price_rules/market_rule.rb +6 -0
- data/app/models/spree/price_rules/user_rule.rb +12 -3
- data/app/models/spree/price_rules/volume_rule.rb +6 -0
- data/app/models/spree/price_rules/zone_rule.rb +5 -13
- data/app/models/spree/pricing_provider/base.rb +51 -0
- data/app/models/spree/pricing_provider/internal.rb +277 -0
- data/app/models/spree/pricing_provider.rb +28 -0
- data/app/models/spree/product.rb +528 -544
- data/app/models/spree/product_category.rb +65 -0
- data/app/models/spree/product_collection.rb +20 -0
- data/app/models/spree/product_option_type.rb +0 -1
- data/app/models/spree/product_promotion_rule.rb +0 -1
- data/app/models/spree/product_publication.rb +0 -1
- data/app/models/spree/product_submission.rb +72 -0
- data/app/models/spree/product_type.rb +116 -0
- data/app/models/spree/product_type_category.rb +8 -0
- data/app/models/spree/product_type_custom_field_definition.rb +39 -0
- data/app/models/spree/promotion/actions/create_adjustment.rb +9 -7
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +11 -16
- data/app/models/spree/promotion/actions/create_line_items.rb +19 -8
- data/app/models/spree/promotion/actions/free_shipping.rb +12 -18
- data/app/models/spree/promotion/rules/category.rb +181 -0
- data/app/models/spree/promotion/rules/channel.rb +3 -3
- data/app/models/spree/promotion/rules/country.rb +43 -17
- data/app/models/spree/promotion/rules/currency.rb +2 -2
- data/app/models/spree/promotion/rules/customer_group.rb +13 -5
- data/app/models/spree/promotion/rules/first_order.rb +3 -3
- data/app/models/spree/promotion/rules/item_total.rb +2 -2
- data/app/models/spree/promotion/rules/market.rb +3 -3
- data/app/models/spree/promotion/rules/one_use_per_user.rb +4 -4
- data/app/models/spree/promotion/rules/option_value.rb +34 -11
- data/app/models/spree/promotion/rules/product.rb +3 -5
- data/app/models/spree/promotion/rules/taxon.rb +10 -131
- data/app/models/spree/promotion/rules/user.rb +14 -22
- data/app/models/spree/promotion/rules/user_logged_in.rb +3 -3
- data/app/models/spree/promotion.rb +59 -21
- data/app/models/spree/promotion_action.rb +52 -11
- data/app/models/spree/promotion_action_line_item.rb +1 -1
- data/app/models/spree/promotion_handler/coupon.rb +44 -16
- data/app/models/spree/promotion_handler/free_shipping.rb +1 -1
- data/app/models/spree/promotion_handler/promotion_duplicator.rb +1 -1
- data/app/models/spree/promotion_rule.rb +2 -9
- data/app/models/spree/promotion_rule_category.rb +22 -0
- data/app/models/spree/promotion_rule_taxon.rb +7 -6
- data/app/models/spree/promotion_rule_user.rb +2 -2
- data/app/models/spree/prototype.rb +3 -13
- data/app/models/spree/purchase_order.rb +95 -0
- data/app/models/spree/purchase_order_item.rb +40 -0
- data/app/models/spree/quantity_rule.rb +114 -0
- data/app/models/spree/refresh_token.rb +20 -2
- data/app/models/spree/refund.rb +96 -42
- data/app/models/spree/refund_reason.rb +32 -11
- data/app/models/spree/return.rb +151 -0
- data/app/models/spree/return_authorization_reason.rb +11 -6
- data/app/models/spree/return_line_item.rb +42 -0
- data/app/models/spree/return_reason.rb +26 -0
- data/app/models/spree/rich_text_sanitizer.rb +99 -0
- data/app/models/spree/role.rb +179 -4
- data/app/models/spree/role_user.rb +5 -21
- data/app/models/spree/saved_report.rb +56 -0
- data/app/models/spree/search_provider/base.rb +8 -2
- data/app/models/spree/search_provider/database.rb +73 -22
- data/app/models/spree/search_provider.rb +29 -0
- data/app/models/spree/seller.rb +475 -0
- data/app/models/spree/seller_balance.rb +86 -0
- data/app/models/spree/seller_payout.rb +116 -0
- data/app/models/spree/seller_requirement.rb +274 -0
- data/app/models/spree/seller_requirement_custom_field.rb +38 -0
- data/app/models/spree/seller_requirement_status.rb +144 -0
- data/app/models/spree/seller_requirement_submission.rb +91 -0
- data/app/models/spree/seller_requirements/accept_terms.rb +104 -0
- data/app/models/spree/seller_requirements/attestation.rb +22 -0
- data/app/models/spree/seller_requirements/billing_address.rb +13 -0
- data/app/models/spree/seller_requirements/complete_profile.rb +26 -0
- data/app/models/spree/seller_requirements/delivery_method.rb +20 -0
- data/app/models/spree/seller_requirements/document.rb +62 -0
- data/app/models/spree/seller_requirements/minimum_products.rb +20 -0
- data/app/models/spree/seller_requirements/operator_review.rb +23 -0
- data/app/models/spree/seller_requirements/package_type.rb +40 -0
- data/app/models/spree/seller_requirements/payout_account.rb +55 -0
- data/app/models/spree/seller_requirements/policy.rb +43 -0
- data/app/models/spree/seller_requirements/required_custom_fields.rb +56 -0
- data/app/models/spree/seller_requirements/returns_address.rb +19 -0
- data/app/models/spree/seller_transfer.rb +166 -0
- data/app/models/spree/setup_tasks.rb +3 -6
- data/app/models/spree/shipment.rb +3 -560
- data/app/models/spree/shipping_calculator.rb +7 -0
- data/app/models/spree/shipping_document.rb +32 -0
- data/app/models/spree/shipping_label.rb +146 -0
- data/app/models/spree/shipping_method.rb +3 -146
- data/app/models/spree/shipping_rate.rb +3 -97
- data/app/models/spree/state.rb +57 -23
- data/app/models/spree/stock/availability_validator.rb +1 -1
- data/app/models/spree/stock/content_item.rb +1 -0
- data/app/models/spree/stock/coordinator.rb +69 -9
- data/app/models/spree/stock/estimator.rb +198 -33
- data/app/models/spree/stock/inventory_unit_builder.rb +6 -1
- data/app/models/spree/stock/package.rb +145 -14
- data/app/models/spree/stock/packer.rb +20 -3
- data/app/models/spree/stock/prioritizer.rb +27 -4
- data/app/models/spree/stock/quantifier.rb +63 -38
- data/app/models/spree/stock/splitter/base.rb +3 -1
- data/app/models/spree/stock/splitter/delivery_profile.rb +41 -0
- data/app/models/spree/stock_item.rb +3 -147
- data/app/models/spree/stock_level/custom_events.rb +48 -0
- data/app/models/spree/stock_level.rb +305 -0
- data/app/models/spree/stock_location.rb +165 -87
- data/app/models/spree/stock_movement/custom_events.rb +1 -1
- data/app/models/spree/stock_movement.rb +166 -22
- data/app/models/spree/stock_receipt.rb +61 -0
- data/app/models/spree/stock_receipt_item.rb +35 -0
- data/app/models/spree/stock_reservation.rb +114 -11
- data/app/models/spree/stock_transfer.rb +84 -59
- data/app/models/spree/stock_transfer_item.rb +25 -0
- data/app/models/spree/store.rb +431 -107
- data/app/models/spree/store_credit.rb +88 -21
- data/app/models/spree/store_credit_category.rb +21 -28
- data/app/models/spree/store_credit_event.rb +1 -1
- data/app/models/spree/store_credit_type.rb +10 -2
- data/app/models/spree/store_payment_method.rb +0 -1
- data/app/models/spree/store_product.rb +2 -2
- data/app/models/spree/store_promotion.rb +0 -1
- data/app/models/spree/storefront/access_denied.rb +22 -0
- data/app/models/spree/storefront/access_policy.rb +180 -0
- data/app/models/spree/subscriber.rb +6 -6
- data/app/models/spree/supplier.rb +76 -0
- data/app/models/spree/tax_category.rb +15 -5
- data/app/models/spree/tax_exemption/item_override.rb +22 -0
- data/app/models/spree/tax_exemption.rb +81 -0
- data/app/models/spree/tax_exemption_certificate.rb +95 -0
- data/app/models/spree/tax_identifier.rb +209 -0
- data/app/models/spree/tax_identifiers/validation_result.rb +41 -0
- data/app/models/spree/tax_identifiers/validator/base.rb +53 -0
- data/app/models/spree/tax_identifiers/validator/eu_vat.rb +76 -0
- data/app/models/spree/tax_line.rb +79 -0
- data/app/models/spree/tax_provider/base.rb +150 -0
- data/app/models/spree/tax_provider/internal.rb +227 -0
- data/app/models/spree/tax_rate.rb +63 -100
- data/app/models/spree/taxon.rb +13 -514
- data/app/models/spree/taxon_rule.rb +8 -9
- data/app/models/spree/taxonomy.rb +8 -42
- data/app/models/spree/user_identity.rb +2 -2
- data/app/models/spree/variant.rb +629 -150
- data/app/models/spree/variant_media.rb +6 -7
- data/app/models/spree/webhook_endpoint.rb +2 -1
- data/app/models/spree/wished_item.rb +3 -31
- data/app/models/spree/wishlist.rb +17 -10
- data/app/models/spree/wishlist_item/custom_events.rb +42 -0
- data/app/models/spree/wishlist_item.rb +37 -0
- data/app/models/spree/zone.rb +24 -182
- data/app/models/spree/zone_member.rb +5 -8
- data/app/presenters/spree/csv/custom_fields_helper.rb +25 -0
- data/app/presenters/spree/csv/customer_presenter.rb +7 -6
- data/app/presenters/spree/csv/gift_card_presenter.rb +9 -8
- data/app/presenters/spree/csv/newsletter_subscriber_presenter.rb +7 -6
- data/app/presenters/spree/csv/order_line_item_presenter.rb +53 -21
- data/app/presenters/spree/csv/price_list_price_presenter.rb +41 -0
- data/app/presenters/spree/csv/product_variant_presenter.rb +22 -21
- data/app/presenters/spree/csv/purchase_order_item_presenter.rb +50 -0
- data/app/presenters/spree/data_feeds/google_presenter.rb +24 -10
- data/app/presenters/spree/filters/options_presenter.rb +2 -2
- data/app/services/spree/addresses/create.rb +70 -27
- data/app/services/spree/addresses/helper.rb +17 -54
- data/app/services/spree/addresses/update.rb +53 -31
- data/app/services/spree/carts/associate.rb +46 -0
- data/app/services/spree/carts/check_availability.rb +72 -0
- data/app/services/spree/carts/create.rb +7 -1
- data/app/services/spree/carts/destroy.rb +71 -0
- data/app/services/spree/carts/empty.rb +42 -0
- data/app/services/spree/carts/partition_by_seller.rb +71 -0
- data/app/services/spree/carts/price_items.rb +119 -0
- data/app/services/spree/carts/remove_item.rb +42 -0
- data/app/services/spree/carts/remove_line_item.rb +42 -0
- data/app/services/spree/carts/remove_out_of_stock_items.rb +104 -0
- data/app/services/spree/carts/set_quantity.rb +39 -0
- data/app/services/spree/carts/split_by_seller.rb +475 -0
- data/app/services/spree/carts/update.rb +157 -51
- data/app/services/spree/catalogs/resolve_prices.rb +192 -0
- data/app/services/spree/catalogs/resolve_quantity_rules.rb +115 -0
- data/app/services/spree/catalogs/set_assignments.rb +59 -0
- data/app/services/spree/catalogs/set_order_minimums.rb +44 -0
- data/app/services/spree/catalogs/set_product_terms.rb +83 -0
- data/app/services/spree/categories/add_products.rb +51 -0
- data/app/services/spree/categories/remove_products.rb +72 -0
- data/app/services/spree/checkout/add_store_credit.rb +11 -79
- data/app/services/spree/checkout/advance.rb +38 -38
- data/app/services/spree/checkout/remove_store_credit.rb +7 -12
- data/app/services/spree/collections/add_products.rb +42 -0
- data/app/services/spree/collections/regenerate_products.rb +67 -0
- data/app/services/spree/collections/remove_products.rb +65 -0
- data/app/services/spree/commissions/calculate_line.rb +132 -0
- data/app/services/spree/commissions/commission_order.rb +185 -0
- data/app/services/spree/commissions/resolve_rate.rb +114 -0
- data/app/services/spree/commissions/resolve_tax_rate.rb +78 -0
- data/app/services/spree/companies/add_member.rb +38 -0
- data/app/services/spree/company_invitations/accept.rb +60 -0
- data/app/services/spree/coupon_codes/coupon_codes_handler.rb +14 -2
- data/app/services/spree/customers/data_export.rb +372 -0
- data/app/services/spree/data_requests/create.rb +77 -0
- data/app/services/spree/deliveries/create.rb +56 -0
- data/app/services/spree/deliveries/destroy.rb +39 -0
- data/app/services/spree/deliveries/upsert_primary.rb +43 -0
- data/app/services/spree/fulfillments/recalculate_delivery.rb +62 -0
- data/app/services/spree/fulfillments/stand_down_provider.rb +47 -0
- data/app/services/spree/imports/row_processors/customer.rb +8 -8
- data/app/services/spree/imports/row_processors/price_list_price.rb +164 -0
- data/app/services/spree/imports/row_processors/product_variant.rb +193 -57
- data/app/services/spree/imports/row_processors/purchase_order.rb +157 -0
- data/app/services/spree/media/destroy.rb +88 -0
- data/app/services/spree/media/usage.rb +175 -0
- data/app/services/spree/newsletter/link_user.rb +4 -3
- data/app/services/spree/newsletter/subscribe.rb +3 -3
- data/app/services/spree/newsletter/verify.rb +6 -2
- data/app/services/spree/order_groups/allocate_payments.rb +101 -0
- data/app/services/spree/orders/approve.rb +11 -24
- data/app/services/spree/orders/build_fulfillments.rb +29 -0
- data/app/services/spree/orders/create.rb +38 -17
- data/app/services/spree/orders/create_from_cart.rb +88 -0
- data/app/services/spree/orders/create_user_account.rb +14 -67
- data/app/services/spree/orders/discounts/create.rb +84 -0
- data/app/services/spree/orders/discounts/destroy.rb +25 -0
- data/app/services/spree/orders/discounts/update.rb +29 -0
- data/app/services/spree/orders/fees/create.rb +28 -0
- data/app/services/spree/orders/fees/destroy.rb +22 -0
- data/app/services/spree/orders/fees/update.rb +25 -0
- data/app/services/spree/orders/remove_item.rb +13 -0
- data/app/services/spree/orders/remove_line_item.rb +13 -0
- data/app/services/spree/orders/update.rb +56 -11
- data/app/services/spree/orders/update_item.rb +105 -0
- data/app/services/spree/orders/update_statuses.rb +109 -0
- data/app/services/spree/payments/create.rb +31 -5
- data/app/services/spree/prices/bulk_upsert.rb +156 -30
- data/app/services/spree/product_submissions/close.rb +46 -0
- data/app/services/spree/product_types/apply_to_products.rb +167 -0
- data/app/services/spree/products/auto_match_collections.rb +75 -0
- data/app/services/spree/products/auto_match_taxons.rb +7 -54
- data/app/services/spree/products/duplicator.rb +16 -22
- data/app/services/spree/products/for_context.rb +54 -0
- data/app/services/spree/products/select_buy_box.rb +98 -0
- data/app/services/spree/purchases/amount_due_at_checkout.rb +33 -0
- data/app/services/spree/returns/eligibility_validator.rb +53 -0
- data/app/services/spree/sample_data/helper.rb +3 -3
- data/app/services/spree/sample_data/import_builder.rb +8 -4
- data/app/services/spree/sample_data/import_runner.rb +7 -4
- data/app/services/spree/sample_data/loader.rb +15 -6
- data/app/services/spree/search_provider/custom_field_schema.rb +153 -0
- data/app/services/spree/seeds/admin_user.rb +72 -12
- data/app/services/spree/seeds/all.rb +24 -13
- data/app/services/spree/seeds/commission_rates.rb +53 -0
- data/app/services/spree/seeds/digital_delivery.rb +18 -8
- data/app/services/spree/seeds/product_types.rb +23 -0
- data/app/services/spree/seeds/returns_environment.rb +44 -16
- data/app/services/spree/seeds/roles.rb +6 -1
- data/app/services/spree/seeds/saved_reports.rb +107 -0
- data/app/services/spree/seeds/seller_requirements.rb +19 -0
- data/app/services/spree/seeds/stores.rb +1 -1
- data/app/services/spree/seeds/tax_categories.rb +9 -2
- data/app/services/spree/sellers/requirements.rb +129 -0
- data/app/services/spree/shipments/update.rb +4 -33
- data/app/services/spree/shipping_labels/confirm_refund.rb +47 -0
- data/app/services/spree/shipping_labels/store_file.rb +68 -0
- data/app/services/spree/stock_levels/bulk_upsert.rb +67 -0
- data/app/services/spree/stock_levels/correct.rb +69 -0
- data/app/services/spree/stock_levels/recount.rb +103 -0
- data/app/services/spree/stock_locations/stock_items/create.rb +8 -13
- data/app/services/spree/stock_locations/stock_levels/create.rb +25 -0
- data/app/services/spree/stock_reservations/extend.rb +9 -5
- data/app/services/spree/stock_reservations/release.rb +4 -3
- data/app/services/spree/stock_reservations/reserve.rb +43 -32
- data/app/services/spree/store_credits/apply.rb +93 -0
- data/app/services/spree/store_credits/remove.rb +17 -0
- data/app/services/spree/stores/provision_defaults.rb +269 -0
- data/app/services/spree/tax/resolve_exemptions.rb +44 -0
- data/app/services/spree/tax/unusable_exemption_error.rb +8 -0
- data/app/services/spree/tax_identifiers/validate.rb +77 -0
- data/app/services/spree/taxons/add_products.rb +6 -39
- data/app/services/spree/taxons/regenerate_products.rb +8 -53
- data/app/services/spree/taxons/remove_products.rb +6 -60
- data/app/services/spree/variants/remove_line_items.rb +6 -1
- data/app/subscribers/spree/event_log_subscriber.rb +1 -1
- data/app/subscribers/spree/order_commission_subscriber.rb +23 -0
- data/app/subscribers/spree/order_placed_subscriber.rb +58 -0
- data/app/subscribers/spree/order_status_subscriber.rb +82 -0
- data/app/subscribers/spree/payment_split_subscriber.rb +71 -0
- data/app/subscribers/spree/product_metrics_subscriber.rb +2 -2
- data/app/subscribers/spree/seller_onboarding_subscriber.rb +32 -0
- data/app/subscribers/spree/seller_transfer_reversal_subscriber.rb +26 -0
- data/app/subscribers/spree/seller_transfer_subscriber.rb +26 -0
- data/app/subscribers/spree/seller_user_email_subscriber.rb +27 -0
- data/app/subscribers/spree/tax_identifier_validation_subscriber.rb +26 -0
- data/app/validators/spree/addresses/phone_validator.rb +2 -2
- data/app/validators/spree/attachment_content_type_validator.rb +183 -0
- data/app/validators/spree/password_length_validator.rb +23 -0
- data/app/views/spree/seller_user_mailer/password_reset_email.html.erb +8 -0
- data/app/views/spree/shared/_purchased_items_styles.html.erb +7 -0
- data/app/workflows/spree/carts/add_item.rb +234 -0
- data/app/workflows/spree/carts/complete.rb +516 -0
- data/app/workflows/spree/carts/merge.rb +90 -0
- data/app/workflows/spree/carts/recalculate.rb +54 -0
- data/app/workflows/spree/carts/recalculate_totals.rb +233 -0
- data/app/workflows/spree/carts/upsert_items.rb +368 -0
- data/app/workflows/spree/catalogs/activate.rb +51 -0
- data/app/workflows/spree/catalogs/create.rb +83 -0
- data/app/workflows/spree/catalogs/deactivate.rb +35 -0
- data/app/workflows/spree/catalogs/set_price_list.rb +130 -0
- data/app/workflows/spree/catalogs/update.rb +85 -0
- data/app/workflows/spree/claims/approve.rb +38 -0
- data/app/workflows/spree/claims/cancel.rb +37 -0
- data/app/workflows/spree/claims/create.rb +82 -0
- data/app/workflows/spree/claims/deny.rb +35 -0
- data/app/workflows/spree/claims/resolve.rb +166 -0
- data/app/workflows/spree/customers/anonymize.rb +502 -0
- data/app/workflows/spree/customers/create.rb +247 -0
- data/app/workflows/spree/data_requests/fulfill.rb +165 -0
- data/app/workflows/spree/deliveries/update_tracking.rb +96 -0
- data/app/workflows/spree/exchanges/approve.rb +38 -0
- data/app/workflows/spree/exchanges/cancel.rb +40 -0
- data/app/workflows/spree/exchanges/create.rb +90 -0
- data/app/workflows/spree/exchanges/fulfill.rb +146 -0
- data/app/workflows/spree/exchanges/receive.rb +86 -0
- data/app/workflows/spree/fulfillments/cancel.rb +87 -0
- data/app/workflows/spree/fulfillments/create.rb +346 -0
- data/app/workflows/spree/fulfillments/fulfill.rb +354 -0
- data/app/workflows/spree/fulfillments/mark_delivered.rb +67 -0
- data/app/workflows/spree/fulfillments/purchase_label.rb +40 -0
- data/app/workflows/spree/fulfillments/update.rb +123 -0
- data/app/workflows/spree/gift_cards/apply.rb +235 -0
- data/app/workflows/spree/gift_cards/cancel.rb +43 -0
- data/app/workflows/spree/gift_cards/redeem.rb +59 -0
- data/app/workflows/spree/gift_cards/remove.rb +78 -0
- data/app/workflows/spree/imports/complete.rb +45 -0
- data/app/workflows/spree/imports/complete_mapping.rb +50 -0
- data/app/workflows/spree/imports/retry_failed_rows.rb +46 -0
- data/app/workflows/spree/imports/start_mapping.rb +48 -0
- data/app/workflows/spree/imports/start_processing.rb +36 -0
- data/app/workflows/spree/invitations/accept.rb +50 -0
- data/app/workflows/spree/orders/add_item.rb +12 -0
- data/app/workflows/spree/orders/cancel.rb +261 -0
- data/app/workflows/spree/orders/complete.rb +169 -0
- data/app/workflows/spree/orders/recalculate.rb +11 -0
- data/app/workflows/spree/orders/recalculate_totals.rb +12 -0
- data/app/workflows/spree/orders/upsert_items.rb +28 -0
- data/app/workflows/spree/payment_sessions/complete.rb +44 -0
- data/app/workflows/spree/payments/capture.rb +109 -0
- data/app/workflows/spree/payments/handle_webhook.rb +100 -0
- data/app/workflows/spree/payments/process.rb +73 -0
- data/app/workflows/spree/payments/void.rb +72 -0
- data/app/workflows/spree/price_lists/activate.rb +49 -0
- data/app/workflows/spree/price_lists/create.rb +57 -0
- data/app/workflows/spree/price_lists/deactivate.rb +30 -0
- data/app/workflows/spree/price_lists/update.rb +117 -0
- data/app/workflows/spree/products/activate.rb +33 -0
- data/app/workflows/spree/products/approve.rb +52 -0
- data/app/workflows/spree/products/archive.rb +44 -0
- data/app/workflows/spree/products/create.rb +82 -0
- data/app/workflows/spree/products/destroy.rb +35 -0
- data/app/workflows/spree/products/draft.rb +49 -0
- data/app/workflows/spree/products/nested_attributes.rb +242 -0
- data/app/workflows/spree/products/propose.rb +62 -0
- data/app/workflows/spree/products/reject.rb +54 -0
- data/app/workflows/spree/products/update.rb +83 -0
- data/app/workflows/spree/purchase_orders/cancel.rb +57 -0
- data/app/workflows/spree/purchase_orders/close.rb +57 -0
- data/app/workflows/spree/purchase_orders/create.rb +68 -0
- data/app/workflows/spree/purchase_orders/mark_draft.rb +49 -0
- data/app/workflows/spree/purchase_orders/mark_ordered.rb +50 -0
- data/app/workflows/spree/purchase_orders/receive.rb +65 -0
- data/app/workflows/spree/purchase_orders/update.rb +56 -0
- data/app/workflows/spree/receivables/incoming_counter.rb +50 -0
- data/app/workflows/spree/refunds/create.rb +136 -0
- data/app/workflows/spree/refunds/order_payments.rb +129 -0
- data/app/workflows/spree/returns/approve.rb +47 -0
- data/app/workflows/spree/returns/cancel.rb +52 -0
- data/app/workflows/spree/returns/create.rb +135 -0
- data/app/workflows/spree/returns/purchase_label.rb +32 -0
- data/app/workflows/spree/returns/receive.rb +94 -0
- data/app/workflows/spree/returns/refund.rb +134 -0
- data/app/workflows/spree/seller_payouts/complete.rb +80 -0
- data/app/workflows/spree/seller_payouts/sweep.rb +192 -0
- data/app/workflows/spree/seller_requirement_submissions/accept.rb +40 -0
- data/app/workflows/spree/seller_requirement_submissions/create.rb +104 -0
- data/app/workflows/spree/seller_requirement_submissions/reject.rb +45 -0
- data/app/workflows/spree/seller_requirement_submissions/reviewable.rb +19 -0
- data/app/workflows/spree/seller_requirement_submissions/waive.rb +64 -0
- data/app/workflows/spree/seller_transfers/create.rb +131 -0
- data/app/workflows/spree/seller_transfers/reverse.rb +241 -0
- data/app/workflows/spree/sellers/approve.rb +88 -0
- data/app/workflows/spree/sellers/create.rb +72 -0
- data/app/workflows/spree/sellers/invite.rb +61 -0
- data/app/workflows/spree/sellers/reject.rb +52 -0
- data/app/workflows/spree/sellers/reopen_onboarding.rb +55 -0
- data/app/workflows/spree/sellers/start_onboarding.rb +46 -0
- data/app/workflows/spree/sellers/submit_for_review.rb +76 -0
- data/app/workflows/spree/sellers/suspend.rb +55 -0
- data/app/workflows/spree/shipping_labels/purchase.rb +154 -0
- data/app/workflows/spree/shipping_labels/record.rb +102 -0
- data/app/workflows/spree/shipping_labels/refund.rb +77 -0
- data/app/workflows/spree/stock_receipts/recording.rb +165 -0
- data/app/workflows/spree/stock_transfers/cancel.rb +103 -0
- data/app/workflows/spree/stock_transfers/close.rb +56 -0
- data/app/workflows/spree/stock_transfers/create.rb +63 -0
- data/app/workflows/spree/stock_transfers/mark_draft.rb +41 -0
- data/app/workflows/spree/stock_transfers/mark_in_transit.rb +91 -0
- data/app/workflows/spree/stock_transfers/mark_ready.rb +36 -0
- data/app/workflows/spree/stock_transfers/receive.rb +62 -0
- data/app/workflows/spree/stock_transfers/update.rb +55 -0
- data/app/workflows/spree/tax_exemption_certificates/verify.rb +48 -0
- data/app/workflows/spree/variants/create.rb +66 -0
- data/app/workflows/spree/variants/nested_attributes.rb +90 -0
- data/app/workflows/spree/variants/update.rb +55 -0
- data/config/brakeman.ignore +79 -79
- data/config/i18n-tasks.yml +4 -3
- data/config/initializers/mobility.rb +0 -4
- data/config/initializers/spree_store_setup_tasks.rb +4 -0
- data/config/locales/en.yml +952 -189
- data/config/routes.rb +11 -4
- data/db/migrate/20220201103922_add_first_name_and_last_name_to_spree_users.rb +7 -5
- data/db/migrate/20221215151408_add_selected_locale_to_spree_users.rb +6 -4
- data/db/migrate/20250127151258_add_phone_to_spree_users.rb +3 -1
- data/db/migrate/20250207084000_add_accepts_email_marketing_field_to_spree_users_table.rb +4 -2
- data/db/migrate/20250410061306_create_spree_invitations.rb +1 -1
- data/db/migrate/20250605131334_add_missing_fields_to_users.rb +24 -20
- data/db/migrate/20260315100000_add_product_media_support.rb +4 -1
- data/db/migrate/20260613000001_add_store_id_to_spree_role_users.rb +6 -3
- data/db/migrate/20260630000001_add_default_variant_id_to_spree_products.rb +9 -0
- data/db/migrate/20260708160054_create_spree_collections.rb +69 -0
- data/db/migrate/20260710000001_rename_taxons_to_categories.rb +28 -0
- data/db/migrate/20260727000001_add_unique_country_abbr_index_to_spree_states.rb +27 -4
- data/db/migrate/20260728000000_create_spree_customers_and_admin_users.rb +59 -0
- data/db/migrate/20260728000001_rename_prototypes_to_product_types.rb +59 -0
- data/db/migrate/20260728000002_create_spree_delivery_zones.rb +29 -0
- data/db/migrate/20260728000003_create_spree_carts.rb +58 -0
- data/db/migrate/20260728000003_rename_user_id_to_customer_id.rb +30 -0
- data/db/migrate/20260728000004_rename_shipping_to_fulfillment_and_delivery.rb +83 -0
- data/db/migrate/20260728000005_add_fulfillment_type_columns.rb +33 -0
- data/db/migrate/20260729000001_create_typed_adjustment_tables.rb +87 -0
- data/db/migrate/20260729100001_add_checkout_columns_to_spree_carts.rb +15 -0
- data/db/migrate/20260729100002_relax_owner_null_constraints.rb +7 -0
- data/db/migrate/20260729120001_rename_order_totals_to_standard_names.rb +7 -0
- data/db/migrate/20260729130001_create_spree_delivery_method_rules.rb +19 -0
- data/db/migrate/20260729140001_add_coupon_code_to_spree_orders.rb +6 -0
- data/db/migrate/20260729150001_add_store_to_delivery_methods_and_stock_locations.rb +6 -0
- data/db/migrate/20260802190001_create_spree_returns.rb +49 -0
- data/db/migrate/20260802210001_create_spree_exchanges_and_claims.rb +80 -0
- data/db/migrate/20260805100001_rename_return_authorization_reasons_to_return_reasons.rb +109 -0
- data/db/migrate/20260806000001_add_store_id_to_spree_tax_rates_and_categories.rb +16 -0
- data/db/migrate/20260806000001_create_spree_delivery_method_rule_products.rb +22 -0
- data/db/migrate/20260806000002_add_treatment_columns_to_spree_tax_lines.rb +19 -0
- data/db/migrate/20260806000003_create_spree_tax_identifiers.rb +41 -0
- data/db/migrate/20260806000004_add_tax_provider_to_spree_markets.rb +9 -0
- data/db/migrate/20260806000005_add_country_and_state_to_spree_tax_rates.rb +20 -0
- data/db/migrate/20260806100001_create_spree_product_type_custom_field_definitions.rb +17 -0
- data/db/migrate/20260806120001_add_rate_provider_to_delivery_methods.rb +7 -0
- data/db/migrate/20260806120002_add_carrier_columns_to_delivery_rates.rb +13 -0
- data/db/migrate/20260806130001_add_unique_store_type_index_to_spree_integrations.rb +9 -0
- data/db/migrate/20260807000001_add_permissions_to_spree_roles.rb +14 -0
- data/db/migrate/20260807000001_create_spree_companies.rb +66 -0
- data/db/migrate/20260807000003_create_spree_tax_exemption_certificates.rb +31 -0
- data/db/migrate/20260807120001_remove_claim_type_from_spree_claims.rb +5 -0
- data/db/migrate/20260807130001_add_country_state_codes_to_consumers.rb +28 -0
- data/db/migrate/20260807150001_reindex_spree_categories_by_store.rb +42 -0
- data/db/migrate/20260809000001_rename_metafields_to_custom_fields.rb +126 -0
- data/db/migrate/20260809100001_support_multi_rate_delivery_methods.rb +35 -0
- data/db/migrate/20260809120001_consolidate_metadata_columns.rb +120 -0
- data/db/migrate/20260809150001_promote_shipping_categories_to_delivery_profiles.rb +153 -0
- data/db/migrate/20260809170001_create_spree_channel_stock_locations.rb +17 -0
- data/db/migrate/20260809200001_add_rich_text_columns_for_action_text_removal.rb +11 -0
- data/db/migrate/20260810000001_rename_digitals_to_digital_assets.rb +38 -0
- data/db/migrate/20260811000001_add_delivery_tracking_to_fulfillments.rb +17 -0
- data/db/migrate/20260812000001_add_provider_type_to_spree_digital_assets.rb +7 -0
- data/db/migrate/20260812000002_add_metadata_to_spree_digital_assets.rb +11 -0
- data/db/migrate/20260813000001_create_spree_number_sequences.rb +13 -0
- data/db/migrate/20260813120001_add_setup_token_to_spree_stores.rb +11 -0
- data/db/migrate/20260813130001_add_capture_method_to_payment_methods.rb +17 -0
- data/db/migrate/20260813130001_add_unique_indexes_to_spree_data_feeds.rb +10 -0
- data/db/migrate/20260814000001_add_customs_fields_to_spree_variants.rb +7 -0
- data/db/migrate/20260814000001_rename_stock_items_to_stock_levels.rb +72 -0
- data/db/migrate/20260814000002_add_typed_stock_movements.rb +25 -0
- data/db/migrate/20260815000001_add_audience_to_spree_refresh_tokens.rb +14 -0
- data/db/migrate/20260815000002_add_resource_to_spree_roles.rb +190 -0
- data/db/migrate/20260816000001_create_spree_sellers.rb +59 -0
- data/db/migrate/20260816000002_add_seller_to_spree_products.rb +10 -0
- data/db/migrate/20260816210001_create_spree_commission_rates.rb +229 -0
- data/db/migrate/20260816210002_create_spree_commission_lines.rb +72 -0
- data/db/migrate/20260817000001_add_seller_to_spree_line_items.rb +15 -0
- data/db/migrate/20260817000002_add_seller_and_delivery_profile_to_spree_variants.rb +17 -0
- data/db/migrate/20260818000001_create_spree_external_references.rb +33 -0
- data/db/migrate/20260818000001_create_spree_seller_requirements.rb +60 -0
- data/db/migrate/20260818000001_rename_spree_payments_state_to_status.rb +5 -0
- data/db/migrate/20260818000002_add_price_source_to_spree_line_items.rb +9 -0
- data/db/migrate/20260818090001_rename_assets_to_media.rb +10 -0
- data/db/migrate/20260819000001_create_spree_seller_requirement_custom_fields.rb +15 -0
- data/db/migrate/20260819000001_replace_payment_method_display_on_with_storefront_visible.rb +25 -0
- data/db/migrate/20260819000002_rename_spree_gift_cards_state_to_status.rb +5 -0
- data/db/migrate/20260820000001_add_seller_business_identity_and_stock_locations.rb +17 -0
- data/db/migrate/20260820000001_create_spree_order_groups.rb +33 -0
- data/db/migrate/20260820000002_add_order_group_to_spree_orders_and_payments.rb +14 -0
- data/db/migrate/20260820000003_create_spree_payment_splits.rb +21 -0
- data/db/migrate/20260820000004_add_order_to_spree_refunds.rb +32 -0
- data/db/migrate/20260821000001_add_claimed_amount_to_spree_payment_splits.rb +14 -0
- data/db/migrate/20260822000001_create_spree_seller_transfers.rb +94 -0
- data/db/migrate/20260822000002_create_spree_seller_payouts.rb +48 -0
- data/db/migrate/20260822000003_add_payout_account_to_spree_sellers.rb +11 -0
- data/db/migrate/20260824000001_add_store_to_spree_media.rb +16 -0
- data/db/migrate/20260825000001_create_spree_catalogs.rb +40 -0
- data/db/migrate/20260826000001_add_owner_to_spree_addresses.rb +30 -0
- data/db/migrate/20260826000002_create_spree_product_submissions.rb +28 -0
- data/db/migrate/20260827000001_add_seller_to_spree_exports.rb +5 -0
- data/db/migrate/20260828100001_unify_import_and_export_tenancy.rb +79 -0
- data/db/migrate/20260830000001_add_catalog_to_spree_price_lists.rb +47 -0
- data/db/migrate/20260830000002_add_po_number_to_purchases.rb +16 -0
- data/db/migrate/20260830000002_add_price_adjustment_to_spree_price_lists.rb +14 -0
- data/db/migrate/20260831000001_add_description_to_spree_catalogs.rb +7 -0
- data/db/migrate/20260831000002_add_quantity_rules_to_spree_variants.rb +18 -0
- data/db/migrate/20260831000003_create_spree_catalog_terms.rb +35 -0
- data/db/migrate/20260831100001_create_spree_package_types.rb +38 -0
- data/db/migrate/20260831100002_add_carton_details_to_spree_variants.rb +10 -0
- data/db/migrate/20260831100003_add_unpriced_to_spree_delivery_rates.rb +8 -0
- data/db/migrate/20260901000001_add_seller_to_spree_delivery_methods.rb +11 -0
- data/db/migrate/20260902000001_add_store_and_filter_key_to_custom_field_definitions.rb +143 -0
- data/db/migrate/20260902000002_add_eu_legal_compliance.rb +68 -0
- data/db/migrate/20260902000002_replace_order_cancellation_tables_with_cancel_columns.rb +88 -0
- data/db/migrate/20260902100001_rename_wished_items_to_wishlist_items.rb +8 -0
- data/db/migrate/20260902100002_rename_promo_total_to_discount_total.rb +9 -0
- data/db/migrate/20260902100003_rename_address_name_and_postal_code_columns.rb +24 -0
- data/db/migrate/20260902100004_rename_option_presentation_to_label.rb +13 -0
- data/db/migrate/20260903000001_create_spree_shipping_labels_and_deliveries.rb +73 -0
- data/db/migrate/20260903120000_create_spree_saved_reports.rb +57 -0
- data/db/migrate/20260904000001_add_returns_enabled_to_stock_locations.rb +14 -0
- data/db/migrate/20260906000001_add_commission_total_to_orders.rb +22 -0
- data/db/migrate/20260907000001_add_inventory_operations.rb +113 -0
- data/db/migrate/20260907000001_add_min_quantity_to_spree_prices.rb +28 -0
- data/db/migrate/20260907000002_create_spree_price_adjustment_tiers.rb +19 -0
- data/db/migrate/20260908000001_add_seller_to_spree_package_types.rb +78 -0
- data/db/migrate/20260910000001_add_stock_receipts.rb +44 -0
- data/db/migrate/20260910000002_add_counters_to_spree_stock_levels.rb +6 -0
- data/db/migrate/20260910120000_index_reporting_time_columns.rb +12 -0
- data/db/migrate/20260912120000_index_reporting_lifetime_and_promotion_columns.rb +19 -0
- data/db/migrate/20260914000001_add_settlement_to_spree_seller_transfers.rb +18 -0
- data/db/migrate/20260914230000_add_store_to_spree_option_types.rb +46 -0
- data/db/migrate/20260916000001_order_operation_actors_polymorphic.rb +30 -0
- data/db/sample_data/collections.rb +58 -0
- data/db/sample_data/custom_field_definitions.rb +9 -0
- data/db/sample_data/digital_products.rb +26 -0
- data/db/sample_data/fulfillment.rb +88 -0
- data/db/sample_data/options.rb +25 -1
- data/db/sample_data/orders.rb +53 -30
- data/db/sample_data/payment_methods.rb +2 -2
- data/db/sample_data/price_list_prices.csv +25 -0
- data/db/sample_data/product_type_categories.rb +27 -0
- data/db/sample_data/product_types.rb +83 -0
- data/db/sample_data/products.csv +39 -38
- data/db/sample_data/wholesale.rb +42 -3
- data/lib/generators/spree/api_resource/api_resource_generator.rb +64 -6
- data/lib/generators/spree/api_resource/templates/admin_controller.rb.tt +5 -0
- data/lib/generators/spree/api_resource/templates/admin_controller_spec.rb.tt +3 -0
- data/lib/generators/spree/api_resource/templates/store_controller_spec.rb.tt +4 -1
- data/lib/generators/spree/authentication/dummy/templates/create_spree_admin_users.rb.tt +1 -0
- data/lib/generators/spree/controller_decorator/controller_decorator_generator.rb +4 -4
- data/lib/generators/spree/dummy/dummy_generator.rb +5 -12
- data/lib/generators/spree/dummy/templates/rails/test.rb +5 -0
- data/lib/generators/spree/model/model_generator.rb +46 -7
- data/lib/generators/spree/model/templates/create_table_migration.rb.tt +9 -0
- data/lib/generators/spree/model/templates/model.rb.tt +17 -7
- data/lib/spree/category_permalink_deduplicator.rb +328 -0
- data/lib/spree/checkout/default_requirements.rb +134 -0
- data/lib/spree/checkout/registry.rb +164 -0
- data/lib/spree/checkout/requirement.rb +49 -0
- data/lib/spree/checkout/requirements.rb +61 -0
- data/lib/spree/checkout/step.rb +52 -0
- data/lib/spree/core/configuration.rb +112 -63
- data/lib/spree/core/controller_helpers/store.rb +8 -9
- data/lib/spree/core/dependencies.rb +324 -71
- data/lib/spree/core/dependencies_helper.rb +4 -0
- data/lib/spree/core/engine.rb +360 -75
- data/lib/spree/core/number_generator.rb +37 -33
- data/lib/spree/core/permission_configuration.rb +183 -91
- data/lib/spree/core/permissions/default_catalog.rb +236 -0
- data/lib/spree/core/permissions/entry.rb +15 -0
- data/lib/spree/core/permissions/scope.rb +76 -0
- data/lib/spree/core/preferences/masking.rb +24 -2
- data/lib/spree/core/preferences/preferable.rb +52 -2
- data/lib/spree/core/preferences/preferable_class_methods.rb +41 -2
- data/lib/spree/core/preferences/runtime_configuration.rb +142 -9
- data/lib/spree/core/previews/admin_user_preview.rb +0 -8
- data/lib/spree/core/previews/invitation_preview.rb +1 -1
- data/lib/spree/core/previews/preview_data.rb +2 -2
- data/lib/spree/core/previews/seller_user_preview.rb +14 -0
- data/lib/spree/core/pricing/context.rb +28 -8
- data/lib/spree/core/pricing/price_resolution.rb +150 -0
- data/lib/spree/core/pricing/resolver.rb +17 -107
- data/lib/spree/core/ransack_configuration.rb +3 -3
- data/lib/spree/core/routes.rb +4 -6
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +446 -59
- data/lib/spree/events/adapters/base.rb +42 -15
- data/lib/spree/hooks.rb +146 -0
- data/lib/spree/iso_data.rb +188 -0
- data/lib/spree/measurement.rb +113 -0
- data/lib/spree/money.rb +70 -0
- data/lib/spree/number_generators/registry.rb +80 -0
- data/lib/spree/reporting/adapters/base.rb +71 -0
- data/lib/spree/reporting/adapters/live.rb +677 -0
- data/lib/spree/reporting/counter_result.rb +19 -0
- data/lib/spree/reporting/counters.rb +33 -0
- data/lib/spree/reporting/default_vocabulary.rb +705 -0
- data/lib/spree/reporting/hydration.rb +64 -0
- data/lib/spree/reporting/query.rb +487 -0
- data/lib/spree/reporting/registry.rb +294 -0
- data/lib/spree/reporting/result.rb +10 -0
- data/lib/spree/reporting/schema.rb +124 -0
- data/lib/spree/reporting.rb +49 -0
- data/lib/spree/service_module.rb +6 -0
- data/lib/spree/store_scope_guard.rb +180 -0
- data/lib/spree/testing_support/action_text.rb +33 -0
- data/lib/spree/testing_support/common_rake.rb +4 -66
- data/lib/spree/testing_support/country_pool.rb +50 -0
- data/lib/spree/testing_support/extension_rake.rb +2 -6
- data/lib/spree/testing_support/factories/address_factory.rb +45 -15
- data/lib/spree/testing_support/factories/api_key_factory.rb +1 -1
- data/lib/spree/testing_support/factories/calculator_factory.rb +0 -3
- data/lib/spree/testing_support/factories/cart_factory.rb +60 -0
- data/lib/spree/testing_support/factories/catalog_factory.rb +37 -0
- data/lib/spree/testing_support/factories/category_factory.rb +21 -0
- data/lib/spree/testing_support/factories/claim_factory.rb +33 -0
- data/lib/spree/testing_support/factories/classification_factory.rb +3 -2
- data/lib/spree/testing_support/factories/collection_factory.rb +25 -0
- data/lib/spree/testing_support/factories/collection_rule_factory.rb +47 -0
- data/lib/spree/testing_support/factories/commission_rate_factory.rb +75 -0
- data/lib/spree/testing_support/factories/company_factory.rb +31 -0
- data/lib/spree/testing_support/factories/consent_record_factory.rb +10 -0
- data/lib/spree/testing_support/factories/country_factory.rb +28 -9
- data/lib/spree/testing_support/factories/custom_field_definition_factory.rb +79 -0
- data/lib/spree/testing_support/factories/custom_field_factory.rb +64 -0
- data/lib/spree/testing_support/factories/customer_group_user_factory.rb +1 -1
- data/lib/spree/testing_support/factories/data_request_factory.rb +17 -0
- data/lib/spree/testing_support/factories/delivery_factory.rb +13 -0
- data/lib/spree/testing_support/factories/delivery_method_factory.rb +47 -0
- data/lib/spree/testing_support/factories/delivery_origin_group_factory.rb +5 -0
- data/lib/spree/testing_support/factories/delivery_profile_factory.rb +9 -0
- data/lib/spree/testing_support/factories/delivery_rate_factory.rb +7 -0
- data/lib/spree/testing_support/factories/delivery_zone_factory.rb +34 -0
- data/lib/spree/testing_support/factories/digital_asset_factory.rb +13 -0
- data/lib/spree/testing_support/factories/digital_link_factory.rb +1 -1
- data/lib/spree/testing_support/factories/discount_factory.rb +9 -0
- data/lib/spree/testing_support/factories/exchange_factory.rb +50 -0
- data/lib/spree/testing_support/factories/external_reference_factory.rb +8 -0
- data/lib/spree/testing_support/factories/fee_factory.rb +8 -0
- data/lib/spree/testing_support/factories/fulfillment_factory.rb +32 -0
- data/lib/spree/testing_support/factories/fulfillment_item_factory.rb +17 -0
- data/lib/spree/testing_support/factories/gateway_customer_factory.rb +1 -1
- data/lib/spree/testing_support/factories/gift_card_factory.rb +2 -2
- data/lib/spree/testing_support/factories/import_factory.rb +33 -1
- data/lib/spree/testing_support/factories/line_item_factory.rb +10 -5
- data/lib/spree/testing_support/factories/market_factory.rb +5 -12
- data/lib/spree/testing_support/factories/media_factory.rb +36 -0
- data/lib/spree/testing_support/factories/newsletter_subscriber_factory.rb +1 -1
- data/lib/spree/testing_support/factories/number_sequence_factory.rb +7 -0
- data/lib/spree/testing_support/factories/options_factory.rb +5 -5
- data/lib/spree/testing_support/factories/order_factory.rb +39 -23
- data/lib/spree/testing_support/factories/order_group_factory.rb +29 -0
- data/lib/spree/testing_support/factories/package_type_factory.rb +36 -0
- data/lib/spree/testing_support/factories/payment_factory.rb +7 -7
- data/lib/spree/testing_support/factories/payment_method_factory.rb +5 -5
- data/lib/spree/testing_support/factories/payment_session_factory.rb +10 -6
- data/lib/spree/testing_support/factories/payment_setup_session_factory.rb +2 -2
- data/lib/spree/testing_support/factories/payment_split_factory.rb +10 -0
- data/lib/spree/testing_support/factories/price_adjustment_tier_factory.rb +7 -0
- data/lib/spree/testing_support/factories/price_factory.rb +6 -0
- data/lib/spree/testing_support/factories/price_rule_factory.rb +0 -10
- data/lib/spree/testing_support/factories/product_collection_factory.rb +8 -0
- data/lib/spree/testing_support/factories/product_factory.rb +35 -7
- data/lib/spree/testing_support/factories/product_type_custom_field_definition_factory.rb +10 -0
- data/lib/spree/testing_support/factories/product_type_factory.rb +12 -0
- data/lib/spree/testing_support/factories/promotion_factory.rb +4 -0
- data/lib/spree/testing_support/factories/promotion_rule_factory.rb +1 -1
- data/lib/spree/testing_support/factories/purchase_order_factory.rb +49 -0
- data/lib/spree/testing_support/factories/refresh_token_factory.rb +2 -0
- data/lib/spree/testing_support/factories/refund_factory.rb +1 -2
- data/lib/spree/testing_support/factories/return_factory.rb +52 -0
- data/lib/spree/testing_support/factories/return_reason_factory.rb +19 -0
- data/lib/spree/testing_support/factories/role_factory.rb +1 -0
- data/lib/spree/testing_support/factories/saved_report_factory.rb +7 -0
- data/lib/spree/testing_support/factories/seller_factory.rb +34 -0
- data/lib/spree/testing_support/factories/seller_payout_factory.rb +14 -0
- data/lib/spree/testing_support/factories/seller_requirement_factory.rb +61 -0
- data/lib/spree/testing_support/factories/seller_requirement_submission_factory.rb +32 -0
- data/lib/spree/testing_support/factories/seller_transfer_factory.rb +21 -0
- data/lib/spree/testing_support/factories/shipping_label_factory.rb +44 -0
- data/lib/spree/testing_support/factories/state_factory.rb +18 -5
- data/lib/spree/testing_support/factories/stock_level_factory.rb +24 -0
- data/lib/spree/testing_support/factories/stock_location_factory.rb +12 -6
- data/lib/spree/testing_support/factories/stock_movement_factory.rb +20 -3
- data/lib/spree/testing_support/factories/stock_receipt_factory.rb +37 -0
- data/lib/spree/testing_support/factories/stock_reservation_factory.rb +11 -8
- data/lib/spree/testing_support/factories/stock_transfer_factory.rb +53 -6
- data/lib/spree/testing_support/factories/store_credit_factory.rb +1 -3
- data/lib/spree/testing_support/factories/supplier_factory.rb +17 -0
- data/lib/spree/testing_support/factories/tax_exemption_certificate_factory.rb +18 -0
- data/lib/spree/testing_support/factories/tax_identifier_factory.rb +33 -0
- data/lib/spree/testing_support/factories/tax_line_factory.rb +19 -0
- data/lib/spree/testing_support/factories/tax_rate_factory.rb +5 -2
- data/lib/spree/testing_support/factories/taxon_factory.rb +6 -23
- data/lib/spree/testing_support/factories/taxonomy_factory.rb +8 -0
- data/lib/spree/testing_support/factories/user_factory.rb +8 -13
- data/lib/spree/testing_support/factories/variant_factory.rb +1 -1
- data/lib/spree/testing_support/factories/wishlist_factory.rb +1 -1
- data/lib/spree/testing_support/factories/wishlist_item_factory.rb +10 -0
- data/lib/spree/testing_support/factories/zone_factory.rb +2 -25
- data/lib/spree/testing_support/factories/zone_member_factory.rb +2 -1
- data/lib/spree/testing_support/factories.rb +1 -6
- data/lib/spree/testing_support/imports.rb +16 -0
- data/lib/spree/testing_support/label_provider.rb +49 -0
- data/lib/spree/testing_support/lifecycle_events.rb +6 -1
- data/lib/spree/testing_support/metadata.rb +38 -36
- data/lib/spree/testing_support/order_walkthrough.rb +46 -36
- data/lib/spree/testing_support/preferences.rb +39 -0
- data/lib/spree/testing_support/purchase_order.rb +111 -0
- data/lib/spree/testing_support/store.rb +6 -2
- data/lib/spree/testing_support/tax_identifier_validators.rb +68 -0
- data/lib/spree/translations.rb +139 -5
- data/lib/spree/upgrades/5_4_to_5_5/manifest.yml +1 -1
- data/lib/spree/upgrades/5_5_to_5_6/manifest.yml +17 -9
- data/lib/spree/upgrades/5_6_to_6_0/manifest.yml +683 -0
- data/lib/spree/validators.rb +74 -0
- data/lib/spree/workflow.rb +335 -0
- data/lib/tasks/backfill_actor_types.rake +35 -0
- data/lib/tasks/backfill_custom_field_definition_stores.rake +82 -0
- data/lib/tasks/backfill_import_export_tenancy.rake +93 -0
- data/lib/tasks/backfill_library_media_placements.rake +29 -0
- data/lib/tasks/backfill_media_store_ids.rake +70 -0
- data/lib/tasks/backfill_reason_store_ids.rake +28 -0
- data/lib/tasks/capture_methods_migration.rake +30 -0
- data/lib/tasks/carts_migration.rake +113 -0
- data/lib/tasks/categories_and_collections.rake +188 -0
- data/lib/tasks/cli.rake +22 -3
- data/lib/tasks/consolidate_metadata.rake +73 -0
- data/lib/tasks/core.rake +1 -11
- data/lib/tasks/deliveries_migration.rake +52 -0
- data/lib/tasks/delivery_method_rules_migration.rake +51 -0
- data/lib/tasks/delivery_migration.rake +213 -0
- data/lib/tasks/delivery_profiles_migration.rake +109 -0
- data/lib/tasks/fold_store_credit_categories.rake +40 -0
- data/lib/tasks/fulfillment_statuses_migration.rake +59 -0
- data/lib/tasks/inventory_operations_migration.rake +223 -0
- data/lib/tasks/markets.rake +7 -2
- data/lib/tasks/media.rake +2 -2
- data/lib/tasks/media_class_rename.rake +56 -0
- data/lib/tasks/migrate_country_state_codes.rake +228 -0
- data/lib/tasks/migrate_promotion_option_value_rules.rake +124 -0
- data/lib/tasks/migrate_returns.rake +322 -0
- data/lib/tasks/migrate_rich_text_to_columns.rake +128 -0
- data/lib/tasks/migrate_users_to_customers.rake +161 -0
- data/lib/tasks/order_coupon_code_backfill.rake +32 -0
- data/lib/tasks/order_market_backfill.rake +27 -0
- data/lib/tasks/package_types.rake +62 -0
- data/lib/tasks/price_history.rake +49 -6
- data/lib/tasks/products.rake +21 -2
- data/lib/tasks/remove_master_variant.rake +58 -0
- data/lib/tasks/rich_text.rake +44 -0
- data/lib/tasks/seller_sample_data.rake +142 -0
- data/lib/tasks/setup.rake +18 -0
- data/lib/tasks/single_store_associations.rake +11 -0
- data/lib/tasks/stock.rake +15 -0
- data/lib/tasks/store_binding_migration.rake +33 -0
- data/lib/tasks/store_settings.rake +105 -0
- data/lib/tasks/tax_zones_migration.rake +147 -0
- data/lib/tasks/taxons.rake +9 -10
- data/lib/tasks/typed_adjustments_migration.rake +189 -0
- data/lib/tasks/typed_stock_movements_migration.rake +250 -0
- data/lib/tasks/upgrade.rake +13 -8
- data/spec/fixtures/files/eu_vat_numbers.txt +56 -0
- data/spec/fixtures/files/price_list_prices_import.csv +4 -0
- data/spec/fixtures/files/products_import.csv +1 -1
- data/spec/fixtures/tiny-video.mp4 +0 -0
- metadata +798 -546
- data/app/assets/config/spree_core_manifest.js +0 -4
- data/app/assets/images/google_on_white_hdpi.png +0 -0
- data/app/assets/images/logo.png +0 -0
- data/app/assets/images/payment_icons/ach.svg +0 -1
- data/app/assets/images/payment_icons/achdirectdebit.svg +0 -1
- data/app/assets/images/payment_icons/ada.svg +0 -1
- data/app/assets/images/payment_icons/adyen.svg +0 -1
- data/app/assets/images/payment_icons/affinbank.svg +0 -1
- data/app/assets/images/payment_icons/affirm.svg +0 -1
- data/app/assets/images/payment_icons/afterpay.svg +0 -1
- data/app/assets/images/payment_icons/airtel_money.svg +0 -1
- data/app/assets/images/payment_icons/airteltigo_mobile_money.svg +0 -1
- data/app/assets/images/payment_icons/alandsbanken.svg +0 -1
- data/app/assets/images/payment_icons/alipay.svg +0 -1
- data/app/assets/images/payment_icons/alipay_hk.svg +0 -1
- data/app/assets/images/payment_icons/alliancebank.svg +0 -1
- data/app/assets/images/payment_icons/alma.svg +0 -1
- data/app/assets/images/payment_icons/amazon.svg +0 -1
- data/app/assets/images/payment_icons/ambank.svg +0 -1
- data/app/assets/images/payment_icons/american_express.svg +0 -1
- data/app/assets/images/payment_icons/apecoin.svg +0 -1
- data/app/assets/images/payment_icons/apple_pay.svg +0 -1
- data/app/assets/images/payment_icons/arbitrum.svg +0 -1
- data/app/assets/images/payment_icons/atome.svg +0 -1
- data/app/assets/images/payment_icons/authorizenet.svg +0 -1
- data/app/assets/images/payment_icons/avalanche.svg +0 -1
- data/app/assets/images/payment_icons/bacs.svg +0 -1
- data/app/assets/images/payment_icons/bancontact.svg +0 -1
- data/app/assets/images/payment_icons/bangkokbank.svg +0 -1
- data/app/assets/images/payment_icons/bankislam.svg +0 -1
- data/app/assets/images/payment_icons/bankmuamalat.svg +0 -1
- data/app/assets/images/payment_icons/bankofamerica.svg +0 -1
- data/app/assets/images/payment_icons/bankrakyat.svg +0 -1
- data/app/assets/images/payment_icons/banktransfer.svg +0 -1
- data/app/assets/images/payment_icons/base.svg +0 -1
- data/app/assets/images/payment_icons/becs.svg +0 -1
- data/app/assets/images/payment_icons/benefit.svg +0 -1
- data/app/assets/images/payment_icons/billie.svg +0 -1
- data/app/assets/images/payment_icons/bitcoin.svg +0 -1
- data/app/assets/images/payment_icons/bitcoin_cash.svg +0 -1
- data/app/assets/images/payment_icons/bizum.svg +0 -1
- data/app/assets/images/payment_icons/blik.svg +0 -1
- data/app/assets/images/payment_icons/bnbchain.svg +0 -1
- data/app/assets/images/payment_icons/bogus.svg +0 -1
- data/app/assets/images/payment_icons/bogus_app_coin.svg +0 -1
- data/app/assets/images/payment_icons/boleto.svg +0 -1
- data/app/assets/images/payment_icons/boost.svg +0 -1
- data/app/assets/images/payment_icons/braintree.svg +0 -1
- data/app/assets/images/payment_icons/buckaroopaybybank.svg +0 -1
- data/app/assets/images/payment_icons/busd.svg +0 -1
- data/app/assets/images/payment_icons/cartes_bancaires.svg +0 -1
- data/app/assets/images/payment_icons/cash.svg +0 -1
- data/app/assets/images/payment_icons/cashappafterpay.svg +0 -1
- data/app/assets/images/payment_icons/cashapppay.svg +0 -1
- data/app/assets/images/payment_icons/checkout_finance.svg +0 -1
- data/app/assets/images/payment_icons/chinabank.svg +0 -1
- data/app/assets/images/payment_icons/clearpay.svg +0 -1
- data/app/assets/images/payment_icons/collector_bank.svg +0 -1
- data/app/assets/images/payment_icons/dai.svg +0 -1
- data/app/assets/images/payment_icons/dana.svg +0 -1
- data/app/assets/images/payment_icons/dankort.svg +0 -1
- data/app/assets/images/payment_icons/danske_bank.svg +0 -1
- data/app/assets/images/payment_icons/deutschebank.svg +0 -1
- data/app/assets/images/payment_icons/diners_club.svg +0 -1
- data/app/assets/images/payment_icons/directbanktransferlatinamerica.svg +0 -1
- data/app/assets/images/payment_icons/discover.svg +0 -1
- data/app/assets/images/payment_icons/dogecoin.svg +0 -1
- data/app/assets/images/payment_icons/duitnow.svg +0 -1
- data/app/assets/images/payment_icons/eft_secure.svg +0 -1
- data/app/assets/images/payment_icons/eftpos_au.svg +0 -1
- data/app/assets/images/payment_icons/eftposau.svg +0 -1
- data/app/assets/images/payment_icons/elo.svg +0 -1
- data/app/assets/images/payment_icons/eos.svg +0 -1
- data/app/assets/images/payment_icons/eps.svg +0 -1
- data/app/assets/images/payment_icons/ethereum.svg +0 -1
- data/app/assets/images/payment_icons/eurobonuscheckout.svg +0 -1
- data/app/assets/images/payment_icons/ezcash.svg +0 -1
- data/app/assets/images/payment_icons/fantom.svg +0 -1
- data/app/assets/images/payment_icons/fpx.svg +0 -1
- data/app/assets/images/payment_icons/gcash.svg +0 -1
- data/app/assets/images/payment_icons/generic.svg +0 -1
- data/app/assets/images/payment_icons/genericbank.svg +0 -1
- data/app/assets/images/payment_icons/gift-card.svg +0 -1
- data/app/assets/images/payment_icons/giropay.svg +0 -1
- data/app/assets/images/payment_icons/glbepaypal.svg +0 -1
- data/app/assets/images/payment_icons/gmobanktransfer.svg +0 -1
- data/app/assets/images/payment_icons/gnosis.svg +0 -1
- data/app/assets/images/payment_icons/google_pay.svg +0 -1
- data/app/assets/images/payment_icons/google_wallet.svg +0 -1
- data/app/assets/images/payment_icons/gopay.svg +0 -1
- data/app/assets/images/payment_icons/grabpay.svg +0 -1
- data/app/assets/images/payment_icons/gusd.svg +0 -1
- data/app/assets/images/payment_icons/handelsbanken.svg +0 -1
- data/app/assets/images/payment_icons/hongleongbank.svg +0 -1
- data/app/assets/images/payment_icons/hypercard.svg +0 -1
- data/app/assets/images/payment_icons/hypercash.svg +0 -1
- data/app/assets/images/payment_icons/ideal.svg +0 -1
- data/app/assets/images/payment_icons/in3viaideal.svg +0 -1
- data/app/assets/images/payment_icons/inbank.svg +0 -1
- data/app/assets/images/payment_icons/jcb.svg +0 -1
- data/app/assets/images/payment_icons/kakao_pay.svg +0 -1
- data/app/assets/images/payment_icons/kasikornbank.svg +0 -1
- data/app/assets/images/payment_icons/klarna-pay-later.svg +0 -1
- data/app/assets/images/payment_icons/klarna-pay-now.svg +0 -1
- data/app/assets/images/payment_icons/klarna-slice-it.svg +0 -1
- data/app/assets/images/payment_icons/klarna.svg +0 -1
- data/app/assets/images/payment_icons/knet.svg +0 -1
- data/app/assets/images/payment_icons/krungthaibank.svg +0 -1
- data/app/assets/images/payment_icons/landbank.svg +0 -1
- data/app/assets/images/payment_icons/laybuybyklarna.svg +0 -1
- data/app/assets/images/payment_icons/litecoin.svg +0 -1
- data/app/assets/images/payment_icons/lunchcheck.svg +0 -1
- data/app/assets/images/payment_icons/mach.svg +0 -1
- data/app/assets/images/payment_icons/mada.svg +0 -1
- data/app/assets/images/payment_icons/maestro.svg +0 -1
- data/app/assets/images/payment_icons/master.svg +0 -1
- data/app/assets/images/payment_icons/mayabank.svg +0 -1
- data/app/assets/images/payment_icons/maybank.svg +0 -1
- data/app/assets/images/payment_icons/maybankm2u.svg +0 -1
- data/app/assets/images/payment_icons/maybankqrpay.svg +0 -1
- data/app/assets/images/payment_icons/mbway.svg +0 -1
- data/app/assets/images/payment_icons/mcash.svg +0 -1
- data/app/assets/images/payment_icons/medicinosbankas.svg +0 -1
- data/app/assets/images/payment_icons/mercadopago.svg +0 -1
- data/app/assets/images/payment_icons/metrobank.svg +0 -1
- data/app/assets/images/payment_icons/mobilepay.svg +0 -1
- data/app/assets/images/payment_icons/momopay.svg +0 -1
- data/app/assets/images/payment_icons/monero.svg +0 -1
- data/app/assets/images/payment_icons/mtn_mobile_money.svg +0 -1
- data/app/assets/images/payment_icons/mybank.svg +0 -1
- data/app/assets/images/payment_icons/naver_pay.svg +0 -1
- data/app/assets/images/payment_icons/nelo.svg +0 -1
- data/app/assets/images/payment_icons/netbanking.svg +0 -1
- data/app/assets/images/payment_icons/novalnetdirectdebitach.svg +0 -1
- data/app/assets/images/payment_icons/nubank.svg +0 -1
- data/app/assets/images/payment_icons/ocbcbank.svg +0 -1
- data/app/assets/images/payment_icons/offlinebanktransferlatinamerica.svg +0 -1
- data/app/assets/images/payment_icons/ola_money.svg +0 -1
- data/app/assets/images/payment_icons/oney.svg +0 -1
- data/app/assets/images/payment_icons/onlinebanking.svg +0 -1
- data/app/assets/images/payment_icons/onlinebanktransfer.svg +0 -1
- data/app/assets/images/payment_icons/orangemobilemoney.svg +0 -1
- data/app/assets/images/payment_icons/otpbank.svg +0 -1
- data/app/assets/images/payment_icons/oxxo.svg +0 -1
- data/app/assets/images/payment_icons/paybybank.svg +0 -1
- data/app/assets/images/payment_icons/paybybankmollie.svg +0 -1
- data/app/assets/images/payment_icons/paybybankus.svg +0 -1
- data/app/assets/images/payment_icons/paycash.svg +0 -1
- data/app/assets/images/payment_icons/payco.svg +0 -1
- data/app/assets/images/payment_icons/payeverpaybybank.svg +0 -1
- data/app/assets/images/payment_icons/payme.svg +0 -1
- data/app/assets/images/payment_icons/paynow.svg +0 -1
- data/app/assets/images/payment_icons/paynowmbank.svg +0 -1
- data/app/assets/images/payment_icons/paypal.svg +0 -1
- data/app/assets/images/payment_icons/paypo.svg +0 -1
- data/app/assets/images/payment_icons/payrexxbanktransfer.svg +0 -1
- data/app/assets/images/payment_icons/payrexxpaybybank.svg +0 -1
- data/app/assets/images/payment_icons/paysafecash.svg +0 -1
- data/app/assets/images/payment_icons/pix.svg +0 -1
- data/app/assets/images/payment_icons/polygon.svg +0 -1
- data/app/assets/images/payment_icons/przelewy24.svg +0 -1
- data/app/assets/images/payment_icons/publicbank.svg +0 -1
- data/app/assets/images/payment_icons/publicbank_pbe.svg +0 -1
- data/app/assets/images/payment_icons/qr_promptpay.svg +0 -1
- data/app/assets/images/payment_icons/rabobank.svg +0 -1
- data/app/assets/images/payment_icons/revolut.svg +0 -1
- data/app/assets/images/payment_icons/rhbbank.svg +0 -1
- data/app/assets/images/payment_icons/riverty.svg +0 -1
- data/app/assets/images/payment_icons/safetypaybanktransfer.svg +0 -1
- data/app/assets/images/payment_icons/samsung_pay.svg +0 -1
- data/app/assets/images/payment_icons/satispay.svg +0 -1
- data/app/assets/images/payment_icons/scalapay.svg +0 -1
- data/app/assets/images/payment_icons/scotiabank.svg +0 -1
- data/app/assets/images/payment_icons/seabankid.svg +0 -1
- data/app/assets/images/payment_icons/seabankph.svg +0 -1
- data/app/assets/images/payment_icons/sepa_bank_transfer.svg +0 -1
- data/app/assets/images/payment_icons/sepadebit.svg +0 -22
- data/app/assets/images/payment_icons/sepadirectdebit.svg +0 -1
- data/app/assets/images/payment_icons/seveneleven.svg +0 -1
- data/app/assets/images/payment_icons/shib.svg +0 -1
- data/app/assets/images/payment_icons/shopcash.svg +0 -1
- data/app/assets/images/payment_icons/siauliubankas.svg +0 -1
- data/app/assets/images/payment_icons/skeps.svg +0 -1
- data/app/assets/images/payment_icons/snap_checkout.svg +0 -1
- data/app/assets/images/payment_icons/sofort.svg +0 -1
- data/app/assets/images/payment_icons/softbank.svg +0 -1
- data/app/assets/images/payment_icons/spei.svg +0 -1
- data/app/assets/images/payment_icons/storecredit.svg +0 -1
- data/app/assets/images/payment_icons/stripe.svg +0 -1
- data/app/assets/images/payment_icons/sveacheckout.svg +0 -1
- data/app/assets/images/payment_icons/swedbank.svg +0 -1
- data/app/assets/images/payment_icons/swish.svg +0 -1
- data/app/assets/images/payment_icons/tbibank.svg +0 -1
- data/app/assets/images/payment_icons/thanachartbank.svg +0 -1
- data/app/assets/images/payment_icons/tnmmoney.svg +0 -1
- data/app/assets/images/payment_icons/touchngo.svg +0 -1
- data/app/assets/images/payment_icons/trustly.svg +0 -1
- data/app/assets/images/payment_icons/twint.svg +0 -1
- data/app/assets/images/payment_icons/uaevisa.svg +0 -1
- data/app/assets/images/payment_icons/unionpay.svg +0 -1
- data/app/assets/images/payment_icons/unzerbanktransfer.svg +0 -1
- data/app/assets/images/payment_icons/upi.svg +0 -1
- data/app/assets/images/payment_icons/usbank.svg +0 -1
- data/app/assets/images/payment_icons/usdc.svg +0 -1
- data/app/assets/images/payment_icons/usdt.svg +0 -1
- data/app/assets/images/payment_icons/venmo.svg +0 -1
- data/app/assets/images/payment_icons/vipps.svg +0 -1
- data/app/assets/images/payment_icons/visa.svg +0 -1
- data/app/assets/images/payment_icons/volksbank.svg +0 -1
- data/app/assets/images/payment_icons/waavepaybybank.svg +0 -1
- data/app/assets/images/payment_icons/walley.svg +0 -1
- data/app/assets/images/payment_icons/wbtc.svg +0 -1
- data/app/assets/images/payment_icons/wechatpay.svg +0 -1
- data/app/assets/images/payment_icons/whishcheckout.svg +0 -1
- data/app/assets/images/payment_icons/wingbank.svg +0 -1
- data/app/assets/images/payment_icons/xrp.svg +0 -1
- data/app/assets/images/payment_icons/zip.svg +0 -1
- data/app/controllers/spree/base_controller.rb +0 -11
- data/app/finders/concerns/spree/product_filterable.rb +0 -9
- data/app/finders/spree/addresses/find.rb +0 -27
- data/app/finders/spree/base_finder.rb +0 -14
- data/app/finders/spree/countries/find.rb +0 -31
- data/app/finders/spree/credit_cards/find.rb +0 -12
- data/app/finders/spree/option_values/find_available.rb +0 -28
- data/app/finders/spree/orders/find_complete.rb +0 -114
- data/app/finders/spree/orders/find_current.rb +0 -24
- data/app/finders/spree/orders/finder_helper.rb +0 -17
- data/app/finders/spree/products/find.rb +0 -328
- data/app/finders/spree/taxons/find.rb +0 -99
- data/app/finders/spree/variants/find.rb +0 -30
- data/app/finders/spree/variants/option_types_finder.rb +0 -21
- data/app/helpers/spree/addresses_helper.rb +0 -97
- data/app/helpers/spree/base_helper.rb +0 -132
- data/app/helpers/spree/currency_helper.rb +0 -46
- data/app/helpers/spree/integrations_helper.rb +0 -15
- data/app/helpers/spree/locale_helper.rb +0 -44
- data/app/helpers/spree/localized_names_helper.rb +0 -25
- data/app/helpers/spree/products_helper.rb +0 -147
- data/app/helpers/spree/shipment_helper.rb +0 -12
- data/app/javascript/spree/core/controllers/address_autocomplete_controller.js +0 -230
- data/app/javascript/spree/core/controllers/address_form_controller.js +0 -98
- data/app/javascript/spree/core/controllers/disable_submit_button_controller.js +0 -19
- data/app/javascript/spree/core/controllers/enable_button_controller.js +0 -29
- data/app/javascript/spree/core/helpers/address_autocomplete/google_places_suggestions_provider.js +0 -161
- data/app/javascript/spree/core/helpers/debounce.js +0 -9
- data/app/javascript/spree/core/helpers/scroll_lock.js +0 -25
- data/app/jobs/spree/media/migrate_product_assets_job.rb +0 -83
- data/app/jobs/spree/reports/generate_job.rb +0 -23
- data/app/mailers/spree/report_mailer.rb +0 -20
- data/app/models/concerns/spree/adjustment_source.rb +0 -58
- data/app/models/concerns/spree/default_price.rb +0 -138
- data/app/models/concerns/spree/display_on.rb +0 -50
- data/app/models/concerns/spree/image_methods.rb +0 -40
- data/app/models/concerns/spree/legacy_multi_store_support.rb +0 -48
- data/app/models/concerns/spree/metafield_filterable.rb +0 -162
- data/app/models/concerns/spree/metafields.rb +0 -256
- data/app/models/concerns/spree/number_as_param.rb +0 -13
- data/app/models/concerns/spree/store_scoped_resource.rb +0 -37
- data/app/models/concerns/spree/unique_name.rb +0 -12
- data/app/models/spree/adjustable/adjuster/base.rb +0 -25
- data/app/models/spree/adjustable/adjuster/promotion.rb +0 -41
- data/app/models/spree/adjustable/adjuster/tax.rb +0 -26
- data/app/models/spree/adjustable/adjustments_updater.rb +0 -74
- data/app/models/spree/adjustable/promotion_accumulator.rb +0 -78
- data/app/models/spree/adjustment.rb +0 -130
- data/app/models/spree/asset/support/active_storage.rb +0 -26
- data/app/models/spree/calculator/default_tax.rb +0 -87
- data/app/models/spree/calculator/returns/default_refund_amount.rb +0 -40
- data/app/models/spree/checkout/default_requirements.rb +0 -51
- data/app/models/spree/checkout/registry.rb +0 -112
- data/app/models/spree/checkout/requirement.rb +0 -49
- data/app/models/spree/checkout/requirements.rb +0 -56
- data/app/models/spree/checkout/step.rb +0 -52
- data/app/models/spree/customer_return.rb +0 -94
- data/app/models/spree/image/configuration/active_storage.rb +0 -11
- data/app/models/spree/image.rb +0 -6
- data/app/models/spree/legacy_admin_user.rb +0 -31
- data/app/models/spree/legacy_user.rb +0 -33
- data/app/models/spree/log_entry.rb +0 -30
- data/app/models/spree/metafield_definition/search_capabilities.rb +0 -104
- data/app/models/spree/metafields/boolean.rb +0 -15
- data/app/models/spree/metafields/json.rb +0 -37
- data/app/models/spree/metafields/long_text.rb +0 -11
- data/app/models/spree/metafields/number.rb +0 -23
- data/app/models/spree/metafields/rich_text.rb +0 -18
- data/app/models/spree/metafields/short_text.rb +0 -15
- data/app/models/spree/option_type_prototype.rb +0 -9
- data/app/models/spree/order/address_book.rb +0 -100
- data/app/models/spree/order/checkout.rb +0 -350
- data/app/models/spree/order/currency_updater.rb +0 -37
- data/app/models/spree/order/digital.rb +0 -60
- data/app/models/spree/order/gift_card.rb +0 -71
- data/app/models/spree/order/payments.rb +0 -64
- data/app/models/spree/order/store_credit.rb +0 -110
- data/app/models/spree/order/webhooks.rb +0 -19
- data/app/models/spree/order_approval.rb +0 -19
- data/app/models/spree/order_cancellation.rb +0 -19
- data/app/models/spree/order_contents.rb +0 -31
- data/app/models/spree/order_routing/strategy/legacy.rb +0 -33
- data/app/models/spree/payment/webhooks.rb +0 -15
- data/app/models/spree/permission_sets/base.rb +0 -81
- data/app/models/spree/permission_sets/configuration_management.rb +0 -64
- data/app/models/spree/permission_sets/dashboard_display.rb +0 -17
- data/app/models/spree/permission_sets/default_customer.rb +0 -83
- data/app/models/spree/permission_sets/order_display.rb +0 -27
- data/app/models/spree/permission_sets/order_management.rb +0 -33
- data/app/models/spree/permission_sets/product_display.rb +0 -27
- data/app/models/spree/permission_sets/product_management.rb +0 -28
- data/app/models/spree/permission_sets/promotion_management.rb +0 -22
- data/app/models/spree/permission_sets/role_management.rb +0 -21
- data/app/models/spree/permission_sets/stock_display.rb +0 -19
- data/app/models/spree/permission_sets/stock_management.rb +0 -19
- data/app/models/spree/permission_sets/super_user.rb +0 -28
- data/app/models/spree/permission_sets/user_display.rb +0 -19
- data/app/models/spree/permission_sets/user_management.rb +0 -20
- data/app/models/spree/product/webhooks.rb +0 -17
- data/app/models/spree/prototype_taxon.rb +0 -9
- data/app/models/spree/reimbursement/credit.rb +0 -27
- data/app/models/spree/reimbursement/reimbursement_type_engine.rb +0 -44
- data/app/models/spree/reimbursement/reimbursement_type_validator.rb +0 -15
- data/app/models/spree/reimbursement.rb +0 -167
- data/app/models/spree/reimbursement_performer.rb +0 -34
- data/app/models/spree/reimbursement_tax_calculator.rb +0 -37
- data/app/models/spree/reimbursement_type/credit.rb +0 -13
- data/app/models/spree/reimbursement_type/exchange.rb +0 -9
- data/app/models/spree/reimbursement_type/original_payment.rb +0 -13
- data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +0 -64
- data/app/models/spree/reimbursement_type/store_credit.rb +0 -20
- data/app/models/spree/reimbursement_type.rb +0 -22
- data/app/models/spree/report.rb +0 -140
- data/app/models/spree/report_line_item.rb +0 -27
- data/app/models/spree/report_line_items/products_performance.rb +0 -76
- data/app/models/spree/report_line_items/sales_total.rb +0 -49
- data/app/models/spree/reports/products_performance.rb +0 -44
- data/app/models/spree/reports/sales_total.rb +0 -18
- data/app/models/spree/return_authorization.rb +0 -109
- data/app/models/spree/return_item/eligibility_validator/base_validator.rb +0 -24
- data/app/models/spree/return_item/eligibility_validator/default.rb +0 -30
- data/app/models/spree/return_item/eligibility_validator/inventory_shipped.rb +0 -16
- data/app/models/spree/return_item/eligibility_validator/no_reimbursements.rb +0 -16
- data/app/models/spree/return_item/eligibility_validator/order_completed.rb +0 -16
- data/app/models/spree/return_item/eligibility_validator/rma_required.rb +0 -16
- data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +0 -16
- data/app/models/spree/return_item/exchange_variant_eligibility/same_option_value.rb +0 -34
- data/app/models/spree/return_item/exchange_variant_eligibility/same_product.rb +0 -9
- data/app/models/spree/return_item.rb +0 -287
- data/app/models/spree/returns_calculator.rb +0 -7
- data/app/models/spree/search_provider/meilisearch.rb +0 -551
- data/app/models/spree/shipment/custom_events.rb +0 -47
- data/app/models/spree/shipment/webhooks.rb +0 -11
- data/app/models/spree/shipment_handler.rb +0 -38
- data/app/models/spree/shipping_category.rb +0 -25
- data/app/models/spree/shipping_method_category.rb +0 -8
- data/app/models/spree/shipping_method_zone.rb +0 -8
- data/app/models/spree/state_change.rb +0 -12
- data/app/models/spree/stock/splitter/digital.rb +0 -35
- data/app/models/spree/stock/splitter/shipping_category.rb +0 -31
- data/app/models/spree/stock_item/webhooks.rb +0 -6
- data/app/models/spree/stock_movement/webhooks.rb +0 -6
- data/app/models/spree/variant/webhooks.rb +0 -6
- data/app/presenters/spree/csv/metafields_helper.rb +0 -17
- data/app/presenters/spree/search_provider/product_presenter.rb +0 -158
- data/app/presenters/spree/variant_presenter.rb +0 -81
- data/app/presenters/spree/variants/option_types_presenter.rb +0 -87
- data/app/services/spree/account/addresses/create.rb +0 -8
- data/app/services/spree/account/addresses/update.rb +0 -8
- data/app/services/spree/account/create.rb +0 -17
- data/app/services/spree/account/update.rb +0 -15
- data/app/services/spree/cart/add_item.rb +0 -63
- data/app/services/spree/cart/associate.rb +0 -29
- data/app/services/spree/cart/change_currency.rb +0 -27
- data/app/services/spree/cart/create.rb +0 -26
- data/app/services/spree/cart/destroy.rb +0 -50
- data/app/services/spree/cart/empty.rb +0 -38
- data/app/services/spree/cart/estimate_shipping_rates.rb +0 -39
- data/app/services/spree/cart/recalculate.rb +0 -35
- data/app/services/spree/cart/remove_item.rb +0 -39
- data/app/services/spree/cart/remove_line_item.rb +0 -28
- data/app/services/spree/cart/remove_out_of_stock_items.rb +0 -65
- data/app/services/spree/cart/set_quantity.rb +0 -32
- data/app/services/spree/cart/update.rb +0 -37
- data/app/services/spree/carts/complete.rb +0 -50
- data/app/services/spree/carts/upsert_items.rb +0 -76
- data/app/services/spree/checkout/complete.rb +0 -23
- data/app/services/spree/checkout/get_shipping_rates.rb +0 -52
- data/app/services/spree/checkout/next.rb +0 -13
- data/app/services/spree/checkout/select_shipping_method.rb +0 -63
- data/app/services/spree/checkout/update.rb +0 -72
- data/app/services/spree/credit_cards/destroy.rb +0 -25
- data/app/services/spree/fulfillments/create.rb +0 -259
- data/app/services/spree/gift_cards/apply.rb +0 -78
- data/app/services/spree/gift_cards/redeem.rb +0 -17
- data/app/services/spree/gift_cards/remove.rb +0 -39
- data/app/services/spree/line_items/create.rb +0 -20
- data/app/services/spree/line_items/destroy.rb +0 -18
- data/app/services/spree/line_items/helper.rb +0 -11
- data/app/services/spree/line_items/update.rb +0 -17
- data/app/services/spree/orders/build_shipments.rb +0 -29
- data/app/services/spree/orders/cancel.rb +0 -54
- data/app/services/spree/orders/complete.rb +0 -53
- data/app/services/spree/orders/update_contact_information.rb +0 -19
- data/app/services/spree/orders/upsert_items.rb +0 -70
- data/app/services/spree/payments/handle_webhook.rb +0 -57
- data/app/services/spree/search_provider/metafield_schema.rb +0 -144
- data/app/services/spree/seeds/countries.rb +0 -35
- data/app/services/spree/seeds/default_reimbursement_types.rb +0 -12
- data/app/services/spree/seeds/shipping_categories.rb +0 -12
- data/app/services/spree/seeds/states.rb +0 -82
- data/app/services/spree/seeds/stock_locations.rb +0 -18
- data/app/services/spree/seeds/store_credit_categories.rb +0 -14
- data/app/services/spree/seeds/zones.rb +0 -52
- data/app/services/spree/shipments/add_item.rb +0 -32
- data/app/services/spree/shipments/change_state.rb +0 -14
- data/app/services/spree/shipments/create.rb +0 -48
- data/app/services/spree/shipments/helper.rb +0 -23
- data/app/services/spree/shipments/remove_item.rb +0 -55
- data/app/services/spree/stores/settings_defaults_by_country.rb +0 -38
- data/app/services/spree/themes/duplicator.rb +0 -40
- data/app/sorters/spree/base_sorter.rb +0 -47
- data/app/sorters/spree/classifications/sort.rb +0 -68
- data/app/sorters/spree/products/sort.rb +0 -73
- data/app/subscribers/spree/report_subscriber.rb +0 -26
- data/app/views/spree/addresses/_form.html.erb +0 -59
- data/app/views/spree/addresses/_suggestions_box.erb +0 -14
- data/app/views/spree/admin_user_mailer/confirmation_email.html.erb +0 -7
- data/app/views/spree/report_mailer/report_done.html.erb +0 -7
- data/app/views/spree/shared/_google_places_api_loader.html.erb +0 -7
- data/app/views/spree/shared/_mailer_line_item.html.erb +0 -12
- data/app/views/spree/shared/_payment.html.erb +0 -52
- data/config/importmap.rb +0 -15
- data/config/initializers/carmen.rb +0 -23
- data/config/initializers/rails61_fixes.rb +0 -1
- data/db/migrate/20250120152208_add_default_locale_to_action_text_rich_texts.rb +0 -7
- data/db/migrate/20250122113708_add_first_and_last_name_to_spree_admin_class.rb +0 -9
- data/db/migrate/20250204162453_create_spree_reports.rb +0 -13
- data/db/migrate/20250217171018_create_action_text_video_embeds.rb +0 -11
- data/db/migrate/20250508060800_add_selected_locale_to_spree_admin_users.rb +0 -8
- data/db/migrate/20260429000001_create_spree_order_cancellations.rb +0 -25
- data/db/migrate/20260429000002_create_spree_order_approvals.rb +0 -22
- data/db/sample_data/markets.rb +0 -64
- data/db/sample_data/metafield_definitions.rb +0 -7
- data/db/sample_data/shipping_methods.rb +0 -61
- data/lib/generators/spree/authentication/custom/custom_generator.rb +0 -49
- data/lib/generators/spree/authentication/custom/templates/authentication_helpers.rb.tt +0 -50
- data/lib/generators/spree/authentication/devise/devise_generator.rb +0 -84
- data/lib/generators/spree/authentication/devise/templates/authentication_helpers.rb.tt +0 -50
- data/lib/generators/spree/dummy/templates/app/assets/config/manifest.js +0 -0
- data/lib/spree/core/components.rb +0 -31
- data/lib/spree/core/controller_helpers/auth.rb +0 -52
- data/lib/spree/core/controller_helpers/currency.rb +0 -59
- data/lib/spree/core/controller_helpers/locale.rb +0 -99
- data/lib/spree/core/controller_helpers/order.rb +0 -172
- data/lib/spree/core/controller_helpers/strong_parameters.rb +0 -48
- data/lib/spree/core/controller_helpers/turbo.rb +0 -19
- data/lib/spree/core/partials.rb +0 -42
- data/lib/spree/core/previews/report_preview.rb +0 -40
- data/lib/spree/permitted_attributes.rb +0 -337
- data/lib/spree/testing_support/authorization_helpers.rb +0 -72
- data/lib/spree/testing_support/caching.rb +0 -47
- data/lib/spree/testing_support/capybara_config.rb +0 -45
- data/lib/spree/testing_support/capybara_ext.rb +0 -83
- data/lib/spree/testing_support/controller_requests.rb +0 -11
- data/lib/spree/testing_support/factories/adjustment_factory.rb +0 -28
- data/lib/spree/testing_support/factories/asset_factory.rb +0 -12
- data/lib/spree/testing_support/factories/customer_return_factory.rb +0 -36
- data/lib/spree/testing_support/factories/digital_factory.rb +0 -10
- data/lib/spree/testing_support/factories/image_factory.rb +0 -11
- data/lib/spree/testing_support/factories/inventory_unit_factory.rb +0 -18
- data/lib/spree/testing_support/factories/log_entry_factory.rb +0 -6
- data/lib/spree/testing_support/factories/metafield_definition_factory.rb +0 -82
- data/lib/spree/testing_support/factories/metafield_factory.rb +0 -68
- data/lib/spree/testing_support/factories/prototype_factory.rb +0 -9
- data/lib/spree/testing_support/factories/reimbursement_credit_factory.rb +0 -7
- data/lib/spree/testing_support/factories/reimbursement_factory.rb +0 -16
- data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +0 -7
- data/lib/spree/testing_support/factories/report_factory.rb +0 -33
- data/lib/spree/testing_support/factories/return_authorization_factory.rb +0 -21
- data/lib/spree/testing_support/factories/return_item_factory.rb +0 -14
- data/lib/spree/testing_support/factories/shipment_factory.rb +0 -21
- data/lib/spree/testing_support/factories/shipping_category_factory.rb +0 -9
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +0 -31
- data/lib/spree/testing_support/factories/shipping_rate_factory.rb +0 -7
- data/lib/spree/testing_support/factories/state_change_factory.rb +0 -8
- data/lib/spree/testing_support/factories/stock_item_factory.rb +0 -22
- data/lib/spree/testing_support/factories/store_credit_category_factory.rb +0 -9
- data/lib/spree/testing_support/factories/store_credit_type_factory.rb +0 -16
- data/lib/spree/testing_support/factories/wished_variant_factory.rb +0 -6
- data/lib/spree/webhooks.rb +0 -22
- data/lib/tasks/role_users.rake +0 -21
- data/vendor/javascript/@rails--request.js.js +0 -4
- data/vendor/javascript/@stimulus-components--auto-submit.js +0 -4
- data/vendor/javascript/stimulus-reveal-controller.js +0 -4
- data/vendor/javascript/stimulus-textarea-autogrow.js +0 -4
- data/vendor/javascript/tailwindcss-stimulus-components.js +0 -4
|
@@ -0,0 +1,705 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Reporting
|
|
3
|
+
# Core's starter metric/dimension vocabulary. Installed by the engine
|
|
4
|
+
# initializer before app initializers run, so applications and extensions
|
|
5
|
+
# can register their own members (or `replace:` these) in
|
|
6
|
+
# config/initializers.
|
|
7
|
+
#
|
|
8
|
+
# Model classes appear only inside lambdas and %{table} placeholders —
|
|
9
|
+
# nothing here may autoload during initialization.
|
|
10
|
+
module DefaultVocabulary
|
|
11
|
+
# A cart converts when an order was completed from it. Counted as
|
|
12
|
+
# checkouts rather than orders: a basket spanning several sellers becomes
|
|
13
|
+
# several orders from one cart, and that is one conversion.
|
|
14
|
+
# What counts as a real sale, in SQL. Spelled once because copies of it
|
|
15
|
+
# would silently diverge the first time an order gains a status.
|
|
16
|
+
COMPLETED_ORDER = "%{alias}.completed_at IS NOT NULL AND %{alias}.status <> 'canceled'".freeze
|
|
17
|
+
|
|
18
|
+
CART_CONVERTED_CONDITION = <<~SQL.squish.freeze
|
|
19
|
+
EXISTS (SELECT 1 FROM %{orders} o WHERE o.cart_id = %{carts}.id
|
|
20
|
+
AND #{format(COMPLETED_ORDER, alias: 'o')})
|
|
21
|
+
SQL
|
|
22
|
+
|
|
23
|
+
CARTS_CONVERTED_SUM = "SUM(CASE WHEN #{CART_CONVERTED_CONDITION} THEN 1 ELSE 0 END)".freeze
|
|
24
|
+
|
|
25
|
+
# A cart is abandoned when it never completed and has gone quiet for
|
|
26
|
+
# longer than the store's window. `updated_at` is the codebase's own
|
|
27
|
+
# measure of a cart going quiet — Carts::ReapExpiredJob reads the same
|
|
28
|
+
# column, and it is indexed.
|
|
29
|
+
#
|
|
30
|
+
# Deliberately NOT the reaper's population: that job additionally skips
|
|
31
|
+
# carts carrying a live payment session, because it must not destroy
|
|
32
|
+
# rows with money attached. A cart stalled mid-payment is abandoned by
|
|
33
|
+
# any merchant's reading, and it is the most recoverable kind there is.
|
|
34
|
+
#
|
|
35
|
+
# `%{abandoned_cutoff}` is filled in per query from the store's
|
|
36
|
+
# preference, so every cart metric in one report reads one cutoff.
|
|
37
|
+
ABANDONED_CONDITION = <<~SQL.squish.freeze
|
|
38
|
+
%{carts}.completed_at IS NULL AND %{carts}.updated_at < %{abandoned_cutoff}
|
|
39
|
+
SQL
|
|
40
|
+
|
|
41
|
+
ABANDONED_CARTS_SUM = "SUM(CASE WHEN #{ABANDONED_CONDITION} THEN 1 ELSE 0 END)".freeze
|
|
42
|
+
ABANDONED_VALUE_SUM = "SUM(CASE WHEN #{ABANDONED_CONDITION} THEN %{carts}.total ELSE 0 END)".freeze
|
|
43
|
+
|
|
44
|
+
# 'converted' wins over 'abandoned' so the three states stay exclusive:
|
|
45
|
+
# a cart that completed is never abandoned, however long it sat first.
|
|
46
|
+
CART_STATUS_SQL = <<~SQL.squish.freeze
|
|
47
|
+
CASE WHEN #{CART_CONVERTED_CONDITION} THEN 'converted'
|
|
48
|
+
WHEN #{ABANDONED_CONDITION} THEN 'abandoned'
|
|
49
|
+
ELSE 'active' END
|
|
50
|
+
SQL
|
|
51
|
+
|
|
52
|
+
# One customer's whole order history, correlated on the email the
|
|
53
|
+
# `customer` dimension groups by and scoped to the same store.
|
|
54
|
+
LIFETIME_HISTORY_CONDITION = <<~SQL.squish.freeze
|
|
55
|
+
h.email = %{orders}.email AND h.store_id = %{orders}.store_id
|
|
56
|
+
AND #{format(COMPLETED_ORDER, alias: 'h')}
|
|
57
|
+
SQL
|
|
58
|
+
|
|
59
|
+
# A customer's whole history, correlated on the email the `customer`
|
|
60
|
+
# dimension groups by and scoped to the same store. MIN() rather than
|
|
61
|
+
# SUM(): the subquery already covers every one of that customer's
|
|
62
|
+
# orders, so summing it once per order in the period would multiply the
|
|
63
|
+
# figure by how often they bought — and every row in a customer group
|
|
64
|
+
# carries the identical value, so the minimum is that value.
|
|
65
|
+
#
|
|
66
|
+
# Net of refunds, consistent with net_sales: a customer who returned most
|
|
67
|
+
# of what they bought is not a high-value customer. The consequence is
|
|
68
|
+
# that a refund restates the figure after the fact.
|
|
69
|
+
LIFETIME_VALUE_SUBQUERY = <<~SQL.squish.freeze
|
|
70
|
+
MIN((SELECT COALESCE(SUM(h.total), 0) - COALESCE(SUM(
|
|
71
|
+
(SELECT SUM(hr.amount) FROM %{refunds} hr WHERE hr.order_id = h.id)), 0)
|
|
72
|
+
FROM %{orders} h
|
|
73
|
+
WHERE #{LIFETIME_HISTORY_CONDITION}))
|
|
74
|
+
SQL
|
|
75
|
+
|
|
76
|
+
LIFETIME_ORDERS_SUBQUERY = <<~SQL.squish.freeze
|
|
77
|
+
MIN((SELECT COUNT(*) FROM %{orders} h WHERE #{LIFETIME_HISTORY_CONDITION}))
|
|
78
|
+
SQL
|
|
79
|
+
|
|
80
|
+
# Discount money summed from the joined discount rows themselves.
|
|
81
|
+
#
|
|
82
|
+
# Read through the join rather than a per-line subquery because a line
|
|
83
|
+
# carrying two promotions must credit each with what it actually took
|
|
84
|
+
# off: a subquery over the line gives both rows the combined figure, and
|
|
85
|
+
# the breakdown then adds up to double what the store discounted.
|
|
86
|
+
#
|
|
87
|
+
# The grouped query is the only one that carries the join (Decision 13),
|
|
88
|
+
# so the dimensionless total uses the subquery form below instead.
|
|
89
|
+
PROMOTION_DISCOUNTS_JOINED = 'SUM(-COALESCE(%{discounts}.amount, 0))'.freeze
|
|
90
|
+
|
|
91
|
+
PROMOTION_DISCOUNTS_SUBQUERY = <<~SQL.squish.freeze
|
|
92
|
+
SUM(COALESCE((SELECT -SUM(d.amount) FROM %{discounts} d
|
|
93
|
+
WHERE d.line_item_id = %{line_items}.id AND d.kind = 'promotion'), 0))
|
|
94
|
+
SQL
|
|
95
|
+
|
|
96
|
+
# Checkouts that used a promotion. Counted in checkouts rather than
|
|
97
|
+
# orders (a basket split across sellers is one redemption), and narrowed
|
|
98
|
+
# to lines actually carrying a promotion discount — without the EXISTS
|
|
99
|
+
# the ungrouped total would count every order in the period, promoted or
|
|
100
|
+
# not, since the totals query carries no dimension join to narrow it.
|
|
101
|
+
PROMOTION_REDEMPTIONS_SQL = <<~SQL.squish.freeze
|
|
102
|
+
COUNT(DISTINCT CASE WHEN EXISTS (
|
|
103
|
+
SELECT 1 FROM %{discounts} d
|
|
104
|
+
WHERE d.line_item_id = %{line_items}.id AND d.kind = 'promotion'
|
|
105
|
+
) THEN COALESCE(%{orders}.order_group_id, %{orders}.id) END)
|
|
106
|
+
SQL
|
|
107
|
+
|
|
108
|
+
# Order-level money that lives on another table. Correlated on the
|
|
109
|
+
# order's own id so the aggregate stays one value per order — joining
|
|
110
|
+
# would multiply the base row and inflate every other metric in the
|
|
111
|
+
# same query.
|
|
112
|
+
REFUNDS_SUBQUERY = <<~SQL.squish.freeze
|
|
113
|
+
SUM(COALESCE((SELECT SUM(r.amount) FROM %{refunds} r WHERE r.order_id = %{orders}.id), 0))
|
|
114
|
+
SQL
|
|
115
|
+
|
|
116
|
+
# A refund is issued against the order, not a line, so it is apportioned
|
|
117
|
+
# by the line's share of the order's pre-tax value. The denominator is
|
|
118
|
+
# summed over the order's own lines rather than read from item_total:
|
|
119
|
+
# item_total is priced before discounts, so on a discounted order the
|
|
120
|
+
# shares would not add up to one and part of the refund would vanish.
|
|
121
|
+
# The `* 1.0` forces real division: SQLite divides two integer-valued
|
|
122
|
+
# decimals as integers, which silently rounds every share to zero.
|
|
123
|
+
LINE_ITEM_REFUNDS_SUBQUERY = <<~SQL.squish.freeze
|
|
124
|
+
SUM(
|
|
125
|
+
COALESCE((SELECT SUM(r.amount) FROM %{refunds} r WHERE r.order_id = %{orders}.id), 0)
|
|
126
|
+
* CASE
|
|
127
|
+
WHEN COALESCE((SELECT SUM(sibling.pre_tax_amount) FROM %{line_items} sibling
|
|
128
|
+
WHERE sibling.order_id = %{orders}.id), 0) > 0
|
|
129
|
+
THEN (%{line_items}.pre_tax_amount * 1.0)
|
|
130
|
+
/ (SELECT SUM(sibling.pre_tax_amount) FROM %{line_items} sibling
|
|
131
|
+
WHERE sibling.order_id = %{orders}.id)
|
|
132
|
+
ELSE 0
|
|
133
|
+
END
|
|
134
|
+
)
|
|
135
|
+
SQL
|
|
136
|
+
|
|
137
|
+
# An order is the customer's first when no earlier completed order shares
|
|
138
|
+
# its email in the same store.
|
|
139
|
+
CUSTOMER_TYPE_SQL = <<~SQL.squish.freeze
|
|
140
|
+
CASE WHEN EXISTS (
|
|
141
|
+
SELECT 1 FROM %{orders} prior
|
|
142
|
+
WHERE prior.email = %{orders}.email
|
|
143
|
+
AND prior.store_id = %{orders}.store_id
|
|
144
|
+
AND prior.status <> 'canceled'
|
|
145
|
+
AND prior.completed_at IS NOT NULL
|
|
146
|
+
AND prior.completed_at < %{orders}.completed_at
|
|
147
|
+
) THEN 'returning' ELSE 'first_time' END
|
|
148
|
+
SQL
|
|
149
|
+
|
|
150
|
+
DUTIES_SUBQUERY = <<~SQL.squish.freeze
|
|
151
|
+
SUM(COALESCE((SELECT SUM(f.amount) FROM %{fees} f
|
|
152
|
+
WHERE f.order_id = %{orders}.id AND f.kind = 'duty'), 0))
|
|
153
|
+
SQL
|
|
154
|
+
|
|
155
|
+
SELLER_COMMISSION_SUBQUERY = <<~SQL.squish.freeze
|
|
156
|
+
SUM(COALESCE((SELECT SUM(c.total) FROM %{commission_lines} c
|
|
157
|
+
WHERE c.line_item_id = %{line_items}.id), 0))
|
|
158
|
+
SQL
|
|
159
|
+
|
|
160
|
+
# A payment's own refunds, so "what we gave back" is attributed to the
|
|
161
|
+
# instrument that took the money rather than to the order.
|
|
162
|
+
PAYMENTS_COMPLETED_SUM = "SUM(CASE WHEN %{payments}.status = 'completed' THEN %{payments}.amount ELSE 0 END)".freeze
|
|
163
|
+
PAYMENTS_REFUNDED_SUM = <<~SQL.squish.freeze
|
|
164
|
+
SUM(COALESCE((SELECT SUM(pr.amount) FROM %{refunds} pr
|
|
165
|
+
WHERE pr.payment_id = %{payments}.id), 0))
|
|
166
|
+
SQL
|
|
167
|
+
|
|
168
|
+
# A variant reads the same wherever it is ranked — sold on the sales axis,
|
|
169
|
+
# moved on the inventory one — so both dimensions share one payload.
|
|
170
|
+
VARIANT_RESOLVE = ->(store, value) { store.variants.find_by_prefix_id!(value).id }
|
|
171
|
+
VARIANT_HYDRATE = lambda { |store, ids, _params|
|
|
172
|
+
store.variants.where(id: ids).includes(:product, option_values: :option_type).to_h do |variant|
|
|
173
|
+
[variant.id, {
|
|
174
|
+
id: variant.prefixed_id,
|
|
175
|
+
label: variant.descriptive_name,
|
|
176
|
+
meta: { sku: variant.sku, product_id: variant.product&.prefixed_id }
|
|
177
|
+
}]
|
|
178
|
+
end
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
# One movement kind's quantity. The kind carries the direction, so
|
|
182
|
+
# summing across kinds would net a receipt against a dispatch.
|
|
183
|
+
def self.movement_sum(kind)
|
|
184
|
+
"SUM(CASE WHEN %{stock_movements}.kind = '#{kind}' THEN %{stock_movements}.quantity ELSE 0 END)"
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
PAYMENTS_OWED = %w[none authorized partially_paid].freeze
|
|
188
|
+
|
|
189
|
+
# Everything still in flight, not just the first step: an approved return
|
|
190
|
+
# still needs receiving and refunding, so it is as much outstanding work
|
|
191
|
+
# as one nobody has looked at. Terminal statuses drop out.
|
|
192
|
+
OPEN_RETURN_STATUSES = %w[requested approved received].freeze
|
|
193
|
+
OPEN_EXCHANGE_STATUSES = %w[requested approved received].freeze
|
|
194
|
+
OPEN_CLAIM_STATUSES = %w[open approved].freeze
|
|
195
|
+
|
|
196
|
+
# Placed orders a merchant still acts on, narrowed to a channel when one
|
|
197
|
+
# is being looked at.
|
|
198
|
+
PLACED_ORDERS = ->(store, channel) { store.orders.complete.not_canceled.for_channel(channel) }
|
|
199
|
+
|
|
200
|
+
# Post-sale records still owed work. All three hang off an order, which
|
|
201
|
+
# is how a channel narrows them.
|
|
202
|
+
OPEN_POST_SALE = lambda { |relation, channel, statuses|
|
|
203
|
+
relation.joins(:order).where(status: statuses).merge(Spree::Order.for_channel(channel)).count
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
# The Inventory page's own view of the shelves, so a counter and the list
|
|
207
|
+
# it links to cannot disagree: the same rows, one per variant and
|
|
208
|
+
# location, read through the same scopes the page filters on.
|
|
209
|
+
STORE_STOCK = ->(store) { Spree::StockLevel.for_store(store) }
|
|
210
|
+
|
|
211
|
+
def self.install(registry)
|
|
212
|
+
registry.instance_eval do
|
|
213
|
+
# ---- bases ----
|
|
214
|
+
#
|
|
215
|
+
# Four families, because they answer different questions. Sales money
|
|
216
|
+
# is anchored on when an order completed; a payment is anchored on
|
|
217
|
+
# when it was taken, inventory on when stock moved, and a cart on
|
|
218
|
+
# when it was started. Mixing them in one row would put four
|
|
219
|
+
# different clocks in one table.
|
|
220
|
+
|
|
221
|
+
# `currency` is nil when the question does not involve money — see
|
|
222
|
+
# Query#scope_currency. Counting orders in one currency and calling
|
|
223
|
+
# it "orders" would understate a multi-currency store's trade.
|
|
224
|
+
base :orders, family: :sales, table: '%{orders}',
|
|
225
|
+
time_column: '%{orders}.completed_at',
|
|
226
|
+
clock: 'anchored on when the order completed',
|
|
227
|
+
relation: lambda { |store, range, currency|
|
|
228
|
+
scope = store.orders.not_canceled.where(completed_at: range)
|
|
229
|
+
currency ? scope.where(currency: currency) : scope
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
base :line_items, family: :sales, table: '%{line_items}',
|
|
233
|
+
reaches: { line_items: nil, orders: :order },
|
|
234
|
+
time_column: '%{orders}.completed_at',
|
|
235
|
+
clock: 'anchored on when the order completed',
|
|
236
|
+
relation: lambda { |store, range, currency|
|
|
237
|
+
scope = store.line_items.merge(Spree::Order.not_canceled).
|
|
238
|
+
where(Spree::Order.table_name => { completed_at: range })
|
|
239
|
+
currency ? scope.where(Spree::Order.table_name => { currency: currency }) : scope
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
# A payment carries no completion timestamp, so it is anchored on
|
|
243
|
+
# when the row was created — near enough to when the money moved, and
|
|
244
|
+
# the only honest answer the schema can publish.
|
|
245
|
+
#
|
|
246
|
+
# The currency lives on the order, not the payment, but the money
|
|
247
|
+
# metrics here are formatted in one currency — so a store selling in
|
|
248
|
+
# several must filter by it, or a EUR payment and a USD payment are
|
|
249
|
+
# added together and the total labelled with whichever currency was
|
|
250
|
+
# asked for. `store.payments` is already `through: :orders`, so the
|
|
251
|
+
# join this reads is the association's own.
|
|
252
|
+
base :payments, family: :payments, table: '%{payments}',
|
|
253
|
+
time_column: '%{payments}.created_at',
|
|
254
|
+
clock: 'anchored on when the payment was taken',
|
|
255
|
+
relation: lambda { |store, range, currency|
|
|
256
|
+
scope = store.payments.where(Spree::Payment.table_name => { created_at: range })
|
|
257
|
+
currency ? scope.where(Spree::Order.table_name => { currency: currency }) : scope
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
# The movement table carries no store of its own; tenancy is the walk
|
|
261
|
+
# through stock level → variant → product, which `for_store` owns.
|
|
262
|
+
base :stock_movements, family: :inventory, table: '%{stock_movements}', reaches: %i[stock_movements],
|
|
263
|
+
time_column: '%{stock_movements}.created_at',
|
|
264
|
+
clock: 'anchored on when stock moved',
|
|
265
|
+
relation: lambda { |store, range, _currency|
|
|
266
|
+
Spree::StockMovement.for_store(store).
|
|
267
|
+
where(Spree::StockMovement.table_name => { created_at: range })
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
# A cart is anchored on when it was started, not when it completed:
|
|
271
|
+
# the population being measured is the carts that were *started* in
|
|
272
|
+
# the period, and anchoring on completion would drop every cart that
|
|
273
|
+
# never converted — exactly the rows an abandonment report is about.
|
|
274
|
+
base :carts, family: :carts, table: '%{carts}', reaches: %i[carts],
|
|
275
|
+
time_column: '%{carts}.created_at',
|
|
276
|
+
clock: 'anchored on when the cart was started',
|
|
277
|
+
relation: lambda { |store, range, currency|
|
|
278
|
+
scope = store.carts.where(Spree::Cart.table_name => { created_at: range })
|
|
279
|
+
currency ? scope.where(Spree::Cart.table_name => { currency: currency }) : scope
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
# ---- the sales chain ----
|
|
283
|
+
#
|
|
284
|
+
# gross_sales - discounts - returns = net_sales
|
|
285
|
+
# net_sales + shipping + duties + fees + taxes = total_sales
|
|
286
|
+
#
|
|
287
|
+
# Line-item money is the finest grain we hold, so the first three
|
|
288
|
+
# terms aggregate on :line_items and the order-level charges on
|
|
289
|
+
# :orders. Money that lives on another table (refunds, commissions)
|
|
290
|
+
# is summed through a correlated subquery: an order with three
|
|
291
|
+
# refunds must stay one row.
|
|
292
|
+
|
|
293
|
+
metric :gross_sales, sql: 'SUM(%{line_items}.price * %{line_items}.quantity)',
|
|
294
|
+
base: :line_items, format: :money
|
|
295
|
+
metric :discounts, sql: 'SUM(%{line_items}.discount_total)', base: :line_items, format: :money
|
|
296
|
+
metric :returns, sql: REFUNDS_SUBQUERY, base: :orders, format: :money
|
|
297
|
+
# Net of returns as well as discounts, so this is the figure a
|
|
298
|
+
# merchant recognises as "what we actually sold".
|
|
299
|
+
metric :net_sales, sql: "SUM(%{line_items}.pre_tax_amount) - #{LINE_ITEM_REFUNDS_SUBQUERY}",
|
|
300
|
+
base: :line_items, format: :money
|
|
301
|
+
metric :shipping, sql: 'SUM(%{orders}.delivery_total)', base: :orders, format: :money, suggests: 'net_sales'
|
|
302
|
+
metric :duties, sql: DUTIES_SUBQUERY, base: :orders, format: :money, suggests: 'net_sales'
|
|
303
|
+
# Every shopper-visible fee except duties, which the chain counts separately.
|
|
304
|
+
metric :fees, sql: "SUM(COALESCE(%{orders}.fee_total, 0)) - #{DUTIES_SUBQUERY}",
|
|
305
|
+
base: :orders, format: :money, suggests: 'net_sales'
|
|
306
|
+
metric :taxes, sql: 'SUM(%{orders}.additional_tax_total + %{orders}.included_tax_total)',
|
|
307
|
+
base: :orders, format: :money, suggests: 'net_sales'
|
|
308
|
+
# The order grand total, net of what came back.
|
|
309
|
+
metric :total_sales, sql: "SUM(%{orders}.total) - #{REFUNDS_SUBQUERY}",
|
|
310
|
+
base: :orders, format: :money, suggests: 'net_sales'
|
|
311
|
+
|
|
312
|
+
# ---- volume ----
|
|
313
|
+
|
|
314
|
+
metric :orders, sql: 'COUNT(*)', base: :orders, format: :integer
|
|
315
|
+
metric :units_sold, sql: 'SUM(%{line_items}.quantity)', base: :line_items, format: :integer
|
|
316
|
+
metric :customers, sql: 'COUNT(DISTINCT %{orders}.email)', base: :orders, format: :integer
|
|
317
|
+
metric :average_order_value, ratio: %i[total_sales orders], format: :money
|
|
318
|
+
|
|
319
|
+
# ---- margin ----
|
|
320
|
+
#
|
|
321
|
+
# cost_price is nullable, so an uncosted variant contributes zero and
|
|
322
|
+
# margin over an incompletely-costed catalogue reads high. Guessing a
|
|
323
|
+
# cost would be worse than reporting the gap.
|
|
324
|
+
metric :cost_of_goods, sql: 'SUM(COALESCE(%{line_items}.cost_price, 0) * %{line_items}.quantity)',
|
|
325
|
+
base: :line_items, format: :money
|
|
326
|
+
metric :gross_profit,
|
|
327
|
+
sql: 'SUM(%{line_items}.pre_tax_amount) - SUM(COALESCE(%{line_items}.cost_price, 0) * %{line_items}.quantity)',
|
|
328
|
+
base: :line_items, format: :money
|
|
329
|
+
metric :gross_margin, ratio: %i[gross_profit net_sales], format: :percent
|
|
330
|
+
|
|
331
|
+
# ---- marketplace ----
|
|
332
|
+
#
|
|
333
|
+
# A commission is a platform-to-seller settlement, never part of what
|
|
334
|
+
# the shopper paid. Summed from the lines rather than the order's
|
|
335
|
+
# denormalized total so it can be broken down by seller — an order
|
|
336
|
+
# with two sellers owes each of them their own share.
|
|
337
|
+
metric :commission, sql: SELLER_COMMISSION_SUBQUERY, base: :line_items, format: :money,
|
|
338
|
+
subject: -> { Spree::CommissionLine }, key_scope: 'read_commissions'
|
|
339
|
+
# What the sellers are owed on these sales: the goods they sold, less
|
|
340
|
+
# the marketplace's cut and anything the buyer sent back.
|
|
341
|
+
metric :seller_payout,
|
|
342
|
+
sql: "SUM(%{line_items}.pre_tax_amount) - #{LINE_ITEM_REFUNDS_SUBQUERY} - #{SELLER_COMMISSION_SUBQUERY}",
|
|
343
|
+
base: :line_items, format: :money,
|
|
344
|
+
subject: -> { Spree::SellerTransfer }, key_scope: 'read_payouts'
|
|
345
|
+
|
|
346
|
+
# ---- payments ----
|
|
347
|
+
#
|
|
348
|
+
# What was actually taken and given back, by the instrument that
|
|
349
|
+
# moved it. Anchored on when the payment row was created, not on the
|
|
350
|
+
# order's completion — a balance paid weeks later belongs to the week
|
|
351
|
+
# it was paid.
|
|
352
|
+
|
|
353
|
+
metric :payments_received, sql: PAYMENTS_COMPLETED_SUM, base: :payments, format: :money
|
|
354
|
+
metric :payments_refunded, sql: PAYMENTS_REFUNDED_SUM, base: :payments, format: :money
|
|
355
|
+
metric :net_payments, sql: "#{PAYMENTS_COMPLETED_SUM} - #{PAYMENTS_REFUNDED_SUM}",
|
|
356
|
+
base: :payments, format: :money
|
|
357
|
+
metric :payments_count, sql: "COUNT(CASE WHEN %{payments}.status = 'completed' THEN 1 END)",
|
|
358
|
+
base: :payments, format: :integer
|
|
359
|
+
metric :payments_failed, sql: "COUNT(CASE WHEN %{payments}.status = 'failed' THEN 1 END)",
|
|
360
|
+
base: :payments, format: :integer
|
|
361
|
+
|
|
362
|
+
# ---- inventory ----
|
|
363
|
+
#
|
|
364
|
+
# Movement of stock, from the typed ledger. The kind carries the
|
|
365
|
+
# direction, so each metric sums one kind rather than raw quantity —
|
|
366
|
+
# `received` and `shipped` are both positive rows.
|
|
367
|
+
|
|
368
|
+
metric :units_received, sql: DefaultVocabulary.movement_sum('received'), base: :stock_movements, format: :integer
|
|
369
|
+
metric :units_shipped, sql: DefaultVocabulary.movement_sum('shipped'), base: :stock_movements, format: :integer
|
|
370
|
+
metric :units_adjusted, sql: DefaultVocabulary.movement_sum('adjusted'), base: :stock_movements, format: :integer
|
|
371
|
+
# What share of what arrived has left again. Both terms are counts of
|
|
372
|
+
# the same unit, so this reads as a percentage.
|
|
373
|
+
metric :sell_through, ratio: %i[units_shipped units_received], format: :percent
|
|
374
|
+
|
|
375
|
+
# ---- carts ----
|
|
376
|
+
#
|
|
377
|
+
# What happened to the baskets that were started. Anchored on the
|
|
378
|
+
# cart's own clock, which is why these never share a query with sales.
|
|
379
|
+
|
|
380
|
+
metric :carts_started, sql: 'COUNT(*)', base: :carts, format: :integer
|
|
381
|
+
metric :carts_converted, sql: CARTS_CONVERTED_SUM, base: :carts, format: :integer
|
|
382
|
+
metric :carts_abandoned, sql: ABANDONED_CARTS_SUM, base: :carts, format: :integer
|
|
383
|
+
# What the abandoned baskets were worth — the recoverable figure.
|
|
384
|
+
metric :abandoned_value, sql: ABANDONED_VALUE_SUM, base: :carts, format: :money
|
|
385
|
+
# Of the carts started, the share that became orders. NOT the
|
|
386
|
+
# storefront conversion rate: sessions never reach Spree, so this
|
|
387
|
+
# counts baskets, not visits, and the two numbers differ.
|
|
388
|
+
metric :cart_conversion_rate, ratio: %i[carts_converted carts_started], format: :percent
|
|
389
|
+
|
|
390
|
+
# ---- promotions ----
|
|
391
|
+
#
|
|
392
|
+
# Discount money is stored non-positive (a DB check constraint), so
|
|
393
|
+
# these negate it: a merchant reads "4,210 discounted", not "-4,210".
|
|
394
|
+
|
|
395
|
+
metric :promotion_discounts, sql: PROMOTION_DISCOUNTS_SUBQUERY,
|
|
396
|
+
grouped_sql: PROMOTION_DISCOUNTS_JOINED,
|
|
397
|
+
base: :line_items, format: :money,
|
|
398
|
+
subject: -> { Spree::Promotion }, key_scope: 'read_promotions'
|
|
399
|
+
# Counted in checkouts, not orders: a basket spanning several sellers
|
|
400
|
+
# becomes several orders, and charging one customer's single
|
|
401
|
+
# redemption three times would spend a limited promotion too fast.
|
|
402
|
+
metric :promotion_redemptions, sql: PROMOTION_REDEMPTIONS_SQL,
|
|
403
|
+
base: :line_items, format: :integer,
|
|
404
|
+
subject: -> { Spree::Promotion }, key_scope: 'read_promotions'
|
|
405
|
+
|
|
406
|
+
# ---- lifetime ----
|
|
407
|
+
#
|
|
408
|
+
# A customer's whole history, deliberately ignoring the query's time
|
|
409
|
+
# range: the range picks *which* customers appear, their figure
|
|
410
|
+
# covers everything they have ever bought. Query#validate_lifetime_
|
|
411
|
+
# metrics! refuses these ungrouped, where they would add every
|
|
412
|
+
# customer's history into one meaningless total.
|
|
413
|
+
|
|
414
|
+
metric :customer_lifetime_value, sql: LIFETIME_VALUE_SUBQUERY, base: :orders, format: :money,
|
|
415
|
+
requires_grouping: :customer,
|
|
416
|
+
subject: -> { Spree.customer_class }, key_scope: 'read_customers'
|
|
417
|
+
metric :orders_lifetime, sql: LIFETIME_ORDERS_SUBQUERY, base: :orders, format: :integer,
|
|
418
|
+
requires_grouping: :customer,
|
|
419
|
+
subject: -> { Spree.customer_class }, key_scope: 'read_customers'
|
|
420
|
+
|
|
421
|
+
dimension :completed_at, base: :orders, column: :completed_at, type: :time,
|
|
422
|
+
grains: %i[hour day week month]
|
|
423
|
+
dimension :payment_status, base: :orders, column: :payment_status,
|
|
424
|
+
values: -> { Spree::Order::PAYMENT_STATUSES }
|
|
425
|
+
# The rollup values Orders::UpdateStatuses writes today; the model
|
|
426
|
+
# constant still carries the legacy machine states until 6.1.
|
|
427
|
+
dimension :fulfillment_status, base: :orders, column: :fulfillment_status,
|
|
428
|
+
values: -> { %w[backorder canceled partial unfulfilled fulfilled delivered] }
|
|
429
|
+
|
|
430
|
+
# Keyed by ISO code straight off the shipping address — countries are
|
|
431
|
+
# reference data (Spree::Country is not a record), so the code is the id.
|
|
432
|
+
dimension :country, base: :orders, column: '%{addresses}.country_code', joins: [:ship_address],
|
|
433
|
+
lookup: :country,
|
|
434
|
+
hydrate: lambda { |_store, codes, _params|
|
|
435
|
+
codes.to_h do |code|
|
|
436
|
+
[code, { id: code, label: Spree::Country.by_iso(code)&.name || code, meta: {} }]
|
|
437
|
+
end
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
dimension :market, base: :orders, column: :market_id, lookup: :market,
|
|
441
|
+
resolve: ->(store, value) { store.markets.find_by_prefix_id!(value).id },
|
|
442
|
+
hydrate: lambda { |store, ids, _params|
|
|
443
|
+
store.markets.where(id: ids).to_h do |market|
|
|
444
|
+
[market.id, { id: market.prefixed_id, label: market.name, meta: {} }]
|
|
445
|
+
end
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
dimension :channel, base: :orders, column: :channel_id, lookup: :channel,
|
|
449
|
+
resolve: ->(store, value) { store.channels.find_by_prefix_id!(value).id },
|
|
450
|
+
hydrate: lambda { |store, ids, _params|
|
|
451
|
+
store.channels.where(id: ids).to_h do |channel|
|
|
452
|
+
[channel.id, { id: channel.prefixed_id, label: channel.name, meta: { code: channel.code } }]
|
|
453
|
+
end
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
# First-time or returning, decided per order against the buyer's own
|
|
457
|
+
# history rather than a stored flag: an order is "returning" when the
|
|
458
|
+
# same email completed an earlier one. Imported history and canceled
|
|
459
|
+
# orders therefore stay correct without a backfill.
|
|
460
|
+
dimension :customer_type, base: :orders, expression: CUSTOMER_TYPE_SQL,
|
|
461
|
+
values: -> { %w[first_time returning] }
|
|
462
|
+
|
|
463
|
+
# The seller who sold the line. Marketplace stores group by this;
|
|
464
|
+
# single-seller stores get one row, which is honest.
|
|
465
|
+
dimension :seller, base: :line_items, column: :seller_id, lookup: :seller,
|
|
466
|
+
subject: -> { Spree::Seller }, key_scope: 'read_sellers',
|
|
467
|
+
resolve: ->(store, value) { store.sellers.find_by_prefix_id!(value).id },
|
|
468
|
+
hydrate: lambda { |store, ids, _params|
|
|
469
|
+
store.sellers.where(id: ids).to_h do |seller|
|
|
470
|
+
[seller.id, { id: seller.prefixed_id, label: seller.name, meta: { slug: seller.slug } }]
|
|
471
|
+
end
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
# Keyed by the order's email (guests have no customer row); a
|
|
475
|
+
# prefixed customer id in a filter resolves to that customer's email.
|
|
476
|
+
dimension :customer, base: :orders, column: :email, lookup: :customer,
|
|
477
|
+
subject: -> { Spree.customer_class }, key_scope: 'read_customers',
|
|
478
|
+
resolve: lambda { |store, value|
|
|
479
|
+
Spree::PrefixedId.prefixed_id?(value.to_s) ? Spree.customer_class.find_by_prefix_id!(value).email : value
|
|
480
|
+
},
|
|
481
|
+
hydrate: lambda { |store, emails, _params|
|
|
482
|
+
customers = store.customers.distinct.where(email: emails).index_by(&:email)
|
|
483
|
+
emails.to_h do |email|
|
|
484
|
+
customer = customers[email]
|
|
485
|
+
[email, { id: customer&.prefixed_id, label: customer&.full_name.presence || email, meta: { email: email } }]
|
|
486
|
+
end
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
# The buying organisation. Keyed by whichever node the purchase named
|
|
490
|
+
# — a division's spend stays that division's, rather than rolling
|
|
491
|
+
# silently into its parent.
|
|
492
|
+
dimension :company, base: :orders, column: :company_id, lookup: :company,
|
|
493
|
+
subject: -> { Spree::Company }, key_scope: 'read_customers',
|
|
494
|
+
resolve: ->(store, value) { store.companies.find_by_prefix_id!(value).id },
|
|
495
|
+
hydrate: lambda { |store, ids, _params|
|
|
496
|
+
store.companies.where(id: ids).to_h do |company|
|
|
497
|
+
[company.id, { id: company.prefixed_id, label: company.name, meta: { kind: company.kind } }]
|
|
498
|
+
end
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
dimension :category, base: :line_items, column: '%{product_categories}.category_id',
|
|
502
|
+
joins: [{ variant: { product: :product_categories } }], lookup: :category,
|
|
503
|
+
subject: -> { Spree::Category }, key_scope: 'read_categories',
|
|
504
|
+
resolve: ->(store, value) { store.categories.find_by_prefix_id!(value).id },
|
|
505
|
+
hydrate: lambda { |store, ids, _params|
|
|
506
|
+
store.categories.where(id: ids).to_h do |category|
|
|
507
|
+
[category.id, { id: category.prefixed_id, label: category.name, meta: {} }]
|
|
508
|
+
end
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
# SKU-level merchandising; the label carries the option values so
|
|
512
|
+
# variants of one product stay distinguishable in a ranking.
|
|
513
|
+
dimension :variant, base: :line_items, column: :variant_id, lookup: :variant,
|
|
514
|
+
subject: -> { Spree::Product }, key_scope: 'read_products',
|
|
515
|
+
resolve: VARIANT_RESOLVE, hydrate: VARIANT_HYDRATE
|
|
516
|
+
|
|
517
|
+
# Meta rides on the admin product serializer so thumbnails match the
|
|
518
|
+
# rest of the Admin API; the lambda only runs inside API requests.
|
|
519
|
+
dimension :product, base: :line_items, column: '%{variants}.product_id', joins: [:variant],
|
|
520
|
+
lookup: :product,
|
|
521
|
+
subject: -> { Spree::Product }, key_scope: 'read_products',
|
|
522
|
+
# Live products only: a deleted product that never sold is
|
|
523
|
+
# not a merchandising gap worth reporting, though a deleted
|
|
524
|
+
# one that did sell still hydrates through the resolve path.
|
|
525
|
+
population: ->(store) { store.products },
|
|
526
|
+
resolve: ->(store, value) { store.products.with_deleted.find_by_prefix_id!(value).id },
|
|
527
|
+
# Four display fields, read directly: the product serializer
|
|
528
|
+
# would resolve buy-box variants, price lists, seller, type
|
|
529
|
+
# and tax category per row and throw all of it away.
|
|
530
|
+
hydrate: lambda { |store, ids, _params|
|
|
531
|
+
currency = Spree::Current.currency || store.default_currency
|
|
532
|
+
products = store.products.with_deleted.includes(:primary_media).where(id: ids)
|
|
533
|
+
products.to_h do |product|
|
|
534
|
+
amount = product.default_variant&.amount_in(currency)
|
|
535
|
+
[product.id, {
|
|
536
|
+
id: product.prefixed_id,
|
|
537
|
+
label: product.name,
|
|
538
|
+
meta: {
|
|
539
|
+
slug: product.slug,
|
|
540
|
+
thumbnail_url: Spree::Reporting.image_url(product.primary_media),
|
|
541
|
+
price: (Spree::Money.new(amount, currency: currency).to_s if amount)
|
|
542
|
+
}
|
|
543
|
+
}]
|
|
544
|
+
end
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
# ---- cart axes ----
|
|
548
|
+
|
|
549
|
+
dimension :started_at, base: :carts, column: :created_at, type: :time,
|
|
550
|
+
grains: %i[hour day week month]
|
|
551
|
+
|
|
552
|
+
dimension :cart_status, base: :carts, expression: CART_STATUS_SQL,
|
|
553
|
+
values: -> { %w[active abandoned converted] }
|
|
554
|
+
|
|
555
|
+
dimension :cart_channel, base: :carts, column: :channel_id, lookup: :channel,
|
|
556
|
+
resolve: ->(store, value) { store.channels.find_by_prefix_id!(value).id },
|
|
557
|
+
hydrate: lambda { |store, ids, _params|
|
|
558
|
+
store.channels.where(id: ids).to_h do |channel|
|
|
559
|
+
[channel.id, { id: channel.prefixed_id, label: channel.name, meta: {} }]
|
|
560
|
+
end
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
# ---- promotion axes ----
|
|
564
|
+
#
|
|
565
|
+
# Attribution reads the money rows themselves: every discount row
|
|
566
|
+
# carries promotion_id, promotion_action_id and a snapshot of the
|
|
567
|
+
# redeemed code, all indexed, so a breakdown is a plain GROUP BY.
|
|
568
|
+
# The join table carries no amount and would need a subquery to
|
|
569
|
+
# produce one.
|
|
570
|
+
#
|
|
571
|
+
# The join runs from the line item, and the :line_items base already
|
|
572
|
+
# restricts to completed orders, so cart-owned discount rows cannot
|
|
573
|
+
# reach a sales report. A discount dimension registered on a base
|
|
574
|
+
# that does include carts would need an explicit owner predicate:
|
|
575
|
+
# discount rows are order_id XOR cart_id.
|
|
576
|
+
#
|
|
577
|
+
# It joins only promotion discounts, not every discount. Including
|
|
578
|
+
# the manual ones would give a hand-discounted line a second group
|
|
579
|
+
# under "no promotion" beside its real promotion row, and the two
|
|
580
|
+
# rows would then count the same line twice.
|
|
581
|
+
|
|
582
|
+
dimension :promotion, base: :line_items, column: '%{discounts}.promotion_id',
|
|
583
|
+
joins: [:promotion_discounts], lookup: :promotion,
|
|
584
|
+
subject: -> { Spree::Promotion }, key_scope: 'read_promotions',
|
|
585
|
+
population: ->(store) { store.promotions },
|
|
586
|
+
resolve: ->(store, value) { store.promotions.find_by_prefix_id!(value).id },
|
|
587
|
+
hydrate: lambda { |store, ids, _params|
|
|
588
|
+
store.promotions.where(id: ids).to_h do |promotion|
|
|
589
|
+
[promotion.id, { id: promotion.prefixed_id, label: promotion.name, meta: {} }]
|
|
590
|
+
end
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
# The code is its own label, and it is snapshotted on the money row,
|
|
594
|
+
# so it survives the promotion being deleted.
|
|
595
|
+
dimension :coupon_code, base: :line_items, column: '%{discounts}.code', joins: [:promotion_discounts],
|
|
596
|
+
subject: -> { Spree::Promotion }, key_scope: 'read_promotions'
|
|
597
|
+
|
|
598
|
+
# ---- payment axes ----
|
|
599
|
+
|
|
600
|
+
dimension :payment_method, base: :payments, column: :payment_method_id, lookup: :payment_method,
|
|
601
|
+
subject: -> { Spree::PaymentMethod }, key_scope: 'read_settings',
|
|
602
|
+
resolve: ->(store, value) { store.payment_methods.find_by_prefix_id!(value).id },
|
|
603
|
+
hydrate: lambda { |store, ids, _params|
|
|
604
|
+
store.payment_methods.where(id: ids).to_h do |method|
|
|
605
|
+
[method.id, { id: method.prefixed_id, label: method.name, meta: { type: method.type } }]
|
|
606
|
+
end
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
# Distinct from the order-level `payment_status`, which says how much
|
|
610
|
+
# of an order is paid; this says whether one charge went through.
|
|
611
|
+
dimension :payment_result, base: :payments, column: :status,
|
|
612
|
+
values: -> { Spree::Payment.statuses }
|
|
613
|
+
|
|
614
|
+
dimension :paid_at, base: :payments, column: :created_at, type: :time,
|
|
615
|
+
grains: %i[hour day week month]
|
|
616
|
+
|
|
617
|
+
# ---- inventory axes ----
|
|
618
|
+
|
|
619
|
+
dimension :moved_at, base: :stock_movements, column: :created_at, type: :time,
|
|
620
|
+
grains: %i[hour day week month]
|
|
621
|
+
|
|
622
|
+
dimension :movement_kind, base: :stock_movements, column: :kind,
|
|
623
|
+
values: -> { Spree::StockMovement::KINDS }
|
|
624
|
+
|
|
625
|
+
# Reached through the movement's stock level, which is also how the
|
|
626
|
+
# base scopes itself to the store.
|
|
627
|
+
dimension :moved_variant, base: :stock_movements, column: '%{stock_levels}.variant_id',
|
|
628
|
+
joins: [:stock_level], lookup: :variant,
|
|
629
|
+
subject: -> { Spree::Product }, key_scope: 'read_products',
|
|
630
|
+
resolve: VARIANT_RESOLVE, hydrate: VARIANT_HYDRATE
|
|
631
|
+
|
|
632
|
+
dimension :stock_location, base: :stock_movements, column: '%{stock_levels}.stock_location_id',
|
|
633
|
+
joins: [:stock_level], lookup: :stock_location,
|
|
634
|
+
subject: -> { Spree::StockLocation }, key_scope: 'read_stock',
|
|
635
|
+
resolve: ->(store, value) { store.stock_locations.find_by_prefix_id!(value).id },
|
|
636
|
+
hydrate: lambda { |store, ids, _params|
|
|
637
|
+
store.stock_locations.where(id: ids).to_h do |location|
|
|
638
|
+
[location.id, { id: location.prefixed_id, label: location.name, meta: {} }]
|
|
639
|
+
end
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
# ---- counters ----
|
|
643
|
+
#
|
|
644
|
+
# What needs attention right now. Order counters honour the channel
|
|
645
|
+
# a merchant is looking at; stock is channel-agnostic. Each link
|
|
646
|
+
# names the list filter that shows exactly the rows counted — the
|
|
647
|
+
# stock counters carry none until an inventory list can express
|
|
648
|
+
# "at or below n on hand" (docs/plans/6.0-inventory-operations.md).
|
|
649
|
+
|
|
650
|
+
counter :orders_to_fulfill,
|
|
651
|
+
subject: -> { Spree::Order }, key_scope: 'read_orders', nav: 'orders',
|
|
652
|
+
count: ->(store, channel:) { PLACED_ORDERS.call(store, channel).ready_to_ship.count },
|
|
653
|
+
# `in` rather than `eq`, though it names one value: the
|
|
654
|
+
# orders table's Fulfillment control reads `in`, so an `eq`
|
|
655
|
+
# rule lands beside it as a separate chip and the control
|
|
656
|
+
# still says "All" — two filters on screen for one idea.
|
|
657
|
+
link: { resource: 'orders',
|
|
658
|
+
filters: [{ field: 'fulfillment_status', operator: 'in', value: 'unfulfilled' }] }
|
|
659
|
+
|
|
660
|
+
# Placed orders still owed money: nothing collected yet, authorized
|
|
661
|
+
# but not captured, or only partially paid.
|
|
662
|
+
counter :payments_to_collect,
|
|
663
|
+
subject: -> { Spree::Order }, key_scope: 'read_orders',
|
|
664
|
+
count: lambda { |store, channel:|
|
|
665
|
+
PLACED_ORDERS.call(store, channel).where(payment_status: PAYMENTS_OWED).count
|
|
666
|
+
},
|
|
667
|
+
link: { resource: 'orders',
|
|
668
|
+
filters: [{ field: 'payment_status', operator: 'in', value: PAYMENTS_OWED.join(',') }] }
|
|
669
|
+
|
|
670
|
+
counter :open_returns,
|
|
671
|
+
subject: -> { Spree::Return }, key_scope: 'read_orders', nav: 'returns',
|
|
672
|
+
count: ->(store, channel:) { OPEN_POST_SALE.call(store.returns, channel, OPEN_RETURN_STATUSES) },
|
|
673
|
+
link: { resource: 'returns',
|
|
674
|
+
filters: [{ field: 'status', operator: 'in', value: OPEN_RETURN_STATUSES.join(',') }] }
|
|
675
|
+
|
|
676
|
+
counter :open_exchanges,
|
|
677
|
+
subject: -> { Spree::Exchange }, key_scope: 'read_orders', nav: 'exchanges',
|
|
678
|
+
count: ->(store, channel:) { OPEN_POST_SALE.call(store.exchanges, channel, OPEN_EXCHANGE_STATUSES) },
|
|
679
|
+
link: { resource: 'exchanges',
|
|
680
|
+
filters: [{ field: 'status', operator: 'in', value: OPEN_EXCHANGE_STATUSES.join(',') }] }
|
|
681
|
+
|
|
682
|
+
counter :open_claims,
|
|
683
|
+
subject: -> { Spree::Claim }, key_scope: 'read_orders', nav: 'claims',
|
|
684
|
+
count: ->(store, channel:) { OPEN_POST_SALE.call(store.claims, channel, OPEN_CLAIM_STATUSES) },
|
|
685
|
+
link: { resource: 'claims',
|
|
686
|
+
filters: [{ field: 'status', operator: 'in', value: OPEN_CLAIM_STATUSES.join(',') }] }
|
|
687
|
+
|
|
688
|
+
counter :low_stock_items,
|
|
689
|
+
subject: -> { Spree::StockLevel }, key_scope: 'read_stock',
|
|
690
|
+
count: lambda { |store, channel:|
|
|
691
|
+
STORE_STOCK.call(store).low_stock(store.preferred_low_stock_threshold).count
|
|
692
|
+
},
|
|
693
|
+
link: { resource: 'inventory',
|
|
694
|
+
filters: [{ field: 'stock_status', operator: 'in', value: 'low_stock' }] }
|
|
695
|
+
|
|
696
|
+
counter :out_of_stock_items,
|
|
697
|
+
subject: -> { Spree::StockLevel }, key_scope: 'read_stock',
|
|
698
|
+
count: ->(store, channel:) { STORE_STOCK.call(store).out_of_stock.count },
|
|
699
|
+
link: { resource: 'inventory',
|
|
700
|
+
filters: [{ field: 'stock_status', operator: 'in', value: 'out_of_stock' }] }
|
|
701
|
+
end
|
|
702
|
+
end
|
|
703
|
+
end
|
|
704
|
+
end
|
|
705
|
+
end
|