spree_core 5.6.0 → 6.0.0.beta1
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 +46 -27
- data/app/jobs/spree/imports/process_job.rb +164 -0
- data/app/jobs/spree/imports/process_rows_job.rb +4 -63
- 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/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/admin_user_methods.rb +14 -34
- 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 +16 -1
- 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 +29 -28
- 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 +119 -13
- 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 +466 -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 +5 -6
- data/app/models/spree/channel.rb +38 -4
- data/app/models/spree/channel_stock_location.rb +8 -0
- data/app/models/spree/checkout/default_requirements.rb +105 -22
- data/app/models/spree/checkout/registry.rb +64 -12
- data/app/models/spree/checkout/requirement.rb +9 -9
- data/app/models/spree/checkout/requirements.rb +25 -20
- data/app/models/spree/checkout/step.rb +12 -12
- data/app/models/spree/claim.rb +68 -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 +124 -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 +49 -44
- data/app/models/spree/exchange_line_item.rb +52 -0
- data/app/models/spree/export.rb +138 -23
- 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 +222 -92
- 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 +239 -105
- 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 -91
- data/app/models/spree/metafield_definition.rb +11 -127
- 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 +628 -571
- 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 +255 -0
- data/app/models/spree/pricing_provider.rb +28 -0
- data/app/models/spree/product.rb +539 -537
- 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 +94 -41
- data/app/models/spree/refund_reason.rb +32 -11
- data/app/models/spree/return.rb +150 -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 +11 -0
- data/app/models/spree/search_provider/database.rb +106 -9
- 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 +56 -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 +427 -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 +199 -58
- 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 +9 -23
- 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 +55 -0
- data/app/services/spree/sample_data/import_builder.rb +36 -0
- data/app/services/spree/sample_data/import_runner.rb +25 -41
- data/app/services/spree/sample_data/loader.rb +21 -63
- 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/allowed_origins.rb +3 -4
- 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 +260 -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 +955 -187
- 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/20260722000001_add_searchable_sortable_to_spree_metafield_definitions.rb +6 -0
- data/db/migrate/20260727000001_add_unique_country_abbr_index_to_spree_states.rb +53 -0
- 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/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 +1 -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 +6 -6
- data/lib/generators/spree/model/templates/model.rb.tt +7 -3
- data/lib/spree/category_permalink_deduplicator.rb +328 -0
- data/lib/spree/core/configuration.rb +96 -47
- 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 +333 -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 +59 -3
- data/lib/spree/core/preferences/preferable_class_methods.rb +41 -2
- data/lib/spree/core/preferences/runtime_configuration.rb +68 -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 +422 -62
- 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 -12
- 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_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/product_tag_tenants.rake +1 -3
- 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 +104 -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 +792 -538
- 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/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/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/metafields/boolean.rb +0 -15
- data/app/models/spree/metafields/json.rb +0 -37
- data/app/models/spree/metafields/long_text.rb +0 -7
- data/app/models/spree/metafields/number.rb +0 -15
- data/app/models/spree/metafields/rich_text.rb +0 -18
- data/app/models/spree/metafields/short_text.rb +0 -7
- 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 -130
- 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 -496
- 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 -138
- 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/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 -63
- 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 -333
- 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 -72
- data/lib/spree/testing_support/factories/metafield_factory.rb +0 -68
- data/lib/spree/testing_support/factories/prototype_factory.rb +0 -9
- data/lib/spree/testing_support/factories/reimbursement_credit_factory.rb +0 -7
- data/lib/spree/testing_support/factories/reimbursement_factory.rb +0 -16
- data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +0 -7
- data/lib/spree/testing_support/factories/report_factory.rb +0 -33
- data/lib/spree/testing_support/factories/return_authorization_factory.rb +0 -21
- data/lib/spree/testing_support/factories/return_item_factory.rb +0 -14
- data/lib/spree/testing_support/factories/shipment_factory.rb +0 -21
- data/lib/spree/testing_support/factories/shipping_category_factory.rb +0 -9
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +0 -31
- data/lib/spree/testing_support/factories/shipping_rate_factory.rb +0 -7
- data/lib/spree/testing_support/factories/state_change_factory.rb +0 -8
- data/lib/spree/testing_support/factories/stock_item_factory.rb +0 -22
- data/lib/spree/testing_support/factories/store_credit_category_factory.rb +0 -9
- data/lib/spree/testing_support/factories/store_credit_type_factory.rb +0 -16
- data/lib/spree/testing_support/factories/wished_variant_factory.rb +0 -6
- data/lib/spree/webhooks.rb +0 -22
- data/lib/tasks/role_users.rake +0 -21
- data/vendor/javascript/@rails--request.js.js +0 -4
- data/vendor/javascript/@stimulus-components--auto-submit.js +0 -4
- data/vendor/javascript/stimulus-reveal-controller.js +0 -4
- data/vendor/javascript/stimulus-textarea-autogrow.js +0 -4
- data/vendor/javascript/tailwindcss-stimulus-components.js +0 -4
|
@@ -0,0 +1,973 @@
|
|
|
1
|
+
require 'ostruct'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
class Fulfillment < Spree.base_class
|
|
5
|
+
has_prefix_id :ful
|
|
6
|
+
|
|
7
|
+
include Spree::DerivedNumber
|
|
8
|
+
derives_number infix: 'F'
|
|
9
|
+
include Spree::HasCustomFields
|
|
10
|
+
include Spree::Metadata
|
|
11
|
+
include Spree::StorePreferences
|
|
12
|
+
if defined?(Spree::Security::Shipments)
|
|
13
|
+
include Spree::Security::Shipments
|
|
14
|
+
end
|
|
15
|
+
include Spree::Fulfillment::CustomEvents
|
|
16
|
+
|
|
17
|
+
publishes_lifecycle_events
|
|
18
|
+
|
|
19
|
+
with_options inverse_of: :fulfillments do
|
|
20
|
+
belongs_to :address, class_name: 'Spree::Address', optional: true
|
|
21
|
+
belongs_to :order, class_name: 'Spree::Order', touch: true, optional: true
|
|
22
|
+
belongs_to :cart, class_name: 'Spree::Cart', optional: true
|
|
23
|
+
end
|
|
24
|
+
belongs_to :stock_location, -> { with_deleted }, class_name: 'Spree::StockLocation'
|
|
25
|
+
|
|
26
|
+
with_options dependent: :delete_all do
|
|
27
|
+
has_many :fulfillment_items, class_name: 'Spree::FulfillmentItem', inverse_of: :fulfillment
|
|
28
|
+
# Cheapest first, with unpriced rates after every priced one — a rate
|
|
29
|
+
# quoted after review costs zero only because nobody has priced it, so
|
|
30
|
+
# ordering on cost alone would list freight above real quotes. Matches
|
|
31
|
+
# the order the Estimator hands back, so a rate read from the database
|
|
32
|
+
# sorts the same way as one just computed.
|
|
33
|
+
has_many :delivery_rates, -> { order(:unpriced, :cost) }, class_name: 'Spree::DeliveryRate'
|
|
34
|
+
end
|
|
35
|
+
has_many :tax_lines, class_name: 'Spree::TaxLine', dependent: :destroy, inverse_of: :fulfillment
|
|
36
|
+
has_many :discounts, class_name: 'Spree::Discount', dependent: :destroy, inverse_of: :fulfillment
|
|
37
|
+
has_many :fees, class_name: 'Spree::Fee', dependent: :destroy, inverse_of: :fulfillment
|
|
38
|
+
has_many :delivery_methods, through: :delivery_rates
|
|
39
|
+
has_many :variants, through: :fulfillment_items
|
|
40
|
+
# The ledger rows this fulfillment caused. Deliberately no `dependent:`
|
|
41
|
+
# option: a movement is a committed fact about stock that outlives the
|
|
42
|
+
# fulfillment behind it, and every option Rails offers would either delete
|
|
43
|
+
# those rows or rewrite their cause. Draining a fulfillment already hands
|
|
44
|
+
# its promise to the one taking the units over, so nothing is left holding
|
|
45
|
+
# stock by the time it is destroyed.
|
|
46
|
+
has_many :stock_movements, class_name: 'Spree::StockMovement', inverse_of: :fulfillment
|
|
47
|
+
has_one :selected_delivery_rate, -> { where(selected: true).order(:cost) }, class_name: 'Spree::DeliveryRate'
|
|
48
|
+
# The carrier documents bought or uploaded for this parcel, and its
|
|
49
|
+
# consignments in flight (docs/plans/6.0-shipping-labels-and-deliveries.md).
|
|
50
|
+
# The first delivery is the primary one that #tracking summarizes.
|
|
51
|
+
has_many :shipping_labels, -> { order(:created_at, :id) }, class_name: 'Spree::ShippingLabel', as: :owner, dependent: :destroy
|
|
52
|
+
has_many :deliveries, -> { order(:created_at, :id) }, class_name: 'Spree::Delivery', as: :owner, dependent: :destroy
|
|
53
|
+
|
|
54
|
+
after_save :update_adjustments
|
|
55
|
+
after_commit :apply_pending_tracking, if: -> { defined?(@pending_tracking) }
|
|
56
|
+
|
|
57
|
+
before_validation :set_cost_zero_when_nil
|
|
58
|
+
|
|
59
|
+
validate :exactly_one_owner
|
|
60
|
+
|
|
61
|
+
attr_accessor :special_instructions
|
|
62
|
+
|
|
63
|
+
accepts_nested_attributes_for :address
|
|
64
|
+
accepts_nested_attributes_for :fulfillment_items
|
|
65
|
+
|
|
66
|
+
# unfulfilled/fulfilled/delivered/canceled scopes + predicates come from
|
|
67
|
+
# has_status below. These are the ones it cannot generate.
|
|
68
|
+
#
|
|
69
|
+
# @deprecated legacy names — removed in 6.1
|
|
70
|
+
scope :shipped, -> { fulfilled }
|
|
71
|
+
scope :pending, -> { unfulfilled }
|
|
72
|
+
scope :ready, -> { unfulfilled }
|
|
73
|
+
scope :ready_or_pending, -> { unfulfilled }
|
|
74
|
+
# Everything that has left the merchant's hands, whether or not the carrier
|
|
75
|
+
# has confirmed receipt — the natural set for reporting and for skipping
|
|
76
|
+
# work that only applies to packages still on the shelf.
|
|
77
|
+
scope :fulfilled_or_delivered, -> { where(status: %w(fulfilled delivered)) }
|
|
78
|
+
scope :trackable, -> { where(id: Spree::Delivery.where(owner_type: name).select(:owner_id)) }
|
|
79
|
+
scope :with_state, ->(*s) { where(status: s) }
|
|
80
|
+
# sort by most recent fulfilled_at, falling back to created_at. add "id desc" to make specs that involve this scope more deterministic.
|
|
81
|
+
scope :reverse_chronological, -> { order(Arel.sql("coalesce(#{table_name}.fulfilled_at, #{table_name}.created_at) desc"), id: :desc) }
|
|
82
|
+
scope :valid, -> { where.not(status: :canceled) }
|
|
83
|
+
scope :not_canceled, -> { where.not(status: 'canceled') }
|
|
84
|
+
scope :shipped_but_canceled, -> { canceled.where.not(fulfilled_at: nil) }
|
|
85
|
+
# This scope will select the delivery_method_id from the fulfillments' selected delivery rate
|
|
86
|
+
scope :with_selected_delivery_method, lambda {
|
|
87
|
+
joins(:selected_delivery_rate).
|
|
88
|
+
where(Spree::DeliveryRate.arel_table[:delivery_method_id].not_eq(nil)).
|
|
89
|
+
select(Spree::DeliveryRate.arel_table[:delivery_method_id])
|
|
90
|
+
}
|
|
91
|
+
scope :digital_delivery, -> { joins(:delivery_methods).merge(Spree::DeliveryMethod.digital) }
|
|
92
|
+
|
|
93
|
+
delegate :store, :currency, to: :owner
|
|
94
|
+
|
|
95
|
+
# The exactly-one owner of this fulfillment — the cart during checkout,
|
|
96
|
+
# the order after completion. New code must read +owner+, never assume
|
|
97
|
+
# +order+.
|
|
98
|
+
#
|
|
99
|
+
# @return [Spree::Cart, Spree::Order, nil]
|
|
100
|
+
def owner
|
|
101
|
+
order || cart
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# `store` is delegated to the owner, which raises when a fulfillment has
|
|
105
|
+
# neither an order nor a cart yet.
|
|
106
|
+
# @return [Spree::Store, nil]
|
|
107
|
+
def preference_store
|
|
108
|
+
owner&.store
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Bridge for legacy callers assigning +current_order+ (now a Spree::Cart)
|
|
112
|
+
# to the order association — routes carts to the cart FK instead.
|
|
113
|
+
def order=(record)
|
|
114
|
+
if record.is_a?(Spree::Cart)
|
|
115
|
+
self.cart = record
|
|
116
|
+
super(nil)
|
|
117
|
+
else
|
|
118
|
+
super
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Read off the raw cost rather than the formatted one: an unpriced freight
|
|
123
|
+
# fulfillment formats as "quoted after review", and a String has no cents.
|
|
124
|
+
#
|
|
125
|
+
# @return [Integer]
|
|
126
|
+
def amount_in_cents
|
|
127
|
+
Spree::Money.new(cost, currency: currency).amount_in_cents
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Statuses describe what the merchant did with the package — nothing else.
|
|
131
|
+
# Payment and stock readiness used to be encoded here as pending/ready and
|
|
132
|
+
# re-derived from the order on every recalculation, so a refund could move a
|
|
133
|
+
# fulfillment backwards with no physical change. That gate now lives in
|
|
134
|
+
# Spree::Fulfillments::Fulfill, where it can explain itself and be
|
|
135
|
+
# overridden. Transitions belong to the workflows in
|
|
136
|
+
# app/workflows/spree/fulfillments (docs/plans/6.0-fulfillment-and-delivery.md).
|
|
137
|
+
include Spree::HasStatus
|
|
138
|
+
has_status :unfulfilled, :fulfilled, :delivered, :canceled, default: :unfulfilled
|
|
139
|
+
|
|
140
|
+
# @deprecated Use {Spree::Fulfillments::Fulfill}; removed in 6.1.
|
|
141
|
+
def ship(*args)
|
|
142
|
+
Spree::Deprecation.warn('Spree::Fulfillment#ship is deprecated and will be removed in Spree 6.1. Use Spree::Fulfillments::Fulfill instead.')
|
|
143
|
+
Spree.fulfillment_fulfill_workflow.call(fulfillment: self, **args.first.to_h)
|
|
144
|
+
end
|
|
145
|
+
alias ship! ship
|
|
146
|
+
|
|
147
|
+
# @deprecated Use {#can_fulfill?}; removed in 6.1.
|
|
148
|
+
def can_ship?
|
|
149
|
+
Spree::Deprecation.warn('Spree::Fulfillment#can_ship? is deprecated and will be removed in Spree 6.1. Use #can_fulfill? instead.')
|
|
150
|
+
can_fulfill?
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# @deprecated Use {#fulfilled?}; removed in 6.1.
|
|
154
|
+
def shipped?
|
|
155
|
+
Spree::Deprecation.warn('Spree::Fulfillment#shipped? is deprecated and will be removed in Spree 6.1. Use #fulfilled? instead.')
|
|
156
|
+
fulfilled?
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Whether this fulfillment may still be handed over. Composes the status
|
|
160
|
+
# rule with the provider's own veto; the payment and stock side of the
|
|
161
|
+
# question belongs to Spree::Fulfillments::Fulfill, which can report why.
|
|
162
|
+
#
|
|
163
|
+
# Stated negatively — anything that has not already gone out can go out —
|
|
164
|
+
# so a status an extension adds before `fulfilled` (an `in_production`
|
|
165
|
+
# stage, say) is fulfillable without overriding anything. Whether it
|
|
166
|
+
# SHOULD go out yet is the fulfill workflow's validate hook's question.
|
|
167
|
+
#
|
|
168
|
+
# @return [Boolean]
|
|
169
|
+
def can_fulfill?
|
|
170
|
+
!fulfilled_or_delivered? && !canceled? && provider.can_fulfill?(self)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Whether the package can still be recalled: anything that has neither
|
|
174
|
+
# gone out nor already been recalled. Negative for the same reason as
|
|
175
|
+
# {#can_fulfill?} — custom pre-handover statuses stay cancelable.
|
|
176
|
+
#
|
|
177
|
+
# @return [Boolean]
|
|
178
|
+
def can_cancel?
|
|
179
|
+
!fulfilled_or_delivered? && !canceled?
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# @return [Boolean] whether receipt can still be confirmed
|
|
183
|
+
def can_mark_delivered?
|
|
184
|
+
fulfilled?
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Everything that has left the merchant's hands. Reads better than
|
|
188
|
+
# `fulfilled? || delivered?` at call sites that only care that the package
|
|
189
|
+
# is gone.
|
|
190
|
+
#
|
|
191
|
+
# @return [Boolean]
|
|
192
|
+
def fulfilled_or_delivered?
|
|
193
|
+
fulfilled? || delivered?
|
|
194
|
+
end
|
|
195
|
+
# @deprecated the column is +status+ since 6.0
|
|
196
|
+
alias_attribute :state, :status
|
|
197
|
+
alias_attribute :shipped_at, :fulfilled_at
|
|
198
|
+
# Legacy association names — removed in 6.1.
|
|
199
|
+
has_many :inventory_units, class_name: 'Spree::FulfillmentItem', foreign_key: :fulfillment_id, inverse_of: :fulfillment, deprecated: true
|
|
200
|
+
has_many :shipping_rates, -> { order(:cost) }, class_name: 'Spree::DeliveryRate', foreign_key: :fulfillment_id, deprecated: true
|
|
201
|
+
has_one :selected_shipping_rate, -> { where(selected: true).order(:cost) }, class_name: 'Spree::DeliveryRate', foreign_key: :fulfillment_id, deprecated: true
|
|
202
|
+
has_many :shipping_methods, through: :delivery_rates, source: :delivery_method, deprecated: true
|
|
203
|
+
|
|
204
|
+
self.whitelisted_ransackable_attributes = ['number']
|
|
205
|
+
|
|
206
|
+
extend DisplayMoney
|
|
207
|
+
money_methods :cost, :discounted_cost, :final_price, :item_cost, :additional_tax_total, :included_tax_total, :tax_total, :discount_total
|
|
208
|
+
|
|
209
|
+
# True while the shipping price is still the forwarder's to quote — the
|
|
210
|
+
# selected rate is a freight rate carrying logistics instead of an amount.
|
|
211
|
+
#
|
|
212
|
+
# @return [Boolean]
|
|
213
|
+
def unpriced?
|
|
214
|
+
selected_delivery_rate&.unpriced? || false
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# An unpriced fulfillment's cost is zero only because nobody has priced
|
|
218
|
+
# it, and every display reading that zero as money — the order
|
|
219
|
+
# fulfillments card included — would call a container of goods free
|
|
220
|
+
# shipping. Same doctrine as the rate's own displays.
|
|
221
|
+
#
|
|
222
|
+
# @return [String, Spree::Money]
|
|
223
|
+
def display_cost(**options)
|
|
224
|
+
return Spree.t('delivery_rates.quoted_after_review') if unpriced?
|
|
225
|
+
|
|
226
|
+
Spree::Money.new(cost, { currency: currency }.merge(options))
|
|
227
|
+
end
|
|
228
|
+
alias display_amount display_cost
|
|
229
|
+
# Standardized column name (renamed in 6.0); the legacy reader stays one
|
|
230
|
+
# release.
|
|
231
|
+
alias_attribute :promo_total, :discount_total
|
|
232
|
+
alias display_promo_total display_discount_total
|
|
233
|
+
|
|
234
|
+
# Returns the shipment number and shipping method name
|
|
235
|
+
#
|
|
236
|
+
# @return [String]
|
|
237
|
+
def name
|
|
238
|
+
[number, delivery_method&.name].compact.join(' ').strip
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def amount
|
|
242
|
+
cost
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Strict decimal bridge for string input — raises ArgumentError on
|
|
246
|
+
# malformed values instead of letting Rails' cast silently truncate
|
|
247
|
+
# ("12 boxes" would otherwise become 12.0). Blank strings cast to nil,
|
|
248
|
+
# matching the default Rails behavior.
|
|
249
|
+
#
|
|
250
|
+
# @param value [String, Numeric, nil]
|
|
251
|
+
def cost=(value)
|
|
252
|
+
value = value.blank? ? nil : BigDecimal(value.strip) if value.is_a?(String)
|
|
253
|
+
super
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def digital?
|
|
257
|
+
delivery_method&.digital? || false
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# @deprecated Use {#delivery_method}; removed in 6.1.
|
|
261
|
+
def shipping_method
|
|
262
|
+
Spree::Deprecation.warn('Spree::Fulfillment#shipping_method is deprecated and will be removed in Spree 6.1. Use #delivery_method instead.')
|
|
263
|
+
delivery_method
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def add_delivery_method(delivery_method, selected = false)
|
|
267
|
+
delivery_rates.create(delivery_method: delivery_method, selected: selected, cost: cost)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# @deprecated Use {#add_delivery_method}; removed in 6.1.
|
|
271
|
+
def add_shipping_method(delivery_method, selected = false)
|
|
272
|
+
Spree::Deprecation.warn('Spree::Fulfillment#add_shipping_method is deprecated and will be removed in Spree 6.1. Use #add_delivery_method instead.')
|
|
273
|
+
add_delivery_method(delivery_method, selected)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# @deprecated Cancel through {Spree::Fulfillments::Cancel}; removed in 6.1.
|
|
277
|
+
# Restocking and the provider call are workflow steps now, so this no
|
|
278
|
+
# longer runs as a transition callback. Kept only so a host app that
|
|
279
|
+
# called it directly keeps working for one release.
|
|
280
|
+
def after_cancel
|
|
281
|
+
Spree::Deprecation.warn('Spree::Fulfillment#after_cancel is deprecated and will be removed in Spree 6.1. Cancel through Spree::Fulfillments::Cancel instead.')
|
|
282
|
+
manifest.each { |item| manifest_restock(item) }
|
|
283
|
+
provider.cancel_fulfillment(self)
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# Returns true if the shipment has any backordered inventory units
|
|
287
|
+
#
|
|
288
|
+
# @return [Boolean]
|
|
289
|
+
def backordered?
|
|
290
|
+
fulfillment_items.any?(&:backordered?)
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Returns true if the shipment is tracked
|
|
294
|
+
#
|
|
295
|
+
# @return [Boolean]
|
|
296
|
+
def tracked?
|
|
297
|
+
tracking.present? || tracking_url.present?
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# Returns true if the shipment is shippable
|
|
301
|
+
#
|
|
302
|
+
# @return [Boolean]
|
|
303
|
+
def shippable?
|
|
304
|
+
can_fulfill? && (tracked? || digital?)
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Returns true if not all of the shipment's line items are fully shipped
|
|
308
|
+
#
|
|
309
|
+
# @return [Boolean]
|
|
310
|
+
def partial?
|
|
311
|
+
manifest.any? do |manifest_item|
|
|
312
|
+
line_item = manifest_item.line_item
|
|
313
|
+
line_item.quantity > manifest_item.quantity
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def discounted_cost
|
|
318
|
+
cost + discount_total
|
|
319
|
+
end
|
|
320
|
+
alias discounted_amount discounted_cost
|
|
321
|
+
|
|
322
|
+
# Returns the amount this shipment is taxed on: its discounted cost,
|
|
323
|
+
# never negative (stacked shipping promotions can push discounted_cost
|
|
324
|
+
# below zero). Whole-order promotions are not allocated to shipments.
|
|
325
|
+
#
|
|
326
|
+
# @return [BigDecimal]
|
|
327
|
+
def taxable_basis
|
|
328
|
+
[discounted_cost, BigDecimal(0)].max
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def final_price
|
|
332
|
+
cost + adjustment_total
|
|
333
|
+
end
|
|
334
|
+
alias total final_price
|
|
335
|
+
# Every money display on an unpriced fulfillment says the same thing, for
|
|
336
|
+
# the same reason display_cost does: a container nobody has quoted must
|
|
337
|
+
# not render as free.
|
|
338
|
+
#
|
|
339
|
+
# @return [String, Spree::Money]
|
|
340
|
+
def display_final_price(**options)
|
|
341
|
+
return Spree.t('delivery_rates.quoted_after_review') if unpriced?
|
|
342
|
+
|
|
343
|
+
Spree::Money.new(final_price, { currency: currency }.merge(options))
|
|
344
|
+
end
|
|
345
|
+
alias display_total display_final_price
|
|
346
|
+
|
|
347
|
+
def final_price_with_items
|
|
348
|
+
item_cost + final_price
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
# An unpriced fulfillment is never free — its cost is zero only because
|
|
352
|
+
# the forwarder has not quoted it yet.
|
|
353
|
+
def free?
|
|
354
|
+
return false if unpriced?
|
|
355
|
+
return true if final_price == BigDecimal(0)
|
|
356
|
+
|
|
357
|
+
with_free_shipping_promotion?
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
# Returns true if the shipment has a free shipping promotion applied
|
|
361
|
+
#
|
|
362
|
+
# @return [Boolean]
|
|
363
|
+
def with_free_shipping_promotion?
|
|
364
|
+
discounts.promotion.exists?
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
# Placement no longer moves physical stock — the units are promised in
|
|
368
|
+
# Spree::Orders::Complete and only leave the shelf when the parcel does.
|
|
369
|
+
def finalize!
|
|
370
|
+
fulfillment_items.finalize_units!
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
# Units this fulfillment still holds a promise for, keyed by variant id:
|
|
374
|
+
# what was allocated to it, less anything since released or shipped
|
|
375
|
+
# against it. A fulfillment has one origin, so a variant maps to exactly
|
|
376
|
+
# one stock level here.
|
|
377
|
+
#
|
|
378
|
+
# @return [Hash{Integer => Integer}]
|
|
379
|
+
def allocated_quantities
|
|
380
|
+
# An unsaved fulfillment has caused nothing.
|
|
381
|
+
return {} unless persisted?
|
|
382
|
+
|
|
383
|
+
totals = Hash.new(0)
|
|
384
|
+
|
|
385
|
+
stock_movements.
|
|
386
|
+
joins(:stock_level).
|
|
387
|
+
group("#{Spree::StockLevel.table_name}.variant_id", :kind).
|
|
388
|
+
sum(:quantity).
|
|
389
|
+
each do |(variant_id, kind), quantity|
|
|
390
|
+
case kind
|
|
391
|
+
when 'allocated' then totals[variant_id] += quantity.abs
|
|
392
|
+
when 'released', 'shipped' then totals[variant_id] -= quantity.abs
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
totals.select { |_, quantity| quantity.positive? }
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
# Total units still promised to this fulfillment.
|
|
400
|
+
#
|
|
401
|
+
# @return [Integer]
|
|
402
|
+
def allocated_quantity
|
|
403
|
+
allocated_quantities.values.sum
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def include?(variant)
|
|
407
|
+
inventory_units_for(variant).present?
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
def inventory_units_for(variant)
|
|
411
|
+
fulfillment_items.where(variant_id: variant.id)
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
def inventory_units_for_item(line_item, variant = nil)
|
|
415
|
+
fulfillment_items.where(line_item_id: line_item.id, variant_id: line_item.variant_id || variant.id)
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
# Returns the total quantity of all line items in the shipment
|
|
419
|
+
def item_quantity
|
|
420
|
+
manifest.sum(&:quantity)
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
# Returns the cost of the shipment
|
|
424
|
+
#
|
|
425
|
+
# @return [BigDecimal]
|
|
426
|
+
def item_cost
|
|
427
|
+
manifest.map { |m| (m.line_item.price + (m.line_item.adjustment_total / m.line_item.quantity)) * m.quantity }.sum
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
# Returns the weight of the shipment
|
|
431
|
+
#
|
|
432
|
+
# @return [BigDecimal]
|
|
433
|
+
def item_weight
|
|
434
|
+
manifest.map { |m| m.line_item.item_weight }.sum
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
# Returns the weight unit of the shipment
|
|
438
|
+
#
|
|
439
|
+
# @return [String]
|
|
440
|
+
def weight_unit
|
|
441
|
+
manifest.first.line_item.weight_unit
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
def line_items
|
|
445
|
+
fulfillment_items.includes(:line_item).map(&:line_item).uniq
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
ManifestItem = Struct.new(:line_item, :variant, :quantity, :states)
|
|
449
|
+
|
|
450
|
+
def manifest
|
|
451
|
+
# Grouping by the ID means that we don't have to call out to the association accessor
|
|
452
|
+
# This makes the grouping by faster because it results in less SQL cache hits.
|
|
453
|
+
fulfillment_items.group_by(&:variant_id).flat_map do |_variant_id, units|
|
|
454
|
+
units.group_by(&:line_item_id).filter_map do |_line_item_id, units|
|
|
455
|
+
line_item = units.first.line_item
|
|
456
|
+
# Defensively skip orphaned inventory units (line item destroyed
|
|
457
|
+
# without cascading) so a single bad row doesn't crash callers that
|
|
458
|
+
# rely on line_item being present (item_cost, item_weight, the admin
|
|
459
|
+
# shipment manifest view, etc.).
|
|
460
|
+
next if line_item.nil?
|
|
461
|
+
|
|
462
|
+
states = {}
|
|
463
|
+
units.group_by(&:status).each { |status, iu| states[status] = iu.sum(&:quantity) }
|
|
464
|
+
|
|
465
|
+
variant = units.first.variant
|
|
466
|
+
ManifestItem.new(line_item, variant, units.sum(&:quantity), states)
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
# Payments whose method charges on dispatch. A method set to charge
|
|
472
|
+
# manually is never swept up by a dispatch — that is the whole point of
|
|
473
|
+
# choosing it — so it is left for staff to capture.
|
|
474
|
+
#
|
|
475
|
+
# Read through +owner+ rather than +order+: a fulfillment can still belong
|
|
476
|
+
# to a cart, and both carry pending_payments.
|
|
477
|
+
#
|
|
478
|
+
# An order placed in a split checkout has no payments of its own — the
|
|
479
|
+
# customer paid once, against the group — so the pool comes from there
|
|
480
|
+
# instead. What this parcel may draw from it is still bounded by its own
|
|
481
|
+
# order's share; see {#process_order_payments}.
|
|
482
|
+
#
|
|
483
|
+
# @return [Array<Spree::Payment>]
|
|
484
|
+
def payments_to_capture_on_dispatch
|
|
485
|
+
pool = grouped_owner? ? owner.settlement_payments.pending : Array(owner&.pending_payments)
|
|
486
|
+
|
|
487
|
+
Array(pool).select { |payment| payment.payment_method&.capture_on_dispatch? }
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
def process_order_payments
|
|
491
|
+
pending_payments = payments_to_capture_on_dispatch.
|
|
492
|
+
sort_by(&:uncaptured_amount).reverse
|
|
493
|
+
|
|
494
|
+
shipment_to_pay = final_price_with_items
|
|
495
|
+
payments_amount = 0
|
|
496
|
+
|
|
497
|
+
payments_pool = pending_payments.each_with_object([]) do |payment, pool|
|
|
498
|
+
break if payments_amount >= shipment_to_pay
|
|
499
|
+
|
|
500
|
+
payments_amount += payment.uncaptured_amount
|
|
501
|
+
pool << payment
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
payments_pool.each do |payment|
|
|
505
|
+
capturable_amount = if payment.amount >= shipment_to_pay
|
|
506
|
+
shipment_to_pay
|
|
507
|
+
else
|
|
508
|
+
payment.amount
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
captured = capture_from(payment, capturable_amount)
|
|
512
|
+
shipment_to_pay -= captured
|
|
513
|
+
end
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
# @deprecated Use {#unfulfilled?}; removed in 6.1.
|
|
517
|
+
def ready_or_pending?
|
|
518
|
+
unfulfilled?
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
# @deprecated Use {#unfulfilled?}; removed in 6.1.
|
|
522
|
+
def pending?
|
|
523
|
+
unfulfilled?
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
# @deprecated Use {#unfulfilled?}; removed in 6.1.
|
|
527
|
+
def ready?
|
|
528
|
+
unfulfilled?
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
# @deprecated `ready_for_pickup` is not a status since 6.0 — for pickup
|
|
532
|
+
# fulfillments `fulfilled` means "waiting at the counter". Removed in 6.1.
|
|
533
|
+
def ready_for_pickup?
|
|
534
|
+
fulfilled? && provider.class.pickup?
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
# @param audience [Symbol] {Spree::DeliveryMethod::STOREFRONT} (default)
|
|
538
|
+
# or {Spree::DeliveryMethod::BACKOFFICE}
|
|
539
|
+
# @return [Array<Spree::DeliveryRate>]
|
|
540
|
+
def refresh_rates(audience = DeliveryMethod::STOREFRONT)
|
|
541
|
+
return delivery_rates if fulfilled?
|
|
542
|
+
return [] unless can_get_rates?
|
|
543
|
+
|
|
544
|
+
# StockEstimator.new assignment below will replace the current delivery_method
|
|
545
|
+
original_shipping_method_id = delivery_method.try(:id)
|
|
546
|
+
# A carrier method quotes several rates (one per service), so the
|
|
547
|
+
# method id alone no longer identifies the customer's choice — capture
|
|
548
|
+
# the selected rate's carrier service too.
|
|
549
|
+
original_selection = selected_delivery_rate
|
|
550
|
+
original_carrier = original_selection&.carrier
|
|
551
|
+
original_service_level = original_selection&.service_level
|
|
552
|
+
|
|
553
|
+
self.delivery_rates = Stock::Estimator.new(owner).
|
|
554
|
+
delivery_rates(to_package, audience)
|
|
555
|
+
|
|
556
|
+
if delivery_method
|
|
557
|
+
# Keep the previously chosen carrier service when it is still quoted,
|
|
558
|
+
# then the previously chosen method, then the estimator's own pick
|
|
559
|
+
# (the cheapest rate, already flagged selected) rather than leaving
|
|
560
|
+
# the fulfillment unselected.
|
|
561
|
+
selected_rate =
|
|
562
|
+
if original_shipping_method_id && original_carrier
|
|
563
|
+
delivery_rates.detect do |rate|
|
|
564
|
+
rate.delivery_method_id == original_shipping_method_id &&
|
|
565
|
+
rate.carrier == original_carrier &&
|
|
566
|
+
rate.service_level == original_service_level
|
|
567
|
+
end
|
|
568
|
+
end
|
|
569
|
+
selected_rate ||=
|
|
570
|
+
if original_shipping_method_id
|
|
571
|
+
delivery_rates.detect { |rate| rate.delivery_method_id == original_shipping_method_id }
|
|
572
|
+
end
|
|
573
|
+
selected_rate ||= delivery_rates.detect(&:selected)
|
|
574
|
+
|
|
575
|
+
save!
|
|
576
|
+
self.selected_shipping_rate_id = selected_rate.id if selected_rate
|
|
577
|
+
reload
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
delivery_rates
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
# Public API v3 name for the selected rate (see docs/plans/6.0-fulfillment-and-delivery.md).
|
|
584
|
+
#
|
|
585
|
+
# @return [String, nil] the selected delivery rate's prefixed ID
|
|
586
|
+
def selected_delivery_rate_id
|
|
587
|
+
selected_delivery_rate&.prefixed_id
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
# Selects a delivery rate by its public prefixed ID (+dr_...+); raw IDs
|
|
591
|
+
# are accepted for internal callers. The model owns this naming bridge so
|
|
592
|
+
# API clients never deal with the legacy shipping-rate name.
|
|
593
|
+
#
|
|
594
|
+
# @param id [String, Integer] delivery rate prefixed or raw ID
|
|
595
|
+
def selected_delivery_rate_id=(id)
|
|
596
|
+
rate = Spree::PrefixedId.prefixed_id?(id) ? delivery_rates.find_by_prefix_id!(id) : delivery_rates.find(id)
|
|
597
|
+
self.selected_shipping_rate_id = rate.id
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
def selected_shipping_rate_id
|
|
601
|
+
selected_delivery_rate.try(:id)
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
def selected_shipping_rate_id=(id)
|
|
605
|
+
# Explicitly updates the timestamp in order to bust cache dependent on "updated_at"
|
|
606
|
+
delivery_rates.update_all(selected: false, updated_at: Time.current)
|
|
607
|
+
delivery_rates.update(id, selected: true)
|
|
608
|
+
save!
|
|
609
|
+
# Reload associations to pick up the new selected shipping rate
|
|
610
|
+
delivery_rates.reset
|
|
611
|
+
association(:selected_delivery_rate).reset
|
|
612
|
+
# A different rate can be a different carrier, and the provider is
|
|
613
|
+
# derived from the method behind it — a stale one buys, tracks or
|
|
614
|
+
# cancels through the account the parcel is no longer shipping on.
|
|
615
|
+
@provider = nil
|
|
616
|
+
# Update shipment cost and owner totals only during checkout.
|
|
617
|
+
# For completed orders, totals are managed separately (e.g., in tests or admin adjustments)
|
|
618
|
+
return if owner.nil? || owner.completed?
|
|
619
|
+
|
|
620
|
+
update_amounts
|
|
621
|
+
reload # reload to pick up cost set by update_columns in update_amounts
|
|
622
|
+
owner.set_fulfillments_cost
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
# +owner+ is the cart or order the units belong to. The item's order_id is
|
|
626
|
+
# a completion-time denormalization (backorder processing joins through
|
|
627
|
+
# it): during checkout it stays nil — writing a cart's id into an order
|
|
628
|
+
# foreign key would silently link the item to whatever order shares that
|
|
629
|
+
# id. Carts::Complete stamps the real order onto the copied items.
|
|
630
|
+
def set_up_inventory(status, variant, owner, line_item, quantity = 1)
|
|
631
|
+
return if quantity <= 0
|
|
632
|
+
|
|
633
|
+
fulfillment_items.create(
|
|
634
|
+
status: status,
|
|
635
|
+
variant_id: variant.id,
|
|
636
|
+
order_id: owner.is_a?(Spree::Order) ? owner.id : nil,
|
|
637
|
+
line_item_id: line_item.id,
|
|
638
|
+
quantity: quantity
|
|
639
|
+
)
|
|
640
|
+
end
|
|
641
|
+
|
|
642
|
+
def shipped=(value)
|
|
643
|
+
return unless value == '1' && fulfilled_at.nil?
|
|
644
|
+
|
|
645
|
+
self.fulfilled_at = Time.current
|
|
646
|
+
end
|
|
647
|
+
|
|
648
|
+
# Returns the shipping method of the selected shipping rate
|
|
649
|
+
#
|
|
650
|
+
# @return [Spree::DeliveryMethod]
|
|
651
|
+
def delivery_method
|
|
652
|
+
selected_delivery_rate&.delivery_method || delivery_rates.first&.delivery_method
|
|
653
|
+
end
|
|
654
|
+
|
|
655
|
+
# The fulfillment provider strategy handling this fulfillment's
|
|
656
|
+
# create/track/cancel mechanics — from the selected delivery method,
|
|
657
|
+
# falling back to Manual when no method is selected.
|
|
658
|
+
#
|
|
659
|
+
# @return [Spree::FulfillmentProvider::Base]
|
|
660
|
+
def provider
|
|
661
|
+
@provider ||= delivery_method&.provider || Spree::FulfillmentProvider::Manual.new
|
|
662
|
+
end
|
|
663
|
+
|
|
664
|
+
# Commission base for multi-seller include_shipping: the cost net of
|
|
665
|
+
# fulfillment-attached discounts.
|
|
666
|
+
#
|
|
667
|
+
# @return [BigDecimal]
|
|
668
|
+
def delivery_amount
|
|
669
|
+
cost + discounts.sum(:amount)
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
# How the delivery charge is classified for tax, as the merchant set it on
|
|
673
|
+
# the delivery method. Read from the method rather than through the selected
|
|
674
|
+
# rate's tax_rate: that hop answers out of the internal provider's rate
|
|
675
|
+
# table, so an external provider asking for the freight classification got
|
|
676
|
+
# nothing, and a classification with no matching rate configured reported
|
|
677
|
+
# none at all — leaving delivery to be taxed under the store's default
|
|
678
|
+
# category instead.
|
|
679
|
+
#
|
|
680
|
+
# @return [Spree::TaxCategory, nil]
|
|
681
|
+
def tax_category
|
|
682
|
+
delivery_method&.tax_category
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
# @return [String, nil]
|
|
686
|
+
def tax_category_id
|
|
687
|
+
delivery_method&.tax_category_id
|
|
688
|
+
end
|
|
689
|
+
|
|
690
|
+
# Only one of either included_tax_total or additional_tax_total is set
|
|
691
|
+
# This method returns the total of the two. Saves having to check if
|
|
692
|
+
# tax is included or additional.
|
|
693
|
+
def tax_total
|
|
694
|
+
included_tax_total + additional_tax_total
|
|
695
|
+
end
|
|
696
|
+
|
|
697
|
+
def to_package
|
|
698
|
+
package = Stock::Package.new(stock_location)
|
|
699
|
+
package.owner = owner
|
|
700
|
+
fulfillment_items.includes(:variant).joins(:variant).group_by(&:status).each do |status, units|
|
|
701
|
+
package.add_multiple units, status.to_sym
|
|
702
|
+
end
|
|
703
|
+
package
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
# The consignment the 5.6 +tracking+/+tracking_url+ summary describes —
|
|
707
|
+
# the earliest delivery. Every other delivery is read through
|
|
708
|
+
# #deliveries; the fulfillment only ever summarizes this one.
|
|
709
|
+
#
|
|
710
|
+
# @return [Spree::Delivery, nil]
|
|
711
|
+
def primary_delivery
|
|
712
|
+
deliveries.first
|
|
713
|
+
end
|
|
714
|
+
|
|
715
|
+
# The primary delivery's tracking number. Read-only since 6.0: tracking is
|
|
716
|
+
# a {Spree::Delivery} created through Spree::Deliveries::Create or the
|
|
717
|
+
# +tracking:+ shortcut on Spree::Fulfillments::Fulfill / Update.
|
|
718
|
+
#
|
|
719
|
+
# @return [String, nil]
|
|
720
|
+
def tracking
|
|
721
|
+
primary_delivery&.tracking_number
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
# @deprecated Assigning tracking writes a delivery on save; removed in
|
|
725
|
+
# 6.1. Use Spree::Deliveries::Create or the +tracking:+ keyword on
|
|
726
|
+
# Spree::Fulfillments::Fulfill / Update instead.
|
|
727
|
+
def tracking=(value)
|
|
728
|
+
Spree::Deprecation.warn(
|
|
729
|
+
'Spree::Fulfillment#tracking= is deprecated and will be removed in Spree 6.1. ' \
|
|
730
|
+
'Tracking is a Spree::Delivery — use Spree::Deliveries::Create or the tracking: keyword ' \
|
|
731
|
+
'on Spree::Fulfillments::Fulfill / Update.'
|
|
732
|
+
)
|
|
733
|
+
@pending_tracking = value
|
|
734
|
+
end
|
|
735
|
+
|
|
736
|
+
# The public page where the primary consignment can be followed.
|
|
737
|
+
#
|
|
738
|
+
# @return [String, nil]
|
|
739
|
+
def tracking_url
|
|
740
|
+
primary_delivery&.resolved_tracking_url
|
|
741
|
+
end
|
|
742
|
+
|
|
743
|
+
# The label that currently binds this parcel — bought or uploaded, and not
|
|
744
|
+
# refunded. At most one exists: the label workflows refuse a second one.
|
|
745
|
+
#
|
|
746
|
+
# @return [Spree::ShippingLabel, nil]
|
|
747
|
+
def active_shipping_label
|
|
748
|
+
shipping_labels.active.last
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
def update_amounts
|
|
752
|
+
if selected_delivery_rate && cost != selected_delivery_rate.cost
|
|
753
|
+
# Typed adjustment columns are refreshed by the order recalculation.
|
|
754
|
+
update_columns(cost: selected_delivery_rate.cost, updated_at: Time.current)
|
|
755
|
+
end
|
|
756
|
+
end
|
|
757
|
+
|
|
758
|
+
# @deprecated No-op since 6.0; removed in 6.1.
|
|
759
|
+
#
|
|
760
|
+
# This re-derived the status from the order's payment state on every order
|
|
761
|
+
# recalculation, which is what made a fulfillment move backwards when a
|
|
762
|
+
# refund landed. A fulfillment's status now only changes when a workflow
|
|
763
|
+
# changes it, so there is nothing left to refresh.
|
|
764
|
+
def update!(*args)
|
|
765
|
+
# Only the legacy `update!(order)` form is dead. Anything else is
|
|
766
|
+
# ActiveRecord's own update! — a Hash of attributes — which workflows
|
|
767
|
+
# rely on to write the status.
|
|
768
|
+
return super unless args.one? && (args.first.is_a?(Spree::Order) || args.first.is_a?(Spree::Cart))
|
|
769
|
+
|
|
770
|
+
Spree::Deprecation.warn('Spree::Fulfillment#update!(order) is a no-op since Spree 6.0 and will be removed in 6.1. Fulfillment statuses change through Spree::Fulfillments workflows.')
|
|
771
|
+
true
|
|
772
|
+
end
|
|
773
|
+
|
|
774
|
+
def transfer_to_location(variant, quantity, stock_location)
|
|
775
|
+
transfer_to_shipment(
|
|
776
|
+
variant,
|
|
777
|
+
quantity,
|
|
778
|
+
order.shipments.build(stock_location: stock_location)
|
|
779
|
+
)
|
|
780
|
+
end
|
|
781
|
+
|
|
782
|
+
def transfer_to_shipment(variant, quantity, shipment_to_transfer_to)
|
|
783
|
+
Spree::FulfillmentChanger.new(
|
|
784
|
+
current_stock_location: stock_location,
|
|
785
|
+
desired_stock_location: shipment_to_transfer_to.stock_location,
|
|
786
|
+
current_shipment: self,
|
|
787
|
+
desired_shipment: shipment_to_transfer_to,
|
|
788
|
+
variant: variant,
|
|
789
|
+
quantity: quantity
|
|
790
|
+
)
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
private
|
|
794
|
+
|
|
795
|
+
# @return [Boolean] whether this parcel's order shares its payment with
|
|
796
|
+
# others placed in the same checkout
|
|
797
|
+
# Draws one parcel's worth from a payment and reports what it took.
|
|
798
|
+
#
|
|
799
|
+
# A payment shared by a split checkout is only ever drawn on up to this
|
|
800
|
+
# order's own share of it — without the bound, the first seller to ship
|
|
801
|
+
# would capture against the whole basket and leave nothing authorised for
|
|
802
|
+
# the rest. The bound is read and written **inside the share's lock**, so
|
|
803
|
+
# two parcels of the same order dispatching at once cannot both read the
|
|
804
|
+
# same remaining share and each capture it.
|
|
805
|
+
#
|
|
806
|
+
# @return [BigDecimal] what was actually captured
|
|
807
|
+
def capture_from(payment, capturable_amount)
|
|
808
|
+
return capture_at_gateway(payment, capturable_amount) unless grouped_owner?
|
|
809
|
+
|
|
810
|
+
split = owner.payment_split_for(payment)
|
|
811
|
+
return 0 if split.nil?
|
|
812
|
+
|
|
813
|
+
# Claimed before the gateway, and in its own short transaction rather
|
|
814
|
+
# than one held across the network call. Two reasons the claim comes
|
|
815
|
+
# first: two parcels of the same order dispatching at once would
|
|
816
|
+
# otherwise both read the same remaining share, and capturing part of a
|
|
817
|
+
# shared payment forks the remainder, carrying each order's
|
|
818
|
+
# still-uncaptured share across — a share not yet marked taken would be
|
|
819
|
+
# carried over in full and paid to this order twice.
|
|
820
|
+
bounded = claim_share(split, capturable_amount)
|
|
821
|
+
return 0 if bounded <= 0
|
|
822
|
+
|
|
823
|
+
begin
|
|
824
|
+
capture_at_gateway(payment, bounded)
|
|
825
|
+
rescue StandardError
|
|
826
|
+
# Released only when the money truly never moved. The capture workflow
|
|
827
|
+
# keeps working after the charge commits — it authorizes the remainder
|
|
828
|
+
# of a partially captured payment — so a failure at that point is not a
|
|
829
|
+
# failure to capture, and giving the claim back would let this order
|
|
830
|
+
# draw the same money again.
|
|
831
|
+
settle_share(split, bounded, captured: payment.reload.completed?)
|
|
832
|
+
raise
|
|
833
|
+
end
|
|
834
|
+
|
|
835
|
+
settle_share(split, bounded, captured: true)
|
|
836
|
+
bounded
|
|
837
|
+
end
|
|
838
|
+
|
|
839
|
+
# Turns a claim into the thing it turned out to be: money the gateway took,
|
|
840
|
+
# or nothing at all. Failures here are reported rather than raised — a
|
|
841
|
+
# caller in the rescue path is already raising the reason the capture
|
|
842
|
+
# failed, and losing that to a bookkeeping error would hide it.
|
|
843
|
+
def settle_share(split, amount, captured:)
|
|
844
|
+
split.with_lock do
|
|
845
|
+
attributes = { claimed_amount: split.claimed_amount - amount }
|
|
846
|
+
attributes[:captured_amount] = split.captured_amount + amount if captured
|
|
847
|
+
split.update!(attributes)
|
|
848
|
+
end
|
|
849
|
+
rescue StandardError => e
|
|
850
|
+
Rails.error.report(e, handled: true, context: { payment_split_id: split.id }, source: 'spree.core')
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
# @return [BigDecimal] how much of the share this parcel may take, marked
|
|
854
|
+
# as taken; zero when nothing is left
|
|
855
|
+
def claim_share(split, capturable_amount)
|
|
856
|
+
split.with_lock do
|
|
857
|
+
# What is left to draw counts money already taken *and* money another
|
|
858
|
+
# parcel has reserved but not yet drawn, so two dispatching at once
|
|
859
|
+
# cannot both reach for the same amount.
|
|
860
|
+
bounded = [capturable_amount, split.undrawn_amount].min
|
|
861
|
+
next 0 if bounded <= 0
|
|
862
|
+
|
|
863
|
+
split.update!(claimed_amount: split.claimed_amount + bounded)
|
|
864
|
+
bounded
|
|
865
|
+
end
|
|
866
|
+
end
|
|
867
|
+
|
|
868
|
+
# @return [BigDecimal] the amount captured, so callers can draw it down
|
|
869
|
+
def capture_at_gateway(payment, amount)
|
|
870
|
+
return 0 if amount <= 0
|
|
871
|
+
|
|
872
|
+
units = Spree::Money::Rounding.to_minor_units(amount, payment.currency)
|
|
873
|
+
result = Spree.payment_capture_workflow.call(payment: payment, amount: units)
|
|
874
|
+
raise Spree::Core::GatewayError, result.error.value.to_s if result.failure?
|
|
875
|
+
|
|
876
|
+
amount
|
|
877
|
+
end
|
|
878
|
+
|
|
879
|
+
def grouped_owner?
|
|
880
|
+
owner.is_a?(Spree::Order) && owner.grouped?
|
|
881
|
+
end
|
|
882
|
+
|
|
883
|
+
# Inlined from the removed ShipmentHandler (its name-constantize factory
|
|
884
|
+
# could never match a real subclass); FulfillmentProvider takes over the
|
|
885
|
+
# type-specific mechanics in the provider wave.
|
|
886
|
+
def after_fulfill
|
|
887
|
+
fulfillment_items.each(&:ship!)
|
|
888
|
+
process_order_payments
|
|
889
|
+
touch :fulfilled_at
|
|
890
|
+
run_provider_create_fulfillment
|
|
891
|
+
update_order_fulfillment_status
|
|
892
|
+
end
|
|
893
|
+
|
|
894
|
+
# Lets the provider perform its dispatch mechanics; tracking data it
|
|
895
|
+
# returns becomes the primary delivery unless an admin already entered one.
|
|
896
|
+
def run_provider_create_fulfillment
|
|
897
|
+
result = provider.create_fulfillment(self)
|
|
898
|
+
return unless result.is_a?(Hash)
|
|
899
|
+
|
|
900
|
+
new_tracking = result[:tracking_number].presence
|
|
901
|
+
return if new_tracking.blank? || tracking.present?
|
|
902
|
+
|
|
903
|
+
Spree.delivery_create_service.call(
|
|
904
|
+
owner: self, tracking_number: new_tracking, tracking_url: result[:tracking_url]
|
|
905
|
+
)
|
|
906
|
+
end
|
|
907
|
+
|
|
908
|
+
def update_order_fulfillment_status
|
|
909
|
+
return if order.nil?
|
|
910
|
+
|
|
911
|
+
order.update_statuses!
|
|
912
|
+
end
|
|
913
|
+
|
|
914
|
+
def can_get_rates?
|
|
915
|
+
return true unless owner&.shipping_address_required?
|
|
916
|
+
|
|
917
|
+
owner.ship_address&.valid?
|
|
918
|
+
end
|
|
919
|
+
|
|
920
|
+
# Cancelling withdraws the promise made at placement — nothing physical
|
|
921
|
+
# comes back, so on-hand and backordered units go back the same way and
|
|
922
|
+
# the old backordered special case is gone.
|
|
923
|
+
def manifest_restock(item)
|
|
924
|
+
quantity = [item.quantity, allocated_quantities[item.variant.id].to_i].min
|
|
925
|
+
return unless quantity.positive?
|
|
926
|
+
|
|
927
|
+
stock_location.release(item.variant, quantity, self)
|
|
928
|
+
end
|
|
929
|
+
|
|
930
|
+
def manifest_unstock(item)
|
|
931
|
+
stock_location.allocate(item.variant, item.quantity, self) if item.variant.track_inventory?
|
|
932
|
+
end
|
|
933
|
+
|
|
934
|
+
def set_cost_zero_when_nil
|
|
935
|
+
self.cost = 0 unless cost
|
|
936
|
+
end
|
|
937
|
+
|
|
938
|
+
# The deprecated writer's other half: a tracking number assigned the old
|
|
939
|
+
# way still lands where every reader looks, on the primary delivery.
|
|
940
|
+
# Runs after commit rather than inside the save chain: writing a second
|
|
941
|
+
# record from within this one's callbacks is what the workflows exist to
|
|
942
|
+
# avoid, and the association has to see a committed fulfillment.
|
|
943
|
+
#
|
|
944
|
+
# A rejection surfaces on the fulfillment's own errors rather than as an
|
|
945
|
+
# exception: the save has already committed by the time this runs, and
|
|
946
|
+
# raising here would report a persisted write as a failure. Code that
|
|
947
|
+
# needs the rejection to abort creates the delivery directly.
|
|
948
|
+
def apply_pending_tracking
|
|
949
|
+
value = remove_instance_variable(:@pending_tracking)
|
|
950
|
+
return if value.blank?
|
|
951
|
+
|
|
952
|
+
deliveries.reset
|
|
953
|
+
result = Spree.delivery_upsert_primary_service.call(fulfillment: self, tracking: value)
|
|
954
|
+
return if result.success?
|
|
955
|
+
|
|
956
|
+
errors.merge!(result.value.errors) if result.value.respond_to?(:errors)
|
|
957
|
+
end
|
|
958
|
+
|
|
959
|
+
def exactly_one_owner
|
|
960
|
+
errors.add(:base, :exactly_one_of_cart_or_order, message: Spree.t('errors.messages.exactly_one_of_cart_or_order')) unless [order, cart].compact.one?
|
|
961
|
+
end
|
|
962
|
+
|
|
963
|
+
def update_adjustments
|
|
964
|
+
# A cost change shifts discount and tax bases — rebuild through the
|
|
965
|
+
# order-level recalculation. Creation is excluded (the surrounding flow
|
|
966
|
+
# runs the updater itself; recursing mid-assignment breaks collection
|
|
967
|
+
# replacement) and completed orders are frozen.
|
|
968
|
+
return if previously_new_record?
|
|
969
|
+
|
|
970
|
+
owner.recalculate_totals! if saved_change_to_cost? && status != 'fulfilled' && owner&.persisted? && !owner.completed?
|
|
971
|
+
end
|
|
972
|
+
end
|
|
973
|
+
end
|