Class: Tienda::Product

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/tienda/product.rb,
app/models/tienda/product/variants.rb,
app/models/tienda/product/product_attributes.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#product_attributes_arrayObject

Used for setting an array of product attributes which will be updated. Usually received from a web browser.



9
10
11
# File 'app/models/tienda/product/product_attributes.rb', line 9

def product_attributes_array
  @product_attributes_array
end

Class Method Details

.import(file) ⇒ Object

Imports products from a spreadsheet file Example:

Tienda:Product.import("path/to/file.csv")


124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'app/models/tienda/product.rb', line 124

def self.import(file)
  spreadsheet = open_spreadsheet(file)
  spreadsheet.default_sheet = spreadsheet.sheets.first
  header = spreadsheet.row(1)
  (2..spreadsheet.last_row).each do |i|
    row = Hash[[header, spreadsheet.row(i)].transpose]

    # Don't import products where the name is blank
    unless row["name"].nil?
      if product = find_by(name: row["name"])
        # Dont import products with the same name but update quantities if they're not the same
        qty = row["qty"].to_i
        if qty > 0 && qty != product.stock
          product.stock_level_adjustments.create!(description: I18n.t('tienda.import'), adjustment: qty)
        end
      else
        product = new
        product.name = row["name"]
        product.sku = row["sku"]
        product.description = row["description"]
        product.short_description = row["short_description"]
        product.weight = row["weight"]
        product.price = row["price"].nil? ? 0 : row["price"]

        product.product_category_id = begin
          if Tienda::ProductCategory.find_by(name: row["category_name"]).present?
            # Find and set the category
            Tienda::ProductCategory.find_by(name: row["category_name"]).id
          else
            # Create the category
            Tienda::ProductCategory.create(name: row["category_name"]).id
          end
        end

        product.save!

        # Create quantities
        qty = row["qty"].to_i
        if qty > 0
          product.stock_level_adjustments.create!(description: I18n.t('tienda.import'), adjustment: qty)
        end
      end
    end
  end
end

.open_spreadsheet(file) ⇒ Object



170
171
172
173
174
175
176
177
# File 'app/models/tienda/product.rb', line 170

def self.open_spreadsheet(file)
  case File.extname(file.original_filename)
  when ".csv" then Roo::CSV.new(file.path)
  when ".xls" then Roo::Excel.new(file.path)
  when ".xlsx" then Roo::Excelx.new(file.path)
  else raise I18n.t('tienda.imports.errors.unknown_format', filename: File.original_filename)
  end
end

.with_attributes(key, values) ⇒ Enumerable

Search for products which include the given attributes and return an active record scope of these products. Chainable with other scopes and with_attributes methods. For example:

Tienda::Product.active.with_attribute('Manufacturer', 'Apple').with_attribute('Model', ['Macbook', 'iPhone'])


115
116
117
118
# File 'app/models/tienda/product.rb', line 115

def self.with_attributes(key, values)
  product_ids = Tienda::ProductAttribute.searchable.where(:key => key, :value => values).pluck(:product_id).uniq
  where(:id => product_ids)
end

Instance Method Details

#default_variantTienda::Product

Returns the default variant for the product or nil if none exists.



38
39
40
41
# File 'app/models/tienda/product/variants.rb', line 38

def default_variant
  return nil if self.parent
  @default_variant ||= self.variants.select { |v| v.default? }.first
end

#full_nameString

Return the name of the product



67
68
69
# File 'app/models/tienda/product.rb', line 67

def full_name
  self.parent ? "#{self.parent.name} (#{name})" : name
end

#has_variants?Boolean

Does this product have any variants?



31
32
33
# File 'app/models/tienda/product/variants.rb', line 31

def has_variants?
  !variants.empty?
end

#imagesArray

Return all product images



104
105
106
# File 'app/models/tienda/product.rb', line 104

def images
  nifty_attachments.select { |attachment| attachment.role != "data_sheet" }
end

#in_stock?Boolean

Is this product currently in stock?



90
91
92
# File 'app/models/tienda/product.rb', line 90

def in_stock?
  self.default_variant ? self.default_variant.in_stock? : (stock_control? ? stock > 0 : true)
end

#orderable?Boolean

Is this product orderable?



74
75
76
77
78
# File 'app/models/tienda/product.rb', line 74

def orderable?
  return false unless self.active?
  return false if self.has_variants?
  true
end

#priceBigDecimal

The price for the product



83
84
85
# File 'app/models/tienda/product.rb', line 83

def price
  self.default_variant ? self.default_variant.price : read_attribute(:price)
end

#product_categoryTienda::ProductCategory

The product’s category



23
# File 'app/models/tienda/product.rb', line 23

belongs_to :product_category, :class_name => 'Tienda::ProductCategory'

#stockFixnum

Return the total number of items currently in stock



97
98
99
# File 'app/models/tienda/product.rb', line 97

def stock
  self.stock_level_adjustments.sum(:adjustment)
end

#tax_rateTienda::TaxRate

The product’s tax rate



28
# File 'app/models/tienda/product.rb', line 28

belongs_to :tax_rate, :class_name => "Tienda::TaxRate"

#variant?Boolean

Is this product a variant of another?



46
47
48
# File 'app/models/tienda/product/variants.rb', line 46

def variant?
  !self.parent_id.blank?
end