Skip to content

Instantly share code, notes, and snippets.

@mwhagedorn
Created December 15, 2009 20:05
Show Gist options
  • Save mwhagedorn/257253 to your computer and use it in GitHub Desktop.
Save mwhagedorn/257253 to your computer and use it in GitHub Desktop.
# == Schema Information
#
# Table name: product_data
#
# id :integer(4) not null, primary key
# filename :string(255)
# content_type :string(255)
# size :integer(4)
# created_at :datetime
# updated_at :datetime
# contract_id :integer(4)
# bit_field :integer(4) default(0)
# imported_bit_field :integer(4) default(0)
# ignore_duplicate_skus :boolean(1)
# new_bit_field :text
# new_imported_bit_field :text
# header_row :boolean(1) default(TRUE)
# processing_status :string(255)
#
require 'rubygems'
require 'faster_csv'
class ProductDatum < ActiveRecord::Base
belongs_to :contract
belongs_to :account
has_attachment :content_type => ['application/vnd.ms-excel'],
:storage => :file_system
has_many :unknown_import_items, :dependent => :destroy
has_many :product_datum_line_items
accepts_nested_attributes_for :product_datum_line_items
include DataReader
def after_spreadsheet_load()
self.spreadsheet.each_with_index do |row,i|
unless i == 0 && self.header_row?
pdli = ProductDatumLineItem.new(
:product_datum_id => self,
:sku_name =>data_for_row(i, "sku"),
:description => data_for_row(i, "description"),
:entity_name =>data_for_row(i, "entity"),
:category_name => data_for_row(i, "category"),
:territory_name => data_for_row(i, "territory"))
pdli.save(false)
self.product_datum_line_items << pdli
end
end
end
def data_for_row(index,column_name)
columns = {"sku" =>0, "description"=> 1, "entity"=> 2,"category"=>3, "territory" => 4 }
return nil if columns[column_name].nil?
self.spreadsheet[index][columns[column_name]]
end
validates_presence_of :contract_id, :account_id
def skus
@skus ||= get_skus
end
def item_names
@item_names ||= get_item_names
end
def prices
@prices ||= get_prices
end
def products
@products ||= get_products
end
def categories
@categories ||= get_categories
end
def add_unknown_category(value)
self.unknown_import_items << UnknownImportItem.create(:value=>value, :entity_type => "category")
self.save
end
def add_unknown_product(value)
self.unknown_import_items << UnknownImportItem.create(:value=>value,:entity_type => "product")
self.save
end
private
def get_skus
logger.debug "get_skus"
result = Array.new
begin
rows = self.spreadsheet.size
i= self.header_row ? 1 : 0
while i < rows
logger.debug "reading row #{i}"
value = spreadsheet[i][0]
logger.debug "adding value #{value}"
result << value unless value.blank?
i = i+1
end
rescue
end
return result
end
def get_item_names
logger.debug "get_item_names"
rows = self.spreadsheet.size
result = Array.new
i= self.header_row ? 1 : 0
while i < rows
## logger.debug "reading row #{i}"
value = spreadsheet[i][1]
## logger.debug "adding value #{value}"
result << value unless value.blank?
i = i+1
end
return result
end
def get_prices
logger.debug "get_prices"
rows = self.spreadsheet.size
result = Array.new
i= self.header_row ? 1 : 0
while i < rows
# logger.debug "reading row #{i}"
value = spreadsheet[i][2]
# logger.debug "adding value #{value}"
result << value unless value.blank?
i = i+1
end
return result
end
def get_products
logger.debug "get_products"
rows = self.spreadsheet.size
result = Array.new
i= self.header_row ? 1 : 0
while i < rows
# logger.debug "reading row #{i}"
row = spreadsheet[i]
value = spreadsheet[i][3]
# logger.debug "adding value #{value}"
result << value unless value.blank?
i = i+1
end
return result
end
def get_categories
logger.debug "get_categories"
rows = self.spreadsheet.size
result = Array.new
i= self.header_row ? 1 : 0
while i < rows
# logger.debug "reading row #{i}"
row = spreadsheet[i]
value = spreadsheet[i][4]
# logger.debug "adding value #{value}"
result << value unless value.blank?
i = i+1
end
return result
end
end
######### line items ############
class ProductDatumLineItem < ActiveRecord::Base
belongs_to :product_datum
validates_presence_of :sku_name
validates_presence_of :category_name
validates_presence_of :entity_name
validates_presence_of :territory_name
validates_presence_of :description
validates_presence_of :product_datum
belongs_to :category
belongs_to :territory
belongs_to :entity
belongs_to :sku
def validate
map_category_name
map_entity_name
if self.category && self.entity
map_sku_name
else
false
end
end
def map_category_name
unless self.category
self.category = self.product_datum.contract.find_contract_category_by_description(self.category_name)
unless self.category
self.errors.add("category_name","doesn't map to a known category")
end
end
self.category
end
def map_entity_name
unless self.entity
self.entity = self.product_datum.contract.find_contract_entity_by_description(entity_name)
unless self.entity
self.errors.add("entity_name","doesn't map to a known entity")
end
end
self.entity
end
def map_sku_name
new_or_found_sku = Sku.new_from_product_datum_line_item(self)
if new_or_found_sku.new_record?
self.process_new_sku(new_or_found_sku)
else
unless self.product_datum.ignore_duplicate_skus
self.process_existing_sku(new_or_found_sku)
end
end
return self.sku
end
def process_new_sku(new_sku)
product_datum.contract.skus << new_sku
SkuAssociation.create(:sku => new_sku, :entity => self.entity, :category => self.category, :contract => self.product_datum.contract, :product_datum => self.product_datum)
self.sku =new_sku
end
def process_existing_sku(existing_sku)
unless existing_sku.contracts.include?(self.product_datum.contract)
product_datum.contract.skus << existing_sku
product_datum.contract.save
end
unless existing_sku.contract_entity_category_ids.include?("#{self.product_datum.contract_id}-#{self.entity.id}-#{self.category.id}")
SkuAssociation.create!(:sku => existing_sku, :entity => self.entity, :category => self.category, :contract => self.product_datum.contract, :product_datum => self.product_datum)
end
existing_sku.sku = self.sku_name
existing_sku.save
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment