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,144 @@
|
|
|
1
|
+
module BaSpree
|
|
2
|
+
# Spree のストアを日本仕様に初期設定する。
|
|
3
|
+
#
|
|
4
|
+
# 扱うのは「日本で EC を始めるなら誰でも必要になる設定」だけで、
|
|
5
|
+
# ストア名・URL・メールアドレスといった各ショップ固有の情報には触れない。
|
|
6
|
+
# それらは呼び出し側が設定する。
|
|
7
|
+
#
|
|
8
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1317
|
|
9
|
+
class SetupService
|
|
10
|
+
# 国マスタ (Spree の seed が作る) が無いときに投げる
|
|
11
|
+
class CountryNotFoundError < StandardError; end
|
|
12
|
+
|
|
13
|
+
COUNTRY_NOT_FOUND_MESSAGE =
|
|
14
|
+
"日本 (iso: JP) が spree_countries に見つかりません。先に `rails db:seed` を実行してください。".freeze
|
|
15
|
+
|
|
16
|
+
PREFECTURES = [
|
|
17
|
+
"北海道", "青森県", "岩手県", "宮城県", "秋田県", "山形県", "福島県", "茨城県", "栃木県", "群馬県",
|
|
18
|
+
"埼玉県", "千葉県", "東京都", "神奈川県", "新潟県", "富山県", "石川県", "福井県", "山梨県",
|
|
19
|
+
"長野県", "岐阜県", "静岡県", "愛知県", "三重県", "滋賀県", "京都府", "大阪府", "兵庫県",
|
|
20
|
+
"奈良県", "和歌山県", "鳥取県", "島根県", "岡山県", "広島県", "山口県", "徳島県", "香川県",
|
|
21
|
+
"愛媛県", "高知県", "福岡県", "佐賀県", "長崎県", "熊本県", "大分県", "宮崎県", "鹿児島県", "沖縄県"
|
|
22
|
+
].freeze
|
|
23
|
+
|
|
24
|
+
# Spree::Seeds::Zones が作る海外向けゾーン全7種。日本国内向けストアでは不要なので削除する。
|
|
25
|
+
# @see spree_core-5.3.6/app/services/spree/seeds/zones.rb
|
|
26
|
+
FOREIGN_ZONE_NAMES = [
|
|
27
|
+
"EU_VAT", "UK_VAT", "North America", "South America",
|
|
28
|
+
"Middle East", "Asia", "Australia and Oceania"
|
|
29
|
+
].freeze
|
|
30
|
+
|
|
31
|
+
# 標準税率。配送料の税区分にも使う
|
|
32
|
+
STANDARD_TAX_CODE = "consumption10".freeze
|
|
33
|
+
|
|
34
|
+
TAX_RATES = [
|
|
35
|
+
{ amount: 0.1, name: "消費税10%", code: STANDARD_TAX_CODE },
|
|
36
|
+
# 軽減税率 (飲食料品・定期購読の新聞)
|
|
37
|
+
{ amount: 0.08, name: "消費税8%", code: "consumption8" },
|
|
38
|
+
{ amount: 0, name: "消費税非課税", code: "consumption0" }
|
|
39
|
+
].freeze
|
|
40
|
+
|
|
41
|
+
ZONE_NAME = "日本".freeze
|
|
42
|
+
SHIPPING_METHOD_CODE = "fixed".freeze
|
|
43
|
+
SHIPPING_RATE = 500
|
|
44
|
+
SAGAWA_TRACKING_URL = "https://k2k.sagawa-exp.co.jp/p/web/okurijosearch.do?okurijoNo=:tracking".freeze
|
|
45
|
+
|
|
46
|
+
class << self
|
|
47
|
+
# @param store [Spree::Store] 日本仕様に設定するストア
|
|
48
|
+
# @param load_seed [Boolean] Spree の seed (国マスタ等) を先に流すか
|
|
49
|
+
def setup(store:, load_seed: true)
|
|
50
|
+
Spree::Core::Engine.load_seed if load_seed
|
|
51
|
+
|
|
52
|
+
japan = setup_country
|
|
53
|
+
zone = setup_zone(japan)
|
|
54
|
+
setup_tax_rates(zone)
|
|
55
|
+
setup_store(store, japan, zone)
|
|
56
|
+
setup_shipping_method(zone)
|
|
57
|
+
store
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
# 国マスタは Spree の seed が作る。load_seed: false で呼ぶ場合は
|
|
63
|
+
# 事前に `rails db:seed` を済ませておく必要があるため、
|
|
64
|
+
# 見つからなければ理由の分かる例外で止める。
|
|
65
|
+
def setup_country
|
|
66
|
+
japan = Spree::Country.find_by(iso: "JP")
|
|
67
|
+
raise CountryNotFoundError, COUNTRY_NOT_FOUND_MESSAGE if japan.nil?
|
|
68
|
+
|
|
69
|
+
japan.update(states_required: true)
|
|
70
|
+
PREFECTURES.each do |prefecture|
|
|
71
|
+
Spree::State.find_or_create_by(name: prefecture, country: japan, abbr: prefecture)
|
|
72
|
+
end
|
|
73
|
+
japan
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def setup_zone(japan)
|
|
77
|
+
FOREIGN_ZONE_NAMES.each { |name| Spree::Zone.find_by(name: name)&.destroy }
|
|
78
|
+
|
|
79
|
+
zone = Spree::Zone.find_or_create_by(name: ZONE_NAME, description: "", default_tax: true, kind: "country")
|
|
80
|
+
zone.zone_members = [ Spree::ZoneMember.new(zoneable: japan) ]
|
|
81
|
+
zone.save
|
|
82
|
+
zone
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def setup_tax_rates(zone)
|
|
86
|
+
TAX_RATES.each do |attr|
|
|
87
|
+
# is_default は検索条件に含めない。Spree::TaxCategory#set_default_category が
|
|
88
|
+
# 「default は1つだけ」を保つため他カテゴリの is_default を false に落とすので、
|
|
89
|
+
# 条件に含めると2回目以降マッチせず重複レコードが増える
|
|
90
|
+
tax_category = Spree::TaxCategory.find_or_create_by!(name: attr[:name], tax_code: attr[:code]) do |category|
|
|
91
|
+
category.description = ""
|
|
92
|
+
category.is_default = true
|
|
93
|
+
end
|
|
94
|
+
tax_rate = Spree::TaxRate.find_or_initialize_by(
|
|
95
|
+
amount: attr[:amount],
|
|
96
|
+
zone: zone,
|
|
97
|
+
tax_category: tax_category,
|
|
98
|
+
included_in_price: true,
|
|
99
|
+
name: "消費税",
|
|
100
|
+
show_rate_in_label: true)
|
|
101
|
+
tax_rate.calculator = Spree::Calculator::DefaultTax.new
|
|
102
|
+
tax_rate.save
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# 通貨・ロケール・課税ゾーンなど、日本で運用するうえで必要な設定のみを行う。
|
|
107
|
+
# ストア名・URL・メールアドレスは各ショップ固有の情報なので呼び出し側の責務とする。
|
|
108
|
+
def setup_store(store, japan, zone)
|
|
109
|
+
store.default_currency = "JPY"
|
|
110
|
+
store.supported_currencies = "JPY"
|
|
111
|
+
store.supported_locales = "ja"
|
|
112
|
+
store.default_country = japan
|
|
113
|
+
store.checkout_zone = zone
|
|
114
|
+
store.save
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def setup_shipping_method(zone)
|
|
118
|
+
tax_category = Spree::TaxCategory.find_by(tax_code: STANDARD_TAX_CODE)
|
|
119
|
+
shipping_method = Spree::ShippingMethod.find_or_initialize_by(
|
|
120
|
+
name: "配送料",
|
|
121
|
+
display_on: "both",
|
|
122
|
+
tracking_url: SAGAWA_TRACKING_URL,
|
|
123
|
+
admin_name: "配送料(定額)",
|
|
124
|
+
tax_category: tax_category,
|
|
125
|
+
code: SHIPPING_METHOD_CODE)
|
|
126
|
+
shipping_method.shipping_categories = [ default_shipping_category ]
|
|
127
|
+
calculator = Spree::Calculator::Shipping::FlatRate.new
|
|
128
|
+
calculator.preferred_currency = "JPY"
|
|
129
|
+
calculator.preferred_amount = SHIPPING_RATE
|
|
130
|
+
shipping_method.calculator = calculator
|
|
131
|
+
shipping_method.save
|
|
132
|
+
Spree::ShippingMethodZone.create(shipping_method: shipping_method, zone: zone)
|
|
133
|
+
shipping_method
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Spree の seed が作る既定の配送カテゴリ。
|
|
137
|
+
# 名前は spree.seed.shipping.categories.default の訳 (日本語なら「既定」) になるが、
|
|
138
|
+
# seed 未実行だと存在しないため、無ければここで作る。
|
|
139
|
+
def default_shipping_category
|
|
140
|
+
Spree::ShippingCategory.find_or_create_by!(name: I18n.t("spree.seed.shipping.categories.default"))
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Assets
|
|
3
|
+
# 同一 viewable に属する Spree::Asset の position を、現在の並び順 (position, id) を
|
|
4
|
+
# 保ったまま 1..N の連番へ詰め直す。
|
|
5
|
+
#
|
|
6
|
+
# 管理画面の並び替え (stimulus-sortable) は、移動した 1 件だけに
|
|
7
|
+
# `asset[position] = 画面上のインデックス + 1` を送る。受け側の acts_as_list は
|
|
8
|
+
# 送られた position が既存レコードと衝突したときにしか周囲を詰め直さないため、
|
|
9
|
+
# position が 1..N の連番でないと 200 を返すのに並び順が変わらない。
|
|
10
|
+
# 並び替えの直前と、position が壊れうる経路の直後にこのサービスを呼ぶ。
|
|
11
|
+
#
|
|
12
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1292
|
|
13
|
+
class PositionNormalizer
|
|
14
|
+
# position が 1..N の連番になっていない viewable を検出する条件。
|
|
15
|
+
# 欠番 (最小が 1 でない / 最大が件数と一致しない) と重複 (distinct 数が件数と一致しない) を見る。
|
|
16
|
+
BROKEN_SCOPE_CONDITION = <<~SQL.squish.freeze
|
|
17
|
+
MIN(position) <> 1
|
|
18
|
+
OR MAX(position) <> COUNT(*)
|
|
19
|
+
OR COUNT(DISTINCT position) <> COUNT(*)
|
|
20
|
+
SQL
|
|
21
|
+
|
|
22
|
+
class << self
|
|
23
|
+
# @param viewable_type [String]
|
|
24
|
+
# @param viewable_id [Integer]
|
|
25
|
+
# @return [Boolean] 詰め直しを行った場合 true、もともと連番だった場合 false
|
|
26
|
+
def call(viewable_type:, viewable_id:)
|
|
27
|
+
return false if viewable_type.blank? || viewable_id.blank?
|
|
28
|
+
|
|
29
|
+
assets = ordered_assets(viewable_type, viewable_id)
|
|
30
|
+
return false if sequential?(assets)
|
|
31
|
+
|
|
32
|
+
# 1 件ずつ書き換える途中では position が一時的に重複しうるため、
|
|
33
|
+
# 中断や並行読み取りに晒さないようトランザクションでまとめる。
|
|
34
|
+
Spree::Asset.transaction do
|
|
35
|
+
assets.each_with_index do |asset, index|
|
|
36
|
+
asset.update_column(:position, index + 1) unless asset.position == index + 1
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
true
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# position が壊れている viewable の一覧。
|
|
43
|
+
# @return [Array<Array(String, Integer)>] [viewable_type, viewable_id] の配列
|
|
44
|
+
def broken_scopes
|
|
45
|
+
Spree::Asset.unscoped
|
|
46
|
+
.where.not(viewable_id: nil)
|
|
47
|
+
.group(:viewable_type, :viewable_id)
|
|
48
|
+
.having(BROKEN_SCOPE_CONDITION)
|
|
49
|
+
.pluck(:viewable_type, :viewable_id)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def ordered_assets(viewable_type, viewable_id)
|
|
55
|
+
Spree::Asset.unscoped
|
|
56
|
+
.where(viewable_type: viewable_type, viewable_id: viewable_id)
|
|
57
|
+
.order(:position, :id)
|
|
58
|
+
.to_a
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def sequential?(assets)
|
|
62
|
+
assets.each_with_index.all? { |asset, index| asset.position == index + 1 }
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Products
|
|
3
|
+
# 商品複製時の variant_count カウンタキャッシュずれを補正する。
|
|
4
|
+
#
|
|
5
|
+
# 背景:
|
|
6
|
+
# Spree 5.3.6 で `spree_products.variant_count` カウンタキャッシュが導入され、
|
|
7
|
+
# `Spree::Product#has_variants?` はこの値を参照するようになった。
|
|
8
|
+
# しかし upstream の Duplicator は `product.dup` で元商品の variant_count を
|
|
9
|
+
# そのまま引き継いだ上、複製したバリエーションを autosave するため
|
|
10
|
+
# `Spree::Variant#increment_product_variant_count` が二重に走り、
|
|
11
|
+
# 複製先の variant_count が「元の件数 + 複製件数」に膨らむ。
|
|
12
|
+
#
|
|
13
|
+
# その状態で複製先のバリエーションを全削除すると、
|
|
14
|
+
# 削除1件につき1ずつしか減らないため variant_count が 0 にならず、
|
|
15
|
+
# バリエーションが無いのに has_variants? が true のままとなり、
|
|
16
|
+
# バリエーションなし商品としての在庫(数量)設定フォームが表示されなくなる。
|
|
17
|
+
#
|
|
18
|
+
# 対策:
|
|
19
|
+
# 複製・保存後の新商品について、実際の非マスターバリエーション件数で
|
|
20
|
+
# variant_count を上書きし、dup 引き継ぎ + autosave 二重カウントを打ち消す。
|
|
21
|
+
#
|
|
22
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1250
|
|
23
|
+
module DuplicatorDecorator
|
|
24
|
+
# @gem-override spree_core-5.3.6/app/services/spree/products/duplicator.rb#call
|
|
25
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1250
|
|
26
|
+
def call(product:, include_images: true)
|
|
27
|
+
super.tap do |result|
|
|
28
|
+
new_product = result.value
|
|
29
|
+
next unless new_product.is_a?(Spree::Product) && new_product.persisted?
|
|
30
|
+
|
|
31
|
+
actual_count = new_product.variants.reload.count
|
|
32
|
+
new_product.update_column(:variant_count, actual_count)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
Spree::Products::Duplicator.prepend(Spree::Products::DuplicatorDecorator)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Products
|
|
3
|
+
module PrepareNestedAttributesDecorator
|
|
4
|
+
# @gem-override spree_core-5.3.6/app/services/spree/products/prepare_nested_attributes.rb#update_option_value_variants
|
|
5
|
+
# @see https://github.com/be-agile/giga-repeat/commit/108316dd2cab88a61933080614e15663517c7291
|
|
6
|
+
def update_option_value_variants(option_value_params, existing_variant)
|
|
7
|
+
return {} unless option_value_params.present?
|
|
8
|
+
return {} unless can_manage_option_types?
|
|
9
|
+
|
|
10
|
+
option_value_variant_params = {}
|
|
11
|
+
|
|
12
|
+
option_value_params.each_with_index do |opt, index|
|
|
13
|
+
option_type = Spree::OptionType.find_by(id: opt[:id]) if opt.fetch(:id)
|
|
14
|
+
option_type ||= Spree::OptionType.where(name: opt[:name]).first_or_initialize do |o|
|
|
15
|
+
o.name = o.presentation = opt[:name]
|
|
16
|
+
o.position = opt[:position]
|
|
17
|
+
o.save!
|
|
18
|
+
end
|
|
19
|
+
option_value_identificator = if opt[:option_value_name].present?
|
|
20
|
+
opt[:option_value_name]
|
|
21
|
+
else
|
|
22
|
+
opt[:option_value_presentation]
|
|
23
|
+
end.strip
|
|
24
|
+
|
|
25
|
+
option_value = option_type.option_values.where(name: option_value_identificator).first_or_initialize do |o|
|
|
26
|
+
o.presentation = opt[:option_value_presentation]
|
|
27
|
+
o.save!
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
existing_option_value_variant = existing_variant&.option_value_variants&.find { |ovv| ovv.option_value_id == option_value.id }
|
|
31
|
+
|
|
32
|
+
option_value_variant_params[index.to_s] = { id: existing_option_value_variant&.id, option_value_id: option_value.id }.compact_blank
|
|
33
|
+
|
|
34
|
+
next if product_option_types_params.find { |_i, v| v[:option_type_id] == option_type.id }
|
|
35
|
+
|
|
36
|
+
existing_product_option_type = @product.product_option_types.find { |pot| pot.option_type_id == option_type.id }
|
|
37
|
+
|
|
38
|
+
if existing_product_option_type
|
|
39
|
+
product_option_types_to_remove.delete(existing_product_option_type.id)
|
|
40
|
+
product_option_types_params[opt[:position]] = {
|
|
41
|
+
id: existing_product_option_type.id,
|
|
42
|
+
position: opt[:position],
|
|
43
|
+
option_type_id: option_type.id
|
|
44
|
+
}
|
|
45
|
+
else
|
|
46
|
+
product_option_types_params[opt[:position]] = {
|
|
47
|
+
option_type_id: option_type.id,
|
|
48
|
+
position: opt[:position]
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
option_value_variant_params
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
Spree::Products::PrepareNestedAttributes.prepend(Spree::Products::PrepareNestedAttributesDecorator)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<%# @gem-override spree_storefront-5.3.6/app/views/spree/addresses/edit.html.erb %>
|
|
2
|
+
<%# reason: 破棄ボタンの配色を btn-light からインラインスタイル付き btn-primary に変更している %>
|
|
3
|
+
<%# @see https://github.com/be-agile/giga-repeat/commit/74d9106123e9f58bf410e9cee3d2fefc4336123c %>
|
|
4
|
+
<% if params[:checkout].present? %>
|
|
5
|
+
<%= turbo_frame_tag dom_id(@address) do %>
|
|
6
|
+
<%= render 'spree/shared/error_messages', target: @address %>
|
|
7
|
+
<%= form_for @address, html: { id: 'checkout_form_address' } do |f| %>
|
|
8
|
+
<%= render 'spree/addresses/form',
|
|
9
|
+
address_name: 'address',
|
|
10
|
+
address_form: f,
|
|
11
|
+
address_type: 'shipping',
|
|
12
|
+
address: @address %>
|
|
13
|
+
|
|
14
|
+
<%= hidden_field_tag :checkout, params[:checkout] %>
|
|
15
|
+
<div class="flex justify-between items-center">
|
|
16
|
+
<%= f.submit Spree.t(:update), class: 'btn btn-primary w-25 !py-2' %>
|
|
17
|
+
<%= link_to Spree.t('actions.discard'), :back, class: 'btn btn-primary w-25 !py-2', style: "background-color: #D9D9D9; color: #5E5B5B; border: 1px solid #D9D9D9" %>
|
|
18
|
+
</div>
|
|
19
|
+
<% end %>
|
|
20
|
+
<% end %>
|
|
21
|
+
<% elsif turbo_frame_request? %>
|
|
22
|
+
<%= turbo_frame_tag "edit_address_modal_#{@address.id}" do %>
|
|
23
|
+
<%= render partial: 'spree/account/addresses/edit_address_modal', locals: { address: @address } %>
|
|
24
|
+
<% end %>
|
|
25
|
+
<% else %>
|
|
26
|
+
<div class="page-container grid grid-cols-1 lg:grid-cols-12 lg:gap-6 lg:mt-6">
|
|
27
|
+
<div class="lg:col-span-2">
|
|
28
|
+
<%= render 'spree/account/account_nav', current: 'address' %>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="lg:col-span-6 lg:col-start-4">
|
|
31
|
+
<div class="pb-4 border-b border-default -mx-4 lg:mx-0 px-4 lg:px-8">
|
|
32
|
+
<h3 class="text-xl uppercase font-medium lg:font-semibold"><%= Spree.t(:edit_address) %></h3>
|
|
33
|
+
</div>
|
|
34
|
+
<%= render 'spree/shared/error_messages', target: @address %>
|
|
35
|
+
<%= form_for @address, html: { id: 'checkout_form_address' }, method: :put do |f| %>
|
|
36
|
+
<div class="lg:px-8 pt-4">
|
|
37
|
+
<%= render 'spree/addresses/form',
|
|
38
|
+
address_name: 'address',
|
|
39
|
+
address_form: f,
|
|
40
|
+
address_type: 'shipping',
|
|
41
|
+
address: @address %>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="lg:px-8 pb-4">
|
|
44
|
+
<%= label_tag "default_shipping", class: "flex items-center gap-2 text-sm mb-4" do %>
|
|
45
|
+
<%= check_box_tag "default_shipping", "true", @address.user_default_shipping?,
|
|
46
|
+
class: 'input-checkbox input-address-default',
|
|
47
|
+
disabled: @address.user_default_shipping? %>
|
|
48
|
+
<%= Spree.t('address_book.set_as_default_delivery_address') %>
|
|
49
|
+
<% end %>
|
|
50
|
+
<%= label_tag "default_billing", class: "flex items-center gap-2 text-sm mb-4" do %>
|
|
51
|
+
<%= check_box_tag "default_billing", "true", @address.user_default_billing?,
|
|
52
|
+
class: 'input-checkbox input-address-default',
|
|
53
|
+
disabled: @address.user_default_billing? %>
|
|
54
|
+
<%= Spree.t('address_book.set_as_default_billing_address') %>
|
|
55
|
+
<% end %>
|
|
56
|
+
</div>
|
|
57
|
+
<div class="border-t border-default -mx-4 lg:mx-0 px-4 flex justify-end items-center gap-4 py-6 lg:px-8">
|
|
58
|
+
<%= link_to Spree.t('actions.cancel'), :back, class: 'uppercase text-sm font-semibold tracking-widest' %>
|
|
59
|
+
<%= f.submit Spree.t(:update), class: 'btn-primary' %>
|
|
60
|
+
</div>
|
|
61
|
+
<% end %>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
<% end %>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<%# @gem-override spree_admin-5.3.6/app/views/spree/admin/orders/_order.html.erb %>
|
|
2
|
+
<%# reason: 注文日時の表示を本家の local_time_ago から l(..., format: :middle) に置き換えて日本語ロケール書式で表示する (Issue #605) %>
|
|
3
|
+
<%# Spree 5.3 追従: Bootstrap クラスを v4 化(font-weight-bolder→font-bolder, d-block→block, px-3→px-4, text-decoration-none→no-underline, text-wrap→whitespace-normal) %>
|
|
4
|
+
<%# @see https://github.com/be-agile/giga-repeat/issues/605 %>
|
|
5
|
+
<tr id="<%= dom_id(order) %>" data-controller="row-link">
|
|
6
|
+
<td class="p-0 w-10">
|
|
7
|
+
<%= link_to order.number, spree.edit_admin_order_path(order), class: 'font-bolder block p-2 px-4 no-underline', data: { 'turbo-frame': '_top', row_link_target: :link } %>
|
|
8
|
+
</td>
|
|
9
|
+
<td class="w-15 cursor-pointer" data-action="click->row-link#openLink">
|
|
10
|
+
<%= l((order.completed? ? order.completed_at : order.created_at), format: :middle) %>
|
|
11
|
+
</td>
|
|
12
|
+
<td class="d-customer w-15 cursor-pointer" data-action="click->row-link#openLink">
|
|
13
|
+
<%= render 'spree/admin/orders/customer_summary', order: order %>
|
|
14
|
+
</td>
|
|
15
|
+
<td class="whitespace-normal w-20 cursor-pointer" data-action="click->row-link#openLink">
|
|
16
|
+
<% order.shipments.map(&:stock_location).compact.uniq.each_with_index do |stock_location, index| %>
|
|
17
|
+
<% if index > 0 %>, <% end %><%= stock_location.name %>
|
|
18
|
+
<% end %>
|
|
19
|
+
</td>
|
|
20
|
+
<td class="w-10 cursor-pointer" data-action="click->row-link#openLink">
|
|
21
|
+
<%= order_payment_state(order) %>
|
|
22
|
+
</td>
|
|
23
|
+
<td class="w-10 cursor-pointer" data-action="click->row-link#openLink">
|
|
24
|
+
<%= order_shipment_state(order) %>
|
|
25
|
+
</td>
|
|
26
|
+
<td class="text-right w-10 cursor-pointer" data-action="click->row-link#openLink">
|
|
27
|
+
<%= pluralize(order.item_count, 'item') %>
|
|
28
|
+
</td>
|
|
29
|
+
<td class="text-right w-10 cursor-pointer" data-action="click->row-link#openLink">
|
|
30
|
+
<%= order.display_total.to_html %>
|
|
31
|
+
</td>
|
|
32
|
+
</tr>
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<%# @gem-override spree_admin-5.3.6/app/views/spree/admin/orders/_summary.html.erb %>
|
|
2
|
+
<%# reason: 注文サマリの割引表示を本家の promo_total から all_adjustments を符号別に列挙する方式に変更し、order_page_body_partials に差し替えている %>
|
|
3
|
+
<%# @see https://github.com/be-agile/giga-repeat/commit/85fdfe348ab8f9182a3ca8ac73b521462d6a89ae %>
|
|
4
|
+
<%# Spree 5.3 追従: 本家は OrderSummaryPresenter 化したが giga の符号別 adjustment 列挙・独自 partial フックを %>
|
|
5
|
+
<%# 維持するため独自構造のまま。admin Tailwind v4 化に合わせ Bootstrap クラス(d-flex/justify-content-between/ %>
|
|
6
|
+
<%# align-items-center/font-weight-bold/text-capitalize/text-right/bg-light/border-top)のみ v4 化。margin系(mr/ml/mb)は v4 でも有効なため維持。 %>
|
|
7
|
+
<div class="card mb-6" id="order_tab_summary">
|
|
8
|
+
<div class="card-header">
|
|
9
|
+
<h5 class="card-title"><%= Spree.t(:summary) %></h5>
|
|
10
|
+
</div>
|
|
11
|
+
<ul class="list-group list-group-flush">
|
|
12
|
+
<% if @order.canceled? && @order.canceled_at %>
|
|
13
|
+
<li class="list-group-item flex justify-between items-center border-0">
|
|
14
|
+
<span><%= Spree.t(:canceled_at) %></span>
|
|
15
|
+
<span class="text-end font-bold">
|
|
16
|
+
<%= spree_time(@order.canceled_at) %>
|
|
17
|
+
</span>
|
|
18
|
+
</li>
|
|
19
|
+
<% if @order.canceler.present? %>
|
|
20
|
+
<li class="list-group-item flex justify-between items-center border-0">
|
|
21
|
+
<span><%= Spree.t(:canceler) %></span>
|
|
22
|
+
<span class="text-end font-bold">
|
|
23
|
+
<%= @order.canceler.name %>
|
|
24
|
+
</span>
|
|
25
|
+
</li>
|
|
26
|
+
<% end %>
|
|
27
|
+
<% end %>
|
|
28
|
+
|
|
29
|
+
<li class="list-group-item flex justify-between items-center border-0">
|
|
30
|
+
<span><%= Spree.t(:currency) %></span>
|
|
31
|
+
<span id='currency'>
|
|
32
|
+
<%= @order.currency %>
|
|
33
|
+
</span>
|
|
34
|
+
</li>
|
|
35
|
+
|
|
36
|
+
<li class="list-group-item flex justify-between items-center border-0">
|
|
37
|
+
<span data-hook='admin_order_tab_subtotal_title'><%= Spree.t(:subtotal) %></span>
|
|
38
|
+
<span id='item_total'>
|
|
39
|
+
<%= @order.display_item_total.to_html %>
|
|
40
|
+
</span>
|
|
41
|
+
</li>
|
|
42
|
+
|
|
43
|
+
<% @order.all_adjustments.eligible.where('amount < 0').non_tax.each do |adjustment| %>
|
|
44
|
+
<li class="list-group-item flex justify-between items-center border-0">
|
|
45
|
+
<span data-hook='admin_order_tab_np_fee_adjustment'><%= adjustment.label %></span>
|
|
46
|
+
<span class="font-bold capitalize" id='adjustment'>
|
|
47
|
+
<%= adjustment.display_amount.to_html %>
|
|
48
|
+
</span>
|
|
49
|
+
</li>
|
|
50
|
+
<% end %>
|
|
51
|
+
|
|
52
|
+
<% if @order.checkout_steps.include?("delivery") && @order.ship_total > 0 %>
|
|
53
|
+
<li class="list-group-item flex justify-between items-center border-0">
|
|
54
|
+
<span data-hook='admin_order_tab_ship_total_title'>
|
|
55
|
+
<%= Spree.t(:ship_total) %>
|
|
56
|
+
</span>
|
|
57
|
+
<span id='ship_total'>
|
|
58
|
+
<%= @order.display_ship_total.to_html %>
|
|
59
|
+
</span>
|
|
60
|
+
</li>
|
|
61
|
+
<% end %>
|
|
62
|
+
|
|
63
|
+
<li class="list-group-item flex justify-between items-center border-0">
|
|
64
|
+
<span data-hook='admin_order_tab_included_tax_title'><%= Spree.t(:tax_included) %></span>
|
|
65
|
+
<span id='included_tax_total'>
|
|
66
|
+
<%= @order.display_included_tax_total.to_html %>
|
|
67
|
+
</span>
|
|
68
|
+
</li>
|
|
69
|
+
|
|
70
|
+
<% tax_lines = order_summary_tax_lines_additional(@order) %>
|
|
71
|
+
|
|
72
|
+
<li class="list-group-item border-0" data-controller="reveal">
|
|
73
|
+
<span class="flex justify-between items-center">
|
|
74
|
+
<span><%= Spree.t(:tax) %></span>
|
|
75
|
+
<span id="additional_tax_total">
|
|
76
|
+
<% if tax_lines.any? %>
|
|
77
|
+
<button type="button" class="btn btn-light btn-sm mr-2" data-action="click->reveal#toggle">
|
|
78
|
+
<%= Spree.t(:show_details) %>
|
|
79
|
+
<%= icon('selector', height: 12, class: 'mr-0 ml-1') %>
|
|
80
|
+
</button>
|
|
81
|
+
<% end %>
|
|
82
|
+
|
|
83
|
+
<%= @order.display_additional_tax_total.to_html %>
|
|
84
|
+
</span>
|
|
85
|
+
</span>
|
|
86
|
+
|
|
87
|
+
<%= render 'tax_lines', tax_lines: tax_lines %>
|
|
88
|
+
</li>
|
|
89
|
+
|
|
90
|
+
<%= render_admin_partials(:order_page_body_partials, order: @order) %>
|
|
91
|
+
|
|
92
|
+
<% @order.all_adjustments.eligible.where('amount > 0').non_tax.each do |adjustment| %>
|
|
93
|
+
<li class="list-group-item flex justify-between items-center border-0">
|
|
94
|
+
<span data-hook='admin_order_tab_np_fee_adjustment'><%= adjustment.label %></span>
|
|
95
|
+
<span class="font-bold capitalize" id='adjustment'>
|
|
96
|
+
<%= adjustment.display_amount.to_html %>
|
|
97
|
+
</span>
|
|
98
|
+
</li>
|
|
99
|
+
<% end %>
|
|
100
|
+
|
|
101
|
+
<li class="list-group-item flex justify-between items-center border-0">
|
|
102
|
+
<span data-hook='admin_order_tab_total_title'><%= Spree.t(:total) %></span>
|
|
103
|
+
<span class="font-bold capitalize" id='order_total'>
|
|
104
|
+
<%= @order.display_total.to_html %>
|
|
105
|
+
</span>
|
|
106
|
+
</li>
|
|
107
|
+
|
|
108
|
+
<li class="list-group-item flex justify-between items-center border-t bg-gray-25">
|
|
109
|
+
<span data-hook='admin_order_tab_payment_total_title'><%= Spree.t(:payment_total) %></span>
|
|
110
|
+
<span id='payment_total'>
|
|
111
|
+
<%= @order.display_payment_total.to_html %>
|
|
112
|
+
</span>
|
|
113
|
+
</li>
|
|
114
|
+
|
|
115
|
+
<li class="list-group-item flex justify-between items-center bg-gray-25">
|
|
116
|
+
<span data-hook='admin_order_tab_outstanding_balance_title'><%= Spree.t(:outstanding_balance) %></span>
|
|
117
|
+
<span id='outstanding_balance'>
|
|
118
|
+
<%= @order.display_outstanding_balance.to_html %>
|
|
119
|
+
</span>
|
|
120
|
+
</li>
|
|
121
|
+
</ul>
|
|
122
|
+
</div>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<%# @gem-override spree_admin-5.3.6/app/views/spree/admin/shared/_custom_head.html.erb %>
|
|
2
|
+
<%# reason: 本家では空の管理画面 head 用 partial に、ba_spree の admin/custom スタイルシート読み込みを追加している %>
|
|
3
|
+
<%# (日本語だと管理画面の項目名が長くなり見切れるため、その折り返し対応を含む) %>
|
|
4
|
+
<%# @see https://github.com/be-agile/giga-repeat/commit/99098e3ab960a54164fd6766de4dbd7918c1252c %>
|
|
5
|
+
<%= stylesheet_link_tag "spree/admin/custom", media: "all", "data-turbo-track": "reload" %>
|
|
6
|
+
|
|
7
|
+
<%# local-time gem の JS は config.locale が "en" 固定のため、日時の %a(曜日)が
|
|
8
|
+
「Mon」のように英語で描画される(例: promotions の作成日時 2025年06月23日(Mon))。
|
|
9
|
+
Ruby 側の I18n(ja.date.abbr_day_names)を反映できないので、JS の LocalTime に
|
|
10
|
+
日本語ロケールを登録し locale を ja に切り替えて、曜日を日本語(月)で描画する。
|
|
11
|
+
24時間表記(useFormat24)も合わせ、注文・お客様等の日時表記とも揃える。 %>
|
|
12
|
+
<script type="module">
|
|
13
|
+
import LocalTime from "local-time"
|
|
14
|
+
|
|
15
|
+
LocalTime.config.i18n["ja"] = {
|
|
16
|
+
date: {
|
|
17
|
+
dayNames: ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"],
|
|
18
|
+
abbrDayNames: ["日", "月", "火", "水", "木", "金", "土"],
|
|
19
|
+
monthNames: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
|
|
20
|
+
abbrMonthNames: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
|
|
21
|
+
yesterday: "昨日",
|
|
22
|
+
today: "今日",
|
|
23
|
+
tomorrow: "明日",
|
|
24
|
+
on: "{date}",
|
|
25
|
+
formats: { default: "%Y年%m月%d日", thisYear: "%m月%d日" }
|
|
26
|
+
},
|
|
27
|
+
time: {
|
|
28
|
+
am: "午前", pm: "午後",
|
|
29
|
+
singular: "約{time}", singularAn: "約{time}",
|
|
30
|
+
elapsed: "{time}前",
|
|
31
|
+
second: "秒", seconds: "秒",
|
|
32
|
+
minute: "分", minutes: "分",
|
|
33
|
+
hour: "時間", hours: "時間",
|
|
34
|
+
formats: { default: "%H時%M分", default_24h: "%H時%M分" }
|
|
35
|
+
},
|
|
36
|
+
datetime: {
|
|
37
|
+
at: "{date} {time}",
|
|
38
|
+
formats: { default: "%Y年%m月%d日 %H時%M分", default_24h: "%Y年%m月%d日 %H時%M分" }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
LocalTime.config.locale = "ja"
|
|
42
|
+
LocalTime.config.useFormat24 = true
|
|
43
|
+
|
|
44
|
+
// admin の application.js が先に LocalTime.start() を実行し、既存の <time> 要素には
|
|
45
|
+
// 英語ロケールのまま data-localized が付与され「再処理対象外」になっている場合がある。
|
|
46
|
+
// ロケール切替後に data-localized を外して再描画させ、日本語(曜日)に置き換える。
|
|
47
|
+
const applyJaLocalTime = () => {
|
|
48
|
+
document.querySelectorAll("time[data-local][data-localized]").forEach((el) => {
|
|
49
|
+
el.removeAttribute("data-localized")
|
|
50
|
+
})
|
|
51
|
+
LocalTime.run()
|
|
52
|
+
}
|
|
53
|
+
document.addEventListener("turbo:load", applyJaLocalTime)
|
|
54
|
+
document.addEventListener("turbo:morph", applyJaLocalTime)
|
|
55
|
+
applyJaLocalTime()
|
|
56
|
+
</script>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<%# @gem-override spree_admin-5.3.6/app/views/spree/admin/shared/sidebar/_promotions_nav.html.erb %>
|
|
2
|
+
<%# reason: プロモーション系サイドバーに scheduled_discounts / volume_discount / amount_discount / gift_cards のメニューを追加している %>
|
|
3
|
+
<%# Spree 5.3 追従: 折りたたみサイドバー用 dropdown の非表示クラスを Bootstrap d-none → Tailwind v4 hidden に変更 %>
|
|
4
|
+
<%# @see https://github.com/be-agile/giga-repeat/issues/697 %>
|
|
5
|
+
<% promotions_active = %w[promotions scheduled_discounts volume_discount_tier_groups amount_discount_tier_groups].include?(controller_name) %>
|
|
6
|
+
<% discounts_active = %w[promotions gift_cards gift_card_batches coupon_codes].include?(controller_name) %>
|
|
7
|
+
<% if can?(:manage, Spree::Promotion) %>
|
|
8
|
+
<%= nav_item(Spree.t(:promotions), spree.admin_promotions_path, icon: 'box-seam', active: promotions_active) %>
|
|
9
|
+
|
|
10
|
+
<%# Submenu for expanded sidebar (only shown when active) %>
|
|
11
|
+
<% if promotions_active %>
|
|
12
|
+
<ul class="ml-4 pl-1 mb-2 nav-submenu mt-1">
|
|
13
|
+
<% if can?(:manage, Spree::Promotion) && defined?(Spree::ScheduledDiscount) %>
|
|
14
|
+
<li class="nav-item">
|
|
15
|
+
<%= nav_item(Spree.t(:scheduled_discounts), spree.admin_scheduled_discounts_path, icon: 'basket-star', active: %w[scheduled_discounts].include?(controller_name)) %>
|
|
16
|
+
</li>
|
|
17
|
+
<% end %>
|
|
18
|
+
|
|
19
|
+
<% if can?(:manage, Spree::Promotion) && defined?(Spree::VolumeDiscountTierGroup) %>
|
|
20
|
+
<li class="nav-item">
|
|
21
|
+
<%= nav_item(Spree.t(:volume_discount_tier_groups), spree.admin_volume_discount_tier_groups_path, icon: 'history', active: %w[volume_discount_tier_groups].include?(controller_name)) %>
|
|
22
|
+
</li>
|
|
23
|
+
<% end %>
|
|
24
|
+
|
|
25
|
+
<% if can?(:manage, Spree::Promotion) && defined?(Spree::AmountDiscountTierGroup) %>
|
|
26
|
+
<li class="nav-item">
|
|
27
|
+
<%= nav_item(Spree.t(:amount_discount_tier_groups), spree.admin_amount_discount_tier_groups_path, icon: 'calculator', active: %w[amount_discount_tier_groups].include?(controller_name)) %>
|
|
28
|
+
</li>
|
|
29
|
+
<% end %>
|
|
30
|
+
|
|
31
|
+
<% if discounts_active && defined?(Spree::GiftCard) && spree.respond_to?(:admin_gift_cards_path) && can?(:manage, Spree::GiftCard) %>
|
|
32
|
+
<li class="nav-item">
|
|
33
|
+
<%= active_link_to Spree.t(:gift_cards), spree.admin_gift_cards_path, class: 'nav-link', active: %w[gift_cards gift_card_batches].include?(controller_name) %>
|
|
34
|
+
</li>
|
|
35
|
+
<% end %>
|
|
36
|
+
</ul>
|
|
37
|
+
<% end %>
|
|
38
|
+
|
|
39
|
+
<%# Submenu dropdown for collapsed sidebar (always rendered, shown on hover) %>
|
|
40
|
+
<ul class="nav-submenu-dropdown hidden dropdown-container">
|
|
41
|
+
<%= nav_item(Spree.t(:promotions), spree.admin_promotions_path) %>
|
|
42
|
+
<% if can?(:manage, Spree::Promotion) && defined?(Spree::ScheduledDiscount) %>
|
|
43
|
+
<%= nav_item(Spree.t(:scheduled_discounts), spree.admin_scheduled_discounts_path) %>
|
|
44
|
+
<% end %>
|
|
45
|
+
<% if can?(:manage, Spree::Promotion) && defined?(Spree::VolumeDiscountTierGroup) %>
|
|
46
|
+
<%= nav_item(Spree.t(:volume_discount_tier_groups), spree.admin_volume_discount_tier_groups_path) %>
|
|
47
|
+
<% end %>
|
|
48
|
+
<% if can?(:manage, Spree::Promotion) && defined?(Spree::AmountDiscountTierGroup) %>
|
|
49
|
+
<%= nav_item(Spree.t(:amount_discount_tier_groups), spree.admin_amount_discount_tier_groups_path) %>
|
|
50
|
+
<% end %>
|
|
51
|
+
<% if defined?(Spree::GiftCard) && spree.respond_to?(:admin_gift_cards_path) && can?(:manage, Spree::GiftCard) %>
|
|
52
|
+
<%= nav_item(Spree.t(:gift_cards), spree.admin_gift_cards_path) %>
|
|
53
|
+
<% end %>
|
|
54
|
+
</ul>
|
|
55
|
+
<% end %>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<div class="card mb-4">
|
|
2
|
+
<div class="card-header">
|
|
3
|
+
<h5 class="card-title"><%= Spree.t(:special_instruction_message) %></h5>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<div class="card-body">
|
|
7
|
+
<p class="text-muted">
|
|
8
|
+
<%= Spree.t('admin.checkout_settings.special_instruction_message_description') %>
|
|
9
|
+
</p>
|
|
10
|
+
<div class="trix-container">
|
|
11
|
+
<%= f.rich_text_area :special_instruction_message, class: 'overflow-auto', style: 'height: 300px' %>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|