spree_core 6.0.0.beta3 → 6.0.0.rc1
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/README.md +2 -2
- data/app/helpers/spree/images_helper.rb +0 -57
- data/app/jobs/spree/base_job.rb +21 -0
- data/app/jobs/spree/carts/reap_expired_job.rb +2 -2
- data/app/jobs/spree/collections/regenerate_time_based_job.rb +6 -3
- data/app/jobs/spree/orders/finalize_stale_drafts_job.rb +8 -5
- data/app/jobs/spree/payments/cancel_unused_sessions_job.rb +61 -0
- data/app/jobs/spree/seller_payouts/sweep_seller_job.rb +2 -0
- data/app/mailers/spree/admin_user_mailer.rb +4 -19
- data/app/mailers/spree/base_mailer.rb +96 -13
- data/app/mailers/spree/email_template_mailer.rb +27 -0
- data/app/mailers/spree/export_mailer.rb +3 -4
- data/app/mailers/spree/import_mailer.rb +3 -4
- data/app/mailers/spree/invitation_mailer.rb +24 -7
- data/app/mailers/spree/seller_user_mailer.rb +4 -16
- data/app/mailers/spree/webhook_mailer.rb +2 -2
- data/app/models/concerns/spree/acted_by.rb +1 -1
- data/app/models/concerns/spree/admin_user_methods.rb +13 -1
- data/app/models/concerns/spree/api_typed.rb +91 -0
- data/app/models/concerns/spree/calculator/tiers.rb +76 -0
- data/app/models/concerns/spree/customer_methods.rb +15 -14
- data/app/models/concerns/spree/email_template_identity.rb +52 -0
- data/app/models/concerns/spree/parameterizable_name.rb +2 -0
- data/app/models/concerns/spree/payment_session_transitions.rb +8 -2
- data/app/models/concerns/spree/post_sale/taxation.rb +54 -0
- data/app/models/concerns/spree/post_sale/taxed_line.rb +51 -0
- data/app/models/concerns/spree/preference_schema.rb +4 -12
- data/app/models/concerns/spree/product_scopes.rb +11 -1
- data/app/models/concerns/spree/provider_listing.rb +41 -0
- data/app/models/concerns/spree/publishable.rb +82 -14
- data/app/models/concerns/spree/purchase/addresses.rb +23 -10
- data/app/models/concerns/spree/purchase/currency.rb +1 -1
- data/app/models/concerns/spree/purchase/deprecated_aliases.rb +87 -0
- data/app/models/concerns/spree/purchase/gift_cards.rb +10 -4
- data/app/models/concerns/spree/purchase/locale.rb +1 -1
- data/app/models/concerns/spree/purchase/payment_processing.rb +7 -3
- data/app/models/concerns/spree/purchase/purchase_order.rb +2 -2
- data/app/models/concerns/spree/purchase/totals.rb +49 -1
- data/app/models/concerns/spree/receivable.rb +1 -1
- data/app/models/concerns/spree/searchable.rb +0 -4
- data/app/models/concerns/spree/secret_preferences.rb +59 -0
- data/app/models/concerns/spree/single_store_resource.rb +1 -1
- data/app/models/concerns/spree/stores/email_branding.rb +31 -0
- data/app/models/concerns/spree/type_labels.rb +38 -0
- data/app/models/concerns/spree/typed_adjustment_line.rb +1 -1
- data/app/models/concerns/spree/typed_associations.rb +6 -0
- data/app/models/spree/address.rb +11 -1
- data/app/models/spree/adjusters/promotion.rb +1 -15
- data/app/models/spree/allowed_origin.rb +0 -1
- data/app/models/spree/api_key.rb +5 -6
- data/app/models/spree/authentication/strategies/oidc_strategy.rb +5 -5
- data/app/models/spree/base.rb +70 -22
- data/app/models/spree/calculator/flat_percent_item_total.rb +1 -3
- data/app/models/spree/calculator/flat_rate.rb +1 -3
- data/app/models/spree/calculator/flexi_rate.rb +1 -3
- data/app/models/spree/calculator/percent_on_line_item.rb +1 -1
- data/app/models/spree/calculator/price_sack.rb +1 -3
- data/app/models/spree/calculator/shipping/digital_delivery.rb +1 -3
- data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +1 -3
- data/app/models/spree/calculator/shipping/flat_rate.rb +1 -3
- data/app/models/spree/calculator/shipping/flexi_rate.rb +1 -3
- data/app/models/spree/calculator/shipping/per_item.rb +1 -3
- data/app/models/spree/calculator/shipping/price_sack.rb +1 -3
- data/app/models/spree/calculator/tiered_flat_rate.rb +6 -23
- data/app/models/spree/calculator/tiered_percent.rb +7 -25
- data/app/models/spree/cart.rb +78 -18
- data/app/models/spree/channel/gating.rb +1 -1
- data/app/models/spree/channel.rb +4 -4
- data/app/models/spree/claim.rb +21 -1
- data/app/models/spree/claim_line_item.rb +41 -6
- data/app/models/spree/collection.rb +0 -1
- data/app/models/spree/collection_rule.rb +5 -21
- data/app/models/spree/commission_line.rb +1 -1
- data/app/models/spree/commission_rate.rb +2 -3
- data/app/models/spree/commission_rate_value.rb +1 -1
- data/app/models/spree/commission_rule.rb +4 -11
- data/app/models/spree/commission_rules/product_rule.rb +1 -1
- data/app/models/spree/company_invitation.rb +1 -0
- data/app/models/spree/consent_record.rb +0 -1
- data/app/models/spree/credit_card.rb +1 -1
- data/app/models/spree/current.rb +23 -0
- data/app/models/spree/custom_field.rb +2 -2
- data/app/models/spree/custom_field_definition.rb +9 -23
- data/app/models/spree/custom_fields/boolean.rb +1 -1
- data/app/models/spree/custom_fields/json.rb +1 -1
- data/app/models/spree/data_feed/google.rb +0 -2
- data/app/models/spree/data_request.rb +1 -1
- data/app/models/spree/delivery_method.rb +30 -13
- data/app/models/spree/delivery_method_rule.rb +4 -11
- data/app/models/spree/delivery_rate.rb +4 -5
- data/app/models/spree/delivery_rate_provider/base.rb +1 -0
- data/app/models/spree/delivery_zone.rb +0 -1
- data/app/models/spree/delivery_zone_member.rb +4 -4
- data/app/models/spree/digital_asset.rb +7 -0
- data/app/models/spree/digital_asset_provider/base.rb +2 -0
- data/app/models/spree/digital_link.rb +2 -5
- data/app/models/spree/discount.rb +1 -1
- data/app/models/spree/email_template.rb +25 -0
- data/app/models/spree/email_template_draft.rb +13 -0
- data/app/models/spree/email_template_revision.rb +17 -0
- data/app/models/spree/email_templates/entry.rb +118 -0
- data/app/models/spree/email_templates/sample_record.rb +16 -0
- data/app/models/spree/emails/branding.rb +80 -0
- data/app/models/spree/exchange.rb +15 -1
- data/app/models/spree/exchange_line_item.rb +121 -5
- data/app/models/spree/export.rb +0 -1
- data/app/models/spree/exports/products.rb +10 -1
- data/app/models/spree/exports/report.rb +1 -1
- data/app/models/spree/fee.rb +4 -2
- data/app/models/spree/fulfillment.rb +53 -27
- data/app/models/spree/fulfillment_changer.rb +2 -2
- data/app/models/spree/fulfillment_item.rb +0 -4
- data/app/models/spree/fulfillment_provider/base.rb +1 -0
- data/app/models/spree/gateway/bogus.rb +4 -0
- data/app/models/spree/gateway/custom_payment_source_method.rb +5 -0
- data/app/models/spree/gateway.rb +5 -1
- data/app/models/spree/gift_card.rb +12 -1
- data/app/models/spree/gift_card_batch.rb +0 -1
- data/app/models/spree/import.rb +2 -7
- data/app/models/spree/import_mapping.rb +1 -2
- data/app/models/spree/import_row.rb +2 -2
- data/app/models/spree/import_schemas/products.rb +1 -0
- data/app/models/spree/integration.rb +8 -18
- data/app/models/spree/invitation.rb +5 -5
- data/app/models/spree/line_item.rb +13 -2
- data/app/models/spree/locale.rb +11 -8
- data/app/models/spree/market.rb +1 -0
- data/app/models/spree/newsletter_subscriber.rb +3 -0
- data/app/models/spree/order.rb +56 -138
- data/app/models/spree/order_group.rb +11 -2
- data/app/models/spree/order_inventory.rb +10 -5
- data/app/models/spree/order_promotion.rb +1 -1
- data/app/models/spree/order_routing/has_strategy_preference.rb +1 -1
- data/app/models/spree/order_routing/strategy/base.rb +4 -2
- data/app/models/spree/order_routing/strategy/rules.rb +1 -1
- data/app/models/spree/order_routing_rule.rb +6 -22
- data/app/models/spree/package_type.rb +1 -2
- data/app/models/spree/payment/gateway_options.rb +14 -52
- data/app/models/spree/payment/processing.rb +2 -4
- data/app/models/spree/payment.rb +20 -5
- data/app/models/spree/payment_method/session_instrumentation.rb +1 -0
- data/app/models/spree/payment_method/store_credit.rb +4 -4
- data/app/models/spree/payment_method.rb +36 -4
- data/app/models/spree/payment_session.rb +5 -1
- data/app/models/spree/payment_setup_session.rb +1 -0
- data/app/models/spree/payout_provider/base.rb +3 -1
- data/app/models/spree/pickup_point_provider/base.rb +2 -0
- data/app/models/spree/price_list.rb +1 -2
- data/app/models/spree/price_rules/channel_rule.rb +1 -1
- data/app/models/spree/price_rules/customer_group_rule.rb +1 -1
- data/app/models/spree/product.rb +31 -7
- data/app/models/spree/product_submission.rb +0 -12
- data/app/models/spree/product_type.rb +0 -1
- data/app/models/spree/promotion/actions/create_line_items.rb +27 -17
- data/app/models/spree/promotion/rules/category.rb +0 -4
- data/app/models/spree/promotion/rules/channel.rb +0 -4
- data/app/models/spree/promotion/rules/country.rb +0 -4
- data/app/models/spree/promotion/rules/currency.rb +0 -4
- data/app/models/spree/promotion/rules/customer_group.rb +0 -4
- data/app/models/spree/promotion/rules/first_order.rb +0 -4
- data/app/models/spree/promotion/rules/item_total.rb +4 -8
- data/app/models/spree/promotion/rules/market.rb +0 -4
- data/app/models/spree/promotion/rules/one_use_per_user.rb +0 -4
- data/app/models/spree/promotion/rules/option_value.rb +0 -3
- data/app/models/spree/promotion/rules/product.rb +0 -4
- data/app/models/spree/promotion/rules/user.rb +0 -4
- data/app/models/spree/promotion/rules/user_logged_in.rb +0 -4
- data/app/models/spree/promotion.rb +35 -6
- data/app/models/spree/promotion_action.rb +7 -14
- data/app/models/spree/promotion_action_line_item.rb +1 -1
- data/app/models/spree/promotion_handler/coupon.rb +59 -27
- data/app/models/spree/promotion_rule.rb +7 -14
- data/app/models/spree/purchase_order.rb +1 -0
- data/app/models/spree/quantity_rule.rb +1 -1
- data/app/models/spree/refund.rb +28 -3
- data/app/models/spree/return.rb +30 -2
- data/app/models/spree/return_line_item.rb +65 -14
- data/app/models/spree/role.rb +7 -7
- data/app/models/spree/saved_report.rb +1 -1
- data/app/models/spree/seller.rb +2 -1
- data/app/models/spree/seller_payout.rb +7 -0
- data/app/models/spree/seller_requirement.rb +4 -12
- data/app/models/spree/seller_requirement_custom_field.rb +1 -2
- data/app/models/spree/seller_requirement_submission.rb +2 -2
- data/app/models/spree/seller_requirements/accept_terms.rb +2 -3
- data/app/models/spree/seller_transfer.rb +5 -0
- data/app/models/spree/shipping_label.rb +1 -0
- data/app/models/spree/stock/availability_validator.rb +2 -2
- data/app/models/spree/stock/inventory_unit_builder.rb +1 -1
- data/app/models/spree/stock/packer.rb +2 -2
- data/app/models/spree/stock/splitter/weight.rb +1 -1
- data/app/models/spree/stock_level/custom_events.rb +6 -0
- data/app/models/spree/stock_level.rb +1 -1
- data/app/models/spree/stock_movement.rb +1 -1
- data/app/models/spree/stock_receipt_item.rb +1 -1
- data/app/models/spree/stock_reservation.rb +2 -2
- data/app/models/spree/stock_transfer.rb +4 -2
- data/app/models/spree/store.rb +33 -7
- data/app/models/spree/store_credit.rb +8 -9
- data/app/models/spree/store_credit_event.rb +5 -5
- data/app/models/spree/tax_exemption_certificate.rb +2 -0
- data/app/models/spree/tax_identifier.rb +3 -1
- data/app/models/spree/tax_line.rb +53 -3
- data/app/models/spree/tax_provider/base.rb +71 -14
- data/app/models/spree/tax_provider/internal.rb +59 -33
- data/app/models/spree/tax_provider/recorded_share.rb +114 -0
- data/app/models/spree/tax_rate.rb +1 -2
- data/app/models/spree/taxonomy.rb +0 -1
- data/app/models/spree/variant.rb +4 -3
- data/app/models/spree/variant_media.rb +1 -1
- data/app/models/spree/webhook_endpoint.rb +10 -13
- data/app/models/spree/wishlist.rb +1 -6
- data/app/models/spree/wishlist_item/custom_events.rb +6 -0
- data/app/presenters/spree/csv/customer_presenter.rb +1 -1
- data/app/presenters/spree/csv/newsletter_subscriber_presenter.rb +1 -1
- data/app/presenters/spree/csv/order_line_item_presenter.rb +1 -1
- data/app/presenters/spree/csv/product_variant_presenter.rb +42 -12
- data/app/serializers/spree/emails/base_serializer.rb +14 -0
- data/app/serializers/spree/emails/export_serializer.rb +13 -0
- data/app/serializers/spree/emails/import_serializer.rb +19 -0
- data/app/serializers/spree/emails/invitation_serializer.rb +28 -0
- data/app/serializers/spree/emails/store_serializer.rb +31 -0
- data/app/serializers/spree/emails/user_serializer.rb +12 -0
- data/app/serializers/spree/emails/webhook_endpoint_serializer.rb +16 -0
- data/app/services/spree/carts/create.rb +8 -2
- data/app/services/spree/carts/destroy.rb +2 -2
- data/app/services/spree/carts/remove_out_of_stock_items.rb +2 -2
- data/app/services/spree/carts/split_by_seller.rb +1 -1
- data/app/services/spree/carts/update.rb +19 -5
- data/app/services/spree/catalogs/set_product_terms.rb +1 -1
- data/app/services/spree/categories/add_products.rb +13 -31
- data/app/services/spree/categories/remove_products.rb +12 -51
- data/app/services/spree/checkout/advance.rb +1 -4
- data/app/services/spree/collections/add_products.rb +10 -23
- data/app/services/spree/collections/remove_products.rb +7 -43
- data/app/services/spree/coupon_codes/bulk_generate.rb +8 -14
- data/app/services/spree/data_requests/create.rb +1 -1
- data/app/services/spree/deliveries/destroy.rb +2 -2
- data/app/services/spree/email_templates/check.rb +58 -0
- data/app/services/spree/email_templates/no_sample_record.rb +7 -0
- data/app/services/spree/email_templates/preview.rb +99 -0
- data/app/services/spree/emails/file_system.rb +23 -0
- data/app/services/spree/emails/filters.rb +84 -0
- data/app/services/spree/emails/liquid_context.rb +48 -0
- data/app/services/spree/emails/rendered_email.rb +14 -0
- data/app/services/spree/emails/renderer.rb +125 -0
- data/app/services/spree/emails/template.rb +51 -0
- data/app/services/spree/emails/template_data.rb +23 -0
- data/app/services/spree/emails/template_resolver.rb +109 -0
- data/app/services/spree/emails/text_converter.rb +72 -0
- data/app/services/spree/emails/translation_inliner.rb +134 -0
- data/app/services/spree/imports/row_processors/price_list_price.rb +10 -10
- data/app/services/spree/imports/row_processors/product_variant.rb +65 -34
- data/app/services/spree/imports/row_processors/purchase_order.rb +13 -13
- data/app/services/spree/locales.rb +4 -5
- data/app/services/spree/newsletter/subscribe.rb +8 -12
- data/app/services/spree/orders/build_fulfillments.rb +3 -2
- data/app/services/spree/orders/create.rb +2 -1
- data/app/services/spree/orders/discounts/create.rb +7 -4
- data/app/services/spree/orders/discounts/destroy.rb +1 -0
- data/app/services/spree/orders/discounts/update.rb +1 -0
- data/app/services/spree/orders/fees/create.rb +1 -0
- data/app/services/spree/orders/fees/destroy.rb +1 -0
- data/app/services/spree/orders/fees/update.rb +1 -0
- data/app/services/spree/orders/remove_line_item.rb +13 -3
- data/app/services/spree/orders/update.rb +10 -6
- data/app/services/spree/orders/update_item.rb +6 -3
- data/app/services/spree/orders/update_statuses.rb +3 -1
- data/app/services/spree/product_memberships.rb +61 -0
- data/app/services/spree/returns/eligibility_validator.rb +1 -1
- data/app/services/spree/search_provider/custom_field_schema.rb +2 -2
- data/app/services/spree/seeds/commission_rates.rb +1 -1
- data/app/services/spree/seeds/digital_delivery.rb +1 -1
- data/app/services/spree/seeds/payment_methods.rb +2 -2
- data/app/services/spree/seeds/saved_reports.rb +3 -3
- data/app/services/spree/sellers/requirements.rb +1 -2
- data/app/services/spree/shipping_labels/confirm_refund.rb +1 -1
- data/app/services/spree/shipping_labels/store_file.rb +3 -3
- data/app/services/spree/stock_levels/correct.rb +3 -3
- data/app/services/spree/stock_reservations/reserve.rb +2 -3
- data/app/services/spree/store_credits/apply.rb +15 -13
- data/app/services/spree/stores/provision_defaults.rb +15 -14
- data/app/subscribers/spree/seller_onboarding_subscriber.rb +1 -1
- data/app/views/layouts/spree/base_mailer.html.erb +2 -43
- data/app/views/layouts/spree/base_mailer.liquid +79 -0
- data/app/views/spree/admin_user_mailer/password_reset_email.liquid +14 -0
- data/app/views/spree/export_mailer/export_done.liquid +12 -0
- data/app/views/spree/import_mailer/import_done.liquid +15 -0
- data/app/views/spree/invitation_mailer/invitation_accepted.liquid +9 -0
- data/app/views/spree/invitation_mailer/invitation_email.liquid +13 -0
- data/app/views/spree/seller_user_mailer/password_reset_email.liquid +14 -0
- data/app/views/spree/shared/_mailer_button.html.erb +4 -5
- data/app/views/spree/shared/_mailer_hero.html.erb +6 -5
- data/app/views/spree/shared/_summary_row.liquid +8 -0
- data/app/views/spree/webhook_mailer/endpoint_disabled.liquid +21 -0
- data/app/workflows/spree/carts/add_item.rb +4 -4
- data/app/workflows/spree/carts/complete.rb +13 -3
- data/app/workflows/spree/carts/merge.rb +1 -1
- data/app/workflows/spree/carts/recalculate_totals.rb +5 -0
- data/app/workflows/spree/carts/upsert_items.rb +18 -9
- data/app/workflows/spree/claims/approve.rb +5 -22
- data/app/workflows/spree/claims/cancel.rb +5 -21
- data/app/workflows/spree/claims/create.rb +15 -0
- data/app/workflows/spree/claims/deny.rb +7 -0
- data/app/workflows/spree/claims/resolve.rb +34 -31
- data/app/workflows/spree/customers/anonymize.rb +3 -4
- data/app/workflows/spree/customers/create.rb +1 -1
- data/app/workflows/spree/data_requests/fulfill.rb +2 -2
- data/app/workflows/spree/deliveries/update_tracking.rb +1 -1
- data/app/workflows/spree/email_templates/discard_draft.rb +20 -0
- data/app/workflows/spree/email_templates/publish.rb +70 -0
- data/app/workflows/spree/email_templates/restore_revision.rb +33 -0
- data/app/workflows/spree/email_templates/revert.rb +29 -0
- data/app/workflows/spree/email_templates/save_draft.rb +85 -0
- data/app/workflows/spree/exchanges/approve.rb +5 -22
- data/app/workflows/spree/exchanges/cancel.rb +5 -21
- data/app/workflows/spree/exchanges/create.rb +6 -0
- data/app/workflows/spree/exchanges/fulfill.rb +75 -51
- data/app/workflows/spree/exchanges/receive.rb +6 -65
- data/app/workflows/spree/fulfillments/cancel.rb +1 -1
- data/app/workflows/spree/fulfillments/create.rb +51 -47
- data/app/workflows/spree/fulfillments/fulfill.rb +23 -27
- data/app/workflows/spree/fulfillments/mark_delivered.rb +1 -1
- data/app/workflows/spree/fulfillments/replacements.rb +59 -0
- data/app/workflows/spree/gift_cards/apply.rb +2 -2
- data/app/workflows/spree/orders/add_item.rb +5 -1
- data/app/workflows/spree/orders/cancel.rb +3 -3
- data/app/workflows/spree/orders/complete.rb +16 -8
- data/app/workflows/spree/payments/process.rb +2 -2
- data/app/workflows/spree/post_sale/approval.rb +35 -0
- data/app/workflows/spree/post_sale/cancellation.rb +44 -0
- data/app/workflows/spree/post_sale/receipt.rb +92 -0
- data/app/workflows/spree/products/nested_attributes.rb +1 -1
- data/app/workflows/spree/purchase_orders/cancel.rb +1 -1
- data/app/workflows/spree/purchase_orders/close.rb +3 -31
- data/app/workflows/spree/purchase_orders/mark_draft.rb +2 -2
- data/app/workflows/spree/purchase_orders/mark_ordered.rb +2 -2
- data/app/workflows/spree/purchase_orders/receive.rb +1 -1
- data/app/workflows/spree/purchase_orders/update.rb +5 -34
- data/app/workflows/spree/receivables/closing_short.rb +46 -0
- data/app/workflows/spree/receivables/draft_editing.rb +48 -0
- data/app/workflows/spree/refunds/create.rb +5 -2
- data/app/workflows/spree/refunds/order_payments.rb +14 -2
- data/app/workflows/spree/refunds/tax_credit.rb +67 -0
- data/app/workflows/spree/returns/approve.rb +5 -22
- data/app/workflows/spree/returns/cancel.rb +5 -22
- data/app/workflows/spree/returns/create.rb +8 -0
- data/app/workflows/spree/returns/receive.rb +5 -76
- data/app/workflows/spree/returns/refund.rb +31 -8
- data/app/workflows/spree/seller_requirement_submissions/create.rb +1 -2
- data/app/workflows/spree/seller_transfers/reverse.rb +28 -1
- data/app/workflows/spree/shipping_labels/purchase.rb +8 -8
- data/app/workflows/spree/shipping_labels/record.rb +5 -5
- data/app/workflows/spree/shipping_labels/refund.rb +2 -2
- data/app/workflows/spree/stock_receipts/recording.rb +4 -4
- data/app/workflows/spree/stock_transfers/cancel.rb +2 -2
- data/app/workflows/spree/stock_transfers/close.rb +3 -30
- data/app/workflows/spree/stock_transfers/mark_draft.rb +1 -1
- data/app/workflows/spree/stock_transfers/mark_in_transit.rb +3 -3
- data/app/workflows/spree/stock_transfers/mark_ready.rb +2 -2
- data/app/workflows/spree/stock_transfers/receive.rb +1 -1
- data/app/workflows/spree/stock_transfers/update.rb +5 -33
- data/config/i18n-tasks.yml +32 -18
- data/config/initializers/alba.rb +7 -0
- data/config/language_names.csv +264 -0
- data/config/locales/ar.yml +811 -0
- data/config/locales/be.yml +855 -0
- data/config/locales/bg.yml +723 -0
- data/config/locales/ca.yml +689 -0
- data/config/locales/cs.yml +855 -0
- data/config/locales/da.yml +771 -0
- data/config/locales/de-CH.yml +248 -0
- data/config/locales/de.yml +835 -0
- data/config/locales/el.yml +769 -0
- data/config/locales/en.yml +37 -503
- data/config/locales/es-CL.yml +301 -0
- data/config/locales/es-EC.yml +186 -0
- data/config/locales/es-MX.yml +334 -0
- data/config/locales/es.yml +831 -0
- data/config/locales/et.yml +644 -0
- data/config/locales/fa.yml +709 -0
- data/config/locales/fi.yml +771 -0
- data/config/locales/fr.yml +830 -0
- data/config/locales/hu.yml +751 -0
- data/config/locales/id.yml +756 -0
- data/config/locales/it.yml +833 -0
- data/config/locales/ja.yml +726 -0
- data/config/locales/km.yml +759 -0
- data/config/locales/ko.yml +575 -0
- data/config/locales/ku.yml +753 -0
- data/config/locales/lt.yml +821 -0
- data/config/locales/lv.yml +685 -0
- data/config/locales/nb.yml +824 -0
- data/config/locales/ne.yml +823 -0
- data/config/locales/nl.yml +826 -0
- data/config/locales/pl.yml +835 -0
- data/config/locales/pt-BR.yml +547 -0
- data/config/locales/pt.yml +636 -0
- data/config/locales/ro.yml +750 -0
- data/config/locales/ru.yml +834 -0
- data/config/locales/sk.yml +680 -0
- data/config/locales/sl-SI.yml +600 -0
- data/config/locales/sv.yml +827 -0
- data/config/locales/th.yml +745 -0
- data/config/locales/tr.yml +777 -0
- data/config/locales/uk.yml +836 -0
- data/config/locales/vi.yml +768 -0
- data/config/locales/zh-CN.yml +786 -0
- data/config/locales/zh-TW.yml +834 -0
- data/db/migrate/20260925000001_add_replacement_to_spree_fulfillment_items.rb +5 -0
- data/db/migrate/20261001000001_add_post_sale_tax.rb +30 -0
- data/db/migrate/20261001000001_convert_preferences_to_json.rb +166 -0
- data/db/migrate/20261001000001_create_spree_email_templates.rb +52 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +0 -9
- data/lib/generators/spree/dummy/templates/rails/test.rb +7 -0
- data/lib/spree/checkout/default_requirements.rb +37 -13
- data/lib/spree/core/configuration.rb +1 -1
- data/lib/spree/core/controller_helpers/store.rb +1 -1
- data/lib/spree/core/dependencies.rb +5 -4
- data/lib/spree/core/emails/escaped_output.rb +60 -0
- data/lib/spree/core/engine.rb +48 -167
- data/lib/spree/core/permissions/default_catalog.rb +5 -0
- data/lib/spree/core/preferences/json_conversion.rb +182 -0
- data/lib/spree/core/preferences/masking.rb +4 -1
- data/lib/spree/core/preferences/preferable.rb +137 -83
- data/lib/spree/core/preferences/preferable_class_methods.rb +81 -146
- data/lib/spree/core/previews/import_preview.rb +10 -0
- data/lib/spree/core/tax/provider_error.rb +37 -0
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +85 -370
- data/lib/spree/emails/editable_templates.rb +82 -0
- data/lib/spree/events/catalog.rb +189 -0
- data/lib/spree/events.rb +21 -1
- data/lib/spree/hooks.rb +0 -17
- data/lib/spree/i18n.rb +32 -15
- data/lib/spree/reporting/adapters/live.rb +6 -6
- data/lib/spree/reporting/default_vocabulary.rb +22 -10
- data/lib/spree/reporting/hydration.rb +1 -1
- data/lib/spree/reporting/query.rb +8 -0
- data/lib/spree/reporting/schema.rb +10 -10
- data/lib/spree/testing_support/editable_email_templates.rb +61 -0
- data/lib/spree/testing_support/emails.rb +22 -0
- data/lib/spree/testing_support/factories/cart_factory.rb +1 -1
- data/lib/spree/testing_support/factories/email_template_factory.rb +28 -0
- data/lib/spree/testing_support/factories/order_factory.rb +2 -2
- data/lib/spree/testing_support/factories/refund_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_factory.rb +1 -1
- data/lib/spree/testing_support/factories/variant_factory.rb +1 -1
- data/lib/spree/testing_support/i18n.rb +3 -94
- data/lib/spree/testing_support/lifecycle_events.rb +1 -1
- data/lib/spree/testing_support/order_walkthrough.rb +1 -1
- data/lib/spree/testing_support/preferences.rb +0 -5
- data/lib/spree/testing_support/store.rb +9 -1
- data/lib/spree/upgrades/5_6_to_6_0/manifest.yml +45 -0
- data/lib/tasks/categories_and_collections.rake +3 -3
- data/lib/tasks/core.rake +6 -4
- data/lib/tasks/media.rake +3 -3
- data/lib/tasks/package_types.rake +1 -1
- data/lib/tasks/preferences_json.rake +101 -0
- data/spec/fixtures/mailer_views/custom_views_probe_mailer/welcome_email.html.erb +4 -0
- metadata +188 -44
- data/app/models/acts_as_taggable_on/tag_decorator.rb +0 -10
- data/app/models/concerns/spree/has_image_alt_text.rb +0 -18
- data/app/models/spree/base_analytics_event_handler.rb +0 -54
- data/app/models/spree/invitations/store.rb +0 -6
- data/app/models/spree/preference.rb +0 -14
- data/app/models/spree/promotion_handler/page.rb +0 -25
- data/app/models/spree/promotion_handler/promotion_duplicator.rb +0 -60
- data/app/models/spree/stock/differentiator.rb +0 -45
- data/app/presenters/spree/filters/options_presenter.rb +0 -47
- data/app/services/spree/carts/empty.rb +0 -42
- data/app/services/spree/country_to_timezone.rb +0 -273
- data/app/services/spree/payments/create.rb +0 -92
- data/app/validators/spree/url_validator.rb +0 -23
- data/app/views/active_storage/blobs/_blob.html.erb +0 -14
- data/app/views/spree/admin_user_mailer/password_reset_email.html.erb +0 -8
- data/app/views/spree/export_mailer/export_done.html.erb +0 -7
- data/app/views/spree/import_mailer/import_done.html.erb +0 -12
- data/app/views/spree/invitation_mailer/invitation_accepted.html.erb +0 -4
- data/app/views/spree/invitation_mailer/invitation_email.html.erb +0 -12
- data/app/views/spree/seller_user_mailer/password_reset_email.html.erb +0 -8
- data/app/views/spree/shared/_base_mailer_footer.html.erb +0 -19
- data/app/views/spree/shared/_base_mailer_header.html.erb +0 -8
- data/app/views/spree/shared/_base_mailer_stylesheets.html.erb +0 -399
- data/app/views/spree/shared/_mailer_logo.html.erb +0 -41
- data/app/views/spree/shared/_purchased_items_styles.html.erb +0 -119
- data/app/views/spree/webhook_mailer/endpoint_disabled.html.erb +0 -51
- data/app/views/spree/webhook_mailer/endpoint_disabled.text.erb +0 -10
- data/app/workflows/spree/fulfillments/purchase_label.rb +0 -40
- data/app/workflows/spree/returns/purchase_label.rb +0 -32
- data/lib/spree/analytics.rb +0 -11
- data/lib/spree/core/preferences/scoped_store.rb +0 -34
- data/lib/spree/core/preferences/store.rb +0 -105
- data/lib/spree/translation_migrations.rb +0 -52
|
@@ -2,6 +2,8 @@ module Spree
|
|
|
2
2
|
# One problem item on a {Spree::Claim}, and how it is being made right:
|
|
3
3
|
# money back, a replacement, or both.
|
|
4
4
|
class ClaimLineItem < Spree.base_class
|
|
5
|
+
include Spree::PostSale::TaxedLine
|
|
6
|
+
|
|
5
7
|
has_prefix_id :cli
|
|
6
8
|
|
|
7
9
|
belongs_to :claim, class_name: 'Spree::Claim', inverse_of: :claim_line_items
|
|
@@ -20,16 +22,45 @@ module Spree
|
|
|
20
22
|
|
|
21
23
|
delegate :order, :currency, to: :claim
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
extend Spree::DisplayMoney
|
|
26
|
+
money_methods :refund_amount, :paid_amount, :pre_tax_amount, :included_tax_total,
|
|
27
|
+
:additional_tax_total, :tax_total
|
|
28
|
+
|
|
29
|
+
# What the customer paid for the affected units, after discounts and with
|
|
30
|
+
# the tax charged on top of the price — the ceiling for a refund on this
|
|
31
|
+
# line, which is entered tax included. A claim opened before claims
|
|
32
|
+
# carried tax has none, so its ceiling is unchanged.
|
|
33
|
+
#
|
|
34
|
+
# @return [BigDecimal]
|
|
25
35
|
def paid_amount
|
|
26
|
-
|
|
36
|
+
discounted_amount + additional_tax_total
|
|
37
|
+
end
|
|
27
38
|
|
|
28
|
-
|
|
39
|
+
# @return [BigDecimal] the affected units before tax
|
|
40
|
+
def pre_tax_amount
|
|
41
|
+
discounted_amount - included_tax_total
|
|
29
42
|
end
|
|
30
43
|
|
|
31
|
-
def
|
|
32
|
-
|
|
44
|
+
def tax_total
|
|
45
|
+
included_tax_total + additional_tax_total
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Nothing is given back on a claim that was denied or withdrawn.
|
|
49
|
+
#
|
|
50
|
+
# @return [Integer]
|
|
51
|
+
def credited_quantity
|
|
52
|
+
claim.denied? || claim.canceled? ? 0 : quantity.to_i
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @return [BigDecimal]
|
|
56
|
+
def credited_worth
|
|
57
|
+
paid_amount
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# @return [void]
|
|
61
|
+
def fold_tax_lines!
|
|
62
|
+
included, additional = tax_totals_from(tax_lines.credits.reload)
|
|
63
|
+
update_columns(included_tax_total: included, additional_tax_total: additional)
|
|
33
64
|
end
|
|
34
65
|
|
|
35
66
|
# What actually ships when the claim is resolved with a replacement.
|
|
@@ -39,6 +70,10 @@ module Spree
|
|
|
39
70
|
|
|
40
71
|
private
|
|
41
72
|
|
|
73
|
+
def discounted_amount
|
|
74
|
+
line_item&.discounted_amount_for(quantity) || 0
|
|
75
|
+
end
|
|
76
|
+
|
|
42
77
|
def set_variant_from_line_item
|
|
43
78
|
self.variant ||= line_item&.variant
|
|
44
79
|
end
|
|
@@ -58,7 +58,6 @@ module Spree
|
|
|
58
58
|
#
|
|
59
59
|
# Associations
|
|
60
60
|
#
|
|
61
|
-
belongs_to :store, class_name: 'Spree::Store'
|
|
62
61
|
|
|
63
62
|
has_many :product_collections, class_name: 'Spree::ProductCollection', dependent: :destroy_async, inverse_of: :collection
|
|
64
63
|
has_many :products, through: :product_collections
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module Spree
|
|
4
4
|
class CollectionRule < Spree.base_class
|
|
5
|
+
include Spree::TypeLabels
|
|
6
|
+
|
|
7
|
+
self.type_labels_scope = 'spree.collection_rule_types'
|
|
8
|
+
|
|
5
9
|
has_prefix_id :crule
|
|
6
10
|
|
|
7
11
|
MATCH_POLICIES = %w[is_equal_to is_not_equal_to contains does_not_contain].freeze
|
|
@@ -18,25 +22,6 @@ module Spree
|
|
|
18
22
|
|
|
19
23
|
validate :type_must_be_registered
|
|
20
24
|
|
|
21
|
-
# @return [String] localized display name for the rule kind, used by admin pickers
|
|
22
|
-
def self.human_name
|
|
23
|
-
Spree.t("collection_rule_types.#{api_type}.name", default: api_type.titleize)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# @return [String] localized description for the rule kind
|
|
27
|
-
def self.human_description
|
|
28
|
-
Spree.t("collection_rule_types.#{api_type}.description", default: '')
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Feeds the `description` field of `subclasses_with_preference_schema`
|
|
32
|
-
# (the `/types` discovery payload), which only reads `.description`.
|
|
33
|
-
def self.description
|
|
34
|
-
human_description
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def human_name = self.class.human_name
|
|
38
|
-
def human_description = self.class.human_description
|
|
39
|
-
|
|
40
25
|
registers_subclasses_via { Rails.application.config.spree.collection_rules }
|
|
41
26
|
|
|
42
27
|
private
|
|
@@ -47,8 +32,7 @@ module Spree
|
|
|
47
32
|
return if type.blank?
|
|
48
33
|
return if Rails.application.config.spree.collection_rules.any? { |rule| rule.to_s == type }
|
|
49
34
|
|
|
50
|
-
errors.add(:type, :invalid_collection_rule, message:
|
|
51
|
-
default: 'is not a registered collection rule'))
|
|
35
|
+
errors.add(:type, :invalid_collection_rule, message: I18n.t('spree.errors.messages.invalid_collection_rule'))
|
|
52
36
|
end
|
|
53
37
|
|
|
54
38
|
def regenerate_collection_products
|
|
@@ -81,7 +81,7 @@ module Spree
|
|
|
81
81
|
def exactly_one_subject
|
|
82
82
|
return if [line_item_id, fulfillment_id].compact.one?
|
|
83
83
|
|
|
84
|
-
errors.add(:base, :exactly_one_of_line_item_or_fulfillment, message:
|
|
84
|
+
errors.add(:base, :exactly_one_of_line_item_or_fulfillment, message: I18n.t('spree.errors.messages.exactly_one_of_line_item_or_fulfillment'))
|
|
85
85
|
end
|
|
86
86
|
end
|
|
87
87
|
end
|
|
@@ -43,7 +43,6 @@ module Spree
|
|
|
43
43
|
#
|
|
44
44
|
# Associations
|
|
45
45
|
#
|
|
46
|
-
belongs_to :store, class_name: 'Spree::Store'
|
|
47
46
|
# Every amount this rate states, one row per currency: what a flat fee
|
|
48
47
|
# charges, and the floor and cap a percentage charges within. A flat rate
|
|
49
48
|
# with no amount for the sale's currency does not apply to it (see
|
|
@@ -357,14 +356,14 @@ module Spree
|
|
|
357
356
|
def flat_fee_does_not_charge_delivery
|
|
358
357
|
return unless fixed? && include_shipping?
|
|
359
358
|
|
|
360
|
-
errors.add(:include_shipping, :flat_fee_cannot_charge_delivery, message:
|
|
359
|
+
errors.add(:include_shipping, :flat_fee_cannot_charge_delivery, message: I18n.t('spree.errors.messages.flat_fee_cannot_charge_delivery'))
|
|
361
360
|
end
|
|
362
361
|
|
|
363
362
|
def fixed_rate_states_an_amount
|
|
364
363
|
return unless fixed?
|
|
365
364
|
return if @pending_amounts.present? || commission_rate_values.any?
|
|
366
365
|
|
|
367
|
-
errors.add(:base, :commission_rate_needs_an_amount, message:
|
|
366
|
+
errors.add(:base, :commission_rate_needs_an_amount, message: I18n.t('spree.errors.messages.commission_rate_needs_an_amount'))
|
|
368
367
|
end
|
|
369
368
|
end
|
|
370
369
|
end
|
|
@@ -41,7 +41,7 @@ module Spree
|
|
|
41
41
|
return if max_amount.nil? || min_amount.nil?
|
|
42
42
|
return if max_amount >= min_amount
|
|
43
43
|
|
|
44
|
-
errors.add(:max_amount, :must_be_greater_than_min_amount, message:
|
|
44
|
+
errors.add(:max_amount, :must_be_greater_than_min_amount, message: I18n.t('spree.errors.messages.must_be_greater_than_min_amount'))
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
end
|
|
@@ -15,6 +15,9 @@ module Spree
|
|
|
15
15
|
# setting. A rate with no rules charges every sale.
|
|
16
16
|
class CommissionRule < Spree.base_class
|
|
17
17
|
include Spree::PreferenceSchema
|
|
18
|
+
include Spree::TypeLabels
|
|
19
|
+
|
|
20
|
+
self.type_labels_scope = 'spree.commission_rule_types'
|
|
18
21
|
|
|
19
22
|
has_prefix_id :comrule
|
|
20
23
|
|
|
@@ -47,16 +50,6 @@ module Spree
|
|
|
47
50
|
|
|
48
51
|
registers_subclasses_via { Spree.commission_rules }
|
|
49
52
|
|
|
50
|
-
# @return [String] the name an operator picks this rule kind by
|
|
51
|
-
def self.human_name
|
|
52
|
-
Spree.t("commission_rule_types.#{api_type}.name", default: name.demodulize.titleize)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# @return [String] what the rule does, shown beside the name in the picker
|
|
56
|
-
def self.description
|
|
57
|
-
Spree.t("commission_rule_types.#{api_type}.description", default: '')
|
|
58
|
-
end
|
|
59
|
-
|
|
60
53
|
# Whether this rule admits the sale.
|
|
61
54
|
#
|
|
62
55
|
# @param context [Spree::Commissions::Context]
|
|
@@ -71,7 +64,7 @@ module Spree
|
|
|
71
64
|
return if type.blank?
|
|
72
65
|
return if Spree.commission_rules.any? { |rule| rule.to_s == type }
|
|
73
66
|
|
|
74
|
-
errors.add(:type, :invalid_commission_rule, message:
|
|
67
|
+
errors.add(:type, :invalid_commission_rule, message: I18n.t('spree.errors.messages.invalid_commission_rule'))
|
|
75
68
|
end
|
|
76
69
|
end
|
|
77
70
|
end
|
|
@@ -48,7 +48,7 @@ module Spree
|
|
|
48
48
|
|
|
49
49
|
return if store.products.where(id: chosen_ids).count == chosen_ids.uniq.size
|
|
50
50
|
|
|
51
|
-
errors.add(:products, :product_not_in_store, message:
|
|
51
|
+
errors.add(:products, :product_not_in_store, message: I18n.t('spree.errors.messages.product_not_in_store'))
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
end
|
|
@@ -42,7 +42,6 @@ module Spree
|
|
|
42
42
|
SOURCES = [CHECKOUT, REGISTRATION, ACCOUNT, ADMIN, NEWSLETTER, ANONYMIZATION,
|
|
43
43
|
UNKNOWN, 'import', 'storefront'].freeze
|
|
44
44
|
|
|
45
|
-
belongs_to :store, class_name: 'Spree::Store'
|
|
46
45
|
belongs_to :owner, polymorphic: true
|
|
47
46
|
|
|
48
47
|
validates :purpose, presence: true
|
|
@@ -158,7 +158,7 @@ module Spree
|
|
|
158
158
|
# Show the card brand, eg. "VISA", "MASTERCARD", etc.
|
|
159
159
|
# @return [String]
|
|
160
160
|
def display_brand
|
|
161
|
-
brand.present? ? brand.upcase :
|
|
161
|
+
brand.present? ? brand.upcase : I18n.t('spree.no_cc_type')
|
|
162
162
|
end
|
|
163
163
|
|
|
164
164
|
# Returns the first name of the cardholder.
|
data/app/models/spree/current.rb
CHANGED
|
@@ -38,6 +38,29 @@ module Spree
|
|
|
38
38
|
super || Spree::Store.default
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
+
# Runs the block in +store+ from a clean context: nothing a previous store
|
|
42
|
+
# resolved (channel, market, currency, integrations, pricing) carries in,
|
|
43
|
+
# and nothing resolved inside leaks out. For work that walks several
|
|
44
|
+
# stores in one unit of work, such as an installation-wide sweep job; a
|
|
45
|
+
# request or a single-store job assigns #store once instead.
|
|
46
|
+
#
|
|
47
|
+
# The store scope guard stays armed afterwards, like any other store
|
|
48
|
+
# declaration in this unit of work.
|
|
49
|
+
#
|
|
50
|
+
# @param store [Spree::Store]
|
|
51
|
+
# @return [Object] the block's result
|
|
52
|
+
def with_store(store)
|
|
53
|
+
previous = attributes
|
|
54
|
+
|
|
55
|
+
begin
|
|
56
|
+
self.attributes = {}
|
|
57
|
+
self.store = store
|
|
58
|
+
yield
|
|
59
|
+
ensure
|
|
60
|
+
self.attributes = previous.merge(store_scope_guard_armed: store_scope_guard_armed)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
41
64
|
def channel
|
|
42
65
|
super || (self.channel = store&.default_channel)
|
|
43
66
|
end
|
|
@@ -128,7 +128,7 @@ module Spree
|
|
|
128
128
|
|
|
129
129
|
unless type == custom_field_definition.field_type_class_name
|
|
130
130
|
errors.add(:type, :custom_field_definition_mismatch,
|
|
131
|
-
message:
|
|
131
|
+
message: I18n.t('spree.errors.messages.custom_field_definition_mismatch'))
|
|
132
132
|
end
|
|
133
133
|
end
|
|
134
134
|
|
|
@@ -144,7 +144,7 @@ module Spree
|
|
|
144
144
|
return if definition_type.safe_constantize&.base_class&.name == resource_type
|
|
145
145
|
|
|
146
146
|
errors.add(:resource_type, :custom_field_definition_mismatch,
|
|
147
|
-
message:
|
|
147
|
+
message: I18n.t('spree.errors.messages.custom_field_definition_mismatch'))
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
# Definitions are store-owned, so a record may only carry its own store's.
|
|
@@ -39,6 +39,10 @@ module Spree
|
|
|
39
39
|
#
|
|
40
40
|
# Callbacks
|
|
41
41
|
#
|
|
42
|
+
# The API names resources by shorthand (`product`); the column keeps the
|
|
43
|
+
# class name the custom fields themselves are stored under. Also applies to
|
|
44
|
+
# `where(resource_type:)`, so finders accept either.
|
|
45
|
+
normalizes :resource_type, with: ->(value) { Spree::Base.polymorphic_type_for(value, available_resources) || value }
|
|
42
46
|
normalizes :key, with: ->(value) { value.to_s.parameterize.underscore.strip }
|
|
43
47
|
normalizes :namespace, with: ->(value) { value.to_s.parameterize.underscore.strip }
|
|
44
48
|
before_validation :set_default_type, if: -> { self[:field_type].blank? }, on: :create
|
|
@@ -117,25 +121,13 @@ module Spree
|
|
|
117
121
|
# as the API names it, so a client renders a picker rather than carrying
|
|
118
122
|
# its own list that drifts from the registry.
|
|
119
123
|
#
|
|
120
|
-
#
|
|
121
|
-
# definitions are stored under the old class name, and offering the new
|
|
122
|
-
# one would file a merchant's next definition somewhere the category card
|
|
123
|
-
# does not read. Drops with the alias in 6.1.
|
|
124
|
-
#
|
|
125
|
-
# @return [Array<Hash{Symbol => String}>] `resource_type` + `name`
|
|
124
|
+
# @return [Array<Hash{Symbol => String}>] `resource_type` shorthand + `name`
|
|
126
125
|
def self.enabled_resource_types
|
|
127
126
|
# Through `available_resources`, not the registry directly: that is the
|
|
128
127
|
# accessor the rest of the class reads, so discovery and validation
|
|
129
128
|
# cannot disagree about what a host app has made available.
|
|
130
|
-
Array(available_resources).
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
# The label follows the class a merchant knows; the wire value follows
|
|
134
|
-
# where the rows are actually stored.
|
|
135
|
-
name = resource.to_s.demodulize.titleize.pluralize
|
|
136
|
-
resource_type = resource.to_s == 'Spree::Category' ? 'Spree::Taxon' : resource.to_s
|
|
137
|
-
|
|
138
|
-
{ resource_type: resource_type, name: name }
|
|
129
|
+
Array(available_resources).compact.map do |resource|
|
|
130
|
+
{ resource_type: Spree::Base.polymorphic_api_type(resource), name: resource.to_s.demodulize.titleize.pluralize }
|
|
139
131
|
end.uniq { |entry| entry[:resource_type] }.sort_by { |entry| entry[:name] }
|
|
140
132
|
end
|
|
141
133
|
|
|
@@ -174,7 +166,7 @@ module Spree
|
|
|
174
166
|
|
|
175
167
|
tokens = Spree::CustomField::TYPE_TOKENS.keys.join(', ')
|
|
176
168
|
errors.add(:field_type, :unknown_custom_field_type, types: tokens,
|
|
177
|
-
message:
|
|
169
|
+
message: I18n.t('spree.errors.messages.unknown_custom_field_type', types: tokens))
|
|
178
170
|
end
|
|
179
171
|
|
|
180
172
|
# Validates the stored class name, not the token the reader returns.
|
|
@@ -186,14 +178,8 @@ module Spree
|
|
|
186
178
|
errors.add(:field_type, :inclusion)
|
|
187
179
|
end
|
|
188
180
|
|
|
189
|
-
# Both the registry's own names and the ones discovery offers: a value a
|
|
190
|
-
# client was offered has to be accepted, and the two differ where a class
|
|
191
|
-
# has been renamed (categories are stored under Spree::Taxon while the
|
|
192
|
-
# registry holds Spree::Category). Existing callers name either, so
|
|
193
|
-
# narrowing to one would reject definitions that already work.
|
|
194
181
|
def valid_available_resources
|
|
195
|
-
self.class.available_resources.map(&:to_s)
|
|
196
|
-
self.class.enabled_resource_types.map { |resource| resource[:resource_type] }
|
|
182
|
+
self.class.available_resources.map(&:to_s)
|
|
197
183
|
end
|
|
198
184
|
|
|
199
185
|
def set_default_type
|
|
@@ -31,7 +31,7 @@ module Spree
|
|
|
31
31
|
JSON.parse(value)
|
|
32
32
|
rescue JSON::ParserError => e
|
|
33
33
|
errors.add(:value, :invalid_json, detail: e.message,
|
|
34
|
-
message:
|
|
34
|
+
message: I18n.t('spree.errors.messages.invalid_json', detail: e.message))
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
end
|
|
@@ -19,6 +19,7 @@ module Spree
|
|
|
19
19
|
has_spree_number prefix: 'DSR'
|
|
20
20
|
|
|
21
21
|
publishes_lifecycle_events
|
|
22
|
+
publishes_event :completed
|
|
22
23
|
|
|
23
24
|
include Spree::HasStatus
|
|
24
25
|
has_status :pending, :processing, :completed, :failed, default: :pending
|
|
@@ -37,7 +38,6 @@ module Spree
|
|
|
37
38
|
# asked, and it stops working when the request expires.
|
|
38
39
|
has_secure_token :download_token
|
|
39
40
|
|
|
40
|
-
belongs_to :store, class_name: 'Spree::Store'
|
|
41
41
|
belongs_to :customer, class_name: Spree.customer_class.to_s
|
|
42
42
|
# Null when the subject asked for it themselves; set when staff acted on a
|
|
43
43
|
# request that arrived by email.
|
|
@@ -80,6 +80,12 @@ module Spree
|
|
|
80
80
|
after_save :apply_pending_services, if: :pending_services?
|
|
81
81
|
attribute :fulfillment_provider, :string, default: 'Spree::FulfillmentProvider::Manual'
|
|
82
82
|
|
|
83
|
+
# The API names providers by their shorthand (`manual`, `easy_post`); the
|
|
84
|
+
# columns keep the class name.
|
|
85
|
+
normalizes :fulfillment_provider, with: ->(value) { Spree::ApiTyped.class_name_for(Spree.fulfillment_providers, value) }
|
|
86
|
+
normalizes :rate_provider, with: ->(value) { Spree::ApiTyped.class_name_for(Spree.delivery_rate_providers, value) }
|
|
87
|
+
normalizes :pickup_point_provider, with: ->(value) { Spree::ApiTyped.class_name_for(Spree.pickup_point_providers, value) }
|
|
88
|
+
|
|
83
89
|
# Methods whose fulfillment provider satisfies the predicate — behavior
|
|
84
90
|
# queries route through provider classes, never string vocabularies.
|
|
85
91
|
scope :with_provider, ->(predicate) {
|
|
@@ -138,6 +144,16 @@ module Spree
|
|
|
138
144
|
# not save a provider whose integration isn't connected — that breaks
|
|
139
145
|
# quoting at checkout, not at save time where the admin can see it.
|
|
140
146
|
validate :rate_provider_must_be_available, if: :rate_provider_changed?
|
|
147
|
+
# Every provider column is constantized and instantiated at checkout or
|
|
148
|
+
# ship time, so only a registered class may be stored.
|
|
149
|
+
validates :fulfillment_provider,
|
|
150
|
+
inclusion: { in: -> (_record) { Spree.fulfillment_providers.map(&:to_s) } },
|
|
151
|
+
allow_blank: true,
|
|
152
|
+
if: :fulfillment_provider_changed?
|
|
153
|
+
validates :pickup_point_provider,
|
|
154
|
+
inclusion: { in: -> (_record) { Spree.pickup_point_providers.map(&:to_s) } },
|
|
155
|
+
allow_blank: true,
|
|
156
|
+
if: :pickup_point_provider_changed?
|
|
141
157
|
# Providers declare the fulfillment types they handle; a mismatch would
|
|
142
158
|
# only surface at checkout (no rates) or at ship time (no dispatch),
|
|
143
159
|
# so reject it where the admin can still see why.
|
|
@@ -234,7 +250,7 @@ module Spree
|
|
|
234
250
|
return if delivery_zone.delivery_origin_group_id == delivery_origin_group_id
|
|
235
251
|
|
|
236
252
|
errors.add(:delivery_zone, :does_not_belong_to_origin_group,
|
|
237
|
-
message:
|
|
253
|
+
message: I18n.t('spree.errors.messages.delivery_zone_not_in_origin_group'))
|
|
238
254
|
end
|
|
239
255
|
|
|
240
256
|
def pickup_point?
|
|
@@ -263,7 +279,7 @@ module Spree
|
|
|
263
279
|
#
|
|
264
280
|
# @return [Class]
|
|
265
281
|
def provider_class
|
|
266
|
-
(fulfillment_provider.presence || DEFAULT_FULFILLMENT_PROVIDER)
|
|
282
|
+
Spree::ApiTyped.registered_class(Spree.fulfillment_providers, fulfillment_provider.presence || DEFAULT_FULFILLMENT_PROVIDER) ||
|
|
267
283
|
DEFAULT_FULFILLMENT_PROVIDER.constantize
|
|
268
284
|
end
|
|
269
285
|
|
|
@@ -286,7 +302,8 @@ module Spree
|
|
|
286
302
|
#
|
|
287
303
|
# @return [Class]
|
|
288
304
|
def rate_provider_class
|
|
289
|
-
(rate_provider.presence || DEFAULT_RATE_PROVIDER)
|
|
305
|
+
Spree::ApiTyped.registered_class(Spree.delivery_rate_providers, rate_provider.presence || DEFAULT_RATE_PROVIDER) ||
|
|
306
|
+
DEFAULT_RATE_PROVIDER.constantize
|
|
290
307
|
end
|
|
291
308
|
|
|
292
309
|
|
|
@@ -363,7 +380,7 @@ module Spree
|
|
|
363
380
|
#
|
|
364
381
|
# @return [Spree::PickupPointProvider::Base, nil]
|
|
365
382
|
def pickup_point_provider_instance
|
|
366
|
-
@pickup_point_provider_instance ||= pickup_point_provider
|
|
383
|
+
@pickup_point_provider_instance ||= Spree::ApiTyped.registered_class(Spree.pickup_point_providers, pickup_point_provider)&.new
|
|
367
384
|
end
|
|
368
385
|
|
|
369
386
|
def self.calculators
|
|
@@ -430,14 +447,14 @@ module Spree
|
|
|
430
447
|
|
|
431
448
|
if calculator.is_a?(Spree::Calculator::Shipping::FlatRate)
|
|
432
449
|
if calculator.preferred_amount == 0
|
|
433
|
-
|
|
450
|
+
I18n.t('spree.free')
|
|
434
451
|
else
|
|
435
452
|
Spree::Money.new(calculator.preferred_amount, { currency: calculator.preferred_currency }).to_s
|
|
436
453
|
end
|
|
437
454
|
elsif calculator.is_a?(Spree::Calculator::Shipping::FlexiRate)
|
|
438
455
|
Spree::Money.new(calculator.preferred_first_item, { currency: calculator.preferred_currency }).to_s
|
|
439
456
|
elsif calculator.is_a?(Spree::Calculator::Shipping::FlatPercentItemTotal)
|
|
440
|
-
|
|
457
|
+
ActiveSupport::NumberHelper.number_to_percentage(calculator.preferred_flat_percent, precision: 2)
|
|
441
458
|
else
|
|
442
459
|
''
|
|
443
460
|
end
|
|
@@ -500,7 +517,7 @@ module Spree
|
|
|
500
517
|
return if delivery_zone.delivery_profile_id == delivery_profile_id
|
|
501
518
|
|
|
502
519
|
errors.add(:delivery_zone, :does_not_belong_to_profile,
|
|
503
|
-
message:
|
|
520
|
+
message: I18n.t('spree.errors.messages.delivery_zone_not_in_profile'))
|
|
504
521
|
end
|
|
505
522
|
|
|
506
523
|
def profile_must_accept_provider
|
|
@@ -513,7 +530,7 @@ module Spree
|
|
|
513
530
|
errors.add(
|
|
514
531
|
:fulfillment_provider, :profile_does_not_accept_provider,
|
|
515
532
|
provider: provider_class.provider_name, profile: delivery_profile.name,
|
|
516
|
-
message:
|
|
533
|
+
message: I18n.t('spree.errors.messages.profile_does_not_accept_provider',
|
|
517
534
|
provider: provider_class.provider_name, profile: delivery_profile.name)
|
|
518
535
|
)
|
|
519
536
|
end
|
|
@@ -527,7 +544,7 @@ module Spree
|
|
|
527
544
|
errors.add(
|
|
528
545
|
:rate_provider, :rate_provider_requires_shipping,
|
|
529
546
|
provider: rate_provider_class.provider_name,
|
|
530
|
-
message:
|
|
547
|
+
message: I18n.t('spree.errors.messages.rate_provider_requires_shipping',
|
|
531
548
|
provider: rate_provider_class.provider_name)
|
|
532
549
|
)
|
|
533
550
|
end
|
|
@@ -537,7 +554,7 @@ module Spree
|
|
|
537
554
|
return unless Spree.delivery_rate_providers.map(&:to_s).include?(rate_provider)
|
|
538
555
|
return if rate_provider_class.available_for_store?(store)
|
|
539
556
|
|
|
540
|
-
errors.add(:rate_provider, :rate_provider_unavailable, message:
|
|
557
|
+
errors.add(:rate_provider, :rate_provider_unavailable, message: I18n.t('spree.errors.messages.rate_provider_unavailable'))
|
|
541
558
|
end
|
|
542
559
|
|
|
543
560
|
def seller_must_belong_to_store
|
|
@@ -549,18 +566,18 @@ module Spree
|
|
|
549
566
|
|
|
550
567
|
def seller_methods_use_own_providers
|
|
551
568
|
unless rate_provider.blank? || rate_provider == DEFAULT_RATE_PROVIDER
|
|
552
|
-
errors.add(:rate_provider, :seller_delivery_method_provider, message:
|
|
569
|
+
errors.add(:rate_provider, :seller_delivery_method_provider, message: I18n.t('spree.errors.messages.seller_delivery_method_provider'))
|
|
553
570
|
end
|
|
554
571
|
|
|
555
572
|
return if fulfillment_provider.blank? || fulfillment_provider == DEFAULT_FULFILLMENT_PROVIDER
|
|
556
573
|
|
|
557
|
-
errors.add(:fulfillment_provider, :seller_delivery_method_provider, message:
|
|
574
|
+
errors.add(:fulfillment_provider, :seller_delivery_method_provider, message: I18n.t('spree.errors.messages.seller_delivery_method_provider'))
|
|
558
575
|
end
|
|
559
576
|
|
|
560
577
|
def only_marketplace_methods_are_shared
|
|
561
578
|
return unless available_to_sellers? && seller_owned?
|
|
562
579
|
|
|
563
|
-
errors.add(:available_to_sellers, :seller_delivery_method_not_shareable, message:
|
|
580
|
+
errors.add(:available_to_sellers, :seller_delivery_method_not_shareable, message: I18n.t('spree.errors.messages.seller_delivery_method_not_shareable'))
|
|
564
581
|
end
|
|
565
582
|
end
|
|
566
583
|
end
|
|
@@ -7,6 +7,9 @@ module Spree
|
|
|
7
7
|
# See docs/plans/6.0-delivery-method-rules.md.
|
|
8
8
|
class DeliveryMethodRule < Spree.base_class
|
|
9
9
|
include Spree::PreferenceSchema
|
|
10
|
+
include Spree::TypeLabels
|
|
11
|
+
|
|
12
|
+
self.type_labels_scope = 'spree.delivery_method_rule_types'
|
|
10
13
|
|
|
11
14
|
has_prefix_id :dmrule
|
|
12
15
|
|
|
@@ -27,16 +30,6 @@ module Spree
|
|
|
27
30
|
|
|
28
31
|
registers_subclasses_via { Spree.delivery_method_rules }
|
|
29
32
|
|
|
30
|
-
# @return [String] localized display name for the rule kind, used by admin pickers
|
|
31
|
-
def self.human_name
|
|
32
|
-
Spree.t("delivery_method_rule_types.#{api_type}.name", default: api_type.titleize)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# @return [String] localized description for the rule kind
|
|
36
|
-
def self.human_description
|
|
37
|
-
Spree.t("delivery_method_rule_types.#{api_type}.description", default: '')
|
|
38
|
-
end
|
|
39
|
-
|
|
40
33
|
# @param package [Spree::Stock::Package]
|
|
41
34
|
# @return [Boolean]
|
|
42
35
|
def eligible?(_package)
|
|
@@ -49,7 +42,7 @@ module Spree
|
|
|
49
42
|
return if type.blank?
|
|
50
43
|
return if Spree.delivery_method_rules.any? { |rule| rule.to_s == type }
|
|
51
44
|
|
|
52
|
-
errors.add(:type, :invalid_delivery_method_rule, message:
|
|
45
|
+
errors.add(:type, :invalid_delivery_method_rule, message: I18n.t('spree.errors.messages.invalid_delivery_method_rule'))
|
|
53
46
|
end
|
|
54
47
|
end
|
|
55
48
|
end
|
|
@@ -40,9 +40,8 @@ module Spree
|
|
|
40
40
|
|
|
41
41
|
return price if tax_rate.nil? || tax_amount.zero? || !tax_rate.show_rate_in_label
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
tax_rate.included_in_price? ? :including_tax : :excluding_tax,
|
|
45
|
-
scope: 'shipping_rates.display_price',
|
|
43
|
+
I18n.t(
|
|
44
|
+
"spree.shipping_rates.display_price.#{tax_rate.included_in_price? ? :including_tax : :excluding_tax}",
|
|
46
45
|
price: price,
|
|
47
46
|
tax_amount: display_tax_amount,
|
|
48
47
|
tax_rate_name: tax_rate.name
|
|
@@ -147,14 +146,14 @@ module Spree
|
|
|
147
146
|
def display_delivery_range
|
|
148
147
|
return unless delivery_range
|
|
149
148
|
|
|
150
|
-
|
|
149
|
+
I18n.t('spree.display_delivery_range', delivery_range: delivery_range)
|
|
151
150
|
end
|
|
152
151
|
|
|
153
152
|
private
|
|
154
153
|
|
|
155
154
|
# What every money display on this rate reads instead of an amount.
|
|
156
155
|
def quoted_after_review
|
|
157
|
-
|
|
156
|
+
I18n.t('spree.delivery_rates.quoted_after_review')
|
|
158
157
|
end
|
|
159
158
|
|
|
160
159
|
def discount_amount
|
|
@@ -8,7 +8,6 @@ module Spree
|
|
|
8
8
|
# 2026-03-16 "Consolidate metadata") — write-only developer escape hatch.
|
|
9
9
|
attribute :metadata, default: -> { {} }
|
|
10
10
|
|
|
11
|
-
belongs_to :store, class_name: 'Spree::Store'
|
|
12
11
|
# Zones are destination sets owned by a delivery profile; within it they
|
|
13
12
|
# hang off an origin group, so the same profile can quote different
|
|
14
13
|
# tables per warehouse. The profile's methods bind to at most one zone.
|
|
@@ -78,21 +78,21 @@ module Spree
|
|
|
78
78
|
|
|
79
79
|
def postal_definition
|
|
80
80
|
if postal_code_prefix.present?
|
|
81
|
-
errors.add(:postal_code_prefix, :delivery_zone_prefix_and_range_exclusive, message:
|
|
81
|
+
errors.add(:postal_code_prefix, :delivery_zone_prefix_and_range_exclusive, message: I18n.t('spree.errors.messages.delivery_zone_prefix_and_range_exclusive')) if postal_range?
|
|
82
82
|
return
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
if postal_code_from.blank? || postal_code_to.blank?
|
|
86
|
-
errors.add(:base, :delivery_zone_postal_definition_required, message:
|
|
86
|
+
errors.add(:base, :delivery_zone_postal_definition_required, message: I18n.t('spree.errors.messages.delivery_zone_postal_definition_required'))
|
|
87
87
|
return
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
unless country_code.present? && range_capable_country_codes.include?(country_code)
|
|
91
|
-
errors.add(:base, :delivery_zone_range_not_supported, message:
|
|
91
|
+
errors.add(:base, :delivery_zone_range_not_supported, message: I18n.t('spree.errors.messages.delivery_zone_range_not_supported'))
|
|
92
92
|
return
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
errors.add(:postal_code_to, :delivery_zone_range_inverted, message:
|
|
95
|
+
errors.add(:postal_code_to, :delivery_zone_range_inverted, message: I18n.t('spree.errors.messages.delivery_zone_range_inverted')) if postal_code_to < postal_code_from
|
|
96
96
|
end
|
|
97
97
|
end
|
|
98
98
|
end
|