169 lines
4.2 KiB
Ruby
169 lines
4.2 KiB
Ruby
class Section
|
|
include SimplyStored::Couch
|
|
include Qwaiter::Distribution
|
|
include ActiveModel::SerializerSupport
|
|
|
|
property :title
|
|
property :path, type: Array, default: [[0.0, 0.0], [20.0, 0.0], [20.0, 30.0], [0.0, 30.0]] # default width 20m height 30m
|
|
|
|
belongs_to :supplier
|
|
has_many :tables
|
|
has_many :lists
|
|
has_many :orders
|
|
has_many :section_elements
|
|
has_many :section_areas
|
|
|
|
attr_protected :supplier_id
|
|
|
|
validates :title, presence: true
|
|
validates :supplier_id, presence: true
|
|
|
|
view :by_supplier_id_and_id, key: [:supplier_id, :_id]
|
|
|
|
def occupied_tables
|
|
return @occupied_tables if @occupied_tables.present?
|
|
@active_lists = List.active_for_section(self.id)
|
|
@active_lists.include_relation(:table)
|
|
@occupied_tables = @active_lists.map(&:table)
|
|
end
|
|
|
|
def active_lists
|
|
return @active_lists if @active_lists.present?
|
|
@active_lists = List.active_for_section(self.id)
|
|
end
|
|
|
|
def active_orders
|
|
@active_orders ||= Order.active_for_supplier_and_section(supplier_id, id)
|
|
end
|
|
|
|
def width
|
|
x_coords = path.map(&:first)
|
|
x_coords.max - x_coords.min
|
|
end
|
|
|
|
def height
|
|
y_coords = path.map(&:last)
|
|
y_coords.max - y_coords.min
|
|
end
|
|
|
|
def width=(val)
|
|
val = val.to_f
|
|
return val if width == val
|
|
self.path[0] ||= [0.0, 0.0]
|
|
self.path[1] ||= [0.0, 0.0]
|
|
self.path[2] ||= [0.0, 0.0]
|
|
self.path[3] ||= [0.0, 0.0]
|
|
path[0][0] = 0
|
|
path[1][0] = val
|
|
path[2][0] = val
|
|
path[3][0] = 0
|
|
path_will_change!
|
|
val
|
|
end
|
|
|
|
def height=(val)
|
|
val = val.to_f
|
|
return val if height == val
|
|
self.path[0] ||= [0.0, 0.0]
|
|
self.path[1] ||= [0.0, 0.0]
|
|
self.path[2] ||= [0.0, 0.0]
|
|
self.path[3] ||= [0.0, 0.0]
|
|
path[0][1] = 0
|
|
path[1][1] = 0
|
|
path[2][1] = val
|
|
path[3][1] = val
|
|
path_will_change!
|
|
val
|
|
end
|
|
|
|
def tables_with_active_list_id
|
|
Table.enrich_active_list_id(tables)
|
|
end
|
|
|
|
#def as_json(*)
|
|
#super.merge(width: width, height: height)
|
|
#end
|
|
|
|
def for_tables_as_json
|
|
return @for_tables_as_json if @for_tables_as_json.present?
|
|
h = as_json
|
|
h[:tables] = []
|
|
for table in tables
|
|
ht = table.as_json
|
|
table_list = active_lists.find{|l| l.table_id == table.id}
|
|
ht[:occupied] = occupied_tables.include?(table)
|
|
ht[:needs_help] = ht[:occupied] && table_list ? table_list.needs_help? : false
|
|
ht[:needs_payment] = ht[:occupied] && table_list ? table_list.needs_payment? : false
|
|
ht[:active_order] = ht[:occupied] && table_list ? active_orders.any?{|o| o.list_id == table_list.id } : false
|
|
h[:tables] << ht
|
|
end
|
|
@for_tables_as_json = h
|
|
end
|
|
|
|
def arrange_tables_in_grid(tables = self.tables)
|
|
w = width
|
|
h = height
|
|
n = tables.size
|
|
return false unless w > 0 && h > 0 && n > 0
|
|
lx, ly = distribute_lattice(w, h, n)
|
|
x0 = lx/2
|
|
x = x0
|
|
y = ly/2
|
|
saves = []
|
|
for table in tables.sort_by(&:number)
|
|
if x > w + (1e4*epsilon) # New row, error = epsilon times possible tables in a row
|
|
x = x0
|
|
y += ly
|
|
end
|
|
table.position_x = x - (table.width/2) # Starting point of square + half the square (center) minus half the table size
|
|
table.position_y = y - (table.height/2)
|
|
saves << table.save
|
|
x += lx
|
|
end
|
|
saves.all?
|
|
end
|
|
|
|
def arrange_tables_in_rows_of(n)
|
|
return false unless n.present?
|
|
n = n.to_i
|
|
return false unless n > 0
|
|
dx = width / n
|
|
dy = height / (tables.size.to_f/n).ceil
|
|
x = 0.0
|
|
y = 0.0
|
|
saves = []
|
|
tables.sort_by(&:number).each.with_index do |table, i|
|
|
table.position_x = x + (dx/2) - (table.width/2)
|
|
table.position_y = y + (dy/2) - (table.height/2)
|
|
x += dx
|
|
if (i + 1).multiple_of?( n )
|
|
x = 0.0
|
|
y += dy
|
|
end
|
|
saves << table.save
|
|
end
|
|
return saves.all?
|
|
end
|
|
|
|
def arrange_tables_in_columns_of(n)
|
|
return unless n.present?
|
|
n = n.to_i
|
|
return unless n > 0
|
|
dx = width / (tables.size.to_f/n).ceil
|
|
dy = height / n
|
|
x = 0.0
|
|
y = 0.0
|
|
tables.sort_by(&:number).each.with_index do |table, i|
|
|
table.position_x = x + (dx/2) - (table.width/2)
|
|
table.position_y = y + (dy/2) - (table.height/2)
|
|
y += dy
|
|
if (i + 1).multiple_of?( n )
|
|
y = 0.0
|
|
x += dx
|
|
end
|
|
table.save
|
|
end
|
|
end
|
|
|
|
end
|