Merge branch 'master' into august_spring

This commit is contained in:
Phyo
2017-08-28 14:25:48 +06:30
19 changed files with 500 additions and 170 deletions

View File

@@ -1,14 +1,19 @@
# README # README
SXRestuarant is a new Dedicate project for SmartSales Restaurant. It is improvement from v1.2 with upgrade to latest Bootstrap and Rails 5. The API is better define and route are refactor. SXRestuarant is a new Dedicate project for SmartSales Restaurant. It is improvement from v1.2 with upgrade to latest Bootstrap and Rails 5.2. The API is better define and route are refactor.
Things you may want to cover: Things you may want to cover:
* Ruby version * Ruby version
ruby 2.3.2p217 ruby 2.4.1p111
* ToDo list * ToDo list
1. Cloud Sync
2. Action Cable
3. Shop Setup
4. Payment Integation
* System dependencies * System dependencies
* Configuration * Configuration
@@ -23,4 +28,55 @@ ruby 2.3.2p217
* Deployment instructions * Deployment instructions
* ...
* Features
1. OQS
1. Filter
2. Order Item to each Stations
3. Edit Order Item
2. Origami(Sale)
1. Sale
2. Add Customer for membership
3. Discount and Member Discount for Sale
4. Assign Commissioner
5. Add other charges to Sale
3. CRM
1. Customer Management
2. Queue Management
4. Backend
1. Dining Setup
2. Queue Station Setup
3. Menu Setup
4. Cashier Terminal Setup
5. Tax Profile Setup
6. Printer Setup
7. Payment Integration
8. Employee Management
9. Promotion Setup
10. Commissioner Setup
11. Membership Integration
5. Inventory
6. Report

View File

@@ -4,7 +4,24 @@ class Api::Restaurant::MenuController < Api::ApiController
# Pull the default menu details and also other available (active) menus # Pull the default menu details and also other available (active) menus
# Input Params - order_id # Input Params - order_id
def index def index
@menus = Menu.all param_checksum = params[:checksum]
# checksum = File.readlines("public/checksums/menu_json.txt").pop.chomp
all_menu = Menu.all
# to hash
menu_array = []
all_menu.each do |m|
menu_array.push(m.to_json(:include => {:menu_categories => { :include => { :menu_items => { :include => [:menu_item_sets, :menu_item_instances => {:include => :menu_instance_item_sets}]} } }}))
end
#export Checksum file generate by md5
menu_checksum = Digest::MD5.hexdigest(menu_array.to_json)
if menu_checksum != param_checksum
response.headers['CHECKSUM'] = menu_checksum
@menus = all_menu
end
# @current_menu = Menu.current_menu # @current_menu = Menu.current_menu
end end

View File

@@ -6,13 +6,33 @@ class Crm::CustomersController < BaseCrmController
# GET /crm/customers.json # GET /crm/customers.json
def index def index
filter = params[:filter] filter = params[:filter]
type = params[:type]
if filter.nil? if filter.nil?
@crm_customers = Customer.all @crm_customers = Customer.all
else else
@crm_customers = Customer.search(filter) @crm_customers = Customer.search(filter)
# search account no from paypar
if !@crm_customers.present? && type == "card"
response = Customer.search_paypar_account_no(filter)
if response["status"] == true
@crm_customers = Customer.new
@crm_customers.name = response["customer_data"]["name"]
@crm_customers.contact_no = response["customer_data"]["phone"]
@crm_customers.email = response["customer_data"]["email"]
@crm_customers.date_of_birth = response["customer_data"]["DOB"]
@crm_customers.nrc_no = response["customer_data"]["NRC"]
@crm_customers.address = response["customer_data"]["address"]
@crm_customers.card_no = response["customer_data"]["customer_card_no"]
@crm_customers.paypar_account_no = filter
@crm_customers.membership_id = response["customer_data"]["id"]
@crm_customers.membership_type = response["customer_data"]["member_group_id"]
@crm_customers.customer_type = "Dinein"
@crm_customers.tax_profiles = ["1", "2"]
@crm_customers.save
@crm_customers = Customer.search(filter)
end
end
end end
#@crm_customers = Customer.all
@crm_customers = Kaminari.paginate_array(@crm_customers).page(params[:page]).per(50) @crm_customers = Kaminari.paginate_array(@crm_customers).page(params[:page]).per(50)
@crm_customer = Customer.new @crm_customer = Customer.new
@count_customer = Customer.count_customer @count_customer = Customer.count_customer

View File

@@ -9,13 +9,40 @@ class Origami::CustomersController < BaseOrigamiController
end end
def get_customer def get_customer
filter = params[:filter] filter = params[:filter]
type = params[:type]
if filter.nil? if filter.nil?
@crm_customers = Customer.order("customer_id").page(params[:page]) @crm_customers = Customer.order("customer_id").page(params[:page])
#@products = Product.order("name").page(params[:page]).per(5) #@products = Product.order("name").page(params[:page]).per(5)
else else
@crm_customers = Customer.search(filter) @crm_customers = Customer.search(filter)
# search account no from paypar
if !@crm_customers.present? && type == "card"
response = Customer.search_paypar_account_no(filter)
if response["status"] == true
@crm_customers = Customer.new
@crm_customers.name = response["customer_data"]["name"]
@crm_customers.contact_no = response["customer_data"]["phone"]
@crm_customers.email = response["customer_data"]["email"]
@crm_customers.date_of_birth = response["customer_data"]["DOB"]
@crm_customers.nrc_no = response["customer_data"]["NRC"]
@crm_customers.address = response["customer_data"]["address"]
@crm_customers.card_no = response["customer_data"]["customer_card_no"]
@crm_customers.paypar_account_no = filter
@crm_customers.membership_id = response["customer_data"]["id"]
@crm_customers.membership_type = response["customer_data"]["member_group_id"]
@crm_customers.customer_type = "Dinein"
@crm_customers.tax_profiles = ["1", "2"]
@crm_customers.save
@crm_customers = Customer.search(filter)
else
@crm_customers = [{"customer_id": response["status"],"message": response["message"] }]
end end
end
end
render :json => @crm_customers.to_json render :json => @crm_customers.to_json
end end

View File

@@ -79,7 +79,7 @@ class Settings::SimpleMenuItemsController < ApplicationController
respond_to do |format| respond_to do |format|
if @settings_menu_item.save if @settings_menu_item.save
menu_item = MenuItem.find(@settings_menu_item.id) menu_item = MenuItem.find(@settings_menu_item.id)
menu_item.update_attributes(item_options: params[:simple_menu_item][:item_options]) menu_item.update_attributes(item_attributes: params[:simple_menu_item][:item_attributes], item_options: params[:simple_menu_item][:item_options])
format.html { redirect_to settings_menu_category_simple_menu_items_path, notice: 'Menu item was successfully created.' } format.html { redirect_to settings_menu_category_simple_menu_items_path, notice: 'Menu item was successfully created.' }
format.json { render :show, status: :created, location: @settings_menu_item } format.json { render :show, status: :created, location: @settings_menu_item }

View File

@@ -94,15 +94,26 @@ class Customer < ApplicationRecord
@customers = Customer.where("membership_type IS NOT NULL AND membership_id IS NULL") @customers = Customer.where("membership_type IS NOT NULL AND membership_id IS NULL")
@customers.each do |customer| @customers.each do |customer|
begin member_params = { name: customer.name,phone: customer.contact_no,
response = HTTParty.post(url,
:body =>
{ name: customer.name,phone: customer.contact_no,
email: customer.email,dob: customer.date_of_birth, email: customer.email,dob: customer.date_of_birth,
address: customer.address,nrc:customer.nrc_no, address: customer.address,nrc:customer.nrc_no,
card_no:customer.card_no,member_group_id: customer.membership_type, card_no:customer.card_no,member_group_id: customer.membership_type,
merchant_uid:merchant_uid,auth_token:auth_token merchant_uid:merchant_uid,auth_token:auth_token}.to_json
}.to_json,
# Check for paypar account exists
# if paypar_account_no != nil || paypar_account_no != ''
if paypar_account_no.present?
member_params = { name: customer.name,phone: customer.contact_no,
email: customer.email,dob: customer.date_of_birth,
address: customer.address,nrc:customer.nrc_no,
paypar_account_no: customer.paypar_account_no,
card_no:customer.card_no,member_group_id: customer.membership_type,
merchant_uid:merchant_uid,auth_token:auth_token}.to_json
end
begin
response = HTTParty.post(url,
:body => member_params,
:headers => { :headers => {
'Content-Type' => 'application/json', 'Content-Type' => 'application/json',
'Accept' => 'application/json' 'Accept' => 'application/json'
@@ -120,17 +131,14 @@ class Customer < ApplicationRecord
if response["status"] == true if response["status"] == true
status = customer.update_attributes(membership_id: response["customer_datas"]["id"]) status = customer.update_attributes(membership_id: response["customer_datas"]["id"])
end end
end end
end end
def self.update_rebate def self.update_rebate
sales = Sale.where("rebate_status = 'false'") sales = Sale.where("rebate_status = 'false'")
sales.each do |sale| sales.each do |sale|
if sale.customer.membership_id if sale.customer.membership_id
response = self.rebat(Sale.find(sale.sale_id)) response = self.rebat(Sale.find(sale.sale_id))
puts response.to_json
if response["status"] == true if response["status"] == true
status = sale.update_attributes(rebate_status: "true") status = sale.update_attributes(rebate_status: "true")
end end
@@ -189,11 +197,43 @@ class Customer < ApplicationRecord
end end
return response return response
puts response.to_json
end end
end end
end end
def self.search_paypar_account_no(account_no)
membership = MembershipSetting.find_by_membership_type("paypar_url")
memberaction = MembershipAction.find_by_membership_type("search_paypar_account_no")
merchant_uid = memberaction.merchant_account_id.to_s
auth_token = memberaction.auth_token.to_s
url = membership.gateway_url.to_s + memberaction.gateway_url.to_s
begin
response = HTTParty.get(url,
:body => { paypar_account_no:account_no,
merchant_uid:merchant_uid,
auth_token:auth_token
}.to_json,
:headers => {
'Content-Type' => 'application/json',
'Accept' => 'application/json'
},
:timeout => 10
)
rescue HTTParty::Error
response = {status: false, message: "Server Error"}
rescue Net::OpenTimeout
response = { status: false , message: "Server Time out"}
rescue OpenURI::HTTPError
response = { status: false, message: "Can't connect server"}
rescue SocketError
response = { status: false, message: "Can't connect server"}
end
return response
end
def self.search(search) def self.search(search)
if search if search
# find(:all, :conditions => ['name LIKE ? OR contact_no LIKE ?', "%#{search}%", "%#{search}%"]) # find(:all, :conditions => ['name LIKE ? OR contact_no LIKE ?', "%#{search}%", "%#{search}%"])

View File

@@ -1,6 +1,6 @@
class MenuItemAttribute < ApplicationRecord class MenuItemAttribute < ApplicationRecord
validates_presence_of :attribute_type, :name, :value validates_presence_of :attribute_type, :name, :value
def self.collection def self.collection
MenuItemAttribute.select("name, value").map { |e| [e.name, e.value] } MenuItemAttribute.select("name").map { |e| [e.name, e.name] }
end end
end end

View File

@@ -90,7 +90,7 @@ class Order < ApplicationRecord
# self.employee_name) # self.employee_name)
# end # end
OrderItem.processs_item(menu_item[:item_code], menu_item[:name], menu_item[:alt_name], menu_item[:account_id], 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, item[:quantity],menu_item[:price], item[:options], set_order_items, self.id,
self.employee_name) self.employee_name)

View File

@@ -20,11 +20,12 @@ class OrderItem < ApplicationRecord
# option_values : [], # option_values : [],
# sub_order_items : [], # sub_order_items : [],
# } # }
def self.processs_item (item_code, menu_name, alt_name, account_id, qty,price, options, set_menu_items, order_id, item_order_by) def self.processs_item (item_code, instance_code, menu_name, alt_name, account_id, qty,price, options, set_menu_items, order_id, item_order_by)
orderitem = OrderItem.create do |oitem| orderitem = OrderItem.create do |oitem|
oitem.order_id = order_id oitem.order_id = order_id
oitem.item_code = item_code oitem.item_code = item_code
oitem.item_instance_code = instance_code
oitem.item_name = menu_name oitem.item_name = menu_name
oitem.alt_name = alt_name oitem.alt_name = alt_name
oitem.account_id = account_id oitem.account_id = account_id

View File

@@ -324,7 +324,6 @@ class SalePayment < ApplicationRecord
update_shift update_shift
end end
end end
end end
# update for cashier shift # update for cashier shift

View File

@@ -17,5 +17,4 @@ if (menu.menu_categories)
end end
end end
end end
end end

View File

@@ -1,44 +1,82 @@
# Format for attributes json # Format for attributes json
attr_format = [] attr_format = []
param_count = item.item_attributes.count
# Format for attributes json # Format for attributes json
if item.item_attributes.count > 0
item.item_attributes.each do|attr_id| item.item_attributes.each do|attr_id|
menu_attr = MenuItemAttribute.find(attr_id) menu_attr = MenuItemAttribute.find(attr_id)
if attr_format.count == 0 if attr_format.count == 0
attr_format.push({ type: menu_attr.attribute_type, value: [] }) attr_format.push({ type: menu_attr.attribute_type, values: [menu_attr.name] })
next
end end
attr_format.each do |af| attr_format.each do |af|
if menu_attr.attribute_type.in? attr_format.map {|k| k[:type]}
if menu_attr.attribute_type == af[:type] if menu_attr.attribute_type == af[:type]
af[:value].push(menu_attr.value) af[:values].push(menu_attr.name)
end
else else
new_attr = {type: menu_attr.attribute_type, value: [ menu_attr.value ] } new_attr = {type: menu_attr.attribute_type, values: [ menu_attr.name ] }
attr_format.push(new_attr) attr_format.push(new_attr)
break
end
end
end
end end
break if attr_format.count > param_count # Format for option json
opt_format = []
# Format for attributes json
if item.item_options.count > 0
item.item_options.each do|opt|
menu_opt = MenuItemOption.find(opt)
if opt_format.count == 0
opt_format.push({ type: menu_opt.option_type, values: [menu_opt.name] })
next
end end
param_count -= 1 opt_format.each do |of|
if menu_opt.option_type.in? opt_format.map {|k| k[:type]}
if menu_opt.option_type == of[:type]
of[:values].push(menu_opt.name)
end
else
new_opt = {type: menu_opt.option_type, values: [ menu_opt.name ] }
opt_format.push(new_opt)
break
end
end
end
end end
#Menu Item Information #Menu Item Information
json.id item.id json.id item.id
json.item_code item.item_code json.code item.item_code
json.name item.name json.name item.name
json.alt_name item.alt_name json.alt_name item.alt_name
json.image item.image_path.url json.image item.image_path.url
json.description item.description json.description item.description
json.Information item.information json.information item.information
json.type item.type json.type item.type
json.account_id item.account_id json.account_id item.account_id
json.min_qty item.min_qty json.min_qty item.min_qty
json.is_available item.is_available json.is_available item.is_available
json.is_sub_item item.is_sub_item json.is_sub_item item.is_sub_item
json.unit item.unit json.unit item.unit
json.item_sets item.item_sets
# Item Sets of Menu Item
json.item_sets item.item_sets do |its|
json.id its.id
json.name its.name
json.alt_name its.alt_name
json.min_selectable_qty its.min_selectable_qty
json.max_selectable_qty its.max_selectable_qty
json.instances its.menu_item_instances do |i|
json.id i.id
end
end
json.attributes attr_format json.attributes attr_format
json.options item.item_options json.options opt_format
# json.min_selectable_item item.min_selectable_item # json.min_selectable_item item.min_selectable_item
# json.max_selectable_item item.max_selectable_item # json.max_selectable_item item.max_selectable_item
@@ -52,6 +90,7 @@ json.options item.item_options
# json.item_attributes = item_instance.item_attributes # json.item_attributes = item_instance.item_attributes
json.instances item.menu_item_instances do |is| json.instances item.menu_item_instances do |is|
json.id is.id
json.code is.item_instance_code json.code is.item_instance_code
json.name is.item_instance_name json.name is.item_instance_name
json.price is.price json.price is.price
@@ -59,8 +98,8 @@ json.options item.item_options
json.is_default is.is_default json.is_default is.is_default
json.is_on_promotion is.is_on_promotion json.is_on_promotion is.is_on_promotion
json.promotion_price is.promotion_price json.promotion_price is.promotion_price
json.item_attributes is.item_attributes json.values is.item_attributes
json.item_sets is.item_sets # json.item_sets is.item_sets
end end
#Child Menu items #Child Menu items

View File

@@ -1,4 +1,4 @@
json.array! @menus do |menu| menu_json = json.array! @menus do |menu|
json.id menu.id json.id menu.id
json.name menu.name json.name menu.name
json.valid_days menu.valid_days json.valid_days menu.valid_days
@@ -12,3 +12,4 @@ json.array! @menus do |menu|
# end # end
# end # end
end end

View File

@@ -169,6 +169,7 @@
if(cardNo.length == 16){ if(cardNo.length == 16){
$("#paypar_account_no").val(cardNo); $("#paypar_account_no").val(cardNo);
$("#search").val(cardNo); $("#search").val(cardNo);
$("#type").val("card");
} }
} }
</script> </script>

View File

@@ -25,6 +25,7 @@
<%= form_tag crm_customers_path, :id => "filter_form", :method => :get do %> <%= form_tag crm_customers_path, :id => "filter_form", :method => :get do %>
<div class="input-append col-md-7 form-group pull-left"> <div class="input-append col-md-7 form-group pull-left">
<input type="text" name="filter" style="margin-right:10px" placeholder="Search" id="search" class="form-control input-xs col-md-9"> <input type="text" name="filter" style="margin-right:10px" placeholder="Search" id="search" class="form-control input-xs col-md-9">
<input type="hidden" name="type" id="type" value="">
<button type="submit" class="btn btn-primary btn-md">Search</button> <button type="submit" class="btn btn-primary btn-md">Search</button>
<!-- <a href="modal-window" data-toggle= "modal" data-target="#modal-window" class="btn btn-primary btn-md" id="card_read" >Read Card</a> --> <!-- <a href="modal-window" data-toggle= "modal" data-target="#modal-window" class="btn btn-primary btn-md" id="card_read" >Read Card</a> -->

View File

@@ -50,48 +50,6 @@
</div> </div>
</div> </div>
<!-- Large modal -->
<button class="btn btn-primary" data-toggle="modal" data-target=".sx_item_detailModal">Large modal</button>
<div class="modal fade sx_item_detailModal" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header" style="background-color: #54A5AF;">
<h4 class="modal-title" style="color:#fff;" id="title_name"></h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" style="font-size: 20px;color:#fff;">&times;</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-5">
<%= image_tag "logo.png" ,width: '', height: '', :style => '' %>
<br><br>
<div class="form-group">
<h4 class="col-md-12">Quantity</h4>
<input type="number" name="qty" class="form-control col-md-12 input-number" id="modal-qty" value="" min="1" max="100">
</div>
<div class="form-group row">
<h4 class="col-md-6">Total</h4>
<h4 class="col-md-6" id="total_price"> 2500 Ks</h4>
</div>
</div>
<div class="col-md-7">
<h4>Options</h4>
<h4>Attributes</h4>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal" id="close">Close</button>
<button type="button" class="btn btn-success" data-dismiss="modal" id="save_order">Add Order</button>
</div>
</div>
</div>
</div>
<!-- Modal --> <!-- Modal -->
<div class="modal fade" id="sx_itemModal" tabindex="-1" role="dialog" aria-labelledby="sx_itemModalLabel" aria-hidden="true"> <div class="modal fade" id="sx_itemModal" tabindex="-1" role="dialog" aria-labelledby="sx_itemModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
@@ -130,6 +88,51 @@
</div> </div>
</div> </div>
<!-- Large modal -->
<div class="modal fade sx_item_detailModal" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header" style="background-color: #54A5AF;">
<h4 class="modal-title" style="color:#fff;" id="title_name"></h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" style="font-size: 20px;color:#fff;">&times;</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-5">
<%= image_tag "logo.png" ,width: '', height: '', :style => '' %>
<br><br>
<div class="form-group">
<h4 class="col-md-12">Quantity</h4>
<input type="number" name="qty" class="form-control col-md-12 input-number change_qty" id="change_qty" value="" min="1" max="100">
</div>
<div class="form-group row">
<h4 class="col-md-6">Total</h4>
<h4 class="col-md-6" id="total_price"></h4>
<p class="hidden" id="unit_price"></p>
</div>
</div>
<div class="col-md-7 item-detail">
<div class="hide attr-alert alert-danger" role="alert">
<strong>Oh !</strong>Have not attribute for this item Please select another attribute .
</div>
<div class="attributes-list">
</div>
<div class="option-list">
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal" id="close">Close</button>
<button type="button" class="btn btn-success add_to_order" data-dismiss="modal" id="add_to_order">Add to Order</button>
</div>
</div>
</div>
</div>
<script type="text/javascript"> <script type="text/javascript">
$(function(){ $(function(){
@@ -142,6 +145,13 @@ $(function(){
}); });
//End menu category Click //End menu category Click
$(".change_qty").change(function(){
qty = $(this).val();
price = $("#unit_price").text();
$("#total_price").text(qty*price);
});
//show menu item list when click menu category //show menu item list when click menu category
function show_menu_item_list(url_item){ function show_menu_item_list(url_item){
var menu_list = $('.menu_items_list'); var menu_list = $('.menu_items_list');
@@ -154,43 +164,36 @@ $(function(){
data: {}, data: {},
dataType: "json", dataType: "json",
success: function(data) { success: function(data) {
console.log(data);
var menu_items_list = $('.menu_items_list'); var menu_items_list = $('.menu_items_list');
menu_items_list.empty(); menu_items_list.empty();
menu_items = data.menu_items; menu_items = data.menu_items;
console.log(data);
for(var field in menu_items) { for(var field in menu_items) {
instances = menu_items[field].instances ;
var code = menu_items[field].instances[0].code $(instances).each(function(i){
var name = menu_items[field].instances[0].name if (instances[i].is_default === true) {
var price = parseFloat(menu_items[field].instances[0].price).toFixed(2); code = instances[i].code;
var is_available = menu_items[field].instances[0].is_available name = instances[i].name;
var is_on_promotion = menu_items[field].instances[0].is_on_promotion price = parseFloat(instances[i].price).toFixed(2);
var item_attributes = menu_items[field].instances[0].item_attributes is_available = instances[i].is_available ;
var promotion_price = menu_items[field].instances[0].promotion_price is_on_promotion = instances[i].is_on_promotion;
item_attributes = instances[i].values;
promotion_price = instances[i].promotion_price;
code = instances[i].code;
}
});
row = '<div class="card">' row = '<div class="card">'
+'<div class="card-head" style="line-height:14px;">' +'<div class="card-head" style="line-height:14px;">'
+'<small class="col-md-9">'+ menu_items[field].name +'</small>' +'<small class="col-md-9">'+ menu_items[field].name +'</small>'
+'<div class="col-md-3 add_icon"' +"<div class='col-md-3 add_icon' data-item-code='"+ menu_items[field].code +"' data-name='"+ menu_items[field].name +"' data-price = '"+ price +"' data-instance-code = '"+ code +"' data-instance = '"+ name +"' data-promotion-price = '"+ promotion_price +"' data-attributes = '"+ JSON.stringify(item_attributes) +"'>"
+'data-id="'+ menu_items[field].name +'"'
+'data-item-code="'+ menu_items[field].item_code +'"'
+'data-name="'+ menu_items[field].name +'"'
+'data-price="'+ price +'"'
+'data-available="'+ is_available +'"'
+'data-promotion="'+ is_on_promotion +'"'
+'data-attributes="'+ item_attributes +'"'
+'data-instance-code="'+ code +'"'
+'data-instance="'+ name +'"'
+'data-promotion-price="'+ promotion_price +'"'
+'>'
+'<i class="fa fa-plus "' +'<i class="fa fa-plus "'
+ 'style="margin-top:4px;">' + 'style="margin-top:4px;">'
+'</i></div>' +'</i></div>'
+'</div>' +'</div>'
+'<div class="menu_item_box" data-toggle="modal" data-target=".sx_item_detailModal">' +"<div class='menu_item_box' data-instance = '"+JSON.stringify(menu_items[field].instances)+"' data-id = '"+JSON.stringify(menu_items[field].attributes)+"' data-item = '"+JSON.stringify(item_attributes)+"' data-toggle='modal' data-target='.sx_item_detailModal'>"
+'<div class="card-block">' +'<div class="card-block">'
+'<%= image_tag "logo.png" ,width: '75', height: '75', :style => '' %>' +'<%= image_tag "logo.png" ,width: '75', height: '75', :style => '' %>'
+'</div>' +'</div>'
@@ -206,7 +209,115 @@ $(function(){
}); });
//end Ajax //end Ajax
} }
//end show detail function //end show list function
//click item row for add order
$(document).on('click', '.menu_item_box', function(event){
$('.attributes-list').empty();
$('.attr-alert').addClass('hide');
data = $(this).parent().children().children('.add_icon');
attributes = $(this).data('id');
selected_item = $(this).data('item');
instances = $(this).data('instance');
for(var field in attributes) {
value = attributes[field]["values"];
type = attributes[field]["type"]
row = "<h4>"+attributes[field]["type"]+"</h4>"
$(value).each(function(i){
status ="";
if(parseInt(jQuery.inArray(value[i], selected_item))!== -1){
status = "selected-option";
}
row +="<button id='selected-option' data-instances='"+JSON.stringify(instances)+"' data-type='"+type+"' data-value='"+value[i]+"' class='btn btn-default attribute_btn "+ status +" "+ type +" '>"+value[i]+"</button>";
});
$(".attributes-list").append(row);
}
$('#change_qty').val(1);
$('#title_name').text(data.attr('data-name'));
$('#item_code').text(data.attr('data-item-code'));
$('#total_price').text(data.attr('data-price'));
$('#unit_price').text(data.attr('data-price'));
});
// click select option icon for add
$(document).on('click', '.attribute_btn', function(event){
value = $(this).data('value');
type = $(this).data('type');
instances = $(this).data('instances');
console.log(instances);
if ($(".attribute_btn").attr("data-type")==type){
$('.'+type).removeClass("selected-option");
}
$(this).addClass('selected-option');
selected_item = $('.selected-option').text();
qty = $('#change_qty').val();
total_price = 0;
for(var field in instances) {
item_attr = instances[field].values;
if(parseInt(jQuery.inArray(selected_item, item_attr))!== -1){
unit_price = instances[field].price
total_price = qty * unit_price
$('#instance_name').text(instances[field].name);
$('#instance_code').text(instances[field].code);
$('#promotion_price').text(instances[field].promotion_price);
$('#total_price').text(total_price);
$('#unit_price').text(unit_price);
}
}
if (total_price == 0) {
$('.attr-alert').removeClass('hide');
$('#total_price').text(total_price);
}else{
$('.attr-alert').addClass('hide');
$('#total_price').text(total_price);
}
}); //End selecct attribute buttom
// click add order
$(document).on('click', '.add_to_order', function(event){
total_price = $('#total_price').text();
unit_price = $('#unit_price').text();
qty = $('#change_qty').val();
var item_row = $('.selected-option');
var arr = [];
var attribute_arr = [];
$(item_row).each(function(i){
value = $(item_row[i]).attr('data-value');
arr = {value};
});
console.log(arr);
if(total_price > 0){
$('.add_to_order').attr('data-item-code',$('#item_code').text());
$('.add_to_order').attr('data-name',$('#title_name').text());
$('.add_to_order').attr('data-price',unit_price);
$('.add_to_order').attr('data-instance-code',$('#instance_code').text());
$('.add_to_order').attr('data-instance',$('#instance_name').text());
$('.add_to_order').attr('data-promotion-price',$('#promotion_price').text());
$('.add_to_order').attr('data-attributes',$('#instance_name').text());
var item_data = $(this);
show_item_detail(item_data);
calculate_sub_total();
}else{
$.alert({
title: 'Alert!',
content: 'Please select another item',
type: 'red',
typeAnimated: true,
btnClass: 'btn-danger',
});
}
}); //End Add Icon Click
// click plus icon for add // click plus icon for add
$(document).on('click', '.add_icon', function(event){ $(document).on('click', '.add_icon', function(event){
@@ -219,9 +330,9 @@ $(function(){
qty = 1; qty = 1;
append = 0; append = 0;
price = parseFloat(data.attr('data-price')).toFixed(2); price = parseFloat(data.attr('data-price')).toFixed(2);
instance_code = data.attr('data-instance'); instance_name = data.attr('data-instance');
if (instance_code == "undefined"){ if (instance_name == "undefined"){
instance = ''; instance = '';
}else{ }else{
instance = "("+data.attr('data-instance')+")"; instance = "("+data.attr('data-instance')+")";
@@ -231,11 +342,13 @@ $(function(){
var item_row = $('.summary-items tbody tr'); var item_row = $('.summary-items tbody tr');
$(item_row).each(function(i){ $(item_row).each(function(i){
if ($(item_row[i]).attr('data-code') == data.attr('data-item-code')) { item_code = $(item_row[i]).attr('data-code');
instance_code = $(item_row[i]).attr('data-instance-code');
if (item_code == data.attr('data-item-code') && instance_code == data.attr('data-instance-code')) {
qty = parseInt($(item_row[i]).children('#item_qty').text()) +1; qty = parseInt($(item_row[i]).children('#item_qty').text()) +1;
$(item_row[i]).children('#item_qty').text(qty); $(item_row[i]).children('#item_qty').text(qty);
parseFloat($(item_row[i]).children('#item_price').text(price*qty)).toFixed(2); parseFloat($(item_row[i]).children('#item_price').text(price*qty)).toFixed(2);
append = 1; append = 1;
}else{ }else{
qty = 1; qty = 1;
@@ -243,7 +356,7 @@ $(function(){
}); });
if (append===0) { if (append===0) {
row ="<tr class='item_box' data-price ='"+price+ "'data-toggle='modal' data-target='#sx_itemModal' 'data-instance ='"+instance+ "'data-code='"+data.attr('data-item-code')+"'>" row ="<tr class='item_box' data-price ='"+price+ "'data-toggle='modal' data-target='#sx_itemModal' 'data-instance ='"+instance+ "' data-code='"+data.attr('data-item-code')+"' data-instance-code='"+data.attr('data-instance-code')+"' data-attributes='"+data.attr('data-attributes')+"'>"
+'<td class="item-cell-no">'+rowCount+'</td>' +'<td class="item-cell-no">'+rowCount+'</td>'
+'<td class="item-cell-name" id="item_name" >' + data.attr('data-name')+ ' ' + instance +'</td>' +'<td class="item-cell-name" id="item_name" >' + data.attr('data-name')+ ' ' + instance +'</td>'
+'<td class="item-cell-qty" id="item_qty">' + qty + '</td>' +'<td class="item-cell-qty" id="item_qty">' + qty + '</td>'
@@ -253,7 +366,6 @@ $(function(){
+'</tr>'; +'</tr>';
$(".summary-items tbody").append(row); $(".summary-items tbody").append(row);
} }
} }
//click item row for update qty //click item row for update qty
@@ -265,14 +377,6 @@ $(function(){
$('#modal-qty').val(qty); $('#modal-qty').val(qty);
}); });
//click item row for update qty
$(document).on('click', '.menu_item_box', function(event){
data = $(this).parent().children().children('.add_icon');
$('#title_name').text(data.attr('data-name'));
console.log(data);
});
//click remove buttom in modal box //click remove buttom in modal box
$('#sx_itemModal').on('click','#remove', function(){ $('#sx_itemModal').on('click','#remove', function(){
$('.summary-items tr').filter(function(){ $('.summary-items tr').filter(function(){
@@ -321,7 +425,6 @@ $(function(){
function summary_items_filter(){ function summary_items_filter(){
$('.summary-items tr').filter(function(){ $('.summary-items tr').filter(function(){
if ($(this).attr('data-active') == 'true'){ if ($(this).attr('data-active') == 'true'){
qty = $('#modal-qty').val(); qty = $('#modal-qty').val();
price = parseFloat($(this).attr('data-price')); price = parseFloat($(this).attr('data-price'));
@@ -406,6 +509,17 @@ $(function(){
padding-top: 100px; padding-top: 100px;
} }
.selected-option {
color: #fff !important;
background-color: green !important;
}
.attribute_btn {
white-space: normal !important;
height: 60px;
width: 90px;
margin-bottom: 5px;
margin-right: 5px;
}
</style> </style>

View File

@@ -22,6 +22,7 @@
<%= form_tag path, :id => "filter_form", :method => :get do %> <%= form_tag path, :id => "filter_form", :method => :get do %>
<div class="input-append col-md-7 form-group pull-left"> <div class="input-append col-md-7 form-group pull-left">
<input type="text" name="filter" style="margin-right:10px" id="search" placeholder="Search" class="form-control input-sm col-md-9"> <input type="text" name="filter" style="margin-right:10px" id="search" placeholder="Search" class="form-control input-sm col-md-9">
<input type="hidden" name="type" id="type" value="">
<button type="submit" class="btn btn-primary btn-sm">Search</button> <button type="submit" class="btn btn-primary btn-sm">Search</button>
</div> </div>
<% end %> <% end %>
@@ -258,13 +259,24 @@
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: "get_customer" , url: "get_customer" ,
data: { filter : customer_mamber_card_no }, data: { filter : customer_mamber_card_no ,type :"card"},
dataType: "json", dataType: "json",
success: function(data) { success: function(data) {
if (data[0].customer_id == false) {
$.alert({
title: 'Alert!',
content: data[0].message,
type: 'red',
typeAnimated: true,
btnClass: 'btn-danger',
});
}else{
customer_id = data[0].customer_id; customer_id = data[0].customer_id;
customer_name = data[0].name; customer_name = data[0].name;
update_sale(customer_id, customer_name,sale_id); update_sale(customer_id, customer_name,sale_id);
} }
}
}); });
} }
},100); },100);
@@ -282,6 +294,7 @@
if(cardNo.length == 16){ if(cardNo.length == 16){
$("#paypar_account_no").val(cardNo); $("#paypar_account_no").val(cardNo);
$("#search").val(cardNo); $("#search").val(cardNo);
$("#type").val("card")
} }
} }

View File

@@ -6,6 +6,7 @@ class CreateOrderItems < ActiveRecord::Migration[5.1]
t.string :order_item_status, :null => false, :default => "new" t.string :order_item_status, :null => false, :default => "new"
t.string :item_order_by #person who order this t.string :item_order_by #person who order this
t.string :item_code, :null => false t.string :item_code, :null => false
t.string :item_instance_code
t.string :item_name, :null => false t.string :item_name, :null => false
t.string :alt_name, :null => false t.string :alt_name, :null => false
t.integer :account_id, :limit => 8, :null => false, :default => 1 t.integer :account_id, :limit => 8, :null => false, :default => 1

View File

@@ -218,25 +218,26 @@ zone3 = Zone.create({id:3, name: "H3", is_active:true, created_by: "SYSTEM DEFAU
table = Table.create({name:"77", zone: zone3, status:"available", seater: 2 , order_by:1, created_by:"SYSTEM DEFAULT"}) table = Table.create({name:"77", zone: zone3, status:"available", seater: 2 , order_by:1, created_by:"SYSTEM DEFAULT"})
table = Table.create({name:"78", zone: zone3, status:"available", seater: 2 , order_by:1, created_by:"SYSTEM DEFAULT"}) table = Table.create({name:"78", zone: zone3, status:"available", seater: 2 , order_by:1, created_by:"SYSTEM DEFAULT"})
member_setting = MembershipSetting.create({membership_type:"paypar_url",gateway_url: "http://staging.membership.paypar.ws",merchant_account_id:"vWSsseoZCzxd6xcNf_uS"}) member_setting = MembershipSetting.create({membership_type:"paypar_url",gateway_url: "http://staging.membership.paypar.ws",merchant_account_id:"RxzaYyAGzm7VqAZ4hKnv"})
member_actions= MembershipAction.create([{membership_type:"get_account_balance",gateway_url:"/api/membership_campaigns/get_correspond_account_data",additional_parameter:{campaign_type_id:1},merchant_account_id:"vWSsseoZCzxd6xcNf_uS",auth_token:"code2lab"}, member_actions= MembershipAction.create([{membership_type:"get_account_balance",gateway_url:"/api/membership_campaigns/get_correspond_account_data",additional_parameter:{campaign_type_id:1},merchant_account_id:"RxzaYyAGzm7VqAZ4hKnv",auth_token:"code2lab"},
{membership_type:"redeem",gateway_url:"/api/membership_campaigns/redeem",additional_parameter:{campaign_type_id:1},merchant_account_id:"vWSsseoZCzxd6xcNf_uS",auth_token:"code2lab"}, {membership_type:"redeem",gateway_url:"/api/membership_campaigns/redeem",additional_parameter:{campaign_type_id:1},merchant_account_id:"RxzaYyAGzm7VqAZ4hKnv",auth_token:"code2lab"},
{membership_type:"create_membership_customer",gateway_url:"/api/generic_customer/create_membership_customer",merchant_account_id:"vWSsseoZCzxd6xcNf_uS",auth_token:"code2lab"}, {membership_type:"create_membership_customer",gateway_url:"/api/generic_customer/create_membership_customer",merchant_account_id:"RxzaYyAGzm7VqAZ4hKnv",auth_token:"code2lab"},
{membership_type:"update_membership_customer",gateway_url:"/api/generic_customer/update_membership_customer",merchant_account_id:"vWSsseoZCzxd6xcNf_uS",auth_token:"code2lab"}, {membership_type:"update_membership_customer",gateway_url:"/api/generic_customer/update_membership_customer",merchant_account_id:"RxzaYyAGzm7VqAZ4hKnv",auth_token:"code2lab"},
{membership_type:"get_all_member_group",gateway_url:"/api/member_group/get_all_member_group",merchant_account_id:"vWSsseoZCzxd6xcNf_uS",auth_token:"code2lab"}, {membership_type:"get_all_member_group",gateway_url:"/api/member_group/get_all_member_group",merchant_account_id:"RxzaYyAGzm7VqAZ4hKnv",auth_token:"code2lab"},
{membership_type:"rebate",gateway_url:"/api/membership_campaigns/rebate",additional_parameter:{campaign_type_id:1},merchant_account_id:"vWSsseoZCzxd6xcNf_uS",auth_token:"code2lab"}, {membership_type:"rebate",gateway_url:"/api/membership_campaigns/rebate",additional_parameter:{campaign_type_id:1},merchant_account_id:"RxzaYyAGzm7VqAZ4hKnv",auth_token:"code2lab"},
{membership_type:"get_all_member_account",gateway_url:"/api/generic_customer/get_membership_data",merchant_account_id:"vWSsseoZCzxd6xcNf_uS",auth_token:"code2lab"}, {membership_type:"get_all_member_account",gateway_url:"/api/generic_customer/get_membership_data",merchant_account_id:"RxzaYyAGzm7VqAZ4hKnv",auth_token:"code2lab"},
{membership_type:"get_member_transactions",gateway_url:"/api/generic_customer/get_membership_transactions",merchant_account_id:"vWSsseoZCzxd6xcNf_uS",auth_token:"code2lab"}, {membership_type:"get_member_transactions",gateway_url:"/api/generic_customer/get_membership_transactions",merchant_account_id:"RxzaYyAGzm7VqAZ4hKnv",auth_token:"code2lab"},
{membership_type:"member_discount",gateway_url:"/api/membership_campaigns/discount",additional_parameter:{campaign_type_id:6},merchant_account_id:"vWSsseoZCzxd6xcNf_uS",auth_token:"code2lab"}, {membership_type:"member_discount",gateway_url:"/api/membership_campaigns/discount",additional_parameter:{campaign_type_id:6},merchant_account_id:"RxzaYyAGzm7VqAZ4hKnv",auth_token:"code2lab"},
{membership_type:"get_member_campaign",gateway_url:"/api/membership_campaigns/get_member_campaign",additional_parameter:{campaign_type_id:6},merchant_account_id:"vWSsseoZCzxd6xcNf_uS",auth_token:"code2lab"}, {membership_type:"get_member_campaign",gateway_url:"/api/membership_campaigns/get_member_campaign",additional_parameter:{campaign_type_id:6},merchant_account_id:"RxzaYyAGzm7VqAZ4hKnv",auth_token:"code2lab"},
{membership_type:"search_paypar_account_no",gateway_url:"/api/generic_customer/get_membership_customer_data",merchant_account_id:"RxzaYyAGzm7VqAZ4hKnv",auth_token:"code2lab"}
]) ])
payment_methods = PaymentMethodSetting.create({payment_method:"MPU",gateway_url: "http://membership.paypar.ws"}) payment_methods = PaymentMethodSetting.create({payment_method:"MPU",gateway_url: "http://membership.paypar.ws"})
payment_methods = PaymentMethodSetting.create({payment_method:"VISA",gateway_url: "http://membership.paypar.ws"}) payment_methods = PaymentMethodSetting.create({payment_method:"VISA",gateway_url: "http://membership.paypar.ws"})
payment_methods = PaymentMethodSetting.create({payment_method:"JCB",gateway_url: "http://membership.paypar.ws"}) payment_methods = PaymentMethodSetting.create({payment_method:"JCB",gateway_url: "http://membership.paypar.ws"})
payment_methods = PaymentMethodSetting.create({payment_method:"Master",gateway_url: "http://membership.paypar.ws"}) payment_methods = PaymentMethodSetting.create({payment_method:"Master",gateway_url: "http://membership.paypar.ws"})
payment_methods = PaymentMethodSetting.create({payment_method:"Redeem",gateway_url: "http://membership.paypar.ws",merchant_account_id:"vWSsseoZCzxd6xcNf_uS"}) payment_methods = PaymentMethodSetting.create({payment_method:"Redeem",gateway_url: "http://membership.paypar.ws",merchant_account_id:"RxzaYyAGzm7VqAZ4hKnv"})
#Default Order Queue stations #Default Order Queue stations
order_queue_station1 = OrderQueueStation.create({station_name: "K1", is_active: true,printer_name: "Cashier", 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_station1 = OrderQueueStation.create({station_name: "K1", is_active: true,printer_name: "Cashier", processing_items: JSON.generate(['01001','01002','01003','01004']), print_copy:true, cut_per_item: false, use_alternate_name: false, created_by: "SYSTEM DEFAULT"})