class Order < ApplicationRecord self.primary_key = "order_id" #primary key - need to be unique before_create :generate_custom_id before_create :set_order_date has_many :sale_orders belongs_to :customer has_many :order_items, autosave: true , inverse_of: :order has_many :assigned_order_items #internal references attributes for business logic control attr_accessor :items, :guest, :table_id, :new_booking, :booking_type, :employee_name, :booking_id scope :active, -> { where("date BETWEEN '#{DateTime.now.utc.end_of_day}' AND '#{DateTime.now.utc.beginning_of_day}'") } #Main Controller method to create new order - validate all inputs and generate new order # order_item : { # order_item_code : "", # item_instance_code : "", # quantity : 0, # option_values : [], # sub_order_items : [], # } def generate booking = nil if self.new_booking booking = Booking.create({:dining_facility_id => self.table_id,:type => "TableBooking", :checkin_at => Time.now.utc, :checkin_by => self.employee_name, :booking_status => "assign" }) table = DiningFacility.find(self.table_id) table.status = "occupied" table.save else booking = Booking.find(self.booking_id) end booking.save! self.default_values # cashier already opened? if self.save! self.adding_line_items #Add Order Table and Room relation afrer order creation BookingOrder.create({:booking_id => booking.booking_id, :order => self}) #Send order to queue one it done! process_order_queue #send order to broadcast job send_order_broadcast(booking) return true, booking end return false end def custom_generate booking = nil if self.new_booking booking = Booking.create({:dining_facility_id => self.table_id,:type => "TableBooking", :checkin_at => Time.now.utc, :checkin_by => self.employee_name, :booking_status => "assign" }) table = DiningFacility.find(self.table_id) table.status = "occupied" table.save else booking = Booking.find(self.booking_id) end booking.save! self.default_values # cashier already opened? if self.save! self.adding_line_items #Add Order Table and Room relation afrer order creation BookingOrder.create({:booking_id => booking.booking_id, :order => self}) #Send order to queue one it done! process_order_queue #send order to broadcast job send_order_broadcast(booking) return true, booking end return false end #Main Method - to update order / add items def modify end def adding_line_items if self.items #re-order to ordered_list = re_order_items(self.items) #loop to add all items to order self.items.each do |item| menu_item = MenuItem.search_by_item_code(item[:item_instance_code]) # For Product while item code not in menu item if menu_item.nil? menu_item = Product.search_by_product_code(item[:item_instance_code]) end #if (!menu_item.nil?) Rails.logger.debug menu_item set_order_items = nil ##If menu Item set item - must add child items to order as well, where price is only take from menu_item if (menu_item[:type] == "SetMenuItem") set_order_items end # not insert with price 0 # puts item[:price] # puts item # if(item[:price] != 0 ) # OrderItem.processs_item(menu_item[:item_code], menu_item[:name], menu_item[:account_id], # item[:quantity],menu_item[:price], item[:options], set_order_items, self.id, # self.employee_name) # end OrderItem.processs_item(menu_item[:item_code], item[:item_instance_code], menu_item[:name], menu_item[:alt_name], menu_item[:account_id], item[:quantity],menu_item[:price], item[:options], set_order_items, self.id, self.employee_name) #end end self.item_count = self.order_items.count self.save! return true else self.errors.add(:order_items, :blank, message: "Order items cannot be blank") return false end end def update_items_status_to_billed(items) if (items.nil?) ##Update the order status to ensure that reflect the stage self.order_items.each do |item| item.order_item_status = "billed" item.save end else items.each do |item| item.order_item_status = "billed" item.save end end end def default_values self.customer = Customer.find(1) if self.customer_id.nil? self.source = "emenu" if self.source.nil? self.order_type = "dine-in" if self.order_type.nil? end protected def re_order_items(form_items) #reorder inputs items as parents and child parent_id = Array.new parents = Array.new puts form_items puts "hhhhh" parents_and_children_items = Array.new new_items_list = Array.new form_items.each do |parent| if !parent[:parent_order_item_id].nil? if (!parent_id.include?(parent[:parent_order_item_id])) parent_id.push(parent[:parent_order_item_id]) end end end Rails.logger.debug "Parent Id count -> " + parent_id.count.to_s parent_id.each do |pid| form_items.each do |item| Rails.logger.debug "Adding - Parents -> " + pid.to_s + " - " + item[:order_item_id].to_s if (pid == item[:order_item_id]) parents.push(item) end end end Rails.logger.debug "Parents count -> " + parents.count.to_s parents.each do |parent| children = Array.new form_items.each do |item| if (parent[:order_item_id] == item[:parent_order_item_id] ) children.push(item) #Items to remove for new list parents_and_children_items.push(item) end end parent[:sub_items] = children end Rails.logger.debug "Parent/children Items to remove -> " + parents_and_children_items.count.to_s #Remove process items #c = a.reject{ |e| b.include? e } new_items_list = form_items - parents_and_children_items Rails.logger.debug "New list count -> " + new_items_list.count.to_s #Add parent to the list #new_items_list = new_items_list + parents Rails.logger.debug "Re-Order List (Parent)-" Rails.logger.debug parents Rails.logger.debug "Re-Order List -" Rails.logger.debug new_items_list return new_items_list end #Update Items Count and Quantity changes whenever there is changes def update_products_and_quantity_count item_count = 0 quantity_count = 0 # Count number of different items self.item_count = self.order_items.item_count self.quantity_count = quantity_count # Counter number of quantityf end #Process order items and send to order queue def process_order_queue #Send to background job for processing OrderQueueProcessorJob.perform_later(self.id, self.table_id) end #send order items and send to order queue def send_order_broadcast(booking) table = DiningFacility.find(booking.dining_facility_id) #Send to background job for processing OrderBroadcastJob.perform_later(table) end #Origami: Cashier : to view order Table def self.get_order_table order_table = Order.select("orders.order_id as order_id,sum(order_items.qty*order_items.price) as total_price, order_items.order_items_id as order_items_id,dining_facilities.name as table_name") .joins("left join booking_orders on booking_orders.order_id = orders.order_id left join bookings on bookings.booking_id = booking_orders.booking_order_id left join dining_facilities on dining_facilities.id = bookings.dining_facility_id left join order_items on order_items.order_id = orders.order_id") .where("dining_facilities.type=? and orders.order_type=? and dining_facilities.is_active=?",DiningFacility::TABLE_TYPE,"dine_in",true) .group("orders.order_id, order_items.order_items_id,dining_facilities.name") end #Origami: Cashier : to view booking order Table def self.get_booking_order_table booking_orders = Booking.select("sales.receipt_no,orders.status as order_status, sales.sale_status as sale_status, orders.order_id as order_id,sales.customer_id as sale_customer_id,orders.customer_id as order_customer_id, bookings.booking_id,sales.sale_id as sale_id,dining_facilities.name as table_name") .joins("left join booking_orders on booking_orders.booking_id = bookings.booking_id") .joins("left join dining_facilities on dining_facilities.id = bookings.dining_facility_id") .joins("left join orders on orders.order_id = booking_orders.order_id") .joins("left join sales on sales.sale_id = bookings.sale_id") .where("(orders.status = 'new' or orders.status = 'billed') and (dining_facilities.type=? and dining_facilities.is_active=?)",DiningFacility::TABLE_TYPE,true) .group("bookings.booking_id,sales.receipt_no,orders.status,sales.sale_id,dining_facilities.name,orders.status,orders.order_id") # For PG # booking_orders.order_id IS NOT NULL and dining_facilities.type=? and dining_facilities.is_active=?",DiningFacility::TABLE_TYPE,true # sales.receipt_no,orders.status,sales.sale_id,dining_facilities.name,orders.status,orders.order_id end #Origami: Cashier : to view booking order Table def self.get_completed_order completed_orders = Booking.select("sales.receipt_no, sales.sale_status, orders.status as order_status,orders.order_id, bookings.booking_id,sales.sale_id as sale_id,dining_facilities.name as table_name,sales.customer_id as sale_customer_id,orders.customer_id as order_customer_id") .joins("left join booking_orders on booking_orders.booking_id = bookings.booking_id") .joins("left join dining_facilities on dining_facilities.id = bookings.dining_facility_id") .joins("left join orders on orders.order_id = booking_orders.order_id") .joins("left join sales on sales.sale_id = bookings.sale_id") .where("sales.sale_status='completed'") .group("sales.sale_id,bookings.booking_id,sales.receipt_no,orders.status,sales.sale_id,dining_facilities.name,orders.status,orders.order_id") # For PG #bookings.booking_id,sales.receipt_no,orders.status,sales.sale_id,dining_facilities.name,orders.status,orders.order_id end #Origami: Cashier : to view order type Room def self.get_booking_order_rooms booking_rooms = Booking.select("sales.receipt_no,orders.status as order_status, sales.sale_status as sale_status, orders.order_id as order_id,sales.customer_id as sale_customer_id,orders.customer_id as order_customer_id, bookings.booking_id,orders.customer_id as customer_id, sales.sale_id as sale_id,dining_facilities.name as room_name") .joins("left join booking_orders on booking_orders.booking_id = bookings.booking_id") .joins("left join dining_facilities on dining_facilities.id = bookings.dining_facility_id") .joins("left join orders on orders.order_id = booking_orders.order_id") .joins("left join sales on sales.sale_id = bookings.sale_id") .where("(orders.status = 'new' or orders.status = 'billed') and (dining_facilities.type=? and dining_facilities.is_active=?)",DiningFacility::ROOM_TYPE,true) .group("bookings.booking_id,sales.receipt_no,orders.status,sales.sale_id,dining_facilities.name,orders.customer_id,orders.order_id") # For PG # booking_orders.order_id IS NOT NULL and dining_facilities.type=? and dining_facilities.is_active=?",DiningFacility::ROOM_TYPE,true # sales.receipt_no,orders.status,sales.sale_id,dining_facilities.name,orders.customer_id,orders.order_id end #Origami: Cashier : to view order type Room def self.get_order_rooms order_rooms = Order.select("orders.order_id as order_id,sum(order_items.qty*order_items.price) as total_price, order_items.id as order_items_id,dining_facilities.name as room_name") .joins("left join booking_orders on booking_orders.order_id = orders.order_id left join bookings on bookings.booking_id = booking_orders.order_id left join dining_facilities on dining_facilities.id = bookings.dining_facility_id left join order_items on order_items.order_id = orders.order_id") .where("dining_facilities.type=? and orders.order_type=? and dining_facilities.is_active=?",DiningFacility::ROOM_TYPE,"dine_in",true) .group("orders.order_id") end #Origami: Cashier : to view orders def self.get_orders from = Time.now.beginning_of_day.utc to = Time.now.end_of_day.utc orders=Booking.select("sales.receipt_no, sales.sale_status as sale_status, orders.status as order_status, orders.order_id as order_id,sales.customer_id as sale_customer_id,orders.customer_id as order_customer_id, bookings.booking_id,orders.customer_id as customer_id, sales.sale_id as sale_id,dining_facilities.name as table_name") .joins("left join booking_orders on booking_orders.booking_id = bookings.booking_id") .joins("left join dining_facilities on dining_facilities.id = bookings.dining_facility_id") .joins("left join orders on orders.order_id = booking_orders.order_id") .joins("left join sales on sales.sale_id = bookings.sale_id") .where("(orders.status = 'new' or orders.status = 'billed') AND orders.date between #{ from } and #{ to }") # orders = Order.select("orders.order_id as order_id,sales.receipt_no,orders.status as order_status, sales.sale_status as sale_status, # orders.order_id as order_id,sales.customer_id as sale_customer_id,orders.customer_id as order_customer_id # ,bookings.booking_id,sales.sale_id as sale_id,dining_facilities.name as table_name") # .joins("left join booking_orders on booking_orders.order_id = orders.order_id # left join bookings on bookings.booking_id = booking_orders.order_id # left join dining_facilities on dining_facilities.id = bookings.dining_facility_id # left join order_items on order_items.order_id = orders.order_id # left join sale_orders on sale_orders.order_id = orders.order_id # left join sales on sales.sale_id = sale_orders.sale_id") # .where("(orders.status = 'new' or orders.status = 'billed')") # .group("orders.order_id") # For PG # .where("dining_facilities.is_active=? and orders.date between ? and ?",true,from,to) # .group("orders.order_id,order_items.order_items_id,dining_facilities.name,sales.receipt_no,bookings.booking_id,sales.sale_id,orders.customer_id") end def self.search(filter,from,to,count) if count.to_i > 0 item_count = "and item_count = '#{count}'" else item_count = '' end if from.present? && to.present? Order.where("DATE_FORMAT(date,'%d-%m-%Y') >= ?" + " AND DATE_FORMAT(date,'%d-%m-%Y') <= ? #{item_count}", from,to) elsif !from.present? && !to.present? && count.present? Order.where("item_count = '#{count}'") else Order.where("order_id LIKE ? OR status LIKE ? OR order_type LIKE ? OR source='#{filter}'","%#{filter}%","%#{filter}%","%#{filter}%",) end end private def generate_custom_id self.order_id = SeedGenerator.generate_id(self.class.name, "ODR") end def set_order_date self.date = Time.now.utc end end