class ProductCategory include SimplyStored::Couch include ActiveModel::SerializerSupport property :name property :position, type: Integer, default: 0 property :full_day, type: :boolean, default: true property :start_from, type: Integer, default: 1320 # 22:00 property :end_on, type: Integer, default: 1380 # 23:00 property :active_on_sunday, type: :boolean, default: true property :active_on_monday, type: :boolean, default: true property :active_on_tuesday, type: :boolean, default: true property :active_on_wednesday, type: :boolean, default: true property :active_on_thursday, type: :boolean, default: true property :active_on_friday, type: :boolean, default: true property :active_on_saturday, type: :boolean, default: true belongs_to :supplier #has_and_belongs_to_many :products, storing_keys: true has_many :products 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] #TODO I am uuuuggggllyyyyy 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 # 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(&:to_client_format).select(&: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} product_categories = database.view(by_supplier_id_and_week_time(view_options.merge(keys: [[supplier.id, week_day], [supplier.id, week_day, minute]]))) product_categories.sort_by!{|pc| (pc.position || 90000).to_i } # sort categories product_categories end def active?(time = Time.now) return true unless time_zone = supplier.time_zone.presence # cannot do activity magic without the appropriate time zone true end def to_client_format return {} unless products.present? {name: name, products: products.to_a.map{|p| p.as_json}} 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