diff --git a/app/assets/javascripts/qrammer.js.coffee b/app/assets/javascripts/qrammer.js.coffee index a4c1dc01..80dfe417 100644 --- a/app/assets/javascripts/qrammer.js.coffee +++ b/app/assets/javascripts/qrammer.js.coffee @@ -19,36 +19,10 @@ root.Qrammer = wrapper.modal() currency: (num) -> num = 0.0 if isNaN(num) || num == '' || num == null - '€ ' + parseFloat(num).toFixed(2) - add_product: (product) -> - window.active_products_list = {} unless window.active_products_list - window.active_products_list[product._id] = {product: product, number: 0} unless window.active_products_list[product._id] - window.active_products_list[product._id].number += 1 - Qrammer.build_product_list() - build_product_list: -> - table = $('#active-order-table') - tbody = table.find('tbody') - tbody = $('').appendTo(table) unless tbody.length - tbody.find('tr').remove() - total = 0.0 - for product_id, info of window.active_products_list - total += info.product.price * info.number - row = $('').attr('id', 'active-order-row-'+product_id).appendTo(tbody) - row.append(''+info.product.name+'') - row.append(''+info.number+'') - row.append(''+Qrammer.currency(info.product.price * info.number)+'') - x_btn = $('').click(-> delete(window.active_products_list[product_id]) && Qrammer.build_product_list() ) - row.append($('').append(x_btn)) - $('#active-order-total').html(Qrammer.currency(total)) - table.show() + '€ ' + parseFloat(num).toFixed(2) clear_active_list: -> window.active_products_list = {} $('#active-order-table').hide() - order_active_products_list: (post_uri)-> - h = {list_id: active_list_id} - for product_id, info of window.active_products_list - h['products['+product_id+']'] = info.number - $.post(post_uri, h, ((res) -> Qrammer.handle_response(res)), 'json') handle_response: (res) -> if(typeof(res) == 'string') return unless res.length @@ -97,38 +71,6 @@ root.Qrammer = #foot.append(''+Qrammer.currency(res.total_amount)+''); ) - handle_active_user_list: (callback) -> - $.get('/user/list_info.json', (res) -> - if !res.list_active - window.location = '/phone_home?list_closed=true' - return - window.active_list = res - callback.call() if callback - Qrammer.handle_active_user_list_default_actions() - ) - handle_active_user_list_default_actions: -> - Qrammer.list_needs_payment_default_action() - Qrammer.list_needs_help_default_action() - list_needs_help_default_action: -> - needs_help_container = $('#list-needs-help-button') - if needs_help_container.length - if window.active_list.needs_help - needs_help_container.html('') - else - needs_help_container.html($('').click(Qrammer.list_needs_help)) #TODO TEXT - list_needs_help: -> - return unless window.active_list && !window.active_list.needs_help - $.post('/user/needs_help.json', (res) -> window.active_list = res; Qrammer.list_needs_help_default_action()) - list_needs_payment_default_action: -> - needs_payment_container = $('#list-needs-payment-button') - if needs_payment_container.length - if window.active_list.needs_payment - needs_payment_container.html('') - else - needs_payment_container.html($('').click(Qrammer.list_needs_payment)) #TODO TEXT - list_needs_payment: -> - return unless window.active_list && !window.active_list.needs_payment - $.post('/user/list_needs_payment.json', (res) -> window.active_list = res; Qrammer.list_needs_payment_default_action()) load_active_lists: () -> $.get('/supplier/active_lists.json', (res) -> @@ -167,33 +109,6 @@ root.Qrammer = row.append(td_buttons) #foot.append(''+Qrammer.currency(res.total_amount)+''); ) - active_user_list: (list_id) -> - $.get('/user/active_list.json', (res) -> - window.active_list = res - unless res.list_active - window.location = '/user/list_history/'+res._id + '?list_closed=true' - return - Qrammer.handle_active_user_list_default_actions() - body = $('#active-list-table tbody') - foot = $('#active-list-table tfoot') - body.find('tr').remove() - foot.find('tr').remove() - if !res.orders && !res.orders.length - alert('No orders in list') - return - for order in res.orders - order_txts = [] - row = $('').appendTo(body) - row.addClass(order.state) - #if(order.state == 'placed') row.addClass('info'); - #if(order.state == 'delivered') row.addClass('success'); - row.addClass('error') if order.state == 'cancelled' - for product in order.products - order_txts.push(product.name + ' (' + product['number'] + ')') - row.append($('').text(order_txts.join(', '))) - row.append($('').html(Qrammer.currency(order.total_amount))) - foot.append(''+Qrammer.currency(res.total_amount)+'') - ) build_product_list_as_modal: -> wrapper = $('') diff --git a/app/assets/javascripts/quser.js.coffee b/app/assets/javascripts/quser.js.coffee new file mode 100644 index 00000000..08ce0633 --- /dev/null +++ b/app/assets/javascripts/quser.js.coffee @@ -0,0 +1,126 @@ +root = exports ? this +root.Quser= + handle_active_list: (callback) -> + $.get('/user/list_info.json', (res) -> + if !res.list_active + window.location = '/phone_home?list_closed=true' + return + window.active_list = res + callback.call() if callback + Quser.handle_active_list_default_actions() + ) + handle_active_list_default_actions: -> + Quser.list_needs_payment_default_action() + Quser.list_needs_help_default_action() + list_needs_help_default_action: -> + needs_help_container = $('#list-needs-help-button') + if needs_help_container.length + if window.active_list.needs_help + needs_help_container.html('') + else + needs_help_container.html($('').click(Quser.list_needs_help)) #TODO TEXT + list_needs_help: -> + return unless window.active_list && !window.active_list.needs_help + $.post('/user/needs_help.json', (res) -> window.active_list = res; Quser.list_needs_help_default_action()) + list_needs_payment_default_action: -> + needs_payment_container = $('#list-needs-payment-button') + if needs_payment_container.length + if window.active_list.needs_payment + needs_payment_container.html('') + else + needs_payment_container.html($('').click(Quser.list_needs_payment)) #TODO TEXT + list_needs_payment: -> + return unless window.active_list && !window.active_list.needs_payment + $.post('/user/list_needs_payment.json', (res) -> window.active_list = res; Quser.list_needs_payment_default_action()) + load_active_list: () -> + $.get('/user/active_list.json', (res) -> + window.active_list = res + unless res.list_active + window.location = '/user/list_history/'+res._id + '?list_closed=true' + return + Quser.handle_active_list_default_actions() + body = $('#active-list-table tbody') + foot = $('#active-list-table tfoot') + body.find('tr').remove() + foot.find('tr').remove() + if !res.orders && !res.orders.length + alert('No orders in list') + return + for order in res.orders + order_txts = [] + row = $('').appendTo(body) + row.addClass(order.state) + #if(order.state == 'placed') row.addClass('info'); + #if(order.state == 'delivered') row.addClass('success'); + row.addClass('error') if order.state == 'cancelled' + for product in order.products + order_txts.push(product.name + ' (' + product['number'] + ')') + row.append($('').text(order_txts.join(', '))) + row.append($('').html(Qrammer.currency(order.total_amount))) + foot.append(''+Qrammer.currency(res.total_amount)+'') + ) + order_selected_products: ()-> + h = {list_id: active_list_id} + for product_id, info of window.active_products_list + h['products['+product_id+']'] = info.number + $.post('/user/order_selected_products', h, ((res) -> Qrammer.handle_response(res)), 'json') + build_product_list: -> + table = $('#active-order-table') + tbody = table.find('tbody') + tbody = $('').appendTo(table) unless tbody.length + tbody.find('tr').remove() + total = 0.0 + for product_id, info of window.active_products_list + total += info.product.price * info.number + row = $('').attr('id', 'active-order-row-'+product_id).appendTo(tbody) + row.append(''+info.product.name+'') + row.append(''+info.number+'') + row.append(''+Qrammer.currency(info.product.price * info.number)+'') + x_btn = $('').click(-> delete(window.active_products_list[product_id]) && Quser.build_product_list() ) + row.append($('').append(x_btn)) + $('#active-order-total').html(Qrammer.currency(total)) + table.show() + + load_active_list_products: -> + $.get('/user/list_products.json', (res) -> + window.products = res + body = $('#products-table tbody') + for category, products of window.products + body.append('

'+category+'

') + for product in products + row = $('') + button = $('') + callback = ((prod) -> + -> + product_count_holder = $('#order-product-count-'+prod._id) + count = parseInt(product_count_holder.text()) + product_count_holder.text(1) + Quser.add_product(prod, count) + )(product) + button.click(callback) + row.append(''+product.name+'') + order_product_count = $('1') + order_count_minus = $('-') + order_count_minus.click(-> + val_holder = $(this).siblings('.order-product-count') + val = parseInt(val_holder.text()) + val_holder.text(val - 1) if val > 1 + ) + order_count_plus = $('+') + order_count_plus.click(-> + val_holder = $(this).siblings('.order-product-count') + val = parseInt(val_holder.text()) + val_holder.text(val + 1) + ) + row.append($('').append(order_count_minus).append(' ').append(order_product_count).append(' ').append(order_count_plus)) + row.append(''+Qrammer.currency(product.price)+'') + row.append($('').append(button)) + body.append(row) + ) + + add_product: (product, count) -> + count ||= 1 + window.active_products_list = {} unless window.active_products_list + window.active_products_list[product._id] = {product: product, number: 0} unless window.active_products_list[product._id] + window.active_products_list[product._id].number += count + Quser.build_product_list() diff --git a/app/assets/stylesheets/phone/structure.css.sass b/app/assets/stylesheets/phone/structure.css.sass index e2a448ee..1a14a9ba 100644 --- a/app/assets/stylesheets/phone/structure.css.sass +++ b/app/assets/stylesheets/phone/structure.css.sass @@ -11,3 +11,9 @@ body margin-top: 4px margin-bottom: 6px padding-bottom: 0 + .order-product-count + width: 30px + text-align: right + margin-bottom: 0 + .order-count-cell + white-space: nowrap diff --git a/app/assets/stylesheets/structure.css.sass b/app/assets/stylesheets/structure.css.sass index 9fee012c..89ce440d 100644 --- a/app/assets/stylesheets/structure.css.sass +++ b/app/assets/stylesheets/structure.css.sass @@ -73,3 +73,7 @@ table margin-left: 5px i padding-left: 5px +#qr-list + list-style: none + margin: 0 + padding: 0 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f2a4fe4f..8a754bc5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,14 +1,23 @@ class ApplicationController < ActionController::Base + layout :layout_by_resource + protect_from_forgery private + def layout_by_resource + if devise_controller? + "phone" + else + "application" + end + end def check_active_list_state if session[:active_list_id] unless active_list.active? session[:active_list_id] = nil - redirect_to phone_root_path, alert: t('messages.the_list_has_been_closed', list: List.model_name.human) + redirect_to user_root_path, alert: t('messages.the_list_has_been_closed', list: List.model_name.human) end end @@ -18,6 +27,8 @@ class ApplicationController < ActionController::Base return nil unless session[:active_list_id].present? @active_list ||= List.find(session[:active_list_id]) end + alias :active_list_object :active_list + helper_method :active_list_object def js_alert(message) {ok: false, message: message}.to_json @@ -25,7 +36,4 @@ class ApplicationController < ActionController::Base def js_notice(message) {ok: true, message: message}.to_json end - - - helper_method :active_list end diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 2e1b2c9f..59ebb86a 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -4,10 +4,6 @@ class DashboardController < ApplicationController def home end - def phone_home - flash.now[:notice] = t('messages.the_list_has_been_closed', list: List.model_name.human) if params[:list_closed].present? - render layout: 'phone' - end # Testing action def select_qrcode @@ -15,41 +11,6 @@ class DashboardController < ApplicationController render layout: 'phone' end - def order_active_products_list - respond_to do |format| - format.html do - redirect_to(root_path, alert: t('messages.cannot_order_without_list_id')) and return if params[:list_id].blank? - @list = List.find(params[:list_id]) - redirect_to(root_path, alert: t('messages.cannot_order_on_non_active_list')) and return unless @list.active? - @list.place_order current_user, params[:products] - redirect_to root_path, notice: t('messages.order_is_placed') - end - format.js do - render js: js_alert(t('messages.cannot_order_without_list_id')) and return if params[:list_id].blank? - @list = List.find(params[:list_id]) - render js: js_alert(t('messages.cannot_order_on_non_active_list')) and return unless @list.active? - @list.place_order current_user, params[:products] - render js: js_notice( t('messages.order_is_placed') ) - end - end - end - - # GET /suppliers/1/product_list - # GET /suppliers/1/product_list.json - def product_list - @supplier = active_list.supplier - respond_to do |format| - format.html # show.html.erb - format.json do - products = active_list.supplier.products - products.include_relation(:product_categories) - products.sort_by!{|p| p.product_category.try(:position) || 90000} - h = products.inject({}){|h, p| n = p.product_category.try(:name) || 'other'; h[n] ||= []; h[n] << p; h} - render json: h - end - end - end - def supplier_home redirect_to active_orders_supplier_path(Supplier.first) diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index 7d220a4a..6f440a97 100644 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -3,6 +3,11 @@ class UserController < ApplicationController alias :list :active_list + def home + flash.now[:notice] = t('messages.the_list_has_been_closed', list: List.model_name.human) if params[:list_closed].present? + render layout: 'phone' + end + # POST /user/create_list {table_id: 1234} def create_list @table = Table.find(params[:table_id]) @@ -18,9 +23,22 @@ class UserController < ApplicationController end end + # GET /suppliers/1/product_list + # GET /suppliers/1/product_list.json def list_products - @supplier = Supplier.first - render layout: 'phone' + @supplier = list.supplier + respond_to do |format| + format.html do + render layout: 'phone' + end + format.json do + products = list.supplier.products + products.include_relation(:product_categories) + products.sort_by!{|p| p.product_category.try(:position) || 90000} + h = products.inject({}){|h, p| n = p.product_category.try(:name) || 'other'; h[n] ||= []; h[n] << p; h} + render json: h + end + end end # GET /user/current_list.json @@ -95,7 +113,9 @@ class UserController < ApplicationController ## # Displays the closed lists of the user + # GET /user/list_history def list_history + @lists = current_user.lists render layout: 'phone' end @@ -104,8 +124,31 @@ class UserController < ApplicationController # GET /user/list_history/:list_id def history_list @list = List.find(params[:list_id]) + if params[:list_closed].present? && session[:active_list_id] == @list.id + session[:active_list_id] = nil + flash.now[:notice] = t('messages.the_list_has_been_closed', list: List.model_name.human) + end redirect_to user_root_path, alert: t('messages.illegal_history_list_attempt') and return unless @list.user_ids.include?(current_user.id) render layout: 'phone' end + + def order_selected_products + respond_to do |format| + format.html do + redirect_to(root_path, alert: t('messages.cannot_order_without_list_id')) and return if params[:list_id].blank? + @list = List.find(params[:list_id]) + redirect_to(root_path, alert: t('messages.cannot_order_on_non_active_list')) and return unless @list.active? + @list.place_order current_user, params[:products] + redirect_to root_path, notice: t('messages.order_is_placed') + end + format.js do + render js: js_alert(t('messages.cannot_order_without_list_id')) and return if params[:list_id].blank? + @list = List.find(params[:list_id]) + render js: js_alert(t('messages.cannot_order_on_non_active_list')) and return unless @list.active? + @list.place_order current_user, params[:products] + render js: js_notice( t('messages.order_is_placed') ) + end + end + end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 17235e98..6c3667cc 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -18,6 +18,10 @@ module ApplicationHelper t('helpers.links.are_you_sure') end + def active_list + active_list_object + end + def list_open? session[:active_list_id].present? end diff --git a/app/views/dashboard/home.html.slim b/app/views/dashboard/home.html.slim index ae518566..83590aa8 100644 --- a/app/views/dashboard/home.html.slim +++ b/app/views/dashboard/home.html.slim @@ -1,5 +1,5 @@ .phone-wrapper -iframe.phone-content-frame src=phone_root_path +iframe.phone-content-frame src=user_root_path .tablet-wrapper iframe.tablet-content-frame src=supplier_root_path diff --git a/app/views/dashboard/select_qrcode.html.slim b/app/views/dashboard/select_qrcode.html.slim index 90ce26cc..00a5b09b 100644 --- a/app/views/dashboard/select_qrcode.html.slim +++ b/app/views/dashboard/select_qrcode.html.slim @@ -1,4 +1,4 @@ .page-header= title 'Select Qr code' -ul +ul#qr-list - for table in @tables li= link_to image_tag(url_for(qrcode_table_path(table, format: :png))), user_create_list_path(table_id: table.id) diff --git a/app/views/layouts/phone.html.slim b/app/views/layouts/phone.html.slim index 9e7e84ed..bbeb712f 100644 --- a/app/views/layouts/phone.html.slim +++ b/app/views/layouts/phone.html.slim @@ -28,9 +28,11 @@ html lang="en" span.icon-bar span.icon-bar span.icon-bar - a.brand href=phone_root_path Qrammer + a.brand href=user_root_path Qrammer .container.nav-collapse ul.nav#top-navigation-list + - if list_open? + li= link_to 'Move table', '#' li= link_to 'View history', user_history_path .container diff --git a/app/views/user/active_list.html.slim b/app/views/user/active_list.html.slim index 7cd13b3a..d77a2be3 100644 --- a/app/views/user/active_list.html.slim +++ b/app/views/user/active_list.html.slim @@ -13,6 +13,6 @@ table#active-list-table.table.table-striped - content_for :footer do javascript: jQuery(function(){ - Qrammer.active_user_list('#{session[:active_list_id]}') - setInterval( "Qrammer.active_user_list('#{session[:active_list_id]}')", 7500); + Quser.load_active_list(); + setInterval( "Quser.load_active_list()", 7500); }) diff --git a/app/views/dashboard/phone_home.html.slim b/app/views/user/home.html.slim similarity index 75% rename from app/views/dashboard/phone_home.html.slim rename to app/views/user/home.html.slim index a365ba68..cf06ed8b 100644 --- a/app/views/dashboard/phone_home.html.slim +++ b/app/views/user/home.html.slim @@ -2,9 +2,6 @@ ul.nav.nav-tabs.nav-stacked - if list_open? li= link_to 'Place order', user_list_products_path(supplier_id: active_list.supplier.id) li= link_to 'Active list', user_active_list_path - li= link_to 'Request bill', '#' - li= link_to 'Move table', '#' - li= link_to 'I have a question', '#' - else li= link_to 'Join table with Qr scan', '/select_qrcode' li= link_to 'Subscribe to list', '#' diff --git a/app/views/user/list_products.html.slim b/app/views/user/list_products.html.slim index 027f5f42..62297460 100644 --- a/app/views/user/list_products.html.slim +++ b/app/views/user/list_products.html.slim @@ -16,7 +16,7 @@ table#active-order-table.table.table-striped.hide tfoot tr td colspan=2 - button class="btn btn-primary" onClick="Qrammer.handle_active_user_list(function(){Qrammer.order_active_products_list('/order_active_products_list')})" Bestellen + button class="btn btn-primary" onClick="Quser.handle_active_list(function(){Quser.order_selected_products()})" Bestellen |  button class="btn btn btn-warning" onClick="Qrammer.clear_active_list()" Clear td.currency @@ -25,29 +25,9 @@ table#active-order-table.table.table-striped.hide - content_for :footer do javascript: jQuery(function(){ - Qrammer.handle_active_user_list(function(){ - $.get('/user/product_list.json', function(res){ - window.products = res - body = $('#products-table tbody') - for(var category in window.products){ - body.append('

'+category+'

'); - var category_ref = window.products[category]; - for(var iproduct = 0; iproduct < window.products[category].length; iproduct++){ - var product = window.products[category][iproduct]; - row = $(''); - button = $(''); - var callback = (function(prod){ - return function(){ Qrammer.add_product(prod) } - })(product) - button.click(callback); - row.append(''+product.name+''); - row.append(''+Qrammer.currency(product.price)+''); - row.append($('').append(button)); - body.append(row); - } - } - }) - setInterval('Qrammer.handle_active_user_list()', 7500); + Quser.handle_active_list(function(){ + Quser.load_active_list_products(); + setInterval('Quser.handle_active_list()', 7500); }) }) diff --git a/config/locales/en.yml b/config/locales/en.yml index d74e46de..824add53 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -40,6 +40,7 @@ en: table: Table list: List product: Product + order: Order product_category: Product category plural: user: Users @@ -47,6 +48,7 @@ en: table: Tables list: Lists product: Products + order: Orders product_category: Product categories attributes: product: diff --git a/config/routes.rb b/config/routes.rb index 2eca6523..18576b7a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -28,19 +28,19 @@ Qrammer::Application.routes.draw do post '/supplier/mark_order_in_process' => 'supplier#mark_order_in_process', as: :supplier_mark_order_in_process post '/supplier/order_is_delivered' => 'supplier#order_is_delivered', as: :supplier_order_is_delivered + match '/user' => 'user#home', as: :user_root get '/user/active_list(.:format)' => 'user#active_list', as: :user_active_list get '/user/list_info' => 'user#list_info', as: :user_list_info post '/user/needs_help' => 'user#needs_help', as: :user_needs_help post '/user/list_needs_payment' => 'user#list_needs_payment', as: :user_list_needs_payment match '/user/create_list' => 'user#create_list', as: :user_create_list get '/user/list_products' => 'user#list_products', as: :user_list_products - - match '/phone_home' => 'dashboard#phone_home', as: :phone_root match '/user/list_history' => 'user#list_history', as: :user_list_history match '/user/list_history/:list_id' => 'user#history_list', as: :user_history_list + post '/user/order_selected_products' => 'user#order_selected_products', as: :user_order_selected_products + match '/show_products' => 'dashboard#show_products', as: :user_products - match '/user/product_list(.:format)' => 'dashboard#product_list' match "/:action", controller: 'dashboard' # The priority is based upon order of creation: