office_clerk 0.7 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +11 -0
  3. data/Gemfile.lock +8 -8
  4. data/Guardfile +1 -0
  5. data/README.md +2 -2
  6. data/app/controllers/baskets_controller.rb +1 -1
  7. data/app/controllers/office_controller.rb +3 -43
  8. data/app/controllers/orders_controller.rb +1 -5
  9. data/app/controllers/sessions_controller.rb +14 -7
  10. data/app/helpers/admin_helper.rb +0 -1
  11. data/app/helpers/categories_helper.rb +11 -0
  12. data/app/helpers/office_helper.rb +43 -0
  13. data/app/helpers/orders_helper.rb +4 -0
  14. data/app/mailers/order_mailer.rb +14 -4
  15. data/app/models/clerk.rb +9 -2
  16. data/app/models/order.rb +4 -0
  17. data/app/views/baskets/edit.html.haml +2 -2
  18. data/app/views/categories/show.html.haml +1 -1
  19. data/app/views/layouts/_header_extra.haml +6 -5
  20. data/app/views/layouts/office_clerk.haml +8 -8
  21. data/app/views/order_mailer/_order.text.erb +24 -0
  22. data/app/views/order_mailer/cancel.text.erb +4 -18
  23. data/app/views/order_mailer/confirm.text.erb +7 -20
  24. data/app/views/order_mailer/paid.text.erb +3 -16
  25. data/app/views/order_mailer/shipped.text.erb +7 -13
  26. data/app/views/orders/index.html.haml +3 -3
  27. data/app/views/products/_preview_box.haml +11 -0
  28. data/app/views/products/show.html.haml +1 -1
  29. data/app/views/sessions/sign_in.haml +9 -9
  30. data/app/views/sessions/sign_up.haml +4 -16
  31. data/bin/rspec +4 -0
  32. data/bin/spring +1 -1
  33. data/config/locales/en.yml +3 -0
  34. data/config/locales/fi.yml +3 -0
  35. data/config/routes.rb +1 -15
  36. data/lib/office_clerk/engine.rb +10 -4
  37. data/lib/office_clerk/shipping_method.rb +5 -0
  38. data/lib/office_clerk/version.rb +1 -1
  39. data/office_clerk.gemspec +6 -6
  40. data/spec/controllers/sessions_controller_spec.rb +1 -1
  41. data/spec/features/orders_spec.rb +5 -0
  42. data/spec/features/sessions_spec.rb +3 -4
  43. data/spec/mailers/order_mailer_spec.rb +57 -14
  44. data/spec/models/clerk/email_spec.rb +4 -3
  45. data/spec/models/clerk/misc_spec.rb +19 -0
  46. data/spec/support/product_helper.rb +8 -0
  47. data/test_app/config/environments/development.rb +1 -1
  48. data/test_app/config/environments/test.rb +1 -1
  49. data/test_app/config/locales/config.yml +2 -0
  50. data/test_app/config/routes.rb +4 -1
  51. metadata +33 -21
  52. data/app/controllers/shop_controller.rb +0 -91
  53. data/app/helpers/shop_helper.rb +0 -18
  54. data/app/views/layouts/_google.haml +0 -8
  55. data/app/views/layouts/sales_clerk.haml +0 -10
  56. data/app/views/shop/_product_box.haml +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c64817a8d69623b98ac71359f18f3b2d47683bd2
4
- data.tar.gz: dcfe694a0ed59c10487658e77090d224676c4d39
3
+ metadata.gz: 8f6cbbcac08eb644af00cbaa6ca5748abd294f8b
4
+ data.tar.gz: e97b58ec03899ad284661fb57cb0f8b3cb3a19aa
5
5
  SHA512:
6
- metadata.gz: b9f11aa0e76f6d1683da1e324cf8a8b65bba947adaa6455ec97d5049c2494376cca854a8654b046653a89b20101837e041ea9d5a4629816d3c222d150673023d
7
- data.tar.gz: 0bc48769c8e8d8492e1a9914e92d3c2df7b4fd37f4b8402c0167fadf1507071eb84369bef281c1eff540c247a308a1a4e979f14b7a06cf11db69a8c4d68308c2
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.6)
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, <= 4.2)
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.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.4)
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.0)
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
@@ -3,6 +3,7 @@ begin
3
3
  require "rubygems"
4
4
  require "spring/version" #safe to try
5
5
  command = "spring rspec"
6
+ puts "Using Spring loaded rspec"
6
7
  rescue LoadError
7
8
  end
8
9
  guard :rspec , :cmd => command do
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 "RubyClerks team":http://rubyclerks.org , the manager as it were.
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
- - may use ShopController which is included in office
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
- # Prevent CSRF attacks by raising an exception.
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 OfficeClerk::Engine.routes.url_helpers
4
+ include OfficeHelper
8
5
 
9
- # users are stored in the session by email
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.paid_on = Date.today
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
- url = clerk.admin ? office.baskets_url : root_url
14
- redirect_to url , :notice => I18n.t(:signed_in)
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 root_url, :notice => I18n.t(:signed_out)
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
- redirect_to root_url, :notice => "Signed up!"
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
@@ -36,5 +36,4 @@ module AdminHelper
36
36
  attributes.reverse_merge! defaults
37
37
  best_in_place(object , field , attributes)
38
38
  end
39
- BestInPlace::ViewHelpers.extend OfficeHelper
40
39
  end
@@ -1,4 +1,15 @@
1
1
  # encoding : utf-8
2
2
  require "admin_helper"
3
3
  module CategoriesHelper
4
+
5
+ def parents(group)
6
+ parents = []
7
+ group = group.category
8
+ while group
9
+ parents << group
10
+ group = group.category
11
+ end
12
+ parents.reverse
13
+ end
14
+
4
15
  end
@@ -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
@@ -8,4 +8,8 @@ module OrdersHelper
8
8
  def mail_path action
9
9
 
10
10
  end
11
+ def viite
12
+ base = @order.number[1 .. -1]
13
+ viite = open("http://www1.nordea.fi/P636V/H636VTXT.asp?action=tekstiLista&lkm=1&alkuViite=#{base}&L=1").read[/\d+ \d+/]
14
+ end
11
15
  end
@@ -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, from: "me@here.now" , subject: "Order #{@order.number}")
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, from: "me@here.now" , subject: "Order #{@order.number}")
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, from: "me@here.now" , subject: "Order #{@order.number}")
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, from: "me@here.now" , subject: "Order #{@order.number}")
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
- validates :email, :presence => true, :email => {:ban_disposable_email => true, :mx_with_fallback => true }
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) , :target => "_blank" , :class => "btn btn-primary print_order"
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), :target => "_blank" , :class => "btn btn-primary print_order" , :target => "_blank"
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
- - name = e.engine_name.sub("clerk" , "office")
3
- - next if name == e.engine_name
4
- = stylesheet_link_tag name
5
- = javascript_include_tag name
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