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
|
@@ -7,6 +7,8 @@ module Spree
|
|
|
7
7
|
# decide at resolution time rather than at claim creation.
|
|
8
8
|
class Resolve < Spree::Workflow
|
|
9
9
|
include Spree::Refunds::OrderPayments
|
|
10
|
+
include Spree::Refunds::TaxCredit
|
|
11
|
+
include Spree::Fulfillments::Replacements
|
|
10
12
|
|
|
11
13
|
hooks :validate, :before_settle, :after_resolve
|
|
12
14
|
|
|
@@ -32,6 +34,8 @@ module Spree
|
|
|
32
34
|
step :resolve_amount if refunding?
|
|
33
35
|
run_hooks :validate
|
|
34
36
|
|
|
37
|
+
step :settle_tax
|
|
38
|
+
|
|
35
39
|
ApplicationRecord.transaction do
|
|
36
40
|
run_hooks :before_settle
|
|
37
41
|
step :build_replacement_fulfillments if replacing?
|
|
@@ -40,6 +44,7 @@ module Spree
|
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
external_step :refund_at_gateway if refunding? && !internal_refund?
|
|
47
|
+
external_step :refund_tax if refunding?
|
|
43
48
|
|
|
44
49
|
step :recalculate_order
|
|
45
50
|
run_hooks :after_resolve
|
|
@@ -68,14 +73,35 @@ module Spree
|
|
|
68
73
|
# attribute, and ActiveModel raises when an error names one that
|
|
69
74
|
# does not exist on the record.
|
|
70
75
|
claim.errors.add(:base, :invalid_refund_method,
|
|
71
|
-
message:
|
|
76
|
+
message: I18n.t('spree.errors.messages.invalid_refund_method'))
|
|
72
77
|
failure(claim)
|
|
73
78
|
end
|
|
74
79
|
failure(claim, :not_approved) unless claim.approved?
|
|
75
80
|
end
|
|
76
81
|
|
|
82
|
+
# Rewrites the credit rows for the money actually going back — each line's
|
|
83
|
+
# share of it follows the refund agreed for that line — or clears them
|
|
84
|
+
# when the claim is put right with a replacement alone.
|
|
85
|
+
def settle_tax
|
|
86
|
+
lines = claim.claim_line_items.to_a
|
|
87
|
+
amounts = if refunding?
|
|
88
|
+
weights = lines.index_with(&:refund_amount)
|
|
89
|
+
weights = lines.index_with(&:paid_amount) if weights.values.sum.zero?
|
|
90
|
+
allocate_refund(@amount_to_refund, weights, claim.currency)
|
|
91
|
+
else
|
|
92
|
+
lines.index_with { 0.to_d }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
with_tax_provider(claim) { claim.settle_tax!(amounts: amounts) }
|
|
96
|
+
@tax_amount = claim.credited_tax_total
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def refund_tax
|
|
100
|
+
file_tax_credit(claim, claim.claim_line_items.to_a, @amount_to_refund)
|
|
101
|
+
end
|
|
102
|
+
|
|
77
103
|
# A claim can never refund more than the customer paid for the affected
|
|
78
|
-
# items.
|
|
104
|
+
# items, tax included.
|
|
79
105
|
def resolve_amount
|
|
80
106
|
@amount_to_refund = (amount || claim.refund_total).to_d
|
|
81
107
|
ceiling = claim.claim_line_items.sum(&:paid_amount).to_d
|
|
@@ -96,37 +122,13 @@ module Spree
|
|
|
96
122
|
end
|
|
97
123
|
|
|
98
124
|
def build_replacement_fulfillments
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
variant: line.variant_to_send,
|
|
102
|
-
quantity: line.quantity,
|
|
103
|
-
line_item: line.line_item,
|
|
104
|
-
order: claim.order,
|
|
105
|
-
status: 'on_hand'
|
|
106
|
-
)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
failure(claim, :nothing_to_replace) if units.empty?
|
|
110
|
-
|
|
111
|
-
@fulfillments = Spree::Stock::Coordinator.new(claim.order, units).fulfillments
|
|
112
|
-
if @fulfillments.flat_map(&:fulfillment_items).sum(&:quantity) != units.sum(&:quantity)
|
|
113
|
-
failure(claim, :replacement_out_of_stock)
|
|
125
|
+
items = claim.replacement_line_items.map do |line|
|
|
126
|
+
{ variant: line.variant_to_send, quantity: line.quantity, line_item: line.line_item }
|
|
114
127
|
end
|
|
115
128
|
|
|
116
|
-
claim
|
|
117
|
-
claim.order.save!
|
|
118
|
-
@fulfillments.each { |fulfillment| allocate_replacement_stock(fulfillment) }
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
# See Spree::Exchanges::Fulfill — a replacement that holds no promise
|
|
122
|
-
# ships without writing a movement, so the shelf never follows the goods.
|
|
123
|
-
def allocate_replacement_stock(fulfillment)
|
|
124
|
-
fulfillment.manifest.each do |item|
|
|
125
|
-
next unless item.variant.track_inventory?
|
|
126
|
-
next unless item.quantity.positive?
|
|
129
|
+
failure(claim, :nothing_to_replace) if items.empty?
|
|
127
130
|
|
|
128
|
-
|
|
129
|
-
end
|
|
131
|
+
@fulfillments = build_replacements(claim, items)
|
|
130
132
|
end
|
|
131
133
|
|
|
132
134
|
def issue_store_credit
|
|
@@ -144,7 +146,8 @@ module Spree
|
|
|
144
146
|
order: claim.order,
|
|
145
147
|
amount: @amount_to_refund,
|
|
146
148
|
record: claim,
|
|
147
|
-
refunder: resolver
|
|
149
|
+
refunder: resolver,
|
|
150
|
+
tax_amount: @tax_amount
|
|
148
151
|
)
|
|
149
152
|
|
|
150
153
|
failure(claim, :no_refundable_payments) if @refunds.empty?
|
|
@@ -91,7 +91,7 @@ module Spree
|
|
|
91
91
|
# release gateway data, and hand back success, for a row that is still
|
|
92
92
|
# fully identified.
|
|
93
93
|
unless committed
|
|
94
|
-
return failure(customer,
|
|
94
|
+
return failure(customer, I18n.t('spree.customer_errors.anonymize_failed'))
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
purge_collected_attachments
|
|
@@ -103,9 +103,8 @@ module Spree
|
|
|
103
103
|
customer.reload
|
|
104
104
|
|
|
105
105
|
customer.publish_event(
|
|
106
|
-
'customer.anonymized',
|
|
107
|
-
store_id: store&.prefixed_id,
|
|
108
|
-
requested_by_id: requested_by&.prefixed_id
|
|
106
|
+
'customer.anonymized', nil,
|
|
107
|
+
store_id: store&.prefixed_id, requested_by_id: requested_by&.prefixed_id
|
|
109
108
|
)
|
|
110
109
|
|
|
111
110
|
run_hooks :after_anonymize
|
|
@@ -195,7 +195,7 @@ module Spree
|
|
|
195
195
|
# vocabulary: a store may not have one called "Terms of Service", and
|
|
196
196
|
# then there is nothing to snapshot rather than something to guess at.
|
|
197
197
|
def consent_policies
|
|
198
|
-
store.policies.with_matching_name(
|
|
198
|
+
store.policies.with_matching_name(I18n.t('spree.terms_of_service')).to_a
|
|
199
199
|
end
|
|
200
200
|
|
|
201
201
|
def link_order
|
|
@@ -53,7 +53,7 @@ module Spree
|
|
|
53
53
|
def ensure_pending
|
|
54
54
|
return if data_request.pending?
|
|
55
55
|
|
|
56
|
-
failure(data_request,
|
|
56
|
+
failure(data_request, I18n.t('spree.data_request_errors.not_pending'))
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def mark_processing
|
|
@@ -92,7 +92,7 @@ module Spree
|
|
|
92
92
|
|
|
93
93
|
return unless refused
|
|
94
94
|
|
|
95
|
-
failure(data_request,
|
|
95
|
+
failure(data_request, I18n.t('spree.data_request_errors.already_anonymized'))
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
def attach_export
|
|
@@ -49,7 +49,7 @@ module Spree
|
|
|
49
49
|
return if tracking_status.blank?
|
|
50
50
|
return if Spree::Delivery::STATUSES.include?(tracking_status.to_s)
|
|
51
51
|
|
|
52
|
-
failure(delivery,
|
|
52
|
+
failure(delivery, I18n.t('spree.fulfillments.errors.unknown_tracking_status', status: tracking_status))
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
# Overwrite rather than accumulate: this axis answers "where is it now",
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module EmailTemplates
|
|
3
|
+
# Throws away the draft of one template and language. Given the
|
|
4
|
+
# `lock_version` the draft was seen at, a draft saved or published since
|
|
5
|
+
# is reported as a conflict.
|
|
6
|
+
class DiscardDraft < Spree::Workflow
|
|
7
|
+
def perform(store:, key:, locale: Spree::EmailTemplate::ANY_LOCALE, lock_version: nil)
|
|
8
|
+
super
|
|
9
|
+
draft = store.email_template_drafts.find_by(key: key, locale: locale)
|
|
10
|
+
return failure(nil, :stale) if !lock_version.nil? && lock_version.to_i != draft&.lock_version
|
|
11
|
+
return success(nil) unless draft
|
|
12
|
+
|
|
13
|
+
draft.destroy!
|
|
14
|
+
success(nil)
|
|
15
|
+
rescue ActiveRecord::StaleObjectError
|
|
16
|
+
failure(nil, :stale)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module EmailTemplates
|
|
3
|
+
# Makes a draft live. The draft is first rendered the way customers would
|
|
4
|
+
# receive it (see Spree::EmailTemplates::Check); a draft that does not
|
|
5
|
+
# render is refused with what is wrong and where, so an email already
|
|
6
|
+
# being sent can never break. Publishing records a revision and clears
|
|
7
|
+
# the draft. Given the `lock_version` the draft was reviewed at, a draft
|
|
8
|
+
# saved since is refused rather than published unseen.
|
|
9
|
+
class Publish < Spree::Workflow
|
|
10
|
+
def perform(store:, key:, locale: Spree::EmailTemplate::ANY_LOCALE, actor: nil, lock_version: nil)
|
|
11
|
+
super
|
|
12
|
+
step :ensure_draft
|
|
13
|
+
step :ensure_current
|
|
14
|
+
step :check
|
|
15
|
+
|
|
16
|
+
begin
|
|
17
|
+
ApplicationRecord.transaction do
|
|
18
|
+
step :publish
|
|
19
|
+
step :record_revision
|
|
20
|
+
step :clear_draft
|
|
21
|
+
end
|
|
22
|
+
rescue ActiveRecord::StaleObjectError, ActiveRecord::RecordNotUnique
|
|
23
|
+
failure(nil, :stale)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
template.publish_event('email_template.published')
|
|
27
|
+
success(template)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def draft
|
|
33
|
+
@draft ||= store.email_template_drafts.find_by(key: key, locale: locale)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def template
|
|
37
|
+
@template ||= store.email_templates.find_or_initialize_by(key: draft.key, locale: draft.locale)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def ensure_draft
|
|
41
|
+
failure(nil, :no_draft) unless draft
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def ensure_current
|
|
45
|
+
failure(nil, :stale) if !lock_version.nil? && lock_version.to_i != draft.lock_version
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def check
|
|
49
|
+
problems = Spree::EmailTemplates::Check.new(store: store, draft: draft).call
|
|
50
|
+
failure(problems, :invalid_template) if problems.any?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def publish
|
|
54
|
+
template.assign_attributes(
|
|
55
|
+
subject: draft.subject, body: draft.body, base_subject: draft.base_subject, base_body: draft.base_body,
|
|
56
|
+
status: :published, published_at: Time.current, published_by: actor, reverted_at: nil, reverted_by: nil
|
|
57
|
+
)
|
|
58
|
+
template.save!
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def record_revision
|
|
62
|
+
template.revisions.create!(subject: template.subject, body: template.body, published_by: actor)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def clear_draft
|
|
66
|
+
draft.destroy!
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module EmailTemplates
|
|
3
|
+
# Copies a published revision into the draft, to be checked and
|
|
4
|
+
# published like any other change. A revision of the version for every
|
|
5
|
+
# language can be restored into one language's draft (`locale`).
|
|
6
|
+
class RestoreRevision < Spree::Workflow
|
|
7
|
+
# @param draft_version [Hash] `{ lock_version: }` to check the draft as saving does; empty checks nothing
|
|
8
|
+
def perform(revision:, actor: nil, locale: nil, draft_version: {})
|
|
9
|
+
super
|
|
10
|
+
template = revision.email_template
|
|
11
|
+
target_locale = locale.presence || template.locale
|
|
12
|
+
|
|
13
|
+
Spree.email_template_save_draft_workflow.call(
|
|
14
|
+
store: template.store, key: template.key, locale: target_locale, actor: actor,
|
|
15
|
+
attributes: {
|
|
16
|
+
subject: readable(revision.subject, target_locale, escape: false),
|
|
17
|
+
body: readable(revision.body, target_locale),
|
|
18
|
+
**draft_version.slice(:lock_version)
|
|
19
|
+
}
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
# A shared revision restored into one language reads in that language's words.
|
|
26
|
+
def readable(text, target_locale, escape: true)
|
|
27
|
+
return text if target_locale == Spree::EmailTemplate::ANY_LOCALE
|
|
28
|
+
|
|
29
|
+
Spree::Emails::TranslationInliner.call(text, locale: target_locale, escape: escape)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module EmailTemplates
|
|
3
|
+
# Goes back to Spree's default for one template and language: the
|
|
4
|
+
# published version is marked reverted, so the file answers again, and
|
|
5
|
+
# any draft is discarded. The row and its revisions stay, so the history
|
|
6
|
+
# can still be restored. Given the `lock_version` the draft was seen at,
|
|
7
|
+
# a draft saved or published since is not thrown away.
|
|
8
|
+
class Revert < Spree::Workflow
|
|
9
|
+
def perform(store:, key:, locale: Spree::EmailTemplate::ANY_LOCALE, actor: nil, lock_version: nil)
|
|
10
|
+
super
|
|
11
|
+
template = store.email_templates.find_by(key: key, locale: locale)
|
|
12
|
+
draft = store.email_template_drafts.find_by(key: key, locale: locale)
|
|
13
|
+
return failure(nil, :stale) if !lock_version.nil? && lock_version.to_i != draft&.lock_version
|
|
14
|
+
|
|
15
|
+
begin
|
|
16
|
+
ApplicationRecord.transaction do
|
|
17
|
+
draft&.destroy!
|
|
18
|
+
template&.update!(status: :reverted, reverted_at: Time.current, reverted_by: actor) if template&.published?
|
|
19
|
+
end
|
|
20
|
+
rescue ActiveRecord::StaleObjectError
|
|
21
|
+
return failure(nil, :stale)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
template&.publish_event('email_template.reverted') if template&.reverted?
|
|
25
|
+
success(template)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module EmailTemplates
|
|
3
|
+
# Saves a draft of an editable email template, in any state: it is work
|
|
4
|
+
# in progress and customers keep receiving the published version. The
|
|
5
|
+
# first save starts from what is published, else Spree's default, and
|
|
6
|
+
# remembers that default so an upgrade changing it can be spotted.
|
|
7
|
+
#
|
|
8
|
+
# A save carrying an older `lock_version` than the draft has is refused,
|
|
9
|
+
# so two admins editing at once cannot overwrite each other. `rebase`
|
|
10
|
+
# marks the draft as based on Spree's current default, for a merchant who
|
|
11
|
+
# reviewed an upgraded default and keeps their own version.
|
|
12
|
+
class SaveDraft < Spree::Workflow
|
|
13
|
+
def perform(store:, key:, attributes:, locale: Spree::EmailTemplate::ANY_LOCALE, actor: nil)
|
|
14
|
+
super
|
|
15
|
+
step :ensure_editable
|
|
16
|
+
step :ensure_current
|
|
17
|
+
step :save
|
|
18
|
+
|
|
19
|
+
success(draft)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def draft
|
|
25
|
+
@draft ||= store.email_template_drafts.find_or_initialize_by(key: key, locale: locale)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def ensure_editable
|
|
29
|
+
failure(nil, :not_editable) unless Spree.editable_email_templates.include?(key)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Without `lock_version` nothing is checked. `nil` says the caller saw no
|
|
33
|
+
# draft, so one saved since is refused rather than overwritten.
|
|
34
|
+
def ensure_current
|
|
35
|
+
return unless attributes.key?(:lock_version)
|
|
36
|
+
|
|
37
|
+
expected = attributes[:lock_version]
|
|
38
|
+
if expected.nil?
|
|
39
|
+
failure(nil, :stale) if draft.persisted?
|
|
40
|
+
elsif draft.new_record? || expected.to_i != draft.lock_version
|
|
41
|
+
# A draft that is gone was published or discarded since it was loaded.
|
|
42
|
+
failure(nil, :stale)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def save
|
|
47
|
+
start_from_current if draft.new_record?
|
|
48
|
+
rebase if ActiveModel::Type::Boolean.new.cast(attributes[:rebase])
|
|
49
|
+
draft.subject = attributes[:subject] if attributes.key?(:subject)
|
|
50
|
+
draft.body = attributes[:body] if attributes.key?(:body)
|
|
51
|
+
draft.updated_by = actor
|
|
52
|
+
failure(draft) unless draft.save
|
|
53
|
+
rescue ActiveRecord::StaleObjectError, ActiveRecord::RecordNotUnique
|
|
54
|
+
failure(nil, :stale)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Starts from what customers in this language receive, with Spree's
|
|
58
|
+
# translation keys written out as text in it.
|
|
59
|
+
def start_from_current
|
|
60
|
+
published = store.email_templates.published.where(key: key, locale: [draft.locale, Spree::EmailTemplate::ANY_LOCALE]).
|
|
61
|
+
min_by { |template| template.locale == draft.locale ? 0 : 1 }
|
|
62
|
+
|
|
63
|
+
draft.subject = readable(published&.subject || default&.subject, escape: false)
|
|
64
|
+
draft.body = readable(published&.body || default&.body)
|
|
65
|
+
draft.base_subject = published ? published.base_subject : default&.subject
|
|
66
|
+
draft.base_body = published ? published.base_body : default&.body
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def rebase
|
|
70
|
+
draft.base_subject = default&.subject
|
|
71
|
+
draft.base_body = default&.body
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def readable(text, escape: true)
|
|
75
|
+
return text if draft.locale == Spree::EmailTemplate::ANY_LOCALE
|
|
76
|
+
|
|
77
|
+
Spree::Emails::TranslationInliner.call(text, locale: draft.locale, escape: escape)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def default
|
|
81
|
+
@default ||= Spree::Emails::TemplateResolver.for_mailers.find_default(key)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -1,38 +1,21 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
module Exchanges
|
|
3
3
|
class Approve < Spree::Workflow
|
|
4
|
+
include Spree::PostSale::Approval
|
|
5
|
+
|
|
4
6
|
hooks :validate, :after_approve
|
|
5
7
|
|
|
6
8
|
# @param exchange [Spree::Exchange]
|
|
7
9
|
# @param approver [Object, nil]
|
|
8
10
|
def perform(exchange:, approver: nil)
|
|
9
11
|
super
|
|
10
|
-
|
|
11
|
-
step :ensure_approvable
|
|
12
|
-
run_hooks :validate
|
|
13
|
-
|
|
14
|
-
ApplicationRecord.transaction do
|
|
15
|
-
step :mark_approved
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
run_hooks :after_approve
|
|
19
|
-
exchange.publish_event('exchange.approved')
|
|
20
|
-
success(exchange.reload)
|
|
12
|
+
approve
|
|
21
13
|
end
|
|
22
14
|
|
|
23
15
|
private
|
|
24
16
|
|
|
25
|
-
def
|
|
26
|
-
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def mark_approved
|
|
30
|
-
exchange.update!(
|
|
31
|
-
status: 'approved',
|
|
32
|
-
approved_at: Time.current,
|
|
33
|
-
created_by: exchange.created_by || approver
|
|
34
|
-
)
|
|
35
|
-
end
|
|
17
|
+
def post_sale_record = exchange
|
|
18
|
+
def approvable_status = 'requested'
|
|
36
19
|
end
|
|
37
20
|
end
|
|
38
21
|
end
|
|
@@ -4,37 +4,21 @@ module Spree
|
|
|
4
4
|
# merchant holds the customer's items and must either fulfill the
|
|
5
5
|
# replacement or refund.
|
|
6
6
|
class Cancel < Spree::Workflow
|
|
7
|
+
include Spree::PostSale::Cancellation
|
|
8
|
+
|
|
7
9
|
hooks :validate, :after_cancel
|
|
8
10
|
|
|
9
11
|
# @param exchange [Spree::Exchange]
|
|
10
12
|
# @param reason [String, nil]
|
|
11
13
|
def perform(exchange:, reason: nil)
|
|
12
14
|
super
|
|
13
|
-
|
|
14
|
-
step :ensure_cancellable
|
|
15
|
-
run_hooks :validate
|
|
16
|
-
|
|
17
|
-
ApplicationRecord.transaction do
|
|
18
|
-
step :mark_canceled
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
run_hooks :after_cancel
|
|
22
|
-
exchange.publish_event('exchange.canceled')
|
|
23
|
-
success(exchange.reload)
|
|
15
|
+
cancel
|
|
24
16
|
end
|
|
25
17
|
|
|
26
18
|
private
|
|
27
19
|
|
|
28
|
-
def
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
failure(exchange, :not_cancellable)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def mark_canceled
|
|
35
|
-
memo = [exchange.memo, reason].compact_blank.join("\n")
|
|
36
|
-
exchange.update!(status: 'canceled', canceled_at: Time.current, memo: memo.presence)
|
|
37
|
-
end
|
|
20
|
+
def post_sale_record = exchange
|
|
21
|
+
def cancellable_statuses = %w[requested approved]
|
|
38
22
|
end
|
|
39
23
|
end
|
|
40
24
|
end
|
|
@@ -4,6 +4,7 @@ module Spree
|
|
|
4
4
|
# in their place.
|
|
5
5
|
class Create < Spree::Workflow
|
|
6
6
|
include Spree::Returns::ReturnableQuantity
|
|
7
|
+
include Spree::Refunds::TaxCredit
|
|
7
8
|
|
|
8
9
|
hooks :validate, :after_create
|
|
9
10
|
|
|
@@ -24,6 +25,7 @@ module Spree
|
|
|
24
25
|
|
|
25
26
|
ApplicationRecord.transaction do
|
|
26
27
|
step :build_exchange
|
|
28
|
+
step :calculate_tax
|
|
27
29
|
end
|
|
28
30
|
|
|
29
31
|
run_hooks :after_create
|
|
@@ -92,6 +94,10 @@ module Spree
|
|
|
92
94
|
failure(@exchange) unless @exchange.save
|
|
93
95
|
end
|
|
94
96
|
|
|
97
|
+
def calculate_tax
|
|
98
|
+
with_tax_provider(exchange) { exchange.calculate_tax! }
|
|
99
|
+
end
|
|
100
|
+
|
|
95
101
|
def default_stock_location
|
|
96
102
|
@normalized_items.first[:fulfillment_item].fulfillment&.stock_location ||
|
|
97
103
|
order.store.stock_locations.first
|