many changes

This commit is contained in:
2012-12-03 18:39:36 +01:00
parent e3dc6a7c68
commit 7d64ab2022
37 changed files with 540 additions and 101 deletions
+7 -1
View File
@@ -33,6 +33,8 @@ gem 'couch_potato' , :git => 'git://github.com/bterkuile/couch_potato.git'
gem 'simply_stored' , :git => 'git://github.com/bterkuile/simply_stored.git'
gem 'devise', '2.0.4'
gem 'devise_simply_stored'
gem 'simple_form'
gem 'draper'
gem 'rqrcode'
gem 'mini_magick'
@@ -48,12 +50,16 @@ group :development do
gem 'pry'
gem 'pry-remote'
gem 'rspec-rails'
gem 'rb-fsevent', :require => false if RUBY_PLATFORM =~ /darwin/i
gem 'guard-rspec'
gem 'thin'
end
group :test do
gem 'steak'
gem 'pry'
gem 'steak'
gem 'rb-fsevent', :require => false if RUBY_PLATFORM =~ /darwin/i
gem 'guard-rspec'
gem 'factory_girl_rails'
end
+30 -5
View File
@@ -9,7 +9,7 @@ GIT
GIT
remote: git://github.com/bterkuile/simply_stored.git
revision: 955a484c4046b3343f07fd0d783342d01bf26f66
revision: 04f58b15bb308420f78c66d27ce4d4d3b58183ff
specs:
simply_stored (1.0.0)
activesupport
@@ -88,6 +88,9 @@ GEM
devise_simply_stored (0.0.3)
devise
diff-lcs (1.1.3)
draper (0.18.0)
actionpack (~> 3.2)
activesupport (~> 3.2)
erubis (2.7.0)
eventmachine (1.0.0)
execjs (1.4.0)
@@ -99,6 +102,14 @@ GEM
railties (>= 3.0.0)
ffi (1.2.0)
fssm (0.2.9)
guard (1.5.4)
listen (>= 0.4.2)
lumberjack (>= 1.0.2)
pry (>= 0.9.10)
thor (>= 0.14.6)
guard-rspec (2.3.0)
guard (>= 1.1)
rspec (~> 2.11)
haml (3.1.7)
haml-rails (0.3.5)
actionpack (>= 3.1, < 4.1)
@@ -127,6 +138,8 @@ GEM
libwebsocket (0.1.7.1)
addressable
websocket
listen (0.6.0)
lumberjack (1.0.2)
mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
@@ -135,7 +148,7 @@ GEM
mime-types (1.19)
mini_magick (3.4)
subexec (~> 0.2.1)
multi_json (1.3.7)
multi_json (1.4.0)
mustache (0.99.4)
nokogiri (1.5.5)
orm_adapter (0.0.7)
@@ -172,12 +185,17 @@ GEM
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
rake (10.0.2)
rb-fsevent (0.9.2)
rdoc (3.12)
json (~> 1.4)
rest-client (1.6.7)
mime-types (>= 1.16)
rqrcode (0.4.2)
rspec-core (2.12.0)
rspec (2.12.0)
rspec-core (~> 2.12.0)
rspec-expectations (~> 2.12.0)
rspec-mocks (~> 2.12.0)
rspec-core (2.12.1)
rspec-expectations (2.12.0)
diff-lcs (~> 1.1.3)
rspec-mocks (2.12.0)
@@ -199,6 +217,9 @@ GEM
libwebsocket (~> 0.1.3)
multi_json (~> 1.0)
rubyzip
simple_form (2.0.4)
actionpack (~> 3.0)
activemodel (~> 3.0)
slim (1.3.4)
temple (~> 0.5.5)
tilt (~> 1.3.3)
@@ -208,7 +229,7 @@ GEM
railties (~> 3.0)
slim (~> 1.0)
slop (3.3.3)
sprockets (2.2.1)
sprockets (2.2.2)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
@@ -229,7 +250,7 @@ GEM
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
twitter-bootstrap-rails (2.1.6)
twitter-bootstrap-rails (2.1.7)
actionpack (>= 3.1)
execjs
railties (>= 3.1)
@@ -252,7 +273,9 @@ DEPENDENCIES
couch_potato!
devise (= 2.0.4)
devise_simply_stored
draper
factory_girl_rails
guard-rspec
haml-rails
jquery-rails
kaminari-bootstrap
@@ -263,9 +286,11 @@ DEPENDENCIES
pry-remote
rack-cors
rails (= 3.2.9)
rb-fsevent
rqrcode
rspec-rails
sass-rails (~> 3.2.3)
simple_form
simply_stored!
slim-rails
steak
+24
View File
@@ -0,0 +1,24 @@
# A sample Guardfile
# More info at https://github.com/guard/guard#readme
guard 'rspec' do
watch(%r{^spec/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { "spec" }
# Rails example
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
watch('config/routes.rb') { "spec/routing" }
watch('app/controllers/application_controller.rb') { "spec/controllers" }
# Capybara features specs
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
# Turnip features and steps
watch(%r{^spec/acceptance/(.+)\.feature$})
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
end
@@ -9,13 +9,13 @@
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require twitter/bootstrap
//= require mustache
//= require faye
//= require supplier/base
//= require_directory .
//= require_self
var path_mapping = {
@@ -33,8 +33,5 @@ function redirect_to(mapping, variables){
window.location = path_mapping[mapping] + '?' + vars.join('&')
}
function currency(num) {
if (isNaN(num) || num === '' || num === null) {
num = 0.0;
}
return '&euro;&nbsp;' + parseFloat(num).toFixed(2);
return Qwaiter.currency(num);
}
@@ -0,0 +1,6 @@
jQuery ->
$('#product-category-list').sortable
axis: 'y'
handle: '.handle'
update: ->
$.post($(this).data('update-url'), $(this).sortable('serialize'))
+11 -17
View File
@@ -283,29 +283,23 @@ class Quser
@populate_products_table('/user/list_products_for_table.json?'+authentication_string+'&table_id='+table_id)
populate_products_table: (src)->
$.getJSON(data_host + src, (res) =>
if res.has_occupied_info
include_order_buttons = !res.is_occupied
delete(res['has_occupied_info'])
delete(res['is_occupied'])
else
include_order_buttons = true
body = $('#products-table tbody')
if res.table_number
$('.table-number').text(res.table_number)
delete(res['table_number'])
if res.supplier_name
$('.supplier-name').text(res.supplier_name)
delete(res['supplier_name'])
include_order_buttons = res.my_list
$('.table-number').text(res.table_number) if res.table_number
$('.supplier-name').text(res.supplier_name) if res.supplier_name
window.products = {}
body = $('#products-table tbody')
body.find('tr').remove()
script_id = if include_order_buttons then '#products-category-for-order-template' else '#products-category-template'
for category, products of res
#for category, products of res
for category in res.categories
body.append @mustache(script_id,
category: category,
products: products,
category: category.name,
products: category.products,
include_order_buttons: include_order_buttons
)
for product in products
for product in category.products
window.products[product._id] = product
)
increment_products_counter: (product_id)->
@@ -0,0 +1,7 @@
#product-category-list
list-style: none
li
clear: both
margin-bottom: 8px
.name
padding: 5px 5px
@@ -26,3 +26,7 @@ body
border: 1px solid black
padding: 2px
display: inline-block
.handle
cursor: move
font-size: 0.8em
color: #777
+1 -1
View File
@@ -19,7 +19,7 @@ class DashboardController < ApplicationController
# Testing action
def select_qrcode
@tables = Table.all.sample(2)
@tables = Table.all.sample(2) | List.active.map(&:table)
render layout: 'phone'
end
@@ -4,7 +4,7 @@ module Suppliers
# GET /product_categories
# GET /product_categories.json
def index
@product_categories = current_supplier.product_categories
@product_categories = current_supplier.product_categories.sort_by(&:position)
respond_to do |format|
format.html # index.html.erb
@@ -83,5 +83,14 @@ module Suppliers
format.json { head :no_content }
end
end
# POST /supplier/product_categories/sort
# params ~= product_category: ['abc', 'def', 'another id', ...]
def sort
@product_categories = ProductCategory.find(params[:product_category])
1.upto(@product_categories.size){|i| @product_categories[i-1].position = i}
CouchPotato.database.couchrest_database.bulk_save(@product_categories)
render nothing: true
end
end
end
@@ -4,7 +4,7 @@ module Suppliers
# GET /products
# GET /products.json
def index
@products = current_supplier.products
@products = ProductDecorator.decorate(current_supplier.products)
respond_to do |format|
format.html # index.html.erb
@@ -15,7 +15,7 @@ module Suppliers
# GET /products/1
# GET /products/1.json
def show
@product = Product.find(params[:id])
@product = ProductDecorator.find(params[:id])
respond_to do |format|
format.html # show.html.erb
@@ -27,7 +27,6 @@ module Suppliers
# GET /products/new.json
def new
@product = Product.new
@product.product_category_id = params[:product_category_id].presence
respond_to do |format|
format.html # new.html.erb
+11 -13
View File
@@ -85,11 +85,17 @@ class UserController < ApplicationController
handle_message_params
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({table_number: list.table_number, supplier_name: @supplier.name}){|h, p| n = p.product_category.try(:name) || 'other'; h[n] ||= []; h[n] << p; h}
h = ProductCategory.for_user(current_user, table: list.table, list: list) # list is performance parameter
render json: h
#products = list.supplier.products
#product_categories = list.supplier.product_categories
#other = product_categories.find(&:other?) || (product_categories << ProductCategory.other).last # Container for non categorized products
#product_categories.sort_by!{|p| p.product_category.try(:position) || 90000}
#h = {table_number: list.table_number, supplier_name: @supplier.name}
#h[:categories] = product_categories.map{|pc| {pc.name => pc.product_ids.map{|p| p.as_json}}}
#){|h, p| n = p.product_category.try(:name) || 'other'; h[n] ||= []; h[n] << p; h}
#render json: h
end
end
end
@@ -100,15 +106,7 @@ class UserController < ApplicationController
format.html do
end
format.json do
products = @table.supplier.products
products.include_relation(:product_categories)
products.sort_by!{|p| p.product_category.try(:position) || 90000}
h = products.inject({
table_number: @table.number,
supplier_name: @table.supplier.name,
has_occupied_info: true,
is_occupied: @table.occupied?
}){|h, p| n = p.product_category.try(:name) || 'other'; h[n] ||= []; h[n] << p; h}
h = ProductCategory.for_user(current_user, table: @table)
render json: h
end
end
+40
View File
@@ -0,0 +1,40 @@
class ProductDecorator < Draper::Base
decorates :product
def category_links(options = {})
if namespace = options[:namespace]
product_categories.map{|pc| h.link_to pc.name, [namespace, pc]}.join(', ').html_safe
else
product_categories.map{|pc| h.link_to pc.name, pc}.join(', ').html_safe
end
end
# Accessing Helpers
# You can access any helper via a proxy
#
# Normal Usage: helpers.number_to_currency(2)
# Abbreviated : h.number_to_currency(2)
#
# Or, optionally enable "lazy helpers" by including this module:
# include Draper::LazyHelpers
# Then use the helpers with no proxy:
# number_to_currency(2)
# Defining an Interface
# Control access to the wrapped subject's methods using one of the following:
#
# To allow only the listed methods (whitelist):
# allows :method1, :method2
#
# To allow everything except the listed methods (blacklist):
# denies :method1, :method2
# Presentation Methods
# Define your own instance methods, even overriding accessors
# generated by ActiveRecord:
#
# def created_at
# h.content_tag :span, attributes["created_at"].strftime("%a %m/%d/%y"),
# :class => 'timestamp'
# end
end
+7 -1
View File
@@ -8,6 +8,8 @@ class List
property :closed_at, type: Time
property :join_requests, type: Array, default: []
property :price, type: Float
property :is_payed, type: :boolean, default: false
property :payed_at, type: Time
has_many :orders, dependent: :destroy
belongs_to :table
@@ -90,6 +92,11 @@ class List
database.view(for_supplier_view({startkey: [supplier.id, range.last], endkey: [supplier.id, range.first], include_docs: true, reduce: false, descending: true}.merge(options)))
end
def mark_as_payed
self.is_payed = true
self.payed_at = Time.now
end
def close!
orders.include_relation(:product_orders)
set_price
@@ -155,7 +162,6 @@ class List
add_user(user)
user.save
self.is_dirty
binding.pry
if save
broadcast_user user.id, 'join_request_approved'
end
+17 -1
View File
@@ -5,10 +5,26 @@ class Product
property :code
property :price, type: Float
belongs_to :product_category
#belongs_to :product_category
has_and_belongs_to_many :product_categories, storing_keys: false
belongs_to :supplier # direct! category is an aid
has_many :product_orders
validates :supplier_id, presence: true
after_save :persist_product_category_ids
def product_category_ids=(ids)
@product_category_ids = ids.select(&:present?)
end
private
def persist_product_category_ids
return unless @product_category_ids.present?
database.load(@product_category_ids).each do |product_category|
product_category.product_ids ||= []
product_category.product_ids |= [id]
product_category.save
end
end
end
+32 -1
View File
@@ -5,10 +5,41 @@ class ProductCategory
property :position, type: Fixnum, default: 0
belongs_to :supplier
has_many :products
has_and_belongs_to_many :products, storing_keys: true
attr_protected :supplier_id
validates :position, numericality: true
validates :supplier_id, presence: true
def self.for_user(user, options = {})
table = options[:table]
raise "ProductCategory.for_user requires a table" unless table.present?
list = options[:list] || table.active_list
# Get supplier objects
products = table.supplier.products
product_categories = table.supplier.product_categories || []
# sort categories
product_categories.sort_by!{|pc| (pc.position || 90000).to_i }
# Append other category if not defined by supplier
other = product_categories.find(&:other?) || (product_categories << self.other).last # Container for non categorized products
# Initialize base return object
h = {table_number: table.number, supplier_name: table.supplier.name, my_list: list.try(:user_ids).to_a.include?(user.id)}
(products - product_categories.map(&:products).flatten).each{ |p| other.add_product(p) }
h[:categories] = product_categories.map{|pc| {name: pc.name, products: pc.products.to_a.map{|p| p.as_json}}}.select{|pc| pc && pc[:products].present?}
h
end
def other?
%w[other overig].include?(name.to_s.downcase)
end
def self.other(options = {})
new(options.reverse_merge(name: I18n.t('user.product_category.other_name')))
end
end
+1
View File
@@ -50,6 +50,7 @@ html lang="en"
//li= link_to t('supplier.menu.active_orders', orders: Order.model_name.human_plural), supplier_active_orders_path
//li= link_to t('supplier.menu.active_lists', lists: List.model_name.human_plural), supplier_active_lists_path
li= link_to ProductCategory.model_name.human_plural, suppliers_product_categories_path
li= link_to ProductCategory.model_name.human_plural, suppliers_product_categories_path
li= link_to Product.model_name.human_plural, suppliers_products_path
li= link_to Section.model_name.human_plural, suppliers_sections_path
li= link_to Table.model_name.human_plural, suppliers_tables_path
+1 -1
View File
@@ -12,7 +12,7 @@
= f.label :price, class: 'control-label'
.controls
= f.text_field :price, class: 'text_field'
.control-group class=(@product.errors[:product_category_id].any? ? 'error' : nil)
/.control-group class=(@product.errors[:product_category_id].any? ? 'error' : nil)
= f.label :product_category_id, ProductCategory.model_name.human, class: 'control-label'
.controls
= f.collection_select :product_category_id, @product_categories, :id, :name, include_blank: ''
@@ -1,14 +1,15 @@
= form_for [:suppliers, @product_category], html: {class: 'form-horizontal' } do |f|
= simple_form_for [:suppliers, @product_category], html: {class: 'form-horizontal'} do |f|
= render 'error_messages', target: @product_category
.control-group class=(@product_category.errors[:name].any? ? 'error' : nil)
= f.label :name, class: 'control-label'
= f.input :name
.control-group
= hidden_field_tag 'product_category[product_ids][]', ''
= label_tag nil, Product.model_name.human_plural, class: 'control-label'
.controls
= f.text_field :name, class: 'text_field'
.control-group class=(@product_category.errors[:position].any? ? 'error' : nil)
= f.label :position, class: 'control-label'
.controls
= f.text_field :position, class: 'text_field'
- for product in current_supplier.products
= check_box_tag "product_category[product_ids][]", product.id, @product_category.product_ids.to_a.include?(product.id), id: "product-checker-#{product.id}"
= label_tag "product-checker-#{product.id}", product.name
br
.form-actions
= f.submit nil, class: 'btn btn-primary'
= f.button :submit, class: 'btn-primary'
'
= link_to t("helpers.links.cancel"), suppliers_product_categories_path, class: 'btn'
@@ -2,25 +2,16 @@
.page-header= title :index, model_class
.well
- if @product_categories.any?
table.table
thead
tr
th= model_class.human_attribute_name(:name)
th= model_class.human_attribute_name(:position)
th.timestamp= model_class.human_attribute_name(:created_at)
th.actions=t 'helpers.actions'
tbody
- @product_categories.each do |product_category|
tr
td.link= link_to product_category.name, [:suppliers, product_category]
td= product_category.position
td.timestamp=l product_category.created_at, format: :short
td.actions
= link_to t('helpers.links.edit'), [:edit, :suppliers, product_category], class: 'btn btn-mini'
'
= link_to t("helpers.links.destroy"), [:suppliers, product_category], method: :delete, data: {confirm: are_you_sure? }, class: 'btn btn-mini btn-danger'
ul#product-category-list data-update-url=sort_suppliers_product_categories_path
- for product_category in @product_categories
= content_tag_for :li, product_category do
span.handle [drag]
span.name= link_to product_category.name, [:suppliers, product_category]
.pull-right.actions
= link_to t('helpers.links.edit'), [:edit, :suppliers, product_category], class: 'btn btn-mini'
'
= link_to t("helpers.links.destroy"), [:suppliers, product_category], method: :delete, data: {confirm: are_you_sure? }, class: 'btn btn-mini btn-danger'
- else
= no_content_given model_class
.form-actions
= link_to t("helpers.links.new"), new_suppliers_product_category_path, class: 'btn btn-primary'
@@ -14,5 +14,5 @@ dl.dl-horizontal.show-list
'
= link_to t("helpers.links.destroy"), [:suppliers, @product_category], method: :delete, data: {confirm: are_you_sure? }, class: 'btn btn-danger'
- content_for :row do
- @products = @product_category.products
- @products = ProductDecorator.decorate(@product_category.products)
= render template: 'suppliers/products/index'
+13 -17
View File
@@ -1,22 +1,18 @@
= form_for [:suppliers, @product], html: {class: 'form-horizontal' } do |f|
= simple_form_for [:suppliers, @product], html: {class: 'form-horizontal'} do |f|
= render 'error_messages', target: @product
.control-group class=(@product.errors[:name].any? ? 'error' : nil)
= f.label :name, class: 'control-label'
= f.input :name
= f.input :code
= f.input :price
.control-group
= hidden_field_tag 'product[product_category_ids][]', []
= label_tag nil, ProductCategory.model_name.human_plural, class: 'control-label'
.controls
= f.text_field :name, class: 'text_field'
.control-group class=(@product.errors[:code].any? ? 'error' : nil)
= f.label :code, class: 'control-label'
.controls
= f.text_field :code, class: 'text_field'
.control-group class=(@product.errors[:price].any? ? 'error' : nil)
= f.label :price, class: 'control-label'
.controls
= f.text_field :price, class: ['text_field', :currency]
.control-group class=(@product.errors[:product_category_id].any? ? 'error' : nil)
= f.label :product_category_id, ProductCategory.model_name.human, class: 'control-label'
.controls
= f.collection_select :product_category_id, current_supplier.product_categories, :id, :name, include_blank: ''
- for product_category in current_supplier.product_categories
= check_box_tag "product[product_category_ids][]", product_category.id, @product.product_categories.to_a.include?(product_category), id: "product-category-checker-#{product_category.id}"
= label_tag "product-category-checker-#{product_category.id}", product_category.name
br
.form-actions
= f.submit nil, class: 'btn btn-primary'
= f.button :submit, class: 'btn-primary'
'
= link_to t("helpers.links.cancel"), suppliers_products_path, class: 'btn'
+2 -2
View File
@@ -8,7 +8,7 @@
th= model_class.human_attribute_name(:name)
th= model_class.human_attribute_name(:code)
th.currency= model_class.human_attribute_name(:price)
th= ProductCategory.model_name.human
th= ProductCategory.model_name.human_plural
th.timestamp= model_class.human_attribute_name(:created_at)
th.actions=t 'helpers.actions'
tbody
@@ -17,7 +17,7 @@
td.link= link_to product.name, [:suppliers, product]
td= product.code
td.currency=currency product.price
td.link= link_to_if product.product_category.present?, product.product_category.try(:name), [:suppliers, product.product_category]
td.link= product.category_links namespace: :suppliers
td.timestamp=l product.created_at, format: :short
td.actions
= link_to t('helpers.links.edit'), [:edit, :suppliers, product], class: 'btn btn-mini'
+2 -3
View File
@@ -8,9 +8,8 @@ dl.dl-horizontal.show-list
dd= @product.code
dt= model_class.human_attribute_name(:price)
dd=currency @product.price
- if @product.product_category.present?
dt= ProductCategory.model_name.human
dd= link_to @product.product_category.name, @product.product_category
dt= ProductCategory.model_name.human_plural
dd= @product.category_links(namespace: :suppliers)
.form-actions
= link_to t("helpers.links.back"), suppliers_products_path, class: 'btn'
+142
View File
@@ -0,0 +1,142 @@
# Use this setup block to configure all options available in SimpleForm.
SimpleForm.setup do |config|
# Wrappers are used by the form builder to generate a
# complete input. You can remove any component from the
# wrapper, change the order or even add your own to the
# stack. The options given below are used to wrap the
# whole input.
config.wrappers :default, :class => :input,
:hint_class => :field_with_hint, :error_class => :field_with_errors do |b|
## Extensions enabled by default
# Any of these extensions can be disabled for a
# given input by passing: `f.input EXTENSION_NAME => false`.
# You can make any of these extensions optional by
# renaming `b.use` to `b.optional`.
# Determines whether to use HTML5 (:email, :url, ...)
# and required attributes
b.use :html5
# Calculates placeholders automatically from I18n
# You can also pass a string as f.input :placeholder => "Placeholder"
b.use :placeholder
## Optional extensions
# They are disabled unless you pass `f.input EXTENSION_NAME => :lookup`
# to the input. If so, they will retrieve the values from the model
# if any exists. If you want to enable the lookup for any of those
# extensions by default, you can change `b.optional` to `b.use`.
# Calculates maxlength from length validations for string inputs
b.optional :maxlength
# Calculates pattern from format validations for string inputs
b.optional :pattern
# Calculates min and max from length validations for numeric inputs
b.optional :min_max
# Calculates readonly automatically from readonly attributes
b.optional :readonly
## Inputs
b.use :label_input
b.use :hint, :wrap_with => { :tag => :span, :class => :hint }
b.use :error, :wrap_with => { :tag => :span, :class => :error }
end
# The default wrapper to be used by the FormBuilder.
config.default_wrapper = :default
# Define the way to render check boxes / radio buttons with labels.
# Defaults to :nested for bootstrap config.
# :inline => input + label
# :nested => label > input
config.boolean_style = :nested
# Default class for buttons
config.button_class = 'btn'
# Method used to tidy up errors. Specify any Rails Array method.
# :first lists the first message for each field.
# Use :to_sentence to list all errors for each field.
# config.error_method = :first
# Default tag used for error notification helper.
config.error_notification_tag = :div
# CSS class to add for error notification helper.
config.error_notification_class = 'alert alert-error'
# ID to add for error notification helper.
# config.error_notification_id = nil
# Series of attempts to detect a default label method for collection.
# config.collection_label_methods = [ :to_label, :name, :title, :to_s ]
# Series of attempts to detect a default value method for collection.
# config.collection_value_methods = [ :id, :to_s ]
# You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
# config.collection_wrapper_tag = nil
# You can define the class to use on all collection wrappers. Defaulting to none.
# config.collection_wrapper_class = nil
# You can wrap each item in a collection of radio/check boxes with a tag,
# defaulting to :span. Please note that when using :boolean_style = :nested,
# SimpleForm will force this option to be a label.
# config.item_wrapper_tag = :span
# You can define a class to use in all item wrappers. Defaulting to none.
# config.item_wrapper_class = nil
# How the label text should be generated altogether with the required text.
# config.label_text = lambda { |label, required| "#{required} #{label}" }
# You can define the class to use on all labels. Default is nil.
config.label_class = 'control-label'
# You can define the class to use on all forms. Default is simple_form.
# config.form_class = :simple_form
# You can define which elements should obtain additional classes
# config.generate_additional_classes_for = [:wrapper, :label, :input]
# Whether attributes are required by default (or not). Default is true.
# config.required_by_default = true
# Tell browsers whether to use default HTML5 validations (novalidate option).
# Default is enabled.
config.browser_validations = false
# Collection of methods to detect if a file type was given.
# config.file_methods = [ :mounted_as, :file?, :public_filename ]
# Custom mappings for input types. This should be a hash containing a regexp
# to match as key, and the input type that will be used when the field name
# matches the regexp as value.
# config.input_mappings = { /count/ => :integer }
# Custom wrappers for input types. This should be a hash containing an input
# type as key and the wrapper that will be used for all inputs with specified type.
# config.wrapper_mappings = { :string => :prepend }
# Default priority for time_zone inputs.
# config.time_zone_priority = nil
# Default priority for country inputs.
# config.country_priority = nil
# Default size for text inputs.
# config.default_input_size = 50
# When false, do not use translations for labels.
# config.translate_labels = true
# Automatically discover new inputs in Rails' autoload path.
# config.inputs_discovery = true
# Cache SimpleForm inputs discovery
# config.cache_discovery = !Rails.env.development?
end
@@ -0,0 +1,45 @@
# Use this setup block to configure all options available in SimpleForm.
SimpleForm.setup do |config|
config.wrappers :bootstrap, :tag => 'div', :class => 'control-group', :error_class => 'error' do |b|
b.use :html5
b.use :placeholder
b.use :label
b.wrapper :tag => 'div', :class => 'controls' do |ba|
ba.use :input
ba.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' }
ba.use :hint, :wrap_with => { :tag => 'p', :class => 'help-block' }
end
end
config.wrappers :prepend, :tag => 'div', :class => "control-group", :error_class => 'error' do |b|
b.use :html5
b.use :placeholder
b.use :label
b.wrapper :tag => 'div', :class => 'controls' do |input|
input.wrapper :tag => 'div', :class => 'input-prepend' do |prepend|
prepend.use :input
end
input.use :hint, :wrap_with => { :tag => 'span', :class => 'help-block' }
input.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' }
end
end
config.wrappers :append, :tag => 'div', :class => "control-group", :error_class => 'error' do |b|
b.use :html5
b.use :placeholder
b.use :label
b.wrapper :tag => 'div', :class => 'controls' do |input|
input.wrapper :tag => 'div', :class => 'input-append' do |append|
append.use :input
end
input.use :hint, :wrap_with => { :tag => 'span', :class => 'help-block' }
input.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' }
end
end
# Wrappers for forms and inputs using the Twitter Bootstrap toolkit.
# Check the Bootstrap docs (http://twitter.github.com/bootstrap)
# to learn about the different styles for forms and inputs,
# buttons and other elements.
config.default_wrapper = :bootstrap
end
+14
View File
@@ -14,9 +14,21 @@ en:
are_you_sure: 'Are you sure?'
place_order: Place order
show_active_list: Show %{list}
edit: Edit
show: Show
new: New
destroy: Delete
back: Back
cancel: Cancel
forms:
errors:
title: There are problems found during saving (%{count})
submit:
create: 'Add %{model}'
update: 'Update %{model}'
submit: 'Save %{model}'
list:
no_records: There are no items present
messages:
cannot_order_on_non_active_list: You cannot place an order on a closed list
order_is_placed: Your order has been received in good order
@@ -130,6 +142,8 @@ en:
show_active_list_products: Go to the menu
basket:
total: Total
product_category:
other_name: Overig
section:
first_section_title: Room
manage_tables:
+14
View File
@@ -13,9 +13,21 @@ nl:
are_you_sure: 'Weet je dit zeker?'
place_order: Bestellen
show_active_list: Toon %{list}
edit: Bewerk
show: Toon
new: Nieuw
destroy: Verwijder
back: Terug
cancel: Terug
forms:
errors:
title: Er zijn een problemen opgetreden (%{count})
submit:
create: '%{model} toevoegen'
update: '%{model} bewaren'
submit: '%{model} opslaan'
list:
no_records: Er zijn geen items aanwezig
messages:
cannot_order_on_non_active_list: Je kan niet bestellen op een gesloten lijst
order_is_placed: Je bestelling is in goede orde aangekomen
@@ -143,6 +155,8 @@ nl:
show_active_list_products: Ga naar het menu
basket:
total: Totaal
product_category:
other_name: Overig
section:
first_section_title: Ruimte
manage_tables:
+26
View File
@@ -0,0 +1,26 @@
en:
simple_form:
"yes": 'Yes'
"no": 'No'
required:
text: 'required'
mark: '*'
# You can uncomment the line below if you need to overwrite the whole required html.
# When using html, text and mark won't be used.
# html: '<abbr title="required">*</abbr>'
error_notification:
default_message: "Please review the problems below:"
# Labels and hints examples
# labels:
# defaults:
# password: 'Password'
# user:
# new:
# email: 'E-mail to sign in.'
# edit:
# email: 'E-mail.'
# hints:
# defaults:
# username: 'User name to sign in.'
# password: 'No special characters, please.'
+5 -1
View File
@@ -90,7 +90,11 @@ Qwaiter::Application.routes.draw do
end
resources :products
resources :lists
resources :product_categories
resources :product_categories do
collection do
post :sort
end
end
root to: 'sections#index'
end
@@ -0,0 +1,10 @@
= simple_form_for(@<%= singular_table_name %>) do |f|
= f.error_notification
.form-inputs
<%- attributes.each do |attribute| -%>
= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %>
<%- end -%>
.form-actions
= f.button :submit
@@ -9,8 +9,12 @@ feature 'Supplier main board spec.rb', %q{
create_supplier 'supplier@qwaiter.com'
create_user 'user@qwaiter.com'
end
def create_active_list(options = {})
end
scenario 'loaded orders should have a list_id present for handling actions' do
create_active_list
login_supplier_as 'supplier@qwaiter.com'
end
@@ -0,0 +1,4 @@
require 'spec_helper'
describe ProductDecorator do
end
+1
View File
@@ -1,5 +1,6 @@
FactoryGirl.define do
factory :list do
association :table
association :supplier
end
end
+6
View File
@@ -0,0 +1,6 @@
FactoryGirl.define do
factory :user do
email "test@example.com"
password "secret"
end
end
+13
View File
@@ -14,4 +14,17 @@ describe List do
end
end
describe :mark_as_payed do
it "should set payed_at to a time" do
@list.payed_at.should be_nil
@list.mark_as_payed
@list.payed_at.should be_kind_of Time
end
it "should set is_payed to true" do
@list.is_payed.should be_false
@list.mark_as_payed
@list.is_payed.should be_true
end
end
end
+6
View File
@@ -0,0 +1,6 @@
require 'spec_helper'
describe Product do
end