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,34 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module ExportDecorator
|
|
3
|
+
# @gem-override spree_core-5.3.6/app/models/spree/export.rb#generate_csv
|
|
4
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1271
|
|
5
|
+
# 標準CSVエクスポートは UTF-8(BOMなし)で出力するため、Windows/Excel や
|
|
6
|
+
# 日本語エディタが Shift_JIS と誤判定して文字化けする。生成後のファイル先頭に
|
|
7
|
+
# UTF-8 BOM を付与して、UTF-8 として正しく認識されるようにする。
|
|
8
|
+
#
|
|
9
|
+
# Spree 5.3 追従: メソッド本体(FormulaSanitizer 等)は super 経由で取り込むため、
|
|
10
|
+
# 本 override はファイルへの BOM 付与のみを追加する設計(upstream 追従)。
|
|
11
|
+
def generate_csv
|
|
12
|
+
super
|
|
13
|
+
prepend_utf8_bom(export_tmp_file_path)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def prepend_utf8_bom(path)
|
|
19
|
+
return unless ::File.exist?(path)
|
|
20
|
+
|
|
21
|
+
bom = "\xEF\xBB\xBF".b
|
|
22
|
+
return if ::File.binread(path, bom.bytesize) == bom # 既に BOM 付きなら何もしない
|
|
23
|
+
|
|
24
|
+
tmp_path = "#{path}.bom"
|
|
25
|
+
::File.open(tmp_path, 'wb') do |out|
|
|
26
|
+
out.write(bom)
|
|
27
|
+
::File.open(path, 'rb') { |input| ::IO.copy_stream(input, out) }
|
|
28
|
+
end
|
|
29
|
+
::File.rename(tmp_path, path)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
Spree::Export.prepend(Spree::ExportDecorator)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
# 明細(line_item)削除時に、在庫を戻してから inventory_unit を消す順序を保証する。
|
|
3
|
+
#
|
|
4
|
+
# Spree 5.3.6 で `has_many :inventory_units` に `dependent: :destroy` が付いた結果、
|
|
5
|
+
# アソシエーション宣言の時点で登録される before_destroy が
|
|
6
|
+
# `verify_order_inventory_before_destroy` より先に走るようになった。
|
|
7
|
+
# そのため Spree::OrderInventory#verify に到達した時点で inventory_units が 0 件になっており、
|
|
8
|
+
# 「削除」ではなく「追加」に分岐して次の 2 つの不具合が起きる。
|
|
9
|
+
#
|
|
10
|
+
# 1. 削除しようとしている line_item を指す inventory_unit を作り直してしまう。
|
|
11
|
+
# line_item が消えたあと orphan となり、Spree::Stock::ContentItem#amount が
|
|
12
|
+
# nil * quantity で NoMethodError を投げる (管理画面の明細削除が 500)
|
|
13
|
+
# 2. remove_from_shipment を通らないため restock されず、逆に unstock される (在庫が戻らない)
|
|
14
|
+
#
|
|
15
|
+
# ActiveSupport::Callbacks は同じシンボルのコールバックを重複排除するため、
|
|
16
|
+
# prepend: true で登録し直すだけで元の登録は取り除かれる (skip_callback は不要)。
|
|
17
|
+
# これにより 5.1.x と同じ順序に戻る。
|
|
18
|
+
#
|
|
19
|
+
# @gem-override spree_core-5.3.6/app/models/spree/line_item.rb
|
|
20
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1298
|
|
21
|
+
module LineItemDestroyCallbackDecorator
|
|
22
|
+
def self.prepended(base)
|
|
23
|
+
base.before_destroy :verify_order_inventory_before_destroy,
|
|
24
|
+
prepend: true,
|
|
25
|
+
if: -> { order.has_checkout_step?('delivery') }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
Spree::LineItem.prepend Spree::LineItemDestroyCallbackDecorator
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
# @gem-override spree_core-5.3.6/app/models/spree/metafield_definition.rb
|
|
3
|
+
# reason: 本家 MetafieldDefinition は key/namespace に
|
|
4
|
+
# `normalizes :key, with: ->(v){ v.parameterize.underscore.strip }` を掛けており、
|
|
5
|
+
# parameterize が非ASCII(日本語)を除去するため、日本語のプロパティ名(「地図形式」「提供形態」等)を
|
|
6
|
+
# key にすると空文字になり、key 必須・name 必須(set_name_from_key も空)でバリデーションに失敗する。
|
|
7
|
+
# ba_spree は既に Property / OptionType / OptionValue / FilterParam で
|
|
8
|
+
# 「parameterize を使わず日本語を保持する」方針を採用済み(ba_spree の各 *_decorator 参照)。
|
|
9
|
+
# MetafieldDefinition も同方針に揃え、Spree 5.2 の product properties → metafields 移行で
|
|
10
|
+
# 日本語のプロパティ名をそのまま key/name として保持できるようにする。
|
|
11
|
+
#
|
|
12
|
+
# 実装メモ:
|
|
13
|
+
# 本家の normalizes は decorate_attributes で属性の型を NormalizedValueType でラップし、
|
|
14
|
+
# before_validation(:normalize_changed_in_place_attributes) でも再正規化する。
|
|
15
|
+
# 後から normalizes を再宣言しても元の parameterize が累積して残るため、
|
|
16
|
+
# いったん `attribute` で型をリセットしてラップを外し、normalized_attributes からも除外したうえで、
|
|
17
|
+
# parameterize を使わない自前の正規化(前後空白の除去のみ)を宣言し直す。
|
|
18
|
+
module MetafieldDefinitionDecorator
|
|
19
|
+
extend ActiveSupport::Concern
|
|
20
|
+
|
|
21
|
+
included do
|
|
22
|
+
# 本家 normalizes(parameterize)のラップを外す
|
|
23
|
+
attribute :key, :string
|
|
24
|
+
attribute :namespace, :string
|
|
25
|
+
self.normalized_attributes -= [ :key, :namespace ]
|
|
26
|
+
|
|
27
|
+
# parameterize せず、前後空白の除去のみ(日本語を保持)
|
|
28
|
+
normalizes :key, with: ->(value) { value.to_s.strip }
|
|
29
|
+
normalizes :namespace, with: ->(value) { value.to_s.strip }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
Spree::MetafieldDefinition.include(Spree::MetafieldDefinitionDecorator)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module OptionTypeDecorator
|
|
3
|
+
# @gem-override spree_core-5.3.6/app/models/spree/option_type.rb#filter_param
|
|
4
|
+
# @see https://github.com/be-agile/giga-repeat/commit/108316dd2cab88a61933080614e15663517c7291
|
|
5
|
+
# Spree 5.3 追従: 本家変更は deprecation 文言のみ。本実装は日本語保持のため独自(name.parameterize を使わない)。
|
|
6
|
+
def filter_param
|
|
7
|
+
# parameterizeを使わず、空白を_に置換し小文字化
|
|
8
|
+
name.to_s.gsub(/\s+/, '_').downcase
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @gem-override spree_core-5.3.6/app/models/concerns/spree/parameterizable_name.rb#normalize_name
|
|
12
|
+
# @see https://github.com/be-agile/giga-repeat/commit/108316dd2cab88a61933080614e15663517c7291
|
|
13
|
+
def normalize_name
|
|
14
|
+
# 日本語などの非ASCII文字を保持するための修正
|
|
15
|
+
# parameterizeを使わず、空白の除去と小文字化のみを行う
|
|
16
|
+
self.name = name.to_s.strip.downcase
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Decoratorを適用
|
|
22
|
+
Spree::OptionType.prepend(Spree::OptionTypeDecorator)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module OptionValueDecorator
|
|
3
|
+
def filter_param
|
|
4
|
+
# parameterizeを使わず、空白を_に置換し小文字化
|
|
5
|
+
name.to_s.gsub(/\s+/, '_').downcase
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# @gem-override spree_core-5.3.6/app/models/concerns/spree/parameterizable_name.rb#normalize_name
|
|
9
|
+
# @see https://github.com/be-agile/giga-repeat/commit/108316dd2cab88a61933080614e15663517c7291
|
|
10
|
+
def normalize_name
|
|
11
|
+
# 日本語などの非ASCII文字を保持するための修正
|
|
12
|
+
# parameterizeを使わず、空白の除去と小文字化のみを行う
|
|
13
|
+
self.name = name.to_s.strip.downcase
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Decoratorを適用
|
|
19
|
+
Spree::OptionValue.prepend(Spree::OptionValueDecorator)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module OptionValueVariantDecorator
|
|
3
|
+
def self.prepended(base)
|
|
4
|
+
base.extend(ClassMethods)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
module ClassMethods
|
|
8
|
+
# @gem-override spree_core-5.3.6/app/models/spree/base.rb#to_tom_select_json
|
|
9
|
+
# @see https://github.com/be-agile/giga-repeat/commit/108316dd2cab88a61933080614e15663517c7291
|
|
10
|
+
# カスタムto_tom_select_jsonメソッドの実装
|
|
11
|
+
# OptionValueVariantにはnameがないため、関連するOptionValueとOptionTypeから情報を取得
|
|
12
|
+
def to_tom_select_json
|
|
13
|
+
joins(:option_value)
|
|
14
|
+
.joins('JOIN spree_option_types ON spree_option_types.id = spree_option_values.option_type_id')
|
|
15
|
+
.select('spree_option_value_variants.id,
|
|
16
|
+
spree_option_values.presentation AS value_presentation,
|
|
17
|
+
spree_option_types.presentation AS type_presentation')
|
|
18
|
+
.map do |ov|
|
|
19
|
+
{
|
|
20
|
+
id: ov.id,
|
|
21
|
+
name: "#{ov.type_presentation}: #{ov.value_presentation}"
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Decoratorを適用
|
|
30
|
+
Spree::OptionValueVariant.prepend(Spree::OptionValueVariantDecorator)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Order::AddressBookDecorator
|
|
3
|
+
# @gem-override spree_core-5.3.6/app/models/spree/order/address_book.rb#ship_address_attributes=
|
|
4
|
+
# @see https://github.com/be-agile/giga-repeat/commit/e57a39c4
|
|
5
|
+
# 本家との差分は user.reload を挟む点(チェックアップ住所ステップ通過時のデフォルト住所同期ズレ対策)。
|
|
6
|
+
def ship_address_attributes=(attributes)
|
|
7
|
+
self.ship_address = update_or_create_address(attributes)
|
|
8
|
+
user.reload.ship_address = ship_address if should_assign_user_default_address?(ship_address)
|
|
9
|
+
self.ship_address = nil if quick_checkout_address?(attributes[:quick_checkout]) && !ship_address.persisted?
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
Spree::Order::AddressBook.prepend Spree::Order::AddressBookDecorator
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module OrderMergerDecorator
|
|
3
|
+
# @gem-override spree_core-5.3.6/app/models/spree/order_merger.rb#merge!
|
|
4
|
+
# @see https://github.com/be-agile/giga-repeat/commit/d0dbe2b4524e22c1cf974bbd4829c587ef7cd254
|
|
5
|
+
def merge!(other_order, user = nil, discard_merged: true)
|
|
6
|
+
other_order.line_items.each do |other_order_line_item|
|
|
7
|
+
next unless other_order_line_item.currency == order.currency
|
|
8
|
+
|
|
9
|
+
current_line_item = find_matching_line_item(other_order_line_item)
|
|
10
|
+
handle_merge(current_line_item, other_order_line_item)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
set_user(user)
|
|
14
|
+
clear_addresses(other_order) if discard_merged
|
|
15
|
+
persist_merge
|
|
16
|
+
|
|
17
|
+
if discard_merged
|
|
18
|
+
# So that the destroy doesn't take out line items which may have been re-assigned
|
|
19
|
+
other_order.line_items.reload
|
|
20
|
+
other_order.destroy
|
|
21
|
+
else
|
|
22
|
+
other_order.line_items.reload
|
|
23
|
+
other_order.updater.update
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
Spree::OrderMerger.prepend(Spree::OrderMergerDecorator)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module PriceRules
|
|
3
|
+
module CustomerGroupRuleDecorator
|
|
4
|
+
module ClassMethods
|
|
5
|
+
# @gem-override spree_core-5.3.6/app/models/spree/price_rule.rb#human_name
|
|
6
|
+
# Spree 5.3: 本家 self.human_name は name.demodulize.titleize で英語固定(i18n を引かない)。
|
|
7
|
+
# 価格表ルール追加モーダルの見出しを日本語化するため i18n を引く。
|
|
8
|
+
# (description は本家 CustomerGroupRule が既に Spree.t を使い日本語化済みのため上書き不要)
|
|
9
|
+
# 訳語は config/locales/spree.ja.yml の spree.price_rules.customer_group_rule.name。
|
|
10
|
+
def human_name
|
|
11
|
+
Spree.t('price_rules.customer_group_rule.name')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
Spree::PriceRules::CustomerGroupRule.singleton_class.prepend(Spree::PriceRules::CustomerGroupRuleDecorator::ClassMethods)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module PriceRules
|
|
3
|
+
module UserRuleDecorator
|
|
4
|
+
module ClassMethods
|
|
5
|
+
# @gem-override spree_core-5.3.6/app/models/spree/price_rule.rb#human_name
|
|
6
|
+
# Spree 5.3: 本家 self.human_name は name.demodulize.titleize で英語固定(i18n を引かない)。
|
|
7
|
+
# 価格表ルール追加モーダルの見出しを日本語化するため i18n を引く。
|
|
8
|
+
# 訳語は config/locales/spree.ja.yml の spree.price_rules.user_rule.name。
|
|
9
|
+
def human_name
|
|
10
|
+
Spree.t('price_rules.user_rule.name')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @gem-override spree_core-5.3.6/app/models/spree/price_rules/user_rule.rb#description
|
|
14
|
+
# Spree 5.3: 本家 self.description は英語文字列をハードコードしており i18n を引かない。
|
|
15
|
+
# CustomerGroupRule のみ Spree.t を使うため、UserRule も同流儀で i18n 化し日本語化する。
|
|
16
|
+
# 訳語は config/locales/spree.ja.yml の spree.price_rules.user_rule.description。
|
|
17
|
+
def description
|
|
18
|
+
Spree.t('price_rules.user_rule.description')
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Spree::PriceRules::UserRule.singleton_class.prepend(Spree::PriceRules::UserRuleDecorator::ClassMethods)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module PriceRules
|
|
3
|
+
module VolumeRuleDecorator
|
|
4
|
+
module ClassMethods
|
|
5
|
+
# @gem-override spree_core-5.3.6/app/models/spree/price_rule.rb#human_name
|
|
6
|
+
# Spree 5.3: 本家 self.human_name は name.demodulize.titleize で英語固定(i18n を引かない)。
|
|
7
|
+
# 価格表ルール追加モーダルの見出しを日本語化するため i18n を引く。
|
|
8
|
+
# 訳語は config/locales/spree.ja.yml の spree.price_rules.volume_rule.name。
|
|
9
|
+
def human_name
|
|
10
|
+
Spree.t('price_rules.volume_rule.name')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @gem-override spree_core-5.3.6/app/models/spree/price_rules/volume_rule.rb#description
|
|
14
|
+
# Spree 5.3: 本家 self.description は英語文字列をハードコードしており i18n を引かない。
|
|
15
|
+
# CustomerGroupRule のみ Spree.t を使うため、VolumeRule も同流儀で i18n 化し日本語化する。
|
|
16
|
+
# 訳語は config/locales/spree.ja.yml の spree.price_rules.volume_rule.description。
|
|
17
|
+
def description
|
|
18
|
+
Spree.t('price_rules.volume_rule.description')
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Spree::PriceRules::VolumeRule.singleton_class.prepend(Spree::PriceRules::VolumeRuleDecorator::ClassMethods)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module PriceRules
|
|
3
|
+
module ZoneRuleDecorator
|
|
4
|
+
module ClassMethods
|
|
5
|
+
# @gem-override spree_core-5.3.6/app/models/spree/price_rule.rb#human_name
|
|
6
|
+
# Spree 5.3: 本家 self.human_name は name.demodulize.titleize で英語固定(i18n を引かない)。
|
|
7
|
+
# 価格表ルール追加モーダルの見出しを日本語化するため i18n を引く。
|
|
8
|
+
# 訳語は config/locales/spree.ja.yml の spree.price_rules.zone_rule.name。
|
|
9
|
+
def human_name
|
|
10
|
+
Spree.t('price_rules.zone_rule.name')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @gem-override spree_core-5.3.6/app/models/spree/price_rules/zone_rule.rb#description
|
|
14
|
+
# Spree 5.3: 本家 self.description は英語文字列をハードコードしており i18n を引かない。
|
|
15
|
+
# CustomerGroupRule のみ Spree.t を使うため、ZoneRule も同流儀で i18n 化し日本語化する。
|
|
16
|
+
# 訳語は config/locales/spree.ja.yml の spree.price_rules.zone_rule.description。
|
|
17
|
+
def description
|
|
18
|
+
Spree.t('price_rules.zone_rule.description')
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Spree::PriceRules::ZoneRule.singleton_class.prepend(Spree::PriceRules::ZoneRuleDecorator::ClassMethods)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Pricing
|
|
3
|
+
# 1商品の全 variant について、適用される実価格をまとめて解決する。
|
|
4
|
+
#
|
|
5
|
+
# 本家の Resolver は variant ごとに price_list の適用判定とクエリ(または Rails.cache 往復)を
|
|
6
|
+
# 行うため、多 variant 商品ではフラグメントキャッシュが冷えた際の一覧描画が極端に遅くなる。
|
|
7
|
+
# price_list の適用判定は variant に依存しない(active/scheduled + 期間 + rules のみ)ので、
|
|
8
|
+
# 商品ごとに1回だけ判定し、全 variant の価格をまとめて読んでから選び直す。
|
|
9
|
+
#
|
|
10
|
+
# 価格の選択規則は Resolver から複製しているため、Spree アップグレード時は各メソッドの
|
|
11
|
+
# @gem-override マーカーで本家の変更(rake gem_override_marker:diff / :check)を確認すること。
|
|
12
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1290
|
|
13
|
+
class BatchResolver
|
|
14
|
+
attr_reader :variants, :context
|
|
15
|
+
|
|
16
|
+
# @param variants [Array<Spree::Variant>] master を含む解決対象の variant
|
|
17
|
+
# @param context [Spree::Pricing::Context] 商品共通の価格解決コンテキスト
|
|
18
|
+
def initialize(variants:, context:)
|
|
19
|
+
@variants = variants
|
|
20
|
+
@context = context
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# @return [Array<Spree::Price>] amount が確定した価格のみ(価格未設定の variant は除外)
|
|
24
|
+
def resolve
|
|
25
|
+
return [] if variants.empty?
|
|
26
|
+
|
|
27
|
+
price_list_ids = applicable_price_lists.map(&:id)
|
|
28
|
+
prices_by_variant_id = prices_by_variant_id_for(currency)
|
|
29
|
+
|
|
30
|
+
variants.filter_map do |variant|
|
|
31
|
+
find_best_price(prices_by_variant_id[variant.id] || [], price_list_ids)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def currency
|
|
38
|
+
@currency ||= context.currency&.upcase
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @gem-override spree_core-5.3.6/lib/spree/core/pricing/resolver.rb#find_best_price
|
|
42
|
+
# reason: 本家は variant ごとに price_list を1件ずつ照会するが、ここでは読み込み済みの価格配列と
|
|
43
|
+
# 商品単位で判定済みの price_list id から同じ優先順位で選ぶ。本家の find_price_for_list
|
|
44
|
+
# (.non_zero) と find_base_price (amount present) の条件もこのメソッドに畳んである。
|
|
45
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1290
|
|
46
|
+
# @param prices [Array<Spree::Price>] その variant の該当通貨の価格
|
|
47
|
+
# @param price_list_ids [Array] 適用される price_list の id(position 昇順)
|
|
48
|
+
# @return [Spree::Price, nil]
|
|
49
|
+
def find_best_price(prices, price_list_ids)
|
|
50
|
+
price_list_ids.each do |price_list_id|
|
|
51
|
+
price = prices.find do |candidate|
|
|
52
|
+
candidate.price_list_id == price_list_id && candidate.amount.present? && !candidate.amount.zero?
|
|
53
|
+
end
|
|
54
|
+
return price if price
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
prices.find { |price| price.price_list_id.nil? && price.amount.present? }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# @gem-override spree_core-5.3.6/lib/spree/core/pricing/resolver.rb#applicable_price_lists
|
|
61
|
+
# reason: 本家は variant ごとの Resolver インスタンス単位でメモ化するが、適用判定は variant に
|
|
62
|
+
# 依存しないため商品単位(このインスタンス)で1回だけ評価する。判定そのものは本家と同一。
|
|
63
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1290
|
|
64
|
+
# @return [Array<Spree::PriceList>]
|
|
65
|
+
def applicable_price_lists
|
|
66
|
+
@applicable_price_lists ||= price_lists_for_context.select { |price_list| price_list.applicable?(context) }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @gem-override spree_core-5.3.6/lib/spree/core/pricing/resolver.rb#price_lists_for_context
|
|
70
|
+
# reason: 本家と同一。Resolver を経由しないため取得元の分岐だけ複製している。
|
|
71
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1290
|
|
72
|
+
# @return [Enumerable<Spree::PriceList>]
|
|
73
|
+
def price_lists_for_context
|
|
74
|
+
if context.store == Spree::Current.store && context.currency == Spree::Current.currency
|
|
75
|
+
Spree::Current.price_lists
|
|
76
|
+
else
|
|
77
|
+
Spree::PriceList.for_context(context)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# variant_id ごとの該当通貨の価格。未ロードの variant があれば1クエリでまとめて読む。
|
|
82
|
+
# 通貨の比較は、本家が SQL(with_currency)で行い spree_prices の照合順序が
|
|
83
|
+
# utf8mb4_general_ci = 大文字小文字を区別しないため、Ruby 側でも区別しない。
|
|
84
|
+
# @param currency [String]
|
|
85
|
+
# @return [Hash]
|
|
86
|
+
def prices_by_variant_id_for(currency)
|
|
87
|
+
unloaded = variants.reject { |variant| variant.association(:prices).loaded? }
|
|
88
|
+
ActiveRecord::Associations::Preloader.new(records: unloaded, associations: :prices).call if unloaded.any?
|
|
89
|
+
|
|
90
|
+
variants.to_h do |variant|
|
|
91
|
+
[ variant.id, variant.prices.select { |price| price.currency&.casecmp?(currency) } ]
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module PromotionHandler
|
|
3
|
+
module CartDecorator
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
# @gem-override spree_core-5.3.6/app/models/spree/promotion_handler/cart.rb#promotions
|
|
7
|
+
# @see https://github.com/be-agile/giga-repeat/issues/723
|
|
8
|
+
# プロモーションが大量にあるとカート処理が重くなるため、本家のスコープ取得を
|
|
9
|
+
# UNION の生 SQL に置き換え、カート内容にマッチしない Product ルールを除外する。
|
|
10
|
+
def promotions
|
|
11
|
+
union_sql = "#{order.promotions.active.to_sql} UNION #{promotion_scope.active.automatic.to_sql}"
|
|
12
|
+
|
|
13
|
+
if exclude_promotion_ids.present?
|
|
14
|
+
final_sql = "SELECT * FROM (#{union_sql}) AS unioned_promotions WHERE id NOT IN (#{exclude_promotion_ids.join(',')})"
|
|
15
|
+
promotion_scope.find_by_sql(final_sql)
|
|
16
|
+
else
|
|
17
|
+
promotion_scope.find_by_sql(union_sql)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def exclude_promotion_ids
|
|
22
|
+
cart_product_ids = order.line_items.joins(:variant).pluck('spree_variants.product_id').uniq
|
|
23
|
+
# Find all promotions with Product rules
|
|
24
|
+
all_product_rule_promotions = Spree::Promotion
|
|
25
|
+
.joins(:promotion_rules)
|
|
26
|
+
.where(promotion_rules: { type: 'Spree::Promotion::Rules::Product' })
|
|
27
|
+
.distinct
|
|
28
|
+
|
|
29
|
+
return all_product_rule_promotions.pluck(:id) if cart_product_ids.blank?
|
|
30
|
+
|
|
31
|
+
# Find promotions with Product rules that match cart contents
|
|
32
|
+
# Use ProductPromotionRule as starting point since the association exists
|
|
33
|
+
matching_promotion_rule_ids = Spree::ProductPromotionRule
|
|
34
|
+
.where(product_id: cart_product_ids)
|
|
35
|
+
.joins(:promotion_rule)
|
|
36
|
+
.where(promotion_rule: { type: 'Spree::Promotion::Rules::Product' })
|
|
37
|
+
.pluck(:promotion_rule_id)
|
|
38
|
+
|
|
39
|
+
matching_promotions = Spree::Promotion
|
|
40
|
+
.joins(:promotion_rules)
|
|
41
|
+
.where(promotion_rules: { id: matching_promotion_rule_ids })
|
|
42
|
+
.distinct
|
|
43
|
+
|
|
44
|
+
# Exclude Product rule promotions that don't match cart contents
|
|
45
|
+
all_product_rule_promotions.where.not(id: matching_promotions.select(:id)).pluck(:id)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
Spree::PromotionHandler::Cart.prepend(Spree::PromotionHandler::CartDecorator)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Stock
|
|
3
|
+
module PackerDecorator
|
|
4
|
+
# 同一 variant の複数 line_item が order に存在する場合 (例: spree_embed_gravity_forms の
|
|
5
|
+
# `wp_gf_entry_id` で line_item を分離するケース) に、Spree 本家の実装では
|
|
6
|
+
# `inventory_units.index_by(&:variant_id)` で 1 つに集約してしまい、最初に作られた
|
|
7
|
+
# line_item の inventory_unit が package に渡らず orphan になる問題への対処。
|
|
8
|
+
# Issue #1187 を参照。
|
|
9
|
+
#
|
|
10
|
+
# 修正方針: variant ごとに qty 合計で fill_status を呼び (本家の在庫判定ロジックを維持)、
|
|
11
|
+
# 結果を line_item 単位で先着順に on_hand / backordered へ按分する。
|
|
12
|
+
# 単純な each 置換では fill_status が読み取り専用 (count_on_hand を減らさない) なため
|
|
13
|
+
# 過剰販売が起きてしまうので、按分配置が必須。
|
|
14
|
+
#
|
|
15
|
+
# @gem-override spree_core-5.3.6/app/models/spree/stock/packer.rb#default_package
|
|
16
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1187
|
|
17
|
+
def default_package
|
|
18
|
+
package = Package.new(stock_location)
|
|
19
|
+
|
|
20
|
+
inventory_units.group_by(&:variant_id).each do |variant_id, units_for_variant|
|
|
21
|
+
variant = Spree::Variant.find(variant_id)
|
|
22
|
+
|
|
23
|
+
if variant.should_track_inventory?
|
|
24
|
+
next unless stock_location.stocks?(variant)
|
|
25
|
+
|
|
26
|
+
total_qty = units_for_variant.sum(&:quantity)
|
|
27
|
+
on_hand, _backordered = stock_location.fill_status(variant, total_qty)
|
|
28
|
+
|
|
29
|
+
allocate_units_to_package(package, units_for_variant, on_hand)
|
|
30
|
+
else
|
|
31
|
+
units_for_variant.each { |inventory_unit| package.add(inventory_unit.dup) }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
package
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
# variant 単位の fill_status 結果 (on_hand 数) を line_item 単位の inventory_unit に
|
|
41
|
+
# 先着順で配分する。on_hand_remaining を使い切ったら以降は backordered になる。
|
|
42
|
+
def allocate_units_to_package(package, units_for_variant, on_hand)
|
|
43
|
+
on_hand_remaining = on_hand
|
|
44
|
+
|
|
45
|
+
units_for_variant.each do |inventory_unit|
|
|
46
|
+
unit = inventory_unit.dup
|
|
47
|
+
qty = inventory_unit.quantity
|
|
48
|
+
|
|
49
|
+
unit_on_hand = [ qty, on_hand_remaining ].min
|
|
50
|
+
on_hand_remaining -= unit_on_hand
|
|
51
|
+
unit_backordered = qty - unit_on_hand
|
|
52
|
+
|
|
53
|
+
package.add(InventoryUnit.split(unit, unit_backordered), :backordered) if unit_backordered.positive?
|
|
54
|
+
package.add(InventoryUnit.split(unit, unit_on_hand), :on_hand) if unit_on_hand.positive?
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
Spree::Stock::Packer.prepend(Spree::Stock::PackerDecorator)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Stock
|
|
3
|
+
module PrioritizerDecorator
|
|
4
|
+
# 同一 variant の複数 line_item が order に存在する場合 (例: spree_embed_gravity_forms の
|
|
5
|
+
# `wp_gf_entry_id` で line_item を分離するケース) に、Spree 本家の
|
|
6
|
+
# `hash_item` は shipment が無いと `variant.hash` のみで識別するため、
|
|
7
|
+
# 同 variant の inventory_unit が同じ adjuster を共有してしまい、
|
|
8
|
+
# 後発の inventory_unit が `Adjuster#adjust` の `fulfilled?` 判定で
|
|
9
|
+
# `remove_item` されて shipment から欠落する。
|
|
10
|
+
# Issue #1187 を参照。Packer decorator の修正と合わせて line_item 単位で adjuster を
|
|
11
|
+
# 個別化することで対処する。
|
|
12
|
+
#
|
|
13
|
+
# @gem-override spree_core-5.3.6/app/models/spree/stock/prioritizer.rb#hash_item
|
|
14
|
+
# @see https://github.com/be-agile/giga-repeat/issues/1187
|
|
15
|
+
def hash_item(item)
|
|
16
|
+
line_item_id = item.inventory_unit.line_item_id
|
|
17
|
+
return super unless line_item_id
|
|
18
|
+
|
|
19
|
+
shipment = item.inventory_unit.shipment
|
|
20
|
+
base = item.inventory_unit.variant.hash ^ line_item_id.hash
|
|
21
|
+
shipment.present? ? (base ^ shipment.hash) : base
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Spree::Stock::Prioritizer.prepend(Spree::Stock::PrioritizerDecorator)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module TaxRateDecorator
|
|
3
|
+
def adjust_order_level_adjustments(order)
|
|
4
|
+
return unless order.tax_address.nil? || zone.include?(order.tax_address)
|
|
5
|
+
|
|
6
|
+
order_adjustments = order.adjustments.eligible.non_tax
|
|
7
|
+
.where(adjustable_type: 'Spree::Order')
|
|
8
|
+
|
|
9
|
+
total_tax_amount = 0
|
|
10
|
+
|
|
11
|
+
order_adjustments.each do |adjustment|
|
|
12
|
+
tax_amount = calculate_tax_for_adjustment(adjustment)
|
|
13
|
+
total_tax_amount += tax_amount if tax_amount
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
return if total_tax_amount.round(0).zero?
|
|
17
|
+
|
|
18
|
+
existing_tax = find_existing_tax_adjustment_for_order(order)
|
|
19
|
+
|
|
20
|
+
if existing_tax
|
|
21
|
+
update_tax_adjustment(existing_tax, total_tax_amount)
|
|
22
|
+
else
|
|
23
|
+
create_tax_adjustment(order, total_tax_amount)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def calculate_tax_for_adjustment(adjustment)
|
|
28
|
+
tax_category = get_tax_category_for_adjustment(adjustment)
|
|
29
|
+
return nil unless tax_category
|
|
30
|
+
return nil unless tax_category == self.tax_category
|
|
31
|
+
return nil if adjustment.amount.zero?
|
|
32
|
+
|
|
33
|
+
pre_tax_amount = adjustment.amount / (1 + amount)
|
|
34
|
+
tax_amount = adjustment.amount - pre_tax_amount
|
|
35
|
+
|
|
36
|
+
tax_amount
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def get_tax_category_for_adjustment(adjustment)
|
|
40
|
+
source = adjustment.source
|
|
41
|
+
return nil unless source
|
|
42
|
+
|
|
43
|
+
case adjustment.source_type
|
|
44
|
+
when 'Spree::PromotionAction'
|
|
45
|
+
# 定額(FlatRate)など tax_category を持たない calculator もあるため、
|
|
46
|
+
# respond_to? でガードして NoMethodError を避ける(try で同等)。
|
|
47
|
+
source.calculator.try(:tax_category)
|
|
48
|
+
when 'Spree::Calculator'
|
|
49
|
+
source.try(:tax_category)
|
|
50
|
+
when 'Spree::ShippingMethod'
|
|
51
|
+
source.try(:tax_category)
|
|
52
|
+
when 'Spree::PaymentMethod'
|
|
53
|
+
source.try(:tax_category)
|
|
54
|
+
else
|
|
55
|
+
nil
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def find_existing_tax_adjustment_for_order(order)
|
|
60
|
+
order.adjustments.tax.find_by(
|
|
61
|
+
source_type: 'Spree::TaxRate',
|
|
62
|
+
source_id: id,
|
|
63
|
+
adjustable_type: 'Spree::Order'
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def create_tax_adjustment(order, tax_amount)
|
|
68
|
+
order.adjustments.create!(
|
|
69
|
+
adjustable_type: 'Spree::Order',
|
|
70
|
+
adjustable_id: order.id,
|
|
71
|
+
amount: tax_amount.round(0),
|
|
72
|
+
included: true,
|
|
73
|
+
label: label,
|
|
74
|
+
order: order,
|
|
75
|
+
state: 'closed',
|
|
76
|
+
source_type: 'Spree::TaxRate',
|
|
77
|
+
source_id: id
|
|
78
|
+
)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def update_tax_adjustment(existing_tax, tax_amount)
|
|
82
|
+
new_amount = tax_amount.round(0)
|
|
83
|
+
if existing_tax.amount != new_amount
|
|
84
|
+
existing_tax.update_columns(
|
|
85
|
+
amount: new_amount,
|
|
86
|
+
updated_at: Time.current
|
|
87
|
+
)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
Spree::TaxRate.prepend(Spree::TaxRateDecorator)
|