office_clerk 0.7 → 0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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