Refactor
This commit is contained in:
parent
de1436f5c7
commit
b55ba47209
21 changed files with 102 additions and 97 deletions
24
app/controllers/concerns/statistics.rb
Normal file
24
app/controllers/concerns/statistics.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
module Statistics
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def products_group_by_category
|
||||
products
|
||||
.select("products.category", "sum(order_items.count) as count")
|
||||
.group(:category)
|
||||
end
|
||||
|
||||
def all_orders page
|
||||
orders
|
||||
.order(:created_at)
|
||||
.reverse_order
|
||||
.paginate(page: page)
|
||||
end
|
||||
|
||||
def products_group_by_id
|
||||
products
|
||||
.select("products.*", "sum(order_items.count) as count")
|
||||
.group(:product_id)
|
||||
.order("count")
|
||||
.reverse_order
|
||||
end
|
||||
end
|
|
@ -1,13 +1,12 @@
|
|||
class OrdersController < ApplicationController
|
||||
include ActionView::Helpers::NumberHelper
|
||||
include ApplicationHelper
|
||||
|
||||
load_resource :user
|
||||
load_and_authorize_resource :order, through: :user, shallow: true
|
||||
|
||||
def new
|
||||
products = (@user.products.for_sale.select("products.*", "sum(order_items.count) as count").group(:product_id).order("count desc") | Product.for_sale)
|
||||
@order.g_order_items products
|
||||
products.each do |p|
|
||||
@order.order_items.build(product: p)
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
|
@ -29,18 +28,6 @@ class OrdersController < ApplicationController
|
|||
@users = User.members.publik.order(:name)
|
||||
end
|
||||
|
||||
def quickpay
|
||||
user = User.find(params[:id])
|
||||
order = user.orders.build
|
||||
order.order_items << OrderItem.new(count: 1, product: user.dagschotel, order: order)
|
||||
if order.save
|
||||
flash[:success] = "Quick pay succeeded. #{view_context.link_to("Undo", [user, order], method: :delete)}."
|
||||
else
|
||||
flash[:error] = order.errors.full_messages.first
|
||||
end
|
||||
redirect_to root_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def order_params
|
||||
|
|
|
@ -4,11 +4,9 @@ class ProductsController < ApplicationController
|
|||
respond_to :html, :js
|
||||
|
||||
def new
|
||||
@product = Product.new
|
||||
end
|
||||
|
||||
def create
|
||||
@product = Product.new(product_params)
|
||||
if @product.save
|
||||
flash[:success] = "Product created!"
|
||||
redirect_to products_path
|
||||
|
@ -25,12 +23,10 @@ class ProductsController < ApplicationController
|
|||
end
|
||||
|
||||
def edit
|
||||
@product = Product.find(params[:id])
|
||||
respond_with @product
|
||||
end
|
||||
|
||||
def update
|
||||
@product = Product.find(params[:id])
|
||||
@product.update_attributes product_params
|
||||
respond_with @product
|
||||
end
|
||||
|
|
|
@ -2,7 +2,6 @@ class StocksController < ApplicationController
|
|||
load_and_authorize_resource
|
||||
|
||||
def new
|
||||
@stock = Stock.new
|
||||
Product.all.each do |p|
|
||||
@stock.stock_entries << Stock::StockEntry.new(product: p)
|
||||
end
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
class UsersController < ApplicationController
|
||||
load_and_authorize_resource
|
||||
before_action :init, only: [:show, :edit, :update]
|
||||
before_action :init, only: :show
|
||||
|
||||
def show
|
||||
@categories = @user.products
|
||||
.select("products.category", "sum(order_items.count) as count")
|
||||
.group(:category)
|
||||
end
|
||||
|
||||
def edit
|
||||
|
@ -26,15 +23,12 @@ class UsersController < ApplicationController
|
|||
end
|
||||
|
||||
def destroy
|
||||
user = User.find(params[:id])
|
||||
user.destroy
|
||||
@user.destroy
|
||||
flash[:success] = "Succesfully removed user"
|
||||
redirect_to users_path
|
||||
end
|
||||
|
||||
def edit_dagschotel
|
||||
@user = User.find(params[:id])
|
||||
authorize! :update_dagschotel, @user
|
||||
@dagschotel = @user.dagschotel
|
||||
|
||||
@products = Product.for_sale
|
||||
|
@ -42,14 +36,22 @@ class UsersController < ApplicationController
|
|||
end
|
||||
|
||||
def update_dagschotel
|
||||
user = User.find(params[:id])
|
||||
authorize! :update_dagschotel, user
|
||||
|
||||
user.dagschotel = Product.find(params[:product_id])
|
||||
user.save
|
||||
@user.dagschotel = Product.find(params[:product_id])
|
||||
@user.save
|
||||
|
||||
flash[:success] = "Succesfully updated dagschotel"
|
||||
redirect_to user
|
||||
redirect_to @user
|
||||
end
|
||||
|
||||
def quickpay
|
||||
order = @user.orders.build
|
||||
order.order_items.build(count: 1, product: user.dagschotel)
|
||||
if order.save
|
||||
flash[:success] = "Quick pay succeeded. #{view_context.link_to("Undo", [user, order], method: :delete)}."
|
||||
else
|
||||
flash[:error] = order.errors.full_messages.first
|
||||
end
|
||||
redirect_to root_path
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -60,14 +62,5 @@ class UsersController < ApplicationController
|
|||
|
||||
def init
|
||||
@user = User.find_by_id(params[:id]) || current_user
|
||||
@orders = @user.orders
|
||||
.order(:created_at)
|
||||
.reverse_order
|
||||
.paginate(page: params[:page])
|
||||
@products = @user.products
|
||||
.select("products.*", "sum(order_items.count) as count")
|
||||
.group(:product_id)
|
||||
.order("count")
|
||||
.reverse_order
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
module CallbacksHelper
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module SessionsHelper
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module StockHelper
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module WelcomeHelper
|
||||
end
|
|
@ -2,8 +2,18 @@ TabApiJob = Struct.new(:order_id) do
|
|||
def perform(*args)
|
||||
order = Order.find_by(id: order_id)
|
||||
if order && !order.transaction_id
|
||||
body = { transaction: { debtor: order.user.uid, cents: order.price_cents, message: order.to_sentence, id_at_client: order.id } }
|
||||
headers = { "Authorization" => "Token token=#{Rails.application.secrets.tab_api_key}" }
|
||||
body = {
|
||||
transaction: {
|
||||
debtor: order.user.uid,
|
||||
cents: order.price_cents,
|
||||
message: order.to_sentence,
|
||||
id_at_client: order.id
|
||||
}
|
||||
}
|
||||
headers = {
|
||||
"Authorization" => "Token token=#{Rails.application.secrets.tab_api_key}"
|
||||
}
|
||||
|
||||
result = HTTParty.post("https://zeus.ugent.be/tab/transactions", body: body, headers: headers )
|
||||
order.update_attribute(:transaction_id, JSON.parse(result.body)["id"].to_i)
|
||||
end
|
||||
|
|
|
@ -2,18 +2,21 @@ class Ability
|
|||
include CanCan::Ability
|
||||
|
||||
def initialize(user)
|
||||
user ||= User.new # guest user (not logged in)
|
||||
return unless user
|
||||
|
||||
if user.admin?
|
||||
can :manage, :all
|
||||
elsif user.koelkast?
|
||||
can :manage, Order
|
||||
elsif user[:id]
|
||||
else
|
||||
can :read, :all
|
||||
can :manage, User, id: user.id
|
||||
can :manage, Order do |order|
|
||||
can :create, Order do |order|
|
||||
order.try(:user) == user
|
||||
end
|
||||
can :delete, Order do |order|
|
||||
order.try(:user) == user && order.created_at > Rails.application.config.call_api_after.ago
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
# transaction_id :integer
|
||||
#
|
||||
|
||||
require 'httparty'
|
||||
class Order < ActiveRecord::Base
|
||||
include ActionView::Helpers::TextHelper
|
||||
|
||||
|
@ -20,11 +19,12 @@ class Order < ActiveRecord::Base
|
|||
|
||||
before_validation :calculate_price
|
||||
before_save { |o| o.order_items = o.order_items.reject{ |oi| oi.count == 0 } }
|
||||
after_create { Delayed::Job.enqueue TabApiJob.new(id) }
|
||||
after_create :create_api_job
|
||||
|
||||
validates :user, presence: true
|
||||
validates :order_items, presence: true, in_stock: true
|
||||
validates :order_items, presence: true
|
||||
validates :price_cents, presence: true
|
||||
validates_associated :order_items
|
||||
|
||||
accepts_nested_attributes_for :order_items
|
||||
|
||||
|
@ -34,15 +34,17 @@ class Order < ActiveRecord::Base
|
|||
}.to_sentence
|
||||
end
|
||||
|
||||
def g_order_items(products)
|
||||
products.each do |p|
|
||||
self.order_items.build(product: p)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def calculate_price
|
||||
self.price_cents = self.order_items.map{ |oi| oi.count * oi.product.price_cents }.sum
|
||||
end
|
||||
def calculate_price
|
||||
self.price_cents = self.order_items.map{ |oi| oi.count * oi.product.price_cents }.sum
|
||||
end
|
||||
|
||||
def create_api_job
|
||||
priority = 0
|
||||
run_at = Rails.application.config.call_api_after.from_now
|
||||
job = TabApiJob.new(id)
|
||||
|
||||
Delayed::Job.enqueue job, priority, run_at
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,25 +13,31 @@ class OrderItem < ActiveRecord::Base
|
|||
belongs_to :product
|
||||
|
||||
validates :product, presence: true
|
||||
validates :count, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }
|
||||
validates :count, presence: true, numericality: { only_integer: true,
|
||||
less_than_or_equal_to: ->(oi) { oi.product.stock },
|
||||
greater_than_or_equal_to: 0 }
|
||||
|
||||
before_destroy :put_back_in_stock
|
||||
after_create :remove_from_stock
|
||||
before_destroy :put_back_in_stock!
|
||||
after_create :remove_from_stock!
|
||||
|
||||
accepts_nested_attributes_for :product
|
||||
|
||||
def product_attributes=(attributes)
|
||||
self.product = Product.find(attributes[:id])
|
||||
self.product = OrderItem.products.select{ |p| p.id == attributes[:id].to_i }.first
|
||||
super
|
||||
end
|
||||
|
||||
def self.products
|
||||
@products || Product.all
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def remove_from_stock
|
||||
def remove_from_stock!
|
||||
product.decrement!(:stock, count)
|
||||
end
|
||||
|
||||
def put_back_in_stock
|
||||
def put_back_in_stock!
|
||||
product.increment!(:stock, self.count)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,7 +42,7 @@ class Product < ActiveRecord::Base
|
|||
self.price_cents = (value.to_f * 100).to_int
|
||||
end
|
||||
|
||||
def out_of_sale
|
||||
def take_out_of_sale!
|
||||
update_attribute :deleted, true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
require 'identicon'
|
||||
class User < ActiveRecord::Base
|
||||
include Statistics
|
||||
|
||||
devise :database_authenticatable, :trackable, :omniauthable, :omniauth_providers => [:zeuswpi]
|
||||
|
||||
has_paper_trail
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
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
|
|
@ -8,7 +8,6 @@
|
|||
<%= order.to_sentence %>
|
||||
</td>
|
||||
<td>
|
||||
<% p order %>
|
||||
<%= euro_from_cents(order.price_cents) %>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<ul class="list-group">
|
||||
<li class="list-group-item text-muted">Orders</li>
|
||||
<li class="list-group-item"><strong>Orders placed</strong><span class="badge"><%= @user.orders_count %></span></li>
|
||||
<li class="list-group-item"><strong>Products ordered</strong><span class="badge"><%= @products.map(&:count).sum %></span></li>
|
||||
<li class="list-group-item"><strong>Products ordered</strong><span class="badge"><%= @user.products_group_by_id.map(&:count).sum %></span></li>
|
||||
<% if can? :create, @user.orders.build %>
|
||||
<li class="list-group-item"><%= link_to "Place new order", new_user_order_path(@user), class: "btn btn-default btn-block" %></li>
|
||||
<% end %>
|
||||
|
|
|
@ -2,25 +2,25 @@
|
|||
<div class="row">
|
||||
<%= render 'sidebar' %>
|
||||
<div id="user_info" class="col-sm-9">
|
||||
<% if @orders.any? %>
|
||||
<% if (all_orders = @user.all_orders(params[:page])).any? %>
|
||||
<h4>Previously ordered</h4>
|
||||
Total:
|
||||
<ul>
|
||||
<li>
|
||||
<%= @categories.map{|c| pluralize(c.count, c.category)}.to_sentence %>
|
||||
<%= @user.products_group_by_category.map{|c| pluralize(c.count, c.category)}.to_sentence %>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
Specifics:
|
||||
<%= content_tag :ul do %>
|
||||
<% @products.each do |p| %>
|
||||
<% @user.products_group_by_id.each do |p| %>
|
||||
<%= content_tag :li, pluralize(p.count, p.name) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<h4>All orders (<%= @user.orders_count %>)</h4>
|
||||
<table class="orders"><%= render @orders %></table>
|
||||
<%= will_paginate @orders %>
|
||||
<table class="orders"><%= render all_orders %></table>
|
||||
<%= will_paginate all_orders %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -21,5 +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
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,17 +18,17 @@ Rails.application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
resources :users do
|
||||
resources :orders
|
||||
resources :users, only: [:show, :edit, :update, :destroy] do
|
||||
resources :orders, only: [:new, :create, :destroy]
|
||||
member do
|
||||
get 'quickpay' => 'orders#quickpay'
|
||||
get 'quickpay' => 'users#quickpay'
|
||||
get 'dagschotel/edit' => 'users#edit_dagschotel', as: 'edit_dagschotel'
|
||||
get 'dagschotel/:product_id' => 'users#update_dagschotel', as: 'dagschotel'
|
||||
end
|
||||
end
|
||||
|
||||
resources :products
|
||||
resources :stocks
|
||||
resources :products, only: [:new, :create, :index, :edit, :update]
|
||||
resources :stocks, only: [:new, :create]
|
||||
|
||||
get 'overview' => 'orders#overview', as: "orders"
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue