class OrderReservation < ApplicationRecord self.primary_key = "order_reservation_id" #primary key - need to be unique generated for multiple shops before_create :generate_custom_id has_many :order_reservation_items has_one :delivery scope :active, -> { where("created_at BETWEEN '#{Time.current.beginning_of_day.utc}' AND '#{Time.current.end_of_day.utc}'") } scope :latest_order, -> { order("order_reservation_id desc, created_at desc") } SEND_TO_KITCHEN = "send_to_kitchen" READY_TO_DELIVERY = "ready_to_delivery" DELIVERED = "delivered" COMPLETED = "completed" #new customer for doemal def self.addCustomer(params) if params[:gender] == "female" gender = "Female" else gender = "Male" end if params[:customer_id] && !params[:customer_id].nil? customer = Customer.find(params[:customer_id]) else customer = Customer.new end customer.name = params[:name] customer.email = params[:email] customer.contact_no = params[:contact_no] ? params[:contact_no] : '' customer.gender = gender customer.address = params[:address] ? params[:address] : '' customer.date_of_birth = params[:date_of_birth] ? Time.zone.parse(params[:date_of_birth]).strftime("%Y-%m-%d") : '' customer.membership_id = params[:membership_id] customer.customer_type = "Doemal" customer.tax_profiles = ["2"] customer.save # unless customer.valid? # render json: { # status: 422, # message: "Validation error", # errors: customer.errors # }.to_json # return # end return customer end def self.addOrderReservationInfo(order_reserve) Rails.logger.debug order_reserve.to_s check_order_reservation = OrderReservation.where("transaction_ref = ?",order_reserve[:reference]) if check_order_reservation.empty? OrderReservation.transaction do begin order_reservation = OrderReservation.new order_reservation.order_reservation_type = order_reserve[:order_type] order_reservation.customer_id = order_reserve[:cus_info] order_reservation.requested_time = Time.zone.parse(order_reserve[:requested_time]).utc if order_reserve[:pickup_time] order_reservation.pickup_time = Time.zone.parse(order_reserve[:pickup_time]).utc end order_reservation.callback_url = order_reserve[:callback_url] order_reservation.transaction_ref = order_reserve[:reference] if order_reserve[:order_info] order_reservation.item_count = order_reserve[:order_info][:items].count order_reservation.payment_type = order_reserve[:payment_info][:payment_type] order_reservation.payment_status = order_reserve[:payment_info][:payment_status] order_reservation.payment_ref = order_reserve[:payment_info][:payment_ref] order_reservation.taxes = order_reserve[:payment_info][:taxes].to_json order_reservation.total_amount = order_reserve[:payment_info][:sub_total] order_reservation.total_tax = order_reserve[:payment_info][:total_tax] order_reservation.discount_amount = order_reserve[:payment_info][:discount_amount] order_reservation.convenience_charge = order_reserve[:payment_info][:convenience_charge] order_reservation.grand_total = order_reserve[:payment_info][:grand_total] # order_reservation.transaction_fee = order_reserve[:payment_info][:transaction_fee] order_reservation.order_remark = order_reserve[:order_info][:order_remark] end if order_reserve[:reservation_info] order_reservation.total_customer = order_reserve[:reservation_info][:total_user] # order_reservation.order_remark = order_reserve[:reservation_info][:reservation_note] end order_reservation.save! if order_reserve[:order_info][:items] order_reserve[:order_info][:items].each do |oritem| OrderReservationItem.process_order_reservation_item(oritem[:product_code],oritem[:item_instance_code],oritem[:product_name],oritem[:product_alt_name], oritem[:account_id],oritem[:qty],oritem[:price],oritem[:unit_price], oritem[:options],nil,order_reservation.id) end end if order_reserve[:delivery_info] Delivery.addDeliveryInfo(order_reserve[:delivery_info],order_reservation.id) end return order_reservation.id, true rescue ActiveRecord::StatementInvalid raise ActiveRecord::Rollback return nil, false end end else return check_order_reservation[0].id, false end end def self.create_doemal_order(order,current_user) is_extra_time = false extra_time = '' items_arr = [] count = 1 order.order_reservation_items.each { |i| i.item_instance_code = i.item_instance_code.downcase.to_s items = {"order_item_id": count,"item_instance_code": i.item_instance_code,"quantity": i.qty,"options": i.options} count += 1 items_arr.push(items) } customer_id = order.customer_id @order = Order.new @order.source = "doemal_order" @order.order_type = "delivery" @order.customer_id = customer_id @order.items = items_arr @order.guest = '' @order.table_id = nil # this is dining facilities's id @order.new_booking = true @order.waiters = current_user.name @order.employee_name = current_user.name @order.is_extra_time = is_extra_time @order.extra_time = extra_time @status, @booking = @order.generate # Order.send_customer_view(@booking) if @status && @booking @status, @sale = Sale.request_bill(@order,current_user,current_user) #order status send to doemal callback_response = send_status_to_ordering(order.callback_url,order.transaction_ref,SEND_TO_KITCHEN) # order reservation status updated update_order_reservation(order.id, @sale.sale_id, SEND_TO_KITCHEN) result = {:status=> @status, :data => @sale, :message => "send to kitchen" } else result = {:status=> @status, :message => "No current shift open for this employee!" } end return result end def self.update_doemal_payment(order,current_user,receipt_bill) if(Sale.exists?(order.sale_id)) saleObj = Sale.find(order.sale_id) shop_details = Shop.current_shop # rounding adjustment if shop_details.is_rounding_adj a = saleObj.grand_total % 25 # Modulus b = saleObj.grand_total / 25 # Division #not calculate rounding if modulus is 0 and division is even #calculate rounding if modulus is zero or not zero and division are not even if (a != 0.0 && b%2 != 0.0) || (a==0.0 && b%2 !=0) new_total = Sale.get_rounding_adjustment(saleObj.grand_total) rounding_adj = new_total-saleObj.grand_total saleObj.update_attributes(grand_total: new_total,old_grand_total: saleObj.grand_total,rounding_adjustment:rounding_adj) end end #end rounding adjustment sale_payment = SalePayment.new if(order.payment_type == "cash_on_delivery") sale_payment.process_payment(saleObj, current_user, saleObj.grand_total, "cash") else remark = "credit payment for Receipt No #{saleObj.receipt_no}" @status, @sale = sale_payment.process_payment(saleObj, current_user, saleObj.grand_total, "creditnote", remark) end #order status send to doemal callback_response = send_status_to_ordering(order.callback_url,order.transaction_ref,DELIVERED) #order reservation status updated update_order_reservation(order.id, saleObj.sale_id, DELIVERED) Rails.logger.debug "@@@@ receipt_bill :: " Rails.logger.debug receipt_bill if receipt_bill == 1 #receipt bill pdf setting # get printer info unique_code = "ReceiptBillOrderPdf" print_settings=PrintSetting.find_by_unique_code(unique_code) shift = ShiftSale.find(saleObj.shift_sale_id) cashier_terminal = CashierTerminal.find(shift.cashier_terminal_id) shop_detail = Shop.current_shop order_reservation = OrderReservation.get_order_reservation_info(saleObj.sale_id) if !cashier_terminal.nil? # Calculate Food and Beverage Total item_price_by_accounts = SaleItem.calculate_price_by_accounts(saleObj.sale_items) discount_price_by_accounts = SaleItem.get_discount_price_by_accounts(saleObj.sale_items) other_amount = SaleItem.calculate_other_charges(saleObj.sale_items) printer = Printer::ReceiptPrinter.new(print_settings) filename, sale_receipt_no, printer_name = printer.print_receipt_bill(print_settings, false, nil,cashier_terminal,saleObj.sale_items,saleObj,saleObj.customer.name, item_price_by_accounts, discount_price_by_accounts, nil,nil,shop_details, "Paid",nil,nil,other_amount,nil,nil, order_reservation,nil) #receipt bill pdf setting result = {:status=> true, :filepath => filename, :sale_id => saleObj.sale_id, :receipt_no => sale_receipt_no, :printer_name => printer_name, :printer_model => print_settings.brand_name, :printer_url => print_settings.api_settings , :message => DELIVERED } else result = {:status=> true, :message => DELIVERED } end Rails.logger.debug "@@@@ result :: " Rails.logger.debug result else result = {:status=> true, :message => DELIVERED } end return result end end def self.send_status_to_ordering(url,ref_no,status,waiting_time=nil,min_type=nil,reason=nil) base_url = 'https://api.doemal.com' token = '3T-tnlYtFJ-5Z1vY6XQqxQ' order_reservation = Lookup.collection_of("order_reservation") if !order_reservation.empty? order_reservation.each do |order_reserve| if order_reserve[0] == 'BaseURL' base_url = order_reserve[1] elsif order_reserve[0] == 'Token' token = order_reserve[1] end end else Rails.logger.debug "Add order reservation BaseURL " response = {status: false} end Rails.logger.debug "Doemal URL" + base_url post_url = base_url + url # if status == 'processed' # status = 'send_to_kitchen' # elsif status == 'delivery' # status = 'ready_to_delivery' # elsif status == 'completed' # status = 'delivered' # else # status = status # end if (!min_type.nil? && !waiting_time.nil?) && (min_type != "" && waiting_time != "") send_params = {id: ref_no,type: min_type, waiting_time: waiting_time, status: status} elsif !reason.nil? && reason != "" send_params = {id: ref_no, status: status, reason: reason} else send_params = {id: ref_no, status: status} end begin response = HTTParty.post(post_url, :body => send_params.to_json, :headers => { 'Authorization' => 'Token token='+token, 'Content-Type' => 'application/json', 'Accept' => 'application/json; version=3' }, :timeout => 10 ) rescue Net::OpenTimeout response = { status: false } rescue OpenURI::HTTPError response = { status: false} rescue SocketError response = { status: false} end Rails.logger.debug "Get Doemal Status => #{send_params}" Rails.logger.debug response.to_json return response end def self.update_order_reservation(id, sale_id, status, expected_waiting_time=nil, remark=nil, access_code=nil, current_user=nil) order_reservation = OrderReservation.find(id) action_times = {} if sale_id.present? order_reservation.sale_id = sale_id end if !expected_waiting_time.nil? order_reservation.expected_waiting_time = expected_waiting_time end if !status.nil? order_reservation.status = status end if !remark.nil? order_reservation.order_remark = remark end if status == "delivered" order_reservation.payment_status = "paid" elsif status == 'foc' order_reservation.payment_status = "paid" elsif status == 'void' order_reservation.payment_status = "void" end if status == "accepted" action_times = {"accepted_time" => Time.now.utc, "kitchen_time" => "", "ready_time" => ""} order_reservation.action_times = action_times.to_json elsif status == SEND_TO_KITCHEN if !order_reservation.action_times.nil? action_data = JSON.parse(order_reservation.action_times) action_data["kitchen_time"] = Time.now.utc order_reservation.action_times = action_data.to_json end elsif status == READY_TO_DELIVERY if !order_reservation.action_times.nil? action_data = JSON.parse(order_reservation.action_times) action_data["ready_time"] = Time.now.utc order_reservation.action_times = action_data.to_json end end order_reservation.save if !order_reservation.sale_id.nil? && (status == "rejected" || status == "void") void_doemal_payment(order_reservation.sale_id, remark, access_code, current_user) end end def self.void_doemal_payment(sale_id, remark, access_code, current_user) if Sale.exists?(sale_id) sale = Sale.find_by_sale_id(sale_id) # update count for shift sale if(sale.sale_status == "completed") if sale.shift_sale_id != nil shift = ShiftSale.find(sale.shift_sale_id) shift.calculate(sale_id, "void") end else # void before sale payment complete if sale.shift_sale_id != nil shift = ShiftSale.find(sale.shift_sale_id) shift.total_void = shift.total_void + sale.grand_total shift.save end end sale.payment_status = 'void' sale.sale_status = 'void' sale.save # For Sale Audit if !current_user.nil? action_by = current_user.name else action_by = "doemal" end approved_name = nil approved_by = Employee.find_by_emp_id(access_code) if !approved_by.nil? approved_name = approved_by.name end cashier_name = Employee.where("id=?",sale.cashier_id).name # remark = "Void Sale ID #{sale_id} | Receipt No #{sale.receipt_no} | Receipt No #{sale.receipt_no} | Table ->#{table.name}" sale_audit = SaleAudit.record_audit_for_edit(sale_id,cashier_name, approved_name,remark,"SALEVOID" ) # update complete order items in oqs SaleOrder.where("sale_id = '#{ sale_id }'").find_each do |sodr| AssignedOrderItem.where("order_id = '#{ sodr.order_id }'").find_each do |aoi| aoi.delivery_status = 1 aoi.save end end end end def self.get_count_on_order order_reservation = OrderReservation.select("COUNT(order_reservation_id) as count, status") .where("status != 'delivered'") .group("status") end def self.get_count_on_completed order_reservation = OrderReservation.select("COUNT(order_reservation_id) as count") .where("created_at BETWEEN '#{Time.current.beginning_of_day.utc}' AND '#{Time.current.end_of_day.utc}' AND status = 'delivered'").first() end def self.get_pending_orders order_reservation = OrderReservation.select("order_reservations.*,del.provider,del.delivery_type") .joins(" JOIN deliveries as del on del.order_reservation_id=order_reservations.order_reservation_id") .where("order_reservations.status='new'") .order("order_reservations.order_reservation_id desc, order_reservations.created_at desc") end def self.check_new_order shop = Shop.current_shop if !shop.shop_code.nil? shop_code = shop.shop_code else shop_code = '' end order_reservation = OrderReservation.where("status='new'") if order_reservation.length > 0 if ENV["SERVER_MODE"] == 'cloud' from = request.subdomain + "." + request.domain else from = "" end ActionCable.server.broadcast "check_new_order_channel",data: order_reservation, shop_code: shop_code,from:from end end def self.check_order_send_to_kitchen shop = Shop.current_shop if !shop.shop_code.nil? shop_code = shop.shop_code else shop_code = '' end order_reservation = OrderReservation.where("status='accepted' and requested_time <= '#{Time.now.utc}'") if order_reservation.length > 0 if ENV["SERVER_MODE"] == 'cloud' from = request.subdomain + "." + request.domain else from = "" end ActionCable.server.broadcast "check_order_send_to_kitchen_channel",data: order_reservation, shop_code: shop_code,from:from end end def self.check_order_ready_to_delivery shop = Shop.current_shop if !shop.shop_code.nil? shop_code = shop.shop_code else shop_code = '' end order_reservation = OrderReservation.where("status='send_to_kitchen' and requested_time <= '#{Time.now.utc}'") if order_reservation.length > 0 if ENV["SERVER_MODE"] == 'cloud' from = request.subdomain + "." + request.domain else from = "" end ActionCable.server.broadcast "check_order_ready_to_delivery_channel",data: order_reservation, shop_code: shop_code,from:from end end def self.get_order_reservation_by_shift(shift_sale_range,shift,from,to,provider,payment_type) ## => left join -> show all sales although no orders if provider.blank? provider = '' else if provider.present? provider = " and deliveries.provider = '#{provider}'" end end if payment_type.blank? payment_type = '' else if payment_type.present? payment_type = " and order_reservations.payment_type = '#{payment_type}'" end end query = OrderReservation.select("order_reservations.*, sales.receipt_date, sales.receipt_no, deliveries.provider, deliveries.delivery_fee, customers.name, customers.email") .joins(" JOIN deliveries on deliveries.order_reservation_id = order_reservations.order_reservation_id") .joins(" JOIN customers on customers.customer_id = order_reservations.customer_id") .joins(" JOIN sales on sales.sale_id = order_reservations.sale_id") if shift.present? query = query.where("sales.shift_sale_id in (?) #{provider} #{payment_type} and sales.sale_status= 'completed' and sale_payments.payment_amount != 0", shift.to_a) .joins("join sale_payments on sale_payments.sale_id = sales.sale_id") .group("sales.sale_id") elsif shift_sale_range.present? query = query.where("sales.sale_status='completed' #{provider} #{payment_type} and sale_payments.payment_amount != 0 and sales.shift_sale_id in (?)",shift_sale_range.to_a) .joins("join sale_payments on sale_payments.sale_id = sales.sale_id") .group("sales.sale_id") else query = query.where("sales.sale_status='completed' and sales.receipt_date between ? and ? #{provider} #{payment_type} and sale_payments.payment_amount != 0",from,to) .joins("join sale_payments on sale_payments.sale_id = sales.sale_id") .group("sales.sale_id") end return query end def self.search(filter,from,to) if filter.blank? keyword = '' else keyword = "status LIKE '%#{filter}%' OR payment_type LIKE '%#{filter}%'" end if from.present? && to.present? order_reservation = OrderReservation.select("order_reservations.*, deliveries.provider, deliveries.delivery_fee") .joins(" JOIN deliveries on deliveries.order_reservation_id = order_reservations.order_reservation_id") .where("order_reservations.created_at >= ?" + " AND order_reservations.created_at <= ? and NOT status = 'new' ", from,to) query = order_reservation.where(keyword) else select("order_reservations.*, deliveries.provider, deliveries.delivery_fee") .joins(" JOIN deliveries on deliveries.order_reservation_id = order_reservations.order_reservation_id") .where("status LIKE '%#{filter}%' OR payment_type LIKE '%#{filter}%'") end end #Create get_data for order_reservation def self.get_order_reservation_info(sale_id) query=OrderReservation.select("order_reservations.* ,deliveries.delivery_type,deliveries.delivery_fee") .joins("join deliveries on deliveries.order_reservation_id = order_reservations.order_reservation_id") .where("order_reservations.sale_id = '#{sale_id}'").first() return query end private def generate_custom_id self.order_reservation_id = SeedGenerator.generate_id(self.class.name, "ODRS") end end