ba_spree 1.0.0
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 +7 -0
- data/LICENSE +673 -0
- data/README.md +150 -0
- data/app/assets/config/manifest.js +1 -0
- data/app/assets/javascripts/ba_spree/admin_overrides/query_builder_controller.js +505 -0
- data/app/assets/javascripts/ba_spree/storefront/ba_spree_local_time.js +9 -0
- data/app/assets/stylesheets/spree/admin/custom.scss +40 -0
- data/app/controllers/ba_spree/checkout_controller_decorator.rb +111 -0
- data/app/controllers/ba_spree/store_controller_decorator.rb +55 -0
- data/app/controllers/concerns/ba_spree/theme_concern_decorator.rb +16 -0
- data/app/controllers/spree/admin/assets_controller_decorator.rb +48 -0
- data/app/controllers/spree/admin/products_controller_decorator.rb +25 -0
- data/app/controllers/spree/admin/promotion_rules_controller_decorator.rb +30 -0
- data/app/controllers/spree/admin/users_controller_decorator.rb +34 -0
- data/app/controllers/spree/contacts_controller_decorator.rb +23 -0
- data/app/controllers/spree/digital_links_controller.rb +61 -0
- data/app/controllers/spree/orders_controller_decorator.rb +24 -0
- data/app/decorators/ba_spree/product_pricing_decorator.rb +65 -0
- data/app/decorators/spree/current_decorator.rb +17 -0
- data/app/decorators/spree/money_decorator.rb +51 -0
- data/app/decorators/spree/order_email_subscriber_decorator.rb +64 -0
- data/app/decorators/spree/page_sections/featured_posts_decorator.rb +17 -0
- data/app/helpers/currency_rounding_helper.rb +10 -0
- data/app/helpers/spree/admin/filter_params_preservation.rb +130 -0
- data/app/helpers/spree/admin/navigation_helper_decorator.rb +23 -0
- data/app/helpers/spree/admin/promotion_rules_helper_decorator.rb +33 -0
- data/app/helpers/spree/admin/table_helper_decorator.rb +40 -0
- data/app/helpers/spree/base_helper_decorator.rb +63 -0
- data/app/helpers/spree/checkout_analytics_helper_decorator.rb +32 -0
- data/app/javascript/ba_spree/controllers/disable_when_hidden_controller.js +70 -0
- data/app/javascript/ba_spree/index.js +11 -0
- data/app/javascript/spree/admin/controllers/calendar_range_controller.js +61 -0
- data/app/javascript/spree/admin/controllers/slug_form_controller.js +17 -0
- data/app/models/ba_spree/address_decorator.rb +43 -0
- data/app/models/ba_spree/adjustment_decorator.rb +13 -0
- data/app/models/ba_spree/order_decorator.rb +95 -0
- data/app/models/ba_spree/order_updater_decorator.rb +33 -0
- data/app/models/ba_spree/payment_method_decorator.rb +10 -0
- data/app/models/ba_spree/product_decorator.rb +44 -0
- data/app/models/ba_spree/store_decorator.rb +23 -0
- data/app/models/ba_spree/variant_decorator.rb +49 -0
- data/app/models/concerns/spree/adjustment_source_decorator.rb +66 -0
- data/app/models/concerns/spree/product_property_metafields.rb +52 -0
- data/app/models/spree/adjustable/adjuster/promotion_decorator.rb +16 -0
- data/app/models/spree/admin/table/filter_decorator.rb +52 -0
- data/app/models/spree/admin/table/filter_group_decorator.rb +64 -0
- data/app/models/spree/asset_decorator.rb +102 -0
- data/app/models/spree/contact_decorator.rb +22 -0
- data/app/models/spree/digital_link_decorator.rb +9 -0
- data/app/models/spree/export_decorator.rb +34 -0
- data/app/models/spree/line_item_destroy_callback_decorator.rb +30 -0
- data/app/models/spree/metafield_definition_decorator.rb +34 -0
- data/app/models/spree/option_type_decorator.rb +22 -0
- data/app/models/spree/option_value_decorator.rb +19 -0
- data/app/models/spree/option_value_variant_decorator.rb +30 -0
- data/app/models/spree/order/address_book_decorator.rb +14 -0
- data/app/models/spree/order_merger_decorator.rb +29 -0
- data/app/models/spree/price_rules/customer_group_rule_decorator.rb +18 -0
- data/app/models/spree/price_rules/user_rule_decorator.rb +25 -0
- data/app/models/spree/price_rules/volume_rule_decorator.rb +25 -0
- data/app/models/spree/price_rules/zone_rule_decorator.rb +25 -0
- data/app/models/spree/pricing/batch_resolver.rb +96 -0
- data/app/models/spree/promotion_handler/cart_decorator.rb +51 -0
- data/app/models/spree/stock/packer_decorator.rb +61 -0
- data/app/models/spree/stock/prioritizer_decorator.rb +27 -0
- data/app/models/spree/tax_rate_decorator.rb +93 -0
- data/app/models/spree/taxon_decorator.rb +42 -0
- data/app/models/spree/user_bill_address_sync_decorator.rb +33 -0
- data/app/overrides/add_ba_spree_storefront_javascript_importmap_tags.rb +8 -0
- data/app/overrides/add_cache_to_product_listing_page.rb +41 -0
- data/app/overrides/add_class_to_login_link.rb +6 -0
- data/app/overrides/add_confirm_state_to_checkout_content_block.rb.rb +30 -0
- data/app/overrides/add_promotions_nav.rb +8 -0
- data/app/overrides/add_turbo_frame_to_admin_order_line_item_edit_link.rb +23 -0
- data/app/overrides/add_turbo_frame_to_promotion_action_edit_link.rb +20 -0
- data/app/overrides/add_turbo_stream_format_to_cart_path_in_cart_pane.rb +8 -0
- data/app/overrides/ba_spree_local_time_add_custom_javascript_import_map_tags.rb +8 -0
- data/app/overrides/disable_hidden_bill_address_fields_on_payment.rb +15 -0
- data/app/overrides/disable_turbo_on_user_registration_form.rb +18 -0
- data/app/overrides/fix_coupon_apply_button_layout.rb +7 -0
- data/app/overrides/hide_gift_cards_and_store_credits_from_account_nav.rb +11 -0
- data/app/overrides/hide_shipping_message_for_digital_only_orders.rb +15 -0
- data/app/overrides/localize_apply_button_text.rb +6 -0
- data/app/overrides/localize_newsletter_button_text.rb +6 -0
- data/app/overrides/replace_announcement_bar_text.rb +6 -0
- data/app/overrides/replace_button_edit_checkout.rb +10 -0
- data/app/overrides/replace_checkout_delivery_info.rb +6 -0
- data/app/overrides/replace_checkout_pay_button_with_dynamic_label.rb +14 -0
- data/app/overrides/replace_variant_not_available_button.rb +19 -0
- data/app/overrides/set_logo_width_height_in_admin_store_basic_form.rb +12 -0
- data/app/overrides/show_breadcrumbs_on_taxon_page.rb +30 -0
- data/app/overrides/show_individual_adjustments_in_order_details.rb +18 -0
- data/app/overrides/show_only_selected_payment_method_on_confirm.rb +29 -0
- data/app/overrides/spree/admin/preserve_filter_params_across_table_forms.rb +64 -0
- data/app/overrides/spree/admin/promotion_rules/_promotion_rule/set_turbo_frame_on_edit_link.html.erb.deface +11 -0
- data/app/overrides/spree/admin/stores/add_special_instruction_message_settings.rb +17 -0
- data/app/overrides/use_absolute_time_for_order_header_completed_at.rb +15 -0
- data/app/presenters/spree/mega_nav_presenter_decorator.rb +26 -0
- data/app/services/ba_spree/setup_service.rb +144 -0
- data/app/services/spree/assets/position_normalizer.rb +67 -0
- data/app/services/spree/products/duplicator_decorator.rb +39 -0
- data/app/services/spree/products/prepare_nested_attributes_decorator.rb +58 -0
- data/app/views/spree/addresses/edit.html.erb +64 -0
- data/app/views/spree/admin/orders/_order.html.erb +32 -0
- data/app/views/spree/admin/orders/_summary.html.erb +122 -0
- data/app/views/spree/admin/shared/_custom_head.html.erb +56 -0
- data/app/views/spree/admin/shared/sidebar/_promotions_nav.html.erb +55 -0
- data/app/views/spree/admin/stores/_special_instruction_message_settings.html.erb +14 -0
- data/app/views/spree/checkout/_accept_marketing_checkbox.html.erb +40 -0
- data/app/views/spree/checkout/_address.html.erb +135 -0
- data/app/views/spree/checkout/_confirm.html.erb +25 -0
- data/app/views/spree/checkout/_line_item.html.erb +26 -0
- data/app/views/spree/checkout/_payment_method_confirm.html.erb +8 -0
- data/app/views/spree/checkout/_payment_methods.html.erb +88 -0
- data/app/views/spree/checkout/_summary.html.erb +146 -0
- data/app/views/spree/shared/_purchased_items_table.html.erb +60 -0
- data/app/views/spree/shared/_purchased_items_table.text.erb +24 -0
- data/app/views/themes/default/spree/orders/_empty.html.erb +14 -0
- data/app/views/themes/default/spree/orders/_summary.html.erb +87 -0
- data/app/views/themes/default/spree/orders/edit.turbo_stream.erb +10 -0
- data/app/views/themes/default/spree/page_sections/_featured_taxons.html.erb +38 -0
- data/app/views/themes/default/spree/page_sections/_header.html.erb +124 -0
- data/app/views/themes/default/spree/page_sections/_newsletter.html.erb +4 -0
- data/app/views/themes/default/spree/page_sections/_post_details.html.erb +22 -0
- data/app/views/themes/default/spree/page_sections/_product_details.html.erb +88 -0
- data/app/views/themes/default/spree/page_sections/_product_grid.html.erb +58 -0
- data/app/views/themes/default/spree/page_sections/nav/_desktop.html.erb +94 -0
- data/app/views/themes/default/spree/page_sections/nav/_mobile.html.erb +148 -0
- data/app/views/themes/default/spree/posts/_post.html.erb +16 -0
- data/app/views/themes/default/spree/products/_description.html.erb +7 -0
- data/app/views/themes/default/spree/products/_details.html.erb +65 -0
- data/app/views/themes/default/spree/products/_json_ld_variant.html.erb +15 -0
- data/app/views/themes/default/spree/products/_price.html.erb +76 -0
- data/app/views/themes/default/spree/products/_swiper.html.erb +90 -0
- data/app/views/themes/default/spree/shared/_account_pane.html.erb +18 -0
- data/app/views/themes/default/spree/shared/_cart_icon.html.erb +19 -0
- data/app/views/themes/default/spree/shared/_line_item_options.html.erb +9 -0
- data/app/views/themes/default/spree/shared/_logo.html.erb +39 -0
- data/app/views/themes/default/spree/shared/_nav_taxon_square_image.html.erb +8 -0
- data/app/views/themes/default/spree/shared/_order_shipment.html.erb +79 -0
- data/app/views/themes/default/spree/shared/_search.html.erb +33 -0
- data/app/views/themes/default/spree/shared/icons/_cart.html.erb +6 -0
- data/app/views/themes/default/spree/shared/icons/_cart_48.html.erb +8 -0
- data/app/views/themes/default/spree/shared/icons/_heart.html.erb +15 -0
- data/config/importmap.rb +12 -0
- data/config/initializers/admin_navigation.rb +43 -0
- data/config/initializers/spree.rb +6 -0
- data/config/initializers/spree_admin_label_i18n_alias.rb +52 -0
- data/config/initializers/spree_admin_tables.rb +57 -0
- data/config/initializers/spree_permitted_attributes.rb +1 -0
- data/config/locales/en.yml +15 -0
- data/config/locales/ja.yml +18 -0
- data/config/locales/spree.en.yml +4 -0
- data/config/locales/spree.ja.yml +3493 -0
- data/lib/ba_spree/engine.rb +41 -0
- data/lib/ba_spree/spree_events_dedup_patch.rb +44 -0
- data/lib/ba_spree/version.rb +3 -0
- data/lib/ba_spree.rb +20 -0
- data/lib/generators/ba_spree/install/install_generator.rb +85 -0
- metadata +594 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
# Spree 5.3.6 の注文確認 / 店舗オーナー通知メールが、本番のインスタンス複数台 + Sidekiq 非同期
|
|
3
|
+
# 環境で2通送信される race condition への対策。
|
|
4
|
+
#
|
|
5
|
+
# 本家 OrderEmailSubscriber#send_confirmation_email は
|
|
6
|
+
# ① return if order.confirmation_delivered? (チェック)
|
|
7
|
+
# ② OrderMailer.confirm_email(...).deliver_later (送信)
|
|
8
|
+
# ③ order.update_column(:confirmation_delivered, true) (フラグ更新)
|
|
9
|
+
# の順で、①〜③が非アトミック。さらに本家は complete 遷移時に order.completed を2回 publish するため
|
|
10
|
+
# (finalize! 内 + after_transition)、2インスタンスが①を同時に false で通過すると②を両方実行し2通になる。
|
|
11
|
+
#
|
|
12
|
+
# 「flag=false の行を true に更新できた1プロセスだけが送信権を得る」条件付き UPDATE 一発に変更し、
|
|
13
|
+
# MySQL の行ロックで直列化することで、同時実行でも送信を1通に絞る。
|
|
14
|
+
# 確認メール / 店舗オーナー通知の両方が同型の race を持つため、両方に適用する。
|
|
15
|
+
#
|
|
16
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1232
|
|
17
|
+
module OrderEmailSubscriberDecorator
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
# @gem-override spree_emails-5.3.6/app/subscribers/spree/order_email_subscriber.rb#send_confirmation_email
|
|
21
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1232
|
|
22
|
+
def send_confirmation_email(event)
|
|
23
|
+
order = find_order(event)
|
|
24
|
+
return unless order
|
|
25
|
+
return unless order.store.prefers_send_consumer_transactional_emails?
|
|
26
|
+
|
|
27
|
+
# アトミックに false→true を更新できた1プロセスだけが送信する(多重送信防止)
|
|
28
|
+
return if claim_delivery_flag(order, :confirmation_delivered).zero?
|
|
29
|
+
|
|
30
|
+
OrderMailer.confirm_email(order.id).deliver_later
|
|
31
|
+
|
|
32
|
+
send_store_owner_notification(order) if order.store.new_order_notifications_email.present?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @gem-override spree_emails-5.3.6/app/subscribers/spree/order_email_subscriber.rb#send_store_owner_notification
|
|
36
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1232
|
|
37
|
+
def send_store_owner_notification(order)
|
|
38
|
+
return if order.store.new_order_notifications_email.blank?
|
|
39
|
+
return if claim_delivery_flag(order, :store_owner_notification_delivered).zero?
|
|
40
|
+
|
|
41
|
+
OrderMailer.store_owner_notification_email(order.id).deliver_later
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# id 指定 + 当該フラグが「未送信」の行を true に更新し、更新できた行数を返す。
|
|
45
|
+
# 同時実行時は MySQL の行ロックで直列化され、勝者のみ 1、それ以外は 0 を得る。
|
|
46
|
+
#
|
|
47
|
+
# 「未送信」は false だけでなく NULL も含める必要がある。
|
|
48
|
+
# store_owner_notification_delivered は upstream スキーマ上 default 未指定 (= NULL) で、
|
|
49
|
+
# 新規注文ではこのカラムが NULL のまま作られる。`column => false` だけだと MySQL の
|
|
50
|
+
# `NULL = FALSE` が真にならず更新0行となり、店舗オーナー通知が永久に送られない (#1241)。
|
|
51
|
+
def claim_delivery_flag(order, column)
|
|
52
|
+
Spree::Order
|
|
53
|
+
.where(id: order.id)
|
|
54
|
+
.where(arel_table[column].eq(false).or(arel_table[column].eq(nil)))
|
|
55
|
+
.update_all(column => true)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def arel_table
|
|
59
|
+
Spree::Order.arel_table
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
Spree::OrderEmailSubscriber.prepend(Spree::OrderEmailSubscriberDecorator)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
module PageSections
|
|
5
|
+
module FeaturedPostsDecorator
|
|
6
|
+
def retrieve_posts
|
|
7
|
+
Spree::Post.where(store: store)
|
|
8
|
+
.where("published_at < ?", Time.zone.now.utc)
|
|
9
|
+
.order(id: :desc)
|
|
10
|
+
.includes(:post_category)
|
|
11
|
+
.limit(preferred_max_posts_to_show)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
::Spree::PageSections::FeaturedPosts.prepend(Spree::PageSections::FeaturedPostsDecorator)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module CurrencyRoundingHelper
|
|
2
|
+
def round_by_currency(amount, currency)
|
|
3
|
+
decimal_places = currency_decimal_places(currency)
|
|
4
|
+
BigDecimal(amount.to_s).round(decimal_places, BigDecimal::ROUND_HALF_UP)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def currency_decimal_places(currency)
|
|
8
|
+
Money::Currency.find(currency).decimal_places
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
module Admin
|
|
5
|
+
# 一覧テーブル (spree/admin/tables/_table) の絞り込み条件は、操作するたびに URL から消えてしまう。
|
|
6
|
+
#
|
|
7
|
+
# 1. ツールバーの「検索」「期間」「フィルタービルダー」は独立した GET フォームで、
|
|
8
|
+
# GET フォームは送信時に action URL のクエリ文字列を捨てて自分の入力だけを付け直すため、
|
|
9
|
+
# どれか一つを適用すると他のフォームの条件が消える。
|
|
10
|
+
# 2. 並び替え・表示件数のリンクは url_for / query_parameters.slice(:q) で組まれており、
|
|
11
|
+
# query_state が落ちる (q は残るので結果は絞り込まれたままだが、
|
|
12
|
+
# フィルターの件数バッジとドロワーが空になり「効いているのに見えないフィルタ」状態になる)。
|
|
13
|
+
#
|
|
14
|
+
# 絞り込み条件を引き継ぐための共通処理をここにまとめる。
|
|
15
|
+
#
|
|
16
|
+
# なおコントローラの TableConcern#process_table_query_state が query_state を params[:q] に
|
|
17
|
+
# マージし直すため、query_state さえ引き継げば ransack のパラメータは再生成される。
|
|
18
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1262
|
|
19
|
+
module FilterParamsPreservation
|
|
20
|
+
# 絞り込み条件ではないため引き継がないパラメータ
|
|
21
|
+
# (page: 条件を変えたら1ページ目に戻すのが自然、commit: 送信ボタンのラベル)
|
|
22
|
+
NON_FILTER_PARAMS = %w[page commit utf8 authenticity_token _method].freeze
|
|
23
|
+
|
|
24
|
+
# 現在の URL にある絞り込みパラメータのうち、そのフォーム自身が送信しないものを
|
|
25
|
+
# hidden input として出力する。
|
|
26
|
+
#
|
|
27
|
+
# @param except_q [Array<String, Symbol>] フォーム自身が送信する q[...] のキー
|
|
28
|
+
# @param owns_query_state [Boolean] フィルタービルダーのフォームなら true。
|
|
29
|
+
# query_state と、そこから生成される q[...] を除外する
|
|
30
|
+
# (フィルターを削除したときに古い条件が残らないようにするため)
|
|
31
|
+
# @param table [Spree::Admin::Table, nil] owns_query_state が true のときに必要
|
|
32
|
+
# @return [String] hidden input の HTML
|
|
33
|
+
def preserved_filter_params_inputs(except_q: [], owns_query_state: false, table: nil)
|
|
34
|
+
preserved = request.query_parameters.deep_dup
|
|
35
|
+
NON_FILTER_PARAMS.each { |key| preserved.delete(key) }
|
|
36
|
+
|
|
37
|
+
excluded_q_keys = except_q.map(&:to_s)
|
|
38
|
+
if owns_query_state
|
|
39
|
+
preserved.delete('query_state')
|
|
40
|
+
excluded_q_keys += query_state_ransack_keys(table)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
if preserved['q'].is_a?(Hash)
|
|
44
|
+
remaining_q = sanitize_ransack_params(preserved['q']).except(*excluded_q_keys)
|
|
45
|
+
remaining_q.present? ? preserved['q'] = remaining_q : preserved.delete('q')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
hidden_inputs_for_params(preserved)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# ページネーションのリンク用パラメータ。
|
|
52
|
+
# 本家は request.query_parameters をそのまま使うため、OR グループの壊れた ransack キーが
|
|
53
|
+
# そのまま (しかも名前が変質しながら) URL に載り続ける。
|
|
54
|
+
#
|
|
55
|
+
# @param page [Integer] 遷移先のページ
|
|
56
|
+
# @return [Hash]
|
|
57
|
+
def preserved_pagination_params(page)
|
|
58
|
+
preserved = request.query_parameters.deep_dup
|
|
59
|
+
preserved['q'] = preserved_ransack_params if preserved['q'].is_a?(Hash)
|
|
60
|
+
preserved.merge(page: page)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# URL に載っている ransack のパラメータ (壊れたキーは除く)。
|
|
64
|
+
#
|
|
65
|
+
# コントローラの process_table_query_state が query_state 由来の条件を params[:q] に
|
|
66
|
+
# マージするため、params[:q] を使うと OR グループの grouping が丸ごと展開されてしまう。
|
|
67
|
+
# リンクを組むときは URL 生の q を使う (条件は query_state から再生成される)。
|
|
68
|
+
#
|
|
69
|
+
# @return [Hash]
|
|
70
|
+
def preserved_ransack_params
|
|
71
|
+
sanitize_ransack_params(request.query_parameters['q']) || {}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
# 現在の query_state を引き継ぐための url_for 用パラメータ
|
|
77
|
+
# (値が nil なら url_for が落としてくれる)
|
|
78
|
+
# @return [Hash]
|
|
79
|
+
def preserved_query_state_param
|
|
80
|
+
{ query_state: params[:query_state].presence }
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# ransack として意味をなさない壊れたキーを捨てる。
|
|
84
|
+
#
|
|
85
|
+
# フィルタービルダーで「または」グループを使うと、gem の JS が q[g[0][m]] という
|
|
86
|
+
# Rack が正しくパースできない名前の input を生成する:
|
|
87
|
+
# Rack::Utils.parse_nested_query("q[g[0][m]]=or") #=> {"q"=>{"g[0"=>{"m"=>{"]"=>"or"}}}}
|
|
88
|
+
# これをそのまま引き継ぐと名前が変質したまま増殖していくので捨てる。
|
|
89
|
+
# OR の条件は query_state から正しく再生成されるため、捨てても絞り込み結果は変わらない。
|
|
90
|
+
#
|
|
91
|
+
# @param q_params [Hash, nil]
|
|
92
|
+
# @return [Hash, nil]
|
|
93
|
+
def sanitize_ransack_params(q_params)
|
|
94
|
+
return q_params unless q_params.is_a?(Hash)
|
|
95
|
+
|
|
96
|
+
q_params.reject { |key, _value| key.to_s.match?(/[\[\]]/) }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# 現在の query_state から生成される ransack のキー
|
|
100
|
+
# (コントローラの process_table_query_state と同じ変換を行う)
|
|
101
|
+
# @return [Array<String>]
|
|
102
|
+
def query_state_ransack_keys(table)
|
|
103
|
+
return [] if table.blank? || params[:query_state].blank?
|
|
104
|
+
|
|
105
|
+
query_builder = Spree::Admin::Table::QueryBuilder.new(table)
|
|
106
|
+
query_builder.load_from_json(params[:query_state])
|
|
107
|
+
query_builder.to_ransack_params.keys.map(&:to_s)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# ネストしたパラメータを hidden input に展開する
|
|
111
|
+
# id は付けない (画面上の入力欄と id が重複するのを避けるため)
|
|
112
|
+
def hidden_inputs_for_params(params_hash, prefix = nil)
|
|
113
|
+
safe_join(
|
|
114
|
+
params_hash.map do |key, value|
|
|
115
|
+
name = prefix ? "#{prefix}[#{key}]" : key.to_s
|
|
116
|
+
|
|
117
|
+
case value
|
|
118
|
+
when Hash
|
|
119
|
+
hidden_inputs_for_params(value, name)
|
|
120
|
+
when Array
|
|
121
|
+
safe_join(value.map { |item| hidden_field_tag("#{name}[]", item, id: nil) })
|
|
122
|
+
else
|
|
123
|
+
hidden_field_tag(name, value, id: nil)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
module Admin
|
|
5
|
+
# 表示件数 (per page) のリンクに query_state を引き継ぐ。
|
|
6
|
+
# @see Spree::Admin::FilterParamsPreservation
|
|
7
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1262
|
|
8
|
+
module NavigationHelperDecorator
|
|
9
|
+
include Spree::Admin::FilterParamsPreservation
|
|
10
|
+
|
|
11
|
+
# 本家は request.query_parameters.slice(:q) しか引き継がないため query_state が落ちる。
|
|
12
|
+
# q は残るので結果は絞り込まれたままだが、フィルターの件数バッジとドロワーが空になってしまう。
|
|
13
|
+
# あわせて、OR グループで壊れた ransack キーが URL に載らないようにする。
|
|
14
|
+
def per_page_dropdown_params(per_page)
|
|
15
|
+
dropdown_params = super
|
|
16
|
+
dropdown_params[:q] = preserved_ransack_params if dropdown_params[:q].present?
|
|
17
|
+
dropdown_params.merge(preserved_query_state_param)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
Spree::Admin::NavigationHelper.prepend(Spree::Admin::NavigationHelperDecorator)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
module PromotionRulesHelperDecorator
|
|
4
|
+
# オプション値プロモーションルールのアクティブなオプションを取得するメソッドをオーバーライド
|
|
5
|
+
# @gem-override spree_admin-5.3.6/app/helpers/spree/admin/promotion_rules_helper.rb#active_options_for_option_value_promotion_rule
|
|
6
|
+
# reason: 実装当時は本家未実装だったため独自実装した。その後 spree_admin 5.1.6 で本家にも
|
|
7
|
+
# 同名メソッドが追加され、現在は本家実装を super なしで上書きしている状態 (commit a8034366)
|
|
8
|
+
# @see https://github.com/be-agile/giga-repeat/commit/a803436627949044869c3dfdae26f8909ecaf617
|
|
9
|
+
def active_options_for_option_value_promotion_rule(promotion_rule)
|
|
10
|
+
eligible_values = promotion_rule.preferred_eligible_values || []
|
|
11
|
+
return [] if eligible_values.empty?
|
|
12
|
+
|
|
13
|
+
# eligible_valuesはoption_value_idのリストなので、idではなくoption_value_idで検索
|
|
14
|
+
option_values = Spree::OptionValue.joins(:option_type)
|
|
15
|
+
.where(id: eligible_values)
|
|
16
|
+
.select('spree_option_values.id,
|
|
17
|
+
spree_option_values.presentation AS value_presentation,
|
|
18
|
+
spree_option_types.presentation AS type_presentation')
|
|
19
|
+
|
|
20
|
+
# tom-select用のJSON形式にフォーマット
|
|
21
|
+
option_values.map do |ov|
|
|
22
|
+
{
|
|
23
|
+
id: ov.id,
|
|
24
|
+
name: "#{ov.type_presentation}: #{ov.value_presentation}"
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Decoratorを適用
|
|
33
|
+
Spree::Admin::PromotionRulesHelper.prepend(Spree::Admin::PromotionRulesHelperDecorator)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
module Admin
|
|
5
|
+
# 一覧テーブルの絞り込み条件を引き継ぐ。
|
|
6
|
+
# ビューからは preserved_filter_params_inputs を使う (Deface で各フォームに差し込んでいる)。
|
|
7
|
+
# @see Spree::Admin::FilterParamsPreservation
|
|
8
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1262
|
|
9
|
+
module TableHelperDecorator
|
|
10
|
+
include Spree::Admin::FilterParamsPreservation
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
# 並び替えリンクに query_state を引き継ぐ。
|
|
15
|
+
#
|
|
16
|
+
# 本家は url_for(q: ...) でリンクを組むため query_state が落ちる。q は残るので結果は
|
|
17
|
+
# 絞り込まれたままだが、フィルターの件数バッジとドロワーが空になってしまう。
|
|
18
|
+
#
|
|
19
|
+
# 引数の current_q (= params[:q]) はコントローラが query_state 由来の条件をマージした後の値で、
|
|
20
|
+
# OR グループの grouping が丸ごと展開されてリンクが肥大する。URL 生の q を使えば
|
|
21
|
+
# 表示件数・ページネーションのリンクと同じ内容になり、条件は query_state から再生成される。
|
|
22
|
+
#
|
|
23
|
+
# @gem-override spree_admin-5.3.6/app/helpers/spree/admin/table_helper.rb#sort_dropdown_item
|
|
24
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1262
|
|
25
|
+
def sort_dropdown_item(label, sort_value, is_active, _current_q)
|
|
26
|
+
sort_params = preserved_query_state_param.merge(q: preserved_ransack_params.merge(s: sort_value))
|
|
27
|
+
|
|
28
|
+
link_to(
|
|
29
|
+
url_for(sort_params),
|
|
30
|
+
class: "dropdown-item flex items-center justify-between #{'active' if is_active}",
|
|
31
|
+
data: { turbo_action: 'advance' }
|
|
32
|
+
) do
|
|
33
|
+
safe_join([ content_tag(:span, label), is_active ? icon('check') : '' ])
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
Spree::Admin::TableHelper.prepend(Spree::Admin::TableHelperDecorator)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module BaseHelperDecorator
|
|
3
|
+
CHILD_TAXONS_SECTION_DEFAULT_PREFERENCES = {
|
|
4
|
+
heading_size: 'medium',
|
|
5
|
+
heading_alignment: 'center'
|
|
6
|
+
}.freeze
|
|
7
|
+
|
|
8
|
+
# 子カテゴリを「注目カテゴリ」セクションとして描画する。
|
|
9
|
+
# taxon ページの商品グリッド (_product_grid.html.erb) から呼ばれる。
|
|
10
|
+
def render_child_taxons_section(taxon, preferences: CHILD_TAXONS_SECTION_DEFAULT_PREFERENCES)
|
|
11
|
+
return if taxon.blank?
|
|
12
|
+
|
|
13
|
+
children = taxon.children
|
|
14
|
+
return if children.blank?
|
|
15
|
+
|
|
16
|
+
section = Spree::PageSections::FeaturedTaxons.build
|
|
17
|
+
(preferences || {}).each do |key, value|
|
|
18
|
+
section.send("preferred_#{key}=", value)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
section.links = children.map do |child|
|
|
22
|
+
Spree::PageLink.build(label: child.name, linkable: child)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
render('spree/page_sections/featured_taxons', section: ChildTaxonsSection.new(section))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# 永続化されていない PageSection をラップし、フラグメントキャッシュのキーを
|
|
29
|
+
# 子カテゴリの内容から導出する。
|
|
30
|
+
# 未保存の AR レコードは cache_key が常に ".../new" になり、カテゴリを跨いで
|
|
31
|
+
# キャッシュが衝突するため。
|
|
32
|
+
class ChildTaxonsSection < SimpleDelegator
|
|
33
|
+
def cache_key
|
|
34
|
+
child_taxon_ids = links.map(&:linkable_id)
|
|
35
|
+
max_updated_at = links.filter_map(&:linkable).map(&:updated_at).max.to_i
|
|
36
|
+
"spree/page_sections/child_taxons/#{child_taxon_ids.join('-')}-#{max_updated_at}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# ActiveSupport::Cache は cache_key より先にこちらを見るため、
|
|
40
|
+
# 委譲先の実装が使われないよう合わせて上書きする
|
|
41
|
+
def cache_key_with_version
|
|
42
|
+
cache_key
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def sort_adjustments_with_flat_percent_last(adjustments)
|
|
47
|
+
adjustments.sort_by do |adj|
|
|
48
|
+
if adj.adjustable_type == 'Spree::Order' && adj.source_type == 'Spree::PaymentMethod'
|
|
49
|
+
3
|
|
50
|
+
elsif adj.source_type == 'Spree::PromotionAction' &&
|
|
51
|
+
adj.source&.calculator&.is_a?(Spree::Calculator::FlatPercentOrderTotal)
|
|
52
|
+
2
|
|
53
|
+
elsif adj.source_type == 'Spree::PromotionAction'
|
|
54
|
+
1
|
|
55
|
+
else
|
|
56
|
+
0
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
Spree::BaseHelper.prepend Spree::BaseHelperDecorator
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module CheckoutAnalyticsHelperDecorator
|
|
3
|
+
# @gem-override spree_storefront-5.3.6/app/helpers/spree/checkout_analytics_helper.rb#clear_checkout_completed_session
|
|
4
|
+
# reason: 本家のセッションクリア (super) に加え、ゲスト注文の token cookie・signed cookie・
|
|
5
|
+
# return_to セッションも削除して不要なリダイレクトを防ぐ (commit 5df2e778)
|
|
6
|
+
# @see https://github.com/be-agile/giga-repeat/commit/5df2e7780bcd683db4dfb369edc26c72f73d1d5b
|
|
7
|
+
def clear_checkout_completed_session
|
|
8
|
+
super
|
|
9
|
+
# Clear guest order tokens from cookies
|
|
10
|
+
cookies.delete(:token) if cookies[:token].present?
|
|
11
|
+
cookies.delete(:guest_token) if cookies[:guest_token].present?
|
|
12
|
+
cookies.delete(:order_token) if cookies[:order_token].present?
|
|
13
|
+
|
|
14
|
+
# Clear permanent signed tokens
|
|
15
|
+
cookies.permanent.signed[:token] = nil if cookies.permanent.signed[:token].present?
|
|
16
|
+
cookies.permanent.signed[:guest_token] = nil if cookies.permanent.signed[:guest_token].present?
|
|
17
|
+
cookies.permanent.signed[:order_token] = nil if cookies.permanent.signed[:order_token].present?
|
|
18
|
+
|
|
19
|
+
# Clear session-based stored locations that cause unwanted redirects
|
|
20
|
+
session.delete("user_return_to") if session["user_return_to"]
|
|
21
|
+
session.delete("#{resource_name}_return_to") if session["#{resource_name}_return_to"]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def resource_name
|
|
27
|
+
:user
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
Spree::CheckoutAnalyticsHelper.prepend(Spree::CheckoutAnalyticsHelperDecorator)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
|
2
|
+
|
|
3
|
+
// 非表示(hidden クラス等で display:none)になっている間、配下の入力欄を disabled にする。
|
|
4
|
+
//
|
|
5
|
+
// 目的: チェックアウトの payment 画面では、請求先住所(bill_address)フォームが
|
|
6
|
+
// 「配送先と同じ(use_shipping)」のとき hidden クラスで隠されるが、中の
|
|
7
|
+
// firstname_kana / lastname_kana などには required が付いたまま残る。
|
|
8
|
+
// この状態で「保存して続ける」を押すと、ブラウザの HTML5 バリデーションが
|
|
9
|
+
// 空の required フィールドを検証しようとし、対象が非表示で focus できないため
|
|
10
|
+
// "An invalid form control ... is not focusable"
|
|
11
|
+
// を出して submit を完全に中止する(POST が一切飛ばない)。
|
|
12
|
+
//
|
|
13
|
+
// 非表示の input を disabled にすると、HTML5 バリデーションの対象から外れ、
|
|
14
|
+
// かつフォーム送信にも含まれなくなるため、この問題を回避できる。
|
|
15
|
+
// 表示に戻った際は disabled を解除し、required 等の挙動を元通りにする。
|
|
16
|
+
// @see https://github.com/be-agile/giga-repeat/issues/1210
|
|
17
|
+
export default class extends Controller {
|
|
18
|
+
connect() {
|
|
19
|
+
this.observer = new MutationObserver(() => this.sync())
|
|
20
|
+
this.observer.observe(this.element, {
|
|
21
|
+
attributes: true,
|
|
22
|
+
attributeFilter: ["class", "style"]
|
|
23
|
+
})
|
|
24
|
+
this.sync()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
disconnect() {
|
|
28
|
+
if (this.observer) {
|
|
29
|
+
this.observer.disconnect()
|
|
30
|
+
this.observer = null
|
|
31
|
+
}
|
|
32
|
+
// コントローラ離脱時に disabled を残さない(送信から欠落させない)
|
|
33
|
+
this.enableControls()
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
sync() {
|
|
37
|
+
if (this.isHidden()) {
|
|
38
|
+
this.disableControls()
|
|
39
|
+
} else {
|
|
40
|
+
this.enableControls()
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// offsetParent が null = display:none(hidden クラス含む)で実際に非表示
|
|
45
|
+
isHidden() {
|
|
46
|
+
return this.element.offsetParent === null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
disableControls() {
|
|
50
|
+
this.controls().forEach((el) => {
|
|
51
|
+
if (!el.disabled) {
|
|
52
|
+
el.dataset.disabledByHidden = "true"
|
|
53
|
+
el.disabled = true
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
enableControls() {
|
|
59
|
+
this.controls().forEach((el) => {
|
|
60
|
+
if (el.dataset.disabledByHidden === "true") {
|
|
61
|
+
el.disabled = false
|
|
62
|
+
delete el.dataset.disabledByHidden
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
controls() {
|
|
68
|
+
return this.element.querySelectorAll("input, select, textarea")
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { lazyLoadControllersFromManifest } from "spree/storefront/helpers/lazy_load_controllers_with_manifest"
|
|
2
|
+
|
|
3
|
+
const controllers = ["disable-when-hidden"]
|
|
4
|
+
const manifest = {
|
|
5
|
+
"disable-when-hidden": "ba_spree/controllers/disable_when_hidden_controller"
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
document.addEventListener('turbo:load', function () {
|
|
9
|
+
const application = window.Stimulus
|
|
10
|
+
lazyLoadControllersFromManifest(controllers, null, application, manifest)
|
|
11
|
+
})
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
|
2
|
+
import { easepick } from '@easepick/core';
|
|
3
|
+
import { RangePlugin } from '@easepick/range-plugin';
|
|
4
|
+
import { PresetPlugin } from '@easepick/preset-plugin';
|
|
5
|
+
|
|
6
|
+
export default class extends Controller {
|
|
7
|
+
static targets = [ "picker", "dateFrom", "dateTo", "label" ]
|
|
8
|
+
connect() {
|
|
9
|
+
this.picker = new easepick.create({
|
|
10
|
+
element: this.pickerTarget,
|
|
11
|
+
lang: 'ja-JP',
|
|
12
|
+
inline: true,
|
|
13
|
+
css: [
|
|
14
|
+
'https://cdn.jsdelivr.net/npm/@easepick/core@1.2.0/dist/index.css',
|
|
15
|
+
'https://cdn.jsdelivr.net/npm/@easepick/range-plugin@1.2.0/dist/index.css',
|
|
16
|
+
'https://cdn.jsdelivr.net/npm/@easepick/preset-plugin@1.2.0/dist/index.css',
|
|
17
|
+
],
|
|
18
|
+
doc: document,
|
|
19
|
+
plugins: [RangePlugin, PresetPlugin],
|
|
20
|
+
RangePlugin: {
|
|
21
|
+
tooltip: true,
|
|
22
|
+
locale: {
|
|
23
|
+
one: '日',
|
|
24
|
+
other: '日間'
|
|
25
|
+
},
|
|
26
|
+
startDate: this.dateFromTarget.value,
|
|
27
|
+
endDate: this.dateToTarget.value,
|
|
28
|
+
},
|
|
29
|
+
PresetPlugin: {
|
|
30
|
+
customLabels: [
|
|
31
|
+
'今日',
|
|
32
|
+
'昨日',
|
|
33
|
+
'直近7日間',
|
|
34
|
+
'直近30日間',
|
|
35
|
+
'今月',
|
|
36
|
+
'先月'
|
|
37
|
+
],
|
|
38
|
+
position: 'left'
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
this.picker.on('render', () => {
|
|
43
|
+
this.picker.ui.container.style.boxShadow = 'none';
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
this.picker.on('select', (event) => {
|
|
47
|
+
const data = event.detail;
|
|
48
|
+
this.dateFromTarget.value = data.start
|
|
49
|
+
this.dateToTarget.value = data.end
|
|
50
|
+
|
|
51
|
+
// https://stackoverflow.com/questions/68624668/how-can-i-submit-a-form-on-input-change-with-turbo-streams
|
|
52
|
+
this.pickerTarget.closest('form').requestSubmit()
|
|
53
|
+
|
|
54
|
+
this.labelTarget.innerHTML = this.pickerTarget.innerHTML
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
open() {
|
|
59
|
+
this.picker.show()
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Controller } from '@hotwired/stimulus'
|
|
2
|
+
|
|
3
|
+
export default class extends Controller {
|
|
4
|
+
static targets = [
|
|
5
|
+
'name',
|
|
6
|
+
'url',
|
|
7
|
+
]
|
|
8
|
+
|
|
9
|
+
updateUrlFromName() {
|
|
10
|
+
const name = this.nameTarget.value
|
|
11
|
+
const url = name.toLowerCase().replace(/[^a-z0-9\u4e00-\u9faf\u3040-\u309f\u30a0-\u30ff\uff00-\uff9fa-z]+/gi, '-').replace(/(^-|-$)+/g, '');
|
|
12
|
+
this.urlTarget.value = url
|
|
13
|
+
|
|
14
|
+
// TODO: do ajax call and check if url is available
|
|
15
|
+
// if not, append a number to the end to make it unique
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module BaSpree
|
|
2
|
+
module AddressDecorator
|
|
3
|
+
def self.prepended(base)
|
|
4
|
+
# NOTE: Spree::Address は Spree 標準で `after_create :set_user_attributes` が設定されており、
|
|
5
|
+
# 配送先・請求先の区別なく Address 作成時に User の名前等が上書きされていたが、
|
|
6
|
+
# 「プレゼント送付先(配送先)の名前で User の本名が上書きされる」問題があったため、
|
|
7
|
+
# Spree 標準の callback そのものを解除する。
|
|
8
|
+
# 代わりに User#bill_address_id 変更時のコールバック(Spree::UserBillAddressSyncDecorator)で
|
|
9
|
+
# 請求先からのみ User 情報を同期するように変更した。
|
|
10
|
+
# raise: false は必須。prepend されたモジュールが再度 prepend されると Ruby は
|
|
11
|
+
# ancestors を変えないままこの prepended フックだけを再実行するため、2回目以降は
|
|
12
|
+
# 解除済みの callback を探して ArgumentError になる。development では
|
|
13
|
+
# engine の activate が to_prepare からリロードのたびに decorator を load し直すので、
|
|
14
|
+
# ガードがないとファイルを1つ編集しただけでリロードが落ちる。
|
|
15
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1307
|
|
16
|
+
base.skip_callback :create, :after, :set_user_attributes, raise: false
|
|
17
|
+
|
|
18
|
+
base.after_initialize :set_default_values, if: -> { new_record? && user.present? }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @gem-override spree_core-5.3.6/app/models/spree/address.rb#show_company_address_field?
|
|
22
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1165
|
|
23
|
+
# 本家は Store#prefers_company_field_enabled? を見るが、ba_spree では常に会社名欄を表示する。
|
|
24
|
+
# 日本の EC では法人向け配送のため会社名欄が求められることが多いため。
|
|
25
|
+
def show_company_address_field?
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
# @gem-override spree_core-5.3.6/app/models/spree/address.rb#set_default_values
|
|
32
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1165
|
|
33
|
+
# 本家の firstname / lastname / phone 補完に加えて company も User から補完する。
|
|
34
|
+
def set_default_values
|
|
35
|
+
self.firstname ||= user.first_name
|
|
36
|
+
self.lastname ||= user.last_name
|
|
37
|
+
self.phone ||= user.phone
|
|
38
|
+
self.company ||= user.company
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
Spree::Address.prepend BaSpree::AddressDecorator
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module BaSpree
|
|
2
|
+
module AdjustmentDecorator
|
|
3
|
+
def self.prepended(base)
|
|
4
|
+
base.scope :payment_method, -> { where(source_type: 'Spree::PaymentMethod') }
|
|
5
|
+
base.scope :non_payment_method, -> { where.not(source_type: 'Spree::PaymentMethod') }
|
|
6
|
+
base.scope :non_shipping, -> { where.not(adjustable_type: 'Spree::Shipment') }
|
|
7
|
+
base.scope :promotion, -> { where(source_type: 'Spree::PromotionAction') }
|
|
8
|
+
base.scope :non_promotion, -> { where.not(source_type: 'Spree::PromotionAction') }
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Spree::Adjustment.prepend BaSpree::AdjustmentDecorator
|