order queue processing
This commit is contained in:
@@ -7,6 +7,8 @@ Things you may want to cover:
|
||||
* Ruby version
|
||||
ruby 2.3.2p217
|
||||
|
||||
* ToDo list
|
||||
|
||||
* System dependencies
|
||||
|
||||
* Configuration
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
class ApplicationController < ActionController::Base
|
||||
JSONclass ApplicationController < ActionController::Base
|
||||
#before_action :check_installation
|
||||
protect_from_forgery with: :exception
|
||||
|
||||
|
||||
@@ -5,10 +5,12 @@ class OrderQueueProcessorJob < ApplicationJob
|
||||
# Do something later
|
||||
#Order ID
|
||||
order = Order.find(order_id)
|
||||
|
||||
|
||||
#Loop through the order stations and process the items
|
||||
#Execute orders and send to order stations
|
||||
if order
|
||||
|
||||
oqs = OrderQueueStation.new
|
||||
oqs.process_order(order)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
13
app/models/assigned_order_item.rb
Normal file
13
app/models/assigned_order_item.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class AssignedOrderItem < ApplicationRecord
|
||||
belongs_to :order_queue_station
|
||||
|
||||
def self.assigned_order_item (order, item_code, order_queue_station )
|
||||
assigned_order_item = AssignedOrderItem.new()
|
||||
assigned_order_item.order = order
|
||||
assigned_order_item.item_code = item_code
|
||||
assigned_order_item.order_queue_station = order_queue_station
|
||||
assigned_order_item.print_status = false
|
||||
assigned_order_item.delivery_status = false
|
||||
assigned_order_item.save
|
||||
end
|
||||
end
|
||||
@@ -4,17 +4,19 @@ class Lookup < ApplicationRecord
|
||||
{'Employee Roles' => 'employee_roles',
|
||||
'Dining Facilities Status' => 'dining_facilities_status',
|
||||
'Menu Item Type' => 'menu_item_type',
|
||||
'Menu Item Attribute Type' => 'menu_item_attribute_type',
|
||||
'Order Type' => 'order_type',
|
||||
'Order Source' => 'order_source',
|
||||
'Order Status' => 'order_status',
|
||||
'Order Item Status' => 'order_item_status',
|
||||
'Sale Status' => 'sales_status',
|
||||
'Payment Status' => 'payment_status',
|
||||
'Payment Methods' => 'payment_methods'}
|
||||
'Payment Methods' => 'payment_methods',
|
||||
"Gateway Communication Type" => "gateway_communication_type"}
|
||||
end
|
||||
|
||||
def self.collection_of(type)
|
||||
Lookup.select("name, value").where("lookup_type" => type ).map { |l| [l.name, l.value] }
|
||||
Lookup.select("name, value").where("lookup_type" => type ).map { |l| [l.name, l.value] }
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
2
app/models/membership_setting.rb
Normal file
2
app/models/membership_setting.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
class MembershipSetting < ApplicationRecord
|
||||
end
|
||||
@@ -4,6 +4,7 @@ class Order < ApplicationRecord
|
||||
|
||||
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
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
class OrderQueueProcessByZone < ApplicationRecord
|
||||
belongs_to :zone
|
||||
belongs_to :order_queue_station
|
||||
end
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
class OrderQueueProcessLog < ApplicationRecord
|
||||
belongs_to :order
|
||||
end
|
||||
@@ -1,2 +1,47 @@
|
||||
|
||||
# Order Queue station is where order are submitted to
|
||||
# Order can send from tablet | table
|
||||
# Source of order will determin where it will appear
|
||||
class OrderQueueStation < ApplicationRecord
|
||||
has_many :assigned_order_items
|
||||
has_many :order_items
|
||||
|
||||
scope :active, -> {where(is_active: true)}
|
||||
|
||||
def process_order (order)
|
||||
oqs_stations = OrderQueueStation.active
|
||||
|
||||
order_items = order.order_items
|
||||
#Assign OQS id to order Items
|
||||
oqs_stations.each do |oqs|
|
||||
#Get List of items -
|
||||
pq_items = JSON.parse(oqs.processing_items)
|
||||
|
||||
#Loop through the processing items
|
||||
pq_items.each do |pq_item|
|
||||
#Processing through the looping items
|
||||
order_items.each do |order_item|
|
||||
if (pq_item == order_item.item_code)
|
||||
#Same Order_items can appear in two location.
|
||||
AssignedOrderItem.assigned_order_item(order, order_item.item_code, oqs)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
#Print OQS where printing is require
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
#Print order_items in 1 slip
|
||||
def print_slip
|
||||
|
||||
end
|
||||
|
||||
#Print order_items in 1 slip per item
|
||||
def print_slip_item
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,27 +3,60 @@ class Sale < ApplicationRecord
|
||||
belongs_to :cashier
|
||||
belongs_to :customer
|
||||
has_many :sale_items
|
||||
has_many :sale_discount_items
|
||||
has_many :sale_discounts
|
||||
has_many :sale_taxes
|
||||
has_many :sale_payments
|
||||
has_many :sale_orders
|
||||
|
||||
def generate_invoice_from_order (order_no)
|
||||
def generate_invoice_from_order (order_no, sale_id)
|
||||
#if sale_id is exsit and validate
|
||||
#add order to that invoice
|
||||
if (sale_id)
|
||||
self = Sale.find(sale_id)
|
||||
end
|
||||
if self.sale_status == "void"
|
||||
return false, "Invoice is void. Cannot be edited"
|
||||
else
|
||||
order = Order.find(order_no)
|
||||
if order
|
||||
order.order_items.each do |item|
|
||||
self.sale_items.add(add_item(item))
|
||||
end
|
||||
end
|
||||
|
||||
link_order_sale(order.id)
|
||||
|
||||
return self.save!
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
def generate_invoice_by_items (items)
|
||||
|
||||
end
|
||||
|
||||
def add_item (item)
|
||||
#check if the item is on promotion
|
||||
|
||||
#save sale_audit
|
||||
sale_item = SaleItem.new
|
||||
sale_item.sale = self
|
||||
sale_item.product_code = item.item_code
|
||||
sale_item.product_name = item.item_name
|
||||
sale_item.qty = item.qty
|
||||
return sale_item
|
||||
end
|
||||
|
||||
def remove_item (item)
|
||||
|
||||
def update_item (item)
|
||||
#save sale_audit
|
||||
|
||||
end
|
||||
|
||||
def apply_discount_item (promotion_id, item)
|
||||
def apply_item_discount (promotion_id, item)
|
||||
end
|
||||
|
||||
def apply_discount (discount_type, discount_code)
|
||||
@@ -33,8 +66,13 @@ class Sale < ApplicationRecord
|
||||
def accept_payment (payment_method, amount, payment_ref, payment_external_result)
|
||||
end
|
||||
|
||||
def void_sales (void_by, reason, approval_code)
|
||||
def void_sales (void_by, reason, approval_code, request_by)
|
||||
#save sale_audit
|
||||
self.sale_status = "void"
|
||||
self.
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
#compute - invoice total
|
||||
@@ -64,14 +102,17 @@ class Sale < ApplicationRecord
|
||||
#tax_profile - list by order_by
|
||||
tax_profiles = TaxProfile.all.order("order_by asc")
|
||||
|
||||
|
||||
total_amount = self.total_amount
|
||||
#Creat new tax records
|
||||
tax_profiles.each do |tax|
|
||||
sale_tax = SaleTax.new(:sale => self)
|
||||
sale_tax.tax_name = tax.name
|
||||
sale_tax.tax_rate = tax.rate
|
||||
#include or execulive
|
||||
sale_tax.tax_payable_amount = self.total_amount * tax.rate
|
||||
sale_tax.tax_payable_amount = total_amount * tax.rate
|
||||
#new taxable amount
|
||||
total_amount = total_amount + sale_tax.tax_payable_amount
|
||||
|
||||
sale_tax.inclusive = tax.inclusive
|
||||
sale_tax.save
|
||||
end
|
||||
@@ -82,12 +123,22 @@ class Sale < ApplicationRecord
|
||||
|
||||
|
||||
private
|
||||
def product_get_unit_price(item.item_code)
|
||||
menu_instance_code = MenuInstanceCode.find_by_item_instance_code(item.item_code)
|
||||
if (menu_instance_code)
|
||||
|
||||
end
|
||||
|
||||
def link_order_sale(order.id)
|
||||
|
||||
end
|
||||
#Generate new Receipt No when it is not assigned
|
||||
def generate_receipt_no
|
||||
#Date-Shift-
|
||||
if !self.receipt_no.nil?
|
||||
prefix = Date.now()
|
||||
self.receipt_no = prefix.to_s + "/" + self.shit_id.to_s + "/" + SeedGenerator.new_receipt_no().to_s
|
||||
self.receipt_date = prefix
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,2 +1,41 @@
|
||||
class SaleAudit < ApplicationRecord
|
||||
belongs_to :sale
|
||||
|
||||
def record_audit_void(sale_id, void_by, approved_by, reason)
|
||||
#sale_audit
|
||||
sale_audit = SaleAudit.new()
|
||||
sale_audit.sale_id = sale_id
|
||||
sale_audit.action = "SALEVOID"
|
||||
sale_audit.action_at = DateTime.now.utc
|
||||
sale_audit.action_by = void_by
|
||||
sale_audit.approved_by = approved_by
|
||||
sale_audit.remark = reason
|
||||
sale_audit.save!
|
||||
#sale_audit.
|
||||
end
|
||||
|
||||
def record_audit_discount(sale_id, discount_by, approved_by, reason)
|
||||
#sale_audit
|
||||
sale_audit = SaleAudit.new()
|
||||
sale_audit.sale_id = sale_id
|
||||
sale_audit.action = "SALEDISCOUNT"
|
||||
sale_audit.action_at = DateTime.now.utc
|
||||
sale_audit.action_by = discount_by
|
||||
sale_audit.approved_by = approved_by
|
||||
sale_audit.remark = reason
|
||||
sale_audit.save!
|
||||
#sale_audit.
|
||||
end
|
||||
|
||||
def record_audit_foc(sale_id, cashier_id, approved_by, reason)
|
||||
#sale_audit
|
||||
sale_audit = SaleAudit.new()
|
||||
sale_audit.sale_id = sale_id
|
||||
sale_audit.action = "SALEFOC"
|
||||
sale_audit.action_at = DateTime.now.utc
|
||||
sale_audit.action_by = cashier_id
|
||||
sale_audit.approved_by = approved_by
|
||||
sale_audit.remark = reason
|
||||
sale_audit.save!
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<meta name="description" content=""/>
|
||||
<meta name="author" content=""/>
|
||||
|
||||
<title>Film Buff</title>
|
||||
<title>SmartSales : Restaurant</title>
|
||||
<%= csrf_meta_tags %>
|
||||
|
||||
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<meta name="description" content=""/>
|
||||
<meta name="author" content=""/>
|
||||
|
||||
<title>Film Buff</title>
|
||||
<title>SmartSales : Restaurant</title>
|
||||
<%= csrf_meta_tags %>
|
||||
|
||||
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
||||
|
||||
@@ -7,10 +7,11 @@ class CreateMenuItems < ActiveRecord::Migration[5.0]
|
||||
t.string :type, :null => false, :default => "SimpleMenuItem"
|
||||
t.references :menu_category, foreign_key: true
|
||||
t.references :menu_item, foreign_key: true
|
||||
t.integer :min_qty, :null => false, :default => 1
|
||||
t.integer :min_selectable_item, :null => false, :default => 1
|
||||
t.integer :max_selectable_item, :null => false, :default => 1
|
||||
t.json :options #save value
|
||||
t.json :attributes #value IDS
|
||||
t.json :item_attributes #value IDS
|
||||
t.string :created_by
|
||||
|
||||
t.timestamps
|
||||
|
||||
@@ -10,7 +10,6 @@ class CreateOrderItems < ActiveRecord::Migration[5.0]
|
||||
t.string :remark
|
||||
t.string :options
|
||||
t.json :set_menu_items #this parameter is require to route the items correctly
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
class CreateOrderQueueProcessLogs < ActiveRecord::Migration[5.0]
|
||||
def change
|
||||
create_table :order_queue_process_logs do |t|
|
||||
t.references :order, foreign_key: true
|
||||
t.string :job_status, :default => "new", :null => "false"
|
||||
t.string :print_status, :default => "new"
|
||||
t.json :header #{table name, order_type, order_date}
|
||||
t.json :items #{name, comment, qty}
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
15
db/migrate/20170414071634_create_membership_settings.rb
Normal file
15
db/migrate/20170414071634_create_membership_settings.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
class CreateMembershipSettings < ActiveRecord::Migration[5.0]
|
||||
def change
|
||||
create_table :membership_settings do |t|
|
||||
t.string :membership_type, :null => false, :default => "internal"
|
||||
t.boolean :is_active, :null => false, :default => true
|
||||
t.string :gateway_communication_type, :null => false, :default => "api"
|
||||
t.string :gateway_url
|
||||
t.string :auth_token
|
||||
t.string :merchant_account_id
|
||||
t.string :created_by
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
13
db/migrate/20170414090001_create_assigned_order_items.rb
Normal file
13
db/migrate/20170414090001_create_assigned_order_items.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class CreateAssignedOrderItems < ActiveRecord::Migration[5.0]
|
||||
def change
|
||||
create_table :assigned_order_items do |t|
|
||||
t.string :item_code, :null => false, :index => true
|
||||
t.references :order_queue_station, foreign_key: true
|
||||
t.references :order, foreign_key: true
|
||||
t.boolean :print_status
|
||||
t.boolean :delivery_status
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
40
db/seeds.rb
40
db/seeds.rb
@@ -6,6 +6,9 @@
|
||||
# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
|
||||
# Character.create(name: 'Luke', movie: movies.first)
|
||||
|
||||
gateway_communication_type = Lookup.create([{lookup_type:'gateway_communication_type', name: 'API', value: 'api'},
|
||||
{lookup_type:'gateway_communication_type', name: 'USB', value: 'usb'}])
|
||||
|
||||
payment_methods = Lookup.create([{lookup_type:'payment_methods', name: 'Cash', value: 'cash'},
|
||||
{lookup_type:'payment_methods', name: 'CreditNote', value: 'creditnote'},
|
||||
{lookup_type:'payment_methods', name: 'Card - VISA', value: 'visa'},
|
||||
@@ -47,6 +50,10 @@ menu_item_type = Lookup.create([{lookup_type:'menu_item_type', name: 'SIMPLE', v
|
||||
{lookup_type:'menu_item_type', name: 'Set Menu', value: 'set_menu'},
|
||||
{lookup_type:'menu_item_type', name: 'DIY', value: 'diy'}])
|
||||
|
||||
#menu_item_attribute:[size|]
|
||||
menu_item_attribute_type = Lookup.create([{lookup_type:'menu_item_attribute_type', name: 'Size', value: 'size'},
|
||||
{lookup_type:'menu_item_attribute_type', name: 'Spicy', value: 'spicy'},
|
||||
{lookup_type:'menu_item_attribute_type', name: 'Sweetness', value: 'sweetness'}])
|
||||
|
||||
#Employee Roles
|
||||
employee_roles = Lookup.create([{lookup_type:'employee_roles', name: 'Cashier', value: 'cashier'},
|
||||
@@ -63,15 +70,46 @@ booking_status = Lookup.create([{lookup_type:'booking_status', name: 'Available'
|
||||
|
||||
#WALK CUSTOMER - Default CUSTOMER (take key 1)
|
||||
customer = Customer.create({id:1, name:"WALK-IN", contact_no:"000000000"})
|
||||
customer = Customer.create({id:2, name:"TAKEAWAY", contact_no:"000000000"})
|
||||
|
||||
|
||||
#Default ZOne
|
||||
zone = Zone.create({id:1, name: "Default Zone", is_active:true, created_by: "SYSTEM DEFAULT"})
|
||||
zone2 = Zone.create({id:2, name: "Default Zone 2", is_active:true, created_by: "SYSTEM DEFAULT"})
|
||||
|
||||
#Default dining_facilities
|
||||
dining_facilities = DiningFacility.create({id:1, name:"Default Table", zone: zone, status:"available", type: "Table", seater: 2 , order_by:1, created_by:"SYSTEM DEFAULT"})
|
||||
table = Table.create({name:"Default Table", zone: zone, status:"available", seater: 2 , order_by:1, created_by:"SYSTEM DEFAULT"})
|
||||
room = Room.create({name:"Default Room", zone: zone2, status:"available", seater: 4 , order_by:1, created_by:"SYSTEM DEFAULT"})
|
||||
|
||||
#Tax Profile
|
||||
tax_profiles = TaxProfile.create({id:1, name: "Commerical Tax", rate:5.0, order_by:1, created_by:"SYSTEM DEFAULT"})
|
||||
|
||||
|
||||
#Default menu
|
||||
menu = Menu.create({name: "Default Menu", is_active: true, created_by: "SYSTEM DEFAULT"})
|
||||
|
||||
#Default Menu Category
|
||||
menu_category1 = MenuCategory.create({menu: menu, name: "Sample Menu Category 1", alt_name: "Sample Alternate Name 1", order_by: 1})
|
||||
menu_category2 = MenuCategory.create({menu: menu, name: "Sample Menu Category 2", alt_name: "Sample Alternate Name 2", order_by: 2})
|
||||
menu_category3 = MenuCategory.create({menu: menu, name: "Sample Menu Category 3", alt_name: "Sample Alternate Name 3", order_by: 3})
|
||||
menu_category4 = MenuCategory.create({menu: menu, name: "Sample Menu Category 4", alt_name: "Sample Alternate Category 4", order_by: 1, menu_category_id: menu_category3.id})
|
||||
|
||||
#Default Menu items
|
||||
menu_category1_menu_item0 = SimpleMenuItem.create({item_code:"01001", name: "Default Menu Item Name 0", alt_name: "Alternate Menu Item Name 0",menu_category: menu_category1 , min_selectable_item: 1, max_selectable_item:1 })
|
||||
menu_category1_menu_item1 = SimpleMenuItem.create({item_code:"01002", name: "Default Menu Item Name 1", alt_name: "Alternate Menu Item Name 1",menu_category: menu_category1 , min_selectable_item: 1, max_selectable_item:1 })
|
||||
menu_category1_menu_item2 = SimpleMenuItem.create({item_code:"01003", name: "Default Menu Item Name 2", alt_name: "Alternate Menu Item Name 2",menu_category: menu_category1 , min_selectable_item: 1, max_selectable_item:1 })
|
||||
menu_category1_menu_item3 = SimpleMenuItem.create({item_code:"01004", name: "Default Menu Item Name 3", alt_name: "Alternate Menu Item Name 3",menu_category: menu_category1 , min_selectable_item: 1, max_selectable_item:1 })
|
||||
|
||||
menu_category2_menu_item0 = SimpleMenuItem.create({item_code:"02005", name: "Default Menu Item Name 0", alt_name: "Alternate Menu Item Name 0",menu_category: menu_category2 , min_selectable_item: 1, max_selectable_item:1, min_qty: 2 })
|
||||
menu_category2_menu_item1 = SimpleMenuItem.create({item_code:"02006", name: "Default Menu Item Name 1", alt_name: "Alternate Menu Item Name 1",menu_category: menu_category2 , min_selectable_item: 1, max_selectable_item:1, min_qty: 2 })
|
||||
menu_category2_menu_item2 = SimpleMenuItem.create({item_code:"02007", name: "Default Menu Item Name 2", alt_name: "Alternate Menu Item Name 2",menu_category: menu_category2 , min_selectable_item: 1, max_selectable_item:1, min_qty: 3 })
|
||||
menu_category2_menu_item3 = SimpleMenuItem.create({item_code:"02008", name: "Default Menu Item Name 3", alt_name: "Alternate Menu Item Name 3",menu_category: menu_category2 , min_selectable_item: 1, max_selectable_item:1, min_qty: 4 })
|
||||
|
||||
#Default Order Queue stations
|
||||
order_queue_station1 = OrderQueueStation.create({station_name: "Queue Station 1", is_active: true,printer_name: "kitchen_printer", processing_items: JSON.generate(['01001','01002','01003','01004']), print_copy:true, cut_per_item: false, use_alternate_name: false, created_by: "SYSTEM DEFAULT"})
|
||||
order_queue_station2 = OrderQueueStation.create({station_name: "Queue Station 2", is_active: true,printer_name: "drink_printer", processing_items: JSON.generate(['02005','02006','02007','02008']), print_copy:true, cut_per_item: true, use_alternate_name: true, created_by: "SYSTEM DEFAULT"})
|
||||
zone_order_queue_station = OrderQueueStation.create({station_name: "Zone 1 Queue Station 2", is_active: true, printer_name: "print_station", processing_items: JSON.generate(['01001','01002','01003','01004','02005','02006','02007','02008']), print_copy: true, cut_per_item: true, use_alternate_name: false, created_by: "SYSTEM DEFAULT"})
|
||||
|
||||
|
||||
#Default Order Queue Process By Zone
|
||||
zone_queue_station = OrderQueueProcessByZone.create({order_queue_station: zone_order_queue_station, zone: zone2})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe OrderQueueProcessLog, type: :model do
|
||||
RSpec.describe AssignedOrderItem, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
5
spec/models/membership_setting_spec.rb
Normal file
5
spec/models/membership_setting_spec.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe MembershipSetting, type: :model do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
Reference in New Issue
Block a user