spree_core 6.0.0.beta4 → 6.0.0.rc2
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 +5 -5
- 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/search_provider/index_job.rb +4 -0
- data/app/jobs/spree/seller_payouts/sweep_seller_job.rb +2 -0
- data/app/jobs/spree/uploads/purge_unattached_job.rb +49 -0
- data/app/mailers/spree/admin_user_mailer.rb +4 -19
- data/app/mailers/spree/base_mailer.rb +97 -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 +15 -1
- data/app/models/concerns/spree/api_typed.rb +91 -0
- data/app/models/concerns/spree/calculated_adjustments.rb +41 -13
- data/app/models/concerns/spree/calculator/currency_amounts.rb +1 -1
- data/app/models/concerns/spree/calculator/tiers.rb +63 -0
- data/app/models/concerns/spree/canonical_decimals.rb +61 -0
- data/app/models/concerns/spree/customer_methods.rb +23 -18
- data/app/models/concerns/spree/derived_number.rb +11 -13
- 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/json_schema.rb +139 -0
- data/app/models/concerns/spree/preference_schema.rb +62 -32
- data/app/models/concerns/spree/product_scopes.rb +16 -2
- 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 +8 -4
- data/app/models/concerns/spree/purchase/purchase_order.rb +9 -4
- data/app/models/concerns/spree/purchase/store_credits.rb +36 -1
- data/app/models/concerns/spree/purchase/totals.rb +49 -8
- data/app/models/concerns/spree/ransackable_attributes.rb +46 -0
- 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/signed_id_attachments.rb +54 -0
- data/app/models/concerns/spree/single_store_resource.rb +1 -1
- data/app/models/concerns/spree/stores/email_branding.rb +32 -0
- data/app/models/concerns/spree/stores/markets.rb +5 -2
- data/app/models/concerns/spree/type_labels.rb +38 -0
- data/app/models/concerns/spree/typed_adjustment_line.rb +5 -6
- data/app/models/concerns/spree/typed_associations.rb +12 -18
- data/app/models/concerns/spree/vat_price_calculation.rb +5 -6
- data/app/models/spree/address.rb +12 -2
- data/app/models/spree/adjusters/largest_remainder.rb +14 -1
- data/app/models/spree/adjusters/promotion.rb +4 -19
- data/app/models/spree/allowed_origin.rb +3 -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 +99 -22
- data/app/models/spree/calculator/flat_percent_item_total.rb +2 -4
- data/app/models/spree/calculator/flat_rate.rb +3 -5
- data/app/models/spree/calculator/flexi_rate.rb +4 -6
- data/app/models/spree/calculator/percent_on_line_item.rb +2 -2
- data/app/models/spree/calculator/price_sack.rb +5 -7
- data/app/models/spree/calculator/shipping/digital_delivery.rb +3 -5
- data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +7 -7
- data/app/models/spree/calculator/shipping/flat_rate.rb +5 -7
- data/app/models/spree/calculator/shipping/flexi_rate.rb +4 -6
- data/app/models/spree/calculator/shipping/per_item.rb +3 -5
- data/app/models/spree/calculator/shipping/price_sack.rb +5 -7
- data/app/models/spree/calculator/tiered_flat_rate.rb +7 -24
- data/app/models/spree/calculator/tiered_percent.rb +7 -25
- data/app/models/spree/cart.rb +78 -18
- data/app/models/spree/catalog.rb +1 -0
- data/app/models/spree/catalog_price.rb +0 -7
- data/app/models/spree/catalog_price_tier.rb +0 -8
- data/app/models/spree/category.rb +3 -1
- data/app/models/spree/channel/gating.rb +3 -2
- data/app/models/spree/channel.rb +6 -4
- data/app/models/spree/claim.rb +22 -1
- data/app/models/spree/claim_line_item.rb +41 -6
- data/app/models/spree/collection.rb +2 -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 +7 -4
- 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/category_rule.rb +2 -5
- data/app/models/spree/commission_rules/item_total_rule.rb +2 -2
- data/app/models/spree/commission_rules/product_rule.rb +1 -1
- data/app/models/spree/commission_rules/seller_rule.rb +2 -5
- data/app/models/spree/company.rb +1 -0
- 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 +20 -35
- data/app/models/spree/custom_fields/boolean.rb +1 -1
- data/app/models/spree/custom_fields/json.rb +1 -1
- data/app/models/spree/customer_group.rb +1 -0
- data/app/models/spree/data_feed/google.rb +0 -2
- data/app/models/spree/data_request.rb +2 -1
- data/app/models/spree/delivery_method.rb +36 -14
- data/app/models/spree/delivery_method_rule.rb +4 -11
- data/app/models/spree/delivery_method_rules/channel_rule.rb +2 -5
- data/app/models/spree/delivery_method_rules/item_total_rule.rb +2 -2
- data/app/models/spree/delivery_profile.rb +1 -0
- data/app/models/spree/delivery_rate.rb +7 -8
- data/app/models/spree/delivery_rate_provider/base.rb +1 -0
- data/app/models/spree/delivery_zone.rb +1 -2
- 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 +16 -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 +3 -3
- data/app/models/spree/fee.rb +4 -2
- data/app/models/spree/file_upload.rb +155 -0
- data/app/models/spree/fulfillment.rb +66 -30
- data/app/models/spree/fulfillment_changer.rb +2 -2
- data/app/models/spree/fulfillment_group.rb +6 -1
- 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 +6 -0
- data/app/models/spree/gateway/custom_payment_source_method.rb +5 -0
- data/app/models/spree/gateway.rb +6 -2
- data/app/models/spree/gift_card.rb +18 -8
- data/app/models/spree/gift_card_batch.rb +3 -5
- data/app/models/spree/import.rb +5 -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 +9 -19
- data/app/models/spree/invitation.rb +5 -5
- data/app/models/spree/line_item.rb +15 -4
- data/app/models/spree/locale.rb +11 -8
- data/app/models/spree/market.rb +8 -2
- data/app/models/spree/media.rb +1 -9
- data/app/models/spree/newsletter_subscriber.rb +4 -0
- data/app/models/spree/option_type.rb +2 -1
- data/app/models/spree/option_value.rb +2 -1
- data/app/models/spree/order.rb +60 -142
- data/app/models/spree/order_group.rb +18 -4
- 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 +2 -2
- data/app/models/spree/payment/gateway_options.rb +15 -53
- data/app/models/spree/payment/processing.rb +2 -4
- data/app/models/spree/payment.rb +21 -13
- data/app/models/spree/payment_method/check.rb +2 -0
- data/app/models/spree/payment_method/session_instrumentation.rb +1 -0
- data/app/models/spree/payment_method/store_credit.rb +15 -13
- data/app/models/spree/payment_method.rb +78 -6
- 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/policy.rb +1 -0
- data/app/models/spree/price.rb +17 -14
- data/app/models/spree/price_adjustment_tier.rb +4 -0
- data/app/models/spree/price_list.rb +14 -9
- data/app/models/spree/price_rules/channel_rule.rb +3 -6
- data/app/models/spree/price_rules/customer_group_rule.rb +3 -6
- data/app/models/spree/price_rules/market_rule.rb +2 -5
- data/app/models/spree/price_rules/user_rule.rb +1 -3
- data/app/models/spree/product/channels.rb +9 -2
- data/app/models/spree/product.rb +54 -30
- data/app/models/spree/product_submission.rb +0 -12
- data/app/models/spree/product_type.rb +1 -1
- data/app/models/spree/promotion/actions/create_line_items.rb +28 -18
- data/app/models/spree/promotion/rules/category.rb +1 -5
- data/app/models/spree/promotion/rules/channel.rb +2 -9
- data/app/models/spree/promotion/rules/country.rb +3 -8
- data/app/models/spree/promotion/rules/currency.rb +1 -5
- data/app/models/spree/promotion/rules/customer_group.rb +2 -9
- data/app/models/spree/promotion/rules/first_order.rb +0 -4
- data/app/models/spree/promotion/rules/item_total.rb +6 -10
- data/app/models/spree/promotion/rules/market.rb +2 -9
- data/app/models/spree/promotion/rules/one_use_per_user.rb +0 -4
- data/app/models/spree/promotion/rules/option_value.rb +2 -6
- data/app/models/spree/promotion/rules/product.rb +1 -5
- 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 +36 -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 +3 -0
- data/app/models/spree/quantity_rule.rb +1 -1
- data/app/models/spree/refund.rb +41 -18
- data/app/models/spree/return.rb +31 -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 +2 -1
- data/app/models/spree/search_provider/base.rb +4 -0
- data/app/models/spree/seller.rb +10 -2
- data/app/models/spree/seller_payout.rb +8 -0
- data/app/models/spree/seller_requirement.rb +5 -12
- data/app/models/spree/seller_requirement_custom_field.rb +1 -2
- data/app/models/spree/seller_requirement_submission.rb +3 -2
- data/app/models/spree/seller_requirements/accept_terms.rb +2 -3
- data/app/models/spree/seller_transfer.rb +6 -0
- data/app/models/spree/shipping_label.rb +2 -0
- data/app/models/spree/stock/availability_validator.rb +2 -2
- data/app/models/spree/stock/estimator.rb +1 -1
- 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 +3 -1
- data/app/models/spree/stock_location.rb +1 -0
- 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 +6 -2
- data/app/models/spree/store.rb +70 -19
- data/app/models/spree/store_credit.rb +13 -13
- data/app/models/spree/store_credit_event.rb +5 -5
- data/app/models/spree/supplier.rb +1 -0
- data/app/models/spree/tax_category.rb +1 -0
- data/app/models/spree/tax_exemption_certificate.rb +3 -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 +70 -41
- data/app/models/spree/tax_provider/recorded_share.rb +114 -0
- data/app/models/spree/tax_rate.rb +30 -8
- data/app/models/spree/taxon.rb +1 -1
- data/app/models/spree/taxonomy.rb +0 -1
- data/app/models/spree/update_status.rb +25 -0
- data/app/models/spree/variant.rb +10 -12
- data/app/models/spree/variant_media.rb +1 -1
- data/app/models/spree/webhook_delivery.rb +1 -0
- data/app/models/spree/webhook_endpoint.rb +46 -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 +10 -6
- data/app/presenters/spree/csv/price_list_price_presenter.rb +3 -8
- data/app/presenters/spree/csv/product_variant_presenter.rb +59 -20
- data/app/presenters/spree/csv/purchase_order_item_presenter.rb +1 -3
- 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 +22 -8
- 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 +77 -34
- data/app/services/spree/imports/row_processors/purchase_order.rb +13 -13
- data/app/services/spree/locales.rb +43 -10
- 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 +5 -4
- data/app/services/spree/orders/discounts/create.rb +14 -11
- 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/prices/bulk_upsert.rb +32 -25
- 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/seeds/stores.rb +1 -1
- 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 +23 -25
- data/app/services/spree/update_check.rb +160 -0
- data/app/services/spree/uploads/assign_stores.rb +92 -0
- data/app/subscribers/spree/seller_onboarding_subscriber.rb +1 -1
- data/app/validators/spree/attachment_content_type_validator.rb +19 -2
- data/app/validators/spree/locale_codes_validator.rb +22 -0
- 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 +53 -49
- 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/capture.rb +20 -5
- data/app/workflows/spree/payments/process.rb +5 -3
- 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/price_lists/update.rb +4 -4
- 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/create.rb +3 -1
- 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 +7 -7
- 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/create.rb +3 -1
- 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/currency_exponents.json +180 -0
- 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/content_locales.rb +9 -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 +47 -505
- 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/db/migrate/20261009000001_change_money_columns_to_decimal_19_4.rb +116 -0
- data/db/migrate/20261010000001_add_store_id_to_active_storage_blobs.rb +12 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +0 -9
- data/lib/generators/spree/dummy/templates/rails/test.rb +26 -0
- data/lib/spree/checkout/default_requirements.rb +37 -13
- data/lib/spree/core/configuration.rb +19 -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 +72 -165
- data/lib/spree/core/permissions/default_catalog.rb +5 -0
- data/lib/spree/core/preferences/invalid_preferences.rb +18 -0
- data/lib/spree/core/preferences/json_conversion.rb +186 -0
- data/lib/spree/core/preferences/masking.rb +55 -2
- data/lib/spree/core/preferences/preferable.rb +343 -103
- data/lib/spree/core/preferences/preferable_class_methods.rb +188 -136
- data/lib/spree/core/previews/import_preview.rb +10 -0
- data/lib/spree/core/ransack_configuration.rb +13 -2
- data/lib/spree/core/tax/provider_error.rb +37 -0
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +91 -373
- 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/iso_data.rb +7 -0
- data/lib/spree/localized_number.rb +6 -0
- data/lib/spree/migrations.rb +4 -1
- data/lib/spree/money.rb +196 -15
- data/lib/spree/reporting/adapters/base.rb +7 -6
- 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/registry.rb +13 -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/product_factory.rb +9 -0
- 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 +67 -1
- data/lib/spree/uploads.rb +101 -0
- data/lib/tasks/categories_and_collections.rake +3 -3
- data/lib/tasks/core.rake +6 -4
- data/lib/tasks/markets.rake +2 -1
- data/lib/tasks/media.rake +3 -3
- data/lib/tasks/migrate_users_to_customers.rake +23 -18
- data/lib/tasks/money.rake +46 -0
- data/lib/tasks/package_types.rake +1 -1
- data/lib/tasks/preferences_json.rake +101 -0
- data/lib/tasks/seller_sample_data.rake +2 -2
- data/lib/tasks/store_settings.rake +13 -6
- data/lib/tasks/typed_adjustments_migration.rake +1 -1
- data/lib/tasks/uploads.rake +19 -0
- data/spec/fixtures/mailer_views/custom_views_probe_mailer/welcome_email.html.erb +4 -0
- metadata +219 -46
- data/app/jobs/spree/products/touch_categories_job.rb +0 -15
- data/app/jobs/spree/products/touch_taxons_job.rb +0 -13
- 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
data/app/models/spree/store.rb
CHANGED
|
@@ -13,6 +13,7 @@ module Spree
|
|
|
13
13
|
include Spree::Stores::Setup
|
|
14
14
|
include Spree::Stores::Markets
|
|
15
15
|
include Spree::Stores::Channels
|
|
16
|
+
include Spree::Stores::EmailBranding
|
|
16
17
|
include Spree::StoreDataSources
|
|
17
18
|
include Spree::Security::Stores if defined?(Spree::Security::Stores)
|
|
18
19
|
include Spree::UserManagement
|
|
@@ -40,11 +41,16 @@ module Spree
|
|
|
40
41
|
#
|
|
41
42
|
# Preferences
|
|
42
43
|
#
|
|
44
|
+
UNIT_SYSTEMS = %w[metric imperial].freeze
|
|
45
|
+
|
|
43
46
|
# general preferences
|
|
44
|
-
preference :admin_locale, :string
|
|
45
|
-
preference :timezone, :string, default: Time.zone.name
|
|
46
|
-
preference :weight_unit, :string, default: 'lb'
|
|
47
|
-
preference :unit_system, :string, default: 'imperial'
|
|
47
|
+
preference :admin_locale, :string, format: :locale
|
|
48
|
+
preference :timezone, :string, format: :timezone, default: Time.zone.name
|
|
49
|
+
preference :weight_unit, :string, default: 'lb', choices: -> { Spree::Variant::WEIGHT_UNITS }
|
|
50
|
+
preference :unit_system, :string, default: 'imperial', choices: -> { UNIT_SYSTEMS }
|
|
51
|
+
# Anonymous identifier of this installation, kept on the default store
|
|
52
|
+
# (see Spree.install_id). Written by Spree, never by the operator.
|
|
53
|
+
preference :install_id, :string, internal: true, nullable: true
|
|
48
54
|
# email preferences
|
|
49
55
|
preference :send_consumer_transactional_emails, :boolean, default: true
|
|
50
56
|
# Sellers are a different audience from shoppers, with their own reasons to
|
|
@@ -69,7 +75,8 @@ module Spree
|
|
|
69
75
|
# Who pays this store's sellers. Blank means core's record-only provider,
|
|
70
76
|
# so a marketplace that has connected nothing still keeps a correct ledger
|
|
71
77
|
# and settles by hand.
|
|
72
|
-
preference :payout_provider, :string, default: nil
|
|
78
|
+
preference :payout_provider, :string, default: nil,
|
|
79
|
+
parse_on_set: ->(value) { Spree::ApiTyped.class_name_for(Spree.payout_providers, value) }
|
|
73
80
|
# Refused at write time rather than silently falling back at read time: an
|
|
74
81
|
# operator who mistypes a provider would otherwise get a bookkeeping-only
|
|
75
82
|
# ledger and no indication anywhere that their choice was ignored.
|
|
@@ -78,22 +85,22 @@ module Spree
|
|
|
78
85
|
# How often sellers are settled, unless one carries its own schedule.
|
|
79
86
|
# Monthly by default because it is the interval that needs least of an
|
|
80
87
|
# operator paying by hand, which is what the built-in provider expects.
|
|
81
|
-
preference :default_payouts_schedule_interval, :string, default: 'monthly'
|
|
88
|
+
preference :default_payouts_schedule_interval, :string, default: 'monthly', choices: -> { Spree::Seller::PAYOUT_INTERVALS }
|
|
82
89
|
validates :preferred_default_payouts_schedule_interval,
|
|
83
90
|
inclusion: { in: Spree::Seller::PAYOUT_INTERVALS }, allow_blank: true
|
|
84
91
|
# What a seller's balance must reach before a settlement is worth sending;
|
|
85
92
|
# below it the balance carries to the next period. Zero pays whatever is
|
|
86
93
|
# owed, which is right for a provider that moves money for free.
|
|
87
|
-
preference :default_minimum_payout_amount, :
|
|
94
|
+
preference :default_minimum_payout_amount, :money, default: 0
|
|
88
95
|
# Checkout preferences
|
|
89
96
|
# Store-level fallback for the channel-owned `guest_checkout` preference
|
|
90
97
|
# (see Spree::Channel::Gating). Retained so existing accessors keep working.
|
|
91
98
|
preference :guest_checkout, :boolean, default: true
|
|
92
99
|
# Store-level fallback for the channel-owned `storefront_access` posture.
|
|
93
|
-
preference :storefront_access, :string, default: 'public'
|
|
100
|
+
preference :storefront_access, :string, default: 'public', choices: -> { Spree::Channel::Gating::STOREFRONT_ACCESS }
|
|
94
101
|
# Canonical storefront origin used in customer-facing emails and links,
|
|
95
102
|
# e.g. "https://myshop.com" — see #storefront_url for the fallback chain.
|
|
96
|
-
preference :storefront_url, :string
|
|
103
|
+
preference :storefront_url, :string, format: :url
|
|
97
104
|
preference :special_instructions_enabled, :boolean, default: false
|
|
98
105
|
# Advertises a confirm/review step for every checkout, even when no
|
|
99
106
|
# payment method asks for one. Payment methods that require confirmation
|
|
@@ -103,7 +110,8 @@ module Spree
|
|
|
103
110
|
# Store-wide default for when a customer is charged rather than only
|
|
104
111
|
# authorized. A payment method's own capture_method wins when set.
|
|
105
112
|
# See Spree::CaptureMethod.
|
|
106
|
-
preference :capture_method, :string, default: Spree::CaptureMethod::DEFAULT_CAPTURE_METHOD
|
|
113
|
+
preference :capture_method, :string, default: Spree::CaptureMethod::DEFAULT_CAPTURE_METHOD,
|
|
114
|
+
choices: -> { Spree::CaptureMethod::CAPTURE_METHODS }
|
|
107
115
|
preference :stock_reservations_enabled, :boolean, default: true
|
|
108
116
|
# Which address a sale's tax is computed against. Stores selling where tax
|
|
109
117
|
# follows the destination keep this on; billing-address jurisdictions turn
|
|
@@ -115,9 +123,9 @@ module Spree
|
|
|
115
123
|
preference :inventory_provider, :string, default: 'internal'
|
|
116
124
|
# What happens when an external source cannot be reached.
|
|
117
125
|
preference :pricing_provider_failure_policy, :string,
|
|
118
|
-
default: Spree::ProviderFailurePolicy::DEFAULT_PRICING_POLICY
|
|
126
|
+
default: Spree::ProviderFailurePolicy::DEFAULT_PRICING_POLICY, choices: -> { Spree::ProviderFailurePolicy::VALUES }
|
|
119
127
|
preference :inventory_provider_failure_policy, :string,
|
|
120
|
-
default: Spree::ProviderFailurePolicy::DEFAULT_INVENTORY_POLICY
|
|
128
|
+
default: Spree::ProviderFailurePolicy::DEFAULT_INVENTORY_POLICY, choices: -> { Spree::ProviderFailurePolicy::VALUES }
|
|
121
129
|
# Catalog preferences
|
|
122
130
|
preference :track_inventory_levels, :boolean, default: true
|
|
123
131
|
# On-hand quantity at or below which a tracked variant counts as running
|
|
@@ -151,17 +159,34 @@ module Spree
|
|
|
151
159
|
preference :digital_asset_link_expire_time, :integer, default: 300
|
|
152
160
|
# Class name of the Spree::OrderRouting::Strategy::Base subclass that
|
|
153
161
|
# decides which StockLocation fulfills which items.
|
|
154
|
-
preference :order_routing_strategy, :string, default: 'Spree::OrderRouting::Strategy::Rules'
|
|
162
|
+
preference :order_routing_strategy, :string, default: 'Spree::OrderRouting::Strategy::Rules',
|
|
163
|
+
parse_on_set: ->(value) { Spree::ApiTyped.class_name_for(Spree.order_routing.strategies, value) }
|
|
155
164
|
|
|
156
165
|
# Document numbering (docs/plans/6.0-document-numbers.md). The format
|
|
157
166
|
# applies to every numbered document; prefix, suffix and starting value
|
|
158
167
|
# are order-only — other document types keep their code-level prefixes.
|
|
159
168
|
# Changes affect future numbers only; existing numbers are permanent.
|
|
160
|
-
preference :document_number_format, :string, default: 'sequential'
|
|
169
|
+
preference :document_number_format, :string, default: 'sequential', choices: -> { Spree::NumberGenerators::Registry::FORMATS.keys }
|
|
161
170
|
preference :order_number_prefix, :string, default: 'R'
|
|
162
171
|
preference :order_number_suffix, :string, default: ''
|
|
163
172
|
preference :order_number_sequence_start, :integer, default: 1001
|
|
164
173
|
|
|
174
|
+
# The settings the API reads and writes under their plain names.
|
|
175
|
+
exposes_preferences :admin_locale, :timezone, :storefront_url, :weight_unit, :unit_system, :storefront_access, :guest_checkout,
|
|
176
|
+
:always_include_confirm_step, :company_field_enabled, :address_requires_company,
|
|
177
|
+
:address_requires_phone, :capture_method, :track_inventory_levels, :stock_reservations_enabled,
|
|
178
|
+
:low_stock_threshold, :tax_using_ship_address, :track_price_history,
|
|
179
|
+
:show_products_without_price, :disable_sku_validation, :order_routing_strategy,
|
|
180
|
+
:pricing_provider, :inventory_provider, :pricing_provider_failure_policy,
|
|
181
|
+
:inventory_provider_failure_policy, :payout_provider, :default_payouts_schedule_interval,
|
|
182
|
+
:default_minimum_payout_amount, :auto_approve_sellers, :auto_approve_seller_products,
|
|
183
|
+
:send_seller_transactional_emails, :default_commission_tax_rate, :document_number_format,
|
|
184
|
+
:order_number_prefix, :order_number_suffix, :order_number_sequence_start,
|
|
185
|
+
:limit_digital_download_count, :digital_asset_authorized_clicks,
|
|
186
|
+
:limit_digital_download_days, :digital_asset_authorized_days,
|
|
187
|
+
:send_consumer_transactional_emails, :email_accent_color, :email_background_color,
|
|
188
|
+
:email_card_color, :email_text_color, :email_heading_color, :email_font
|
|
189
|
+
|
|
165
190
|
#
|
|
166
191
|
# Associations
|
|
167
192
|
#
|
|
@@ -300,6 +325,8 @@ module Spree
|
|
|
300
325
|
has_many :policies, class_name: 'Spree::Policy', dependent: :destroy, as: :owner
|
|
301
326
|
|
|
302
327
|
has_many :webhook_endpoints, class_name: 'Spree::WebhookEndpoint', dependent: :destroy, inverse_of: :store
|
|
328
|
+
has_many :email_templates, class_name: 'Spree::EmailTemplate', dependent: :destroy, inverse_of: :store
|
|
329
|
+
has_many :email_template_drafts, class_name: 'Spree::EmailTemplateDraft', dependent: :destroy, inverse_of: :store
|
|
303
330
|
has_many :webhook_deliveries, through: :webhook_endpoints, class_name: 'Spree::WebhookDelivery'
|
|
304
331
|
|
|
305
332
|
has_many :channels, class_name: 'Spree::Channel', dependent: :destroy
|
|
@@ -335,6 +362,10 @@ module Spree
|
|
|
335
362
|
validates :preferred_default_commission_tax_rate,
|
|
336
363
|
numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 1 }
|
|
337
364
|
validates :preferred_storefront_access, inclusion: { in: Spree::Channel::Gating::STOREFRONT_ACCESS }
|
|
365
|
+
# Blank falls back to the defaults where they are read, so a store saved
|
|
366
|
+
# with one before these checks existed stays savable.
|
|
367
|
+
validates :preferred_unit_system, inclusion: { in: UNIT_SYSTEMS }, allow_blank: true
|
|
368
|
+
validates :preferred_weight_unit, inclusion: { in: Spree::Variant::WEIGHT_UNITS }, allow_blank: true
|
|
338
369
|
validates :preferred_document_number_format,
|
|
339
370
|
inclusion: { in: Spree::NumberGenerators::Registry::FORMATS.keys }
|
|
340
371
|
validates :preferred_order_number_sequence_start,
|
|
@@ -362,6 +393,7 @@ module Spree
|
|
|
362
393
|
#
|
|
363
394
|
has_one_attached :logo, service: Spree.public_storage_service_name
|
|
364
395
|
has_one_attached :mailer_logo, service: Spree.public_storage_service_name
|
|
396
|
+
signed_id_attachments :logo, :mailer_logo
|
|
365
397
|
|
|
366
398
|
# First-run setup credential (docs/plans/6.0-store-context-and-first-run-setup.md):
|
|
367
399
|
# printed by the installer, only consulted by the setup endpoint while no
|
|
@@ -384,6 +416,7 @@ module Spree
|
|
|
384
416
|
before_validation :set_default_code, on: :create
|
|
385
417
|
before_validation :normalize_preferred_storefront_url
|
|
386
418
|
before_save :ensure_default_exists_and_is_unique
|
|
419
|
+
before_save :set_install_id
|
|
387
420
|
after_create :create_default_policies
|
|
388
421
|
after_create :create_default_delivery_profile
|
|
389
422
|
|
|
@@ -475,14 +508,12 @@ module Spree
|
|
|
475
508
|
#
|
|
476
509
|
# @return [Class]
|
|
477
510
|
def payout_provider_class
|
|
478
|
-
configured = preferred_payout_provider.presence
|
|
479
511
|
# A name no longer in the registry — a typo, or a gem since removed —
|
|
480
512
|
# would otherwise raise inside a subscriber on every fulfillment and stop
|
|
481
513
|
# the ledger recording anything. The built-in provider keeps the books
|
|
482
514
|
# until an operator fixes the setting.
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
(configured || Spree.default_payout_provider.to_s).constantize
|
|
515
|
+
Spree::ApiTyped.registered_class(Spree.payout_providers, preferred_payout_provider) ||
|
|
516
|
+
Spree.default_payout_provider.to_s.constantize
|
|
486
517
|
end
|
|
487
518
|
|
|
488
519
|
def formatted_url
|
|
@@ -521,6 +552,7 @@ module Spree
|
|
|
521
552
|
end
|
|
522
553
|
|
|
523
554
|
# Returns the storefront origin URL for use in customer-facing emails and links.
|
|
555
|
+
# Replaces the plain `storefront_url` reader `exposes_preferences` defines.
|
|
524
556
|
# Uses the `storefront_url` preference when set, then the oldest non-loopback
|
|
525
557
|
# allowed origin (the `http://localhost` origin seeded on install must never
|
|
526
558
|
# leak into customer emails), otherwise falls back to formatted_url.
|
|
@@ -543,6 +575,21 @@ module Spree
|
|
|
543
575
|
allowed_origins.any? { |allowed_origin| allowed_origin.matches?(url) }
|
|
544
576
|
end
|
|
545
577
|
|
|
578
|
+
# The logo emails show: the dedicated mailer logo, else the store logo.
|
|
579
|
+
#
|
|
580
|
+
# @return [ActiveStorage::Attached::One, nil] nil when neither is an image
|
|
581
|
+
def email_logo
|
|
582
|
+
logo = mailer_logo.attached? ? mailer_logo : self.logo
|
|
583
|
+
logo if logo.attached? && logo.variable?
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
# The address customers are told to write to: the support address, else the sender address.
|
|
587
|
+
#
|
|
588
|
+
# @return [String, nil]
|
|
589
|
+
def support_email_address
|
|
590
|
+
customer_support_email.presence || mail_from_address
|
|
591
|
+
end
|
|
592
|
+
|
|
546
593
|
# Returns the states available for checkout for the store
|
|
547
594
|
# @param country [Spree::Country] the country to get the states for
|
|
548
595
|
# @return [Array<Spree::State>]
|
|
@@ -613,7 +660,7 @@ module Spree
|
|
|
613
660
|
@default_stock_location ||= begin
|
|
614
661
|
stock_location_scope = stock_locations.first_party.where(default: true)
|
|
615
662
|
stock_location_scope.first || ActiveRecord::Base.connected_to(role: :writing) do
|
|
616
|
-
stock_location_scope.create(default: true, name:
|
|
663
|
+
stock_location_scope.create(default: true, name: I18n.t('spree.default_stock_location_name'),
|
|
617
664
|
country_code: default_country&.iso)
|
|
618
665
|
end
|
|
619
666
|
end
|
|
@@ -699,6 +746,10 @@ module Spree
|
|
|
699
746
|
I18n.t(key, locale: locale, default: I18n.t(key, locale: :en))
|
|
700
747
|
end
|
|
701
748
|
|
|
749
|
+
def set_install_id
|
|
750
|
+
self.preferred_install_id = SecureRandom.uuid if preferred_install_id.blank?
|
|
751
|
+
end
|
|
752
|
+
|
|
702
753
|
def ensure_default_exists_and_is_unique
|
|
703
754
|
if default
|
|
704
755
|
Spree::Store.where.not(id: id).update_all(default: false)
|
|
@@ -5,6 +5,9 @@ module Spree
|
|
|
5
5
|
include Spree::SingleStoreResource
|
|
6
6
|
include Spree::HasCustomFields
|
|
7
7
|
include Spree::Metadata
|
|
8
|
+
include Spree::CanonicalDecimals
|
|
9
|
+
|
|
10
|
+
canonical_decimals :amount
|
|
8
11
|
|
|
9
12
|
publishes_lifecycle_events
|
|
10
13
|
|
|
@@ -18,7 +21,6 @@ module Spree
|
|
|
18
21
|
AUTHORIZE_ACTION = 'authorize'.freeze
|
|
19
22
|
ALLOCATION_ACTION = 'allocation'.freeze
|
|
20
23
|
|
|
21
|
-
belongs_to :store, class_name: 'Spree::Store'
|
|
22
24
|
# A gift card applied to a guest cart issues store credit with no customer
|
|
23
25
|
# to attach it to.
|
|
24
26
|
belongs_to :customer, class_name: "::#{Spree.customer_class}", optional: true
|
|
@@ -106,13 +108,11 @@ module Spree
|
|
|
106
108
|
extend Spree::DisplayMoney
|
|
107
109
|
money_methods :amount, :amount_used, :amount_remaining, :amount_authorized
|
|
108
110
|
|
|
109
|
-
def amount=(amount)
|
|
110
|
-
self[:amount] = Spree::LocalizedNumber.parse(amount)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
111
|
self.whitelisted_ransackable_attributes = %w[customer_id created_by_id amount currency memo]
|
|
112
|
+
search_by :memo
|
|
114
113
|
self.whitelisted_ransackable_associations = %w[customer created_by]
|
|
115
114
|
self.whitelisted_ransackable_scopes = %w[outstanding from_gift_card]
|
|
115
|
+
self.ransackable_scope_types = %w[outstanding from_gift_card].index_with('boolean')
|
|
116
116
|
# Staff notes and who issued the credit are back-office data.
|
|
117
117
|
self.private_ransackable_attributes = { store: %w[memo created_by_id] }
|
|
118
118
|
|
|
@@ -146,16 +146,16 @@ module Spree
|
|
|
146
146
|
)
|
|
147
147
|
authorization_code
|
|
148
148
|
else
|
|
149
|
-
errors.add(:base, :insufficient_authorized_amount, message:
|
|
149
|
+
errors.add(:base, :insufficient_authorized_amount, message: I18n.t('spree.store_credit_payment_method.insufficient_authorized_amount'))
|
|
150
150
|
false
|
|
151
151
|
end
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
def validate_authorization(amount, order_currency)
|
|
155
155
|
if BigDecimal(amount_remaining, 3) < BigDecimal(amount, 3)
|
|
156
|
-
errors.add(:base, :insufficient_funds, message:
|
|
156
|
+
errors.add(:base, :insufficient_funds, message: I18n.t('spree.store_credit_payment_method.insufficient_funds'))
|
|
157
157
|
elsif currency != order_currency
|
|
158
|
-
errors.add(:base, :currency_mismatch, message:
|
|
158
|
+
errors.add(:base, :currency_mismatch, message: I18n.t('spree.store_credit_payment_method.currency_mismatch'))
|
|
159
159
|
end
|
|
160
160
|
errors.blank?
|
|
161
161
|
end
|
|
@@ -165,7 +165,7 @@ module Spree
|
|
|
165
165
|
|
|
166
166
|
if amount <= amount_authorized
|
|
167
167
|
if currency != order_currency
|
|
168
|
-
errors.add(:base, :currency_mismatch, message:
|
|
168
|
+
errors.add(:base, :currency_mismatch, message: I18n.t('spree.store_credit_payment_method.currency_mismatch'))
|
|
169
169
|
false
|
|
170
170
|
else
|
|
171
171
|
update!(
|
|
@@ -179,7 +179,7 @@ module Spree
|
|
|
179
179
|
authorization_code
|
|
180
180
|
end
|
|
181
181
|
else
|
|
182
|
-
errors.add(:base, :insufficient_authorized_amount, message:
|
|
182
|
+
errors.add(:base, :insufficient_authorized_amount, message: I18n.t('spree.store_credit_payment_method.insufficient_authorized_amount'))
|
|
183
183
|
false
|
|
184
184
|
end
|
|
185
185
|
end
|
|
@@ -196,7 +196,7 @@ module Spree
|
|
|
196
196
|
true
|
|
197
197
|
else
|
|
198
198
|
errors.add(:base, :unable_to_void, auth_code: authorization_code,
|
|
199
|
-
message:
|
|
199
|
+
message: I18n.t('spree.store_credit_payment_method.unable_to_void', auth_code: authorization_code))
|
|
200
200
|
false
|
|
201
201
|
end
|
|
202
202
|
end
|
|
@@ -206,7 +206,7 @@ module Spree
|
|
|
206
206
|
capture_event = store_credit_events.find_by(action: CAPTURE_ACTION, authorization_code: authorization_code)
|
|
207
207
|
|
|
208
208
|
if currency != order_currency # sanity check to make sure the order currency hasn't changed since the auth
|
|
209
|
-
errors.add(:base, :currency_mismatch, message:
|
|
209
|
+
errors.add(:base, :currency_mismatch, message: I18n.t('spree.store_credit_payment_method.currency_mismatch'))
|
|
210
210
|
false
|
|
211
211
|
elsif capture_event && amount <= capture_event.amount
|
|
212
212
|
action_attributes = {
|
|
@@ -219,7 +219,7 @@ module Spree
|
|
|
219
219
|
true
|
|
220
220
|
else
|
|
221
221
|
errors.add(:base, :unable_to_credit, auth_code: authorization_code,
|
|
222
|
-
message:
|
|
222
|
+
message: I18n.t('spree.store_credit_payment_method.unable_to_credit', auth_code: authorization_code))
|
|
223
223
|
false
|
|
224
224
|
end
|
|
225
225
|
end
|
|
@@ -24,15 +24,15 @@ module Spree
|
|
|
24
24
|
def display_action
|
|
25
25
|
case action
|
|
26
26
|
when Spree::StoreCredit::CAPTURE_ACTION
|
|
27
|
-
|
|
27
|
+
I18n.t('spree.store_credit.captured')
|
|
28
28
|
when Spree::StoreCredit::AUTHORIZE_ACTION
|
|
29
|
-
|
|
29
|
+
I18n.t('spree.store_credit.authorized')
|
|
30
30
|
when Spree::StoreCredit::ALLOCATION_ACTION
|
|
31
|
-
|
|
31
|
+
I18n.t('spree.store_credit.allocated')
|
|
32
32
|
when Spree::StoreCredit::ELIGIBLE_ACTION
|
|
33
|
-
|
|
33
|
+
I18n.t('spree.store_credit.eligible')
|
|
34
34
|
when Spree::StoreCredit::VOID_ACTION, Spree::StoreCredit::CREDIT_ACTION
|
|
35
|
-
|
|
35
|
+
I18n.t('spree.store_credit.credit')
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
@@ -32,6 +32,7 @@ module Spree
|
|
|
32
32
|
normalizes :name, :contact_name, :phone, with: ->(value) { value.strip }
|
|
33
33
|
|
|
34
34
|
self.whitelisted_ransackable_attributes = %w[name contact_name email phone city country_code created_at]
|
|
35
|
+
search_by :name, :contact_name, :email
|
|
35
36
|
|
|
36
37
|
# The postal address, built from this row's own columns the way
|
|
37
38
|
# {Spree::StockLocation#address} does. Unsaved, and blank when nothing has
|
|
@@ -9,6 +9,8 @@ module Spree
|
|
|
9
9
|
# valid in one state and not the next is the ordinary case, and the country
|
|
10
10
|
# and state columns say exactly where it holds.
|
|
11
11
|
class TaxExemptionCertificate < Spree.base_class
|
|
12
|
+
publishes_event :verified
|
|
13
|
+
|
|
12
14
|
has_prefix_id :cert
|
|
13
15
|
|
|
14
16
|
include Spree::HasStatus
|
|
@@ -25,6 +27,7 @@ module Spree
|
|
|
25
27
|
# Confidential, so the private service rather than the public one that
|
|
26
28
|
# serves product images.
|
|
27
29
|
has_one_attached :document, service: Spree.private_storage_service_name
|
|
30
|
+
signed_id_attachments :document
|
|
28
31
|
|
|
29
32
|
validates :certificate_number, :reason_code, presence: true
|
|
30
33
|
# Certificates exist only on legal-entity nodes — a division's purchases
|
|
@@ -36,6 +36,8 @@ module Spree
|
|
|
36
36
|
# directly. It is a habit of the gems that use it, not a rule this model
|
|
37
37
|
# applies.
|
|
38
38
|
class TaxIdentifier < Spree.base_class
|
|
39
|
+
publishes_event :number_changed
|
|
40
|
+
|
|
39
41
|
has_prefix_id :txi
|
|
40
42
|
|
|
41
43
|
# Statuses the platform records rather than the buyer chooses: nil means
|
|
@@ -150,7 +152,7 @@ module Spree
|
|
|
150
152
|
# The kind as the dashboard shows it, falling back to the raw key so an
|
|
151
153
|
# extension's kind reads as itself rather than blank.
|
|
152
154
|
def kind_label
|
|
153
|
-
|
|
155
|
+
I18n.t("spree.tax_identifier_kinds.#{kind}", default: kind.to_s.humanize)
|
|
154
156
|
end
|
|
155
157
|
|
|
156
158
|
# The class registered for this kind, or nil when nothing is registered and
|
|
@@ -4,6 +4,11 @@ module Spree
|
|
|
4
4
|
# per estimate. Snapshot columns (+rate+, +label+, +provider_id+) keep rows
|
|
5
5
|
# self-describing after a TaxRate is deleted or when an external provider
|
|
6
6
|
# computed them.
|
|
7
|
+
#
|
|
8
|
+
# Rows on a return, claim or exchange line are post-sale: the tax given back
|
|
9
|
+
# (+credit+), or the tax on an exchange's replacement. They are owned by the
|
|
10
|
+
# order like every other row but never count towards its totals — the order
|
|
11
|
+
# reads only {.sale} rows.
|
|
7
12
|
class TaxLine < Spree.base_class
|
|
8
13
|
include Spree::TypedAdjustmentLine
|
|
9
14
|
|
|
@@ -35,6 +40,13 @@ module Spree
|
|
|
35
40
|
belongs_to :line_item, class_name: 'Spree::LineItem', optional: true
|
|
36
41
|
belongs_to :fulfillment, class_name: 'Spree::Fulfillment', optional: true
|
|
37
42
|
belongs_to :fee, class_name: 'Spree::Fee', optional: true
|
|
43
|
+
belongs_to :return_line_item, class_name: 'Spree::ReturnLineItem', optional: true
|
|
44
|
+
belongs_to :claim_line_item, class_name: 'Spree::ClaimLineItem', optional: true
|
|
45
|
+
belongs_to :exchange_line_item, class_name: 'Spree::ExchangeLineItem', optional: true
|
|
46
|
+
|
|
47
|
+
# The sale row a credit gives back — what caps repeated credits against one
|
|
48
|
+
# line, and the original a credit note refers to.
|
|
49
|
+
belongs_to :original_tax_line, class_name: 'Spree::TaxLine', optional: true
|
|
38
50
|
|
|
39
51
|
# Tax included in price vs additional. Per-row (mixed regimes on one order).
|
|
40
52
|
attribute :included, :boolean, default: false
|
|
@@ -46,20 +58,50 @@ module Spree
|
|
|
46
58
|
inclusion: { in: ->(tax_line) { tax_line.class.taxability_reasons } },
|
|
47
59
|
allow_nil: true
|
|
48
60
|
validate :exactly_one_adjustable
|
|
61
|
+
validate :post_sale_owned_by_order
|
|
49
62
|
|
|
50
63
|
# Tax reporting is the reason the treatment columns exist — "which country's
|
|
51
64
|
# tax was this, and which sales were reverse-charged" has to be answerable.
|
|
52
65
|
self.whitelisted_ransackable_attributes = %w[taxability_reason country_code state_code included provider_id]
|
|
53
66
|
|
|
67
|
+
POST_SALE_KEYS = %i[return_line_item_id claim_line_item_id exchange_line_item_id].freeze
|
|
68
|
+
|
|
69
|
+
ADJUSTABLE_KEYS = {
|
|
70
|
+
'Spree::LineItem' => :line_item_id,
|
|
71
|
+
'Spree::Fulfillment' => :fulfillment_id,
|
|
72
|
+
'Spree::Fee' => :fee_id,
|
|
73
|
+
'Spree::ReturnLineItem' => :return_line_item_id,
|
|
74
|
+
'Spree::ClaimLineItem' => :claim_line_item_id,
|
|
75
|
+
'Spree::ExchangeLineItem' => :exchange_line_item_id
|
|
76
|
+
}.freeze
|
|
77
|
+
|
|
54
78
|
scope :included_in_price, -> { where(included: true) }
|
|
55
79
|
scope :additional, -> { where(included: false) }
|
|
56
80
|
scope :for_line_items, -> { where.not(line_item_id: nil) }
|
|
57
81
|
scope :for_fulfillments, -> { where.not(fulfillment_id: nil) }
|
|
58
82
|
scope :for_fees, -> { where.not(fee_id: nil) }
|
|
83
|
+
scope :sale, -> { where(POST_SALE_KEYS.index_with(nil)) }
|
|
84
|
+
scope :post_sale, -> { where.not(POST_SALE_KEYS.index_with(nil)) }
|
|
85
|
+
scope :credits, -> { where(credit: true) }
|
|
86
|
+
scope :charges, -> { where(credit: false) }
|
|
87
|
+
|
|
88
|
+
# The foreign key a row uses to point at an item of this class.
|
|
89
|
+
#
|
|
90
|
+
# @param klass [Class]
|
|
91
|
+
# @return [Symbol]
|
|
92
|
+
# @raise [ArgumentError] for a class that is not taxed
|
|
93
|
+
def self.adjustable_key_for(klass)
|
|
94
|
+
ADJUSTABLE_KEYS.fetch(klass.name) { raise ArgumentError, "#{klass} is not taxable" }
|
|
95
|
+
end
|
|
59
96
|
|
|
60
|
-
# @return [Spree::LineItem, Spree::Fulfillment, Spree::Fee,
|
|
97
|
+
# @return [Spree::LineItem, Spree::Fulfillment, Spree::Fee, Spree::ReturnLineItem,
|
|
98
|
+
# Spree::ClaimLineItem, Spree::ExchangeLineItem, nil]
|
|
61
99
|
def adjustable
|
|
62
|
-
line_item || fulfillment || fee
|
|
100
|
+
line_item || fulfillment || fee || return_line_item || claim_line_item || exchange_line_item
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def post_sale?
|
|
104
|
+
POST_SALE_KEYS.any? { |key| self[key].present? }
|
|
63
105
|
end
|
|
64
106
|
|
|
65
107
|
def included?
|
|
@@ -73,7 +115,15 @@ module Spree
|
|
|
73
115
|
private
|
|
74
116
|
|
|
75
117
|
def exactly_one_adjustable
|
|
76
|
-
|
|
118
|
+
adjustables = [line_item, fulfillment, fee, return_line_item, claim_line_item, exchange_line_item]
|
|
119
|
+
errors.add(:base, :exactly_one_adjustable, message: I18n.t('spree.errors.messages.exactly_one_adjustable')) unless adjustables.compact.one?
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Returns, claims and exchanges only exist on placed orders.
|
|
123
|
+
def post_sale_owned_by_order
|
|
124
|
+
return unless post_sale? && order.nil?
|
|
125
|
+
|
|
126
|
+
errors.add(:base, :exactly_one_of_cart_or_order, message: I18n.t('spree.errors.messages.exactly_one_of_cart_or_order'))
|
|
77
127
|
end
|
|
78
128
|
end
|
|
79
129
|
end
|
|
@@ -3,12 +3,16 @@ module Spree
|
|
|
3
3
|
# Contract for tax providers — the only sanctioned writers of
|
|
4
4
|
# {Spree::TaxLine} rows. +estimate+ must use replace-all set semantics per
|
|
5
5
|
# target item (delete the item's stale lines, insert fresh ones); that is
|
|
6
|
-
# what keeps tax correct after address or item changes
|
|
7
|
-
#
|
|
6
|
+
# what keeps tax correct after address or item changes, and the post-sale
|
|
7
|
+
# +estimate_refund+ / +estimate_replacement+ follow the same rule.
|
|
8
|
+
# Commit/void/refund/commit_replacement are lifecycle no-ops for providers
|
|
9
|
+
# without a remote ledger.
|
|
8
10
|
#
|
|
9
11
|
# Providers are stateless and constructed without arguments, so anything
|
|
10
12
|
# request-specific arrives as an argument rather than through the instance.
|
|
11
13
|
class Base
|
|
14
|
+
extend Spree::ApiTyped
|
|
15
|
+
|
|
12
16
|
# Domains this provider cannot handle, so a merchant is warned when
|
|
13
17
|
# pairing it with a market instead of silently under-collecting. Declared
|
|
14
18
|
# on the class because core reads it while presenting the choice, before
|
|
@@ -47,8 +51,8 @@ module Spree
|
|
|
47
51
|
unsupported_capabilities.map do |capability|
|
|
48
52
|
{
|
|
49
53
|
key: capability.to_s,
|
|
50
|
-
label:
|
|
51
|
-
description:
|
|
54
|
+
label: I18n.t("spree.tax_capabilities.#{capability}.label", default: capability.to_s.humanize),
|
|
55
|
+
description: I18n.t("spree.tax_capabilities.#{capability}.description", default: nil)
|
|
52
56
|
}.compact
|
|
53
57
|
end
|
|
54
58
|
end
|
|
@@ -61,7 +65,7 @@ module Spree
|
|
|
61
65
|
# @return [Hash]
|
|
62
66
|
def self.to_api_hash(store)
|
|
63
67
|
{
|
|
64
|
-
id:
|
|
68
|
+
id: api_type,
|
|
65
69
|
name: display_name,
|
|
66
70
|
available: available_for_store?(store),
|
|
67
71
|
unsupported_capabilities: unsupported_capability_details,
|
|
@@ -128,19 +132,72 @@ module Spree
|
|
|
128
132
|
nil
|
|
129
133
|
end
|
|
130
134
|
|
|
135
|
+
# Works out the tax given back on lines of a return, claim or exchange,
|
|
136
|
+
# and writes it as credit TaxLine rows on them. The customer is refunded
|
|
137
|
+
# exactly what these rows hold, so this — not +refund+ — decides the
|
|
138
|
+
# figure.
|
|
139
|
+
#
|
|
140
|
+
# Each item credits its +credited_quantity+, and zero means no rows.
|
|
141
|
+
# Replace-all per item, as +estimate+: the rows are rewritten when the
|
|
142
|
+
# warehouse counts what arrived and again when the money goes back.
|
|
143
|
+
#
|
|
144
|
+
# A provider may quote the credit, for example at the original
|
|
145
|
+
# +tax_date+, or give back the recorded share of what the sale charged —
|
|
146
|
+
# {Spree::TaxProvider::RecordedShare}, which Internal uses. Either way
|
|
147
|
+
# it answers in the same rows.
|
|
148
|
+
#
|
|
149
|
+
# @param order [Spree::Order] a placed order
|
|
150
|
+
# @param items [Array<Spree::ReturnLineItem, Spree::ClaimLineItem, Spree::ExchangeLineItem>]
|
|
151
|
+
# @param amounts [Hash{Object => BigDecimal}, nil] the money refunded per
|
|
152
|
+
# item when it is less than the item's worth — a restocking fee, a
|
|
153
|
+
# part refund. Tax is then credited in the same proportion. Nil
|
|
154
|
+
# credits every item's full worth.
|
|
155
|
+
# @param tax_date [Time, nil] the date whose rates apply; nil = order.completed_at
|
|
156
|
+
# @return [void]
|
|
157
|
+
# @raise [Spree::Tax::ProviderError] when the credit could not be worked out
|
|
158
|
+
def estimate_refund(order, items, amounts: nil, tax_date: nil)
|
|
159
|
+
raise NotImplementedError, "Please implement 'estimate_refund' in your tax provider: #{self.class.name}"
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Taxes the replacement an exchange sends out, as a new sale, and writes
|
|
163
|
+
# it as charge TaxLine rows on the exchange lines. Never touches the
|
|
164
|
+
# order's own rows, which stay as the sale was placed. Replace-all per
|
|
165
|
+
# item; each item is taxed on its +taxable_basis+ under its
|
|
166
|
+
# +tax_category_id+, and one whose +credited_quantity+ is zero ships
|
|
167
|
+
# nothing and ends with no rows.
|
|
168
|
+
#
|
|
169
|
+
# @param order [Spree::Order] a placed order
|
|
170
|
+
# @param items [Array<Spree::ExchangeLineItem>]
|
|
171
|
+
# @param tax_date [Time, nil] date whose rates apply; nil = now
|
|
172
|
+
# @param tax_identifier [Spree::TaxIdentifier, nil] the order's frozen registration
|
|
173
|
+
# @param exemptions [Array] exemption evidence to apply
|
|
174
|
+
# @return [void]
|
|
175
|
+
# @raise [Spree::Tax::ProviderError] when the tax could not be worked out
|
|
176
|
+
def estimate_replacement(order, items, tax_date: nil, tax_identifier: nil, exemptions: [])
|
|
177
|
+
raise NotImplementedError, "Please implement 'estimate_replacement' in your tax provider: #{self.class.name}"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Files an exchange's replacement as a sale. Called once the exchange is
|
|
181
|
+
# fulfilled; must be idempotent, keyed on the exchange. No-op for a
|
|
182
|
+
# provider without a remote ledger.
|
|
183
|
+
#
|
|
184
|
+
# @param order [Spree::Order]
|
|
185
|
+
# @param items [Array<Spree::ExchangeLineItem>]
|
|
186
|
+
# @return [void]
|
|
187
|
+
def commit_replacement(order, items); end
|
|
188
|
+
|
|
131
189
|
# Reports a partial credit against the committed document, keyed to the
|
|
132
|
-
# original transaction rather than voiding and re-committing it.
|
|
190
|
+
# original transaction rather than voiding and re-committing it. Called
|
|
191
|
+
# after the money has moved.
|
|
133
192
|
#
|
|
134
|
-
#
|
|
135
|
-
#
|
|
136
|
-
#
|
|
137
|
-
#
|
|
138
|
-
#
|
|
139
|
-
# return is marked refunded once, so nothing later corrects it. Where the
|
|
140
|
-
# amount is short, allocate proportionally.
|
|
193
|
+
# By then each item's credit rows hold what went back (see
|
|
194
|
+
# +estimate_refund+), and a provider must credit no more than they do:
|
|
195
|
+
# the customer was repaid that tax and no more. +amount+ is the money
|
|
196
|
+
# refunded, which may be less than the items are worth when an admin kept
|
|
197
|
+
# a restocking fee or refunded a goodwill figure of their own.
|
|
141
198
|
#
|
|
142
199
|
# @param order [Spree::Order]
|
|
143
|
-
# @param return_items [Array<Spree::ReturnLineItem>]
|
|
200
|
+
# @param return_items [Array<Spree::ReturnLineItem, Spree::ClaimLineItem, Spree::ExchangeLineItem>]
|
|
144
201
|
# @param amount [BigDecimal, nil] the refund issued; nil = the lines' full worth
|
|
145
202
|
# @param tax_date [Time, nil] the original supply date; nil = order.completed_at
|
|
146
203
|
# @return [void]
|