diff --git a/Gemfile b/Gemfile index be43fd8..d539375 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,5 @@ source 'https://rubygems.org' - # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '4.2' @@ -8,19 +7,15 @@ gem 'rails', '4.2' gem 'sass-rails', '~> 4.0.3' gem 'bootstrap-sass', '3.2.0.0' gem 'uglifier', '>= 1.3.0' -gem 'coffee-rails', '~> 4.0.0' gem 'jquery-rails' # Haml for templating! gem "haml-rails", "~> 0.9" -# Responders -gem 'responders', '~> 2.0' - # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks gem 'turbolinks' -# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder -gem 'jbuilder', '~> 2.0' +# Friendly ids! +gem 'friendly_id', '~> 5.1.0' group :doc do gem 'sdoc', '~> 0.4.0' @@ -57,7 +52,6 @@ group :development, :test do gem 'factory_girl_rails' gem 'faker', '1.4.2' gem 'pry-rails' - gem 'pry-byebug' end # Airbrake @@ -77,9 +71,6 @@ gem 'omniauth-oauth2' # Use cancancan for authorization gem 'cancancan' -# Safety first -gem 'paper_trail', '~> 4.0.0.beta' - # Default avatar for users gem 'identicon' diff --git a/Gemfile.lock b/Gemfile.lock index 53a4869..36375cb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,10 +50,6 @@ GEM bootstrap-will_paginate (0.0.10) will_paginate builder (3.2.2) - byebug (3.5.1) - columnize (~> 0.8) - debugger-linecache (~> 1.2) - slop (~> 3.6) cancancan (1.10.1) capistrano (3.3.5) capistrano-stats (~> 1.1.0) @@ -91,7 +87,6 @@ GEM execjs coffee-script-source (1.9.0) colorize (0.7.5) - columnize (0.9.0) coveralls (0.7.11) multi_json (~> 1.10) rest-client (>= 1.6.8, < 2) @@ -99,7 +94,6 @@ GEM term-ansicolor (~> 1.3) thor (~> 0.19.1) daemons (1.2.3) - debugger-linecache (1.2.0) delayed_job (4.0.6) activesupport (>= 3.0, < 5.0) delayed_job_active_record (4.0.3) @@ -126,6 +120,8 @@ GEM faraday (0.9.1) multipart-post (>= 1.2, < 3) ffi (1.9.6-x64-mingw32) + friendly_id (5.1.0) + activerecord (>= 4.0.0) globalid (0.3.2) activesupport (>= 4.1.0) haml (4.0.7) @@ -149,9 +145,6 @@ GEM i18n (0.7.0) identicon (0.0.3) chunky_png - jbuilder (2.2.6) - activesupport (>= 3.0.0, < 5) - multi_json (~> 1.2) jquery-rails (4.0.3) rails-dom-testing (~> 1.0) railties (>= 4.2.0) @@ -193,9 +186,6 @@ GEM oauth2 (~> 1.0) omniauth (~> 1.2) orm_adapter (0.5.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) activesupport (>= 3.0.0) @@ -210,9 +200,6 @@ GEM method_source (~> 0.8.1) slop (~> 3.4) win32console (~> 1.3) - pry-byebug (3.0.1) - byebug (~> 3.4) - pry (~> 0.10) pry-rails (0.3.4) pry (>= 0.9.10) rack (1.6.0) @@ -339,7 +326,6 @@ DEPENDENCIES capistrano-rbenv capistrano-rvm codeclimate-test-reporter - coffee-rails (~> 4.0.0) coveralls daemons delayed_job (~> 4.0) @@ -347,19 +333,16 @@ DEPENDENCIES devise factory_girl_rails faker (= 1.4.2) + friendly_id (~> 5.1.0) haml-rails (~> 0.9) httparty identicon - jbuilder (~> 2.0) jquery-rails mysql2 omniauth-oauth2 - paper_trail (~> 4.0.0.beta) paperclip - pry-byebug pry-rails rails (= 4.2) - responders (~> 2.0) rspec-rails sass-rails (~> 4.0.3) sdoc (~> 0.4.0) diff --git a/app/assets/javascripts/admins.js.coffee b/app/assets/javascripts/admins.js.coffee deleted file mode 100644 index 24f83d1..0000000 --- a/app/assets/javascripts/admins.js.coffee +++ /dev/null @@ -1,3 +0,0 @@ -# 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/ diff --git a/app/assets/javascripts/callbacks.js.coffee b/app/assets/javascripts/callbacks.js.coffee deleted file mode 100644 index 24f83d1..0000000 --- a/app/assets/javascripts/callbacks.js.coffee +++ /dev/null @@ -1,3 +0,0 @@ -# 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/ diff --git a/app/assets/javascripts/orders.js b/app/assets/javascripts/orders.js new file mode 100644 index 0000000..1581f19 --- /dev/null +++ b/app/assets/javascripts/orders.js @@ -0,0 +1,66 @@ +// 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/ +ready = function() { + $('.btn-inc').on('click', function() { + increment($(this), 1); + }); + $('.btn-dec').on('click', function() { + increment($(this), -1); + }); + $('.form_row').each(function(index, row) { + updateInput(row, false); + $(row).on('input', function() { + updateInput(row); + }); + }); + recalculate(); +}; + +// Validate input, and then update +updateInput = function(row, useRecalculate) { + if (useRecalculate == null) { + useRecalculate = true; + } + cell = row.querySelector("input"); + if (!cell.validity.valid) { + if (parseInt(cell.value) > parseInt(cell.max)) { + cell.value = parseInt(cell.max); + } else { + cell.value = 0; + } + } + disIfNec(row) + if (useRecalculate) { + recalculate() + } +}; + +disIfNec = function(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('.row_counter').attr('max'))) +}; + +recalculate = function() { + sum = 0 + $('.row_counter').each(function(i, value) { sum += parseInt($(value).val()) * parseInt($(value).data('price')) }) + return $('#order_price').html((sum / 100.0).toFixed(2)) +}; + +increment = function(button, n) { + row = $(button).closest('.form_row') + + // Fix the counter + counter = $(row).find('.row_counter') + value = parseInt(counter.val()) + if (isNaN(value)) { + value = 0 + } + counter.val(value + n) + + updateInput(row[0]) +} + +$(document).ready(ready); +$(document).on('page:load', ready); diff --git a/app/assets/javascripts/orders.js.coffee b/app/assets/javascripts/orders.js.coffee deleted file mode 100644 index f901168..0000000 --- a/app/assets/javascripts/orders.js.coffee +++ /dev/null @@ -1,60 +0,0 @@ -# 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/ -ready = -> - $('.btn-inc').on 'click', -> - increment($(this), 1) - - $('.btn-dec').on 'click', -> - increment($(this), -1) - - $('.form_row').each((index, row) -> - updateInput(row, false) - $(row).on('input', -> - updateInput(row) - ) - ) - - recalculate() - - - -# Validate input, and then update -updateInput = (row, useRecalculate = true) -> - cell = row.querySelector("input") - if ! cell.validity.valid - if(parseInt(cell.value) > parseInt(cell.max)) - cell.value = parseInt(cell.max) - else - cell.value = 0 - - # Disable buttons if necessary - disIfNec(row) - - if useRecalculate - 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('.row_counter').attr('max'))) - -recalculate = () -> - value = ($(row).val() * $(row).data('price') for row in $('.row_counter')).reduce(((a, b) -> a+b), 0) - $('#order_price').html((value / 100.0).toFixed(2)) - -increment = (button, n) -> - row = $(button).closest('.form_row') - - # Fix the counter - counter = $(row).find('.row_counter') - value = parseInt(counter.val()) - if isNaN(value) - value = 0 - counter.val(value + n) - - updateInput(row[0]) - -$(document).ready(ready) -$(document).on('page:load', ready) diff --git a/app/assets/javascripts/products.js.coffee b/app/assets/javascripts/products.js.coffee deleted file mode 100644 index 24f83d1..0000000 --- a/app/assets/javascripts/products.js.coffee +++ /dev/null @@ -1,3 +0,0 @@ -# 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/ diff --git a/app/assets/javascripts/sessions.js.coffee b/app/assets/javascripts/sessions.js.coffee deleted file mode 100644 index 24f83d1..0000000 --- a/app/assets/javascripts/sessions.js.coffee +++ /dev/null @@ -1,3 +0,0 @@ -# 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/ diff --git a/app/assets/javascripts/stock.js.coffee b/app/assets/javascripts/stock.js.coffee deleted file mode 100644 index 24f83d1..0000000 --- a/app/assets/javascripts/stock.js.coffee +++ /dev/null @@ -1,3 +0,0 @@ -# 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/ diff --git a/app/assets/javascripts/users.js.coffee b/app/assets/javascripts/users.js.coffee deleted file mode 100644 index 24f83d1..0000000 --- a/app/assets/javascripts/users.js.coffee +++ /dev/null @@ -1,3 +0,0 @@ -# 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/ diff --git a/app/assets/javascripts/welcome.js.coffee b/app/assets/javascripts/welcome.js.coffee deleted file mode 100644 index 24f83d1..0000000 --- a/app/assets/javascripts/welcome.js.coffee +++ /dev/null @@ -1,3 +0,0 @@ -# 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/ diff --git a/app/jobs/tab_api_job.rb b/app/jobs/tab_api_job.rb index 2137af2..e9cda89 100644 --- a/app/jobs/tab_api_job.rb +++ b/app/jobs/tab_api_job.rb @@ -4,7 +4,7 @@ TabApiJob = Struct.new(:order_id) do if order && !order.transaction_id body = { transaction: { - debtor: order.user.uid, + debtor: order.user.name, cents: order.price_cents, message: order.to_sentence, id_at_client: order.id @@ -14,7 +14,7 @@ TabApiJob = Struct.new(:order_id) do "Authorization" => "Token token=#{Rails.application.secrets.tab_api_key}" } - result = HTTParty.post("https://zeus.ugent.be/tab/transactions", body: body, headers: headers ) + result = HTTParty.post(File.join(Rails.application.config.api_url, "transactions"), body: body, headers: headers ) order.update_attribute(:transaction_id, JSON.parse(result.body)["id"].to_i) end end diff --git a/app/models/concerns/avatarable.rb b/app/models/concerns/avatarable.rb new file mode 100644 index 0000000..37807e2 --- /dev/null +++ b/app/models/concerns/avatarable.rb @@ -0,0 +1,18 @@ +module Avatarable + extend ActiveSupport::Concern + + included do + avatar_styles = { + large: "150x150>", + medium: "100x100>", + dagschotel: "80x80>", + small: "40x40>" + } + + has_attached_file :avatar, styles: avatar_styles, default_style: :medium + + validates_attachment :avatar, + presence: true, + content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] } + end +end diff --git a/app/models/order.rb b/app/models/order.rb index a2e3b82..5866cea 100644 --- a/app/models/order.rb +++ b/app/models/order.rb @@ -22,7 +22,6 @@ class Order < ActiveRecord::Base after_create :create_api_job validates :user, presence: true - validates :price_cents, presence: true validates_associated :order_items validate :product_presence diff --git a/app/models/order_item.rb b/app/models/order_item.rb index 4561fa7..45adfac 100644 --- a/app/models/order_item.rb +++ b/app/models/order_item.rb @@ -13,9 +13,9 @@ class OrderItem < ActiveRecord::Base belongs_to :product validates :product, presence: true - validates :count, presence: true, numericality: { only_integer: true, - less_than_or_equal_to: ->(oi) { oi.product.try(:stock) || 100 }, - greater_than_or_equal_to: 0 } + validates :count, presence: true, numericality: { only_integer: true, + less_than_or_equal_to: ->(oi) { oi.product.try(:stock) || 100 }, + greater_than_or_equal_to: 0 } before_destroy :put_back_in_stock! after_create :remove_from_stock! diff --git a/app/models/product.rb b/app/models/product.rb index 3f78e98..4e8dd22 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -18,18 +18,16 @@ # class Product < ActiveRecord::Base + include Avatarable + has_many :order_items - has_attached_file :avatar, styles: { dagschotel: "80x80>", medium: "100x100>", small: "40x40>" }, default_style: :medium enum category: %w(food beverages other) - validates :name, presence: true - validates :price_cents, numericality: { only_integer: true, greater_than: 0 } - validates :stock, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 } - validates :calories, numericality: { only_integer: true, allow_nil: true, greater_than_or_equal_to: 0 } - validates_attachment :avatar, - presence: true, - content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] } + validates :name, presence: true + validates :price_cents, presence: true, numericality: { only_integer: true, greater_than: 0 } + validates :stock, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 } + validates :calories, numericality: { only_integer: true, allow_nil: true, greater_than_or_equal_to: 0 } scope :for_sale, -> { where deleted: false } diff --git a/app/models/user.rb b/app/models/user.rb index 86266c4..b98deb9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -19,34 +19,26 @@ # avatar_updated_at :datetime # orders_count :integer default("0") # koelkast :boolean default("f") -# provider :string # name :string # encrypted_password :string default(""), not null # private :boolean default("f") # -require 'identicon' class User < ActiveRecord::Base - include Statistics + include Statistics, Avatarable, FriendlyId + friendly_id :name, use: :finders - devise :database_authenticatable, :trackable, :omniauthable, :omniauth_providers => [:zeuswpi] + devise :database_authenticatable, :omniauthable, :omniauth_providers => [:zeuswpi] - has_paper_trail - has_attached_file :avatar, styles: { large: "150x150>", medium: "100x100>", small: "40x40>" }, default_style: :medium has_many :orders, -> { includes :products } has_many :products, through: :orders belongs_to :dagschotel, class_name: 'Product' - validates_attachment :avatar, - presence: true, - content_type: { content_type: ["image/jpeg", "image/gif", "image/png"] } - scope :members, -> { where koelkast: false } - scope :publik, -> { where private: false } + scope :publik, -> { where private: false } def self.from_omniauth(auth) - where(provider: auth.provider, name: auth.uid).first_or_create do |user| - user.provider = auth.provider + where(name: auth.uid).first_or_create do |user| user.name = auth.uid user.avatar = Identicon.data_url_for auth.uid end @@ -55,10 +47,4 @@ class User < ActiveRecord::Base def debt 42.15 end - - # Change URL params for User - - def to_param - "#{id} #{name}".parameterize - end end diff --git a/config/application.rb b/config/application.rb index 7163fc6..94dca5c 100644 --- a/config/application.rb +++ b/config/application.rb @@ -21,6 +21,6 @@ module Tab002 # config.i18n.default_locale = :de config.active_record.raise_in_transactional_callbacks = true config.active_job.queue_adapter = :delayed_job - config.call_api_after = 5.minutes + config.call_api_after = (-5).minutes end end diff --git a/config/environments/development.rb b/config/environments/development.rb index 2faafd4..6c0915c 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -38,4 +38,6 @@ Rails.application.configure do Paperclip.options[:command_path] = "/usr/local/bin/" config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } + + config.api_url = "http://localhost:3001" end diff --git a/config/environments/production.rb b/config/environments/production.rb index 2c63bb2..09d62b3 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -86,4 +86,7 @@ Rails.application.configure do host: config.x.host, script_name: config.relative_url_root, } + + config.api_url = "http://zeus.ugent.be/tab" + end diff --git a/config/secrets.yml b/config/secrets.yml index 03566fd..4340ef3 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -15,7 +15,7 @@ development: omniauth_client_id: tomtest omniauth_client_secret: blargh access_token: "token" - tab_api_key: "6GNUM/BhsU3If20qXluPIA==" + tab_api_key: "HriaktSIhRaB5CJzD71uLQ==" test: secret_key_base: 961437e28e7d6055ffaad9cf1f8d614354f57f10cb2d7601c9d6ede72a03b9c9535ad9e63507e3eb31252c4895970a63117493408f2e9a46c7a0c4a5a7836b81 diff --git a/db/migrate/20150209113630_create_versions.rb b/db/migrate/20150209113630_create_versions.rb deleted file mode 100644 index 23be970..0000000 --- a/db/migrate/20150209113630_create_versions.rb +++ /dev/null @@ -1,13 +0,0 @@ -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 diff --git a/db/migrate/20150917165758_remove_provider_from_users.rb b/db/migrate/20150917165758_remove_provider_from_users.rb new file mode 100644 index 0000000..91c14e9 --- /dev/null +++ b/db/migrate/20150917165758_remove_provider_from_users.rb @@ -0,0 +1,5 @@ +class RemoveProviderFromUsers < ActiveRecord::Migration + def change + remove_column :users, :provider, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 5a3683e..01c418f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150914153143) do +ActiveRecord::Schema.define(version: 20150917165758) do create_table "delayed_jobs", force: :cascade do |t| t.integer "priority", default: 0, null: false @@ -79,7 +79,6 @@ ActiveRecord::Schema.define(version: 20150914153143) do t.datetime "avatar_updated_at" t.integer "orders_count", default: 0 t.boolean "koelkast", default: false - t.string "provider" t.string "name" t.string "encrypted_password", default: "", null: false t.boolean "private", default: false @@ -88,15 +87,4 @@ ActiveRecord::Schema.define(version: 20150914153143) do add_index "users", ["koelkast"], name: "index_users_on_koelkast" add_index "users", ["orders_count"], name: "index_users_on_orders_count" - create_table "versions", force: :cascade 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"], name: "index_versions_on_item_type_and_item_id" - end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 18b4677..3859e70 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -19,7 +19,6 @@ # avatar_updated_at :datetime # orders_count :integer default("0") # koelkast :boolean default("f") -# provider :string # name :string # encrypted_password :string default(""), not null # private :boolean default("f") diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 6b4c9bc..d68a59a 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -19,7 +19,6 @@ # avatar_updated_at :datetime # orders_count :integer default("0") # koelkast :boolean default("f") -# provider :string # name :string # encrypted_password :string default(""), not null # private :boolean default("f")