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
data/app/models/spree/variant.rb
CHANGED
|
@@ -6,42 +6,65 @@ module Spree
|
|
|
6
6
|
acts_as_list scope: :product
|
|
7
7
|
|
|
8
8
|
include Spree::MemoizedData
|
|
9
|
-
include Spree::
|
|
9
|
+
include Spree::HasCustomFields
|
|
10
10
|
include Spree::Metadata
|
|
11
|
+
include Spree::HasExternalReferences
|
|
11
12
|
include Spree::Searchable
|
|
12
|
-
include Spree::
|
|
13
|
+
include Spree::StorePreferences
|
|
13
14
|
|
|
14
15
|
publishes_lifecycle_events
|
|
15
16
|
|
|
16
|
-
MEMOIZED_METHODS = %w(in_stock on_sale backorderable tax_category options_text compare_at_price)
|
|
17
|
+
MEMOIZED_METHODS = %w(in_stock on_sale backorderable tax_category tax_category_id options_text compare_at_price)
|
|
17
18
|
|
|
18
19
|
DIMENSION_UNITS = %w[mm cm in ft]
|
|
19
20
|
WEIGHT_UNITS = %w[g kg lb oz]
|
|
20
21
|
|
|
22
|
+
# What a buyer is quoted in. Stored quantities are units at every level;
|
|
23
|
+
# this only changes the vocabulary a storefront presents.
|
|
24
|
+
PURCHASE_UNITS = %w[unit carton]
|
|
25
|
+
|
|
21
26
|
belongs_to :product, -> { with_deleted }, touch: true, class_name: 'Spree::Product', inverse_of: :variants
|
|
22
27
|
belongs_to :tax_category, class_name: 'Spree::TaxCategory', optional: true
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
# The carton this variant is packed into. Geometry lives on the shared
|
|
29
|
+
# row; how many units fit and what a packed carton weighs stay here.
|
|
30
|
+
belongs_to :carton_package_type, class_name: 'Spree::PackageType', optional: true,
|
|
31
|
+
inverse_of: :variants
|
|
32
|
+
# Which seller sells this variant. Nil is the operator's own listing, and
|
|
33
|
+
# on a product whose seller owns every variant the product answers instead
|
|
34
|
+
# — see #resolved_seller_id. Several sellers on one product is the whole point: two
|
|
35
|
+
# of them are two variant rows, so their stock, prices and line-item
|
|
36
|
+
# attribution are separate by construction.
|
|
37
|
+
belongs_to :seller, class_name: 'Spree::Seller', optional: true
|
|
38
|
+
# Nil defers to the product, exactly as tax_category does.
|
|
39
|
+
belongs_to :delivery_profile, class_name: 'Spree::DeliveryProfile', optional: true
|
|
40
|
+
|
|
41
|
+
delegate :name, :name=, :description, :slug, :available_on, :make_active_at, :product_type_id,
|
|
42
|
+
:meta_description, :meta_keywords, :product_type, :store_id, to: :product
|
|
26
43
|
|
|
27
44
|
normalizes :sku, with: ->(value) { value&.to_s&.strip }
|
|
45
|
+
normalizes :hs_code, with: ->(value) { value&.to_s&.gsub(/[^0-9]/, '') }
|
|
46
|
+
normalizes :country_of_origin, with: ->(value) { value&.to_s&.strip&.upcase }
|
|
28
47
|
|
|
29
48
|
# we need to have this callback before any dependent: :destroy associations
|
|
30
49
|
# https://github.com/rails/rails/issues/3458
|
|
31
50
|
before_destroy :ensure_not_in_complete_orders
|
|
32
51
|
after_destroy :remove_line_items_from_incomplete_orders
|
|
33
52
|
|
|
34
|
-
#
|
|
35
|
-
|
|
53
|
+
# Terms stated for this variant go with it. Nothing below the cart layer
|
|
54
|
+
# reads them, but a row pointing at a destroyed variant would resolve for
|
|
55
|
+
# nobody and count against the agreement's overrides forever.
|
|
56
|
+
has_many :catalog_quantity_rules, class_name: 'Spree::CatalogQuantityRule',
|
|
57
|
+
dependent: :destroy, inverse_of: :variant
|
|
36
58
|
|
|
37
59
|
with_options inverse_of: :variant do
|
|
38
|
-
has_many :
|
|
60
|
+
has_many :fulfillment_items, class_name: 'Spree::FulfillmentItem'
|
|
39
61
|
has_many :line_items
|
|
40
|
-
has_many :
|
|
62
|
+
has_many :stock_levels, class_name: 'Spree::StockLevel', dependent: :destroy, autosave: true
|
|
41
63
|
end
|
|
64
|
+
has_many :inventory_units, class_name: 'Spree::FulfillmentItem', inverse_of: :variant, deprecated: true
|
|
42
65
|
|
|
43
66
|
has_many :orders, through: :line_items
|
|
44
|
-
with_options through: :
|
|
67
|
+
with_options through: :stock_levels do
|
|
45
68
|
has_many :stock_locations
|
|
46
69
|
has_many :stock_movements
|
|
47
70
|
has_many :stock_reservations
|
|
@@ -50,17 +73,25 @@ module Spree
|
|
|
50
73
|
has_many :option_value_variants, class_name: 'Spree::OptionValueVariant'
|
|
51
74
|
has_many :option_values, through: :option_value_variants, dependent: :destroy, class_name: 'Spree::OptionValue'
|
|
52
75
|
|
|
53
|
-
has_many :images, -> { order(:position) }, as: :viewable, dependent: :destroy, class_name: 'Spree::
|
|
76
|
+
has_many :images, -> { order(:position) }, as: :viewable, dependent: :destroy, class_name: 'Spree::Media'
|
|
54
77
|
|
|
55
78
|
has_many :variant_media, class_name: 'Spree::VariantMedia', dependent: :destroy
|
|
56
79
|
# Order through the asset's product-level position so a variant's gallery
|
|
57
80
|
# follows whatever ordering the merchant set on the product. There's no
|
|
58
81
|
# per-variant reordering — link/unlink only.
|
|
59
82
|
has_many :associated_media,
|
|
60
|
-
-> { order(Spree::
|
|
61
|
-
through: :variant_media, source: :asset, class_name: 'Spree::
|
|
83
|
+
-> { order(Spree::Media.arel_table[:position].asc) },
|
|
84
|
+
through: :variant_media, source: :asset, class_name: 'Spree::Media'
|
|
85
|
+
|
|
86
|
+
belongs_to :primary_media, class_name: 'Spree::Media', optional: true, foreign_key: :primary_media_id
|
|
62
87
|
|
|
63
|
-
|
|
88
|
+
# The variant's own image, or its product's when it has none — the
|
|
89
|
+
# picture a list row shows for it.
|
|
90
|
+
#
|
|
91
|
+
# @return [Spree::Media, nil]
|
|
92
|
+
def thumbnail
|
|
93
|
+
primary_media || product&.primary_media
|
|
94
|
+
end
|
|
64
95
|
|
|
65
96
|
has_many :prices,
|
|
66
97
|
class_name: 'Spree::Price',
|
|
@@ -68,50 +99,126 @@ module Spree
|
|
|
68
99
|
inverse_of: :variant,
|
|
69
100
|
autosave: true
|
|
70
101
|
|
|
71
|
-
has_many :
|
|
102
|
+
has_many :wishlist_items, class_name: 'Spree::WishlistItem', dependent: :destroy
|
|
103
|
+
has_many :wished_items, class_name: 'Spree::WishlistItem', inverse_of: :variant, deprecated: true
|
|
72
104
|
|
|
73
|
-
has_many :
|
|
105
|
+
has_many :digital_assets, class_name: 'Spree::DigitalAsset', dependent: :destroy
|
|
106
|
+
has_many :digitals, class_name: 'Spree::DigitalAsset', deprecated: true
|
|
74
107
|
|
|
75
108
|
before_validation :set_cost_currency
|
|
76
109
|
before_validation :apply_pending_options, if: :pending_options?
|
|
77
|
-
|
|
78
|
-
validate :check_price, if: -> { Spree::Config.enable_legacy_default_price }
|
|
79
|
-
|
|
80
|
-
validates :option_value_variants, presence: true, unless: :is_master?
|
|
110
|
+
before_validation :apply_pending_stock_levels, if: :pending_stock_levels?
|
|
81
111
|
|
|
82
112
|
validates :cost_price, numericality: { greater_than_or_equal_to: 0, allow_nil: true }
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
113
|
+
# Uniqueness is scoped to the seller — see #validate_sku_uniqueness. Written
|
|
114
|
+
# by hand rather than as a `scope:` option because the seller is resolved
|
|
115
|
+
# (the variant's own, else its product's) and the built-in validator reads
|
|
116
|
+
# the raw column, which would let two sellers who each own a whole product
|
|
117
|
+
# collide.
|
|
118
|
+
validate :validate_sku_uniqueness, if: -> { sku.present? && !disable_sku_validation? }
|
|
119
|
+
|
|
120
|
+
# Both guards catch raw prefixed-id assignment as well as association
|
|
121
|
+
# writes, the way the same pair does on Product: a seller or a shipping
|
|
122
|
+
# configuration from another store must never be reachable by id.
|
|
123
|
+
validate :seller_must_belong_to_store, if: -> { will_save_change_to_seller_id? }
|
|
124
|
+
validate :delivery_profile_must_belong_to_store, if: -> { will_save_change_to_delivery_profile_id? }
|
|
125
|
+
validate :carton_package_type_must_belong_to_store, if: -> { will_save_change_to_carton_package_type_id? }
|
|
126
|
+
|
|
127
|
+
# On an owned product the variant's own seller and profile columns carry
|
|
128
|
+
# no meaning — every variant is the product's seller's and ships as the
|
|
129
|
+
# product does — so they are kept blank rather than validated. A client
|
|
130
|
+
# that reads a resolved `seller_id` and writes it straight back therefore
|
|
131
|
+
# changes nothing, and the storefront never has to know which mode it is
|
|
132
|
+
# in. Only a variant on a master product keeps what it is given.
|
|
133
|
+
before_validation :blank_owned_product_overrides
|
|
87
134
|
|
|
88
135
|
validates :dimensions_unit, inclusion: { in: DIMENSION_UNITS }, allow_blank: true
|
|
89
136
|
validates :weight_unit, inclusion: { in: WEIGHT_UNITS }, allow_blank: true
|
|
90
137
|
|
|
91
138
|
validates :backorder_limit, numericality: { only_integer: true, greater_than_or_equal_to: 0, allow_nil: true }
|
|
92
139
|
|
|
93
|
-
|
|
94
|
-
|
|
140
|
+
# Base purchasing rules. Blank means unrestricted, so the columns start
|
|
141
|
+
# empty and every existing variant keeps buying one at a time.
|
|
142
|
+
validates :minimum_order_quantity, numericality: { only_integer: true, greater_than: 0, allow_nil: true }
|
|
143
|
+
validates :order_multiple, numericality: { only_integer: true, greater_than: 0, allow_nil: true }
|
|
144
|
+
validates :units_per_carton, numericality: { only_integer: true, greater_than: 0, allow_nil: true }
|
|
145
|
+
validates :cartons_per_pallet, numericality: { only_integer: true, greater_than: 0, allow_nil: true }
|
|
146
|
+
validates :carton_weight, numericality: { greater_than: 0, allow_nil: true }
|
|
147
|
+
validate :carton_package_type_is_a_carton
|
|
148
|
+
validates :purchase_unit, inclusion: { in: PURCHASE_UNITS }, allow_blank: true
|
|
149
|
+
|
|
150
|
+
# Both are data errors the merchant should hear about while editing, not
|
|
151
|
+
# discover through a customer complaint: an order multiple that straddles
|
|
152
|
+
# carton boundaries can never be shipped whole, and quoting cartons
|
|
153
|
+
# without saying how many units one holds leaves the storefront no way to
|
|
154
|
+
# render the offer.
|
|
155
|
+
validate :order_multiple_fits_cartons
|
|
156
|
+
validate :carton_purchase_unit_has_divisor
|
|
157
|
+
|
|
158
|
+
# Customs classification. Optional everywhere — only an international
|
|
159
|
+
# shipment or a duties provider needs it, and each raises its own error
|
|
160
|
+
# when it does. Carriers reject an HS code outside 6..13 digits, so the
|
|
161
|
+
# format is checked here rather than at the label counter.
|
|
162
|
+
validates :hs_code, format: { with: /\A\d{6,13}\z/ }, allow_blank: true
|
|
163
|
+
validates :country_of_origin, format: { with: /\A[A-Z]{2}\z/ }, allow_blank: true
|
|
164
|
+
|
|
165
|
+
after_create :create_stock_levels
|
|
95
166
|
after_commit :clear_line_items_cache, on: :update
|
|
96
167
|
|
|
97
|
-
after_save :
|
|
168
|
+
after_save :create_default_stock_level, unless: :track_inventory?
|
|
98
169
|
after_update_commit :handle_track_inventory_change
|
|
99
170
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
after_create :increment_product_variant_count, unless: :is_master?
|
|
103
|
-
after_destroy :decrement_product_variant_count, unless: :is_master?
|
|
171
|
+
after_create :increment_product_variant_count
|
|
172
|
+
after_destroy :decrement_product_variant_count
|
|
104
173
|
|
|
105
|
-
scope :in_stock, -> { left_joins(:
|
|
106
|
-
scope :backorderable, -> { left_joins(:
|
|
174
|
+
scope :in_stock, -> { left_joins(:stock_levels).where("#{Spree::Variant.table_name}.track_inventory = ? OR (#{Spree::StockLevel.table_name}.count_on_hand - #{Spree::StockLevel.table_name}.allocated_count) > ?", false, 0) }
|
|
175
|
+
scope :backorderable, -> { left_joins(:stock_levels).where(Spree::StockLevel.table_name => { backorderable: true }) }
|
|
107
176
|
scope :in_stock_or_backorderable, -> { in_stock.or(backorderable) }
|
|
108
177
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
178
|
+
# Variants one warehouse could actually send: it holds a level for them
|
|
179
|
+
# with something available on it. Written for the transfer form's picker,
|
|
180
|
+
# which would otherwise offer SKUs the source has none of — and
|
|
181
|
+
# `MarkInTransit` refuses those per line, once the van is supposedly
|
|
182
|
+
# loaded and the merchant has moved on.
|
|
183
|
+
#
|
|
184
|
+
# Untracked variants are excluded on purpose, unlike `in_stock`: a
|
|
185
|
+
# transfer moves counted units, and the ship guard would refuse them too.
|
|
186
|
+
#
|
|
187
|
+
# Takes a prefixed or a raw id — a ransackable scope decodes its own
|
|
188
|
+
# argument, since the controller only decodes keys carrying a predicate
|
|
189
|
+
# suffix.
|
|
190
|
+
scope :available_at_stock_location, ->(stock_location) {
|
|
191
|
+
levels = Spree::StockLevel.table_name
|
|
192
|
+
# Decoded against the stock location's own prefix, so another model's ID
|
|
193
|
+
# cannot resolve to a warehouse whose numeric payload happens to match.
|
|
194
|
+
# Anything that is neither that nor a raw id selects nothing rather than
|
|
195
|
+
# reaching the database, where a non-numeric value raises on PostgreSQL.
|
|
196
|
+
location_id = Spree::StockLocation.decode_own_prefixed_id(stock_location)
|
|
197
|
+
location_id ||= stock_location if stock_location.to_s.match?(/\A\d+\z/)
|
|
198
|
+
|
|
199
|
+
next none if location_id.blank?
|
|
200
|
+
|
|
201
|
+
joins(:stock_levels).
|
|
202
|
+
where(levels => { stock_location_id: location_id }).
|
|
203
|
+
where("#{levels}.count_on_hand - #{levels}.allocated_count > ?", 0)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
scope :eligible, -> { all }
|
|
207
|
+
|
|
208
|
+
# Variants whose *resolved* seller is the given one: their own column when
|
|
209
|
+
# set, otherwise their product's. Passing nil selects first-party listings,
|
|
210
|
+
# which on a store with no sellers is the whole catalog.
|
|
211
|
+
scope :for_seller, lambda { |seller|
|
|
212
|
+
seller_id = seller.respond_to?(:id) ? seller.id : seller
|
|
213
|
+
own = arel_table[:seller_id]
|
|
214
|
+
products = Spree::Product.arel_table[:seller_id]
|
|
215
|
+
|
|
216
|
+
relation = joins(:product)
|
|
217
|
+
if seller_id.nil?
|
|
218
|
+
relation.where(own.eq(nil).and(products.eq(nil)))
|
|
219
|
+
else
|
|
220
|
+
relation.where(own.eq(seller_id).or(own.eq(nil).and(products.eq(seller_id))))
|
|
221
|
+
end
|
|
115
222
|
}
|
|
116
223
|
|
|
117
224
|
scope :not_discontinued, lambda {
|
|
@@ -124,9 +231,15 @@ module Spree
|
|
|
124
231
|
|
|
125
232
|
scope :not_deleted, -> { where("#{Spree::Variant.quoted_table_name}.deleted_at IS NULL") }
|
|
126
233
|
|
|
234
|
+
# Variants the shop sells in this currency. Base prices only: a price
|
|
235
|
+
# list's rows are what one audience pays under an agreement, and a ladder
|
|
236
|
+
# holds several rows for one variant, so a contract-only variant is not
|
|
237
|
+
# available to everyone (docs/plans/6.0-volume-pricing.md).
|
|
127
238
|
scope :for_currency_and_available_price_amount, lambda { |currency = nil|
|
|
128
239
|
currency ||= Spree::Store.default.default_currency
|
|
129
|
-
joins(:prices).
|
|
240
|
+
joins(:prices).
|
|
241
|
+
where(Spree::Price.table_name => { currency: currency, price_list_id: nil }).
|
|
242
|
+
where("#{Spree::Price.table_name}.amount IS NOT NULL").distinct
|
|
130
243
|
}
|
|
131
244
|
|
|
132
245
|
scope :active, lambda { |currency = nil|
|
|
@@ -135,13 +248,18 @@ module Spree
|
|
|
135
248
|
}
|
|
136
249
|
|
|
137
250
|
scope :with_option_value, lambda { |option_name, option_value|
|
|
138
|
-
|
|
251
|
+
# Option types are per store, so two stores may each define `size`;
|
|
252
|
+
# narrow to the store in context so a filter never matches another
|
|
253
|
+
# store's values.
|
|
254
|
+
option_types = OptionType.where(name: option_name)
|
|
255
|
+
option_types = option_types.where(store_id: Spree::Current.store.id) if Spree::Current.store
|
|
256
|
+
option_type_ids = option_types.ids
|
|
139
257
|
return none if option_type_ids.empty?
|
|
140
258
|
|
|
141
259
|
joins(:option_values).where(Spree::OptionValue.table_name => { name: option_value, option_type_id: option_type_ids })
|
|
142
260
|
}
|
|
143
261
|
|
|
144
|
-
scope :with_digital_assets, -> { joins(:
|
|
262
|
+
scope :with_digital_assets, -> { joins(:digital_assets) }
|
|
145
263
|
|
|
146
264
|
# Free-text variant search: SKU, parent product name, and any
|
|
147
265
|
# option-value presentation (e.g. "Red", "XL"). The 3-char floor
|
|
@@ -151,7 +269,7 @@ module Spree
|
|
|
151
269
|
|
|
152
270
|
conditions = [
|
|
153
271
|
search_condition(self, :sku, query),
|
|
154
|
-
search_condition(Spree::OptionValue, :
|
|
272
|
+
search_condition(Spree::OptionValue, :label, query),
|
|
155
273
|
]
|
|
156
274
|
|
|
157
275
|
if Spree.use_translations?
|
|
@@ -180,7 +298,7 @@ module Spree
|
|
|
180
298
|
end
|
|
181
299
|
|
|
182
300
|
accepts_nested_attributes_for(
|
|
183
|
-
:
|
|
301
|
+
:stock_levels,
|
|
184
302
|
reject_if: ->(attributes) { attributes['stock_location_id'].blank? || attributes['count_on_hand'].blank? },
|
|
185
303
|
allow_destroy: false
|
|
186
304
|
)
|
|
@@ -197,10 +315,21 @@ module Spree
|
|
|
197
315
|
allow_destroy: false
|
|
198
316
|
)
|
|
199
317
|
|
|
200
|
-
self.whitelisted_ransackable_associations = %w[option_values product tax_category prices
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
318
|
+
self.whitelisted_ransackable_associations = %w[option_values product tax_category prices seller]
|
|
319
|
+
# `seller_id` and `delivery_profile_id` are deliberately absent: they are
|
|
320
|
+
# the raw columns, nil on every variant that inherits from its product —
|
|
321
|
+
# so "filter by seller" against them would silently miss the inheritors,
|
|
322
|
+
# which on a single-owner catalog is all of them. Server-side callers
|
|
323
|
+
# narrow by seller with the `for_seller` scope, which resolves the way
|
|
324
|
+
# `resolved_seller` does; a client-facing filter needs an endpoint that
|
|
325
|
+
# applies it, not an allowlist entry that quietly answers a different
|
|
326
|
+
# question.
|
|
327
|
+
self.whitelisted_ransackable_attributes = %w[weight depth width height sku discontinue_on cost_price cost_currency track_inventory
|
|
328
|
+
deleted_at product_id hs_code country_of_origin
|
|
329
|
+
minimum_order_quantity order_multiple purchase_unit units_per_carton
|
|
330
|
+
carton_package_type_id carton_weight cartons_per_pallet]
|
|
331
|
+
self.whitelisted_ransackable_scopes = %i(product_name_or_sku_cont search_by_product_name_or_sku search
|
|
332
|
+
available_at_stock_location)
|
|
204
333
|
|
|
205
334
|
def self.product_name_or_sku_cont(query)
|
|
206
335
|
sanitized_query = ActiveRecord::Base.sanitize_sql_like(query.to_s.downcase.strip)
|
|
@@ -231,7 +360,7 @@ module Spree
|
|
|
231
360
|
joins(option_type: :product_option_types).
|
|
232
361
|
merge(product.product_option_types).
|
|
233
362
|
reorder('spree_product_option_types.position').
|
|
234
|
-
pluck(:
|
|
363
|
+
pluck(:label).join('/')
|
|
235
364
|
end
|
|
236
365
|
|
|
237
366
|
# Returns true if the variant is available.
|
|
@@ -279,16 +408,72 @@ module Spree
|
|
|
279
408
|
end
|
|
280
409
|
end
|
|
281
410
|
|
|
411
|
+
# Who sells this variant. Two modes, and they never mix:
|
|
412
|
+
#
|
|
413
|
+
# * An OWNED product (`product.seller_id` set) — every variant is that
|
|
414
|
+
# seller's, by definition. No other seller can create a variant here, so
|
|
415
|
+
# the variant's own column is meaningless and is kept blank.
|
|
416
|
+
# * A MASTER product (`product.seller_id` nil) — the shared catalog. This
|
|
417
|
+
# is the only place `variant.seller_id` means anything: several sellers
|
|
418
|
+
# list variants on one page, and each row names its own.
|
|
419
|
+
#
|
|
420
|
+
# So the answer is the product's seller if it has one, else the variant's
|
|
421
|
+
# own — a plain read, not an inheritance chain. Line items snapshot it at
|
|
422
|
+
# add-to-cart, and the buy box and SKU check read it. Nil is first-party.
|
|
423
|
+
#
|
|
424
|
+
# @return [Spree::Seller, nil]
|
|
425
|
+
def resolved_seller
|
|
426
|
+
product&.seller || seller
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
# @return [Integer, nil]
|
|
430
|
+
def resolved_seller_id
|
|
431
|
+
product&.seller_id || self[:seller_id]
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
# Whether this variant sits on an owned product — the mode in which the
|
|
435
|
+
# variant's own seller and delivery-profile columns carry no meaning.
|
|
436
|
+
#
|
|
437
|
+
# @return [Boolean]
|
|
438
|
+
def owned_by_product_seller?
|
|
439
|
+
product&.seller_id.present?
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
# How this variant ships, on the same two-mode rule as the seller, keyed
|
|
443
|
+
# on OWNERSHIP rather than on whether the product has a profile — every
|
|
444
|
+
# product does, so "product's profile if set" would never reach the
|
|
445
|
+
# variant's own and no seller on a master could ship differently.
|
|
446
|
+
#
|
|
447
|
+
# * Owned product: every variant ships as the product does; the variant's
|
|
448
|
+
# own column is meaningless and is kept blank.
|
|
449
|
+
# * Master product: each seller's row names how that seller ships, and
|
|
450
|
+
# falls back to the master's profile when it does not.
|
|
451
|
+
#
|
|
452
|
+
# A plain read, not memoized.
|
|
453
|
+
#
|
|
454
|
+
# @return [Spree::DeliveryProfile, nil]
|
|
455
|
+
def resolved_delivery_profile
|
|
456
|
+
return product&.resolved_delivery_profile if owned_by_product_seller?
|
|
457
|
+
|
|
458
|
+
delivery_profile || product&.resolved_delivery_profile
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
# @return [Integer, nil]
|
|
462
|
+
def resolved_delivery_profile_id
|
|
463
|
+
resolved_delivery_profile&.id
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
|
|
282
467
|
# Returns the options text of the variant.
|
|
283
468
|
# @return [String] the options text of the variant
|
|
284
469
|
def options_text
|
|
285
470
|
@options_text ||= if option_values.loaded?
|
|
286
471
|
option_values.sort_by do |ov|
|
|
287
472
|
ov.option_type.position
|
|
288
|
-
end.map { |ov| "#{ov.option_type.
|
|
473
|
+
end.map { |ov| "#{ov.option_type.label}: #{ov.label}" }.to_sentence(words_connector: ', ', two_words_connector: ', ')
|
|
289
474
|
else
|
|
290
475
|
option_values.includes(:option_type).joins(:option_type).order("#{Spree::OptionType.table_name}.position").map do |ov|
|
|
291
|
-
"#{ov.option_type.
|
|
476
|
+
"#{ov.option_type.label}: #{ov.label}"
|
|
292
477
|
end.to_sentence(words_connector: ', ', two_words_connector: ', ')
|
|
293
478
|
end
|
|
294
479
|
end
|
|
@@ -296,13 +481,21 @@ module Spree
|
|
|
296
481
|
# Returns the exchange name of the variant.
|
|
297
482
|
# @return [String] the exchange name of the variant
|
|
298
483
|
def exchange_name
|
|
299
|
-
|
|
484
|
+
option_values.any? ? options_text : name
|
|
300
485
|
end
|
|
301
486
|
|
|
302
487
|
# Returns the descriptive name of the variant.
|
|
303
488
|
# @return [String] the descriptive name of the variant
|
|
304
489
|
def descriptive_name
|
|
305
|
-
|
|
490
|
+
option_values.any? ? "#{name} - #{options_text}" : name
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
# Plain-language contents description for a customs declaration. Customs
|
|
494
|
+
# authorities reject marketing names, so merchants set an explicit one;
|
|
495
|
+
# the product name is the fallback that keeps a declaration valid.
|
|
496
|
+
# @return [String, nil]
|
|
497
|
+
def customs_description_for_declaration
|
|
498
|
+
customs_description.presence || name
|
|
306
499
|
end
|
|
307
500
|
|
|
308
501
|
# Returns the variant's media gallery.
|
|
@@ -335,42 +528,45 @@ module Spree
|
|
|
335
528
|
variant_media.exists?
|
|
336
529
|
end
|
|
337
530
|
|
|
338
|
-
# @deprecated Use #primary_media instead.
|
|
339
|
-
def default_image
|
|
340
|
-
Spree::Deprecation.warn('Spree::Variant#default_image is deprecated and will be removed in Spree 6.0. Please use Spree::Variant#primary_media instead.')
|
|
341
|
-
primary_media
|
|
342
|
-
end
|
|
343
|
-
|
|
344
531
|
# Updates primary_media_id to the first media item by position.
|
|
345
532
|
# Called when media is added, removed, or reordered.
|
|
346
533
|
# Uses gallery_media so product-level assets linked via VariantMedia are
|
|
347
534
|
# considered alongside legacy variant-pinned images.
|
|
348
535
|
def update_thumbnail!
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
536
|
+
# Read through a fresh scope, never the cached association — this runs
|
|
537
|
+
# from a media row's after_commit, and a loaded `images`/`associated_media`
|
|
538
|
+
# would be missing the sibling rows created after it.
|
|
539
|
+
candidates = gallery_media.reload.to_a
|
|
540
|
+
# See Product#update_thumbnail! — a video without a still can't be a thumbnail.
|
|
541
|
+
first_media = candidates.find(&:renderable_as_image?)
|
|
352
542
|
|
|
353
|
-
|
|
354
|
-
# @deprecated Use #primary_media instead.
|
|
355
|
-
# @return [Spree::Image, nil]
|
|
356
|
-
def primary_image
|
|
357
|
-
Spree::Deprecation.warn('Spree::Variant#primary_image is deprecated and will be removed in Spree 6.0. Please use Spree::Variant#primary_media instead.')
|
|
358
|
-
primary_media
|
|
543
|
+
update_column(:primary_media_id, first_media&.id)
|
|
359
544
|
end
|
|
360
545
|
|
|
361
|
-
#
|
|
362
|
-
#
|
|
546
|
+
# @deprecated Read #gallery_media directly; removed in 6.1. Nothing in
|
|
547
|
+
# Spree calls this — a hover image is a storefront presentation choice,
|
|
548
|
+
# not something core should name.
|
|
549
|
+
# @return [Spree::Media, nil]
|
|
363
550
|
def secondary_image
|
|
364
|
-
|
|
551
|
+
Spree::Deprecation.warn('Spree::Variant#secondary_image is deprecated and will be removed in Spree 6.1. Use #gallery_media instead.')
|
|
552
|
+
gallery_media.second
|
|
365
553
|
end
|
|
366
554
|
|
|
367
|
-
#
|
|
368
|
-
#
|
|
555
|
+
# @deprecated Read #gallery_media directly; removed in 6.1. Nothing in
|
|
556
|
+
# Spree calls this, and which images to show beside the main one is a
|
|
557
|
+
# storefront presentation choice.
|
|
558
|
+
# @return [Array<Spree::Media>]
|
|
369
559
|
def additional_images
|
|
370
|
-
|
|
560
|
+
Spree::Deprecation.warn('Spree::Variant#additional_images is deprecated and will be removed in Spree 6.1. Use #gallery_media instead.')
|
|
561
|
+
gallery_media.reject { |media| media.id == primary_media&.id }
|
|
371
562
|
end
|
|
372
563
|
|
|
373
|
-
# Returns an array of hashes with the option type name, value and
|
|
564
|
+
# Returns an array of hashes with the option type name, value and label.
|
|
565
|
+
#
|
|
566
|
+
# The +presentation+ key keeps its name through the 6.0 column rename: it
|
|
567
|
+
# is a return shape host apps read, nothing in Spree consumes it, and a
|
|
568
|
+
# renamed hash key breaks silently.
|
|
569
|
+
#
|
|
374
570
|
# @return [Array<Hash>]
|
|
375
571
|
def options
|
|
376
572
|
@options ||= option_values.
|
|
@@ -381,7 +577,7 @@ module Spree
|
|
|
381
577
|
{
|
|
382
578
|
name: option_value.option_type.name,
|
|
383
579
|
value: option_value.name,
|
|
384
|
-
presentation: option_value.
|
|
580
|
+
presentation: option_value.label
|
|
385
581
|
}
|
|
386
582
|
end
|
|
387
583
|
end
|
|
@@ -408,11 +604,8 @@ module Spree
|
|
|
408
604
|
# @param opt_type_position [Integer] the position of the option type
|
|
409
605
|
# @return [void]
|
|
410
606
|
def set_option_value(opt_name, opt_value, opt_type_position = nil)
|
|
411
|
-
# no option values on master
|
|
412
|
-
return if is_master
|
|
413
|
-
|
|
414
607
|
option_type = Spree::OptionType.where(name: opt_name.parameterize).first_or_initialize do |o|
|
|
415
|
-
o.name = o.
|
|
608
|
+
o.name = o.label = opt_name
|
|
416
609
|
o.save!
|
|
417
610
|
end
|
|
418
611
|
|
|
@@ -435,7 +628,7 @@ module Spree
|
|
|
435
628
|
end
|
|
436
629
|
|
|
437
630
|
option_value = option_type.option_values.where(name: opt_value.parameterize).first_or_initialize do |o|
|
|
438
|
-
o.name = o.
|
|
631
|
+
o.name = o.label = opt_value
|
|
439
632
|
o.save!
|
|
440
633
|
end
|
|
441
634
|
|
|
@@ -455,9 +648,9 @@ module Spree
|
|
|
455
648
|
# @return [String] the presentation of the option value for the given option type
|
|
456
649
|
def option_value(option_type)
|
|
457
650
|
if option_type.is_a?(Spree::OptionType)
|
|
458
|
-
option_values.detect { |o| o.option_type_id == option_type.id }.try(:
|
|
651
|
+
option_values.detect { |o| o.option_type_id == option_type.id }.try(:label)
|
|
459
652
|
else
|
|
460
|
-
find_option_value(option_type).try(:
|
|
653
|
+
find_option_value(option_type).try(:label)
|
|
461
654
|
end
|
|
462
655
|
end
|
|
463
656
|
|
|
@@ -530,22 +723,69 @@ module Spree
|
|
|
530
723
|
# Syncs stock items from an array of hashes.
|
|
531
724
|
# Upserts stock for listed locations, soft-deletes stock items for unlisted locations.
|
|
532
725
|
# On new records, defers to after_create callback.
|
|
533
|
-
# @param
|
|
726
|
+
# @param stock_levels_params [Array<Hash>] array of { stock_location_id:, count_on_hand:, backorderable: }
|
|
534
727
|
# @return [void]
|
|
535
|
-
def
|
|
536
|
-
return super if
|
|
728
|
+
def stock_levels=(stock_levels_params)
|
|
729
|
+
return super if stock_levels_params.blank? || stock_levels_params.first.is_a?(Spree::StockLevel)
|
|
730
|
+
return if defer_stock_levels(:stock_levels=, stock_levels_params)
|
|
537
731
|
|
|
538
732
|
location_ids_in_payload = []
|
|
539
733
|
|
|
540
|
-
|
|
734
|
+
stock_levels_params.each do |stock_data|
|
|
541
735
|
stock_data = stock_data.to_h.with_indifferent_access
|
|
542
|
-
location =
|
|
736
|
+
location = stock_location_for_param(stock_data[:stock_location_id])
|
|
737
|
+
# A stale or foreign location id is skipped rather than raising, which
|
|
738
|
+
# is what #stock_levels_attributes= already does for the same payload.
|
|
739
|
+
next if location.nil?
|
|
740
|
+
|
|
543
741
|
location_ids_in_payload << location.id
|
|
544
742
|
set_stock(stock_data[:count_on_hand], stock_data[:backorderable], location)
|
|
545
743
|
end
|
|
546
744
|
|
|
547
|
-
# Soft-delete stock
|
|
548
|
-
|
|
745
|
+
# Soft-delete stock levels for locations not in the payload
|
|
746
|
+
stock_levels.where.not(stock_location_id: location_ids_in_payload).destroy_all if persisted?
|
|
747
|
+
end
|
|
748
|
+
|
|
749
|
+
# @deprecated Use {#stock_levels}; removed in 6.1.
|
|
750
|
+
def stock_items
|
|
751
|
+
Spree::Deprecation.warn('Spree::Variant#stock_items is deprecated and will be removed in Spree 6.1. Use #stock_levels instead.')
|
|
752
|
+
stock_levels
|
|
753
|
+
end
|
|
754
|
+
|
|
755
|
+
# @deprecated Use {#stock_levels=}; removed in 6.1.
|
|
756
|
+
def stock_items=(value)
|
|
757
|
+
Spree::Deprecation.warn('Spree::Variant#stock_items= is deprecated and will be removed in Spree 6.1. Use #stock_levels= instead.')
|
|
758
|
+
self.stock_levels = value
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
# The v3 API sends `stock_levels: [...]`, which the params normalizer
|
|
762
|
+
# rewrites to nested attributes — and Rails would then write count_on_hand
|
|
763
|
+
# straight onto the row. Each entry is routed through {#set_stock} instead,
|
|
764
|
+
# so a count typed in the dashboard lands in the stock history like every
|
|
765
|
+
# other change. Entries are upserted and never removed, which is what
|
|
766
|
+
# accepts_nested_attributes_for did here.
|
|
767
|
+
#
|
|
768
|
+
# @param rows [Array<Hash>, Hash]
|
|
769
|
+
# @return [void]
|
|
770
|
+
def stock_levels_attributes=(rows)
|
|
771
|
+
rows = rows.values if rows.respond_to?(:values) && !rows.is_a?(Array)
|
|
772
|
+
return if defer_stock_levels(:stock_levels_attributes=, rows)
|
|
773
|
+
|
|
774
|
+
Array.wrap(rows).each do |row|
|
|
775
|
+
row = (row.respond_to?(:to_unsafe_h) ? row.to_unsafe_h : row.to_h).with_indifferent_access
|
|
776
|
+
next if row[:stock_location_id].blank? || row[:count_on_hand].blank?
|
|
777
|
+
|
|
778
|
+
stock_location = stock_location_for_param(row[:stock_location_id])
|
|
779
|
+
next if stock_location.nil?
|
|
780
|
+
|
|
781
|
+
set_stock(row[:count_on_hand], row[:backorderable], stock_location)
|
|
782
|
+
end
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
# @deprecated Use +stock_levels_attributes=+; removed in 6.1.
|
|
786
|
+
def stock_items_attributes=(value)
|
|
787
|
+
Spree::Deprecation.warn('Spree::Variant#stock_items_attributes= is deprecated and will be removed in Spree 6.1. Use #stock_levels_attributes= instead.')
|
|
788
|
+
self.stock_levels_attributes = value
|
|
549
789
|
end
|
|
550
790
|
|
|
551
791
|
# Sets the base price (global price, not for a price list) for the given currency.
|
|
@@ -556,26 +796,49 @@ module Spree
|
|
|
556
796
|
def set_price(currency, amount, compare_at_amount = nil)
|
|
557
797
|
# When the prices association is already loaded (eager-loaded for
|
|
558
798
|
# serialization), reuse the cached base-price instance so readers that
|
|
559
|
-
# branch on `prices.loaded?` (
|
|
799
|
+
# branch on `prices.loaded?` (the Internal provider's resolution,
|
|
800
|
+
# #price_in, serializers)
|
|
560
801
|
# observe the write without a reload. `base_prices.find_or_initialize_by`
|
|
561
802
|
# would issue a fresh query and return a detached object, leaving the
|
|
562
803
|
# loaded collection — and the serialized response — stale.
|
|
563
|
-
|
|
804
|
+
existing =
|
|
564
805
|
if prices.loaded?
|
|
565
|
-
prices.detect { |p| p.price_list_id.nil? && p.currency == currency }
|
|
566
|
-
prices.build(currency: currency)
|
|
806
|
+
prices.detect { |p| p.price_list_id.nil? && p.currency == currency }
|
|
567
807
|
else
|
|
568
|
-
prices.base_prices.
|
|
808
|
+
prices.base_prices.find_by(currency: currency)
|
|
569
809
|
end
|
|
570
810
|
|
|
811
|
+
# A blank amount means the merchant left that currency empty, which is
|
|
812
|
+
# the same statement as leaving it out of the payload: there is no base
|
|
813
|
+
# price in this currency. Writing it would persist a nil amount, and a
|
|
814
|
+
# base price (unlike a price-list placeholder) must have one.
|
|
815
|
+
if amount.blank?
|
|
816
|
+
return if existing.nil?
|
|
817
|
+
|
|
818
|
+
prices.delete(existing) if prices.loaded?
|
|
819
|
+
existing.destroy if existing.persisted?
|
|
820
|
+
return
|
|
821
|
+
end
|
|
822
|
+
|
|
823
|
+
price = existing || if prices.loaded?
|
|
824
|
+
prices.build(currency: currency)
|
|
825
|
+
else
|
|
826
|
+
prices.base_prices.build(currency: currency)
|
|
827
|
+
end
|
|
828
|
+
|
|
571
829
|
price.amount = amount
|
|
572
830
|
price.compare_at_amount = compare_at_amount
|
|
573
831
|
price.save! if persisted?
|
|
574
832
|
end
|
|
575
833
|
|
|
576
834
|
# Returns the price for the given context or options.
|
|
835
|
+
#
|
|
836
|
+
# Answered by the store's pricing provider, which is Spree's own resolver
|
|
837
|
+
# unless a connector has been configured. An external provider's price is
|
|
838
|
+
# an unsaved, readonly Spree::Price — see Spree::PricingProvider::Base.
|
|
839
|
+
#
|
|
577
840
|
# @param context_or_options [Spree::Pricing::Context|Hash] the context or options to get the price for
|
|
578
|
-
# @return [Spree::Price] the price for the given context or options
|
|
841
|
+
# @return [Spree::Price, nil] the price for the given context or options
|
|
579
842
|
def price_for(context_or_options)
|
|
580
843
|
context = if context_or_options.is_a?(Spree::Pricing::Context)
|
|
581
844
|
context_or_options
|
|
@@ -585,21 +848,37 @@ module Spree
|
|
|
585
848
|
raise ArgumentError, 'Must provide a Pricing::Context or options hash'
|
|
586
849
|
end
|
|
587
850
|
|
|
588
|
-
Spree::Pricing::
|
|
851
|
+
Spree::Pricing::PriceResolution.call(context)
|
|
589
852
|
end
|
|
590
853
|
|
|
591
|
-
# Sets the
|
|
592
|
-
#
|
|
593
|
-
#
|
|
594
|
-
#
|
|
595
|
-
#
|
|
854
|
+
# Sets the count at a location. The correction goes through an `adjusted`
|
|
855
|
+
# movement so it shows up in the stock history like every other change.
|
|
856
|
+
# A count below zero is refused whatever the variant's backorder settings
|
|
857
|
+
# say, so a caller passing one gets ActiveRecord::RecordInvalid.
|
|
858
|
+
#
|
|
859
|
+
# @param count_on_hand [Integer] the count the level should end up at
|
|
860
|
+
# @param backorderable [Boolean, nil] left as it is when nil
|
|
861
|
+
# @param stock_location [Spree::StockLocation, nil] defaults to the store's
|
|
596
862
|
# @return [void]
|
|
597
863
|
def set_stock(count_on_hand, backorderable = nil, stock_location = nil)
|
|
598
864
|
stock_location ||= default_stock_location
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
865
|
+
stock_level = stock_levels.find_or_initialize_by(stock_location: stock_location)
|
|
866
|
+
# `unless nil?`, not `if present?` — a caller passing false means it.
|
|
867
|
+
stock_level.backorderable = backorderable unless backorderable.nil?
|
|
868
|
+
|
|
869
|
+
# Nothing is saved yet, so the count rides on the in-memory record and
|
|
870
|
+
# the autosave association persists it with the variant.
|
|
871
|
+
unless persisted?
|
|
872
|
+
stock_level.count_on_hand = count_on_hand
|
|
873
|
+
return
|
|
874
|
+
end
|
|
875
|
+
|
|
876
|
+
stock_level.save! if stock_level.changed?
|
|
877
|
+
|
|
878
|
+
delta = count_on_hand.to_i - stock_level.count_on_hand.to_i
|
|
879
|
+
return if delta.zero?
|
|
880
|
+
|
|
881
|
+
stock_location.adjust(self, delta, reason: Spree::StockMovement.default_adjustment_reason)
|
|
603
882
|
end
|
|
604
883
|
|
|
605
884
|
def default_stock_location
|
|
@@ -678,13 +957,25 @@ module Spree
|
|
|
678
957
|
end
|
|
679
958
|
|
|
680
959
|
# Shortcut method to determine if inventory tracking is enabled for this variant
|
|
681
|
-
# This considers both variant tracking flag and
|
|
960
|
+
# This considers both the variant tracking flag and the store's setting
|
|
682
961
|
def should_track_inventory?
|
|
683
|
-
track_inventory? &&
|
|
962
|
+
track_inventory? && store_preference(:track_inventory_levels)
|
|
963
|
+
end
|
|
964
|
+
|
|
965
|
+
# Variants carry no store of their own; the product owns it.
|
|
966
|
+
# @return [Spree::Store, nil]
|
|
967
|
+
def preference_store
|
|
968
|
+
product&.store
|
|
684
969
|
end
|
|
685
970
|
|
|
971
|
+
# The cubic meters one unit of this variant occupies. Multiplying the
|
|
972
|
+
# raw dimension columns would answer in whatever unit the merchant typed,
|
|
973
|
+
# which is a sixteenfold error between inches and centimeters — so the
|
|
974
|
+
# name means CBM everywhere it appears (Variant, ContentItem, Package).
|
|
975
|
+
#
|
|
976
|
+
# @return [BigDecimal]
|
|
686
977
|
def volume
|
|
687
|
-
(width
|
|
978
|
+
Spree::Measurement.cubic_meters(width, height, depth, unit: dimensions_unit) || 0
|
|
688
979
|
end
|
|
689
980
|
|
|
690
981
|
def dimension
|
|
@@ -693,8 +984,33 @@ module Spree
|
|
|
693
984
|
|
|
694
985
|
# Returns the weight unit for the variant
|
|
695
986
|
# @return [String]
|
|
987
|
+
# Falls back to the variant's own store, like {#dimensions_unit} below —
|
|
988
|
+
# on a multi-store install the default store's unit is someone else's,
|
|
989
|
+
# and converting a kilogram catalog as pounds misweighs every quote.
|
|
696
990
|
def weight_unit
|
|
697
|
-
attributes['weight_unit'] || Spree::Store.default
|
|
991
|
+
attributes['weight_unit'] || (preference_store || Spree::Store.default)&.preferred_weight_unit
|
|
992
|
+
end
|
|
993
|
+
|
|
994
|
+
# The unit this variant's width/height/depth are expressed in. Falls back
|
|
995
|
+
# to what the store's unit system implies, which is what every other
|
|
996
|
+
# dimension in the store already means — there is no separate store
|
|
997
|
+
# preference for it, so a second settable value cannot contradict the
|
|
998
|
+
# first. Mirrors {#weight_unit}, which has always resolved this way.
|
|
999
|
+
#
|
|
1000
|
+
# Surfaces that show or export what the merchant actually stored — the CSV
|
|
1001
|
+
# export, so a round-trip does not stamp one store's unit onto every
|
|
1002
|
+
# variant — read the raw column instead.
|
|
1003
|
+
#
|
|
1004
|
+
# @return [String] one of {DIMENSION_UNITS}
|
|
1005
|
+
def dimensions_unit
|
|
1006
|
+
attributes['dimensions_unit'].presence || self.class.store_dimensions_unit(preference_store)
|
|
1007
|
+
end
|
|
1008
|
+
|
|
1009
|
+
# @param store [Spree::Store, nil]
|
|
1010
|
+
# @return [String]
|
|
1011
|
+
def self.store_dimensions_unit(store)
|
|
1012
|
+
store ||= Spree::Store.default
|
|
1013
|
+
store&.metric_unit_system? ? 'cm' : 'in'
|
|
698
1014
|
end
|
|
699
1015
|
|
|
700
1016
|
def discontinue!
|
|
@@ -706,22 +1022,137 @@ module Spree
|
|
|
706
1022
|
end
|
|
707
1023
|
|
|
708
1024
|
def backordered?
|
|
709
|
-
@backordered ||= !in_stock? &&
|
|
1025
|
+
@backordered ||= !in_stock? && stock_levels.exists?(backorderable: true)
|
|
710
1026
|
end
|
|
711
1027
|
|
|
712
1028
|
# Is this variant purely digital? (no physical product)
|
|
713
1029
|
#
|
|
1030
|
+
# Answered by the variant's own profile so a download and its printed
|
|
1031
|
+
# edition can sit on one product — the profile kind declares it, here as
|
|
1032
|
+
# everywhere else.
|
|
1033
|
+
#
|
|
714
1034
|
# @return [Boolean]
|
|
715
1035
|
def digital?
|
|
716
|
-
|
|
1036
|
+
!!resolved_delivery_profile&.digital?
|
|
717
1037
|
end
|
|
718
1038
|
|
|
719
1039
|
def with_digital_assets?
|
|
720
|
-
|
|
1040
|
+
digital_assets.any?
|
|
1041
|
+
end
|
|
1042
|
+
|
|
1043
|
+
# The variant's own purchasing rules — the base every cart obeys, and the
|
|
1044
|
+
# floor a buyer falls back to when their catalogs state nothing. A buyer's
|
|
1045
|
+
# effective rules resolve through {Spree::Catalogs::ResolveQuantityRules};
|
|
1046
|
+
# nothing below the cart layer reads either.
|
|
1047
|
+
#
|
|
1048
|
+
# @return [Spree::QuantityRule]
|
|
1049
|
+
def quantity_rule
|
|
1050
|
+
Spree::QuantityRule.new(
|
|
1051
|
+
minimum_order_quantity: minimum_order_quantity,
|
|
1052
|
+
order_multiple: order_multiple
|
|
1053
|
+
)
|
|
1054
|
+
end
|
|
1055
|
+
|
|
1056
|
+
# True when this variant is quoted in cartons rather than units. Requires
|
|
1057
|
+
# +units_per_carton+, which the validation above guarantees.
|
|
1058
|
+
#
|
|
1059
|
+
# @return [Boolean]
|
|
1060
|
+
def sold_by_carton?
|
|
1061
|
+
purchase_unit == 'carton' && units_per_carton.to_i.positive?
|
|
1062
|
+
end
|
|
1063
|
+
|
|
1064
|
+
# How many cartons a unit quantity fills, rounded up — a part carton still
|
|
1065
|
+
# ships as a carton. Nil when the variant declares no carton size.
|
|
1066
|
+
#
|
|
1067
|
+
# @param quantity [Integer]
|
|
1068
|
+
# @return [Integer, nil]
|
|
1069
|
+
def cartons_for(quantity)
|
|
1070
|
+
return nil unless units_per_carton.to_i.positive?
|
|
1071
|
+
|
|
1072
|
+
(quantity.to_i / units_per_carton.to_f).ceil
|
|
1073
|
+
end
|
|
1074
|
+
|
|
1075
|
+
# The cubic meters one packed carton of this variant occupies. Geometry
|
|
1076
|
+
# comes from the shared carton row, so correcting a carton size fixes
|
|
1077
|
+
# every product packed in it.
|
|
1078
|
+
#
|
|
1079
|
+
# @return [BigDecimal, nil]
|
|
1080
|
+
def carton_volume
|
|
1081
|
+
carton_package_type&.volume
|
|
1082
|
+
end
|
|
1083
|
+
|
|
1084
|
+
# How many units a full pallet of this variant holds. Nil unless both
|
|
1085
|
+
# halves of the chain are recorded.
|
|
1086
|
+
#
|
|
1087
|
+
# @return [Integer, nil]
|
|
1088
|
+
def units_per_pallet
|
|
1089
|
+
return if units_per_carton.to_i.zero? || cartons_per_pallet.to_i.zero?
|
|
1090
|
+
|
|
1091
|
+
units_per_carton * cartons_per_pallet
|
|
721
1092
|
end
|
|
722
1093
|
|
|
723
1094
|
private
|
|
724
1095
|
|
|
1096
|
+
def order_multiple_fits_cartons
|
|
1097
|
+
return if order_multiple.to_i.zero? || units_per_carton.to_i.zero?
|
|
1098
|
+
return if (order_multiple % units_per_carton).zero? || (units_per_carton % order_multiple).zero?
|
|
1099
|
+
|
|
1100
|
+
errors.add(:order_multiple, :incompatible_with_carton, units_per_carton: units_per_carton)
|
|
1101
|
+
end
|
|
1102
|
+
|
|
1103
|
+
# A pallet or a shipping box is not what a product is packed into; only
|
|
1104
|
+
# a carton row can stand in this slot.
|
|
1105
|
+
def carton_package_type_is_a_carton
|
|
1106
|
+
return if carton_package_type.blank? || carton_package_type.carton?
|
|
1107
|
+
|
|
1108
|
+
errors.add(:carton_package_type, :must_be_a_carton)
|
|
1109
|
+
end
|
|
1110
|
+
|
|
1111
|
+
def carton_purchase_unit_has_divisor
|
|
1112
|
+
return unless purchase_unit == 'carton'
|
|
1113
|
+
return if units_per_carton.to_i.positive?
|
|
1114
|
+
|
|
1115
|
+
errors.add(:units_per_carton, :required_for_carton_purchase_unit)
|
|
1116
|
+
end
|
|
1117
|
+
|
|
1118
|
+
# Resolved through the product's own store, because
|
|
1119
|
+
# +Spree::StockLocation.find_by_param+ is global: an id belonging to another
|
|
1120
|
+
# store would otherwise resolve and put this variant's stock in that store's
|
|
1121
|
+
# warehouse. There is no global fallback — a variant is only reachable
|
|
1122
|
+
# through a product, and a product belongs to a store.
|
|
1123
|
+
#
|
|
1124
|
+
# @param param [String, Integer, nil] prefixed or raw stock location id
|
|
1125
|
+
# @return [Spree::StockLocation, nil]
|
|
1126
|
+
def stock_location_for_param(param)
|
|
1127
|
+
return if param.blank?
|
|
1128
|
+
|
|
1129
|
+
product&.store&.stock_locations&.find_by_param(param)
|
|
1130
|
+
end
|
|
1131
|
+
|
|
1132
|
+
# +product.variants.create(stock_levels_attributes: …)+ assigns attributes
|
|
1133
|
+
# before Rails wires the owner, so the store these location ids have to be
|
|
1134
|
+
# scoped against is not known yet. The payload waits for the product rather
|
|
1135
|
+
# than resolving against every warehouse in the installation.
|
|
1136
|
+
#
|
|
1137
|
+
# @return [Boolean] true when the write was deferred
|
|
1138
|
+
def defer_stock_levels(writer, payload)
|
|
1139
|
+
return false if product.present?
|
|
1140
|
+
|
|
1141
|
+
@pending_stock_levels = { writer: writer, payload: payload }
|
|
1142
|
+
true
|
|
1143
|
+
end
|
|
1144
|
+
|
|
1145
|
+
def pending_stock_levels?
|
|
1146
|
+
@pending_stock_levels.present?
|
|
1147
|
+
end
|
|
1148
|
+
|
|
1149
|
+
def apply_pending_stock_levels
|
|
1150
|
+
pending = @pending_stock_levels
|
|
1151
|
+
@pending_stock_levels = nil
|
|
1152
|
+
|
|
1153
|
+
public_send(pending[:writer], pending[:payload])
|
|
1154
|
+
end
|
|
1155
|
+
|
|
725
1156
|
def pending_options?
|
|
726
1157
|
@pending_options.present?
|
|
727
1158
|
end
|
|
@@ -754,70 +1185,118 @@ module Spree
|
|
|
754
1185
|
Spree::Stock::Quantifier.new(self)
|
|
755
1186
|
end
|
|
756
1187
|
|
|
757
|
-
def
|
|
758
|
-
if
|
|
759
|
-
|
|
760
|
-
|
|
1188
|
+
def set_cost_currency
|
|
1189
|
+
self.cost_currency = Spree::Store.default.default_currency if cost_currency.blank?
|
|
1190
|
+
end
|
|
1191
|
+
|
|
1192
|
+
# Only the product's own store's locations — a new variant must not grow
|
|
1193
|
+
# stock items in every other store's warehouses.
|
|
1194
|
+
def create_stock_levels
|
|
1195
|
+
locations = product&.store ? product.store.stock_locations : StockLocation.all
|
|
1196
|
+
locations.where(propagate_all_variants: true).each do |stock_location|
|
|
1197
|
+
stock_location.propagate_variant(self)
|
|
761
1198
|
end
|
|
762
1199
|
end
|
|
763
1200
|
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
1201
|
+
def disable_sku_validation?
|
|
1202
|
+
store_preference(:disable_sku_validation)
|
|
1203
|
+
end
|
|
1204
|
+
|
|
1205
|
+
# A SKU identifies an item within one seller's catalog, not across the
|
|
1206
|
+
# marketplace: two sellers listing the same manufacturer part number is
|
|
1207
|
+
# ordinary, and rejecting the second one would be refusing the sale.
|
|
1208
|
+
#
|
|
1209
|
+
# Compared on the *resolved* seller, so a seller who owns whole products
|
|
1210
|
+
# is separated from another who does, not merged into the nil scope.
|
|
1211
|
+
#
|
|
1212
|
+
# Case-insensitive over a join, so it runs behind index_spree_variants_on_sku
|
|
1213
|
+
# rather than on it. A functional index on LOWER(sku) would suit it better,
|
|
1214
|
+
# but MariaDB rejects MySQL's syntax for one, so bulk writers that care pay
|
|
1215
|
+
# this or turn the check off with the disable_sku_validation preference.
|
|
1216
|
+
# Reads the raw column, not the resolved seller: what is being checked is
|
|
1217
|
+
# the variant's *own* link, and a product-owned variant has none to check.
|
|
1218
|
+
def blank_owned_product_overrides
|
|
1219
|
+
return unless owned_by_product_seller?
|
|
1220
|
+
|
|
1221
|
+
self.seller_id = nil
|
|
1222
|
+
self.delivery_profile_id = nil
|
|
1223
|
+
end
|
|
1224
|
+
|
|
1225
|
+
def seller_must_belong_to_store
|
|
1226
|
+
return if self[:seller_id].nil?
|
|
1227
|
+
|
|
1228
|
+
store = product&.store
|
|
1229
|
+
return if store.nil?
|
|
1230
|
+
return if association(:seller).reader&.store_id == store.id
|
|
767
1231
|
|
|
768
|
-
|
|
1232
|
+
errors.add(:seller, :invalid)
|
|
769
1233
|
end
|
|
770
1234
|
|
|
771
|
-
def
|
|
772
|
-
|
|
773
|
-
current_price = price_in(default_currency).amount
|
|
1235
|
+
def delivery_profile_must_belong_to_store
|
|
1236
|
+
return if self[:delivery_profile_id].nil?
|
|
774
1237
|
|
|
775
|
-
|
|
776
|
-
|
|
1238
|
+
store = product&.store
|
|
1239
|
+
return if store.nil?
|
|
1240
|
+
return if association(:delivery_profile).reader&.store_id == store.id
|
|
777
1241
|
|
|
778
|
-
|
|
779
|
-
inferred_price = product.default_variant.price_in(default_currency).amount
|
|
780
|
-
set_price(default_currency, inferred_price) if inferred_price.present?
|
|
781
|
-
end
|
|
1242
|
+
errors.add(:delivery_profile, :invalid)
|
|
782
1243
|
end
|
|
783
1244
|
|
|
784
|
-
|
|
785
|
-
|
|
1245
|
+
# Same guard as the delivery profile above, widened to ownership: a carton
|
|
1246
|
+
# must belong to this store, and be either the marketplace's shared
|
|
1247
|
+
# vocabulary or this variant's own seller's. Another seller's carton must
|
|
1248
|
+
# never be reachable by id — its measurements would feed this variant's
|
|
1249
|
+
# freight rollups (docs/plans/6.0-seller-package-types.md).
|
|
1250
|
+
def carton_package_type_must_belong_to_store
|
|
1251
|
+
return if self[:carton_package_type_id].nil?
|
|
1252
|
+
|
|
1253
|
+
store = product&.store
|
|
1254
|
+
return if store.nil?
|
|
1255
|
+
|
|
1256
|
+
carton = association(:carton_package_type).reader
|
|
1257
|
+
return if carton&.store_id == store.id && carton.available_to_seller?(resolved_seller_id)
|
|
1258
|
+
|
|
1259
|
+
errors.add(:carton_package_type, :invalid)
|
|
786
1260
|
end
|
|
787
1261
|
|
|
788
|
-
def
|
|
789
|
-
|
|
790
|
-
|
|
1262
|
+
def validate_sku_uniqueness
|
|
1263
|
+
scope = self.class.for_seller(resolved_seller_id).
|
|
1264
|
+
where(deleted_at: nil).
|
|
1265
|
+
where(self.class.arel_table[:sku].lower.eq(sku.to_s.downcase))
|
|
1266
|
+
# Honour a host app's tenancy scope, as the validator this replaced did.
|
|
1267
|
+
# Empty in core, so this narrows nothing here.
|
|
1268
|
+
Array(self.class.spree_base_uniqueness_scope).each do |attribute|
|
|
1269
|
+
scope = scope.where(attribute => self[attribute])
|
|
791
1270
|
end
|
|
792
|
-
|
|
1271
|
+
scope = scope.where.not(id: id) if persisted?
|
|
793
1272
|
|
|
794
|
-
|
|
795
|
-
Spree::Config[:disable_sku_validation]
|
|
1273
|
+
errors.add(:sku, :taken, value: sku) if scope.exists?
|
|
796
1274
|
end
|
|
797
1275
|
|
|
798
1276
|
def clear_line_items_cache
|
|
799
1277
|
line_items.update_all(updated_at: Time.current)
|
|
800
1278
|
end
|
|
801
1279
|
|
|
802
|
-
def
|
|
803
|
-
return if
|
|
1280
|
+
def create_default_stock_level
|
|
1281
|
+
return if stock_levels.any?
|
|
804
1282
|
|
|
805
|
-
Spree::Store.current.default_stock_location.
|
|
1283
|
+
Spree::Store.current.default_stock_location.set_up_stock_level(self)
|
|
806
1284
|
end
|
|
807
1285
|
|
|
1286
|
+
# Turning tracking off writes the remaining stock away. That is a stock
|
|
1287
|
+
# decision, so it goes in the log like any other correction rather than
|
|
1288
|
+
# disappearing through update_all.
|
|
808
1289
|
def handle_track_inventory_change
|
|
809
1290
|
return unless track_inventory_previously_changed?
|
|
810
1291
|
return if track_inventory
|
|
811
1292
|
|
|
812
|
-
|
|
813
|
-
|
|
1293
|
+
stock_levels.reload.each do |stock_level|
|
|
1294
|
+
next if stock_level.count_on_hand.zero?
|
|
814
1295
|
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
def remove_stock_items_from_master_variant
|
|
820
|
-
product.master.stock_items.delete_all
|
|
1296
|
+
stock_level.stock_location.adjust(
|
|
1297
|
+
self, -stock_level.count_on_hand, reason: Spree::StockMovement.default_adjustment_reason
|
|
1298
|
+
)
|
|
1299
|
+
end
|
|
821
1300
|
end
|
|
822
1301
|
|
|
823
1302
|
def increment_product_variant_count
|