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
|
@@ -10,40 +10,19 @@ module Spree
|
|
|
10
10
|
|
|
11
11
|
attr_reader :payment, :order
|
|
12
12
|
delegate :currency, to: :payment
|
|
13
|
-
delegate :email, to: :order
|
|
14
|
-
|
|
15
|
-
def statement_descriptor_suffix
|
|
16
|
-
order.number
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def customer
|
|
20
|
-
order.email
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def customer_id
|
|
24
|
-
order.customer_id
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def ip
|
|
28
|
-
order.last_ip_address
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# The payment number already names its order (`R1001-P1`), so this is
|
|
32
|
-
# the payment number alone rather than the two concatenated.
|
|
33
|
-
def order_id
|
|
34
|
-
payment.number
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def payment_id
|
|
38
|
-
payment.number
|
|
39
|
-
end
|
|
40
|
-
|
|
13
|
+
delegate :email, :customer_id, to: :order
|
|
41
14
|
# Stable handle for a gateway to find its own payment back. The derived
|
|
42
15
|
# number cannot be queried (its column is NULL on 6.0 rows) and shifts
|
|
43
16
|
# if an earlier sibling is destroyed — nothing durable may key on it.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
17
|
+
delegate :prefixed_id, to: :payment, prefix: true
|
|
18
|
+
|
|
19
|
+
def statement_descriptor_suffix = order.number
|
|
20
|
+
def customer = order.email
|
|
21
|
+
def ip = order.last_ip_address
|
|
22
|
+
# The payment number already names its order (`R1001-P1`), so this is
|
|
23
|
+
# the payment number alone rather than the two concatenated.
|
|
24
|
+
def order_id = payment.number
|
|
25
|
+
def payment_id = payment.number
|
|
47
26
|
|
|
48
27
|
# Built on the prefixed ID, not the number: a derived number shifts if
|
|
49
28
|
# an earlier sibling payment is destroyed, and a shifted idempotency
|
|
@@ -53,7 +32,7 @@ module Spree
|
|
|
53
32
|
end
|
|
54
33
|
|
|
55
34
|
def shipping
|
|
56
|
-
order.
|
|
35
|
+
order.delivery_total * exchange_multiplier
|
|
57
36
|
end
|
|
58
37
|
|
|
59
38
|
def tax
|
|
@@ -77,29 +56,12 @@ module Spree
|
|
|
77
56
|
end
|
|
78
57
|
|
|
79
58
|
def hash_methods
|
|
80
|
-
[
|
|
81
|
-
|
|
82
|
-
:customer,
|
|
83
|
-
:customer_id,
|
|
84
|
-
:ip,
|
|
85
|
-
:order_id,
|
|
86
|
-
:payment_id,
|
|
87
|
-
:payment_prefixed_id,
|
|
88
|
-
:idempotency_key,
|
|
89
|
-
:shipping,
|
|
90
|
-
:tax,
|
|
91
|
-
:subtotal,
|
|
92
|
-
:discount,
|
|
93
|
-
:currency,
|
|
94
|
-
:billing_address,
|
|
95
|
-
:shipping_address
|
|
96
|
-
]
|
|
59
|
+
%i[email customer customer_id ip order_id payment_id payment_prefixed_id idempotency_key shipping tax
|
|
60
|
+
subtotal discount currency billing_address shipping_address]
|
|
97
61
|
end
|
|
98
62
|
|
|
99
63
|
def to_hash
|
|
100
|
-
|
|
101
|
-
[method, send(method)]
|
|
102
|
-
end]
|
|
64
|
+
hash_methods.index_with { |method| send(method) }
|
|
103
65
|
end
|
|
104
66
|
|
|
105
67
|
private
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require_dependency 'spree/payment/gateway_options'
|
|
2
|
-
|
|
3
1
|
module Spree
|
|
4
2
|
class Payment < Spree.base_class
|
|
5
3
|
# Gateway mechanics shared by the payments workflows and the payment
|
|
@@ -144,11 +142,11 @@ module Spree
|
|
|
144
142
|
text = if error.is_a? Spree::PaymentResponse
|
|
145
143
|
error.params['message'] || error.params['response_reason_text'] || error.message
|
|
146
144
|
elsif error.is_a? Spree::PaymentConnectionError
|
|
147
|
-
|
|
145
|
+
I18n.t('spree.unable_to_connect_to_gateway')
|
|
148
146
|
else
|
|
149
147
|
error.to_s
|
|
150
148
|
end
|
|
151
|
-
Rails.logger.error(
|
|
149
|
+
Rails.logger.error(I18n.t('spree.gateway_error'))
|
|
152
150
|
Rails.logger.error(" #{error.to_yaml}")
|
|
153
151
|
raise Core::GatewayError, text
|
|
154
152
|
end
|
data/app/models/spree/payment.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require_dependency 'spree/payment/processing'
|
|
2
|
-
|
|
3
1
|
module Spree
|
|
4
2
|
class Payment < Spree.base_class
|
|
5
3
|
has_prefix_id :py # Stripe: py_
|
|
@@ -18,6 +16,7 @@ module Spree
|
|
|
18
16
|
include Spree::Payment::CustomEvents
|
|
19
17
|
|
|
20
18
|
publishes_lifecycle_events
|
|
19
|
+
publishes_events :captured, :completed, :paid, :refunded, :voided
|
|
21
20
|
|
|
22
21
|
NON_RISKY_AVS_CODES = ['B', 'D', 'H', 'J', 'M', 'Q', 'T', 'V', 'X', 'Y'].freeze
|
|
23
22
|
RISKY_AVS_CODES = ['A', 'C', 'E', 'F', 'G', 'I', 'K', 'L', 'N', 'O', 'P', 'R', 'S', 'U', 'W', 'Z'].freeze
|
|
@@ -244,6 +243,9 @@ module Spree
|
|
|
244
243
|
return amount if owner.nil?
|
|
245
244
|
|
|
246
245
|
amount_from_order = owner.total - owner.payment_total
|
|
246
|
+
# A refund for returned goods settled what was owed for them; without
|
|
247
|
+
# this the order would accept a fresh charge for goods it took back.
|
|
248
|
+
amount_from_order -= owner.returned_items_refund_total if owner.respond_to?(:returned_items_refund_total)
|
|
247
249
|
|
|
248
250
|
if payment_method&.store_credit?
|
|
249
251
|
store_credits = owner.available_store_credits
|
|
@@ -263,6 +265,19 @@ module Spree
|
|
|
263
265
|
end || amount
|
|
264
266
|
end
|
|
265
267
|
|
|
268
|
+
# Resizes a store credit payment that has not been taken yet. Completion
|
|
269
|
+
# takes it against the eligibility event recorded for its amount, so the
|
|
270
|
+
# new amount needs one of its own.
|
|
271
|
+
#
|
|
272
|
+
# @param new_amount [BigDecimal]
|
|
273
|
+
# @return [void]
|
|
274
|
+
def update_store_credit_amount!(new_amount)
|
|
275
|
+
return if amount == new_amount
|
|
276
|
+
|
|
277
|
+
update_column(:amount, new_amount)
|
|
278
|
+
create_eligible_credit_event
|
|
279
|
+
end
|
|
280
|
+
|
|
266
281
|
def offsets_total
|
|
267
282
|
offsets.sum(:amount)
|
|
268
283
|
end
|
|
@@ -502,7 +517,7 @@ module Spree
|
|
|
502
517
|
end
|
|
503
518
|
|
|
504
519
|
def exactly_one_owner
|
|
505
|
-
errors.add(:base, :exactly_one_of_cart_or_order, message:
|
|
520
|
+
errors.add(:base, :exactly_one_of_cart_or_order, message: I18n.t('spree.errors.messages.exactly_one_of_cart_or_order')) unless [order, cart, order_group].compact.one?
|
|
506
521
|
end
|
|
507
522
|
|
|
508
523
|
def set_amount
|
|
@@ -532,8 +547,8 @@ module Spree
|
|
|
532
547
|
end
|
|
533
548
|
|
|
534
549
|
def add_source_error(field, message)
|
|
535
|
-
field_name =
|
|
536
|
-
errors.add(
|
|
550
|
+
field_name = source.class.human_attribute_name(field)
|
|
551
|
+
errors.add(source.class.model_name.human, "#{field_name} #{message}")
|
|
537
552
|
end
|
|
538
553
|
|
|
539
554
|
|
|
@@ -22,7 +22,7 @@ module Spree
|
|
|
22
22
|
|
|
23
23
|
def authorize(amount_in_cents, store_credit, gateway_options = {})
|
|
24
24
|
if store_credit.nil?
|
|
25
|
-
Spree::PaymentResponse.new(false,
|
|
25
|
+
Spree::PaymentResponse.new(false, I18n.t('spree.store_credit_payment_method.unable_to_find'), {}, {})
|
|
26
26
|
else
|
|
27
27
|
action = lambda do |store_credit|
|
|
28
28
|
store_credit.authorize(
|
|
@@ -58,7 +58,7 @@ module Spree
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
if event.blank?
|
|
61
|
-
Spree::PaymentResponse.new(false,
|
|
61
|
+
Spree::PaymentResponse.new(false, I18n.t('spree.store_credit_payment_method.unable_to_find'), {}, {})
|
|
62
62
|
else
|
|
63
63
|
capture(amount_in_cents, event.authorization_code, gateway_options)
|
|
64
64
|
end
|
|
@@ -115,7 +115,7 @@ module Spree
|
|
|
115
115
|
# note that we only need to return the auth code on an 'auth', but it's innocuous to always return
|
|
116
116
|
Spree::PaymentResponse.new(
|
|
117
117
|
true,
|
|
118
|
-
|
|
118
|
+
I18n.t('spree.store_credit_payment_method.successful_action', action: action_name),
|
|
119
119
|
{},
|
|
120
120
|
authorization: auth_code || response
|
|
121
121
|
)
|
|
@@ -132,7 +132,7 @@ module Spree
|
|
|
132
132
|
if store_credit.nil?
|
|
133
133
|
Spree::PaymentResponse.new(
|
|
134
134
|
false,
|
|
135
|
-
|
|
135
|
+
I18n.t('spree.store_credit_payment_method.unable_to_find_for_action', auth_code: auth_code, action: action_name),
|
|
136
136
|
{},
|
|
137
137
|
{}
|
|
138
138
|
)
|
|
@@ -13,7 +13,9 @@ module Spree
|
|
|
13
13
|
include Spree::StorePreferences
|
|
14
14
|
include Spree::HasCustomFields
|
|
15
15
|
include Spree::Metadata
|
|
16
|
+
include Spree::SecretPreferences
|
|
16
17
|
include Spree::CaptureMethod
|
|
18
|
+
include Spree::ProviderListing
|
|
17
19
|
if defined?(Spree::Security::PaymentMethods)
|
|
18
20
|
include Spree::Security::PaymentMethods
|
|
19
21
|
end
|
|
@@ -57,7 +59,6 @@ module Spree
|
|
|
57
59
|
validates :storefront_visible, inclusion: { in: [true, false] }
|
|
58
60
|
normalizes :name, with: ->(value) { value&.to_s&.squish&.presence }
|
|
59
61
|
|
|
60
|
-
belongs_to :store, class_name: 'Spree::Store'
|
|
61
62
|
|
|
62
63
|
has_many :payments, class_name: 'Spree::Payment', inverse_of: :payment_method, dependent: :nullify
|
|
63
64
|
has_many :credit_cards, class_name: 'Spree::CreditCard', dependent: :destroy # CCs are soft deleted
|
|
@@ -74,6 +75,20 @@ module Spree
|
|
|
74
75
|
# `providers`; declaring it keeps subclass resolution to a single rule.
|
|
75
76
|
registers_subclasses_via { providers }
|
|
76
77
|
|
|
78
|
+
# Whether this method is backed by an external payment provider (Stripe,
|
|
79
|
+
# Adyen…) rather than handled by the store itself (check, store credit).
|
|
80
|
+
# Only third-party methods are listed under Settings → Integrations.
|
|
81
|
+
#
|
|
82
|
+
# @return [Boolean]
|
|
83
|
+
def self.third_party?
|
|
84
|
+
false
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# @return [Hash] the listing attributes, plus whether the method is third-party
|
|
88
|
+
def self.provider_listing
|
|
89
|
+
super.merge(third_party: third_party?)
|
|
90
|
+
end
|
|
91
|
+
|
|
77
92
|
def provider_class
|
|
78
93
|
raise ::NotImplementedError, 'You must implement provider_class method for this gateway.'
|
|
79
94
|
end
|
|
@@ -136,6 +151,25 @@ module Spree
|
|
|
136
151
|
raise ::NotImplementedError, 'You must implement complete_payment_session method for this gateway.'
|
|
137
152
|
end
|
|
138
153
|
|
|
154
|
+
# Cancels a session nobody is going to complete, so the provider can no
|
|
155
|
+
# longer take money against it. Called for the sessions left pending when
|
|
156
|
+
# an order is placed. The default leaves the session untouched: a
|
|
157
|
+
# gateway that cannot cancel at the provider must not report as canceled
|
|
158
|
+
# a session that can still be paid.
|
|
159
|
+
#
|
|
160
|
+
# Raise Spree::Core::GatewayError only for a refusal, such as a session
|
|
161
|
+
# that was already paid. A timeout, a rate limit, an outage, or rejected
|
|
162
|
+
# credentials is raised as itself. Callers that treat those as a refusal
|
|
163
|
+
# leave a session the buyer can still pay.
|
|
164
|
+
#
|
|
165
|
+
# @param payment_session [Spree::PaymentSession]
|
|
166
|
+
# @return [Boolean] whether the session was canceled
|
|
167
|
+
# @raise [Spree::Core::GatewayError] when the provider refuses, e.g. the
|
|
168
|
+
# session has already been paid
|
|
169
|
+
def cancel_payment_session(payment_session:)
|
|
170
|
+
false
|
|
171
|
+
end
|
|
172
|
+
|
|
139
173
|
# Parses an incoming webhook payload from the payment provider.
|
|
140
174
|
# Override in gateway subclasses to implement provider-specific webhook parsing.
|
|
141
175
|
#
|
|
@@ -284,9 +318,7 @@ module Spree
|
|
|
284
318
|
end
|
|
285
319
|
|
|
286
320
|
def public_preferences
|
|
287
|
-
public_preference_keys.
|
|
288
|
-
hash[key] = preferences[key]
|
|
289
|
-
end
|
|
321
|
+
public_preference_keys.index_with { |key| get_preference(key) }
|
|
290
322
|
end
|
|
291
323
|
|
|
292
324
|
# @deprecated Use {#storefront_visible?}; removed in 6.1.
|
|
@@ -9,6 +9,7 @@ module Spree
|
|
|
9
9
|
self.event_prefix = 'payment_session'
|
|
10
10
|
|
|
11
11
|
publishes_lifecycle_events
|
|
12
|
+
publishes_events :canceled, :completed, :expired, :failed, :processing
|
|
12
13
|
|
|
13
14
|
belongs_to :order, class_name: 'Spree::Order', optional: true
|
|
14
15
|
belongs_to :cart, class_name: 'Spree::Cart', optional: true, inverse_of: :payment_sessions
|
|
@@ -28,6 +29,9 @@ module Spree
|
|
|
28
29
|
|
|
29
30
|
scope :not_expired, -> { where('expires_at IS NULL OR expires_at > ?', Time.current) }
|
|
30
31
|
scope :active, -> { not_expired.where(status: %w[pending processing]) }
|
|
32
|
+
# A declined confirm marks the session failed while its intent can still
|
|
33
|
+
# be paid, so placement has to cancel those too.
|
|
34
|
+
scope :unused, -> { where(status: %w[pending failed]).where.missing(:payment) }
|
|
31
35
|
|
|
32
36
|
before_validation :set_defaults_from_order, on: :create
|
|
33
37
|
|
|
@@ -195,7 +199,7 @@ module Spree
|
|
|
195
199
|
end
|
|
196
200
|
|
|
197
201
|
def exactly_one_owner
|
|
198
|
-
errors.add(:base, :exactly_one_of_cart_or_order, message:
|
|
202
|
+
errors.add(:base, :exactly_one_of_cart_or_order, message: I18n.t('spree.errors.messages.exactly_one_of_cart_or_order')) unless [order, cart].compact.one?
|
|
199
203
|
end
|
|
200
204
|
|
|
201
205
|
def publish_processing_event
|
|
@@ -9,6 +9,7 @@ module Spree
|
|
|
9
9
|
self.event_prefix = 'payment_setup_session'
|
|
10
10
|
|
|
11
11
|
publishes_lifecycle_events
|
|
12
|
+
publishes_events :canceled, :completed, :expired, :failed, :processing
|
|
12
13
|
|
|
13
14
|
belongs_to :customer, class_name: Spree.customer_class.to_s, optional: true
|
|
14
15
|
belongs_to :payment_method, class_name: 'Spree::PaymentMethod'
|
|
@@ -22,6 +22,8 @@ module Spree
|
|
|
22
22
|
# delivery-rate providers are; anything request-specific arrives as an
|
|
23
23
|
# argument.
|
|
24
24
|
class Base
|
|
25
|
+
extend Spree::ApiTyped
|
|
26
|
+
|
|
25
27
|
# The name a merchant sees when choosing how sellers are paid.
|
|
26
28
|
#
|
|
27
29
|
# @return [String]
|
|
@@ -57,7 +59,7 @@ module Spree
|
|
|
57
59
|
# @return [Hash]
|
|
58
60
|
def self.to_api_hash(store)
|
|
59
61
|
{
|
|
60
|
-
id:
|
|
62
|
+
id: api_type,
|
|
61
63
|
name: display_name,
|
|
62
64
|
available: available_for_store?(store),
|
|
63
65
|
requires_payout_account: requires_payout_account?,
|
|
@@ -10,6 +10,8 @@ module Spree
|
|
|
10
10
|
# integrations) and +find_nearby+ gains +zipcode:+/+query:+ params.
|
|
11
11
|
# Build third-party providers against 6.1, not this shape.
|
|
12
12
|
class Base
|
|
13
|
+
extend Spree::ApiTyped
|
|
14
|
+
|
|
13
15
|
# @return [Array<Spree::PickupPointOption>]
|
|
14
16
|
def find_nearby(latitude:, longitude:, limit: 20)
|
|
15
17
|
raise NotImplementedError, "Please implement 'find_nearby' in your pickup point provider: #{self.class.name}"
|
|
@@ -10,7 +10,6 @@ module Spree
|
|
|
10
10
|
|
|
11
11
|
MATCH_POLICIES = %w[all any].freeze
|
|
12
12
|
|
|
13
|
-
belongs_to :store, class_name: 'Spree::Store'
|
|
14
13
|
# The owning agreement, or nil for a standalone list. An owned list is
|
|
15
14
|
# reached only through its catalog — generic rule matching skips it in
|
|
16
15
|
# SQL (see .for_context) — so a deactivated catalog's list goes dormant
|
|
@@ -155,7 +154,7 @@ module Spree
|
|
|
155
154
|
end
|
|
156
155
|
|
|
157
156
|
def self.match_policies
|
|
158
|
-
MATCH_POLICIES.map { |key| [
|
|
157
|
+
MATCH_POLICIES.map { |key| [I18n.t("spree.#{key}"), key] }
|
|
159
158
|
end
|
|
160
159
|
|
|
161
160
|
# Returns true if the price list is applicable to the context
|
data/app/models/spree/product.rb
CHANGED
|
@@ -38,6 +38,7 @@ module Spree
|
|
|
38
38
|
include Spree::StorePreferences
|
|
39
39
|
|
|
40
40
|
publishes_lifecycle_events
|
|
41
|
+
publishes_events :activated, :approved, :archived, :back_in_stock, :drafted, :out_of_stock, :proposed, :rejected
|
|
41
42
|
|
|
42
43
|
MEMOIZED_METHODS = %w[total_on_hand category_and_ancestors
|
|
43
44
|
default_variant_id tax_category default_variant variant_for_images
|
|
@@ -302,9 +303,6 @@ module Spree
|
|
|
302
303
|
where(id: (product_ids + custom_field_ids).uniq.compact)
|
|
303
304
|
}
|
|
304
305
|
|
|
305
|
-
# Backward compatibility alias — remove in Spree 6.0
|
|
306
|
-
scope :multi_search, ->(*args) { search(*args) }
|
|
307
|
-
|
|
308
306
|
scope :archivable, -> { where(status: %w[active draft]) }
|
|
309
307
|
scope :by_source, ->(source) { send(source) }
|
|
310
308
|
scope :published, -> { where(status: 'active') }
|
|
@@ -375,7 +373,7 @@ module Spree
|
|
|
375
373
|
self.storefront_ransackable_associations = %w[tags categories collections]
|
|
376
374
|
self.whitelisted_ransackable_scopes = %w[not_discontinued search_by_name in_taxon in_category in_categories in_collection price_between
|
|
377
375
|
price_lte price_gte
|
|
378
|
-
search
|
|
376
|
+
search in_stock out_of_stock with_option_value_ids
|
|
379
377
|
|
|
380
378
|
ascend_by_price descend_by_price]
|
|
381
379
|
|
|
@@ -693,7 +691,7 @@ module Spree
|
|
|
693
691
|
# variant), reading preloaded associations to avoid an N+1.
|
|
694
692
|
# @return [ActiveSupport::TimeWithZone, nil]
|
|
695
693
|
def preorder_ships_at
|
|
696
|
-
candidates = has_variants? ? variants : [
|
|
694
|
+
candidates = has_variants? ? variants : [default_variant]
|
|
697
695
|
candidates.select(&:preorder?).filter_map(&:preorder_ships_at).max
|
|
698
696
|
end
|
|
699
697
|
|
|
@@ -817,7 +815,13 @@ module Spree
|
|
|
817
815
|
Spree::Products::AutoMatchCollectionsJob.set(wait: 30.seconds).perform_later(id)
|
|
818
816
|
end
|
|
819
817
|
|
|
820
|
-
|
|
818
|
+
# @param seller [Spree::Seller, nil] the seller exporting their own
|
|
819
|
+
# products, whose rows cover only their own locations; nil for the
|
|
820
|
+
# operator, whose rows cover the marketplace's and the product's seller's
|
|
821
|
+
# @param default_stock_location [Spree::StockLocation, nil] the location
|
|
822
|
+
# the full rows carry; further locations get stock-only rows. The
|
|
823
|
+
# store's default when nil
|
|
824
|
+
def to_csv(store = nil, seller: nil, default_stock_location: nil)
|
|
821
825
|
store ||= self.store
|
|
822
826
|
properties_for_csv = if respond_to?(:product_properties) && Spree::Config.respond_to?(:product_properties_enabled) && Spree::Config[:product_properties_enabled]
|
|
823
827
|
Spree::Property.order(:position).flat_map do |property|
|
|
@@ -840,11 +844,12 @@ module Spree
|
|
|
840
844
|
all_variants = variants.to_a
|
|
841
845
|
default_currency = store.default_currency
|
|
842
846
|
additional_currencies = store.supported_currencies_list.map(&:iso_code) - [default_currency]
|
|
847
|
+
default_stock_location ||= store.default_stock_location
|
|
843
848
|
|
|
844
849
|
# Primary rows in the store's default currency
|
|
845
850
|
all_variants.each_with_index do |variant, index|
|
|
846
851
|
csv_lines << Spree::CSV::ProductVariantPresenter.new(self, variant, index, properties_for_csv, categories_for_csv, store,
|
|
847
|
-
custom_field_values).call
|
|
852
|
+
custom_field_values, default_stock_location: default_stock_location).call
|
|
848
853
|
end
|
|
849
854
|
|
|
850
855
|
# Price-only rows for each additional currency
|
|
@@ -857,6 +862,25 @@ module Spree
|
|
|
857
862
|
end
|
|
858
863
|
end
|
|
859
864
|
|
|
865
|
+
# Stock-only rows for every other location the importer can name back. A
|
|
866
|
+
# row the import cannot route to its variant is left out: with no SKU it
|
|
867
|
+
# would land on the default variant.
|
|
868
|
+
location_owner_ids = seller ? [seller.id] : [nil, seller_id].uniq
|
|
869
|
+
all_variants.each do |variant|
|
|
870
|
+
next unless variant.should_track_inventory?
|
|
871
|
+
next if variant.sku.blank? && variant != default_variant
|
|
872
|
+
|
|
873
|
+
variant.stock_levels.each do |stock_level|
|
|
874
|
+
location = stock_level.stock_location
|
|
875
|
+
next if location.nil? || location == default_stock_location
|
|
876
|
+
next unless location.store_id == store.id && location_owner_ids.include?(location.seller_id)
|
|
877
|
+
next if stock_level.count_on_hand.zero?
|
|
878
|
+
|
|
879
|
+
csv_lines << Spree::CSV::ProductVariantPresenter.new(self, variant, 0, [], [], store,
|
|
880
|
+
stock_level: stock_level).call
|
|
881
|
+
end
|
|
882
|
+
end
|
|
883
|
+
|
|
860
884
|
csv_lines
|
|
861
885
|
end
|
|
862
886
|
|
|
@@ -56,17 +56,5 @@ module Spree
|
|
|
56
56
|
def store
|
|
57
57
|
product&.store
|
|
58
58
|
end
|
|
59
|
-
|
|
60
|
-
# Named explicitly rather than left to the `Spree::Api::V3::` convention:
|
|
61
|
-
# a serializer at that level is picked up by the Store API's generated
|
|
62
|
-
# types and OpenAPI document, and a review decision is not something the
|
|
63
|
-
# storefront has any business describing. The seller's own view is the
|
|
64
|
-
# right shape for an event — it already withholds who decided, which a
|
|
65
|
-
# webhook payload leaving the marketplace should not carry.
|
|
66
|
-
#
|
|
67
|
-
# @return [Class]
|
|
68
|
-
def event_serializer_class
|
|
69
|
-
Spree::Api::V3::Seller::ProductSubmissionSerializer
|
|
70
|
-
end
|
|
71
59
|
end
|
|
72
60
|
end
|
|
@@ -10,7 +10,6 @@ module Spree
|
|
|
10
10
|
TRANSLATABLE_FIELDS = %i[name].freeze
|
|
11
11
|
translates(*TRANSLATABLE_FIELDS, column_fallback: Spree.mobility_column_fallback)
|
|
12
12
|
|
|
13
|
-
belongs_to :store, class_name: 'Spree::Store'
|
|
14
13
|
# Creation-time template only: stamped onto the product when it is
|
|
15
14
|
# created with this type, never managed through it afterwards — the same
|
|
16
15
|
# doctrine as every other type-driven attribute. Nil means the store's
|
|
@@ -104,6 +104,31 @@ module Spree
|
|
|
104
104
|
quantifier.can_supply? quantity
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
+
# Whether the promotion gives its gift on this order, judged with other
|
|
108
|
+
# promotions' gifts still counting toward its own rules — a single
|
|
109
|
+
# level, so two gift promotions measuring each other cannot loop.
|
|
110
|
+
#
|
|
111
|
+
# @param order [Spree::Order, Spree::Cart]
|
|
112
|
+
# @return [Boolean]
|
|
113
|
+
def gives_away?(order)
|
|
114
|
+
promotion.eligible?(order, own_gift_only: true) && qualifies_beyond_the_gift?(order, own_gift_only: true)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# How many units of this line the promotion pays for — never more than
|
|
118
|
+
# the line holds, so a shopper buying three of a variant gifted once
|
|
119
|
+
# still pays for two. `quantity` is nullable and written by `upsert_all`,
|
|
120
|
+
# which skips validation, so a missing or negative one gifts nothing
|
|
121
|
+
# rather than raising or turning the discount into a surcharge.
|
|
122
|
+
#
|
|
123
|
+
# @param line_item [Spree::LineItem]
|
|
124
|
+
# @return [Integer]
|
|
125
|
+
def gifted_quantity_of(line_item)
|
|
126
|
+
gifted = promotion_action_line_items.detect { |item| item.variant_id == line_item.variant_id }
|
|
127
|
+
return 0 if gifted.nil?
|
|
128
|
+
|
|
129
|
+
[[line_item.quantity, gifted.quantity.to_i].min, 0].max
|
|
130
|
+
end
|
|
131
|
+
|
|
107
132
|
private
|
|
108
133
|
|
|
109
134
|
# Whether this line holds a variant the promotion gives away.
|
|
@@ -117,30 +142,15 @@ module Spree
|
|
|
117
142
|
# to hold a line the rules count with units this action is not already
|
|
118
143
|
# covering. A promotion with no rules qualifies on anything, so there is
|
|
119
144
|
# nothing for the gift to stand in for.
|
|
120
|
-
def qualifies_beyond_the_gift?(order)
|
|
145
|
+
def qualifies_beyond_the_gift?(order, options = {})
|
|
121
146
|
return true if promotion.promotion_rules.empty?
|
|
122
147
|
|
|
123
148
|
order.line_items.any? do |line_item|
|
|
124
|
-
promotion.line_item_actionable?(order, line_item) &&
|
|
149
|
+
promotion.line_item_actionable?(order, line_item, options) &&
|
|
125
150
|
gifted_quantity_of(line_item) < line_item.quantity
|
|
126
151
|
end
|
|
127
152
|
end
|
|
128
153
|
|
|
129
|
-
# How many units of this line the promotion pays for — never more than
|
|
130
|
-
# the line holds, so a shopper buying three of a variant gifted once
|
|
131
|
-
# still pays for two. `quantity` is nullable and written by `upsert_all`,
|
|
132
|
-
# which skips validation, so a missing or negative one gifts nothing
|
|
133
|
-
# rather than raising or turning the discount into a surcharge.
|
|
134
|
-
#
|
|
135
|
-
# @param line_item [Spree::LineItem]
|
|
136
|
-
# @return [Integer]
|
|
137
|
-
def gifted_quantity_of(line_item)
|
|
138
|
-
gifted = promotion_action_line_items.detect { |item| item.variant_id == line_item.variant_id }
|
|
139
|
-
return 0 if gifted.nil?
|
|
140
|
-
|
|
141
|
-
[[line_item.quantity, gifted.quantity.to_i].min, 0].max
|
|
142
|
-
end
|
|
143
|
-
|
|
144
154
|
def add_missing_line_items(order)
|
|
145
155
|
added_results = promotion_action_line_items.map do |item|
|
|
146
156
|
missing = item.quantity.to_i - order.quantity_of(item.variant)
|
|
@@ -47,10 +47,6 @@ module Spree
|
|
|
47
47
|
#
|
|
48
48
|
after_save :add_categories
|
|
49
49
|
|
|
50
|
-
def applicable?(promotable)
|
|
51
|
-
promotable.is_a?(Spree::Order) || promotable.is_a?(Spree::Cart)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
50
|
def eligible_category_ids
|
|
55
51
|
@eligible_category_ids ||= promotion_rule_categories.pluck(:category_id)
|
|
56
52
|
end
|
|
@@ -14,10 +14,6 @@ module Spree
|
|
|
14
14
|
scope: ->(rule) { rule.promotion.store.channels }
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
-
def applicable?(promotable)
|
|
18
|
-
promotable.is_a?(Spree::Order) || promotable.is_a?(Spree::Cart)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
17
|
def channels
|
|
22
18
|
return Spree::Channel.none if preferred_channel_ids.blank?
|
|
23
19
|
|
|
@@ -15,10 +15,6 @@ module Spree
|
|
|
15
15
|
preference :country_id, :integer # legacy single-country shortcut
|
|
16
16
|
preference :country_code, :string # legacy ISO-based shortcut
|
|
17
17
|
|
|
18
|
-
def applicable?(promotable)
|
|
19
|
-
promotable.is_a?(Spree::Order) || promotable.is_a?(Spree::Cart)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
18
|
def countries
|
|
23
19
|
isos = configured_country_codes.presence || [configured_country_code].compact_blank
|
|
24
20
|
isos = [legacy_country_code(preferred_country_id)].compact_blank if isos.blank? && preferred_country_id.present?
|
|
@@ -5,10 +5,6 @@ module Spree
|
|
|
5
5
|
class Currency < Spree::PromotionRule
|
|
6
6
|
preference :currency, :string
|
|
7
7
|
|
|
8
|
-
def applicable?(promotable)
|
|
9
|
-
promotable.is_a?(Spree::Order) || promotable.is_a?(Spree::Cart)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
8
|
def eligible?(order, options = {})
|
|
13
9
|
return true if order.currency == preferred_currency
|
|
14
10
|
|
|
@@ -15,10 +15,6 @@ module Spree
|
|
|
15
15
|
scope: ->(rule) { rule.promotion.store.customer_groups }
|
|
16
16
|
)
|
|
17
17
|
|
|
18
|
-
def applicable?(promotable)
|
|
19
|
-
promotable.is_a?(Spree::Order) || promotable.is_a?(Spree::Cart)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
18
|
def customer_groups
|
|
23
19
|
return Spree::CustomerGroup.none if preferred_customer_group_ids.blank?
|
|
24
20
|
|
|
@@ -4,10 +4,6 @@ module Spree
|
|
|
4
4
|
class FirstOrder < Spree::PromotionRule
|
|
5
5
|
attr_reader :user, :email, :store
|
|
6
6
|
|
|
7
|
-
def applicable?(promotable)
|
|
8
|
-
promotable.is_a?(Spree::Order) || promotable.is_a?(Spree::Cart)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
7
|
def eligible?(order, options = {})
|
|
12
8
|
@user = order.try(:customer) || options[:user]
|
|
13
9
|
@email = if options[:email].present?
|