spree_core 6.0.0.beta4 → 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
|
@@ -97,7 +97,7 @@ module Spree
|
|
|
97
97
|
index.zero? ? order.status : nil,
|
|
98
98
|
index.zero? ? order.currency : nil,
|
|
99
99
|
index.zero? ? order.item_total.to_f : nil,
|
|
100
|
-
index.zero? ? order.
|
|
100
|
+
index.zero? ? order.delivery_total.to_f : nil,
|
|
101
101
|
index.zero? ? order.tax_total.to_f : nil,
|
|
102
102
|
index.zero? ? order.included_tax_total.positive? : nil,
|
|
103
103
|
index.zero? ? (order.discount_total.negative? || line_item.discount_total.negative?) : nil,
|
|
@@ -30,6 +30,7 @@ module Spree
|
|
|
30
30
|
'track_inventory',
|
|
31
31
|
'inventory_count',
|
|
32
32
|
'inventory_backorderable',
|
|
33
|
+
'stock_location',
|
|
33
34
|
'tax_category',
|
|
34
35
|
'product_type',
|
|
35
36
|
'image1_src',
|
|
@@ -46,7 +47,13 @@ module Spree
|
|
|
46
47
|
'category3',
|
|
47
48
|
].freeze
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
# @param default_stock_location [Spree::StockLocation, nil] where the full row's
|
|
51
|
+
# inventory columns read from, blank when the variant has no stock
|
|
52
|
+
# there; the store's default when nil
|
|
53
|
+
# @param stock_level [Spree::StockLevel, nil] turns the row into a
|
|
54
|
+
# stock-only row for that level's location
|
|
55
|
+
def initialize(product, variant, index = 0, properties = [], categories = [], store = nil, custom_fields = [], currency = nil,
|
|
56
|
+
default_stock_location: nil, stock_level: nil)
|
|
50
57
|
@product = product
|
|
51
58
|
@variant = variant
|
|
52
59
|
@index = index
|
|
@@ -56,9 +63,12 @@ module Spree
|
|
|
56
63
|
@currency = currency || @store.default_currency
|
|
57
64
|
@price_only = @currency != @store.default_currency
|
|
58
65
|
@custom_fields = custom_fields
|
|
66
|
+
@default_stock_location = default_stock_location
|
|
67
|
+
@stock_level = stock_level
|
|
59
68
|
end
|
|
60
69
|
|
|
61
|
-
attr_accessor :product, :variant, :index, :properties, :categories, :store, :currency, :price_only, :custom_fields
|
|
70
|
+
attr_accessor :product, :variant, :index, :properties, :categories, :store, :currency, :price_only, :custom_fields,
|
|
71
|
+
:default_stock_location, :stock_level
|
|
62
72
|
|
|
63
73
|
##
|
|
64
74
|
# Generates an array representing a CSV row of product variant data.
|
|
@@ -73,8 +83,7 @@ module Spree
|
|
|
73
83
|
# @return [Array] An array containing the combined product and variant CSV data.
|
|
74
84
|
def call
|
|
75
85
|
return price_only_row if price_only
|
|
76
|
-
|
|
77
|
-
total_on_hand = variant.total_on_hand
|
|
86
|
+
return stock_only_row if stock_level
|
|
78
87
|
|
|
79
88
|
csv = [
|
|
80
89
|
product.id,
|
|
@@ -104,19 +113,23 @@ module Spree
|
|
|
104
113
|
publication_available_on&.strftime('%Y-%m-%d %H:%M:%S'),
|
|
105
114
|
(variant.discontinue_on || publication_discontinue_on)&.strftime('%Y-%m-%d %H:%M:%S'),
|
|
106
115
|
variant.track_inventory?,
|
|
107
|
-
|
|
108
|
-
|
|
116
|
+
# The shelf count at the one location the import writes this row
|
|
117
|
+
# back to, not what is left to sell: that would drop every unit held
|
|
118
|
+
# by a cart or promised to an order on each round trip.
|
|
119
|
+
variant.should_track_inventory? ? default_stock_level&.count_on_hand : '∞',
|
|
120
|
+
default_stock_level&.backorderable,
|
|
121
|
+
nil,
|
|
109
122
|
variant.tax_category&.name,
|
|
110
123
|
product.product_type&.name,
|
|
111
124
|
spree_image_url(variant.images[0], image_url_options),
|
|
112
125
|
spree_image_url(variant.images[1], image_url_options),
|
|
113
126
|
spree_image_url(variant.images[2], image_url_options),
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
127
|
+
option_type(0)&.label,
|
|
128
|
+
option_value(option_type(0)),
|
|
129
|
+
option_type(1)&.label,
|
|
130
|
+
option_value(option_type(1)),
|
|
131
|
+
option_type(2)&.label,
|
|
132
|
+
option_value(option_type(2))
|
|
120
133
|
]
|
|
121
134
|
|
|
122
135
|
if index.zero?
|
|
@@ -168,6 +181,23 @@ module Spree
|
|
|
168
181
|
csv
|
|
169
182
|
end
|
|
170
183
|
|
|
184
|
+
def stock_only_row
|
|
185
|
+
csv = Array.new(CSV_HEADERS.size)
|
|
186
|
+
csv[CSV_HEADERS.index('sku')] = variant.sku
|
|
187
|
+
csv[CSV_HEADERS.index('slug')] = product.slug
|
|
188
|
+
csv[CSV_HEADERS.index('inventory_count')] = stock_level.count_on_hand
|
|
189
|
+
csv[CSV_HEADERS.index('inventory_backorderable')] = stock_level.backorderable
|
|
190
|
+
csv[CSV_HEADERS.index('stock_location')] = stock_level.stock_location.name
|
|
191
|
+
csv
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def default_stock_level
|
|
195
|
+
return @default_stock_level if defined?(@default_stock_level)
|
|
196
|
+
|
|
197
|
+
location = default_stock_location || store.default_stock_location
|
|
198
|
+
@default_stock_level = variant.stock_levels.find { |level| level.stock_location_id == location.id }
|
|
199
|
+
end
|
|
200
|
+
|
|
171
201
|
def image_url_options
|
|
172
202
|
{ variant: :xlarge }
|
|
173
203
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Emails
|
|
3
|
+
# Base for the serializers that feed email templates. Emails read plain
|
|
4
|
+
# JSON, the same data a renderer outside Ruby would receive, never models.
|
|
5
|
+
# Never expose a token here: URLs carrying secrets are built by the mailer.
|
|
6
|
+
class BaseSerializer
|
|
7
|
+
include Alba::Resource
|
|
8
|
+
|
|
9
|
+
attribute :id do |object|
|
|
10
|
+
object.prefixed_id if object.respond_to?(:prefixed_id)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Emails
|
|
3
|
+
class ExportSerializer < BaseSerializer
|
|
4
|
+
attributes :number, :results_url
|
|
5
|
+
|
|
6
|
+
attribute :filename do |export|
|
|
7
|
+
export.attachment.filename.to_s if export.attachment.attached?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
one :user, resource: Spree::Emails::UserSerializer
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Emails
|
|
3
|
+
class ImportSerializer < BaseSerializer
|
|
4
|
+
attributes :number
|
|
5
|
+
|
|
6
|
+
attribute :results_url, &:results_page_url
|
|
7
|
+
|
|
8
|
+
attribute :completed_count do |import|
|
|
9
|
+
import.rows_status_counts['completed'].to_i
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attribute :failed_count do |import|
|
|
13
|
+
import.rows_status_counts['failed'].to_i
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
one :user, resource: Spree::Emails::UserSerializer
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Emails
|
|
3
|
+
class InvitationSerializer < BaseSerializer
|
|
4
|
+
attributes :email
|
|
5
|
+
|
|
6
|
+
attribute :resource_name do |invitation|
|
|
7
|
+
invitation.resource.try(:name)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
attribute :inviter_name do |invitation|
|
|
11
|
+
invitation.inviter.try(:full_name).presence || invitation.inviter.try(:name)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
attribute :inviter_first_name do |invitation|
|
|
15
|
+
invitation.inviter.try(:first_name)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Nil until the invitation is accepted by someone with an account.
|
|
19
|
+
attribute :invitee_name do |invitation|
|
|
20
|
+
invitation.invitee.try(:full_name).presence || invitation.invitee.try(:name)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
attribute :invitee_first_name do |invitation|
|
|
24
|
+
invitation.invitee.try(:first_name)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Emails
|
|
3
|
+
class StoreSerializer < BaseSerializer
|
|
4
|
+
include Spree::ImagesHelper
|
|
5
|
+
|
|
6
|
+
LOGO_HEIGHT = 32
|
|
7
|
+
|
|
8
|
+
attributes :name, :address, :mail_from_address, :default_currency, :default_locale
|
|
9
|
+
|
|
10
|
+
attribute :url, &:storefront_url
|
|
11
|
+
|
|
12
|
+
attribute :support_email, &:support_email_address
|
|
13
|
+
|
|
14
|
+
attribute :logo_url do |store|
|
|
15
|
+
spree_image_url(store.email_logo, height: LOGO_HEIGHT)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# The width the logo shows at, from its proportions. Nil until the file
|
|
19
|
+
# has been analyzed, when the layout lets the width follow the height.
|
|
20
|
+
attribute :logo_width do |store|
|
|
21
|
+
width, height = store.email_logo&.metadata.to_h.values_at('width', 'height').map(&:to_f)
|
|
22
|
+
(LOGO_HEIGHT * width / height).round if height.to_f.positive?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Colors and font (see Spree::Emails::Branding).
|
|
26
|
+
attribute :branding do |store|
|
|
27
|
+
store.email_branding(params[:branding] || {}).to_h
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Emails
|
|
3
|
+
# Staff and seller-panel users, as back-office emails address them.
|
|
4
|
+
class UserSerializer < BaseSerializer
|
|
5
|
+
attributes :email, :first_name, :last_name
|
|
6
|
+
|
|
7
|
+
attribute :name do |user|
|
|
8
|
+
user.try(:full_name).presence || user.try(:name).presence
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Emails
|
|
3
|
+
# Never add the signing secret: an email must not carry it.
|
|
4
|
+
class WebhookEndpointSerializer < BaseSerializer
|
|
5
|
+
attributes :name, :url, :disabled_reason
|
|
6
|
+
|
|
7
|
+
attribute :display_name do |endpoint|
|
|
8
|
+
endpoint.name.presence || endpoint.url
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attribute :disabled_at do |endpoint|
|
|
12
|
+
endpoint.disabled_at&.iso8601
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -9,8 +9,14 @@ module Spree
|
|
|
9
9
|
store = @params.delete(:store)
|
|
10
10
|
return failure(:store_is_required) if store.nil?
|
|
11
11
|
|
|
12
|
+
customer = @params.delete(:customer)
|
|
13
|
+
if @params.key?(:user)
|
|
14
|
+
Spree::Deprecation.warn('Passing user: to Spree::Carts::Create is deprecated and will be removed in Spree 6.1. Pass customer: instead.')
|
|
15
|
+
customer ||= @params.delete(:user)
|
|
16
|
+
end
|
|
17
|
+
|
|
12
18
|
cart = store.carts.create!(
|
|
13
|
-
|
|
19
|
+
customer: customer,
|
|
14
20
|
market: @params.delete(:market) || Spree::Current.market,
|
|
15
21
|
channel: @params.delete(:channel) || Spree::Current.channel,
|
|
16
22
|
currency: @params.delete(:currency) || store.default_currency,
|
|
@@ -19,7 +25,7 @@ module Spree
|
|
|
19
25
|
|
|
20
26
|
# Delegate all attribute/address/item processing to Carts::Update
|
|
21
27
|
if @params.present?
|
|
22
|
-
result = Spree
|
|
28
|
+
result = Spree.carts_update_service.call(cart: cart, params: @params)
|
|
23
29
|
return result if result.failure?
|
|
24
30
|
end
|
|
25
31
|
|
|
@@ -20,7 +20,7 @@ module Spree
|
|
|
20
20
|
private
|
|
21
21
|
|
|
22
22
|
def check_if_can_be_destroyed(cart:)
|
|
23
|
-
return failure(false,
|
|
23
|
+
return failure(false, I18n.t('spree.cannot_be_destroyed')) unless cart&.can_be_deleted?
|
|
24
24
|
|
|
25
25
|
success(cart: cart)
|
|
26
26
|
end
|
|
@@ -62,7 +62,7 @@ module Spree
|
|
|
62
62
|
def destroy_order(cart:)
|
|
63
63
|
destroyed_result = cart.destroy
|
|
64
64
|
|
|
65
|
-
return failure(false,
|
|
65
|
+
return failure(false, I18n.t('spree.cannot_be_destroyed')) unless destroyed_result.present?
|
|
66
66
|
|
|
67
67
|
success(cart)
|
|
68
68
|
end
|
|
@@ -72,7 +72,7 @@ module Spree
|
|
|
72
72
|
def valid_status?(line_item)
|
|
73
73
|
product = line_item.product
|
|
74
74
|
if !product.active? || product.deleted? || product.discontinued? || line_item.variant.discontinued?
|
|
75
|
-
message =
|
|
75
|
+
message = I18n.t('spree.cart_line_item.discontinued', li_name: line_item.name)
|
|
76
76
|
@messages << message
|
|
77
77
|
@warnings << {
|
|
78
78
|
code: 'line_item_removed',
|
|
@@ -87,7 +87,7 @@ module Spree
|
|
|
87
87
|
|
|
88
88
|
def stock_available?(line_item)
|
|
89
89
|
if line_item.insufficient_stock?
|
|
90
|
-
message =
|
|
90
|
+
message = I18n.t('spree.cart_line_item.out_of_stock', li_name: line_item.name)
|
|
91
91
|
@messages << message
|
|
92
92
|
@warnings << {
|
|
93
93
|
code: 'line_item_removed',
|
|
@@ -242,7 +242,7 @@ module Spree
|
|
|
242
242
|
end
|
|
243
243
|
|
|
244
244
|
def clone_fulfillment(fulfillment, sibling)
|
|
245
|
-
attributes = fulfillment.attributes.except('id', 'cart_id', 'number', 'created_at', 'updated_at')
|
|
245
|
+
attributes = fulfillment.attributes.except('id', 'cart_id', 'number', 'tracking', 'created_at', 'updated_at')
|
|
246
246
|
replacement = sibling.fulfillments.create!(
|
|
247
247
|
attributes.merge('order_id' => sibling.id, 'address_id' => sibling.ship_address_id)
|
|
248
248
|
)
|
|
@@ -16,6 +16,9 @@ module Spree
|
|
|
16
16
|
assign_default_addresses
|
|
17
17
|
|
|
18
18
|
cart.save!
|
|
19
|
+
# Read before the items: processing them reloads the cart, which forgets what this save changed.
|
|
20
|
+
@destination_changed = destination_changed?
|
|
21
|
+
@new_delivery_destination = new_delivery_destination?
|
|
19
22
|
|
|
20
23
|
process_items
|
|
21
24
|
try_advance
|
|
@@ -45,7 +48,7 @@ module Spree
|
|
|
45
48
|
end
|
|
46
49
|
cart.warnings |= warnings if warnings.present?
|
|
47
50
|
|
|
48
|
-
failure(cart,
|
|
51
|
+
failure(cart, I18n.t('spree.cart_line_item.pricing_unavailable'))
|
|
49
52
|
rescue ActiveRecord::RecordInvalid => e
|
|
50
53
|
failure(cart, e.record.errors.full_messages.to_sentence)
|
|
51
54
|
rescue StandardError => e
|
|
@@ -65,6 +68,15 @@ module Spree
|
|
|
65
68
|
cart.saved_change_to_preferred_stock_location_id?
|
|
66
69
|
end
|
|
67
70
|
|
|
71
|
+
# Whether the chosen delivery belongs to a place the cart no longer
|
|
72
|
+
# ships to. A market change or a corrected phone number keeps the
|
|
73
|
+
# choice, quoted again.
|
|
74
|
+
def new_delivery_destination?
|
|
75
|
+
cart.saved_change_to_ship_address_id? ||
|
|
76
|
+
cart.saved_change_to_preferred_stock_location_id? ||
|
|
77
|
+
cart.ship_address&.saved_change_to_destination? || false
|
|
78
|
+
end
|
|
79
|
+
|
|
68
80
|
def assign_cart_attributes
|
|
69
81
|
cart.email = params[:email] if params[:email].present?
|
|
70
82
|
cart.customer_note = params[:customer_note] if params.key?(:customer_note)
|
|
@@ -98,7 +110,7 @@ module Spree
|
|
|
98
110
|
cart.po_document.attach(value)
|
|
99
111
|
end
|
|
100
112
|
rescue ActiveStorage::FileNotFoundError
|
|
101
|
-
cart.errors.add(:po_document, :po_document_upload_incomplete, message:
|
|
113
|
+
cart.errors.add(:po_document, :po_document_upload_incomplete, message: I18n.t('spree.po_document_upload_incomplete'))
|
|
102
114
|
raise ActiveRecord::RecordInvalid, cart
|
|
103
115
|
end
|
|
104
116
|
|
|
@@ -175,7 +187,9 @@ module Spree
|
|
|
175
187
|
def process_items
|
|
176
188
|
return unless params[:items].is_a?(Array)
|
|
177
189
|
|
|
178
|
-
|
|
190
|
+
# Resolved after the save, so a company named in the same request
|
|
191
|
+
# decides which catalogs the items are checked against.
|
|
192
|
+
result = Spree.cart_upsert_items_workflow.call(cart: cart, items: params[:items], orderable_variants: cart.orderable_variants)
|
|
179
193
|
|
|
180
194
|
raise StandardError, result.error.to_s if result.failure?
|
|
181
195
|
end
|
|
@@ -237,8 +251,8 @@ module Spree
|
|
|
237
251
|
def try_advance
|
|
238
252
|
return if cart.complete?
|
|
239
253
|
|
|
240
|
-
if @address_invalidated || destination_changed
|
|
241
|
-
cart.recalculate_for_address_change!
|
|
254
|
+
if @address_invalidated || @destination_changed
|
|
255
|
+
cart.recalculate_for_address_change!(keep_selection: !@new_delivery_destination)
|
|
242
256
|
else
|
|
243
257
|
cart.recalculate_totals!
|
|
244
258
|
end
|
|
@@ -21,7 +21,7 @@ module Spree
|
|
|
21
21
|
return success(catalog) if terms.empty?
|
|
22
22
|
|
|
23
23
|
foreign = terms.keys.reject { |product| product.store_id == catalog.store_id }
|
|
24
|
-
return failure(catalog,
|
|
24
|
+
return failure(catalog, I18n.t('spree.catalogs.product_not_in_store')) if foreign.any?
|
|
25
25
|
|
|
26
26
|
invalid = nil
|
|
27
27
|
|
|
@@ -2,8 +2,9 @@ module Spree
|
|
|
2
2
|
module Categories
|
|
3
3
|
class AddProducts
|
|
4
4
|
prepend Spree::ServiceModule::Base
|
|
5
|
+
include Spree::ProductMemberships
|
|
5
6
|
|
|
6
|
-
#
|
|
7
|
+
# Adds the given products to the given categories, in bulk.
|
|
7
8
|
#
|
|
8
9
|
# @param categories [Array<Spree::Category>]
|
|
9
10
|
# @param products [Array<Spree::Product>]
|
|
@@ -11,40 +12,21 @@ module Spree
|
|
|
11
12
|
def call(categories:, products:)
|
|
12
13
|
return if categories.blank? || products.blank?
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
products.pluck(:id).map do |product_id|
|
|
19
|
-
{
|
|
20
|
-
category_id: category_id,
|
|
21
|
-
product_id: product_id,
|
|
22
|
-
position: (position += 1),
|
|
23
|
-
created_at: Time.current,
|
|
24
|
-
updated_at: Time.current
|
|
25
|
-
}
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
# doing a quick insert_all here to avoid the overhead of instantiating
|
|
29
|
-
Spree::ProductCategory.insert_all(product_categories_params)
|
|
15
|
+
add_memberships(categories, products)
|
|
16
|
+
success(true)
|
|
17
|
+
end
|
|
30
18
|
|
|
31
|
-
|
|
32
|
-
category_ids = categories.pluck(:id)
|
|
33
|
-
product_ids = products.pluck(:id)
|
|
34
|
-
product_ids.each { |id| Spree::Product.reset_counters(id, :product_categories) }
|
|
35
|
-
# Recompute the descendant-inclusive products_count for the categories and
|
|
36
|
-
# their ancestors (bulk insert skips ProductCategory callbacks).
|
|
37
|
-
Spree::Category.recalculate_products_count(category_ids)
|
|
19
|
+
private
|
|
38
20
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
products.each(&:enqueue_search_index)
|
|
21
|
+
def membership_class = Spree::ProductCategory
|
|
22
|
+
def group_class = Spree::Category
|
|
42
23
|
|
|
43
|
-
|
|
44
|
-
|
|
24
|
+
# Recomputes the descendant-inclusive products_count for the categories
|
|
25
|
+
# and their ancestors, and lets an optional storefront extension refresh
|
|
26
|
+
# its featured sections.
|
|
27
|
+
def refresh_group_counters(category_ids)
|
|
28
|
+
Spree::Category.recalculate_products_count(category_ids)
|
|
45
29
|
Spree::Taxons::TouchFeaturedSections.call(taxon_ids: category_ids) if defined?(Spree::Taxons::TouchFeaturedSections)
|
|
46
|
-
|
|
47
|
-
success(true)
|
|
48
30
|
end
|
|
49
31
|
end
|
|
50
32
|
end
|
|
@@ -2,8 +2,9 @@ module Spree
|
|
|
2
2
|
module Categories
|
|
3
3
|
class RemoveProducts
|
|
4
4
|
prepend Spree::ServiceModule::Base
|
|
5
|
+
include Spree::ProductMemberships
|
|
5
6
|
|
|
6
|
-
# Removes the given products from the given categories.
|
|
7
|
+
# Removes the given products from the given categories and re-packs positions.
|
|
7
8
|
#
|
|
8
9
|
# @param categories [Array<Spree::Category>]
|
|
9
10
|
# @param products [Array<Spree::Product>]
|
|
@@ -11,61 +12,21 @@ module Spree
|
|
|
11
12
|
def call(categories:, products:)
|
|
12
13
|
return if categories.blank? || products.blank?
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
product_ids = products.pluck(:id)
|
|
16
|
-
|
|
17
|
-
ApplicationRecord.transaction do
|
|
18
|
-
category_ids.each do |category_id|
|
|
19
|
-
Spree::ProductCategory.where(category_id: category_id, product_id: product_ids).delete_all
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
product_categories_params = category_ids.flat_map do |category_id|
|
|
23
|
-
position = 0
|
|
24
|
-
existing_product_ids = Spree::ProductCategory.where(category_id: category_id).pluck(:product_id)
|
|
25
|
-
|
|
26
|
-
existing_product_ids.map do |product_id|
|
|
27
|
-
{
|
|
28
|
-
category_id: category_id,
|
|
29
|
-
product_id: product_id,
|
|
30
|
-
position: (position += 1),
|
|
31
|
-
created_at: Time.current,
|
|
32
|
-
updated_at: Time.current
|
|
33
|
-
}
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
if product_categories_params.any?
|
|
38
|
-
opts = {}
|
|
39
|
-
opts[:unique_by] = %i[product_id category_id] unless mysql_adapter?
|
|
40
|
-
|
|
41
|
-
Spree::ProductCategory.upsert_all(
|
|
42
|
-
product_categories_params,
|
|
43
|
-
**opts
|
|
44
|
-
)
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# update counter caches
|
|
49
|
-
product_ids.each { |id| Spree::Product.reset_counters(id, :product_categories) }
|
|
50
|
-
# Recompute the descendant-inclusive products_count for the categories and
|
|
51
|
-
# their ancestors (delete_all skips ProductCategory callbacks).
|
|
52
|
-
Spree::Category.recalculate_products_count(category_ids)
|
|
53
|
-
|
|
54
|
-
# clear cache & index products
|
|
55
|
-
Spree::Product.where(id: product_ids).touch_all
|
|
56
|
-
products.each(&:enqueue_search_index)
|
|
57
|
-
|
|
58
|
-
Spree::Category.where(id: category_ids).touch_all
|
|
59
|
-
# Optional external hook (e.g. storefront featured sections); namespace owned by that gem.
|
|
60
|
-
Spree::Taxons::TouchFeaturedSections.call(taxon_ids: category_ids) if defined?(Spree::Taxons::TouchFeaturedSections)
|
|
61
|
-
|
|
15
|
+
remove_memberships(categories, products)
|
|
62
16
|
success(true)
|
|
63
17
|
end
|
|
64
18
|
|
|
65
19
|
private
|
|
66
20
|
|
|
67
|
-
def
|
|
68
|
-
|
|
21
|
+
def membership_class = Spree::ProductCategory
|
|
22
|
+
def group_class = Spree::Category
|
|
23
|
+
|
|
24
|
+
# Recomputes the descendant-inclusive products_count for the categories
|
|
25
|
+
# and their ancestors, and lets an optional storefront extension refresh
|
|
26
|
+
# its featured sections.
|
|
27
|
+
def refresh_group_counters(category_ids)
|
|
28
|
+
Spree::Category.recalculate_products_count(category_ids)
|
|
29
|
+
Spree::Taxons::TouchFeaturedSections.call(taxon_ids: category_ids) if defined?(Spree::Taxons::TouchFeaturedSections)
|
|
69
30
|
end
|
|
70
31
|
end
|
|
71
32
|
end
|
|
@@ -11,10 +11,7 @@ module Spree
|
|
|
11
11
|
def call(order:, state: nil, shipping_method_id: nil)
|
|
12
12
|
cart = order
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
# pure-pickup cart never gets an address, but still needs proposals.
|
|
16
|
-
has_destination = cart.ship_address.present? || cart.preferred_stock_location_id.present?
|
|
17
|
-
if cart.fulfillments.empty? && cart.delivery_step_required? && has_destination && cart.respond_to?(:rebuild_fulfillments!)
|
|
14
|
+
if cart.fulfillments.empty? && cart.delivery_step_required? && cart.can_propose_deliveries? && cart.respond_to?(:rebuild_fulfillments!)
|
|
18
15
|
cart.rebuild_fulfillments!
|
|
19
16
|
end
|
|
20
17
|
|
|
@@ -2,8 +2,9 @@ module Spree
|
|
|
2
2
|
module Collections
|
|
3
3
|
class AddProducts
|
|
4
4
|
prepend Spree::ServiceModule::Base
|
|
5
|
+
include Spree::ProductMemberships
|
|
5
6
|
|
|
6
|
-
# Adds the given products to the given collections
|
|
7
|
+
# Adds the given products to the given collections, in bulk.
|
|
7
8
|
#
|
|
8
9
|
# @param collections [Array<Spree::Collection>]
|
|
9
10
|
# @param products [Array<Spree::Product>]
|
|
@@ -11,31 +12,17 @@ module Spree
|
|
|
11
12
|
def call(collections:, products:)
|
|
12
13
|
return if collections.blank? || products.blank?
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
products.pluck(:id).map do |product_id|
|
|
18
|
-
{
|
|
19
|
-
collection_id: collection_id,
|
|
20
|
-
product_id: product_id,
|
|
21
|
-
position: (position += 1),
|
|
22
|
-
created_at: Time.current,
|
|
23
|
-
updated_at: Time.current
|
|
24
|
-
}
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
Spree::ProductCollection.insert_all(product_collections_params)
|
|
15
|
+
add_memberships(collections, products)
|
|
16
|
+
success(true)
|
|
17
|
+
end
|
|
28
18
|
|
|
29
|
-
|
|
30
|
-
product_ids = products.pluck(:id)
|
|
31
|
-
collection_ids.each { |id| Spree::Collection.reset_counters(id, :product_collections) }
|
|
32
|
-
product_ids.each { |id| Spree::Product.reset_counters(id, :product_collections) }
|
|
19
|
+
private
|
|
33
20
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Spree::Collection.where(id: collection_ids).touch_all
|
|
21
|
+
def membership_class = Spree::ProductCollection
|
|
22
|
+
def group_class = Spree::Collection
|
|
37
23
|
|
|
38
|
-
|
|
24
|
+
def refresh_group_counters(collection_ids)
|
|
25
|
+
collection_ids.each { |id| Spree::Collection.reset_counters(id, :product_collections) }
|
|
39
26
|
end
|
|
40
27
|
end
|
|
41
28
|
end
|