Files
mozo-backend/app/models/product_category.rb
T

94 lines
3.7 KiB
Ruby

class ProductCategory
include SimplyStored::Couch
property :name
property :position, type: Fixnum, default: 0
property :week_days, type: Array, default: Array.new(7, 1)
property :full_day, type: :boolean, default: true
property :start_from, type: Fixnum, default: 1320 # 22:00
property :end_on, type: Fixnum, default: 1380 # 23:00
belongs_to :supplier
has_and_belongs_to_many :products, storing_keys: true
attr_protected :supplier_id
validates :name, presence: true
validates :position, numericality: true
validates :supplier_id, presence: true
validates :end_on, numericality: {less_than: 2880}, presence: {unless: :full_day?}
view :by_supplier_id_and_id, key: [:supplier_id, :_id]
view :by_supplier_id_and_week_time, type: :custom, map_function: "function(doc){
if(doc.ruby_class == 'ProductCategory'){
for(var i=0;i<7;i++){
if(doc.full_day || !doc.end_on){
if(doc.week_days[i]) emit([doc.supplier_id, i], 1);
}else{
for(var j=(doc.start_from || 0);j < doc.end_on;j++){
if(doc.week_days[i]) emit([doc.supplier_id, i, j], 1);
}
}
}
}
}", reduce_function: :_sum
#start_key: [supplier_id, wday, minute], end_key: [supplier_id, wday, 2880, minute]
#alias orignal_week_days= week_days=
def week_days=(ary)
#write_attribute(:week_days, ary.map(&:to_i))
typecasted_value = ary.map(&:to_i)
#return typecasted_value if @week_days == typecasted_value
week_days_will_change! unless @skip_dirty_tracking || typecasted_value == week_days
@week_days = typecasted_value
end
def self.for_user(user, options = {})
table = options[:table]
raise "ProductCategory.for_user requires a table" unless table.present?
list = options[:list] || table.active_list # Performance option to specify it in stead of loading it
supplier = options[:supplier] || table.supplier # same as list
# Get supplier objects
product_categories = for_supplier_in_time(supplier, options[:time])
# The following part is creating the products hash. This should not be performed here!!!!!! #TODO fix this!!!@@!!@@!!@
products = supplier.products
# sort categories
product_categories.sort_by!{|pc| (pc.position || 90000).to_i }
# Append other category if not defined by supplier
other = product_categories.find(&:other?) || (product_categories << self.other).last # Container for non categorized products
# Initialize base return object
h = {table_number: table.number, table_occupied: table.occupied?, supplier_name: supplier.name, my_list: list.try(:user_ids).to_a.include?(user.id)}
(products - product_categories.map(&:products).flatten).each{ |p| other.add_product(p) }
h[:categories] = product_categories.map{|pc| {name: pc.name, products: pc.products.to_a.map{|p| p.as_json}}}.select{|pc| pc && pc[:products].present?}
h
end
# time is not by default Time.now.utc since it can be specified as nil
def self.for_supplier_in_time(supplier, time = nil)
time ||= Time.now.in_time_zone(supplier.time_zone)
minute = (time.seconds_since_midnight/60).round
week_day = time.wday
if minute < supplier.night_offset
minute += 1440 # 1440 is 1 day in minutes 1.day/1.minute
week_day -= 1
week_day = 6 if week_day < 0 # Saturday
end
view_options = {reduce: false, include_docs: true}
database.view(by_supplier_id_and_week_time(view_options.merge(keys: [[supplier.id, week_day], [supplier.id, week_day, minute]])))
end
def other?
%w[other overig].include?(name.to_s.downcase)
end
def self.other(options = {})
new(options.reverse_merge(name: I18n.t('user.product_category.other_name')))
end
end