office_clerk 0.7 → 0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.md +11 -0
- data/Gemfile.lock +8 -8
- data/Guardfile +1 -0
- data/README.md +2 -2
- data/app/controllers/baskets_controller.rb +1 -1
- data/app/controllers/office_controller.rb +3 -43
- data/app/controllers/orders_controller.rb +1 -5
- data/app/controllers/sessions_controller.rb +14 -7
- data/app/helpers/admin_helper.rb +0 -1
- data/app/helpers/categories_helper.rb +11 -0
- data/app/helpers/office_helper.rb +43 -0
- data/app/helpers/orders_helper.rb +4 -0
- data/app/mailers/order_mailer.rb +14 -4
- data/app/models/clerk.rb +9 -2
- data/app/models/order.rb +4 -0
- data/app/views/baskets/edit.html.haml +2 -2
- data/app/views/categories/show.html.haml +1 -1
- data/app/views/layouts/_header_extra.haml +6 -5
- data/app/views/layouts/office_clerk.haml +8 -8
- data/app/views/order_mailer/_order.text.erb +24 -0
- data/app/views/order_mailer/cancel.text.erb +4 -18
- data/app/views/order_mailer/confirm.text.erb +7 -20
- data/app/views/order_mailer/paid.text.erb +3 -16
- data/app/views/order_mailer/shipped.text.erb +7 -13
- data/app/views/orders/index.html.haml +3 -3
- data/app/views/products/_preview_box.haml +11 -0
- data/app/views/products/show.html.haml +1 -1
- data/app/views/sessions/sign_in.haml +9 -9
- data/app/views/sessions/sign_up.haml +4 -16
- data/bin/rspec +4 -0
- data/bin/spring +1 -1
- data/config/locales/en.yml +3 -0
- data/config/locales/fi.yml +3 -0
- data/config/routes.rb +1 -15
- data/lib/office_clerk/engine.rb +10 -4
- data/lib/office_clerk/shipping_method.rb +5 -0
- data/lib/office_clerk/version.rb +1 -1
- data/office_clerk.gemspec +6 -6
- data/spec/controllers/sessions_controller_spec.rb +1 -1
- data/spec/features/orders_spec.rb +5 -0
- data/spec/features/sessions_spec.rb +3 -4
- data/spec/mailers/order_mailer_spec.rb +57 -14
- data/spec/models/clerk/email_spec.rb +4 -3
- data/spec/models/clerk/misc_spec.rb +19 -0
- data/spec/support/product_helper.rb +8 -0
- data/test_app/config/environments/development.rb +1 -1
- data/test_app/config/environments/test.rb +1 -1
- data/test_app/config/locales/config.yml +2 -0
- data/test_app/config/routes.rb +4 -1
- metadata +33 -21
- data/app/controllers/shop_controller.rb +0 -91
- data/app/helpers/shop_helper.rb +0 -18
- data/app/views/layouts/_google.haml +0 -8
- data/app/views/layouts/sales_clerk.haml +0 -10
- data/app/views/shop/_product_box.haml +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f6cbbcac08eb644af00cbaa6ca5748abd294f8b
|
4
|
+
data.tar.gz: e97b58ec03899ad284661fb57cb0f8b3cb3a19aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45e2d64b1a17763ff6297c4bd3dfa34e4e0b88ece8f36ae6cf97e263ae339270d6e8f15576b4bbe532ffb032ac2f60a9921b173898327f27e3e4363497b97113
|
7
|
+
data.tar.gz: 3d430db74a07576e61ad526aeef76d086a4068540640ada2db42dbcd52306d5666c9430c24a5c5a1676fed259ac07b6e41f57d15d3b8be401a98d166a628ac83
|
data/ChangeLog.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
### 0.8
|
2
|
+
|
3
|
+
- fix order search
|
4
|
+
- improve sign_in and up behaviour
|
5
|
+
- move sales layout there
|
6
|
+
- remove analytics (is an app function)
|
7
|
+
- fix emails
|
8
|
+
- manage printing inline (inside the layout), improves navigation
|
9
|
+
- using best in place to edit new order note and simple product features
|
10
|
+
- pin to rails under 4.2
|
11
|
+
|
1
12
|
### 0.7
|
2
13
|
|
3
14
|
- Order search improvements, added a private Note too
|
data/Gemfile.lock
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ../
|
3
3
|
specs:
|
4
|
-
office_clerk (0.
|
4
|
+
office_clerk (0.8)
|
5
5
|
bcrypt-ruby (~> 3.1)
|
6
6
|
best_in_place
|
7
7
|
bootstrap-sass (~> 3.1)
|
8
8
|
bootstrap_form (~> 2.2)
|
9
|
-
coffee-rails
|
9
|
+
coffee-rails (~> 4.0)
|
10
10
|
gon
|
11
11
|
haml (~> 4.0)
|
12
12
|
jquery-rails (~> 3.1)
|
13
13
|
jquery-ui-rails (~> 5.0)
|
14
14
|
kramdown (~> 1.5)
|
15
15
|
paperclip (~> 4.1)
|
16
|
-
rails (~> 4.1,
|
16
|
+
rails (~> 4.1, < 4.2)
|
17
17
|
rails-i18n (~> 4.0)
|
18
|
-
ransack (>= 1.5.1)
|
18
|
+
ransack (~> 1.5, >= 1.5.1)
|
19
19
|
sass-rails (~> 4.0)
|
20
|
-
valid_email
|
20
|
+
valid_email (~> 0.0.10)
|
21
21
|
will_paginate-bootstrap (~> 1.0)
|
22
22
|
|
23
23
|
GEM
|
@@ -54,7 +54,7 @@ GEM
|
|
54
54
|
bcrypt (3.1.9)
|
55
55
|
bcrypt-ruby (3.1.5)
|
56
56
|
bcrypt (>= 3.1.3)
|
57
|
-
best_in_place (3.0.
|
57
|
+
best_in_place (3.0.2)
|
58
58
|
actionpack (>= 3.2)
|
59
59
|
railties (>= 3.2)
|
60
60
|
better_errors (2.0.0)
|
@@ -81,7 +81,7 @@ GEM
|
|
81
81
|
timers (~> 4.0.0)
|
82
82
|
climate_control (0.0.3)
|
83
83
|
activesupport (>= 3.0)
|
84
|
-
cocaine (0.5.
|
84
|
+
cocaine (0.5.5)
|
85
85
|
climate_control (>= 0.0.3, < 1.0)
|
86
86
|
codeclimate-test-reporter (0.4.1)
|
87
87
|
simplecov (>= 0.7.1, < 1.0.0)
|
@@ -159,7 +159,7 @@ GEM
|
|
159
159
|
multi_json (1.10.1)
|
160
160
|
nokogiri (1.6.4.1)
|
161
161
|
mini_portile (~> 0.6.0)
|
162
|
-
paperclip (4.2.
|
162
|
+
paperclip (4.2.1)
|
163
163
|
activemodel (>= 3.0.0)
|
164
164
|
activesupport (>= 3.0.0)
|
165
165
|
cocaine (~> 0.5.3)
|
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
[![Code Climate](https://codeclimate.com/github/rubyclerks/office_clerk/badges/gpa.svg)](https://codeclimate.com/github/rubyclerks/office_clerk)
|
5
5
|
[![Test Coverage](https://codeclimate.com/github/rubyclerks/office_clerk/badges/coverage.svg)](https://codeclimate.com/github/rubyclerks/office_clerk)
|
6
6
|
|
7
|
-
Office Clerk is the back office helper, your accountant, storage manager, secretary and more. It is the heart of the
|
7
|
+
Office Clerk is the back office helper, your accountant, storage manager, secretary and more. It is the heart of the [RubyClerks team](http://rubyclerks.org) , the manager as it were.
|
8
8
|
|
9
9
|
#### Status
|
10
10
|
|
@@ -39,7 +39,7 @@ The longer route, adding to existing project
|
|
39
39
|
|
40
40
|
- add office_clerk to Gemfile (gem or git)
|
41
41
|
- build your public pages
|
42
|
-
-
|
42
|
+
- possibly copy ShopController from sales_clerk as a starting point
|
43
43
|
|
44
44
|
### Further
|
45
45
|
|
@@ -103,7 +103,7 @@ class BasketsController < AdminController
|
|
103
103
|
if p_id = (params[:add] || params[:delete])
|
104
104
|
add = params[:add].blank? ? -1 : 1
|
105
105
|
@basket.add_product Product.find(p_id) , add
|
106
|
-
flash.notice = params[:add] ? t('product_added') : t('item_removed')
|
106
|
+
flash.now.notice = params[:add] ? t('product_added') : t('item_removed')
|
107
107
|
end
|
108
108
|
@basket.save!
|
109
109
|
end
|
@@ -1,54 +1,14 @@
|
|
1
1
|
class OfficeController < ApplicationController
|
2
|
-
|
3
|
-
# For APIs, you may want to use :null_session instead.
|
4
|
-
protect_from_forgery with: :exception
|
5
|
-
helper_method :current_clerk , :current_basket , :current_basket_or_nil
|
2
|
+
|
6
3
|
helper OfficeHelper
|
7
|
-
include
|
4
|
+
include OfficeHelper
|
8
5
|
|
9
|
-
|
10
|
-
# if user is not logged i , return nil
|
11
|
-
def current_clerk
|
12
|
-
return @current_clerk if @current_clerk
|
13
|
-
return nil unless session[:clerk_email]
|
14
|
-
@current_clerk = Clerk.where( :email => session[:clerk_email] ).limit(1).first
|
15
|
-
end
|
6
|
+
include OfficeClerk::Engine.routes.url_helpers
|
16
7
|
|
17
8
|
def error
|
18
9
|
logger.info "Error" + request.url
|
19
10
|
redirect_to "/"
|
20
11
|
end
|
21
12
|
|
22
|
-
def current_basket_or_nil
|
23
|
-
return @current_basket unless @current_basket.nil?
|
24
|
-
if session[:current_basket]
|
25
|
-
Basket.where( :id => session[:current_basket] ).limit(1).first
|
26
|
-
else
|
27
|
-
nil
|
28
|
-
end
|
29
|
-
end
|
30
|
-
# the current user has a shopping basket which is also stored in the session
|
31
|
-
# we *always* return a basket, even if we have to create one (and then store in the session)
|
32
|
-
# this is not associated with the user until an order is finalized at which point the order gets the users email (not id)
|
33
|
-
# that way people don't have to log in to order, but if they are we can retrieve their orders by email
|
34
|
-
def current_basket
|
35
|
-
@current_basket = current_basket_or_nil
|
36
|
-
if @current_basket.nil?
|
37
|
-
@current_basket = Basket.new(:kori_type => "Order")
|
38
|
-
@current_basket.save!
|
39
|
-
session[:current_basket] = @current_basket.id
|
40
|
-
end
|
41
|
-
@current_basket
|
42
|
-
end
|
43
13
|
|
44
|
-
private
|
45
|
-
def has_ssl?
|
46
|
-
return false unless Rails.env.production?
|
47
|
-
OfficeClerk.config(:has_ssl) == true
|
48
|
-
end
|
49
|
-
|
50
|
-
# when the order is made and the basket locked, it's time to make a new one
|
51
|
-
def new_basket
|
52
|
-
session[:current_basket] = nil
|
53
|
-
end
|
54
14
|
end
|
@@ -3,9 +3,6 @@ class OrdersController < AdminController
|
|
3
3
|
|
4
4
|
before_filter :load_order, :only => [:show, :edit, :update , :pay , :ship , :mail]
|
5
5
|
|
6
|
-
# Uncomment for check abilities with CanCan
|
7
|
-
#authorize_resource
|
8
|
-
|
9
6
|
def index
|
10
7
|
@q = Order.search(params[:q])
|
11
8
|
@order_scope = @q.result( :distinct => true)
|
@@ -31,8 +28,7 @@ class OrdersController < AdminController
|
|
31
28
|
redirect_to :action => :show
|
32
29
|
end
|
33
30
|
def pay
|
34
|
-
@order.
|
35
|
-
@order.save!
|
31
|
+
@order.pay_now!
|
36
32
|
render :show
|
37
33
|
end
|
38
34
|
def ship
|
@@ -1,7 +1,6 @@
|
|
1
1
|
class SessionsController < OfficeController
|
2
|
-
layout "sales_clerk"
|
3
2
|
|
4
|
-
force_ssl :if => :has_ssl?
|
3
|
+
force_ssl :if => :has_ssl? , :except => :sign_out
|
5
4
|
|
6
5
|
def sign_in
|
7
6
|
end
|
@@ -10,8 +9,11 @@ class SessionsController < OfficeController
|
|
10
9
|
clerk = Clerk.where(:email => params[:email]).limit(1).first
|
11
10
|
if clerk && clerk.valid_password?(params[:password])
|
12
11
|
session[:clerk_email] = clerk.email
|
13
|
-
|
14
|
-
|
12
|
+
if clerk.admin
|
13
|
+
redirect_to baskets_url , :notice => I18n.t(:signed_in)
|
14
|
+
else
|
15
|
+
redirect_after_sign_up
|
16
|
+
end
|
15
17
|
else
|
16
18
|
redirect_to :sign_in , :notice => I18n.t(:sign_in_invalid)
|
17
19
|
end
|
@@ -19,7 +21,7 @@ class SessionsController < OfficeController
|
|
19
21
|
|
20
22
|
def sign_out
|
21
23
|
session[:clerk_email] = nil
|
22
|
-
redirect_to
|
24
|
+
redirect_to Rails.application.routes.url_helpers.root_path , :notice => I18n.t(:signed_out)
|
23
25
|
end
|
24
26
|
|
25
27
|
def sign_up
|
@@ -29,14 +31,19 @@ class SessionsController < OfficeController
|
|
29
31
|
@clerk = Clerk.new(params_for_clerk)
|
30
32
|
if @clerk.save
|
31
33
|
session[:clerk_email] = @clerk.email
|
32
|
-
|
33
|
-
return
|
34
|
+
return redirect_after_sign_up
|
34
35
|
end
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
38
39
|
private
|
39
40
|
|
41
|
+
def redirect_after_sign_up
|
42
|
+
redirect_to main_app.root_url, :notice => t(:signed_up)
|
43
|
+
end
|
44
|
+
def redirect_after_sign_in
|
45
|
+
redirect_to main_app.root_url, :notice => t(:signed_in)
|
46
|
+
end
|
40
47
|
def params_for_clerk
|
41
48
|
params.require(:clerk).permit(:email,:password,:password_confirmation)
|
42
49
|
end
|
data/app/helpers/admin_helper.rb
CHANGED
@@ -1,6 +1,49 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
module OfficeHelper
|
3
3
|
|
4
|
+
# users are stored in the session by email
|
5
|
+
# if user is not logged i , return nil
|
6
|
+
def current_clerk
|
7
|
+
return @current_clerk if @current_clerk
|
8
|
+
return nil unless session[:clerk_email]
|
9
|
+
@current_clerk = Clerk.where( :email => session[:clerk_email] ).limit(1).first
|
10
|
+
end
|
11
|
+
def current_basket_or_nil
|
12
|
+
return @current_basket unless @current_basket.nil?
|
13
|
+
if session[:current_basket]
|
14
|
+
Basket.where( :id => session[:current_basket] ).limit(1).first
|
15
|
+
else
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
# the current user has a shopping basket which is also stored in the session
|
20
|
+
# we *always* return a basket, even if we have to create one (and then store in the session)
|
21
|
+
# this is not associated with the user until an order is finalized at which point the order gets the users email (not id)
|
22
|
+
# that way people don't have to log in to order, but if they are we can retrieve their orders by email
|
23
|
+
def current_basket
|
24
|
+
@current_basket = current_basket_or_nil
|
25
|
+
if @current_basket.nil?
|
26
|
+
@current_basket = Basket.new(:kori_type => "Order")
|
27
|
+
@current_basket.save!
|
28
|
+
session[:current_basket] = @current_basket.id
|
29
|
+
end
|
30
|
+
@current_basket
|
31
|
+
end
|
32
|
+
|
33
|
+
def has_ssl?
|
34
|
+
return false unless Rails.env.production?
|
35
|
+
OfficeClerk.config(:has_ssl) == true
|
36
|
+
end
|
37
|
+
|
38
|
+
# when the order is made and the basket locked, it's time to make a new one
|
39
|
+
def new_basket
|
40
|
+
session[:current_basket] = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def shipping_method name
|
44
|
+
OfficeClerk::ShippingMethod.method(name)
|
45
|
+
end
|
46
|
+
|
4
47
|
def markdown text
|
5
48
|
return "" if text.blank?
|
6
49
|
return sanitize Kramdown::Document.new(text).to_html
|
data/app/mailers/order_mailer.rb
CHANGED
@@ -1,19 +1,29 @@
|
|
1
|
+
# Mails may be sent from the admin interface for below actions.
|
2
|
+
|
3
|
+
# The SalesClerk sends a confirm when the order is received (they are unpaid at that time)
|
4
|
+
|
5
|
+
# Default from (possibly bcc) and mail delivery method must be set up in production.rb (see rails docs)
|
6
|
+
|
1
7
|
class OrderMailer < ActionMailer::Base
|
2
8
|
|
9
|
+
add_template_helper(OfficeHelper)
|
10
|
+
add_template_helper(OrdersHelper)
|
11
|
+
|
3
12
|
def confirm(order)
|
4
13
|
@order = order
|
5
|
-
mail(to: @order.email,
|
14
|
+
mail(to: @order.email, subject: "#{I18n.t(:order)} #{@order.number}")
|
6
15
|
end
|
7
16
|
def cancel(order)
|
8
17
|
@order = order
|
9
|
-
mail(to: @order.email,
|
18
|
+
mail(to: @order.email, subject: "#{I18n.t(:order)} #{@order.number}")
|
10
19
|
end
|
11
20
|
def paid(order)
|
12
21
|
@order = order
|
13
|
-
mail(to: @order.email,
|
22
|
+
mail(to: @order.email, subject: "#{I18n.t(:order)} #{@order.number}")
|
14
23
|
end
|
15
24
|
def shipped(order)
|
16
25
|
@order = order
|
17
|
-
mail(to: @order.email,
|
26
|
+
mail(to: @order.email, subject: "#{I18n.t(:order)} #{@order.number}")
|
18
27
|
end
|
28
|
+
|
19
29
|
end
|
data/app/models/clerk.rb
CHANGED
@@ -10,8 +10,11 @@ class Clerk < ActiveRecord::Base
|
|
10
10
|
validates_presence_of :encrypted_password
|
11
11
|
|
12
12
|
validates_uniqueness_of :email
|
13
|
-
|
14
|
-
|
13
|
+
if Rails.env.test?
|
14
|
+
validates :email, :presence => true , :email => true
|
15
|
+
else
|
16
|
+
validates :email, :presence => true, :email => {:ban_disposable_email => true, :mx_with_fallback => true }
|
17
|
+
end
|
15
18
|
store :address, accessors: [ :name , :street , :city , :phone ] #, coder: JSON
|
16
19
|
|
17
20
|
def whole_address
|
@@ -28,6 +31,10 @@ class Clerk < ActiveRecord::Base
|
|
28
31
|
res == 0
|
29
32
|
end
|
30
33
|
|
34
|
+
def last_address
|
35
|
+
order = Order.where(:email => self.email).first
|
36
|
+
order ? order.address : {}
|
37
|
+
end
|
31
38
|
private
|
32
39
|
|
33
40
|
def prepare_password
|
data/app/models/order.rb
CHANGED
@@ -44,6 +44,10 @@ class Order < ActiveRecord::Base
|
|
44
44
|
cart
|
45
45
|
end
|
46
46
|
|
47
|
+
def pay_now!
|
48
|
+
self.paid_on = Date.today
|
49
|
+
self.save!
|
50
|
+
end
|
47
51
|
#quick checkout, ie ship (hand over) and pay (externally)
|
48
52
|
def pos_checkout email
|
49
53
|
self.ordered_on = Date.today unless self.ordered_on
|
@@ -57,12 +57,12 @@
|
|
57
57
|
.col-md-2
|
58
58
|
= link_to t(:make_purchase), purchase_basket_path(@basket), :class => "btn btn-primary make_purchase"
|
59
59
|
.col-md-2
|
60
|
-
= link_to t(:checkout), checkout_basket_path(@basket) , :
|
60
|
+
= link_to t(:checkout), checkout_basket_path(@basket) , :class => "btn btn-primary print_order"
|
61
61
|
- elsif @basket.isa(:order)
|
62
62
|
.col-md-2
|
63
63
|
= link_to t(:to_order), order_path(@basket.kori), :class => "btn btn-primary to_order"
|
64
64
|
.col-md-2
|
65
|
-
= link_to t(:print_order), invoice_order_path(@basket.kori), :
|
65
|
+
= link_to t(:print_order), invoice_order_path(@basket.kori), :class => "btn btn-primary print_order"
|
66
66
|
- elsif @basket.isa(:purchase)
|
67
67
|
.col-md-2
|
68
68
|
= link_to t(:to_purchase), purchase_path(@basket.kori), :class => "btn btn-primary to_purchase"
|
@@ -28,7 +28,7 @@
|
|
28
28
|
= link_to t(:edit), edit_category_path(@category), :class => "btn btn-primary"
|
29
29
|
= link_to t(:back), categories_path, :class => "btn btn-primary"
|
30
30
|
%b= t(:shop_link) + " : "
|
31
|
-
= link_to @category.link , shop_group_path(@category.link)
|
31
|
+
= link_to @category.link , main_app.shop_group_path(@category.link)
|
32
32
|
|
33
33
|
=render "triple" , :groups => @category.categories
|
34
34
|
=render "products/triple" , :products => @category.products.no_items
|
@@ -1,5 +1,6 @@
|
|
1
|
-
-Rails::Engine.subclasses.map(&:instance).each do |e|
|
2
|
-
-
|
3
|
-
-
|
4
|
-
|
5
|
-
=
|
1
|
+
- ( Rails::Engine.subclasses.map(&:instance) << Rails.application).each do |e|
|
2
|
+
- next unless e.respond_to? :office_assets
|
3
|
+
- asset = e.office_assets
|
4
|
+
- next if asset.blank?
|
5
|
+
= stylesheet_link_tag asset , :media => :all
|
6
|
+
= javascript_include_tag asset
|