527 lines
20 KiB
Ruby
527 lines
20 KiB
Ruby
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 '#{DateTime.now.utc.beginning_of_day}' AND '#{DateTime.now.utc.end_of_day}'") }
|
|
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.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" => DateTime.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"] = DateTime.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"] = DateTime.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 '#{DateTime.now.beginning_of_day}' AND '#{DateTime.now.end_of_day}' 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
|