spree_core 4.10.1 → 5.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/app/assets/config/spree_core_manifest.js +4 -0
- data/app/assets/images/google_on_white_hdpi.png +0 -0
- data/app/controllers/spree/base_controller.rb +1 -4
- data/app/finders/spree/orders/find_complete.rb +14 -2
- data/app/finders/spree/products/find.rb +74 -23
- data/app/finders/spree/stores/find_current.rb +6 -2
- data/app/helpers/spree/addresses_helper.rb +106 -0
- data/app/helpers/spree/base_helper.rb +83 -55
- data/app/helpers/spree/currency_helper.rb +12 -0
- data/app/helpers/spree/images_helper.rb +18 -0
- data/app/helpers/spree/mail_helper.rb +24 -0
- data/app/helpers/spree/products_helper.rb +1 -20
- data/app/javascript/spree/core/controllers/address_autocomplete_controller.js +233 -0
- data/app/javascript/spree/core/controllers/address_form_controller.js +98 -0
- data/app/javascript/spree/core/controllers/enable_button_controller.js +29 -0
- data/app/javascript/spree/core/helpers/address_autocomplete/google_places_suggestions_provider.js +179 -0
- data/app/javascript/spree/core/helpers/debounce.js +9 -0
- data/app/javascript/spree/core/helpers/scroll_lock.js +25 -0
- data/app/jobs/spree/addresses/geocode_address_job.rb +31 -0
- data/app/jobs/spree/base_job.rb +1 -0
- data/app/jobs/spree/coupon_codes/bulk_generate_job.rb +17 -0
- data/app/jobs/spree/exports/generate_job.rb +12 -0
- data/app/jobs/spree/products/auto_match_taxons_job.rb +14 -0
- data/app/jobs/spree/products/touch_taxons_job.rb +12 -0
- data/app/jobs/spree/reports/generate_job.rb +12 -0
- data/app/jobs/spree/stock_locations/stock_items/create_job.rb +1 -1
- data/app/jobs/spree/themes/duplicate_components_job.rb +59 -0
- data/app/jobs/spree/themes/screenshot_job.rb +81 -0
- data/app/jobs/spree/variants/remove_from_incomplete_orders_job.rb +2 -0
- data/app/jobs/spree/variants/remove_line_item_job.rb +2 -0
- data/app/mailers/spree/base_mailer.rb +51 -0
- data/app/mailers/spree/export_mailer.rb +19 -0
- data/app/mailers/spree/report_mailer.rb +20 -0
- data/app/mailers/spree/test_mailer.rb +8 -0
- data/app/models/action_text/rich_text_decorator.rb +11 -0
- data/app/models/action_text/video_embed.rb +13 -0
- data/app/models/acts_as_taggable_on/tag_decorator.rb +10 -0
- data/app/models/concerns/spree/calculated_adjustments.rb +2 -0
- data/app/models/concerns/spree/display_on.rb +13 -0
- data/app/models/concerns/spree/has_one_link.rb +42 -0
- data/app/models/concerns/spree/has_page_links.rb +53 -0
- data/app/models/concerns/spree/metadata.rb +3 -7
- data/app/models/concerns/spree/multi_searchable.rb +21 -0
- data/app/models/concerns/spree/multi_store_resource.rb +9 -0
- data/app/models/concerns/spree/number_as_param.rb +4 -2
- data/app/models/concerns/spree/parameterizable_name.rb +21 -0
- data/app/models/concerns/spree/previewable.rb +17 -0
- data/app/models/concerns/spree/product_scopes.rb +7 -7
- data/app/models/concerns/spree/stores/setup.rb +52 -0
- data/app/models/concerns/spree/stores/socials.rb +68 -0
- data/app/models/concerns/spree/user_address.rb +4 -0
- data/app/models/concerns/spree/user_methods.rb +61 -11
- data/app/models/concerns/spree/user_reporting.rb +14 -6
- data/app/models/concerns/spree/user_roles.rb +1 -1
- data/app/models/spree/ability.rb +4 -2
- data/app/models/spree/address.rb +122 -28
- data/app/models/spree/adjustment.rb +4 -1
- data/app/models/spree/asset/support/active_storage.rb +1 -1
- data/app/models/spree/asset.rb +18 -6
- data/app/models/spree/base.rb +38 -7
- data/app/models/spree/base_analytics_event_handler.rb +49 -0
- data/app/models/spree/calculator.rb +1 -1
- data/app/models/spree/classification.rb +10 -1
- data/app/models/spree/country.rb +1 -1
- data/app/models/spree/coupon_code.rb +38 -0
- data/app/models/spree/credit_card.rb +4 -3
- data/app/models/spree/current.rb +9 -0
- data/app/models/spree/custom_domain.rb +53 -0
- data/app/models/spree/customer_return.rb +13 -1
- data/app/models/spree/data_feed.rb +1 -1
- data/app/models/spree/digital.rb +5 -6
- data/app/models/spree/digital_link.rb +11 -6
- data/app/models/spree/export.rb +172 -0
- data/app/models/spree/exports/orders.rb +23 -0
- data/app/models/spree/exports/products.rb +35 -0
- data/app/models/spree/gateway/bogus.rb +5 -0
- data/app/models/spree/gateway.rb +14 -4
- data/app/models/spree/gateway_customer.rb +13 -0
- data/app/models/spree/image/configuration/active_storage.rb +1 -1
- data/app/models/spree/inventory_unit.rb +1 -1
- data/app/models/spree/legacy_user.rb +3 -1
- data/app/models/spree/line_item.rb +37 -2
- data/app/models/spree/log_entry.rb +1 -1
- data/app/models/spree/option_type.rb +40 -6
- data/app/models/spree/option_type_prototype.rb +1 -1
- data/app/models/spree/option_value.rb +35 -5
- data/app/models/spree/option_value_variant.rb +2 -2
- data/app/models/spree/order/address_book.rb +34 -15
- data/app/models/spree/order/checkout.rb +12 -2
- data/app/models/spree/order/currency_updater.rb +1 -1
- data/app/models/spree/order/digital.rb +14 -3
- data/app/models/spree/order/emails.rb +1 -1
- data/app/models/spree/order/payments.rb +1 -13
- data/app/models/spree/order/store_credit.rb +17 -5
- data/app/models/spree/order/webhooks.rb +1 -1
- data/app/models/spree/order.rb +179 -49
- data/app/models/spree/order_promotion.rb +1 -1
- data/app/models/spree/order_updater.rb +9 -3
- data/app/models/spree/page.rb +184 -0
- data/app/models/spree/page_block.rb +69 -0
- data/app/models/spree/page_blocks/buttons.rb +29 -0
- data/app/models/spree/page_blocks/heading.rb +18 -0
- data/app/models/spree/page_blocks/image.rb +17 -0
- data/app/models/spree/page_blocks/link.rb +21 -0
- data/app/models/spree/page_blocks/mega_nav.rb +33 -0
- data/app/models/spree/page_blocks/mega_nav_with_subcategories.rb +32 -0
- data/app/models/spree/page_blocks/nav.rb +15 -0
- data/app/models/spree/page_blocks/newsletter_form.rb +18 -0
- data/app/models/spree/page_blocks/products/buy_buttons.rb +12 -0
- data/app/models/spree/page_blocks/products/price.rb +18 -0
- data/app/models/spree/page_blocks/products/quantity_selector.rb +12 -0
- data/app/models/spree/page_blocks/products/share.rb +8 -0
- data/app/models/spree/page_blocks/products/title.rb +15 -0
- data/app/models/spree/page_blocks/products/variant_picker.rb +9 -0
- data/app/models/spree/page_blocks/subheading.rb +17 -0
- data/app/models/spree/page_blocks/text.rb +16 -0
- data/app/models/spree/page_link.rb +59 -0
- data/app/models/spree/page_section.rb +215 -0
- data/app/models/spree/page_sections/announcement_bar.rb +30 -0
- data/app/models/spree/page_sections/collection_banner.rb +18 -0
- data/app/models/spree/page_sections/custom_code.rb +11 -0
- data/app/models/spree/page_sections/featured_posts.rb +43 -0
- data/app/models/spree/page_sections/featured_product.rb +46 -0
- data/app/models/spree/page_sections/featured_taxon.rb +88 -0
- data/app/models/spree/page_sections/featured_taxons.rb +45 -0
- data/app/models/spree/page_sections/footer.rb +94 -0
- data/app/models/spree/page_sections/header.rb +62 -0
- data/app/models/spree/page_sections/image_banner.rb +38 -0
- data/app/models/spree/page_sections/image_with_text.rb +48 -0
- data/app/models/spree/page_sections/main_password_footer.rb +18 -0
- data/app/models/spree/page_sections/main_password_header.rb +20 -0
- data/app/models/spree/page_sections/newsletter.rb +47 -0
- data/app/models/spree/page_sections/page_title.rb +19 -0
- data/app/models/spree/page_sections/post_details.rb +19 -0
- data/app/models/spree/page_sections/post_grid.rb +19 -0
- data/app/models/spree/page_sections/product_details.rb +16 -0
- data/app/models/spree/page_sections/product_grid.rb +13 -0
- data/app/models/spree/page_sections/related_products.rb +60 -0
- data/app/models/spree/page_sections/rich_text.rb +20 -0
- data/app/models/spree/page_sections/taxon_banner.rb +18 -0
- data/app/models/spree/page_sections/taxon_grid.rb +17 -0
- data/app/models/spree/page_sections/video.rb +99 -0
- data/app/models/spree/pages/account.rb +15 -0
- data/app/models/spree/pages/cart.rb +9 -0
- data/app/models/spree/pages/checkout.rb +9 -0
- data/app/models/spree/pages/custom.rb +34 -0
- data/app/models/spree/pages/homepage.rb +68 -0
- data/app/models/spree/pages/login.rb +15 -0
- data/app/models/spree/pages/password.rb +57 -0
- data/app/models/spree/pages/post.rb +27 -0
- data/app/models/spree/pages/post_list.rb +32 -0
- data/app/models/spree/pages/product_details.rb +29 -0
- data/app/models/spree/pages/search_results.rb +43 -0
- data/app/models/spree/pages/shop_all.rb +36 -0
- data/app/models/spree/pages/taxon.rb +29 -0
- data/app/models/spree/pages/taxon_list.rb +41 -0
- data/app/models/spree/pages/wishlist.rb +11 -0
- data/app/models/spree/payment/gateway_options.rb +13 -15
- data/app/models/spree/payment/processing.rb +1 -1
- data/app/models/spree/payment/webhooks.rb +1 -1
- data/app/models/spree/payment.rb +61 -12
- data/app/models/spree/payment_capture_event.rb +1 -1
- data/app/models/spree/payment_method/store_credit.rb +9 -1
- data/app/models/spree/payment_method.rb +26 -8
- data/app/models/spree/payment_source.rb +2 -2
- data/app/models/spree/post.rb +108 -0
- data/app/models/spree/post_category.rb +33 -0
- data/app/models/spree/preference.rb +1 -1
- data/app/models/spree/price.rb +10 -3
- data/app/models/spree/product/webhooks.rb +1 -1
- data/app/models/spree/product.rb +325 -54
- data/app/models/spree/product_option_type.rb +1 -1
- data/app/models/spree/product_promotion_rule.rb +1 -1
- data/app/models/spree/product_property.rb +4 -1
- data/app/models/spree/promotion/actions/create_line_items.rb +37 -2
- data/app/models/spree/promotion/rules/country.rb +22 -4
- data/app/models/spree/promotion/rules/currency.rb +21 -0
- data/app/models/spree/promotion/rules/item_total.rb +12 -3
- data/app/models/spree/promotion/rules/option_value.rb +5 -20
- data/app/models/spree/promotion/rules/product.rb +33 -1
- data/app/models/spree/promotion/rules/taxon.rb +31 -0
- data/app/models/spree/promotion/rules/user.rb +33 -4
- data/app/models/spree/promotion.rb +136 -15
- data/app/models/spree/promotion_action.rb +31 -1
- data/app/models/spree/promotion_action_line_item.rb +1 -1
- data/app/models/spree/promotion_category.rb +1 -1
- data/app/models/spree/promotion_handler/cart.rb +1 -1
- data/app/models/spree/promotion_handler/coupon.rb +46 -8
- data/app/models/spree/promotion_handler/free_shipping.rb +1 -1
- data/app/models/spree/promotion_handler/promotion_duplicator.rb +6 -5
- data/app/models/spree/promotion_rule.rb +23 -1
- data/app/models/spree/promotion_rule_taxon.rb +1 -1
- data/app/models/spree/promotion_rule_user.rb +1 -1
- data/app/models/spree/property.rb +11 -3
- data/app/models/spree/property_prototype.rb +1 -1
- data/app/models/spree/prototype.rb +1 -1
- data/app/models/spree/prototype_taxon.rb +1 -1
- data/app/models/spree/refund.rb +24 -4
- data/app/models/spree/refund_reason.rb +12 -2
- data/app/models/spree/reimbursement/credit.rb +1 -1
- data/app/models/spree/reimbursement/emails.rb +1 -1
- data/app/models/spree/reimbursement.rb +5 -3
- data/app/models/spree/reimbursement_type.rb +1 -1
- data/app/models/spree/report.rb +110 -0
- data/app/models/spree/report_line_item.rb +27 -0
- data/app/models/spree/report_line_items/products_performance.rb +76 -0
- data/app/models/spree/report_line_items/sales_total.rb +49 -0
- data/app/models/spree/reports/products_performance.rb +44 -0
- data/app/models/spree/reports/sales_total.rb +14 -0
- data/app/models/spree/return_authorization.rb +4 -1
- data/app/models/spree/return_authorization_reason.rb +1 -1
- data/app/models/spree/return_item.rb +2 -1
- data/app/models/spree/role.rb +5 -2
- data/app/models/spree/role_user.rb +2 -2
- data/app/models/spree/shipment/emails.rb +1 -1
- data/app/models/spree/shipment/webhooks.rb +1 -1
- data/app/models/spree/shipment.rb +14 -4
- data/app/models/spree/shipping_category.rb +1 -1
- data/app/models/spree/shipping_method.rb +48 -8
- data/app/models/spree/shipping_method_category.rb +1 -1
- data/app/models/spree/shipping_method_zone.rb +1 -1
- data/app/models/spree/shipping_rate.rb +21 -3
- data/app/models/spree/state.rb +1 -1
- data/app/models/spree/state_change.rb +1 -1
- data/app/models/spree/stock_item/webhooks.rb +1 -1
- data/app/models/spree/stock_item.rb +9 -6
- data/app/models/spree/stock_location.rb +35 -8
- data/app/models/spree/stock_movement/webhooks.rb +1 -1
- data/app/models/spree/stock_movement.rb +9 -3
- data/app/models/spree/stock_transfer.rb +41 -3
- data/app/models/spree/store.rb +345 -72
- data/app/models/spree/store_credit.rb +12 -4
- data/app/models/spree/store_credit_category.rb +1 -1
- data/app/models/spree/store_credit_event.rb +21 -1
- data/app/models/spree/store_credit_type.rb +1 -1
- data/app/models/spree/store_payment_method.rb +1 -1
- data/app/models/spree/store_product.rb +1 -1
- data/app/models/spree/store_promotion.rb +1 -1
- data/app/models/spree/tax_category.rb +15 -1
- data/app/models/spree/tax_rate.rb +1 -1
- data/app/models/spree/taxon.rb +210 -27
- data/app/models/spree/taxon_image/configuration/active_storage.rb +1 -1
- data/app/models/spree/taxon_rule.rb +25 -0
- data/app/models/spree/taxon_rules/available_on.rb +20 -0
- data/app/models/spree/taxon_rules/sale.rb +16 -0
- data/app/models/spree/taxon_rules/tag.rb +19 -0
- data/app/models/spree/taxonomy.rb +3 -2
- data/app/models/spree/theme.rb +200 -0
- data/app/models/spree/themes/default.rb +94 -0
- data/app/models/spree/variant/webhooks.rb +1 -1
- data/app/models/spree/variant.rb +211 -62
- data/app/models/spree/wished_item.rb +1 -1
- data/app/models/spree/wishlist.rb +1 -1
- data/app/models/spree/zone.rb +1 -1
- data/app/models/spree/zone_member.rb +1 -1
- data/app/presenters/spree/csv/order_line_item_presenter.rb +145 -0
- data/app/presenters/spree/csv/product_presenter.rb +63 -0
- data/app/presenters/spree/csv/product_variant_presenter.rb +130 -0
- data/app/services/spree/addresses/create.rb +31 -6
- data/app/services/spree/addresses/helper.rb +7 -4
- data/app/services/spree/addresses/update.rb +79 -12
- data/app/services/spree/cart/remove_out_of_stock_items.rb +56 -0
- data/app/services/spree/checkout/add_store_credit.rb +6 -1
- data/app/services/spree/checkout/advance.rb +44 -4
- data/app/services/spree/checkout/select_shipping_method.rb +2 -0
- data/app/services/spree/coupon_codes/bulk_generate.rb +37 -0
- data/app/services/spree/coupon_codes/coupon_codes_handler.rb +34 -0
- data/app/services/spree/orders/create_user_account.rb +70 -0
- data/app/services/spree/orders/update_contact_information.rb +19 -0
- data/app/services/spree/products/auto_match_taxons.rb +64 -0
- data/app/services/spree/products/duplicator.rb +121 -0
- data/app/services/spree/products/prepare_nested_attributes.rb +169 -0
- data/app/services/spree/seeds/admin_user.rb +22 -0
- data/app/services/spree/seeds/all.rb +1 -0
- data/app/services/spree/seeds/stores.rb +5 -10
- data/app/services/spree/seeds/zones.rb +2 -0
- data/app/services/spree/tags/bulk_add.rb +38 -0
- data/app/services/spree/tags/bulk_remove.rb +24 -0
- data/app/services/spree/taxons/add_products.rb +39 -0
- data/app/services/spree/taxons/regenerate_products.rb +53 -0
- data/app/services/spree/taxons/remove_products.rb +53 -0
- data/app/services/spree/taxons/touch_featured_sections.rb +21 -0
- data/app/services/spree/themes/duplicator.rb +40 -0
- data/app/services/spree/variants/remove_line_items.rb +1 -1
- data/app/sorters/spree/classifications/sort.rb +68 -0
- data/app/sorters/spree/products/sort.rb +2 -3
- data/app/views/action_text/video_embeds/_thumbnail.html.erb +1 -0
- data/app/views/action_text/video_embeds/_video_embed.html.erb +3 -0
- data/app/views/active_storage/blobs/_blob.html.erb +20 -0
- data/app/views/layouts/action_text/contents/_content.html.erb +3 -0
- data/app/views/layouts/spree/base_mailer.html.erb +46 -0
- data/app/views/spree/addresses/_form.html.erb +58 -0
- data/app/views/spree/addresses/_suggestions_box.erb +14 -0
- data/app/views/spree/export_mailer/export_done.html.erb +15 -0
- data/app/views/spree/report_mailer/report_done.html.erb +15 -0
- data/app/views/spree/shared/_base_mailer_footer.html.erb +12 -0
- data/app/views/spree/shared/_base_mailer_header.html.erb +6 -0
- data/app/views/spree/shared/_base_mailer_stylesheets.html.erb +456 -0
- data/app/views/spree/shared/_google_places_api_loader.html.erb +7 -0
- data/app/views/spree/shared/_mailer_line_item.html.erb +12 -0
- data/app/views/spree/shared/_mailer_logo.html.erb +41 -0
- data/app/views/spree/shared/_payment.html.erb +41 -0
- data/app/views/spree/test_mailer/test_email.html.erb +40 -0
- data/app/views/spree/test_mailer/test_email.text.erb +4 -0
- data/config/i18n-tasks.yml +178 -0
- data/config/importmap.rb +14 -0
- data/config/initializers/acts_as_taggable_on.rb +2 -0
- data/config/initializers/inflections.rb +2 -0
- data/config/initializers/mobility.rb +4 -0
- data/config/initializers/oembed.rb +1 -0
- data/config/locales/en.yml +823 -413
- data/config/routes.rb +6 -5
- data/db/migrate/20210914000000_spree_four_three.rb +0 -79
- data/db/migrate/20240913143518_change_default_value_of_spree_option_types_filterable.rb +5 -0
- data/db/migrate/20240914153106_add_display_on_to_spree_properties.rb +5 -0
- data/db/migrate/20240915144935_add_position_to_spree_properties.rb +6 -0
- data/db/migrate/20241004181911_create_spree_coupon_codes.rb +15 -0
- data/db/migrate/20241005093437_add_multi_code_to_spree_promotions.rb +14 -0
- data/db/migrate/20241014140140_translate_rich_texts.rb +17 -0
- data/db/migrate/20241030134309_create_spree_exports.rb +23 -0
- data/db/migrate/20241104083457_migrate_spree_promotion_rules_option_value_eligible_values.rb +16 -0
- data/db/migrate/20241123110646_add_estimated_transit_fields_to_spree_shipping_methods.rb +6 -0
- data/db/migrate/20241127193411_create_spree_taxon_rules.rb +13 -0
- data/db/migrate/20241127223627_add_rules_match_policy_and_sort_order_to_spree_taxons.rb +6 -0
- data/db/migrate/20241128103947_add_automatic_to_spree_taxons.rb +5 -0
- data/db/migrate/20241218183905_add_gateway_customer_profile_id_to_spree_payment_sources.rb +5 -0
- data/db/migrate/20250107220432_add_accept_marketing_and_signup_for_an_account_to_spree_orders.rb +6 -0
- data/db/migrate/20250110171203_add_quick_checkout_to_spree_addresses.rb +6 -0
- data/db/migrate/20250113180019_add_preferences_to_spree_stores.rb +5 -0
- data/db/migrate/20250114193857_add_metadata_to_spree_stores.rb +13 -0
- data/db/migrate/20250119165904_create_spree_custom_domains.rb +22 -0
- data/db/migrate/20250120094216_create_page_builder_models.rb +78 -0
- data/db/migrate/20250120152208_add_default_locale_to_action_text_rich_texts.rb +7 -0
- data/db/migrate/20250121160028_create_spree_posts_and_spree_post_categories.rb +33 -0
- data/db/migrate/20250122113708_add_first_and_last_name_to_spree_admin_class.rb +9 -0
- data/db/migrate/20250123135358_add_custom_code_fields_to_spree_store.rb +7 -0
- data/db/migrate/20250127083740_add_kind_to_spree_properties.rb +5 -0
- data/db/migrate/20250127112758_add_latitude_and_longitude_to_spree_addresses.rb +6 -0
- data/db/migrate/20250127151258_add_phone_to_spree_users.rb +5 -0
- data/db/migrate/20250204162453_create_spree_reports.rb +13 -0
- data/db/migrate/20250207084000_add_accepts_email_marketing_field_to_spree_users_table.rb +6 -0
- data/db/migrate/20250217171018_create_action_text_video_embeds.rb +11 -0
- data/db/migrate/20250304115943_add_performed_by_to_spree_reimbursements.rb +5 -0
- data/db/migrate/20250305121352_remove_page_builder_indices.rb +11 -0
- data/db/migrate/20250305121657_remove_spree_posts_indices.rb +7 -0
- data/db/migrate/20250311105934_create_spree_gateway_customers.rb +18 -0
- data/db/migrate/20250312202705_add_unique_index_on_promotion_rules_associations.rb +75 -0
- data/db/migrate/20250313104226_add_user_type_to_spree_role_users.rb +18 -0
- data/db/migrate/20250313175830_add_unique_index_on_promotion_action_line_items.rb +29 -0
- data/db/migrate/20250314144210_create_spree_taggings_and_spree_tags.rb +38 -0
- data/lib/generators/spree/authentication/custom/custom_generator.rb +49 -0
- data/lib/generators/spree/authentication/custom/templates/authentication_helpers.rb.tt +50 -0
- data/lib/generators/spree/authentication/devise/devise_generator.rb +57 -0
- data/lib/generators/spree/authentication/devise/templates/authentication_helpers.rb.tt +50 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +1 -1
- data/lib/generators/spree/dummy/templates/rails/database.yml +1 -0
- data/lib/generators/spree/dummy/templates/rails/test.rb +1 -1
- data/lib/generators/spree/install/install_generator.rb +21 -36
- data/lib/generators/spree/install/templates/config/initializers/spree.rb +40 -6
- data/lib/normalize_string.rb +18 -0
- data/lib/spree/analytics.rb +11 -0
- data/lib/spree/core/components.rb +1 -1
- data/lib/spree/core/configuration.rb +14 -11
- data/lib/spree/core/controller_helpers/auth.rb +0 -26
- data/lib/spree/core/controller_helpers/order.rb +77 -12
- data/lib/spree/core/controller_helpers/search.rb +2 -0
- data/lib/spree/core/controller_helpers/store.rb +0 -5
- data/lib/spree/core/controller_helpers/strong_parameters.rb +4 -0
- data/lib/spree/core/controller_helpers/turbo.rb +19 -0
- data/lib/spree/core/dependencies.rb +3 -5
- data/lib/spree/core/engine.rb +158 -7
- data/lib/spree/core/preferences/configuration.rb +2 -44
- data/lib/spree/core/preferences/preferable.rb +9 -0
- data/lib/spree/core/preferences/preferable_class_methods.rb +11 -1
- data/lib/spree/core/preferences/runtime_configuration.rb +13 -2
- data/lib/spree/core/search/base.rb +2 -0
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +61 -11
- data/lib/spree/i18n.rb +5 -8
- data/lib/spree/migrations.rb +1 -1
- data/lib/spree/permitted_attributes.rb +24 -15
- data/lib/spree/testing_support/authorization_helpers.rb +9 -6
- data/lib/spree/testing_support/capybara_config.rb +11 -0
- data/lib/spree/testing_support/common_rake.rb +20 -12
- data/lib/spree/testing_support/factories/calculator_factory.rb +16 -0
- data/lib/spree/testing_support/factories/country_factory.rb +8 -0
- data/lib/spree/testing_support/factories/coupon_code_factory.rb +7 -0
- data/lib/spree/testing_support/factories/custom_domain_factory.rb +7 -0
- data/lib/spree/testing_support/factories/export_factory.rb +32 -0
- data/lib/spree/testing_support/factories/gateway_customer_factory.rb +7 -0
- data/lib/spree/testing_support/factories/order_factory.rb +14 -3
- data/lib/spree/testing_support/factories/page_block_factory.rb +21 -0
- data/lib/spree/testing_support/factories/page_factory.rb +33 -0
- data/lib/spree/testing_support/factories/page_link_factory.rb +7 -0
- data/lib/spree/testing_support/factories/page_section_factory.rb +24 -0
- data/lib/spree/testing_support/factories/payment_factory.rb +2 -2
- data/lib/spree/testing_support/factories/post_category_factory.rb +7 -0
- data/lib/spree/testing_support/factories/post_factory.rb +10 -0
- data/lib/spree/testing_support/factories/product_factory.rb +3 -8
- data/lib/spree/testing_support/factories/product_property_factory.rb +1 -1
- data/lib/spree/testing_support/factories/promotion_action_factory.rb +5 -0
- data/lib/spree/testing_support/factories/promotion_factory.rb +7 -9
- data/lib/spree/testing_support/factories/promotion_rule_factory.rb +12 -0
- data/lib/spree/testing_support/factories/property_factory.rb +1 -1
- data/lib/spree/testing_support/factories/report_factory.rb +33 -0
- data/lib/spree/testing_support/factories/role_user_factory.rb +7 -0
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +9 -0
- data/lib/spree/testing_support/factories/stock_transfer_factory.rb +5 -2
- data/lib/spree/testing_support/factories/store_factory.rb +6 -9
- data/lib/spree/testing_support/factories/taxon_factory.rb +13 -0
- data/lib/spree/testing_support/factories/taxon_rule_factory.rb +38 -0
- data/lib/spree/testing_support/factories/theme_factory.rb +14 -0
- data/lib/spree/testing_support/factories/user_factory.rb +13 -11
- data/lib/spree/testing_support/factories/variant_factory.rb +23 -5
- data/lib/spree/testing_support/jobs.rb +1 -7
- data/lib/spree/testing_support/metadata.rb +13 -1
- data/lib/spree/testing_support/order_walkthrough.rb +1 -7
- data/lib/spree/testing_support/preferences.rb +1 -4
- data/lib/spree/testing_support/store.rb +26 -0
- data/lib/spree_core.rb +1 -0
- data/vendor/javascript/@rails--request.js.js +4 -0
- data/vendor/javascript/@stimulus-components--auto-submit.js +4 -0
- data/vendor/javascript/stimulus-reveal-controller.js +4 -0
- data/vendor/javascript/tailwindcss-stimulus-components.js +4 -0
- metadata +340 -197
- data/Gemfile +0 -3
- data/app/finders/spree/cms_pages/find.rb +0 -41
- data/app/finders/spree/menus/find.rb +0 -11
- data/app/models/concerns/spree/display_link.rb +0 -30
- data/app/models/spree/cms/pages/feature_page.rb +0 -7
- data/app/models/spree/cms/pages/homepage.rb +0 -20
- data/app/models/spree/cms/pages/standard_page.rb +0 -4
- data/app/models/spree/cms/sections/featured_article.rb +0 -22
- data/app/models/spree/cms/sections/hero_image.rb +0 -38
- data/app/models/spree/cms/sections/image_gallery.rb +0 -97
- data/app/models/spree/cms/sections/product_carousel.rb +0 -14
- data/app/models/spree/cms/sections/rich_text_content.rb +0 -13
- data/app/models/spree/cms/sections/side_by_side_images.rb +0 -68
- data/app/models/spree/cms_page.rb +0 -70
- data/app/models/spree/cms_section.rb +0 -69
- data/app/models/spree/cms_section_image.rb +0 -9
- data/app/models/spree/cms_section_image_one.rb +0 -4
- data/app/models/spree/cms_section_image_three.rb +0 -4
- data/app/models/spree/cms_section_image_two.rb +0 -4
- data/app/models/spree/icon.rb +0 -7
- data/app/models/spree/linkable/homepage.rb +0 -3
- data/app/models/spree/linkable/uri.rb +0 -3
- data/app/models/spree/menu.rb +0 -66
- data/app/models/spree/menu_item.rb +0 -72
- data/brakeman.ignore +0 -328
- data/db/migrate/20211201202851_update_linkable_resource_types.rb +0 -10
- data/db/migrate/20220329113557_fix_cms_pages_unique_indexes.rb +0 -8
- data/lib/generators/spree/custom_authentication/custom_authentication_generator.rb +0 -23
- data/lib/generators/spree/custom_authentication/templates/authentication_helpers.rb.tt +0 -23
- data/lib/generators/spree/custom_user/custom_user_generator.rb +0 -46
- data/lib/generators/spree/custom_user/templates/current_user_helpers.rb.tt +0 -15
- data/lib/generators/spree/custom_user/templates/initializer.rb.tt +0 -1
- data/lib/generators/spree/custom_user/templates/migration.rb.tt +0 -7
- data/lib/generators/spree/dummy/templates/package.json +0 -12
- data/lib/spree/core/product_duplicator.rb +0 -85
- data/lib/spree/core/runtime_configuration.rb +0 -10
- data/lib/spree/testing_support/factories/cms_page_factory.rb +0 -20
- data/lib/spree/testing_support/factories/cms_section_factory.rb +0 -31
- data/lib/spree/testing_support/factories/icon_factory.rb +0 -9
- data/lib/spree/testing_support/factories/menu_factory.rb +0 -16
- data/lib/spree/testing_support/factories/menu_item_factory.rb +0 -10
- data/script/rails +0 -9
- data/spec/fixtures/favicon.ico +0 -0
- data/spec/fixtures/files/icon_256x256.gif +0 -0
- data/spec/fixtures/files/icon_256x256.png +0 -0
- data/spec/fixtures/files/icon_512x512.png +0 -0
- data/spec/fixtures/files/img_256x128.png +0 -0
- data/spec/fixtures/text-file.txt +0 -1
- data/spec/fixtures/thinking-cat.jpg +0 -0
- data/spree_core.gemspec +0 -62
@@ -1,5 +1,5 @@
|
|
1
1
|
module Spree
|
2
|
-
class StockTransfer < Spree
|
2
|
+
class StockTransfer < Spree.base_class
|
3
3
|
include Spree::Core::NumberGenerator.new(prefix: 'T')
|
4
4
|
include Spree::NumberIdentifier
|
5
5
|
include Spree::NumberAsParam
|
@@ -9,12 +9,20 @@ module Spree
|
|
9
9
|
end
|
10
10
|
|
11
11
|
has_many :stock_movements, as: :originator
|
12
|
+
accepts_nested_attributes_for :stock_movements, reject_if: proc { |attributes|
|
13
|
+
attributes[:quantity] = attributes[:quantity].to_i
|
14
|
+
attributes[:quantity].blank? || attributes[:quantity].zero? || attributes[:stock_item_id].blank?
|
15
|
+
}
|
12
16
|
|
13
17
|
belongs_to :source_location, class_name: 'StockLocation', optional: true
|
14
18
|
belongs_to :destination_location, class_name: 'StockLocation'
|
15
19
|
|
16
20
|
self.whitelisted_ransackable_attributes = %w[reference source_location_id destination_location_id number]
|
17
21
|
|
22
|
+
validate :source_location_is_not_destination_location
|
23
|
+
validate :stock_movements_not_empty
|
24
|
+
validates :destination_location, presence: true
|
25
|
+
|
18
26
|
def source_movements
|
19
27
|
find_stock_location_with_location_id(source_location_id)
|
20
28
|
end
|
@@ -24,16 +32,28 @@ module Spree
|
|
24
32
|
end
|
25
33
|
|
26
34
|
def transfer(source_location, destination_location, variants)
|
35
|
+
if variants.nil? || variants.empty?
|
36
|
+
errors.add(:base, Spree.t('stock_transfer.errors.must_have_variant'))
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
|
40
|
+
unless variants_available_in_source_location?(source_location, variants)
|
41
|
+
errors.add(:base, Spree.t('stock_transfer.errors.variants_unavailable'))
|
42
|
+
return false
|
43
|
+
end
|
44
|
+
|
27
45
|
transaction do
|
28
46
|
variants.each_pair do |variant, quantity|
|
29
|
-
source_location&.unstock(variant, quantity, self)
|
30
|
-
destination_location.restock(variant, quantity, self)
|
47
|
+
source_location&.unstock(variant, quantity, self, persist: false)
|
48
|
+
destination_location.restock(variant, quantity, self, persist: false)
|
31
49
|
|
32
50
|
self.source_location = source_location
|
33
51
|
self.destination_location = destination_location
|
34
52
|
save!
|
35
53
|
end
|
36
54
|
end
|
55
|
+
|
56
|
+
true
|
37
57
|
end
|
38
58
|
|
39
59
|
# receive inventory from external vendor
|
@@ -46,5 +66,23 @@ module Spree
|
|
46
66
|
def find_stock_location_with_location_id(location_id)
|
47
67
|
stock_movements.joins(:stock_item).where('spree_stock_items.stock_location_id' => location_id)
|
48
68
|
end
|
69
|
+
|
70
|
+
def source_location_is_not_destination_location
|
71
|
+
return unless source_location_id.present?
|
72
|
+
return unless destination_location_id.present?
|
73
|
+
return if source_location_id != destination_location_id
|
74
|
+
|
75
|
+
errors.add(:source_location, Spree.t('stock_transfer.errors.same_location'))
|
76
|
+
end
|
77
|
+
|
78
|
+
def stock_movements_not_empty
|
79
|
+
errors.add(:base, Spree.t('stock_transfer.errors.must_have_variant')) if stock_movements.empty?
|
80
|
+
end
|
81
|
+
|
82
|
+
def variants_available_in_source_location?(source_location, variants)
|
83
|
+
return true if source_location.nil?
|
84
|
+
|
85
|
+
source_location.stock_items.where(variant: variants.keys).where(Spree::StockItem.arel_table[:count_on_hand].gt(0)).size == variants.keys.size
|
86
|
+
end
|
49
87
|
end
|
50
88
|
end
|
data/app/models/spree/store.rb
CHANGED
@@ -1,39 +1,66 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
1
3
|
module Spree
|
2
|
-
class Store < Spree
|
4
|
+
class Store < Spree.base_class
|
5
|
+
RESERVED_CODES = %w(
|
6
|
+
admin default app api www cdn files assets checkout account auth login user
|
7
|
+
)
|
8
|
+
|
9
|
+
include FriendlyId
|
3
10
|
include Spree::TranslatableResource
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
if defined?(Spree::
|
8
|
-
|
9
|
-
|
11
|
+
include Spree::Metadata
|
12
|
+
include Spree::Stores::Setup
|
13
|
+
include Spree::Stores::Socials
|
14
|
+
include Spree::Webhooks::HasWebhooks if defined?(Spree::Webhooks::HasWebhooks)
|
15
|
+
include Spree::Security::Stores if defined?(Spree::Security::Stores)
|
16
|
+
|
17
|
+
#
|
18
|
+
# Magic methods
|
19
|
+
#
|
20
|
+
acts_as_paranoid
|
21
|
+
friendly_id :slug_candidates, use: [:slugged, :history], slug_column: :code, routes: :normal
|
10
22
|
|
23
|
+
#
|
24
|
+
# Translations
|
25
|
+
#
|
11
26
|
TRANSLATABLE_FIELDS = %i[name meta_description meta_keywords seo_title facebook
|
12
27
|
twitter instagram customer_support_email description
|
13
28
|
address contact_phone new_order_notifications_email].freeze
|
14
29
|
translates(*TRANSLATABLE_FIELDS, column_fallback: !Spree.always_use_translations?)
|
15
|
-
|
16
30
|
self::Translation.class_eval do
|
17
31
|
acts_as_paranoid
|
18
32
|
# deleted translation values still need to be accessible - remove deleted_at scope
|
19
33
|
default_scope { unscope(where: :deleted_at) }
|
20
34
|
end
|
21
35
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
#
|
37
|
+
# Preferences
|
38
|
+
#
|
39
|
+
# general preferences
|
40
|
+
preference :timezone, :string, default: Time.zone.name
|
41
|
+
preference :weight_unit, :string, default: 'lb'
|
42
|
+
preference :unit_system, :string, default: 'imperial'
|
43
|
+
# email preferences
|
44
|
+
preference :send_consumer_transactional_emails, :boolean, default: true
|
45
|
+
# SEO preferences
|
46
|
+
preference :index_in_search_engines, :boolean, default: false
|
47
|
+
preference :password_protected, :boolean, default: false
|
48
|
+
# Checkout preferences
|
49
|
+
preference :guest_checkout, :boolean, default: true
|
50
|
+
# digital assets preferences
|
51
|
+
preference :limit_digital_download_count, :boolean, default: true
|
52
|
+
preference :limit_digital_download_days, :boolean, default: true
|
53
|
+
preference :digital_asset_authorized_clicks, :integer, default: 5
|
54
|
+
preference :digital_asset_authorized_days, :integer, default: 7
|
55
|
+
preference :digital_asset_link_expire_time, :integer, default: 300
|
56
|
+
|
57
|
+
#
|
58
|
+
# Associations
|
59
|
+
#
|
60
|
+
has_many :checkouts, -> { incomplete }, class_name: 'Spree::Order', inverse_of: :store
|
35
61
|
has_many :orders, class_name: 'Spree::Order'
|
36
62
|
has_many :line_items, through: :orders, class_name: 'Spree::LineItem'
|
63
|
+
has_many :digital_links, through: :line_items, class_name: 'Spree::DigitalLink'
|
37
64
|
has_many :shipments, through: :orders, class_name: 'Spree::Shipment'
|
38
65
|
has_many :payments, through: :orders, class_name: 'Spree::Payment'
|
39
66
|
has_many :return_authorizations, through: :orders, class_name: 'Spree::ReturnAuthorization'
|
@@ -42,18 +69,13 @@ module Spree
|
|
42
69
|
has_many :store_payment_methods, class_name: 'Spree::StorePaymentMethod'
|
43
70
|
has_many :payment_methods, through: :store_payment_methods, class_name: 'Spree::PaymentMethod'
|
44
71
|
|
45
|
-
has_many :cms_pages, class_name: 'Spree::CmsPage'
|
46
|
-
has_many :cms_sections, through: :cms_pages, class_name: 'Spree::CmsSection'
|
47
|
-
|
48
|
-
has_many :menus, class_name: 'Spree::Menu'
|
49
|
-
has_many :menu_items, through: :menus, class_name: 'Spree::MenuItem'
|
50
|
-
|
51
72
|
has_many :store_products, class_name: 'Spree::StoreProduct'
|
52
73
|
has_many :products, through: :store_products, class_name: 'Spree::Product'
|
53
74
|
has_many :product_properties, through: :products, class_name: 'Spree::ProductProperty'
|
54
75
|
has_many :variants, through: :products, class_name: 'Spree::Variant', source: :variants_including_master
|
55
76
|
has_many :stock_items, through: :variants, class_name: 'Spree::StockItem'
|
56
77
|
has_many :inventory_units, through: :variants, class_name: 'Spree::InventoryUnit'
|
78
|
+
has_many :option_value_variants, through: :variants, class_name: 'Spree::OptionValueVariant'
|
57
79
|
has_many :customer_returns, class_name: 'Spree::CustomerReturn', inverse_of: :store
|
58
80
|
|
59
81
|
has_many :store_credits, class_name: 'Spree::StoreCredit'
|
@@ -72,15 +94,59 @@ module Spree
|
|
72
94
|
belongs_to :default_country, class_name: 'Spree::Country'
|
73
95
|
belongs_to :checkout_zone, class_name: 'Spree::Zone'
|
74
96
|
|
97
|
+
has_many :reports, class_name: 'Spree::Report'
|
98
|
+
has_many :exports, class_name: 'Spree::Export'
|
99
|
+
|
100
|
+
has_many :custom_domains, class_name: 'Spree::CustomDomain', dependent: :destroy
|
101
|
+
has_one :default_custom_domain, -> { where(default: true) }, class_name: 'Spree::CustomDomain'
|
102
|
+
|
103
|
+
has_many :posts
|
104
|
+
has_many :post_categories
|
105
|
+
|
106
|
+
#
|
107
|
+
# Page Builder associations
|
108
|
+
#
|
109
|
+
has_many :themes, -> { without_previews }, class_name: 'Spree::Theme', dependent: :destroy, inverse_of: :store
|
110
|
+
has_many :theme_previews,
|
111
|
+
-> { only_previews },
|
112
|
+
class_name: 'Spree::Theme',
|
113
|
+
through: :themes,
|
114
|
+
source: :previews,
|
115
|
+
inverse_of: :store,
|
116
|
+
dependent: :destroy
|
117
|
+
has_one :default_theme, -> { without_previews.where(default: true) }, class_name: 'Spree::Theme', inverse_of: :store
|
118
|
+
has_many :theme_pages, class_name: 'Spree::Page', through: :themes, source: :pages
|
119
|
+
has_many :theme_page_previews, class_name: 'Spree::Page', through: :theme_pages, source: :previews
|
120
|
+
has_many :pages, -> { without_previews.custom }, class_name: 'Spree::Pages::Custom', dependent: :destroy, as: :pageable
|
121
|
+
has_many :page_previews, class_name: 'Spree::Pages::Custom', through: :pages, as: :pageable, source: :previews
|
122
|
+
|
123
|
+
#
|
124
|
+
# ActionText
|
125
|
+
#
|
126
|
+
has_rich_text :checkout_message
|
127
|
+
has_rich_text :customer_terms_of_service
|
128
|
+
has_rich_text :customer_privacy_policy
|
129
|
+
has_rich_text :customer_returns_policy
|
130
|
+
has_rich_text :customer_shipping_policy
|
131
|
+
|
132
|
+
#
|
133
|
+
# Virtual attributes
|
134
|
+
#
|
135
|
+
attribute :import_products_from_store_id, :string, default: nil
|
136
|
+
attribute :import_payment_methods_from_store_id, :string, default: nil
|
137
|
+
attr_accessor :skip_validate_not_last
|
138
|
+
store_accessor :private_metadata, :storefront_password
|
139
|
+
|
140
|
+
#
|
141
|
+
# Validations
|
142
|
+
#
|
75
143
|
with_options presence: true do
|
76
|
-
validates :name, :url, :mail_from_address, :default_currency, :code
|
144
|
+
validates :name, :url, :mail_from_address, :default_currency, :default_country, :code
|
77
145
|
end
|
78
|
-
|
79
|
-
validates :
|
80
|
-
validates :
|
81
|
-
validates :code, uniqueness: { case_sensitive: false, conditions: -> { with_deleted } }
|
146
|
+
validates :preferred_digital_asset_authorized_clicks, numericality: { only_integer: true, greater_than: 0 }
|
147
|
+
validates :preferred_digital_asset_authorized_days, numericality: { only_integer: true, greater_than: 0 }
|
148
|
+
validates :code, uniqueness: { case_sensitive: false, conditions: -> { with_deleted } }, exclusion: RESERVED_CODES
|
82
149
|
validates :mail_from_address, email: { allow_blank: false }
|
83
|
-
|
84
150
|
# FIXME: we should remove this condition in v5
|
85
151
|
if !ENV['SPREE_DISABLE_DB_CONNECTION'] &&
|
86
152
|
connected? &&
|
@@ -88,29 +154,48 @@ module Spree
|
|
88
154
|
connection.column_exists?(:spree_stores, :new_order_notifications_email)
|
89
155
|
validates :new_order_notifications_email, email: { allow_blank: true }
|
90
156
|
end
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
157
|
+
validates :favicon_image, :social_image, :mailer_logo, content_type: Rails.application.config.active_storage.web_image_content_types
|
158
|
+
|
159
|
+
#
|
160
|
+
# Attachments
|
161
|
+
#
|
162
|
+
has_one_attached :logo, service: Spree.public_storage_service_name
|
163
|
+
has_one_attached :favicon_image, service: Spree.public_storage_service_name
|
164
|
+
has_one_attached :social_image, service: Spree.public_storage_service_name
|
165
|
+
has_one_attached :mailer_logo, service: Spree.public_storage_service_name
|
166
|
+
|
167
|
+
#
|
168
|
+
# Callbacks
|
169
|
+
before_validation :ensure_default_country
|
170
|
+
before_validation :set_code, on: :create
|
171
|
+
before_validation :set_url
|
103
172
|
before_save :ensure_default_exists_and_is_unique
|
104
|
-
before_save :ensure_supported_currencies, :ensure_supported_locales
|
173
|
+
before_save :ensure_supported_currencies, :ensure_supported_locales
|
174
|
+
after_create :ensure_default_taxonomies_are_created
|
175
|
+
after_create :ensure_default_automatic_taxons
|
176
|
+
after_create :ensure_default_post_categories_are_created
|
177
|
+
after_create :import_products_from_store, if: -> { import_products_from_store_id.present? }
|
178
|
+
after_create :import_payment_methods_from_store, if: -> { import_payment_methods_from_store_id.present? }
|
179
|
+
after_create :create_default_theme
|
105
180
|
before_destroy :validate_not_last, unless: :skip_validate_not_last
|
106
181
|
before_destroy :pass_default_flag_to_other_store
|
182
|
+
after_commit :clear_cache
|
183
|
+
after_commit :handle_code_changes, on: :update, if: -> { code_previously_changed? }
|
107
184
|
|
108
|
-
|
185
|
+
#
|
186
|
+
# Scopes
|
187
|
+
#
|
188
|
+
default_scope { order(created_at: :asc) }
|
189
|
+
scope :by_custom_domain, ->(url) { left_joins(:custom_domains).where("#{Spree::CustomDomain.table_name}.url" => url) }
|
190
|
+
scope :by_url, ->(url) { where("#{table_name}.url like ?", "%#{url}%") }
|
109
191
|
|
110
|
-
|
192
|
+
#
|
193
|
+
# Delegations
|
194
|
+
#
|
195
|
+
delegate :iso, to: :default_country, prefix: true, allow_nil: true
|
111
196
|
|
112
197
|
def self.current(url = nil)
|
113
|
-
Spree::Dependencies.current_store_finder.constantize.new(url: url).execute
|
198
|
+
Spree::Dependencies.current_store_finder.constantize.new(url: url).execute || Spree::Current.store
|
114
199
|
end
|
115
200
|
|
116
201
|
# FIXME: we need to drop `or_initialize` in v5
|
@@ -130,22 +215,34 @@ module Spree
|
|
130
215
|
Spree::Store.all.map(&:supported_locales_list).flatten.uniq
|
131
216
|
end
|
132
217
|
|
133
|
-
def
|
134
|
-
|
218
|
+
def default_country_iso=(iso)
|
219
|
+
return if iso.blank?
|
220
|
+
|
221
|
+
@default_country_iso = iso
|
222
|
+
|
223
|
+
country = Spree::Country.by_iso(iso)
|
135
224
|
|
136
|
-
|
225
|
+
if country.present?
|
226
|
+
self.default_country = country
|
227
|
+
elsif iso_country = ::Country[iso]
|
228
|
+
new_country = Spree::Country.create!(
|
229
|
+
iso_name: iso_country.local_name&.upcase,
|
230
|
+
iso: iso_country.alpha2,
|
231
|
+
iso3: iso_country.alpha3,
|
232
|
+
name: iso_country.local_name,
|
233
|
+
numcode: iso_country.number,
|
234
|
+
states_required: Spree::Address::STATES_REQUIRED.include?(iso),
|
235
|
+
zipcode_required: !Spree::Address::NO_ZIPCODE_ISO_CODES.include?(iso)
|
236
|
+
)
|
237
|
+
|
238
|
+
self.default_country = new_country
|
239
|
+
end
|
137
240
|
end
|
138
241
|
|
139
242
|
def supported_currencies_list
|
140
|
-
@supported_currencies_list ||= (read_attribute(:supported_currencies).to_s.split(',')
|
243
|
+
@supported_currencies_list ||= ([default_currency] + read_attribute(:supported_currencies).to_s.split(',')).uniq.map(&:to_s).map do |code|
|
141
244
|
::Money::Currency.find(code.strip)
|
142
|
-
end.
|
143
|
-
end
|
144
|
-
|
145
|
-
def homepage(requested_locale)
|
146
|
-
cms_pages.by_locale(requested_locale).find_by(type: 'Spree::Cms::Pages::Homepage') ||
|
147
|
-
cms_pages.by_locale(default_locale).find_by(type: 'Spree::Cms::Pages::Homepage') ||
|
148
|
-
cms_pages.find_by(type: 'Spree::Cms::Pages::Homepage')
|
245
|
+
end.compact.sort_by { |currency| currency.iso_code == default_currency ? 0 : 1 }
|
149
246
|
end
|
150
247
|
|
151
248
|
def seo_meta_description
|
@@ -159,7 +256,6 @@ module Spree
|
|
159
256
|
end
|
160
257
|
|
161
258
|
def supported_locales_list
|
162
|
-
# TODO: add support of multiple supported languages to a single Store
|
163
259
|
@supported_locales_list ||= (read_attribute(:supported_locales).to_s.split(',') << default_locale).compact.uniq.sort
|
164
260
|
end
|
165
261
|
|
@@ -168,21 +264,64 @@ module Spree
|
|
168
264
|
end
|
169
265
|
|
170
266
|
def formatted_url
|
171
|
-
|
267
|
+
@formatted_url ||= begin
|
268
|
+
clean_url = url.to_s.sub(%r{^https?://}, '').split(':').first
|
269
|
+
|
270
|
+
if Rails.env.development? || Rails.env.test?
|
271
|
+
scheme = Rails.application.routes.default_url_options[:protocol] || :http
|
272
|
+
port = Rails.application.routes.default_url_options[:port].presence || (Rails.env.development? ? 3000 : nil)
|
273
|
+
|
274
|
+
if scheme.to_sym == :https
|
275
|
+
URI::HTTPS.build(
|
276
|
+
host: clean_url,
|
277
|
+
port: port
|
278
|
+
).to_s
|
279
|
+
else
|
280
|
+
URI::HTTP.build(
|
281
|
+
host: clean_url,
|
282
|
+
port: port
|
283
|
+
).to_s
|
284
|
+
end
|
285
|
+
else
|
286
|
+
URI::HTTPS.build(
|
287
|
+
host: clean_url
|
288
|
+
).to_s
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
def formatted_custom_domain
|
294
|
+
return unless default_custom_domain
|
172
295
|
|
173
|
-
@
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
296
|
+
@formatted_custom_domain ||= if Rails.env.development? || Rails.env.test?
|
297
|
+
URI::Generic.build(
|
298
|
+
scheme: Rails.application.routes.default_url_options[:protocol] || 'http',
|
299
|
+
host: default_custom_domain.url,
|
300
|
+
port: Rails.application.routes.default_url_options[:port]
|
301
|
+
).to_s
|
302
|
+
else
|
303
|
+
URI::HTTPS.build(host: default_custom_domain.url).to_s
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def url_or_custom_domain
|
308
|
+
default_custom_domain&.url || url
|
309
|
+
end
|
310
|
+
|
311
|
+
def formatted_url_or_custom_domain
|
312
|
+
formatted_custom_domain || formatted_url
|
178
313
|
end
|
179
314
|
|
180
315
|
def countries_available_for_checkout
|
181
|
-
@countries_available_for_checkout ||=
|
316
|
+
@countries_available_for_checkout ||= Rails.cache.fetch(countries_available_for_checkout_cache_key) do
|
317
|
+
checkout_zone.try(:country_list) || Spree::Country.all
|
318
|
+
end
|
182
319
|
end
|
183
320
|
|
184
321
|
def states_available_for_checkout(country)
|
185
|
-
|
322
|
+
Rails.cache.fetch(states_available_for_checkout_cache_key(country)) do
|
323
|
+
checkout_zone.try(:state_list_for, country) || country.states
|
324
|
+
end
|
186
325
|
end
|
187
326
|
|
188
327
|
def checkout_zone_or_default
|
@@ -191,18 +330,77 @@ module Spree
|
|
191
330
|
@checkout_zone_or_default ||= checkout_zone || Spree::Zone.default_checkout_zone
|
192
331
|
end
|
193
332
|
|
333
|
+
def supported_shipping_zones
|
334
|
+
@supported_shipping_zones ||= if checkout_zone_id.present?
|
335
|
+
[checkout_zone]
|
336
|
+
else
|
337
|
+
Spree::Zone.includes(zone_members: :zoneable).all
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
def default_stock_location
|
342
|
+
@default_stock_location ||= begin
|
343
|
+
stock_location_scope = Spree::StockLocation.order_default
|
344
|
+
stock_location_scope.first || ActiveRecord::Base.connected_to(role: :writing) do
|
345
|
+
stock_location_scope.create(default: true, name: Spree.t(:default_stock_location_name), country: default_country)
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
def admin_users
|
351
|
+
@admin_users ||= Spree.admin_user_class.joins(:spree_roles).where(spree_roles: { name: :admin })
|
352
|
+
end
|
353
|
+
|
194
354
|
def favicon
|
195
|
-
return unless favicon_image
|
355
|
+
return unless favicon_image.attached? && favicon_image.variable?
|
196
356
|
|
197
|
-
favicon_image.
|
357
|
+
favicon_image.variant(resize_to_limit: [32, 32])
|
198
358
|
end
|
199
359
|
|
200
360
|
def can_be_deleted?
|
201
361
|
self.class.where.not(id: id).any?
|
202
362
|
end
|
203
363
|
|
364
|
+
def metric_unit_system?
|
365
|
+
preferred_unit_system == 'metric'
|
366
|
+
end
|
367
|
+
|
368
|
+
def default_shipping_category
|
369
|
+
@default_shipping_category ||= ShippingCategory.find_or_create_by(name: 'Default')
|
370
|
+
end
|
371
|
+
|
372
|
+
def digital_shipping_category
|
373
|
+
@digital_shipping_category ||= ShippingCategory.find_or_create_by(name: 'Digital')
|
374
|
+
end
|
375
|
+
|
376
|
+
def import_products_from_store
|
377
|
+
store = Store.find(import_products_from_store_id)
|
378
|
+
product_ids = store.products.pluck(:id)
|
379
|
+
|
380
|
+
return if product_ids.empty?
|
381
|
+
|
382
|
+
StoreProduct.insert_all(product_ids.map { |product_id| { store_id: id, product_id: product_id } })
|
383
|
+
end
|
384
|
+
|
385
|
+
def import_payment_methods_from_store
|
386
|
+
store = Store.find(import_payment_methods_from_store_id)
|
387
|
+
payment_method_ids = store.payment_method_ids
|
388
|
+
|
389
|
+
return if payment_method_ids.empty?
|
390
|
+
|
391
|
+
StorePaymentMethod.insert_all(payment_method_ids.map { |payment_method_id| { store_id: id, payment_method_id: payment_method_id } })
|
392
|
+
end
|
393
|
+
|
204
394
|
private
|
205
395
|
|
396
|
+
def countries_available_for_checkout_cache_key
|
397
|
+
"#{cache_key_with_version}/#{checkout_zone&.cache_key_with_version}/countries_available_for_checkout"
|
398
|
+
end
|
399
|
+
|
400
|
+
def states_available_for_checkout_cache_key(country)
|
401
|
+
"#{cache_key_with_version}/#{checkout_zone&.cache_key_with_version}/states_available_for_checkout/#{country&.cache_key_with_version}"
|
402
|
+
end
|
403
|
+
|
206
404
|
def ensure_default_exists_and_is_unique
|
207
405
|
if default
|
208
406
|
Store.where.not(id: id).update_all(default: false)
|
@@ -246,7 +444,6 @@ module Spree
|
|
246
444
|
end
|
247
445
|
|
248
446
|
def ensure_default_country
|
249
|
-
return unless has_attribute?(:default_country_id)
|
250
447
|
return if default_country.present? && (checkout_zone.blank? || checkout_zone.country_list.blank? || checkout_zone.country_list.include?(default_country))
|
251
448
|
|
252
449
|
self.default_country = if checkout_zone.present? && checkout_zone.country_list.any?
|
@@ -255,5 +452,81 @@ module Spree
|
|
255
452
|
Country.find_by(iso: 'US') || Country.first
|
256
453
|
end
|
257
454
|
end
|
455
|
+
|
456
|
+
def ensure_default_taxonomies_are_created
|
457
|
+
taxonomies.find_or_create_by(name: I18n.t('spree.taxonomy_categories_name', default: I18n.t('spree.taxonomy_categories_name', locale: :en)))
|
458
|
+
taxonomies.find_or_create_by(name: I18n.t('spree.taxonomy_brands_name', default: I18n.t('spree.taxonomy_brands_name', locale: :en)))
|
459
|
+
taxonomies.find_or_create_by(name: I18n.t('spree.taxonomy_collections_name', default: I18n.t('spree.taxonomy_collections_name', locale: :en)))
|
460
|
+
rescue ActiveRecord::NotNullViolation
|
461
|
+
end
|
462
|
+
|
463
|
+
def ensure_default_automatic_taxons
|
464
|
+
collections_taxonomy = taxonomies.find_by(name: Spree.t(:taxonomy_collections_name))
|
465
|
+
|
466
|
+
if collections_taxonomy.present?
|
467
|
+
on_sale_taxon = collections_taxonomy.taxons.automatic.where(name: Spree.t('automatic_taxon_names.on_sale')).first_or_create! do |taxon|
|
468
|
+
taxon.parent = collections_taxonomy.root
|
469
|
+
taxon.rules.new(type: 'Spree::TaxonRules::Sale', value: 'true')
|
470
|
+
end
|
471
|
+
|
472
|
+
new_arrivals_taxon = collections_taxonomy.taxons.automatic.where(name: Spree.t('automatic_taxon_names.new_arrivals')).first_or_create! do |taxon|
|
473
|
+
taxon.parent = collections_taxonomy.root
|
474
|
+
taxon.rules.new(type: 'Spree::TaxonRules::AvailableOn', value: 30)
|
475
|
+
end
|
476
|
+
|
477
|
+
[on_sale_taxon, new_arrivals_taxon]
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
def ensure_default_post_categories_are_created
|
482
|
+
post_categories.find_or_create_by(title: Spree.t('default_post_categories.resources'))
|
483
|
+
post_categories.find_or_create_by(title: Spree.t('default_post_categories.articles'))
|
484
|
+
post_categories.find_or_create_by(title: Spree.t('default_post_categories.news'))
|
485
|
+
end
|
486
|
+
|
487
|
+
# code is slug, so we don't want to generate new slug when code changes
|
488
|
+
# we use friendlyId only for history feature
|
489
|
+
def should_generate_new_friendly_id?
|
490
|
+
false
|
491
|
+
end
|
492
|
+
|
493
|
+
def slug_candidates
|
494
|
+
[]
|
495
|
+
end
|
496
|
+
|
497
|
+
def handle_code_changes
|
498
|
+
# implement your custom logic here
|
499
|
+
end
|
500
|
+
|
501
|
+
# This FriendlyId method is overwitten to keep our logic for generating code
|
502
|
+
# there is no option for own format
|
503
|
+
def set_code
|
504
|
+
self.code = if code.present?
|
505
|
+
code.parameterize.strip
|
506
|
+
elsif name.present?
|
507
|
+
name.parameterize.strip
|
508
|
+
end
|
509
|
+
|
510
|
+
return if self.code.blank?
|
511
|
+
|
512
|
+
# ensure code is unique
|
513
|
+
self.code = [name.parameterize, rand(9999)].join('-') while Spree::Store.with_deleted.where(code: self.code).exists?
|
514
|
+
end
|
515
|
+
|
516
|
+
# auto-assign internal URL for stores
|
517
|
+
def set_url
|
518
|
+
return if url_changed?
|
519
|
+
return unless code_changed?
|
520
|
+
return unless Spree.root_domain.present?
|
521
|
+
|
522
|
+
self.url = [code, Spree.root_domain].join('.')
|
523
|
+
end
|
524
|
+
|
525
|
+
def create_default_theme
|
526
|
+
themes.find_or_initialize_by(default: true) do |theme|
|
527
|
+
theme.name = Spree.t(:default_theme_name)
|
528
|
+
theme.save!
|
529
|
+
end
|
530
|
+
end
|
258
531
|
end
|
259
532
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Spree
|
2
|
-
class StoreCredit < Spree
|
2
|
+
class StoreCredit < Spree.base_class
|
3
3
|
include Spree::SingleStoreResource
|
4
4
|
include Spree::Metadata
|
5
5
|
if defined?(Spree::Webhooks::HasWebhooks)
|
@@ -40,7 +40,7 @@ module Spree
|
|
40
40
|
scope :order_by_priority, -> { includes(:credit_type).order('spree_store_credit_types.priority ASC') }
|
41
41
|
|
42
42
|
scope :not_authorized, -> { where(amount_authorized: 0) }
|
43
|
-
scope :not_used, -> { where(
|
43
|
+
scope :not_used, -> { where("#{Spree::StoreCredit.table_name}.amount_used < #{Spree::StoreCredit.table_name}.amount") }
|
44
44
|
scope :available, -> { not_authorized.not_used }
|
45
45
|
|
46
46
|
after_save :store_event
|
@@ -49,7 +49,7 @@ module Spree
|
|
49
49
|
attr_accessor :action, :action_amount, :action_originator, :action_authorization_code
|
50
50
|
|
51
51
|
extend Spree::DisplayMoney
|
52
|
-
money_methods :amount, :amount_used
|
52
|
+
money_methods :amount, :amount_used, :amount_remaining, :amount_authorized
|
53
53
|
|
54
54
|
self.whitelisted_ransackable_attributes = %w[user_id created_by_id amount currency type_id]
|
55
55
|
self.whitelisted_ransackable_associations = %w[type user created_by]
|
@@ -170,6 +170,14 @@ module Spree
|
|
170
170
|
payment.completed? && payment.credit_allowed > 0
|
171
171
|
end
|
172
172
|
|
173
|
+
def editable?
|
174
|
+
amount_used.zero? && amount_authorized.zero?
|
175
|
+
end
|
176
|
+
|
177
|
+
def can_be_deleted?
|
178
|
+
amount_used.zero? && amount_authorized.zero?
|
179
|
+
end
|
180
|
+
|
173
181
|
def generate_authorization_code
|
174
182
|
"#{id}-SC-#{Time.now.utc.strftime('%Y%m%d%H%M%S%6N')}"
|
175
183
|
end
|
@@ -228,7 +236,7 @@ module Spree
|
|
228
236
|
event.update!(
|
229
237
|
amount: action_amount || amount,
|
230
238
|
authorization_code: action_authorization_code || event.authorization_code || generate_authorization_code,
|
231
|
-
user_total_amount: user
|
239
|
+
user_total_amount: user&.total_available_store_credit || 0,
|
232
240
|
originator: action_originator
|
233
241
|
)
|
234
242
|
end
|