comable-core 0.6.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/MIT-LICENSE +20 -0
- data/Rakefile +97 -0
- data/app/assets/javascripts/comable/application.js +13 -0
- data/app/assets/stylesheets/comable/application.css +13 -0
- data/app/controllers/concerns/comable/permitted_attributes.rb +15 -0
- data/app/helpers/comable/application_helper.rb +84 -0
- data/app/helpers/comable/products_helper.rb +82 -0
- data/app/mailers/comable/order_mailer.rb +18 -0
- data/app/models/comable/ability.rb +18 -0
- data/app/models/comable/address.rb +39 -0
- data/app/models/comable/category.rb +72 -0
- data/app/models/comable/image.rb +15 -0
- data/app/models/comable/order.rb +121 -0
- data/app/models/comable/order/associations.rb +22 -0
- data/app/models/comable/order/callbacks.rb +43 -0
- data/app/models/comable/order/morrisable.rb +20 -0
- data/app/models/comable/order/scopes.rb +17 -0
- data/app/models/comable/order/validations.rb +39 -0
- data/app/models/comable/order_item.rb +98 -0
- data/app/models/comable/order_item/csvable.rb +32 -0
- data/app/models/comable/page.rb +30 -0
- data/app/models/comable/payment.rb +87 -0
- data/app/models/comable/payment_method.rb +27 -0
- data/app/models/comable/product.rb +55 -0
- data/app/models/comable/product/csvable.rb +20 -0
- data/app/models/comable/shipment.rb +85 -0
- data/app/models/comable/shipment_method.rb +9 -0
- data/app/models/comable/stock.rb +71 -0
- data/app/models/comable/stock/csvable.rb +26 -0
- data/app/models/comable/store.rb +30 -0
- data/app/models/comable/theme.rb +25 -0
- data/app/models/comable/tracker.rb +17 -0
- data/app/models/comable/user.rb +130 -0
- data/app/models/concerns/comable/cart_owner.rb +94 -0
- data/app/models/concerns/comable/checkout.rb +85 -0
- data/app/models/concerns/comable/importable.rb +67 -0
- data/app/models/concerns/comable/liquidable.rb +12 -0
- data/app/models/concerns/comable/product/search.rb +41 -0
- data/app/models/concerns/comable/ransackable.rb +38 -0
- data/app/models/concerns/comable/role_owner.rb +15 -0
- data/app/models/concerns/comable/sku_choice.rb +19 -0
- data/app/models/concerns/comable/sku_item.rb +17 -0
- data/app/uploaders/image_uploader.rb +7 -0
- data/app/views/comable/order_mailer/complete.text.erb +42 -0
- data/config/initializers/comma.rb +8 -0
- data/config/locales/en.yml +424 -0
- data/config/locales/ja.yml +425 -0
- data/db/migrate/20131214194807_create_comable_products.rb +15 -0
- data/db/migrate/20140120032559_create_comable_users.rb +46 -0
- data/db/migrate/20140502060116_create_comable_stocks.rb +14 -0
- data/db/migrate/20140723175431_create_comable_orders.rb +20 -0
- data/db/migrate/20140723175810_create_comable_order_items.rb +19 -0
- data/db/migrate/20140817194104_create_comable_payment_methods.rb +13 -0
- data/db/migrate/20140921191416_create_comable_shipment_methods.rb +11 -0
- data/db/migrate/20140926063541_create_comable_stores.rb +11 -0
- data/db/migrate/20141024025526_create_comable_addresses.rb +17 -0
- data/db/migrate/20150111031228_create_comable_categories.rb +10 -0
- data/db/migrate/20150111031229_create_comable_products_categories.rb +8 -0
- data/db/migrate/20150112173706_create_comable_images.rb +9 -0
- data/db/migrate/20150423095210_create_comable_shipments.rb +13 -0
- data/db/migrate/20150511171940_create_comable_payments.rb +12 -0
- data/db/migrate/20150513185230_create_comable_trackers.rb +12 -0
- data/db/migrate/20150519080729_create_comable_pages.rb +17 -0
- data/db/migrate/20150612143226_create_comable_themes.rb +15 -0
- data/db/migrate/20150612143445_add_theme_id_to_comable_stores.rb +7 -0
- data/db/seeds.rb +5 -0
- data/db/seeds/comable/users.rb +51 -0
- data/lib/comable/core.rb +48 -0
- data/lib/comable/core/configuration.rb +22 -0
- data/lib/comable/core/engine.rb +50 -0
- data/lib/comable/deprecator.rb +26 -0
- data/lib/comable/payment_provider.rb +14 -0
- data/lib/comable/payment_provider/base.rb +42 -0
- data/lib/comable/payment_provider/general.rb +15 -0
- data/lib/comable/state_machine_patch.rb +32 -0
- data/lib/comma_extractor_extentions.rb +31 -0
- data/lib/generators/comable/install/install_generator.rb +133 -0
- data/lib/generators/comable/install/templates/config/initializers/comable.rb +31 -0
- data/lib/tasks/comable_tasks.rake +4 -0
- metadata +346 -0
| @@ -0,0 +1,87 @@ | |
| 1 | 
            +
            module Comable
         | 
| 2 | 
            +
              class Payment < ActiveRecord::Base
         | 
| 3 | 
            +
                include Comable::Ransackable
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                belongs_to :order, class_name: Comable::Order.name, inverse_of: :payment
         | 
| 6 | 
            +
                belongs_to :payment_method, class_name: Comable::PaymentMethod.name
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                before_validation :copy_attributes_from_payment_method, unless: :order_completed?
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                validates :order, presence: true
         | 
| 11 | 
            +
                validates :payment_method, presence: true
         | 
| 12 | 
            +
                validates :fee, presence: true, numericality: { greater_than_or_equal_to: 0 }
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                delegate :name, to: :payment_method
         | 
| 15 | 
            +
                delegate :payment_provider, to: :payment_method
         | 
| 16 | 
            +
                delegate :authorize!, :complete!, :cancel!, :resume!, to: :payment_provider, prefix: :provider
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                ransack_options ransackable_attributes: { except: [:order_id, :payment_method_id] }
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                # The #state attribute assigns the following values:
         | 
| 21 | 
            +
                #
         | 
| 22 | 
            +
                # pending   when Order is not able to pay (default)
         | 
| 23 | 
            +
                # ready     when Order is able to pay
         | 
| 24 | 
            +
                # completed when Order is already paid
         | 
| 25 | 
            +
                # canceled  when Order is canceled
         | 
| 26 | 
            +
                # resumed   when Order is resumed from the "canceled" state
         | 
| 27 | 
            +
                state_machine initial: :pending do
         | 
| 28 | 
            +
                  state :pending
         | 
| 29 | 
            +
                  state :ready
         | 
| 30 | 
            +
                  state :completed
         | 
| 31 | 
            +
                  state :canceled
         | 
| 32 | 
            +
                  state :resumed
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  event :next_state do
         | 
| 35 | 
            +
                    transition :pending => :ready
         | 
| 36 | 
            +
                    transition :ready => :completed
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  event :cancel do
         | 
| 40 | 
            +
                    transition [:completed, :resumed] => :canceled
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  event :resume do
         | 
| 44 | 
            +
                    transition :canceled => :resumed
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  after_transition to: :ready, do: :next_state!
         | 
| 48 | 
            +
                  before_transition to: :ready, do: -> (s) { s.provider_authorize! }
         | 
| 49 | 
            +
                  before_transition to: :completed, do: -> (s) { s.complete! }
         | 
| 50 | 
            +
                  before_transition to: :canceled, do: -> (s) { s.provider_cancel! }
         | 
| 51 | 
            +
                  before_transition to: :canceled, do: -> (s) { s.provider_resume! }
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                class << self
         | 
| 55 | 
            +
                  def state_names
         | 
| 56 | 
            +
                    state_machine.states.keys
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def stated?(target_state)
         | 
| 61 | 
            +
                  target_state_index = self.class.state_names.index(target_state.to_sym)
         | 
| 62 | 
            +
                  current_state_index = self.class.state_names.index(state_name)
         | 
| 63 | 
            +
                  target_state_index < current_state_index
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                def completed?
         | 
| 67 | 
            +
                  completed_at?
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                def complete!
         | 
| 71 | 
            +
                  provider_complete!
         | 
| 72 | 
            +
                  touch :completed_at
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                private
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                def order_completed?
         | 
| 78 | 
            +
                  order.completed?
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                def copy_attributes_from_payment_method
         | 
| 82 | 
            +
                  self.attributes = {
         | 
| 83 | 
            +
                    fee: payment_method.fee
         | 
| 84 | 
            +
                  }
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
              end
         | 
| 87 | 
            +
            end
         | 
| @@ -0,0 +1,27 @@ | |
| 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 :fee, presence: true, numericality: { greater_than_or_equal_to: 0 }
         | 
| 7 | 
            +
                validates :enable_price_from, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
         | 
| 8 | 
            +
                validates :enable_price_to, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def payment_provider
         | 
| 11 | 
            +
                  return unless Object.const_defined?(payment_provider_type)
         | 
| 12 | 
            +
                  Object.const_get(payment_provider_type)
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def payment_provider_name
         | 
| 16 | 
            +
                  payment_provider.display_name
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def payment_provider_kind_key
         | 
| 20 | 
            +
                  payment_provider.kind.keys.slice(payment_provider_kind)
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                def payment_provider_kind_name
         | 
| 24 | 
            +
                  payment_provider.kind.slice(payment_provider_kind_key).values.first
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
| @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            module Comable
         | 
| 2 | 
            +
              class Product < ActiveRecord::Base
         | 
| 3 | 
            +
                include Comable::SkuItem
         | 
| 4 | 
            +
                include Comable::Ransackable
         | 
| 5 | 
            +
                include Comable::Liquidable
         | 
| 6 | 
            +
                include Comable::Product::Search
         | 
| 7 | 
            +
                include Comable::Product::Csvable
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                has_many :stocks, class_name: Comable::Stock.name, dependent: :destroy
         | 
| 10 | 
            +
                has_many :images, class_name: Comable::Image.name, dependent: :destroy
         | 
| 11 | 
            +
                has_and_belongs_to_many :categories, class_name: Comable::Category.name, join_table: :comable_products_categories
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                accepts_nested_attributes_for :images, allow_destroy: true
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                validates :name, presence: true, length: { maximum: 255 }
         | 
| 16 | 
            +
                validates :code, presence: true, length: { maximum: 255 }
         | 
| 17 | 
            +
                validates :price, presence: true, numericality: { greater_than_or_equal_to: 0, allow_blank: true }
         | 
| 18 | 
            +
                validates :sku_h_item_name, length: { maximum: 255 }
         | 
| 19 | 
            +
                validates :sku_v_item_name, length: { maximum: 255 }
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                liquid_methods :id, :code, :name, :price, :images, :image_url
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                ransack_options attribute_select: { associations: :stocks }
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                # Add conditions for the images association.
         | 
| 26 | 
            +
                # Override method of the images association to support Rails 3.x.
         | 
| 27 | 
            +
                def images
         | 
| 28 | 
            +
                  super.order(:id)
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def image_url
         | 
| 32 | 
            +
                  image = images.first
         | 
| 33 | 
            +
                  return image.url if image
         | 
| 34 | 
            +
                  'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTcxIiBoZWlnaHQ9IjE4MCIgdmlld0JveD0iMCAwIDE3MSAxODAiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjxkZWZzLz48cmVjdCB3aWR0aD0iMTcxIiBoZWlnaHQ9IjE4MCIgZmlsbD0iI0VFRUVFRSIvPjxnPjx0ZXh0IHg9IjU4IiB5PSI5MCIgc3R5bGU9ImZpbGw6I0FBQUFBQTtmb250LXdlaWdodDpib2xkO2ZvbnQtZmFtaWx5OkFyaWFsLCBIZWx2ZXRpY2EsIE9wZW4gU2Fucywgc2Fucy1zZXJpZiwgbW9ub3NwYWNlO2ZvbnQtc2l6ZToxMHB0O2RvbWluYW50LWJhc2VsaW5lOmNlbnRyYWwiPjE3MXgxODA8L3RleHQ+PC9nPjwvc3ZnPg=='
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def stocked?
         | 
| 38 | 
            +
                  stocks.stocked.exists?
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def unstocked?
         | 
| 42 | 
            +
                  !stocked?
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def category_path_names=(category_path_names, delimiter: Comable::Category::DEFAULT_PATH_NAME_DELIMITER)
         | 
| 46 | 
            +
                  self.categories = Comable::Category.find_by_path_names(category_path_names, delimiter: delimiter)
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                private
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                def create_stock
         | 
| 52 | 
            +
                  stocks.create(code: code) unless stocks.exists?
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            module Comable
         | 
| 2 | 
            +
              class Product < ActiveRecord::Base
         | 
| 3 | 
            +
                module Csvable
         | 
| 4 | 
            +
                  extend ActiveSupport::Concern
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  include Comable::Importable
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  included do
         | 
| 9 | 
            +
                    comma do
         | 
| 10 | 
            +
                      name
         | 
| 11 | 
            +
                      code
         | 
| 12 | 
            +
                      price
         | 
| 13 | 
            +
                      caption
         | 
| 14 | 
            +
                      sku_h_item_name
         | 
| 15 | 
            +
                      sku_v_item_name
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
| @@ -0,0 +1,85 @@ | |
| 1 | 
            +
            module Comable
         | 
| 2 | 
            +
              class Shipment < ActiveRecord::Base
         | 
| 3 | 
            +
                include Comable::Ransackable
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                belongs_to :order, class_name: Comable::Order.name, inverse_of: :shipment
         | 
| 6 | 
            +
                belongs_to :shipment_method, class_name: Comable::ShipmentMethod.name
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                before_validation :copy_attributes_from_shipment_method, unless: :order_completed?
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                validates :order, presence: true
         | 
| 11 | 
            +
                validates :shipment_method, presence: true
         | 
| 12 | 
            +
                validates :fee, presence: true, numericality: { greater_than_or_equal_to: 0 }
         | 
| 13 | 
            +
                validates :tracking_number, length: { maximum: 255 }
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                delegate :name, to: :shipment_method
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                ransack_options ransackable_attributes: { except: [:order_id, :shipment_method_id] }
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                # The #state attribute assigns the following values:
         | 
| 20 | 
            +
                #
         | 
| 21 | 
            +
                # pending   when Order is not able to ship (default)
         | 
| 22 | 
            +
                # ready     when Order is able to ship
         | 
| 23 | 
            +
                # completed when Order is already shipped
         | 
| 24 | 
            +
                # canceled  when Order is canceled
         | 
| 25 | 
            +
                # resumed   when Order is resumed from the "canceled" state
         | 
| 26 | 
            +
                state_machine initial: :pending do
         | 
| 27 | 
            +
                  state :pending
         | 
| 28 | 
            +
                  state :ready
         | 
| 29 | 
            +
                  state :completed
         | 
| 30 | 
            +
                  state :canceled
         | 
| 31 | 
            +
                  state :resumed
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  event :next_state do
         | 
| 34 | 
            +
                    transition :pending => :ready
         | 
| 35 | 
            +
                    transition :ready => :completed
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  event :ship do
         | 
| 39 | 
            +
                    transition :ready => :completed
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  event :cancel do
         | 
| 43 | 
            +
                    transition [:completed, :resumed] => :canceled
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  event :resume do
         | 
| 47 | 
            +
                    transition :canceled => :resumed
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  before_transition to: :completed, do: -> (s) { s.complete! }
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                class << self
         | 
| 54 | 
            +
                  def state_names
         | 
| 55 | 
            +
                    state_machine.states.keys
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                def stated?(target_state)
         | 
| 60 | 
            +
                  target_state_index = self.class.state_names.index(target_state.to_sym)
         | 
| 61 | 
            +
                  current_state_index = self.class.state_names.index(state_name)
         | 
| 62 | 
            +
                  target_state_index < current_state_index
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                def completed?
         | 
| 66 | 
            +
                  completed_at?
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                def complete!
         | 
| 70 | 
            +
                  touch :completed_at
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                private
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                def order_completed?
         | 
| 76 | 
            +
                  order.completed?
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                def copy_attributes_from_shipment_method
         | 
| 80 | 
            +
                  self.attributes = {
         | 
| 81 | 
            +
                    fee: shipment_method.fee
         | 
| 82 | 
            +
                  }
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
              end
         | 
| 85 | 
            +
            end
         | 
| @@ -0,0 +1,9 @@ | |
| 1 | 
            +
            module Comable
         | 
| 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 | 
            +
             | 
| 7 | 
            +
                scope :activated, -> { where(activated_flag: true) }
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
            end
         | 
| @@ -0,0 +1,71 @@ | |
| 1 | 
            +
            module Comable
         | 
| 2 | 
            +
              #
         | 
| 3 | 
            +
              # 在庫モデル。
         | 
| 4 | 
            +
              # 商品に複数紐付き、品数やSKU(Stock Keeping Unit)情報を保持する。
         | 
| 5 | 
            +
              #
         | 
| 6 | 
            +
              class Stock < ActiveRecord::Base
         | 
| 7 | 
            +
                include Comable::SkuItem
         | 
| 8 | 
            +
                include Comable::SkuChoice
         | 
| 9 | 
            +
                include Comable::Ransackable
         | 
| 10 | 
            +
                include Comable::Liquidable
         | 
| 11 | 
            +
                include Comable::Stock::Csvable
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                belongs_to :product, class_name: Comable::Product.name
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                #
         | 
| 16 | 
            +
                # @!group Scope
         | 
| 17 | 
            +
                #
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                # @!scope class
         | 
| 20 | 
            +
                # 品切れでない在庫インスタンスを返す
         | 
| 21 | 
            +
                scope :stocked, -> { where('quantity > ?', 0) }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                # @!scope class
         | 
| 24 | 
            +
                # 品切れの在庫インスタンスを返す
         | 
| 25 | 
            +
                scope :unstocked, -> { where('quantity <= ?', 0) }
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                #
         | 
| 28 | 
            +
                # @!endgroup
         | 
| 29 | 
            +
                #
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                validates :product, presence: { message: Comable.t('admin.is_not_exists') }
         | 
| 32 | 
            +
                validates :code, presence: true, length: { maximum: 255 }
         | 
| 33 | 
            +
                validates :sku_h_choice_name, length: { maximum: 255 }
         | 
| 34 | 
            +
                validates :sku_v_choice_name, length: { maximum: 255 }
         | 
| 35 | 
            +
                # TODO: add conditions (by limitless flag, backoder flag and etc..)
         | 
| 36 | 
            +
                validates :quantity, numericality: { greater_than_or_equal_to: 0 }
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                delegate :name, to: :product
         | 
| 39 | 
            +
                delegate :price, to: :product
         | 
| 40 | 
            +
                delegate :sku_h_item_name, to: :product
         | 
| 41 | 
            +
                delegate :sku_v_item_name, to: :product
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                ransack_options attribute_select: { associations: :product }, ransackable_attributes: { except: :product_id }
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                # 在庫の有無を取得する
         | 
| 46 | 
            +
                #
         | 
| 47 | 
            +
                # @example
         | 
| 48 | 
            +
                #   stock.quanaity = 1
         | 
| 49 | 
            +
                #   stock.stocked? #=> true
         | 
| 50 | 
            +
                #
         | 
| 51 | 
            +
                # @param quantity [Fixnum] 減算する在庫数を指定する
         | 
| 52 | 
            +
                # @return [Boolean] 在庫があれば true を返す
         | 
| 53 | 
            +
                # @see #unstocked?
         | 
| 54 | 
            +
                def stocked?(quantity: 1)
         | 
| 55 | 
            +
                  (self.quantity - quantity) >= 0
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                # 在庫の有無を取得する
         | 
| 59 | 
            +
                #
         | 
| 60 | 
            +
                # @example
         | 
| 61 | 
            +
                #   stock.quanaity = 1
         | 
| 62 | 
            +
                #   stock.unstocked? #=> false
         | 
| 63 | 
            +
                #
         | 
| 64 | 
            +
                # @param quantity [Fixnum] 減算する在庫数を指定する
         | 
| 65 | 
            +
                # @return [Boolean] {#stocked?} の逆。在庫がなければ true を返す
         | 
| 66 | 
            +
                # @see #stocked?
         | 
| 67 | 
            +
                def unstocked?(quantity: 1)
         | 
| 68 | 
            +
                  !stocked?(quantity: quantity)
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
              end
         | 
| 71 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            module Comable
         | 
| 2 | 
            +
              class Stock < ActiveRecord::Base
         | 
| 3 | 
            +
                module Csvable
         | 
| 4 | 
            +
                  extend ActiveSupport::Concern
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  include Comable::Importable
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  included do
         | 
| 9 | 
            +
                    comma do
         | 
| 10 | 
            +
                      product_code
         | 
| 11 | 
            +
                      code
         | 
| 12 | 
            +
                      quantity
         | 
| 13 | 
            +
                      sku_h_choice_name
         | 
| 14 | 
            +
                      sku_v_choice_name
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  delegate :code, to: :product, prefix: true, allow_nil: true
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  def product_code=(code)
         | 
| 21 | 
            +
                    return if product_code == code
         | 
| 22 | 
            +
                    self.product = Comable::Product.find_by(code: code)
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            module Comable
         | 
| 2 | 
            +
              class Store < ActiveRecord::Base
         | 
| 3 | 
            +
                include Comable::Liquidable
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                belongs_to :theme, class_name: Comable::Theme.name
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                validates :name, length: { maximum: 255 }
         | 
| 8 | 
            +
                validates :meta_keywords, length: { maximum: 255 }
         | 
| 9 | 
            +
                validates :meta_description, length: { maximum: 255 }
         | 
| 10 | 
            +
                validates :email, length: { maximum: 255 }
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                liquid_methods :name, :meta_keywords, :meta_description, :email
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                delegate :name, to: :theme, prefix: true, allow_nil: true
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                class << self
         | 
| 17 | 
            +
                  def instance
         | 
| 18 | 
            +
                    first || new(name: default_name)
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  def default_name
         | 
| 22 | 
            +
                    Comable.t('default_store_name')
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def can_send_mail?
         | 
| 27 | 
            +
                  email.present?
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            module Comable
         | 
| 2 | 
            +
              class Theme < ActiveRecord::Base
         | 
| 3 | 
            +
                has_one :store, class_name: Comable::Store.name
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                validates :name, uniqueness: { scope: :version }
         | 
| 6 | 
            +
                validates :name, presence: true, length: { maximum: 255 }
         | 
| 7 | 
            +
                validates :version, presence: true, length: { maximum: 255 }
         | 
| 8 | 
            +
                validates :display, length: { maximum: 255 }
         | 
| 9 | 
            +
                validates :description, length: { maximum: 255 }
         | 
| 10 | 
            +
                validates :homepage, length: { maximum: 255 }
         | 
| 11 | 
            +
                validates :author, length: { maximum: 255 }
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def default_version
         | 
| 14 | 
            +
                  '0.1.0'
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def to_param
         | 
| 18 | 
            +
                  name
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def display_name
         | 
| 22 | 
            +
                  display.presence || name
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
            end
         |