Merge branch 'master' of github.com:ZeusWPI/Tab
This commit is contained in:
commit
edef683f86
144 changed files with 1843 additions and 985 deletions
1
.capistrano/metrics
Normal file
1
.capistrano/metrics
Normal file
|
@ -0,0 +1 @@
|
||||||
|
full
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -18,3 +18,7 @@
|
||||||
# Avatars of producst
|
# Avatars of producst
|
||||||
public/system/products
|
public/system/products
|
||||||
public/system/users
|
public/system/users
|
||||||
|
|
||||||
|
.project
|
||||||
|
|
||||||
|
/coverage
|
||||||
|
|
7
.simplecov
Normal file
7
.simplecov
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
require 'simplecov'
|
||||||
|
require 'coveralls'
|
||||||
|
|
||||||
|
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
||||||
|
SimpleCov.start do
|
||||||
|
add_filter 'config/'
|
||||||
|
end
|
18
.travis.yml
Normal file
18
.travis.yml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
language: ruby
|
||||||
|
rvm:
|
||||||
|
- 2.1.0
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- "RAILS_ENV=test bundle exec rake db:create"
|
||||||
|
- "RAILS_ENV=test bundle exec rake db:schema:load"
|
||||||
|
|
||||||
|
script: bundle exec rake
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
slack: zeuswpi:1pHNpPMD56jXSGG1w3Ysa9rd
|
||||||
|
|
||||||
|
email:
|
||||||
|
recipients:
|
||||||
|
- tab@zeus.ugent.be
|
||||||
|
on_success: never
|
||||||
|
on_failure: change
|
30
Gemfile
30
Gemfile
|
@ -2,7 +2,7 @@ source 'https://rubygems.org'
|
||||||
|
|
||||||
|
|
||||||
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
||||||
gem 'rails', '4.1.7'
|
gem 'rails', '4.2'
|
||||||
# Use sqlite3 as the database for Active Record
|
# Use sqlite3 as the database for Active Record
|
||||||
gem 'sqlite3'
|
gem 'sqlite3'
|
||||||
# Use SCSS for stylesheets
|
# Use SCSS for stylesheets
|
||||||
|
@ -29,14 +29,9 @@ gem 'spring', group: :development
|
||||||
# add annotations of schema inside models
|
# add annotations of schema inside models
|
||||||
gem 'annotate'
|
gem 'annotate'
|
||||||
|
|
||||||
# Use ActiveModel has_secure_password
|
|
||||||
# gem 'bcrypt', '~> 3.1.7'
|
|
||||||
|
|
||||||
# Use unicorn as the app server
|
# Use unicorn as the app server
|
||||||
# gem 'unicorn'
|
# gem 'unicorn'
|
||||||
|
|
||||||
# Use Capistrano for deployment
|
|
||||||
# gem 'capistrano-rails', group: :development
|
|
||||||
# Deployment
|
# Deployment
|
||||||
gem 'capistrano', '~> 3.1'
|
gem 'capistrano', '~> 3.1'
|
||||||
gem 'capistrano-rails', '~> 1.1'
|
gem 'capistrano-rails', '~> 1.1'
|
||||||
|
@ -46,9 +41,12 @@ group :production do
|
||||||
gem 'mysql2' # Database
|
gem 'mysql2' # Database
|
||||||
end
|
end
|
||||||
|
|
||||||
# Use debugger
|
group :test do
|
||||||
# gem 'debugger', group: [:development, :test]
|
gem 'capybara'
|
||||||
|
gem 'launchy'
|
||||||
|
gem "codeclimate-test-reporter", require: nil
|
||||||
|
gem 'faker', '1.4.2'
|
||||||
|
end
|
||||||
|
|
||||||
#bootstrap
|
#bootstrap
|
||||||
gem 'bootstrap-sass', '3.2.0.0'
|
gem 'bootstrap-sass', '3.2.0.0'
|
||||||
|
@ -56,9 +54,6 @@ gem 'bootstrap-sass', '3.2.0.0'
|
||||||
#debug stuff
|
#debug stuff
|
||||||
gem 'byebug'
|
gem 'byebug'
|
||||||
|
|
||||||
#passwords
|
|
||||||
gem 'bcrypt', '3.1.7'
|
|
||||||
|
|
||||||
#paginate stuff
|
#paginate stuff
|
||||||
gem 'will_paginate', '3.0.7'
|
gem 'will_paginate', '3.0.7'
|
||||||
gem 'bootstrap-will_paginate', '0.0.10'
|
gem 'bootstrap-will_paginate', '0.0.10'
|
||||||
|
@ -72,5 +67,12 @@ gem 'devise'
|
||||||
# Use cancancan for authorization
|
# Use cancancan for authorization
|
||||||
gem 'cancancan'
|
gem 'cancancan'
|
||||||
|
|
||||||
#ik wil test data maken dus dit
|
# Safety first
|
||||||
gem 'faker', '1.4.2'
|
gem 'paper_trail', '~> 4.0.0.beta'
|
||||||
|
|
||||||
|
# Windoos sux
|
||||||
|
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw]
|
||||||
|
|
||||||
|
gem 'coveralls', require: false
|
||||||
|
|
||||||
|
gem 'omniauth-oauth2'
|
||||||
|
|
231
Gemfile.lock
231
Gemfile.lock
|
@ -1,37 +1,48 @@
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actionmailer (4.1.7)
|
actionmailer (4.2.0)
|
||||||
actionpack (= 4.1.7)
|
actionpack (= 4.2.0)
|
||||||
actionview (= 4.1.7)
|
actionview (= 4.2.0)
|
||||||
|
activejob (= 4.2.0)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
actionpack (4.1.7)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
actionview (= 4.1.7)
|
actionpack (4.2.0)
|
||||||
activesupport (= 4.1.7)
|
actionview (= 4.2.0)
|
||||||
rack (~> 1.5.2)
|
activesupport (= 4.2.0)
|
||||||
|
rack (~> 1.6.0)
|
||||||
rack-test (~> 0.6.2)
|
rack-test (~> 0.6.2)
|
||||||
actionview (4.1.7)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
activesupport (= 4.1.7)
|
rails-html-sanitizer (~> 1.0, >= 1.0.1)
|
||||||
|
actionview (4.2.0)
|
||||||
|
activesupport (= 4.2.0)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubis (~> 2.7.0)
|
erubis (~> 2.7.0)
|
||||||
activemodel (4.1.7)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
activesupport (= 4.1.7)
|
rails-html-sanitizer (~> 1.0, >= 1.0.1)
|
||||||
|
activejob (4.2.0)
|
||||||
|
activesupport (= 4.2.0)
|
||||||
|
globalid (>= 0.3.0)
|
||||||
|
activemodel (4.2.0)
|
||||||
|
activesupport (= 4.2.0)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
activerecord (4.1.7)
|
activerecord (4.2.0)
|
||||||
activemodel (= 4.1.7)
|
activemodel (= 4.2.0)
|
||||||
activesupport (= 4.1.7)
|
activesupport (= 4.2.0)
|
||||||
arel (~> 5.0.0)
|
arel (~> 6.0)
|
||||||
activesupport (4.1.7)
|
activesupport (4.2.0)
|
||||||
i18n (~> 0.6, >= 0.6.9)
|
i18n (~> 0.7)
|
||||||
json (~> 1.7, >= 1.7.7)
|
json (~> 1.7, >= 1.7.7)
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.3, >= 0.3.4)
|
||||||
tzinfo (~> 1.1)
|
tzinfo (~> 1.1)
|
||||||
|
addressable (2.3.7)
|
||||||
annotate (2.6.5)
|
annotate (2.6.5)
|
||||||
activerecord (>= 2.3.0)
|
activerecord (>= 2.3.0)
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
arel (5.0.1.20140414130214)
|
arel (6.0.0)
|
||||||
bcrypt (3.1.7)
|
bcrypt (3.1.10)
|
||||||
|
bcrypt (3.1.10-x64-mingw32)
|
||||||
bootstrap-sass (3.2.0.0)
|
bootstrap-sass (3.2.0.0)
|
||||||
sass (~> 3.2)
|
sass (~> 3.2)
|
||||||
bootstrap-will_paginate (0.0.10)
|
bootstrap-will_paginate (0.0.10)
|
||||||
|
@ -41,12 +52,13 @@ GEM
|
||||||
columnize (~> 0.8)
|
columnize (~> 0.8)
|
||||||
debugger-linecache (~> 1.2)
|
debugger-linecache (~> 1.2)
|
||||||
slop (~> 3.6)
|
slop (~> 3.6)
|
||||||
cancancan (1.9.2)
|
cancancan (1.10.1)
|
||||||
capistrano (3.2.1)
|
capistrano (3.3.5)
|
||||||
|
capistrano-stats (~> 1.1.0)
|
||||||
i18n
|
i18n
|
||||||
rake (>= 10.0.0)
|
rake (>= 10.0.0)
|
||||||
sshkit (~> 1.3)
|
sshkit (~> 1.3)
|
||||||
capistrano-bundler (1.1.3)
|
capistrano-bundler (1.1.4)
|
||||||
capistrano (~> 3.1)
|
capistrano (~> 3.1)
|
||||||
sshkit (~> 1.2)
|
sshkit (~> 1.2)
|
||||||
capistrano-rails (1.1.2)
|
capistrano-rails (1.1.2)
|
||||||
|
@ -55,19 +67,34 @@ GEM
|
||||||
capistrano-rvm (0.1.2)
|
capistrano-rvm (0.1.2)
|
||||||
capistrano (~> 3.0)
|
capistrano (~> 3.0)
|
||||||
sshkit (~> 1.2)
|
sshkit (~> 1.2)
|
||||||
|
capistrano-stats (1.1.1)
|
||||||
|
capybara (2.4.4)
|
||||||
|
mime-types (>= 1.16)
|
||||||
|
nokogiri (>= 1.3.3)
|
||||||
|
rack (>= 1.0.0)
|
||||||
|
rack-test (>= 0.5.4)
|
||||||
|
xpath (~> 2.0)
|
||||||
climate_control (0.0.3)
|
climate_control (0.0.3)
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
cocaine (0.5.4)
|
cocaine (0.5.5)
|
||||||
climate_control (>= 0.0.3, < 1.0)
|
climate_control (>= 0.0.3, < 1.0)
|
||||||
|
codeclimate-test-reporter (0.4.7)
|
||||||
|
simplecov (>= 0.7.1, < 1.0.0)
|
||||||
coffee-rails (4.0.1)
|
coffee-rails (4.0.1)
|
||||||
coffee-script (>= 2.2.0)
|
coffee-script (>= 2.2.0)
|
||||||
railties (>= 4.0.0, < 5.0)
|
railties (>= 4.0.0, < 5.0)
|
||||||
coffee-script (2.3.0)
|
coffee-script (2.3.0)
|
||||||
coffee-script-source
|
coffee-script-source
|
||||||
execjs
|
execjs
|
||||||
coffee-script-source (1.8.0)
|
coffee-script-source (1.9.0)
|
||||||
colorize (0.7.3)
|
colorize (0.7.5)
|
||||||
columnize (0.8.9)
|
columnize (0.9.0)
|
||||||
|
coveralls (0.7.11)
|
||||||
|
multi_json (~> 1.10)
|
||||||
|
rest-client (>= 1.6.8, < 2)
|
||||||
|
simplecov (~> 0.9.1)
|
||||||
|
term-ansicolor (~> 1.3)
|
||||||
|
thor (~> 0.19.1)
|
||||||
debugger-linecache (1.2.0)
|
debugger-linecache (1.2.0)
|
||||||
devise (3.4.1)
|
devise (3.4.1)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
|
@ -76,102 +103,169 @@ GEM
|
||||||
responders
|
responders
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
warden (~> 1.2.3)
|
warden (~> 1.2.3)
|
||||||
|
docile (1.1.5)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
execjs (2.2.2)
|
execjs (2.3.0)
|
||||||
faker (1.4.2)
|
faker (1.4.2)
|
||||||
i18n (~> 0.5)
|
i18n (~> 0.5)
|
||||||
|
faraday (0.9.1)
|
||||||
|
multipart-post (>= 1.2, < 3)
|
||||||
|
ffi (1.9.6-x64-mingw32)
|
||||||
|
globalid (0.3.2)
|
||||||
|
activesupport (>= 4.1.0)
|
||||||
|
hashie (3.4.0)
|
||||||
hike (1.2.3)
|
hike (1.2.3)
|
||||||
i18n (0.6.11)
|
i18n (0.7.0)
|
||||||
jbuilder (2.2.5)
|
jbuilder (2.2.6)
|
||||||
activesupport (>= 3.0.0, < 5)
|
activesupport (>= 3.0.0, < 5)
|
||||||
multi_json (~> 1.2)
|
multi_json (~> 1.2)
|
||||||
jquery-rails (3.1.2)
|
jquery-rails (4.0.3)
|
||||||
railties (>= 3.0, < 5.0)
|
rails-dom-testing (~> 1.0)
|
||||||
|
railties (>= 4.2.0)
|
||||||
thor (>= 0.14, < 2.0)
|
thor (>= 0.14, < 2.0)
|
||||||
json (1.8.1)
|
json (1.8.2)
|
||||||
|
jwt (1.4.1)
|
||||||
|
launchy (2.4.3)
|
||||||
|
addressable (~> 2.3)
|
||||||
|
loofah (2.0.1)
|
||||||
|
nokogiri (>= 1.5.9)
|
||||||
mail (2.6.3)
|
mail (2.6.3)
|
||||||
mime-types (>= 1.16, < 3)
|
mime-types (>= 1.16, < 3)
|
||||||
mime-types (2.4.3)
|
mime-types (2.4.3)
|
||||||
minitest (5.4.3)
|
mini_portile (0.6.2)
|
||||||
|
minitest (5.5.1)
|
||||||
multi_json (1.10.1)
|
multi_json (1.10.1)
|
||||||
|
multi_xml (0.5.5)
|
||||||
|
multipart-post (2.0.0)
|
||||||
mysql2 (0.3.17)
|
mysql2 (0.3.17)
|
||||||
net-scp (1.2.1)
|
net-scp (1.2.1)
|
||||||
net-ssh (>= 2.6.5)
|
net-ssh (>= 2.6.5)
|
||||||
net-ssh (2.9.1)
|
net-ssh (2.9.2)
|
||||||
|
netrc (0.10.3)
|
||||||
|
nokogiri (1.6.6.2)
|
||||||
|
mini_portile (~> 0.6.0)
|
||||||
|
nokogiri (1.6.6.2-x64-mingw32)
|
||||||
|
mini_portile (~> 0.6.0)
|
||||||
|
oauth2 (1.0.0)
|
||||||
|
faraday (>= 0.8, < 0.10)
|
||||||
|
jwt (~> 1.0)
|
||||||
|
multi_json (~> 1.3)
|
||||||
|
multi_xml (~> 0.5)
|
||||||
|
rack (~> 1.2)
|
||||||
|
omniauth (1.2.2)
|
||||||
|
hashie (>= 1.2, < 4)
|
||||||
|
rack (~> 1.0)
|
||||||
|
omniauth-oauth2 (1.2.0)
|
||||||
|
faraday (>= 0.8, < 0.10)
|
||||||
|
multi_json (~> 1.3)
|
||||||
|
oauth2 (~> 1.0)
|
||||||
|
omniauth (~> 1.2)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
paperclip (4.2.0)
|
paper_trail (4.0.0.beta2)
|
||||||
|
activerecord (>= 3.0, < 6.0)
|
||||||
|
activesupport (>= 3.0, < 6.0)
|
||||||
|
paperclip (4.2.1)
|
||||||
activemodel (>= 3.0.0)
|
activemodel (>= 3.0.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
cocaine (~> 0.5.3)
|
cocaine (~> 0.5.3)
|
||||||
mime-types
|
mime-types
|
||||||
rack (1.5.2)
|
rack (1.6.0)
|
||||||
rack-test (0.6.2)
|
rack-test (0.6.3)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rails (4.1.7)
|
rails (4.2.0)
|
||||||
actionmailer (= 4.1.7)
|
actionmailer (= 4.2.0)
|
||||||
actionpack (= 4.1.7)
|
actionpack (= 4.2.0)
|
||||||
actionview (= 4.1.7)
|
actionview (= 4.2.0)
|
||||||
activemodel (= 4.1.7)
|
activejob (= 4.2.0)
|
||||||
activerecord (= 4.1.7)
|
activemodel (= 4.2.0)
|
||||||
activesupport (= 4.1.7)
|
activerecord (= 4.2.0)
|
||||||
|
activesupport (= 4.2.0)
|
||||||
bundler (>= 1.3.0, < 2.0)
|
bundler (>= 1.3.0, < 2.0)
|
||||||
railties (= 4.1.7)
|
railties (= 4.2.0)
|
||||||
sprockets-rails (~> 2.0)
|
sprockets-rails
|
||||||
railties (4.1.7)
|
rails-deprecated_sanitizer (1.0.3)
|
||||||
actionpack (= 4.1.7)
|
activesupport (>= 4.2.0.alpha)
|
||||||
activesupport (= 4.1.7)
|
rails-dom-testing (1.0.5)
|
||||||
|
activesupport (>= 4.2.0.beta, < 5.0)
|
||||||
|
nokogiri (~> 1.6.0)
|
||||||
|
rails-deprecated_sanitizer (>= 1.0.1)
|
||||||
|
rails-html-sanitizer (1.0.1)
|
||||||
|
loofah (~> 2.0)
|
||||||
|
railties (4.2.0)
|
||||||
|
actionpack (= 4.2.0)
|
||||||
|
activesupport (= 4.2.0)
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
rake (10.3.2)
|
rake (10.4.2)
|
||||||
rdoc (4.1.2)
|
rdoc (4.2.0)
|
||||||
json (~> 1.4)
|
json (~> 1.4)
|
||||||
responders (1.1.2)
|
responders (2.1.0)
|
||||||
railties (>= 3.2, < 4.2)
|
railties (>= 4.2.0, < 5)
|
||||||
|
rest-client (1.7.3)
|
||||||
|
mime-types (>= 1.16, < 3.0)
|
||||||
|
netrc (~> 0.7)
|
||||||
|
rest-client (1.7.3-x64-mingw32)
|
||||||
|
ffi (~> 1.9)
|
||||||
|
mime-types (>= 1.16, < 3.0)
|
||||||
|
netrc (~> 0.7)
|
||||||
sass (3.2.19)
|
sass (3.2.19)
|
||||||
sass-rails (4.0.4)
|
sass-rails (4.0.5)
|
||||||
railties (>= 4.0.0, < 5.0)
|
railties (>= 4.0.0, < 5.0)
|
||||||
sass (~> 3.2.2)
|
sass (~> 3.2.2)
|
||||||
sprockets (~> 2.8, < 2.12)
|
sprockets (~> 2.8, < 3.0)
|
||||||
sprockets-rails (~> 2.0)
|
sprockets-rails (~> 2.0)
|
||||||
sdoc (0.4.1)
|
sdoc (0.4.1)
|
||||||
json (~> 1.7, >= 1.7.7)
|
json (~> 1.7, >= 1.7.7)
|
||||||
rdoc (~> 4.0)
|
rdoc (~> 4.0)
|
||||||
|
simplecov (0.9.2)
|
||||||
|
docile (~> 1.1.0)
|
||||||
|
multi_json (~> 1.0)
|
||||||
|
simplecov-html (~> 0.9.0)
|
||||||
|
simplecov-html (0.9.0)
|
||||||
slop (3.6.0)
|
slop (3.6.0)
|
||||||
spring (1.2.0)
|
spring (1.3.1)
|
||||||
sprockets (2.11.3)
|
sprockets (2.12.3)
|
||||||
hike (~> 1.2)
|
hike (~> 1.2)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
rack (~> 1.0)
|
rack (~> 1.0)
|
||||||
tilt (~> 1.1, != 1.3.0)
|
tilt (~> 1.1, != 1.3.0)
|
||||||
sprockets-rails (2.2.0)
|
sprockets-rails (2.2.4)
|
||||||
actionpack (>= 3.0)
|
actionpack (>= 3.0)
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
sprockets (>= 2.8, < 4.0)
|
sprockets (>= 2.8, < 4.0)
|
||||||
sqlite3 (1.3.10)
|
sqlite3 (1.3.10)
|
||||||
sshkit (1.5.1)
|
sqlite3 (1.3.10-x64-mingw32)
|
||||||
colorize
|
sshkit (1.6.1)
|
||||||
|
colorize (>= 0.7.0)
|
||||||
net-scp (>= 1.1.2)
|
net-scp (>= 1.1.2)
|
||||||
net-ssh (>= 2.8.0)
|
net-ssh (>= 2.8.0)
|
||||||
|
term-ansicolor (1.3.0)
|
||||||
|
tins (~> 1.0)
|
||||||
thor (0.19.1)
|
thor (0.19.1)
|
||||||
thread_safe (0.3.4)
|
thread_safe (0.3.4)
|
||||||
tilt (1.4.1)
|
tilt (1.4.1)
|
||||||
turbolinks (2.5.2)
|
tins (1.3.5)
|
||||||
|
turbolinks (2.5.3)
|
||||||
coffee-rails
|
coffee-rails
|
||||||
tzinfo (1.2.2)
|
tzinfo (1.2.2)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
uglifier (2.5.3)
|
tzinfo-data (1.2015.1)
|
||||||
|
tzinfo (>= 1.0.0)
|
||||||
|
uglifier (2.7.0)
|
||||||
execjs (>= 0.3.0)
|
execjs (>= 0.3.0)
|
||||||
json (>= 1.8.0)
|
json (>= 1.8.0)
|
||||||
warden (1.2.3)
|
warden (1.2.3)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
will_paginate (3.0.7)
|
will_paginate (3.0.7)
|
||||||
|
xpath (2.0.0)
|
||||||
|
nokogiri (~> 1.3)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
x64-mingw32
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
annotate
|
annotate
|
||||||
bcrypt (= 3.1.7)
|
|
||||||
bootstrap-sass (= 3.2.0.0)
|
bootstrap-sass (= 3.2.0.0)
|
||||||
bootstrap-will_paginate (= 0.0.10)
|
bootstrap-will_paginate (= 0.0.10)
|
||||||
byebug
|
byebug
|
||||||
|
@ -179,18 +273,25 @@ DEPENDENCIES
|
||||||
capistrano (~> 3.1)
|
capistrano (~> 3.1)
|
||||||
capistrano-rails (~> 1.1)
|
capistrano-rails (~> 1.1)
|
||||||
capistrano-rvm
|
capistrano-rvm
|
||||||
|
capybara
|
||||||
|
codeclimate-test-reporter
|
||||||
coffee-rails (~> 4.0.0)
|
coffee-rails (~> 4.0.0)
|
||||||
|
coveralls
|
||||||
devise
|
devise
|
||||||
faker (= 1.4.2)
|
faker (= 1.4.2)
|
||||||
jbuilder (~> 2.0)
|
jbuilder (~> 2.0)
|
||||||
jquery-rails
|
jquery-rails
|
||||||
|
launchy
|
||||||
mysql2
|
mysql2
|
||||||
|
omniauth-oauth2
|
||||||
|
paper_trail (~> 4.0.0.beta)
|
||||||
paperclip
|
paperclip
|
||||||
rails (= 4.1.7)
|
rails (= 4.2)
|
||||||
sass-rails (~> 4.0.3)
|
sass-rails (~> 4.0.3)
|
||||||
sdoc (~> 0.4.0)
|
sdoc (~> 0.4.0)
|
||||||
spring
|
spring
|
||||||
sqlite3
|
sqlite3
|
||||||
turbolinks
|
turbolinks
|
||||||
|
tzinfo-data
|
||||||
uglifier (>= 1.3.0)
|
uglifier (>= 1.3.0)
|
||||||
will_paginate (= 3.0.7)
|
will_paginate (= 3.0.7)
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
Tab
|
||||||
|
===
|
||||||
|
[![Code Climate](https://codeclimate.com/github/ZeusWPI/Tab/badges/gpa.svg)](https://codeclimate.com/github/ZeusWPI/Tab)
|
||||||
|
[![Travis CI](https://travis-ci.org/ZeusWPI/Tab.svg)](https://travis-ci.org/ZeusWPI/Tab)
|
||||||
|
[![Coverage Status](https://coveralls.io/repos/ZeusWPI/Tab/badge.svg?branch=master)](https://coveralls.io/r/ZeusWPI/Tab?branch=master)
|
||||||
|
|
||||||
|
Yes. We have to drink. But we also have to pay. This combines both.
|
3
app/assets/javascripts/callbacks.js.coffee
Normal file
3
app/assets/javascripts/callbacks.js.coffee
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Place all the behaviors and hooks related to the matching controller here.
|
||||||
|
# All this logic will automatically be available in application.js.
|
||||||
|
# You can use CoffeeScript in this file: http://coffeescript.org/
|
|
@ -8,19 +8,33 @@ ready = ->
|
||||||
$('.btn-dec').on 'click', ->
|
$('.btn-dec').on 'click', ->
|
||||||
increment($(this), -1)
|
increment($(this), -1)
|
||||||
|
|
||||||
$('.btn-dec').prop("disabled", true)
|
$('.form_row').each((index, row) ->
|
||||||
|
disIfNec(row)
|
||||||
|
$(row).on('input', recalculate)
|
||||||
|
)
|
||||||
|
|
||||||
|
recalculate()
|
||||||
|
|
||||||
|
disIfNec = (row) ->
|
||||||
|
counter = parseInt($(row).find('.row_counter').val())
|
||||||
|
$(row).find('.btn-dec').prop('disabled', counter == 0);
|
||||||
|
$(row).find('.btn-inc').prop('disabled', counter == parseInt($(row).find('.stock').val()))
|
||||||
|
|
||||||
|
recalculate = () ->
|
||||||
|
value = ($(row).find('.row_counter').val() * $(row).find('.price').val() for row in $('.form_row')).reduce (a, b) -> a+b
|
||||||
|
$('#order_price').val((value / 100.0).toFixed(2))
|
||||||
|
|
||||||
increment = (button, n) ->
|
increment = (button, n) ->
|
||||||
|
row = $(button).closest('.form_row')
|
||||||
|
|
||||||
# Fix the counter
|
# Fix the counter
|
||||||
counter = $(button).closest('.form_row').find('.row_counter')
|
counter = $(row).find('.row_counter')
|
||||||
counter.val(parseInt(counter.val()) + n)
|
counter.val(parseInt(counter.val()) + n)
|
||||||
|
|
||||||
# Enable or disable the dec button
|
# Disable buttons if necessary
|
||||||
counter.parent().find('.btn-dec').prop("disabled", counter.val() == '0');
|
disIfNec(row)
|
||||||
|
|
||||||
# Update the price
|
recalculate()
|
||||||
oldVal = parseFloat($('#order_total_price').val())
|
|
||||||
$('#order_total_price').val(parseFloat(oldVal + counter.parent().find('.price').val() * n).toFixed(2))
|
|
||||||
|
|
||||||
$(document).ready(ready)
|
$(document).ready(ready)
|
||||||
$(document).on('page:load', ready)
|
$(document).on('page:load', ready)
|
||||||
|
|
|
@ -29,76 +29,58 @@ $gray-medium-light: #eaeaea;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* miscellaneous */
|
/* miscellaneous */
|
||||||
|
|
||||||
.nowrap {
|
.nowrap {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* boostrap */
|
|
||||||
body {
|
|
||||||
padding-top: 80px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* footer */
|
|
||||||
footer {
|
|
||||||
margin-top: 45px;
|
|
||||||
padding-top: 5px;
|
|
||||||
border-top: 1px solid #eaeaea;
|
|
||||||
color: #777;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer a {
|
|
||||||
color: #555;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer a:hover {
|
|
||||||
color: #222;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer small {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer ul {
|
|
||||||
float: right;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer ul li {
|
|
||||||
float: left;
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overview{
|
|
||||||
//margin-left: 2px;
|
|
||||||
width: 50%;
|
|
||||||
float: left;
|
|
||||||
border-radius: 0px;
|
|
||||||
margin-bottom: 0px;
|
|
||||||
border: 0px;
|
|
||||||
|
|
||||||
.btn{
|
|
||||||
margin-top: -55px;
|
|
||||||
width: 100%;
|
|
||||||
border-color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dagschotel{
|
|
||||||
float:left;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar{
|
|
||||||
height: 190px;
|
|
||||||
width: 190px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.center{
|
.center{
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-field{
|
||||||
|
margin-bottom: 15px;
|
||||||
|
text-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bootstrap */
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding-top: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* footer */
|
||||||
|
|
||||||
|
footer {
|
||||||
|
margin-top: 45px;
|
||||||
|
padding-top: 5px;
|
||||||
|
border-top: 1px solid $gray-medium-light;
|
||||||
|
color: #777;
|
||||||
|
a {
|
||||||
|
color: #555;
|
||||||
|
&:hover {
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
small {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
float: right;
|
||||||
|
list-style: none;
|
||||||
|
li {
|
||||||
|
float: left;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.debug_dump{
|
.debug_dump{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-logo{
|
||||||
|
margin:10px;
|
||||||
|
font-size:30px;
|
||||||
|
}
|
||||||
|
|
3
app/assets/stylesheets/callbacks.css.scss
Normal file
3
app/assets/stylesheets/callbacks.css.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
// Place all the styles related to the callbacks controller here.
|
||||||
|
// They will automatically be included in application.css.
|
||||||
|
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
@ -1,3 +1,30 @@
|
||||||
// Place all the styles related to the Orders controller here.
|
// Place all the styles related to the Orders controller here.
|
||||||
// They will automatically be included in application.css.
|
// They will automatically be included in application.css.
|
||||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||||
|
|
||||||
|
.big-form-button {
|
||||||
|
height: 65px;
|
||||||
|
width: 65px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control.big-form-field {
|
||||||
|
height: 65px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form_row_image {
|
||||||
|
height: 100px;
|
||||||
|
width: 100px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
position: relative;
|
||||||
|
img {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
21
app/assets/stylesheets/overview.css.scss
Normal file
21
app/assets/stylesheets/overview.css.scss
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
.overviewthumbnail {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
border: 0px;
|
||||||
|
|
||||||
|
.btn{
|
||||||
|
margin-top: -55px;
|
||||||
|
width: 80%;
|
||||||
|
margin-left:10%;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dagschotel{
|
||||||
|
float:left;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar{
|
||||||
|
height: 150px;
|
||||||
|
width: 150px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,3 +5,20 @@
|
||||||
.orders .thumbnail {
|
.orders .thumbnail {
|
||||||
min-height: 200px;
|
min-height: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pic img {
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caption{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caption h3 {
|
||||||
|
margin: 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caption h6 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
73
app/assets/stylesheets/profile.css.scss
Normal file
73
app/assets/stylesheets/profile.css.scss
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/* User profile */
|
||||||
|
|
||||||
|
.user_info {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user_info h2 {
|
||||||
|
line-height: 45px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user_info h5 {
|
||||||
|
margin-right: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user_info .button_to input[type="submit"] {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #FFF;
|
||||||
|
padding: 12px 50px 12px 50px;
|
||||||
|
border: 1px solid #999;
|
||||||
|
width: 60%;
|
||||||
|
font-family: monospace;
|
||||||
|
|
||||||
|
text-shadow: 0px 1px 1px #666;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
|
||||||
|
background: #64a724;
|
||||||
|
background: -moz-linear-gradient(top, #64a724 0%, #579727 50%, #58982a 51%, #498c25 100%);
|
||||||
|
background: -webkit-gradient(linear, left top, left bottom, from(#64a724), to(#498c25), color-stop(0.4, #579727), color-stop(0.5, #58982a), color-stop(.9, #498c25), color-stop(0.9, #498c25));
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#64a724', endColorstr='#498c25', GradientType=0 );
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.debt {
|
||||||
|
padding: 12px 0;
|
||||||
|
text-align: center;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 16px;
|
||||||
|
width: 60%;
|
||||||
|
margin: auto;
|
||||||
|
margin-top: 10px;
|
||||||
|
background-color: #FF7F00;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats{
|
||||||
|
width: 60%;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats h4 {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-family: monospace;
|
||||||
|
background-color: #333;
|
||||||
|
color: white;
|
||||||
|
padding: 5px 10px;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0 0 0 15px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats li {
|
||||||
|
}
|
|
@ -3,6 +3,16 @@
|
||||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||||
|
|
||||||
|
|
||||||
|
//signin
|
||||||
|
.sign-in{
|
||||||
|
.checkbox label{
|
||||||
|
padding-left: 0px;
|
||||||
|
}
|
||||||
|
#user_remember_me{
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.users .thumbnail {
|
.users .thumbnail {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
min-height: 280px;
|
min-height: 280px;
|
||||||
|
@ -37,11 +47,6 @@
|
||||||
background-color: #f5f5dc;
|
background-color: #f5f5dc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* sidebar */
|
/* sidebar */
|
||||||
|
|
||||||
aside {
|
aside {
|
||||||
|
@ -69,3 +74,36 @@ aside {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orders {
|
||||||
|
margin-top: -10px;
|
||||||
|
line-height: 140%;
|
||||||
|
& tr:nth-child(even){
|
||||||
|
border-bottom: 1px solid #bbb;
|
||||||
|
td {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& tr:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
& tr:nth-child(odd) td {
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
& td.order_date {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.product_dagschotel {
|
||||||
|
height: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#users-table td {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
require 'csv'
|
require 'csv'
|
||||||
class AdminsController < ApplicationController
|
class AdminsController < ApplicationController
|
||||||
|
|
||||||
def schulden
|
def schulden
|
||||||
@users = User.all
|
authorize! :schulden, :admins
|
||||||
|
@users = User.members
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.csv do
|
format.csv do
|
||||||
headers['Content-Disposition'] = "attachment; filename=\"zeus-schulden\""
|
headers['Content-Disposition'] = "attachment; filename=\"zeus-schulden\""
|
||||||
|
|
|
@ -4,24 +4,28 @@ class ApplicationController < ActionController::Base
|
||||||
protect_from_forgery with: :exception
|
protect_from_forgery with: :exception
|
||||||
before_action :configure_permitted_parameters, if: :devise_controller?
|
before_action :configure_permitted_parameters, if: :devise_controller?
|
||||||
|
|
||||||
|
rescue_from CanCan::AccessDenied do |exception|
|
||||||
|
redirect_to root_path, flash: { error: exception.message }
|
||||||
|
end
|
||||||
|
|
||||||
def after_sign_in_path_for(resource)
|
def after_sign_in_path_for(resource)
|
||||||
root_path
|
root_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_sign_up_path_for(resource)
|
def after_sign_up_path_for(resource)
|
||||||
new_user_session_path
|
root_path
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def configure_permitted_parameters
|
def configure_permitted_parameters
|
||||||
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(
|
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(
|
||||||
:nickname, :name, :last_name, :password, :password_confirmation,
|
:nickname, :password, :password_confirmation,
|
||||||
:current_password, :avatar
|
:avatar
|
||||||
) }
|
) }
|
||||||
|
|
||||||
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(
|
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(
|
||||||
:password, :password_confirmation, :current_password, :avatar
|
:password, :password_confirmation, :current_password, :avatar
|
||||||
) }
|
) }
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
7
app/controllers/callbacks_controller.rb
Normal file
7
app/controllers/callbacks_controller.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
class CallbacksController < Devise::OmniauthCallbacksController
|
||||||
|
def zeuswpi
|
||||||
|
@user = User.from_omniauth(request.env["omniauth.auth"])
|
||||||
|
@user.save
|
||||||
|
sign_in_and_redirect @user
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,49 +1,74 @@
|
||||||
class OrdersController < ApplicationController
|
class OrdersController < ApplicationController
|
||||||
|
include ActionView::Helpers::NumberHelper
|
||||||
|
|
||||||
|
load_and_authorize_resource
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@user = User.find(params[:user_id])
|
init
|
||||||
@order = @user.orders.build
|
@order = @user.orders.build
|
||||||
@products = Product.all
|
|
||||||
@order_products = @order.order_products
|
|
||||||
|
|
||||||
@products.each do |p|
|
# products = @user.products.select("products.*", "sum(order_items.count) as count").group(:product_id).order("count desc")
|
||||||
@order_products.build(product: p)
|
# @order.g_order_items(products)
|
||||||
end
|
@order.g_order_items Product.all
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@user = User.find(params[:user_id])
|
init
|
||||||
@order = @user.orders.build(order_params)
|
@order = @user.orders.build order_params
|
||||||
@products = Product.all
|
|
||||||
@order_products = @order.order_products
|
|
||||||
if @order.save
|
if @order.save
|
||||||
flash[:success] = "Ordered things! Get your stuff!"
|
flash[:success] = "#{@order.to_sentence} ordered. Enjoy it!"
|
||||||
redirect_to root_path
|
redirect_to root_path
|
||||||
else
|
else
|
||||||
|
@order.g_order_items Product.all
|
||||||
render 'new'
|
render 'new'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def index
|
def destroy
|
||||||
@users_by_name = User.all.order(:name)
|
order = Order.find(params[:id])
|
||||||
@users_by_order = User.all.order(:orders_count).reverse_order
|
if order.created_at > 5.minutes.ago
|
||||||
|
order.cancel
|
||||||
|
flash[:success] = "Order has been removed."
|
||||||
|
else
|
||||||
|
flash[:error] = "This order has been placed too long ago, it can't be removed. Please contact a sysadmin."
|
||||||
|
end
|
||||||
|
redirect_to root_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def overview
|
||||||
|
@users = User.members.order(:nickname)
|
||||||
end
|
end
|
||||||
|
|
||||||
def quickpay
|
def quickpay
|
||||||
@user = User.find(params[:user_id])
|
user = User.find(params[:user_id])
|
||||||
order = @user.orders.build
|
order = user.orders.build
|
||||||
order.products << @user.dagschotel
|
order.order_items << OrderItem.new(count: 1, product: user.dagschotel, order: order)
|
||||||
if order.save
|
if order.save
|
||||||
flash[:success] = "Quick pay succeeded"
|
flash[:success] = "Quick pay succeeded. #{view_context.link_to("Undo", [user, order], method: :delete)}."
|
||||||
else
|
else
|
||||||
flash[:error] = "Quick pay went wrong ... Sorry!"
|
flash[:error] = order.errors.full_messages.first
|
||||||
end
|
end
|
||||||
redirect_to root_path
|
redirect_to root_path
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def init
|
||||||
|
@user = User.find(params[:user_id])
|
||||||
|
|
||||||
|
if @user.koelkast?
|
||||||
|
flash[:error] = "Koelkast can't order things."
|
||||||
|
redirect_to root_path
|
||||||
|
end
|
||||||
|
|
||||||
|
unless current_user.koelkast? || current_user.admin? || current_user == @user
|
||||||
|
flash[:error] = "Please don't order stuff for other people"
|
||||||
|
redirect_to root_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def order_params
|
def order_params
|
||||||
params.require(:order).permit(order_products_attributes: [:product_id, :count])
|
params.require(:order).permit(order_items_attributes: [:count, :price, product_attributes: [:id]])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
class ProductsController < ApplicationController
|
class ProductsController < ApplicationController
|
||||||
|
load_and_authorize_resource
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@product = Product.new
|
@product = Product.new
|
||||||
end
|
end
|
||||||
|
@ -6,14 +8,15 @@ class ProductsController < ApplicationController
|
||||||
def create
|
def create
|
||||||
@product = Product.new(product_params)
|
@product = Product.new(product_params)
|
||||||
if @product.save
|
if @product.save
|
||||||
redirect_to action: :index
|
redirect_to products_path
|
||||||
else
|
else
|
||||||
render :new
|
render 'new'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@products = Product.all
|
@products = Product.all
|
||||||
|
@categories = Product.categories
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
|
@ -24,7 +27,7 @@ class ProductsController < ApplicationController
|
||||||
@product = Product.find(params[:id])
|
@product = Product.find(params[:id])
|
||||||
if @product.update_attributes(product_params)
|
if @product.update_attributes(product_params)
|
||||||
flash[:success] = "Succesfully updated product"
|
flash[:success] = "Succesfully updated product"
|
||||||
redirect_to action: :index
|
redirect_to products_path
|
||||||
else
|
else
|
||||||
render 'edit'
|
render 'edit'
|
||||||
end
|
end
|
||||||
|
@ -36,10 +39,22 @@ class ProductsController < ApplicationController
|
||||||
redirect_to products_path
|
redirect_to products_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def stock
|
||||||
|
@products = Product.all
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_stock
|
||||||
|
@products = Product.all
|
||||||
|
@products.each do |product|
|
||||||
|
stock_inc = params[:products][product.id.to_s][:stock_inc].to_i
|
||||||
|
product.increment!(:stock, stock_inc) if stock_inc > 0
|
||||||
|
end
|
||||||
|
redirect_to products_path
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def product_params
|
def product_params
|
||||||
params.require(:product).permit(:name, :price, :avatar)
|
params.require(:product).permit(:name, :price, :avatar, :category, :stock)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,23 +1,66 @@
|
||||||
class UsersController < ApplicationController
|
class UsersController < ApplicationController
|
||||||
|
load_and_authorize_resource
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@user = User.find(params[:id])
|
@user = User.find_by_id(params[:id]) || current_user
|
||||||
@orders = @user.orders.paginate(page: params[:page])
|
@orders = @user.orders
|
||||||
|
.active
|
||||||
|
.order(:created_at)
|
||||||
|
.reverse_order
|
||||||
|
.paginate(page: params[:page])
|
||||||
|
@products = @user.products
|
||||||
|
.select("products.*", "sum(order_items.count) as count")
|
||||||
|
.where("orders.cancelled = ?", false)
|
||||||
|
.group(:product_id)
|
||||||
|
.order("count")
|
||||||
|
.reverse_order
|
||||||
|
@categories = @user.products
|
||||||
|
.select("products.category", "sum(order_items.count) as count")
|
||||||
|
.where("orders.cancelled = ?", false)
|
||||||
|
.group(:category)
|
||||||
end
|
end
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@users = User.all
|
@users = User.members
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
User.find(params[:id]).destroy
|
@user = User.find(params[:id])
|
||||||
|
@user.destroy
|
||||||
flash[:success] = "Succesfully removed user"
|
flash[:success] = "Succesfully removed user"
|
||||||
redirect_to users_path
|
redirect_to users_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def dagschotel
|
def edit_dagschotel
|
||||||
user = User.find(params[:user_id])
|
@user = User.find(params[:user_id])
|
||||||
user.dagschotel = Product.find(params[:product_id])
|
@dagschotel = @user.dagschotel
|
||||||
user.save
|
|
||||||
redirect_to edit_user_registration_path(user)
|
@products = Product.all
|
||||||
|
@categories = Product.categories
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_dagschotel
|
||||||
|
@user = User.find(params[:user_id])
|
||||||
|
@user.dagschotel = Product.find(params[:product_id])
|
||||||
|
|
||||||
|
@products = Product.all
|
||||||
|
@categories = Product.categories
|
||||||
|
|
||||||
|
if @user.save
|
||||||
|
flash[:success] = "Succesfully updated dagschotel"
|
||||||
|
redirect_to @user
|
||||||
|
else
|
||||||
|
flash[:error] = "Error updating dagschotel"
|
||||||
|
@dagschotel = @user.reload.dagschotel
|
||||||
|
render 'edit_dagschotel'
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def init
|
||||||
|
@user = User.find(params[:user_id])
|
||||||
|
redirect_to root_path, error: "You are not authorized to access this page." unless @user == current_user || current_user.admin?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
185
app/form_builders/formatted_form_builder.rb
Normal file
185
app/form_builders/formatted_form_builder.rb
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
class FormattedFormBuilder < ActionView::Helpers::FormBuilder
|
||||||
|
include ActionView::Helpers::TextHelper
|
||||||
|
include ActionView::Context
|
||||||
|
include ActionView::Helpers::NumberHelper
|
||||||
|
|
||||||
|
FIELD_HELPERS = %w[text_field number_field file_field password_field]
|
||||||
|
|
||||||
|
delegate :content_tag, to: :@template
|
||||||
|
|
||||||
|
def initialize(object_name, object, template, options)
|
||||||
|
@inline_errors = true
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
FIELD_HELPERS.each do |method_name|
|
||||||
|
with_method_name = "#{method_name}_with_format"
|
||||||
|
without_method_name = "#{method_name}_without_format"
|
||||||
|
|
||||||
|
define_method(with_method_name) do |name, options = {}|
|
||||||
|
form_group_builder(name, options) do
|
||||||
|
send(without_method_name, name, options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method_chain method_name, :format
|
||||||
|
end
|
||||||
|
|
||||||
|
def price_field(name, options = {})
|
||||||
|
options[:min] ||= 0
|
||||||
|
options[:step] ||= 0.01
|
||||||
|
# if object.is_a?(ActiveRecord::Base)
|
||||||
|
# options[:value] ||= object[name]
|
||||||
|
if object.respond_to?(name)
|
||||||
|
options[:value] ||= object.send name
|
||||||
|
end
|
||||||
|
options[:value] = number_with_precision(options[:value], precision: 2)
|
||||||
|
|
||||||
|
form_group_builder(name, options) do
|
||||||
|
number_field_without_format(name, options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_box_with_format(name, options = {}, checked_value = "1", unchecked_value = "0", &block)
|
||||||
|
options.symbolize_keys!
|
||||||
|
|
||||||
|
checkbox = check_box_without_format(name, options.except(:label), checked_value, unchecked_value)
|
||||||
|
label_content = block_given? ? capture(&block) : options[:label]
|
||||||
|
|
||||||
|
content_tag :div, class: control_wrapper_class do
|
||||||
|
checkbox + " " + label(name, label_content)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def counter(name, options = {})
|
||||||
|
form_group_builder(name, options) do
|
||||||
|
counter_button("btn-dec", "glyphicon-minus") +
|
||||||
|
text_field_without_format(name, options.merge({class: 'form-control row_counter big-form-field'})) +
|
||||||
|
counter_button("btn-inc", "glyphicon-plus")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method_chain :check_box, :format
|
||||||
|
|
||||||
|
def collection_select_with_format(name, collection, value_method = :to_s, text_method = :titlecase, options = {}, html_options = {})
|
||||||
|
form_group_builder(name, options, html_options) do
|
||||||
|
collection_select_without_format(name, collection, value_method, text_method, options, html_options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method_chain :collection_select, :format
|
||||||
|
|
||||||
|
def submit_with_format(name = nil, options = {})
|
||||||
|
options[:class] = submit_class unless options[:class]
|
||||||
|
content_tag :div, class: submit_wrapper_class do
|
||||||
|
submit_without_format(name, options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method_chain :submit, :format
|
||||||
|
|
||||||
|
def error_messages
|
||||||
|
if object.errors.any?
|
||||||
|
content_tag :div, class: "panel panel-danger form-errors" do
|
||||||
|
content_tag(:div, class: "panel-body") do
|
||||||
|
error_header + error_body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def error_header
|
||||||
|
content_tag(:div, class: "panel-heading") do
|
||||||
|
"#{pluralize(object.errors.count, "error")} prohibited this #{object.class.name.downcase} from being saved:"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def error_body
|
||||||
|
content_tag :ul do
|
||||||
|
object.errors.full_messages.map do |msg|
|
||||||
|
content_tag :li, msg
|
||||||
|
end.join.html_safe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def label_class
|
||||||
|
"control-label"
|
||||||
|
end
|
||||||
|
|
||||||
|
def control_class
|
||||||
|
"form-control"
|
||||||
|
end
|
||||||
|
|
||||||
|
def control_wrapper_class
|
||||||
|
"form-group"
|
||||||
|
end
|
||||||
|
|
||||||
|
def submit_class
|
||||||
|
"btn btn-primary"
|
||||||
|
end
|
||||||
|
|
||||||
|
def submit_wrapper_class
|
||||||
|
"actions"
|
||||||
|
end
|
||||||
|
|
||||||
|
def form_group(*args, &block)
|
||||||
|
options = args.extract_options!
|
||||||
|
name = args.first
|
||||||
|
|
||||||
|
options[:class] = [control_wrapper_class, options[:class]].compact.join(' ')
|
||||||
|
|
||||||
|
content_tag(:div, options.except(:label)) do
|
||||||
|
label = generate_label(name, options[:label]) if options[:label]
|
||||||
|
control = capture(&block).to_s
|
||||||
|
|
||||||
|
if label
|
||||||
|
label + control
|
||||||
|
else
|
||||||
|
control
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def form_group_builder(method, options, html_options = nil)
|
||||||
|
options.symbolize_keys!
|
||||||
|
|
||||||
|
css_options = html_options || options
|
||||||
|
css_options[:class] = [control_class, css_options[:class]].compact.join(" ")
|
||||||
|
|
||||||
|
wrapper_class = css_options.delete(:wrapper_class)
|
||||||
|
wrapper_options = css_options.delete(:wrapper)
|
||||||
|
|
||||||
|
form_group_options = {
|
||||||
|
class: wrapper_class
|
||||||
|
}
|
||||||
|
|
||||||
|
if wrapper_options.is_a?(Hash)
|
||||||
|
form_group_options.merge!(wrapper_options)
|
||||||
|
end
|
||||||
|
|
||||||
|
unless options.delete(:skip_label)
|
||||||
|
form_group_options.reverse_merge!(label: {
|
||||||
|
text: options.delete(:label),
|
||||||
|
class: label_class
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
form_group(method, form_group_options) do
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_label(name, options = {})
|
||||||
|
label("#{name}:", options[:text], options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def counter_button(button, glyphicon)
|
||||||
|
content_tag :span, class: "input-group-btn" do
|
||||||
|
content_tag :button, class: "btn btn-default btn-lg #{button}", type: "button" do
|
||||||
|
content_tag :span, "", class: "glyphicon btn-lg #{glyphicon}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,2 +0,0 @@
|
||||||
module AdminsHelper
|
|
||||||
end
|
|
|
@ -10,57 +10,11 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def euro(f)
|
def euro(f)
|
||||||
"€#{number_with_precision f, precision: 2}"
|
number_to_currency(f, unit: '€')
|
||||||
end
|
end
|
||||||
|
|
||||||
#tijdelijk voor layout
|
def f_form_for(record, options = {}, &block)
|
||||||
def koelkast(status)
|
options[:builder] = FormattedFormBuilder
|
||||||
@koelkast ||= status
|
form_for(record, options, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Form helpers
|
|
||||||
def form_errors(object)
|
|
||||||
render partial: "form_errors", locals: {object: object}
|
|
||||||
end
|
|
||||||
|
|
||||||
def form_text_field(f, tag)
|
|
||||||
render partial: "form_text_field", locals: {f: f, tag: tag}
|
|
||||||
end
|
|
||||||
|
|
||||||
def form_password_field(f, tag)
|
|
||||||
render partial: "form_password_field", locals: {f: f, tag: tag}
|
|
||||||
end
|
|
||||||
|
|
||||||
def form_text_area(f, tag)
|
|
||||||
render partial: "form_text_area", locals: {f: f, tag: tag}
|
|
||||||
end
|
|
||||||
|
|
||||||
def form_fancy_text_area(f, tag)
|
|
||||||
render partial: "form_fancy_text_area", locals: {f: f, tag: tag}
|
|
||||||
end
|
|
||||||
|
|
||||||
def form_email_field(f, tag)
|
|
||||||
render partial: "form_email_field", locals: {f: f, tag: tag}
|
|
||||||
end
|
|
||||||
|
|
||||||
def form_date_field(f, tag, id, value)
|
|
||||||
render partial: "form_date_field", locals: {f: f, tag: tag, id: id, value: value}
|
|
||||||
end
|
|
||||||
|
|
||||||
def form_number_field(f, tag)
|
|
||||||
render partial: "form_number_field", locals: {f: f, tag: tag}
|
|
||||||
end
|
|
||||||
|
|
||||||
def form_collection_select(f, *args)
|
|
||||||
# This line enable passing optional arguments such as include_blank to the
|
|
||||||
# partial. If nothing is passed, an empty options hash is appended.
|
|
||||||
args << {} if args.length < 5
|
|
||||||
|
|
||||||
render partial: "form_collection_select", locals: {f: f, args: args}
|
|
||||||
end
|
|
||||||
|
|
||||||
def form_check_box(f, tag)
|
|
||||||
render partial: "form_check_box", locals: {f: f, tag: tag}
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
2
app/helpers/callbacks_helper.rb
Normal file
2
app/helpers/callbacks_helper.rb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
module CallbacksHelper
|
||||||
|
end
|
|
@ -1,21 +0,0 @@
|
||||||
module DeviseHelper
|
|
||||||
|
|
||||||
def devise_error_messages!
|
|
||||||
return '' if resource.errors.empty?
|
|
||||||
|
|
||||||
messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
|
|
||||||
sentence = I18n.t('errors.messages.not_saved',
|
|
||||||
count: resource.errors.count,
|
|
||||||
resource: resource.class.model_name.human.downcase)
|
|
||||||
|
|
||||||
html = <<-HTML
|
|
||||||
<div class="alert alert-danger alert-dismissable">
|
|
||||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
|
||||||
<strong>Error!</strong> #{sentence}
|
|
||||||
#{messages}
|
|
||||||
</div>
|
|
||||||
HTML
|
|
||||||
|
|
||||||
html.html_safe
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,2 +0,0 @@
|
||||||
module OrdersHelper
|
|
||||||
end
|
|
|
@ -1,2 +0,0 @@
|
||||||
module ProductsHelper
|
|
||||||
end
|
|
|
@ -1,2 +0,0 @@
|
||||||
module UsersHelper
|
|
||||||
end
|
|
|
@ -5,8 +5,15 @@ class Ability
|
||||||
user ||= User.new # guest user (not logged in)
|
user ||= User.new # guest user (not logged in)
|
||||||
if user.admin?
|
if user.admin?
|
||||||
can :manage, :all
|
can :manage, :all
|
||||||
else
|
can :schulden, :admins
|
||||||
|
elsif user.koelkast?
|
||||||
|
can :manage, Order
|
||||||
|
elsif user[:id]
|
||||||
can :read, :all
|
can :read, :all
|
||||||
|
can :update, User
|
||||||
|
can :edit_dagschotel, User
|
||||||
|
can :update_dagschotel, User
|
||||||
|
can :create, Order
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,47 +2,63 @@
|
||||||
#
|
#
|
||||||
# Table name: orders
|
# Table name: orders
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# user_id :integer
|
# user_id :integer
|
||||||
# cost :integer
|
# price_cents :integer
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
|
# cancelled :boolean default("f")
|
||||||
#
|
#
|
||||||
|
|
||||||
class Order < ActiveRecord::Base
|
class Order < ActiveRecord::Base
|
||||||
after_initialize { self.total_price = 0 }
|
include ActionView::Helpers::TextHelper
|
||||||
after_create :pay_price
|
|
||||||
|
after_create { self.user.increment!(:debt_cents, price_cents) }
|
||||||
|
|
||||||
belongs_to :user, counter_cache: true
|
belongs_to :user, counter_cache: true
|
||||||
has_many :order_products
|
has_many :order_items, dependent: :destroy
|
||||||
has_many :products, { through: :order_products} do
|
has_many :products, through: :order_items
|
||||||
def << (product)
|
|
||||||
if proxy_association.owner.products.include?(product)
|
scope :active, -> { where(cancelled: false) }
|
||||||
proxy_association.owner.order_products.find_by(product: product).increment!(:count, 1)
|
|
||||||
|
validates :user, presence: true
|
||||||
|
validates :order_items, presence: true, in_stock: true
|
||||||
|
|
||||||
|
accepts_nested_attributes_for :order_items, reject_if: proc { |oi| oi[:count].to_i <= 0 }
|
||||||
|
|
||||||
|
def price_cents
|
||||||
|
self.order_items.map{ |oi| oi.count * oi.product.price_cents }.sum
|
||||||
|
end
|
||||||
|
|
||||||
|
def price
|
||||||
|
self.price_cents / 100.0
|
||||||
|
end
|
||||||
|
|
||||||
|
def price=(_)
|
||||||
|
write_attribute(:price_cents, price_cents)
|
||||||
|
end
|
||||||
|
|
||||||
|
def cancel
|
||||||
|
return if self.cancelled
|
||||||
|
user.decrement!(:debt_cents, price_cents)
|
||||||
|
User.decrement_counter(:orders_count, user.id)
|
||||||
|
update_attribute(:cancelled, true)
|
||||||
|
self.order_items.each(&:cancel)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_sentence
|
||||||
|
self.order_items.map {
|
||||||
|
|oi| pluralize(oi.count, oi.product.name)
|
||||||
|
}.to_sentence
|
||||||
|
end
|
||||||
|
|
||||||
|
def g_order_items(products)
|
||||||
|
products.each do |p|
|
||||||
|
if (oi = self.order_items.select { |t| t.product == p }).size > 0
|
||||||
|
oi.first.count = [oi.first.product.stock, oi.first.count].min
|
||||||
else
|
else
|
||||||
super
|
self.order_items.build(product: p)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_accessor :total_price
|
|
||||||
|
|
||||||
validates :user, presence: true
|
|
||||||
validates :order_products, presence: true
|
|
||||||
|
|
||||||
accepts_nested_attributes_for :order_products, reject_if: proc { |op| op[:count].to_i <= 0 }
|
|
||||||
|
|
||||||
def price
|
|
||||||
price = 0
|
|
||||||
order_products.each do |op|
|
|
||||||
price += op.count * op.product.read_attribute(:price)
|
|
||||||
end
|
|
||||||
price
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def pay_price
|
|
||||||
user.pay(price)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
36
app/models/order_item.rb
Normal file
36
app/models/order_item.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: order_items
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# order_id :integer
|
||||||
|
# product_id :integer not null
|
||||||
|
# count :integer default("0")
|
||||||
|
#
|
||||||
|
|
||||||
|
class OrderItem < ActiveRecord::Base
|
||||||
|
belongs_to :order
|
||||||
|
belongs_to :product
|
||||||
|
|
||||||
|
validates :product, presence: true
|
||||||
|
validates :count, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
||||||
|
|
||||||
|
after_create :remove_from_stock
|
||||||
|
|
||||||
|
accepts_nested_attributes_for :product
|
||||||
|
|
||||||
|
def product_attributes=(attributes)
|
||||||
|
self.product = Product.find(attributes[:id])
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def cancel
|
||||||
|
self.product.increment!(:stock, self.count)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def remove_from_stock
|
||||||
|
product.decrement!(:stock, count)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,19 +0,0 @@
|
||||||
# == Schema Information
|
|
||||||
#
|
|
||||||
# Table name: order_products
|
|
||||||
#
|
|
||||||
# id :integer not null, primary key
|
|
||||||
# order_id :integer
|
|
||||||
# product_id :integer
|
|
||||||
# count :integer default(1)
|
|
||||||
#
|
|
||||||
|
|
||||||
class OrderProduct < ActiveRecord::Base
|
|
||||||
belongs_to :order
|
|
||||||
belongs_to :product
|
|
||||||
|
|
||||||
validates :product, presence: true
|
|
||||||
validates :count, numericality: { greater_than_or_equal_to: 0 }
|
|
||||||
|
|
||||||
accepts_nested_attributes_for :product
|
|
||||||
end
|
|
|
@ -3,36 +3,37 @@
|
||||||
# Table name: products
|
# Table name: products
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# name :string(255)
|
# name :string not null
|
||||||
# price :integer
|
# price_cents :integer default("0"), not null
|
||||||
# created_at :datetime
|
# created_at :datetime
|
||||||
# updated_at :datetime
|
# updated_at :datetime
|
||||||
# avatar_file_name :string(255)
|
# avatar_file_name :string
|
||||||
# avatar_content_type :string(255)
|
# avatar_content_type :string
|
||||||
# avatar_file_size :integer
|
# avatar_file_size :integer
|
||||||
# avatar_updated_at :datetime
|
# avatar_updated_at :datetime
|
||||||
|
# category :integer default("0")
|
||||||
|
# stock :integer default("0"), not null
|
||||||
#
|
#
|
||||||
|
|
||||||
class Product < ActiveRecord::Base
|
class Product < ActiveRecord::Base
|
||||||
has_many :order_products
|
has_many :order_items
|
||||||
has_attached_file :avatar, styles: { medium: "100x100>" }, default_style: :medium
|
has_attached_file :avatar, styles: { dagschotel: "80x80>", medium: "100x100>" }, default_style: :medium
|
||||||
|
|
||||||
|
enum category: %w(food beverages other)
|
||||||
|
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
validates :price, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
validates :price_cents, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
||||||
validates_attachment :avatar, presence: true, content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] },
|
validates :stock, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
||||||
default_url: "http://babeholder.pixoil.com/img/190/190"
|
validates_attachment :avatar,
|
||||||
|
presence: true,
|
||||||
def count(order)
|
content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] }
|
||||||
order_products.find_by(order: order).count
|
|
||||||
end
|
|
||||||
|
|
||||||
def price
|
def price
|
||||||
(read_attribute(:price) || 0) / 100.0
|
self.price_cents / 100.0
|
||||||
end
|
end
|
||||||
|
|
||||||
def price=(value)
|
def price=(value)
|
||||||
if value.is_a? String then value.sub!(',', '.') end
|
if value.is_a? String then value.sub!(',', '.') end
|
||||||
write_attribute(:price, (value.to_f * 100).to_int)
|
self.price_cents = (value.to_f * 100).to_int
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,52 +3,76 @@
|
||||||
# Table name: users
|
# Table name: users
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# name :string(255)
|
# debt_cents :integer default("0"), not null
|
||||||
# last_name :string(255)
|
# nickname :string
|
||||||
# balance :integer default(0)
|
|
||||||
# nickname :string(255)
|
|
||||||
# created_at :datetime
|
# created_at :datetime
|
||||||
# updated_at :datetime
|
# updated_at :datetime
|
||||||
# encrypted_password :string(255) default(""), not null
|
# encrypted_password :string default(""), not null
|
||||||
# remember_created_at :datetime
|
# remember_created_at :datetime
|
||||||
# sign_in_count :integer default(0), not null
|
# sign_in_count :integer default("0"), not null
|
||||||
# current_sign_in_at :datetime
|
# current_sign_in_at :datetime
|
||||||
# last_sign_in_at :datetime
|
# last_sign_in_at :datetime
|
||||||
# current_sign_in_ip :string(255)
|
# current_sign_in_ip :string
|
||||||
# last_sign_in_ip :string(255)
|
# last_sign_in_ip :string
|
||||||
# dagschotel :reference
|
# admin :boolean
|
||||||
# dagschotel_id :integer
|
# dagschotel_id :integer
|
||||||
|
# avatar_file_name :string
|
||||||
|
# avatar_content_type :string
|
||||||
|
# avatar_file_size :integer
|
||||||
|
# avatar_updated_at :datetime
|
||||||
|
# orders_count :integer default("0")
|
||||||
|
# koelkast :boolean default("f")
|
||||||
|
# provider :string
|
||||||
|
# uid :string
|
||||||
#
|
#
|
||||||
|
|
||||||
class User < ActiveRecord::Base
|
class User < ActiveRecord::Base
|
||||||
devise :database_authenticatable, :registerable,
|
devise :database_authenticatable, :registerable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:zeuswpi]
|
||||||
:rememberable, :trackable
|
|
||||||
has_attached_file :avatar, styles: { medium: "100x100>" }, default_style: :medium, default_url: "http://babeholder.pixoil.com/img/70/70"
|
has_paper_trail only: [:debt_cents, :admin, :orders_count, :koelkast]
|
||||||
|
|
||||||
|
has_attached_file :avatar, styles: { large: "150x150>", medium: "100x100>", small: "40x40>" }, default_style: :medium
|
||||||
|
|
||||||
has_many :orders, -> { includes :products }
|
has_many :orders, -> { includes :products }
|
||||||
|
has_many :products, through: :orders
|
||||||
belongs_to :dagschotel, class_name: 'Product'
|
belongs_to :dagschotel, class_name: 'Product'
|
||||||
|
|
||||||
validates :nickname, presence: true, uniqueness: true
|
validates :nickname, presence: true, uniqueness: true
|
||||||
validates :name, presence: true
|
validates_attachment :avatar,
|
||||||
validates :last_name, presence: true
|
presence: true,
|
||||||
validates :password, length: { in: 8..128 }, confirmation: true, on: :create
|
content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] }
|
||||||
validates_attachment :avatar, presence: true, content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] }
|
|
||||||
|
|
||||||
def full_name
|
scope :members, -> { where koelkast: false }
|
||||||
"#{name} #{last_name}"
|
|
||||||
|
def self.from_omniauth(auth)
|
||||||
|
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
|
||||||
|
user.provider = auth.provider
|
||||||
|
user.uid = auth.uid
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def pay(amount)
|
def debt
|
||||||
write_attribute(:balance, read_attribute(:balance) - amount)
|
self.debt_cents / 100.0
|
||||||
self.save
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def balance
|
def debt=(value)
|
||||||
(read_attribute(:balance) || 0) / 100.0
|
|
||||||
end
|
|
||||||
|
|
||||||
def balance=(value)
|
|
||||||
if value.is_a? String then value.sub!(',', '.') end
|
if value.is_a? String then value.sub!(',', '.') end
|
||||||
write_attribute(:balance, (value.to_f * 100).to_int)
|
self.debt_cents = (value.to_f * 100).to_int
|
||||||
|
end
|
||||||
|
|
||||||
|
# Change URL params for User
|
||||||
|
|
||||||
|
def to_param
|
||||||
|
"#{id} #{nickname}".parameterize
|
||||||
|
end
|
||||||
|
|
||||||
|
# This is needed so Devise doesn't try to validate :email
|
||||||
|
|
||||||
|
def email_required?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def email_changed?
|
||||||
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
9
app/validators/in_stock_validator.rb
Normal file
9
app/validators/in_stock_validator.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
class InStockValidator < ActiveModel::Validator
|
||||||
|
def validate(record)
|
||||||
|
p_short = []
|
||||||
|
record.order_items.each do |oi|
|
||||||
|
p_short.append oi.product.name if oi.count > oi.product.stock
|
||||||
|
end
|
||||||
|
record.errors.add(:base, "There is not enough stock for your order of the following products: #{p_short.join(', ')}") if p_short.size > 0
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,5 +1,3 @@
|
||||||
<%- headers = ['nickname', 'schulden'] -%>
|
<%- headers = ['nickname', 'schulden'] -%>
|
||||||
<%= CSV.generate_line headers %>
|
<%= CSV.generate_line headers -%>
|
||||||
<%- @users.each do |user| -%>
|
<% @users.each do |user| %><%= CSV.generate_line([user.nickname, user.debt]) %><% end %>
|
||||||
<%= CSV.generate_line([user.nickname, user.balance]) %>
|
|
||||||
<%- end -%>
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
<span class="input-group-btn">
|
|
||||||
<button class="btn btn-default btn-dec" type="button">
|
|
||||||
<span class="glyphicon glyphicon-minus"></span>
|
|
||||||
</button>
|
|
||||||
</span>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<span class="input-group-btn">
|
|
||||||
<button class="btn btn-default btn-inc" type="button">
|
|
||||||
<span class="glyphicon glyphicon-plus"></span>
|
|
||||||
</button>
|
|
||||||
</span>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<% if model.errors.any? %>
|
|
||||||
<div class="panel panel-danger form-errors">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<%= pluralize(model.errors.count, "error") %> prohibited this <%= model.class.name.downcase %> from being saved:
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<ul>
|
|
||||||
<% model.errors.full_messages.each do |msg| %>
|
|
||||||
<li><%= msg %></li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
|
@ -8,7 +8,7 @@
|
||||||
<% if flash[:success] %>
|
<% if flash[:success] %>
|
||||||
<div class="alert alert-success alert-dismissable">
|
<div class="alert alert-success alert-dismissable">
|
||||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||||
<strong>Success!</strong> <%= flash[:success] %>
|
<strong>Success!</strong> <%= raw flash[:success] %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if flash[:notice] %>
|
<% if flash[:notice] %>
|
||||||
|
@ -23,4 +23,10 @@
|
||||||
<strong>Warning!</strong> <%= flash[:warning] %>
|
<strong>Warning!</strong> <%= flash[:warning] %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<% if flash[:alert] %>
|
||||||
|
<div class="alert alert-danger alert-dismissable">
|
||||||
|
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||||
|
<strong>Error!</strong> <%= flash[:alert] %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
<div class="checkbox">
|
|
||||||
<label>
|
|
||||||
<%= f.label tag %>
|
|
||||||
</label>
|
|
||||||
<%= f.check_box tag %>
|
|
||||||
</div>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<%# To pass options to the collection_select, add {options} as the last argument %>
|
|
||||||
<div class="form-group">
|
|
||||||
<%= f.label args.first %>:
|
|
||||||
<%= f.collection_select *args, {class: 'form-control'} %>
|
|
||||||
</div>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<div class="form-group">
|
|
||||||
<%= f.label tag %>:
|
|
||||||
<div class="input-group">
|
|
||||||
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
|
|
||||||
<%= f.text_field tag, class: 'form-control', id: id, value: value %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,4 +0,0 @@
|
||||||
<div class="form-group">
|
|
||||||
<%= f.label tag %>:
|
|
||||||
<%= f.email_field tag, class: 'form-control' %>
|
|
||||||
</div>
|
|
|
@ -1,14 +0,0 @@
|
||||||
<% if object.errors.any? %>
|
|
||||||
<div class="panel panel-danger form-errors">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<%= pluralize(object.errors.count, "error") %> prohibited this <%= object.class.name.downcase %> from being saved:
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<ul>
|
|
||||||
<% object.errors.full_messages.each do |msg| %>
|
|
||||||
<li><%= msg %></li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
|
@ -1,4 +0,0 @@
|
||||||
<div class="form-group">
|
|
||||||
<%= f.label tag %>:
|
|
||||||
<%= f.text_area tag, class: 'form-control ckeditor' %>
|
|
||||||
</div>
|
|
|
@ -1,4 +0,0 @@
|
||||||
<div class="form-group">
|
|
||||||
<%= f.label tag %>:
|
|
||||||
<%= f.number_field tag, class: 'form-control', min: 0 %>
|
|
||||||
</div>
|
|
|
@ -1,4 +0,0 @@
|
||||||
<div class="form-group">
|
|
||||||
<%= f.label tag %>:
|
|
||||||
<%= f.password_field tag, class: 'form-control' %>
|
|
||||||
</div>
|
|
|
@ -1,4 +0,0 @@
|
||||||
<div class="form-group">
|
|
||||||
<%= f.label tag %>:
|
|
||||||
<%= f.text_area tag, class: 'form-control' %>
|
|
||||||
</div>
|
|
|
@ -1,4 +0,0 @@
|
||||||
<div class="form-group">
|
|
||||||
<%= f.label tag %>:
|
|
||||||
<%= f.text_field tag, class: 'form-control' %>
|
|
||||||
</div>
|
|
|
@ -1,16 +0,0 @@
|
||||||
<h2>Resend confirmation instructions</h2>
|
|
||||||
|
|
||||||
<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
|
|
||||||
<%= devise_error_messages! %>
|
|
||||||
|
|
||||||
<div class="field">
|
|
||||||
<%= f.label :email %><br />
|
|
||||||
<%= f.email_field :email, autofocus: true %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="actions">
|
|
||||||
<%= f.submit "Resend confirmation instructions" %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= render "devise/shared/links" %>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<p>Welcome <%= @email %>!</p>
|
|
||||||
|
|
||||||
<p>You can confirm your account email through the link below:</p>
|
|
||||||
|
|
||||||
<p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>
|
|
|
@ -1,8 +0,0 @@
|
||||||
<p>Hello <%= @resource.email %>!</p>
|
|
||||||
|
|
||||||
<p>Someone has requested a link to change your password. You can do this through the link below.</p>
|
|
||||||
|
|
||||||
<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>
|
|
||||||
|
|
||||||
<p>If you didn't request this, please ignore this email.</p>
|
|
||||||
<p>Your password won't change until you access the link above and create a new one.</p>
|
|
|
@ -1,7 +0,0 @@
|
||||||
<p>Hello <%= @resource.email %>!</p>
|
|
||||||
|
|
||||||
<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>
|
|
||||||
|
|
||||||
<p>Click the link below to unlock your account:</p>
|
|
||||||
|
|
||||||
<p><%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %></p>
|
|
|
@ -1,16 +0,0 @@
|
||||||
<h2>Change your password</h2>
|
|
||||||
|
|
||||||
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| %>
|
|
||||||
<%= devise_error_messages! %>
|
|
||||||
<%= f.hidden_field :reset_password_token %>
|
|
||||||
|
|
||||||
<div><%= f.label :password, "New password" %><br />
|
|
||||||
<%= f.password_field :password, :autofocus => true %></div>
|
|
||||||
|
|
||||||
<div><%= f.label :password_confirmation, "Confirm new password" %><br />
|
|
||||||
<%= f.password_field :password_confirmation %></div>
|
|
||||||
|
|
||||||
<div><%= f.submit "Change my password" %></div>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= render "devise/shared/links" %>
|
|
|
@ -1,10 +0,0 @@
|
||||||
<h2>Forgot your password?</h2>
|
|
||||||
|
|
||||||
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
|
|
||||||
<%= devise_error_messages! %>
|
|
||||||
|
|
||||||
<%= form_email_field f, :email %>
|
|
||||||
<%= f.submit "Send me reset password instructions", class: "btn btn-primary" %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= render "devise/shared/links" %>
|
|
|
@ -1,31 +1,15 @@
|
||||||
<h2>Edit <%= resource_name.to_s.humanize %></h2>
|
<h2>Edit <%= resource_name.to_s.humanize %></h2>
|
||||||
|
<%= render 'flash' %>
|
||||||
|
|
||||||
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
|
<%= f_form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
|
||||||
<%= devise_error_messages! %>
|
<%= f.error_messages %>
|
||||||
|
|
||||||
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
|
<%= f.password_field :password %>
|
||||||
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
|
<%= f.password_field :password_confirmation %>
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= form_password_field f, :password %>
|
<%= f.password_field :current_password %>
|
||||||
<%= form_password_field f, :password_confirmation %>
|
|
||||||
|
|
||||||
<%= form_password_field f, :current_password %>
|
|
||||||
|
|
||||||
<%= f.label :avatar %>
|
|
||||||
<%= f.file_field :avatar %>
|
<%= f.file_field :avatar %>
|
||||||
|
|
||||||
<%= f.submit "Update", class: 'btn btn-primary' %>
|
<%= f.submit "Update" %>
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<% if current_user.dagschotel.present? %>
|
|
||||||
<h3>Current Dagschotel:</h3>
|
|
||||||
<div>
|
|
||||||
<%= image_tag current_user.dagschotel.avatar %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<h4>Choose new Dagschotel:</h4>
|
|
||||||
<% Product.all.each do |p| %>
|
|
||||||
<%= link_to image_tag(p.avatar), user_dagschotel_path(current_user, p) %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -1,20 +1,16 @@
|
||||||
<h2>Sign up</h2>
|
<h2>Sign up</h2>
|
||||||
|
|
||||||
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
|
<%= f_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
|
||||||
<%= devise_error_messages! %>
|
<%= f.error_messages %>
|
||||||
|
|
||||||
<%= form_text_field f, :nickname %>
|
<%= f.text_field :nickname %>
|
||||||
<%= form_text_field f, :name %>
|
|
||||||
<%= form_text_field f, :last_name %>
|
|
||||||
|
|
||||||
<%= form_password_field f, :password %>
|
<%= f.password_field :password %>
|
||||||
<%= form_password_field f, :password_confirmation %>
|
<%= f.password_field :password_confirmation %>
|
||||||
|
|
||||||
<%= f.label :avatar %>
|
|
||||||
<%= f.file_field :avatar %>
|
<%= f.file_field :avatar %>
|
||||||
|
|
||||||
<br />
|
<%= f.submit "Sign up" %>
|
||||||
<%= f.submit "Sign up", class: 'btn btn-primary' %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= render "devise/shared/links" %>
|
<%= render "devise/shared/links" %>
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
<h2>Sign in</h2>
|
<h2>Sign in</h2>
|
||||||
<div class="alert alert-info">Partners sign in using the link sent by email.</div>
|
<%= render partial: 'flash' %>
|
||||||
|
|
||||||
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
|
<div class="sign-in">
|
||||||
|
<%= f_form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
|
||||||
|
<%= f.text_field :nickname %>
|
||||||
|
<%= f.password_field :password %>
|
||||||
|
|
||||||
<%= form_text_field f, :nickname %>
|
<% if devise_mapping.rememberable? %>
|
||||||
<%= form_password_field f, :password %>
|
<%= f.check_box :remember_me %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<% if devise_mapping.rememberable? %>
|
<%= f.submit "Sign in" %>
|
||||||
<%= form_check_box f, :remember_me %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
</div>
|
||||||
<%= f.submit "Sign in", class: "btn btn-primary" %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= render "devise/shared/links" %>
|
<%= render "devise/shared/links" %>
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
<%- if controller_name != 'sessions' %>
|
|
||||||
<%= link_to "Sign in", new_session_path(resource_name) %><br />
|
|
||||||
<% end -%>
|
|
||||||
|
|
||||||
<% if devise_mapping.registerable? && controller_name != 'registrations' %>
|
|
||||||
<% link_to "Sign up", new_registration_path(resource_name) %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
|
|
||||||
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
|
|
||||||
<% end -%>
|
|
||||||
|
|
||||||
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
|
|
||||||
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
|
|
||||||
<% end -%>
|
|
||||||
|
|
||||||
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
|
|
||||||
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
|
|
||||||
<% end -%>
|
|
||||||
|
|
||||||
<%- if devise_mapping.omniauthable? %>
|
|
||||||
<%- resource_class.omniauth_providers.each do |provider| %>
|
|
||||||
<%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %><br />
|
|
||||||
<% end -%>
|
|
||||||
<% end -%>
|
|
|
@ -1,16 +0,0 @@
|
||||||
<h2>Resend unlock instructions</h2>
|
|
||||||
|
|
||||||
<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
|
|
||||||
<%= devise_error_messages! %>
|
|
||||||
|
|
||||||
<div class="field">
|
|
||||||
<%= f.label :nickname %><br />
|
|
||||||
<%= f.email_field :nickname, autofocus: true %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="actions">
|
|
||||||
<%= f.submit "Resend unlock instructions" %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<%= render "devise/shared/links" %>
|
|
|
@ -1,7 +1,8 @@
|
||||||
<footer class="footer">
|
<% unless current_user && current_user.koelkast? %>
|
||||||
|
<footer class="footer">
|
||||||
<small>
|
<small>
|
||||||
<%= link_to "Tab", root_path %></a>
|
<%= link_to "Tab", root_path %></a>
|
||||||
by <%= link_to "Zeus WPI", "//zeus.ugent.be" %>
|
by <%= link_to "Zeus WPI", "//zeus.ugent.be" %>
|
||||||
</small>
|
</small>
|
||||||
<nav>
|
<nav>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -10,3 +11,4 @@
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</footer>
|
</footer>
|
||||||
|
<% end %>
|
||||||
|
|
|
@ -7,60 +7,66 @@
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
</button>
|
</button>
|
||||||
<%= link_to "Taþ", root_path, class: "navbar-brand" %>
|
<%= link_to "Taþ", root_path, class: "navbar-brand nav-logo" %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||||
<div class="collapse navbar-collapse">
|
<% unless current_user && current_user.koelkast? %>
|
||||||
<div class="hidden-xs navbar-form navbar-right">
|
<div class="collapse navbar-collapse">
|
||||||
<div class="form-group">
|
<div class="hidden-xs navbar-form navbar-right">
|
||||||
<% if user_signed_in? %>
|
<div class="form-group">
|
||||||
<%= button_to "Logout", destroy_user_session_path, class: "btn btn-default form-control", method: :delete %>
|
<% if user_signed_in? %>
|
||||||
<% else %>
|
<%= button_to "Logout", destroy_user_session_path, class: "btn btn-default form-control", method: :delete %>
|
||||||
<%= link_to "Login", new_user_session_path, class: "btn btn-success form-control" %>
|
<% else %>
|
||||||
<%= link_to "Register", new_user_registration_path, class: "btn btn-default form-control" %>
|
<%= link_to "Login", new_user_session_path, class: "btn btn-success form-control" %>
|
||||||
<% end %>
|
<%= link_to "Register", new_user_registration_path, class: "btn btn-default form-control" %>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul class="nav navbar-nav navbar-right">
|
|
||||||
<li><%= mail_to "tab@zeus.ugent.be", "Send feedback" %></li>
|
|
||||||
<% if user_signed_in? %>
|
|
||||||
<% if can? :manage, :all %>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Products <span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu" role="menu">
|
|
||||||
<li><%= link_to "List", products_path %></li>
|
|
||||||
<li><%= link_to "Add product" , new_product_path %></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Users <span class="caret"></span></a>
|
|
||||||
<ul class="dropdown-menu" role="menu">
|
|
||||||
<li><%= link_to "List" , users_path %></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><%= link_to 'Download schulden', admins_schulden_path(format: :csv) %>/li>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
<li class="dropdown">
|
</div>
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Logged in as <%= current_user.nickname %> <b class="caret"></b></a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><%= link_to "Edit password", edit_user_registration_path %></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="visible-xs navbar-form">
|
|
||||||
<div class="form-group">
|
|
||||||
<% if user_signed_in? %>
|
|
||||||
<%= button_to "Logout", destroy_user_session_path, class: "btn btn-default form-control", method: :delete %>
|
|
||||||
<% else %>
|
|
||||||
<%= link_to "Login", new_user_session_path, class: "btn btn-success form-control" %>
|
|
||||||
<%= link_to "Register", new_user_registration_path, class: "btn btn-default form-control" %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
<li><%= mail_to "tab@zeus.ugent.be", "Send feedback" %></li>
|
||||||
|
<% if user_signed_in? %>
|
||||||
|
<% if can? :manage, :all %>
|
||||||
|
<li>
|
||||||
|
<%= link_to "Place order", orders_path %>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Products <span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li><%= link_to "List", products_path %></li>
|
||||||
|
<li><%= link_to "Add product" , new_product_path %></li>
|
||||||
|
<li><%= link_to "Add stock", stock_products_path %></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Users <span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li><%= link_to "List" , users_path %></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><%= link_to 'Download schulden', admins_schulden_path(format: :csv) %></li>
|
||||||
|
<% end %>
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Logged in as <%= current_user.nickname %> <b class="caret"></b></a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><%= link_to "Edit password", edit_user_registration_path %></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="visible-xs navbar-form">
|
||||||
|
<div class="form-group">
|
||||||
|
<% if user_signed_in? %>
|
||||||
|
<%= button_to "Logout", destroy_user_session_path, class: "btn btn-default form-control", method: :delete %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to "Login", new_user_session_path, class: "btn btn-success form-control" %>
|
||||||
|
<%= link_to "Register", new_user_registration_path, class: "btn btn-default form-control" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
</div><!-- /.navbar-collapse -->
|
</div><!-- /.navbar-collapse -->
|
||||||
</div><!-- /.container-fluid -->
|
</div><!-- /.container-fluid -->
|
||||||
|
|
|
@ -7,19 +7,18 @@
|
||||||
<%= csrf_meta_tags %>
|
<%= csrf_meta_tags %>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<% if current_user && current_user.koelkast? && !Rails.env.development? %>
|
||||||
<%= render "layouts/header" %>
|
<body oncontextmenu="return false">
|
||||||
|
<% else %>
|
||||||
|
<body>
|
||||||
|
<% end %>
|
||||||
|
<%= render 'layouts/header' %>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="container" >
|
<div class="container">
|
||||||
<%= yield %>
|
<%= yield %>
|
||||||
</div>
|
</div>
|
||||||
<%= render "layouts/footer" %>
|
<%= render 'layouts/footer' %>
|
||||||
<%= debug(params) if Rails.env.development? %>
|
<%= debug(params) if Rails.env.development? %>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
17
app/views/order_items/_order_item.html.erb
Normal file
17
app/views/order_items/_order_item.html.erb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<div class="col-md-3 form_products">
|
||||||
|
<div class="thumbnail ">
|
||||||
|
<div class="form_row center">
|
||||||
|
<div class="form_row_image">
|
||||||
|
<%= image_tag product.avatar %>
|
||||||
|
</div>
|
||||||
|
<div class="caption">
|
||||||
|
<%= content_tag :h4, "#{product.name} (#{euro(product.price)})" %>
|
||||||
|
<%= f.counter :count, skip_label: true, wrapper_class: "input-group", class: "row_counter" %>
|
||||||
|
<%= f.fields_for :product do |product| %>
|
||||||
|
<%= product.hidden_field :price_cents, class: :price %>
|
||||||
|
<%= product.hidden_field :stock, class: :stock %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -1,19 +0,0 @@
|
||||||
<div class="col-md-3 form_products">
|
|
||||||
<div class="thumbnail ">
|
|
||||||
<div class="form_row center">
|
|
||||||
<%= image_tag f.object.product.avatar %>
|
|
||||||
<div class="caption">
|
|
||||||
<h3><%= f.object.product.name %> - <%= content_tag :span, euro(f.object.product.price), class: "price" %></h3>
|
|
||||||
<p>
|
|
||||||
<div class="input-group">
|
|
||||||
<%= render 'btn_dec', id: f.object.product_id %>
|
|
||||||
<%= f.text_field :count, class: 'form-control row_counter', value: 0 %>
|
|
||||||
<%= f.hidden_field :price, value: f.object.product.price, class: :price %>
|
|
||||||
<%= render 'btn_inc', id: f.object.product_id %>
|
|
||||||
<%= f.hidden_field :product_id %>
|
|
||||||
</div>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,8 +0,0 @@
|
||||||
<%= f.label :total_price %>
|
|
||||||
<div class="input-group">
|
|
||||||
<span class="input-group-addon">€</span>
|
|
||||||
<%= f.number_field :total_price, step: :any, class: 'form-control input-lg' %>
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<%= f.submit "Order!", class: "btn btn-primary input-lg" %>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
|
@ -1,5 +1,13 @@
|
||||||
<p>
|
<tr>
|
||||||
<% order.products.each do |p| %>
|
<td class="order_date">
|
||||||
<%= p.count(order).to_s + " " + p.name %>
|
<%= order.created_at.strftime("%d %b %Y at %H:%M") %>
|
||||||
<% end %>
|
</td>
|
||||||
</p>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<%= order.to_sentence %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= euro(order.price) %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
10
app/views/orders/_price.html.erb
Normal file
10
app/views/orders/_price.html.erb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<div class="col-md-3 form_total">
|
||||||
|
<%= f.label :total_price %>
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-addon">€</span>
|
||||||
|
<%= f.number_field :price, skip_label: true, step: :any, class: 'form-control big-form-field' %>
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<%= f.submit "Order!", class: "btn btn-primary big-form-button" %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -1,9 +0,0 @@
|
||||||
<% users.each do |user| %>
|
|
||||||
<div class="thumbnail overview">
|
|
||||||
<%= link_to image_tag(user.dagschotel.avatar, class: "img-circle dagschotel"), user_quickpay_path(user) unless user.dagschotel.nil? %>
|
|
||||||
<%= link_to image_tag(user.avatar , class: "img-circle avatar"), new_user_order_path(user) %>
|
|
||||||
|
|
||||||
<%= link_to user.name , new_user_order_path(user), class: "btn btn-info",
|
|
||||||
style: get_color_style(user) %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
|
@ -1,11 +0,0 @@
|
||||||
<%= render partial: 'flash' %>
|
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h3 class="center" >sort by name</h3>
|
|
||||||
<%= render 'orders/user_list', users: @users_by_name %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h3 class="center" >sort by order</h3>
|
|
||||||
<%= render 'orders/user_list', users: @users_by_order %>
|
|
||||||
</div>
|
|
|
@ -1,18 +1,15 @@
|
||||||
<h3>Order for <%= @user.nickname %></h3>
|
<h3>Order for <%= @user.nickname %> (Huidige schuld: <%= euro(@user.debt) %>)</h3>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<%= form_for @order, url: user_orders_path(@user) do |f| %>
|
<%= f_form_for [@user, @order] do |f| %>
|
||||||
<%= render 'application/errors', model: @order %>
|
<%= f.error_messages %>
|
||||||
|
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<%= f.fields_for :order_products do |op_field| %>
|
<%= f.fields_for :order_items do |op_field| %>
|
||||||
<%= render 'order_products/form_row', f: op_field %>
|
<%= render op_field.object, f: op_field, product: op_field.object.product %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-3 form_total">
|
<%= render 'orders/price', f: f %>
|
||||||
<%= render 'order_products/total_price', f: f %>
|
<% end %>
|
||||||
</div>
|
|
||||||
|
|
||||||
<% end %>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
7
app/views/orders/overview.html.erb
Normal file
7
app/views/orders/overview.html.erb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<%= render partial: 'flash' %>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<% @users.each do |user| %>
|
||||||
|
<%= render 'users/new_order', user: user %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
|
@ -1,17 +1,15 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6 col-md-offset-3">
|
<div class="col-md-6 col-md-offset-3 sign-in">
|
||||||
<%= form_for @product, html: { multipart: true } do |f| %>
|
<%= f_form_for @product, html: { multipart: true } do |f| %>
|
||||||
<%= render 'application/errors', model: @product %>
|
<%= f.error_messages %>
|
||||||
|
|
||||||
<%= form_text_field f, :name %>
|
<%= f.text_field :name %>
|
||||||
|
<%= f.price_field :price %>
|
||||||
<%= f.label :price %>
|
<%= f.collection_select :category, Product.categories.keys %>
|
||||||
<%= f.number_field :price, value: number_with_precision(f.object.price, precision: 2), class: 'form-control', placeholder: "0.00", step: :any %>
|
<%= f.number_field :stock %>
|
||||||
|
|
||||||
<%= f.label :avatar %>
|
|
||||||
<%= f.file_field :avatar %>
|
<%= f.file_field :avatar %>
|
||||||
|
|
||||||
<%= f.submit class: "btn btn-primary" %>
|
<%= f.submit %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
22
app/views/products/_index.html.erb
Normal file
22
app/views/products/_index.html.erb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<div role="tabpanel">
|
||||||
|
<!-- Nav tabs -->
|
||||||
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
|
<li role="presentation" class="active"><a href="#all" role="tab" data-toggle="tab">All</a></li>
|
||||||
|
<% @categories.each do |o, i| %>
|
||||||
|
<li role="presentation"><a href="#<%= o %>" aria-controls="<%= o %>" role="tab" data-toggle="tab"><%= o.titleize %></a></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- Tab panes -->
|
||||||
|
<div class="tab-content">
|
||||||
|
<br />
|
||||||
|
<div role="tabpanel" class="tab-pane active" id="all">
|
||||||
|
<%= render @products %>
|
||||||
|
</div>
|
||||||
|
<% @categories.each do |o, i| %>
|
||||||
|
<div role="tabpanel" class="tab-pane" id="<%= o %>">
|
||||||
|
<%= render @products.where(category: i) %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
14
app/views/products/_links.html.erb
Normal file
14
app/views/products/_links.html.erb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<%- if controller_name == 'products' && current_user && current_user.admin? %>
|
||||||
|
<%= link_to "Edit", edit_product_path(product), class: "btn btn-default" %>
|
||||||
|
<%= link_to "Delete", product_path(product), method: :delete, class: "btn btn-danger", data: {confirm: 'Are you sure?'} %>
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
|
<%- if controller_name == 'users' %>
|
||||||
|
<div class="product_dagschotel">
|
||||||
|
<% if current_user.dagschotel != product %>
|
||||||
|
<%= link_to "Make dagschotel", user_dagschotel_path(current_user, product), class: "btn btn-default" %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to "Huidige dagschotel", user_dagschotel_path(current_user, product), class: "btn btn-success", disabled: true %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end -%>
|
|
@ -1,12 +1,13 @@
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="thumbnail">
|
<div class="thumbnail pic">
|
||||||
<%= image_tag product.avatar %>
|
<div class="form_row_image">
|
||||||
|
<%= image_tag product.avatar %>
|
||||||
|
</div>
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
<h3><%= product.name %> - <%= euro(product.price) %></h3>
|
<h4><%= product.name %></h4>
|
||||||
<p>
|
<h3><%= euro(product.price) %></h3>
|
||||||
<%= link_to "Edit", edit_product_path(product), class: "btn btn-default" %>
|
<h6>(In stock: <%= product.stock %>)</h6>
|
||||||
<%= link_to "Delete", product_path(product), method: :delete, class: "btn btn-danger", data: {confirm: 'Are you sure?'} %>
|
<%= render 'products/links', product: product %>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
<h1>All products</h1>
|
<h1>All products</h1>
|
||||||
<%= render partial: 'flash' %>
|
<%= render partial: 'flash' %>
|
||||||
|
<%= render 'products/index' %>
|
||||||
<div class="row products">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<%= render @products %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
14
app/views/products/stock.html.erb
Normal file
14
app/views/products/stock.html.erb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 col-md-offset-3">
|
||||||
|
<%= form_tag do %>
|
||||||
|
<% @products.each do |product| %>
|
||||||
|
<%= fields_for "products[]", product do |form| %>
|
||||||
|
<%= image_tag product.avatar %>
|
||||||
|
<%= form.number_field :stock_inc, value: 0, class: 'form-control' %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= submit_tag "Insert stock", class: 'btn btn-primary' %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
10
app/views/users/_new_order.html.erb
Normal file
10
app/views/users/_new_order.html.erb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<div class="col-md-2 overviewthumbnail">
|
||||||
|
<% unless user.dagschotel.nil? %>
|
||||||
|
<%= link_to user_quickpay_path(user) do %>
|
||||||
|
<%= image_tag user.dagschotel.avatar(:dagschotel), class: "img-circle dagschotel" %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= link_to image_tag(user.avatar(:large) , class: "img-circle avatar"), new_user_order_path(user) %>
|
||||||
|
<%= link_to user.nickname , new_user_order_path(user), class: "btn btn-info", style: get_color_style(user) %>
|
||||||
|
</div>
|
|
@ -1,18 +1,11 @@
|
||||||
<div class="col-md-3">
|
<tr>
|
||||||
<div class="thumbnail monopoly">
|
<td><%= user.id %></td>
|
||||||
<h3 class="header" style="background-color: #<%=get_color(user)%>;" ><%= user.full_name %></h3>
|
<td><%= image_tag user.avatar(:small) %></td>
|
||||||
<div class="caption">
|
<td><%= user.nickname %></td>
|
||||||
<%= image_tag(user.avatar , class: "img-circle avatar") %>
|
<td><%= euro(user.debt) %></td>
|
||||||
<p><strong>Name:</strong> <%= user.name %></p>
|
<% if current_user.admin? %>
|
||||||
<p><strong>Last name:</strong> <%= user.last_name %></p>
|
<td>
|
||||||
<p><strong>Nickname:</strong> <%= user.nickname %></p>
|
<%= link_to "Delete", user_path(user), method: :delete, class: "btn btn-danger", data: { confirm: "Are you sure?" } %>
|
||||||
<p><strong>Balance:</strong> <%= euro(user.balance) %></p>
|
</td>
|
||||||
</div>
|
<% end %>
|
||||||
<div class="footer">
|
</tr>
|
||||||
<p>
|
|
||||||
<%= link_to "Delete", user_path(user), method: :delete, class: "btn btn-danger", data: {confirm: 'Are you sure?'} %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
2
app/views/users/edit_dagschotel.html.erb
Normal file
2
app/views/users/edit_dagschotel.html.erb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<h3>Choose new Dagschotel</h4>
|
||||||
|
<%= render 'products/index' %>
|
|
@ -1,8 +1,17 @@
|
||||||
<h1>All users</h1>
|
|
||||||
<%= render partial: 'flash' %>
|
|
||||||
|
|
||||||
<div class="row users">
|
<div class="row users">
|
||||||
<div class="col-md-12">
|
<div class="col-md-8 col-md-offset-2">
|
||||||
<%= render @users %>
|
<h1>All users</h1>
|
||||||
|
<%= render partial: 'flash' %>
|
||||||
|
|
||||||
|
<table id="users-table" class="table table-striped">
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th></th>
|
||||||
|
<th>Nickname</th>
|
||||||
|
<th>Debt</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
<%= render @users %>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,25 +1,30 @@
|
||||||
|
<%= render partial: 'flash' %>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<aside class="col-md-4">
|
<div class="user_info">
|
||||||
<section class="user_info">
|
<% if current_user == @user %>
|
||||||
<h1>Name: <%= @user.name %></h1>
|
<h5>
|
||||||
<h1>Last name: <%= @user.last_name %></h1>
|
<%= link_to "[Edit dagschotel]" , user_edit_dagschotel_path(@user) %>
|
||||||
<h1>Nickname: <%= @user.nickname %></h1>
|
<%= link_to "[Edit profile]" , edit_user_registration_path %>
|
||||||
<h1>Balance: <%= @user.balance %></h1>
|
</h5>
|
||||||
<h1>User id: <%= @user.id %></h1>
|
|
||||||
<p>
|
|
||||||
<%= link_to "edit" , edit_user_registration_path %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<div class="col-md-8">
|
|
||||||
<% if @user.orders.any? %>
|
|
||||||
<h3>Orders (<%= @user.orders.count %>)</h3>
|
|
||||||
<ol class="orders">
|
|
||||||
<%= render @orders %>
|
|
||||||
</ol>
|
|
||||||
<%= will_paginate @orders %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<h2><%= @user.nickname %></h2>
|
||||||
|
<%= button_to "PLACE ORDER!", new_user_order_path(@user), method: :get if current_user == @user %>
|
||||||
|
<div class="debt">DEBT: <%= euro(@user.debt) %></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<% if @orders.any? %>
|
||||||
|
<div class="stats">
|
||||||
|
<h4>Total products</h4>
|
||||||
|
Total: <br/><ul><li><%= @categories.map{|c| pluralize(c.count, c.category)}.join(", ")%></li></ul>
|
||||||
|
<br/>
|
||||||
|
Specifics:<br/>
|
||||||
|
<ul>
|
||||||
|
<%= @products.map{ |p| content_tag(:li, pluralize(p.count, p.name)) }.join("\n").html_safe %>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h4>All orders (<%= @user.orders_count %>)</h4>
|
||||||
|
<table class="orders"><%= render @orders %></table>
|
||||||
|
<%= will_paginate @orders %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
begin
|
|
||||||
load File.expand_path("../spring", __FILE__)
|
|
||||||
rescue LoadError
|
|
||||||
end
|
|
||||||
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
||||||
require_relative '../config/boot'
|
require_relative '../config/boot'
|
||||||
require 'rails/commands'
|
require 'rails/commands'
|
||||||
|
|
4
bin/rake
4
bin/rake
|
@ -1,8 +1,4 @@
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
begin
|
|
||||||
load File.expand_path("../spring", __FILE__)
|
|
||||||
rescue LoadError
|
|
||||||
end
|
|
||||||
require_relative '../config/boot'
|
require_relative '../config/boot'
|
||||||
require 'rake'
|
require 'rake'
|
||||||
Rake.application.run
|
Rake.application.run
|
||||||
|
|
|
@ -19,5 +19,6 @@ module Tab002
|
||||||
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
||||||
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
||||||
# config.i18n.default_locale = :de
|
# config.i18n.default_locale = :de
|
||||||
|
config.active_record.raise_in_transactional_callbacks = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,7 +13,7 @@ Rails.application.configure do
|
||||||
config.eager_load = false
|
config.eager_load = false
|
||||||
|
|
||||||
# Configure static asset server for tests with Cache-Control for performance.
|
# Configure static asset server for tests with Cache-Control for performance.
|
||||||
config.serve_static_assets = true
|
config.serve_static_files = true
|
||||||
config.static_cache_control = 'public, max-age=3600'
|
config.static_cache_control = 'public, max-age=3600'
|
||||||
|
|
||||||
# Show full error reports and disable caching.
|
# Show full error reports and disable caching.
|
||||||
|
@ -34,6 +34,8 @@ Rails.application.configure do
|
||||||
# Print deprecation notices to the stderr.
|
# Print deprecation notices to the stderr.
|
||||||
config.active_support.deprecation = :stderr
|
config.active_support.deprecation = :stderr
|
||||||
|
|
||||||
|
config.active_support.test_order = :random
|
||||||
|
|
||||||
# Raises error for missing translations
|
# Raises error for missing translations
|
||||||
# config.action_view.raise_on_missing_translations = true
|
# config.action_view.raise_on_missing_translations = true
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# Use this hook to configure devise mailer, warden hooks and so forth.
|
# Use this hook to configure devise mailer, warden hooks and so forth.
|
||||||
# Many of these configuration options can be set straight in your model.
|
# Many of these configuration options can be set straight in your model.
|
||||||
|
# require 'yaml'
|
||||||
Devise.setup do |config|
|
Devise.setup do |config|
|
||||||
# The secret key used by Devise. Devise uses this key to generate
|
# The secret key used by Devise. Devise uses this key to generate
|
||||||
# random tokens. Changing this key will render invalid all existing
|
# random tokens. Changing this key will render invalid all existing
|
||||||
|
@ -232,7 +233,7 @@ Devise.setup do |config|
|
||||||
# ==> OmniAuth
|
# ==> OmniAuth
|
||||||
# Add a new OmniAuth provider. Check the wiki for more information on setting
|
# Add a new OmniAuth provider. Check the wiki for more information on setting
|
||||||
# up on your models and hooks.
|
# up on your models and hooks.
|
||||||
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
|
config.omniauth :zeuswpi, Rails.application.secrets.omniauth_client_id, Rails.application.secrets.omniauth_client_secret
|
||||||
|
|
||||||
# ==> Warden configuration
|
# ==> Warden configuration
|
||||||
# If you want to use other strategies, that are not supported by Devise, or
|
# If you want to use other strategies, that are not supported by Devise, or
|
||||||
|
|
44
config/initializers/zeuswpi.rb
Normal file
44
config/initializers/zeuswpi.rb
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
require 'omniauth-oauth2'
|
||||||
|
|
||||||
|
module OmniAuth
|
||||||
|
module Strategies
|
||||||
|
class Zeuswpi < OmniAuth::Strategies::OAuth2
|
||||||
|
|
||||||
|
option :provider_ignores_state, true
|
||||||
|
|
||||||
|
# Give your strategy a name.
|
||||||
|
option :name, "zeuswpi"
|
||||||
|
|
||||||
|
# This is where you pass the options you would pass when
|
||||||
|
# initializing your consumer from the OAuth gem.
|
||||||
|
option :client_options, {
|
||||||
|
site: "http://kelder.zeus.ugent.be",
|
||||||
|
authorize_url: "/oauth/oauth2/authorize/",
|
||||||
|
token_url: "/oauth/oauth2/token/",
|
||||||
|
}
|
||||||
|
|
||||||
|
# These are called after authentication has succeeded. If
|
||||||
|
# possible, you should try to set the UID without making
|
||||||
|
# additional calls (if the user id is returned with the token
|
||||||
|
# or as a URI parameter). This may not be possible with all
|
||||||
|
# providers.
|
||||||
|
uid{ raw_info['username'] }
|
||||||
|
|
||||||
|
info do
|
||||||
|
{
|
||||||
|
# :nickname => raw_info['username'],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
extra do
|
||||||
|
{
|
||||||
|
'raw_info' => raw_info
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def raw_info
|
||||||
|
@raw_info ||= access_token.get('/oauth/api/current_user/').parsed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,16 +1,34 @@
|
||||||
Rails.application.routes.draw do
|
Rails.application.routes.draw do
|
||||||
|
devise_for :users, controllers: { omniauth_callbacks: "callbacks" }
|
||||||
|
|
||||||
root "orders#index"
|
devise_scope :user do
|
||||||
|
unauthenticated :user do
|
||||||
devise_for :users
|
root to: 'devise/sessions#new'
|
||||||
|
end
|
||||||
resources :users do
|
|
||||||
resources :orders, only: [:new, :create, :index] do
|
authenticated :user, ->(u) { u.koelkast? } do
|
||||||
|
root to: 'orders#overview', as: :koelkast_root
|
||||||
|
end
|
||||||
|
|
||||||
|
authenticated :user, ->(u) { !u.koelkast? } do
|
||||||
|
root to: 'users#show', as: :user_root
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
resources :users do
|
||||||
|
resources :orders
|
||||||
|
get 'quickpay' => 'orders#quickpay'
|
||||||
|
get 'dagschotel/edit' => 'users#edit_dagschotel', as: 'edit_dagschotel'
|
||||||
|
get 'dagschotel/:product_id' => 'users#update_dagschotel', as: 'dagschotel'
|
||||||
|
end
|
||||||
|
|
||||||
|
resources :products do
|
||||||
|
collection do
|
||||||
|
get 'stock' => 'products#stock', as: 'stock'
|
||||||
|
post 'stock' => 'products#update_stock', as: 'update_stock'
|
||||||
end
|
end
|
||||||
get 'quickpay' => 'orders#quickpay'
|
|
||||||
get 'dagschotel/:product_id' => 'users#dagschotel', as: "dagschotel"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :products
|
|
||||||
get 'admins' => 'admins#schulden', as: "admins_schulden"
|
get 'admins' => 'admins#schulden', as: "admins_schulden"
|
||||||
|
get 'overview' => 'orders#overview', as: "orders"
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
|
|
||||||
development:
|
development:
|
||||||
secret_key_base: 5d40610321e19e4f71ee2ba8af4f426fe15096c405da3800c6b33bed6779f2d11f55a0edc455974b19a01fd71f6cd508dba980305dbc55ff82521a2d12f891d8
|
secret_key_base: 5d40610321e19e4f71ee2ba8af4f426fe15096c405da3800c6b33bed6779f2d11f55a0edc455974b19a01fd71f6cd508dba980305dbc55ff82521a2d12f891d8
|
||||||
|
omniauth_client_id: "client_id"
|
||||||
|
omniauth_client_secret: "client_secret"
|
||||||
|
|
||||||
test:
|
test:
|
||||||
secret_key_base: 961437e28e7d6055ffaad9cf1f8d614354f57f10cb2d7601c9d6ede72a03b9c9535ad9e63507e3eb31252c4895970a63117493408f2e9a46c7a0c4a5a7836b81
|
secret_key_base: 961437e28e7d6055ffaad9cf1f8d614354f57f10cb2d7601c9d6ede72a03b9c9535ad9e63507e3eb31252c4895970a63117493408f2e9a46c7a0c4a5a7836b81
|
||||||
|
@ -20,3 +22,6 @@ test:
|
||||||
# instead read values from the environment.
|
# instead read values from the environment.
|
||||||
production:
|
production:
|
||||||
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
||||||
|
omniauth_client_id: ""
|
||||||
|
omniauth_client_secret: ""
|
||||||
|
|
||||||
|
|
5
db/migrate/20141210200008_add_category_to_products.rb
Normal file
5
db/migrate/20141210200008_add_category_to_products.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddCategoryToProducts < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :products, :category, :integer, default: 0
|
||||||
|
end
|
||||||
|
end
|
5
db/migrate/20141217063222_add_koelkast_to_users.rb
Normal file
5
db/migrate/20141217063222_add_koelkast_to_users.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddKoelkastToUsers < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :users, :koelkast, :boolean, default: false
|
||||||
|
end
|
||||||
|
end
|
5
db/migrate/20150113155744_add_stock_to_products.rb
Normal file
5
db/migrate/20150113155744_add_stock_to_products.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class AddStockToProducts < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :products, :stock, :integer, default: 0
|
||||||
|
end
|
||||||
|
end
|
5
db/migrate/20150204155216_change_price_to_price_cents.rb
Normal file
5
db/migrate/20150204155216_change_price_to_price_cents.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class ChangePriceToPriceCents < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
rename_column :products, :price, :price_cents
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class ChangeDefaultOrderProductCountToZero < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
change_column_default :order_products, :count, 0
|
||||||
|
end
|
||||||
|
end
|
13
db/migrate/20150209113630_create_versions.rb
Normal file
13
db/migrate/20150209113630_create_versions.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
class CreateVersions < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :versions do |t|
|
||||||
|
t.string :item_type, :null => false
|
||||||
|
t.integer :item_id, :null => false
|
||||||
|
t.string :event, :null => false
|
||||||
|
t.string :whodunnit
|
||||||
|
t.text :object
|
||||||
|
t.datetime :created_at
|
||||||
|
end
|
||||||
|
add_index :versions, [:item_type, :item_id]
|
||||||
|
end
|
||||||
|
end
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue