comable_core 0.2.3 → 0.3.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +16 -4
  4. data/app/controllers/concerns/comable/permitted_attributes.rb +15 -0
  5. data/app/helpers/comable/application_helper.rb +36 -1
  6. data/app/helpers/comable/products_helper.rb +35 -8
  7. data/app/mailers/comable/order_mailer.rb +1 -1
  8. data/app/models/comable/ability.rb +18 -0
  9. data/app/models/comable/address.rb +6 -2
  10. data/app/models/comable/category.rb +72 -0
  11. data/app/models/comable/customer.rb +53 -53
  12. data/app/models/comable/image.rb +11 -0
  13. data/app/models/comable/order.rb +42 -47
  14. data/app/models/comable/order_detail.rb +30 -37
  15. data/app/models/comable/payment_method.rb +26 -0
  16. data/app/models/comable/product.rb +29 -3
  17. data/app/models/comable/shipment_method.rb +4 -0
  18. data/app/models/comable/stock.rb +8 -24
  19. data/app/models/comable/store.rb +7 -2
  20. data/{lib → app/models/concerns}/comable/cart_owner.rb +25 -11
  21. data/app/models/concerns/comable/checkout.rb +90 -0
  22. data/app/models/concerns/comable/product/search.rb +41 -0
  23. data/app/models/concerns/comable/role_owner.rb +15 -0
  24. data/app/uploaders/image_uploader.rb +7 -0
  25. data/app/views/comable/order_mailer/complete.text.erb +7 -9
  26. data/config/locales/ja.yml +237 -8
  27. data/db/migrate/20140120032559_create_comable_customers.rb +1 -4
  28. data/db/migrate/20140502060116_create_comable_stocks.rb +2 -3
  29. data/db/migrate/20140723175431_create_comable_orders.rb +4 -5
  30. data/db/migrate/20140723175810_create_comable_order_details.rb +3 -3
  31. data/db/migrate/20140817194104_create_comable_payment_methods.rb +11 -0
  32. data/db/migrate/20140926063541_create_comable_stores.rb +1 -1
  33. data/db/migrate/20141024025526_create_comable_addresses.rb +2 -2
  34. data/db/migrate/20150111031228_create_comable_categories.rb +9 -0
  35. data/db/migrate/20150111031229_create_comable_products_categories.rb +8 -0
  36. data/db/migrate/20150112173706_create_comable_images.rb +8 -0
  37. data/lib/comable/core/configuration.rb +6 -0
  38. data/lib/comable/core/engine.rb +23 -11
  39. data/lib/comable/errors.rb +0 -3
  40. data/lib/comable/{payment_method → payment_provider}/base.rb +1 -1
  41. data/lib/comable/{payment_method → payment_provider}/general.rb +1 -1
  42. data/lib/comable/{payment_method.rb → payment_provider.rb} +3 -3
  43. data/lib/comable/state_machine_patch.rb +16 -0
  44. data/lib/comable_core.rb +13 -3
  45. metadata +97 -10
  46. data/app/models/comable/order_delivery.rb +0 -21
  47. data/app/models/comable/payment.rb +0 -24
  48. data/db/migrate/20140723175624_create_comable_order_deliveries.rb +0 -9
  49. data/db/migrate/20140817194104_create_comable_payments.rb +0 -11
@@ -3,28 +3,29 @@ module Comable
3
3
  include Comable::SkuItem
4
4
  include Comable::SkuChoice
5
5
 
6
- belongs_to :stock, class_name: Comable::Stock.name, foreign_key: Comable::Stock.table_name.singularize.foreign_key
7
- belongs_to :order_delivery, class_name: Comable::OrderDelivery.name, foreign_key: Comable::OrderDelivery.table_name.singularize.foreign_key
6
+ belongs_to :stock, class_name: Comable::Stock.name, autosave: true
7
+ belongs_to :order, class_name: Comable::Order.name, inverse_of: :order_details
8
8
 
9
- accepts_nested_attributes_for :stock
10
-
11
- # TODO: バリデーションの追加
9
+ validates :quantity, numericality: { greater_than: 0 }
10
+ validate :valid_stock_quantity
12
11
 
13
12
  delegate :product, to: :stock
14
- delegate :guest_token, to: :order_delivery
15
- delegate :complete?, to: :order_delivery
16
- delegate :order, to: :order_delivery
13
+ delegate :image_url, to: :product
14
+ delegate :guest_token, to: :order
15
+ delegate :completed?, to: :order, allow_nil: true
16
+ delegate :completing?, to: :order, allow_nil: true
17
17
 
18
- before_save :save_to_add_cart, unless: :complete?
19
- before_save :verify_quantity, unless: :complete?
18
+ with_options if: -> { !completed? || completing? } do |incomplete|
19
+ incomplete.before_validation :copy_attributes
20
+ end
20
21
 
21
- def save_to_complete
22
- self.attributes = current_attributes
22
+ def complete
23
+ copy_attributes
23
24
  decrement_stock
24
25
  end
25
26
 
26
27
  # TODO: カート投入時との差額表示
27
- def save_to_add_cart
28
+ def copy_attributes
28
29
  self.attributes = current_attributes
29
30
  end
30
31
 
@@ -43,30 +44,30 @@ module Comable
43
44
  price * quantity
44
45
  end
45
46
 
46
- def valid_order_quantity?
47
- if quantity <= 0
48
- add_order_quantity_invalid_error_to_order
49
- return false
50
- end
51
-
52
- if stock.soldout?(quantity: quantity)
53
- add_product_soldout_error_to_order
54
- return false
47
+ def soldout_stock?
48
+ stock_with_clean_quantity do |stock|
49
+ stock.soldout?(quantity: quantity)
55
50
  end
51
+ end
56
52
 
57
- true
53
+ def valid_stock_quantity
54
+ return unless soldout_stock?
55
+ errors.add :quantity, Comable.t('errors.messages.product_soldout', name: stock.name_with_sku)
58
56
  end
59
57
 
60
58
  private
61
59
 
62
- def decrement_stock
63
- return unless quantity
64
- return unless stock.quantity
65
- stock.quantity -= quantity
60
+ def stock_with_clean_quantity
61
+ quantity_will = stock.quantity
62
+ stock.quantity = stock.quantity_was if stock.quantity_was
63
+ yield stock
64
+ ensure
65
+ stock.quantity = quantity_will
66
66
  end
67
67
 
68
- def verify_quantity
69
- fail Comable::NoStock if stock.soldout?(quantity: quantity)
68
+ def decrement_stock
69
+ stock.lock!
70
+ stock.quantity -= quantity
70
71
  end
71
72
 
72
73
  def current_attributes
@@ -80,13 +81,5 @@ module Comable
80
81
  sku_v_choice_name: stock.sku_v_choice_name
81
82
  }
82
83
  end
83
-
84
- def add_order_quantity_invalid_error_to_order
85
- order.errors.add :base, I18n.t('comable.errors.messages.order_quantity_invalid', name: stock.name_with_sku)
86
- end
87
-
88
- def add_product_soldout_error_to_order
89
- order.errors.add :base, I18n.t('comable.errors.messages.product_soldout', name: stock.name_with_sku)
90
- end
91
84
  end
92
85
  end
@@ -0,0 +1,26 @@
1
+ module Comable
2
+ class PaymentMethod < ActiveRecord::Base
3
+ validates :name, presence: true, length: { maximum: 255 }
4
+ validates :payment_provider_type, presence: true, length: { maximum: 255 }
5
+ validates :payment_provider_kind, presence: true, numericality: { greater_than_or_equal_to: 0 }
6
+ validates :enable_price_from, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
7
+ validates :enable_price_to, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
8
+
9
+ def payment_provider
10
+ return unless Object.const_defined?(payment_provider_type)
11
+ Object.const_get(payment_provider_type)
12
+ end
13
+
14
+ def payment_provider_name
15
+ payment_provider.display_name
16
+ end
17
+
18
+ def payment_provider_kind_key
19
+ payment_provider.kind.keys.slice(payment_provider_kind)
20
+ end
21
+
22
+ def payment_provider_kind_name
23
+ payment_provider.kind.slice(payment_provider_kind_key).values.first
24
+ end
25
+ end
26
+ end
@@ -1,18 +1,44 @@
1
1
  module Comable
2
2
  class Product < ActiveRecord::Base
3
3
  include Comable::SkuItem
4
+ include Comable::Product::Search
4
5
 
5
- has_many :stocks, class_name: Comable::Stock.name, foreign_key: table_name.singularize.foreign_key
6
- after_create :create_stock
6
+ has_many :stocks, class_name: Comable::Stock.name, dependent: :destroy
7
+ has_many :images, class_name: Comable::Image.name, dependent: :destroy
8
+ has_and_belongs_to_many :categories, class_name: Comable::Category.name, join_table: :comable_products_categories
9
+
10
+ accepts_nested_attributes_for :images, allow_destroy: true
11
+
12
+ validates :name, presence: true, length: { maximum: 255 }
13
+ validates :code, presence: true, length: { maximum: 255 }
14
+ validates :price, presence: true, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
15
+ validates :sku_h_item_name, length: { maximum: 255 }
16
+ validates :sku_v_item_name, length: { maximum: 255 }
17
+
18
+ # Add conditions for the images association.
19
+ # Override method of the images association to support Rails 3.x.
20
+ def images
21
+ super.order(:id)
22
+ end
23
+
24
+ def image_url
25
+ image = images.first
26
+ return image.url if image
27
+ 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTcxIiBoZWlnaHQ9IjE4MCIgdmlld0JveD0iMCAwIDE3MSAxODAiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxkZWZzLz48cmVjdCB3aWR0aD0iMTcxIiBoZWlnaHQ9IjE4MCIgZmlsbD0iI0VFRUVFRSIvPjxnPjx0ZXh0IHg9IjU4IiB5PSI5MCIgc3R5bGU9ImZpbGw6I0FBQUFBQTtmb250LXdlaWdodDpib2xkO2ZvbnQtZmFtaWx5OkFyaWFsLCBIZWx2ZXRpY2EsIE9wZW4gU2Fucywgc2Fucy1zZXJpZiwgbW9ub3NwYWNlO2ZvbnQtc2l6ZToxMHB0O2RvbWluYW50LWJhc2VsaW5lOmNlbnRyYWwiPjE3MXgxODA8L3RleHQ+PC9nPjwvc3ZnPg=='
28
+ end
7
29
 
8
30
  def unsold?
9
- stocks.activated.unsold.exists?
31
+ stocks.unsold.exists?
10
32
  end
11
33
 
12
34
  def soldout?
13
35
  !unsold?
14
36
  end
15
37
 
38
+ def category_path_names=(category_path_names, delimiter: Comable::Category::DEFAULT_PATH_NAME_DELIMITER)
39
+ self.categories = Comable::Category.find_by_path_names(category_path_names, delimiter: delimiter)
40
+ end
41
+
16
42
  private
17
43
 
18
44
  def create_stock
@@ -1,5 +1,9 @@
1
1
  module Comable
2
2
  class ShipmentMethod < ActiveRecord::Base
3
+ validates :name, presence: true, length: { maximum: 255 }
4
+ validates :fee, presence: true, numericality: { greater_than_or_equal_to: 0 }
5
+ validates :traking_url, length: { maximum: 255 }
6
+
3
7
  scope :activated, -> { where(activate_flag: true) }
4
8
  scope :deactivated, -> { where(activate_flag: false) }
5
9
  end
@@ -6,16 +6,12 @@ module Comable
6
6
  class Stock < ActiveRecord::Base
7
7
  include Comable::SkuChoice
8
8
 
9
- belongs_to :product, class_name: Comable::Product.name, foreign_key: Comable::Product.table_name.singularize.foreign_key
9
+ belongs_to :product, class_name: Comable::Product.name
10
10
 
11
11
  #
12
12
  # @!group Scope
13
13
  #
14
14
 
15
- # @!scope class
16
- # 有効な在庫インスタンスを返す
17
- scope :activated, -> { where.not(product_id_num: nil) }
18
-
19
15
  # @!scope class
20
16
  # 品切れでない在庫インスタンスを返す
21
17
  scope :unsold, -> { where('quantity > ?', 0) }
@@ -28,6 +24,13 @@ module Comable
28
24
  # @!endgroup
29
25
  #
30
26
 
27
+ validates :product, presence: true
28
+ validates :code, presence: true, length: { maximum: 255 }
29
+ validates :sku_h_choice_name, length: { maximum: 255 }
30
+ validates :sku_v_choice_name, length: { maximum: 255 }
31
+ # TODO: add conditions (by limitless flag, backoder flag and etc..)
32
+ validates :quantity, numericality: { greater_than_or_equal_to: 0 }
33
+
31
34
  delegate :name, to: :product
32
35
  delegate :price, to: :product
33
36
  delegate :sku?, to: :product
@@ -41,8 +44,6 @@ module Comable
41
44
  # @return [Boolean] 在庫があれば true を返す
42
45
  # @see #soldout?
43
46
  def unsold?(quantity: 1)
44
- return false if product_id_num.nil?
45
- return false if self.quantity.nil?
46
47
  (self.quantity - quantity) >= 0
47
48
  end
48
49
 
@@ -57,22 +58,5 @@ module Comable
57
58
  def soldout?(quantity: 1)
58
59
  !unsold?(quantity: quantity)
59
60
  end
60
-
61
- # 在庫減算を行う
62
- #
63
- # @example
64
- # stock.quantity #=> 10
65
- # stock.decrement!(quantity: 1) #=> true
66
- # stock.quantity #=> 9
67
- #
68
- # @param quantity [Fixnum] 減算する在庫数を指定する
69
- # @return [Boolean] レコードの保存に成功すると true を返す
70
- def decrement!(quantity: 1)
71
- with_lock do
72
- # TODO: カラムマッピングのdecrementメソッドへの対応
73
- self.quantity -= quantity
74
- save!
75
- end
76
- end
77
61
  end
78
62
  end
@@ -1,11 +1,16 @@
1
1
  module Comable
2
2
  class Store < ActiveRecord::Base
3
+ validates :name, length: { maximum: 255 }
4
+ validates :meta_keywords, length: { maximum: 255 }
5
+ validates :meta_description, length: { maximum: 255 }
6
+ validates :email_sender, length: { maximum: 255 }
7
+
3
8
  class << self
4
9
  def instance
5
- first || new(name: default_store_name)
10
+ first || new(name: default_name)
6
11
  end
7
12
 
8
- def default_store_name
13
+ def default_name
9
14
  'Comable store'
10
15
  end
11
16
  end
@@ -32,6 +32,21 @@ module Comable
32
32
  def price
33
33
  sum(&:current_subtotal_price)
34
34
  end
35
+
36
+ def count
37
+ sum(&:quantity)
38
+ end
39
+
40
+ alias_method :size, :count
41
+
42
+ # TODO: Refactoring
43
+ def errors
44
+ ActiveModel::Errors.new(self).tap do |obj|
45
+ map(&:errors).map(&:full_messages).flatten.each do |full_message|
46
+ obj[:base] << full_message
47
+ end
48
+ end
49
+ end
35
50
  end
36
51
 
37
52
  private
@@ -50,31 +65,30 @@ module Comable
50
65
  end
51
66
 
52
67
  def add_stock_to_cart(stock, quantity)
53
- cart_items = find_cart_items_by(stock)
54
- if cart_items.any?
55
- cart_item = cart_items.first
68
+ cart_item = find_cart_item_by(stock)
69
+ if cart_item
56
70
  cart_item.quantity += quantity
57
71
  (cart_item.quantity > 0) ? cart_item.save : cart_item.destroy
58
72
  else
59
- cart_items.create(quantity: quantity)
73
+ cart_items.build(stock_id: stock.id, quantity: quantity).save
60
74
  end
61
75
  end
62
76
 
63
77
  def reset_stock_from_cart(stock, quantity)
64
- cart_items = find_cart_items_by(stock)
78
+ cart_item = find_cart_item_by(stock)
65
79
  if quantity > 0
66
- return add_stock_to_cart(stock, quantity) if cart_items.empty?
67
- cart_items.first.update_attributes(quantity: quantity)
80
+ return add_stock_to_cart(stock, quantity) unless cart_item
81
+ cart_item.update_attributes(quantity: quantity)
68
82
  else
69
- return false if cart_items.empty?
70
- cart_items.first.destroy
83
+ return false unless cart_item
84
+ cart_items.destroy(cart_item)
71
85
  end
72
86
  end
73
87
 
74
- def find_cart_items_by(stock)
88
+ def find_cart_item_by(stock)
75
89
  # TODO: Refactoring
76
90
  fail unless stock.is_a?(Comable::Stock)
77
- cart_items.where(Comable::Stock.table_name.singularize.foreign_key => stock.id)
91
+ cart_items.find { |cart_item| cart_item.stock.id == stock.id }
78
92
  end
79
93
  end
80
94
  end
@@ -0,0 +1,90 @@
1
+ module Comable
2
+ module Checkout
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ state_machine initial: :cart do
7
+ state :cart
8
+ state :orderer
9
+ state :delivery
10
+ state :shipment
11
+ state :payment
12
+ state :confirm
13
+ state :complete
14
+
15
+ event :next_state do
16
+ transition :cart => :orderer, if: :orderer_required?
17
+ transition [:cart, :orderer] => :delivery, if: :delivery_required?
18
+ transition [:cart, :orderer, :delivery] => :shipment, if: :shipment_required?
19
+ transition [:cart, :orderer, :delivery, :shipment] => :payment, if: :payment_required?
20
+ transition all - [:confirm, :complete] => :confirm
21
+ transition :confirm => :complete
22
+ end
23
+
24
+ before_transition to: :complete do |order, _transition|
25
+ order.complete
26
+ end
27
+ end
28
+
29
+ # TODO: Remove with_options
30
+ with_options if: -> { state?(:cart) } do |context|
31
+ context.validates :customer_id, presence: true, uniqueness: { scope: [:customer_id, :completed_at] }, unless: :guest_token
32
+ context.validates :guest_token, presence: true, uniqueness: { scope: [:guest_token, :completed_at] }, unless: :customer
33
+ end
34
+
35
+ with_options if: -> { stated?(:cart) } do |context|
36
+ context.validates :email, presence: true
37
+ end
38
+
39
+ with_options if: -> { stated?(:orderer) } do |context|
40
+ context.validates :bill_address, presence: true
41
+ end
42
+
43
+ with_options if: -> { stated?(:delivery) } do |context|
44
+ context.validates :ship_address, presence: true
45
+ end
46
+
47
+ with_options if: -> { stated?(:payment) && payment_required? } do |context|
48
+ context.validates :payment_method, presence: true
49
+ end
50
+
51
+ with_options if: -> { stated?(:shipment) && shipment_required? } do |context|
52
+ context.validates :shipment_method, presence: true
53
+ end
54
+
55
+ with_options if: -> { stated?(:complete) } do |context|
56
+ context.validates :code, presence: true
57
+ context.validates :shipment_fee, presence: true
58
+ context.validates :total_price, presence: true
59
+ end
60
+ end
61
+
62
+ module ClassMethods
63
+ def state_names
64
+ state_machine.states.keys
65
+ end
66
+ end
67
+
68
+ def stated?(target_state)
69
+ target_state_index = self.class.state_names.index(target_state.to_sym)
70
+ current_state_index = self.class.state_names.index(state_name)
71
+ target_state_index < current_state_index
72
+ end
73
+
74
+ def orderer_required?
75
+ bill_address.nil? || bill_address.new_record?
76
+ end
77
+
78
+ def delivery_required?
79
+ ship_address.nil? || ship_address.new_record?
80
+ end
81
+
82
+ def payment_required?
83
+ Comable::PaymentMethod.exists?
84
+ end
85
+
86
+ def shipment_required?
87
+ Comable::ShipmentMethod.activated.exists?
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,41 @@
1
+ module Comable
2
+ class Product
3
+ module Search
4
+ extend ActiveSupport::Concern
5
+
6
+ SEARCH_COLUMNS = %i( code name caption )
7
+
8
+ module ClassMethods
9
+ def search(query)
10
+ keywords = parse_to_keywords(query)
11
+ return (Rails::VERSION::MAJOR == 3) ? scoped : all if keywords.empty?
12
+ where(keywords_to_arel(keywords))
13
+ end
14
+
15
+ private
16
+
17
+ def keywords_to_arel(keywords)
18
+ keywords.inject(nil) do |arel_chain, keyword|
19
+ arel = keyword_to_arel(keyword)
20
+ arel_chain ? arel_chain.and(arel) : arel
21
+ end
22
+ end
23
+
24
+ def keyword_to_arel(keyword)
25
+ SEARCH_COLUMNS.inject(nil) do |arel_chain, column|
26
+ arel = arel_table[column].matches("%#{keyword}%")
27
+ arel_chain ? arel_chain.or(arel) : arel
28
+ end
29
+ end
30
+
31
+ def parse_to_keywords(query)
32
+ return [] if query.blank?
33
+ query
34
+ .delete('%')
35
+ .tr(' ', ' ')
36
+ .split(' ')
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,15 @@
1
+ module Comable
2
+ module RoleOwner
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ extend Enumerize
7
+
8
+ enumerize :role, in: %i(
9
+ admin
10
+ reporter
11
+ customer
12
+ ), default: :customer, predicates: true
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ class ImageUploader < CarrierWave::Uploader::Base
2
+ storage :file
3
+
4
+ def store_dir
5
+ "#{model.class.to_s.underscore}/#{model.id}"
6
+ end
7
+ end
@@ -2,9 +2,9 @@
2
2
  <%= "#{@order.class.human_attribute_name(:code)}: #{@order.code}" %>
3
3
  ----------------------------------------------------------------------
4
4
 
5
- <%= I18n.t('comable.order_mailer.complete.dear', name: @order.full_name) %>
5
+ <%= Comable.t('order_mailer.complete.dear', name: @order.bill_full_name) %>
6
6
 
7
- <%= I18n.t('comable.order_mailer.complete.introductions', store_name: current_store.name) %>
7
+ <%= Comable.t('order_mailer.complete.introductions', store_name: current_store.name) %>
8
8
 
9
9
  <%- shipment_method = @order.shipment_method %>
10
10
  <%- if shipment_method %>
@@ -12,10 +12,8 @@
12
12
  <%= shipment_method.name %>
13
13
  <%- end %>
14
14
 
15
- <%= Comable::OrderDelivery.model_name.human %>:
16
- <%- @order.order_deliveries.each do |order_delivery| %>
17
- <%= name_with_honorific order_delivery.full_name %>
18
- <%- end %>
15
+ <%= @order.class.human_attribute_name(:ship_address) %>:
16
+ <%= name_with_honorific @order.ship_full_name %>
19
17
 
20
18
  ======================================================================
21
19
 
@@ -24,7 +22,7 @@
24
22
  <%= "#{@order.class.human_attribute_name(:code)}: #{@order.code}" %>
25
23
  <%= "#{@order.class.human_attribute_name(:completed_at)}: #{I18n.l @order.completed_at.to_date}" %>
26
24
 
27
- <%- @order.order_deliveries.map(&:order_details).flatten.each do |order_detail| %>
25
+ <%- @order.order_details.each do |order_detail| %>
28
26
  <%= name_with_quantity order_detail.name_with_sku, order_detail.quantity %>
29
27
  <%= number_to_currency order_detail.subtotal_price %>
30
28
 
@@ -36,8 +34,8 @@
36
34
 
37
35
  <%= "#{@order.class.human_attribute_name(:total_price)}: #{number_to_currency @order.total_price}" %>
38
36
 
39
- <%= "#{@order.class.human_attribute_name(:payment)}: #{@order.payment.name}\n" if @order.payment -%>
37
+ <%= "#{@order.class.human_attribute_name(:payment_method)}: #{@order.payment_method.name}\n" if @order.payment_method -%>
40
38
 
41
39
  ======================================================================
42
40
 
43
- <%= I18n.t('comable.order_mailer.complete.outroductions', store_name: current_store.name) %>
41
+ <%= Comable.t('order_mailer.complete.outroductions', store_name: current_store.name) %>