accountant_clerk 0.6 → 0.7

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.
data/Rakefile CHANGED
@@ -4,3 +4,11 @@
4
4
  require File.expand_path('../test_app/config/application', __FILE__)
5
5
 
6
6
  TestApp::Application.load_tasks
7
+ require 'bundler/gem_tasks'
8
+
9
+ desc 'Rebuild test and run specs'
10
+ task :full_test do
11
+ system("rake db:drop db:migrate RAILS_ENV=test && rspec")
12
+ end
13
+
14
+ task :default => 'full_test'
@@ -2,7 +2,7 @@
2
2
  Gem::Specification.new do |s|
3
3
  s.platform = Gem::Platform::RUBY
4
4
  s.name = 'accountant_clerk'
5
- s.version = '0.6'
5
+ s.version = '0.7'
6
6
  s.summary = 'Simple reports for rubyclerks'
7
7
  s.description = 'Simple reports that are not so simple anymore and let you analyse your shops performance'
8
8
  s.required_ruby_version = '>= 1.9.3'
@@ -17,7 +17,6 @@ Gem::Specification.new do |s|
17
17
  s.require_path = 'lib'
18
18
  s.requirements << 'none'
19
19
 
20
- s.add_runtime_dependency 'office_clerk', '~> 0.8'
20
+ s.add_runtime_dependency 'office_clerk', '~> 0.9'
21
21
  s.add_runtime_dependency 'flot-rails', '~> 0.0.6'
22
22
  end
23
-
@@ -0,0 +1,4 @@
1
+ //= require 'jquery.flot'
2
+ //= require 'jquery.flot.resize'
3
+ //= require 'jquery.flot.time'
4
+ //= require 'jquery.flot.stack'
@@ -1,5 +1,3 @@
1
- //= require flotomatic
2
-
3
1
  div.flot_choice_label { font-variant: small-caps; font-weight: bold;}
4
2
  div.flot_canvas {width:600px; height:300px}
5
3
  div.flot_overview {width:600px; height:50px}
@@ -4,13 +4,20 @@ ManageController.class_eval do
4
4
  search = params[:q] || {}
5
5
  search[:meta_sort] = "created_at asc"
6
6
  if search[:created_at_gt].blank?
7
- search[:created_at_gt] = (Time.now - 3.months)
7
+ search[:created_at_gt] = short_date(Time.now - 3.months)
8
8
  else
9
- search[:created_at_gt] = Time.zone.parse(search[:created_at_gt]).beginning_of_day rescue Time.zone.now.beginning_of_month
9
+ search[:created_at_gt] =
10
+ begin
11
+ short_date(Time.zone.parse(search[:created_at_gt]).beginning_of_day)
12
+ rescue
13
+ I18n.l(Time.zone.now.beginning_of_month)
14
+ end
10
15
  end
11
16
  unless search[:created_at_lt].blank?
12
- search[:created_at_lt] =
13
- Time.zone.parse(search[:created_at_lt]).end_of_day rescue search[:created_at_lt]
17
+ begin
18
+ search[:created_at_lt] = short_date(Time.zone.parse(search[:created_at_lt]).end_of_day)
19
+ rescue
20
+ end
14
21
  end
15
22
  @type = params[:type] || "Order"
16
23
  search[:basket_kori_type_eq] = @type
@@ -33,14 +40,19 @@ ManageController.class_eval do
33
40
  Item
34
41
  end
35
42
  @search = search_on.includes(:product).ransack(search)
36
- gon.flot_options = { :series => { :bars => { :show => true , :barWidth => @days * 24*60*60*1000 } , :stack => 0 } ,
43
+ gon.flot_options = { :series => { :bars => { :show => true , :barWidth => @days * 24*60*60*1000 } , :stack => true } ,
37
44
  :legend => { :container => "#legend"} ,
38
45
  :xaxis => { :mode => "time" }
39
46
  }
40
47
  group_data
41
- # csv ? send_data( render_to_string( :csv , :layout => false) , :type => "application/csv" , :filename => "tilaukset.csv")
42
48
  end
43
49
 
50
+ private
51
+
52
+ def short_date d
53
+ d = d.to_date unless d.is_a? Date
54
+ I18n.l( d , :format => :default)
55
+ end
44
56
  def group_data
45
57
  @group_by = (params[:group_by] || "all" )
46
58
  all = @search.result(:distinct => true )
@@ -72,12 +84,9 @@ ManageController.class_eval do
72
84
  when "by_supplier"
73
85
  item.product.supplier.blank? ? "blank" : item.product.supplier.supplier_name
74
86
  when "by_product"
75
- item.product.name
76
- when "by_product_line"
77
- return "Basket #{item.basket.id}" if item.product.line_item? and not item.product.product
78
- return "Basket #{item.basket.id}" unless item.product
79
87
  item.product.full_name
80
- # item.product.line_item? ? item.product.product.name : item.product.name
88
+ when "by_product_line"
89
+ item.product.product ? item.product.product.name : item.product.name
81
90
  else
82
91
  pps = item.product.properties.detect{|p,v| p == @group_by}
83
92
  pps ? pps.value : "blank"
@@ -1,7 +1,5 @@
1
1
  - content_for :head do
2
- = javascript_include_tag 'jquery.flot'
3
- = javascript_include_tag 'jquery.flot.resize'
4
- = javascript_include_tag 'jquery.flot.time'
2
+ = javascript_include_tag 'accountant_report.js'
5
3
  .row
6
4
  .col-md-9
7
5
  #placeholder{:style => "width:800px;height:400px;"}
@@ -18,54 +16,54 @@
18
16
  .col-md-4
19
17
  = f.label :product_name_cont, t("name")
20
18
  .col-md-8
21
- = f.text_field :product_name_cont, :size => 15 , :class => "form-control"
19
+ = f.text_field :product_name_or_product_product_name_cont, :size => 15 , :class => "form-control"
20
+ .form-group
22
21
  .col-md-4
23
22
  = f.label :supplier , t(:supplier)
24
23
  .col-md-8
25
- = f.text_field :product_supplier_supplier_name_cont, :size => 15 , :class => "form-control"
26
- .form-group.row
24
+ = f.collection_select :product_supplier_id_eq, Supplier.all, :id, :supplier_name, {:include_blank => true}, :class=>"form-control"
25
+ .form-group
27
26
  .col-md-4
28
27
  = f.label :category, t(:category)
29
28
  .col-md-8
30
- = f.text_field :product_category_name_cont, :size => 15 , :class => "form-control"
29
+ = f.collection_select :product_category_id_eq, Category.all, :id, :name, {:include_blank => true}, :class=>"form-control"
30
+ .form-group
31
31
  .col-md-4
32
32
  = f.label :property , t(:property)
33
33
  .col-md-8
34
34
  = f.text_field :product_properties_cont, :size => 15 , :class => "form-control"
35
- .form-group.row
36
- .col-md-3
35
+ .form-group
36
+ .col-md-4
37
37
  = f.label :price , t(:price)
38
- .col-md-3
39
- = f.text_field :price_gt , :size => 6 , :class => "form-control"
40
- .col-md-1
41
-
42
- .col-md-3
38
+ .col-md-4
39
+ = f.text_field :price_gt , :size => 6 , :class => "form-control"
40
+ .col-md-4
43
41
  = f.text_field :price_lt , :size => 6 , :class => "form-control"
44
- .form-group.row
42
+ .form-group
45
43
  %label= t("date_range")
46
44
  .date-range-filter
47
45
  .col-md-6
48
46
  = f.text_field :created_at_gt, :class => 'datepicker form-control' , :value => sort_date(:created_at_gt)
49
47
  .col-md-6
50
48
  = f.text_field :created_at_lt, :class => 'datepicker form-control', :value => sort_date(:created_at_lt)
51
- .form-group.row
49
+ .form-group
52
50
  %label= t("group_by")
53
51
  %br/
54
52
  = select_tag :group_by, options_for_select( group_options , @group_by) , :class => "form-control"
55
- .form-group.row
56
- .col-md-6
53
+ .form-group
54
+ .col-md-4
57
55
  = t(:price)
58
- = radio_button_tag :price_or, "total" , :total == @price_or
59
- .col-md-6
56
+ = radio_button_tag :price_or, :total , :total == @price_or
57
+ .col-md-4
58
+ = t(:profit)
59
+ = radio_button_tag :price_or, :profit , :profit == @price_or
60
+ .col-md-4
60
61
  = t(:quantity)
61
- = radio_button_tag :price_or, "quantity" , :quantity == @price_or
62
- .form-group.row
62
+ = radio_button_tag :price_or, :quantity , :quantity == @price_or
63
+ .form-group
63
64
  .col-md-4
64
- = button_tag( :name => 'period' , :value => :day ) do
65
- %span Day
65
+ = f.submit :month , :class => "btn btn-success" , :name => 'period'
66
66
  .col-md-4
67
- = button_tag( :name => 'period' , :value => :week ) do
68
- %span Week
67
+ = f.submit :week , :class => "btn btn-success" , :name => 'period'
69
68
  .col-md-4
70
- = button_tag( :name => 'period' , :value => :month ) do
71
- %span Month
69
+ = f.submit :day , :class => "btn btn-success" , :name => 'period'
@@ -0,0 +1,89 @@
1
+ # i18n-tasks finds and manages missing and unused translations https://github.com/glebm/i18n-tasks
2
+
3
+ base_locale: en
4
+ ## i18n-tasks detects locales automatically from the existing locale files
5
+ ## uncomment to set locales explicitly
6
+ locales: [en, fi]
7
+
8
+ ## i18n-tasks report locale, default: en, available: en, ru
9
+ # internal_locale: ru
10
+
11
+ # Read and write locale data
12
+ data:
13
+ ## by default, translation data are read from the file system, or you can provide a custom data adapter
14
+ # adapter: I18n::Tasks::Data::FileSystem
15
+
16
+ # Locale files to read from
17
+ read:
18
+ - config/locales/%{locale}.yml
19
+ # - config/locales/*.%{locale}.yml
20
+ # - config/locales/**/*.%{locale}.yml
21
+
22
+ # key => file routes, matched top to bottom
23
+ write:
24
+ ## E.g., write devise and simple form keys to their respective files
25
+ - ['{config}.*', 'config/locales/\1.%{locale}.yml']
26
+ # Catch-all
27
+ - config/locales/%{locale}.yml
28
+ # `i18n-tasks normalize -p` will force move the keys according to these rules
29
+
30
+ # YAML / JSON serializer options, passed to load / dump / parse / serialize
31
+ yaml:
32
+ write:
33
+ # do not wrap lines at 80 characters
34
+ line_width: -1
35
+ json:
36
+ write:
37
+ # pretty print JSON
38
+ indent: ' '
39
+ space: ' '
40
+ object_nl: "\n"
41
+ array_nl: "\n"
42
+
43
+ # Find translate calls
44
+ search:
45
+ ## Default scanner finds t() and I18n.t() calls
46
+ # scanner: I18n::Tasks::Scanners::PatternWithScopeScanner
47
+
48
+ ## Paths to search in, passed to File.find
49
+ paths:
50
+ - app/
51
+
52
+ ## Root for resolving relative keys (default)
53
+ # relative_roots:
54
+ # - app/views
55
+
56
+ ## File.fnmatch patterns to exclude from search (default)
57
+ # exclude: ["*.jpg", "*.png", "*.gif", "*.svg", "*.ico", "*.eot", "*.ttf", "*.woff", "*.pdf"]
58
+
59
+ ## Or, File.fnmatch patterns to include
60
+ # include: ["*.rb", "*.html.slim"]
61
+
62
+ ## Google Translate
63
+ # # Get an API key and set billing info at https://code.google.com/apis/console to use Google Translate
64
+ translation:
65
+ api_key: "AIzaSyCRjToD-btZK_eaaLeqKNmoh1fPoqhbAtQ"
66
+
67
+ ## Consider these keys not missing
68
+ # ignore_missing:
69
+ # - 'errors.messages.{accepted,blank,invalid,too_short,too_long}'
70
+ # - '{devise,simple_form}.*'
71
+
72
+ ## Consider these keys used
73
+ # ignore_unused:
74
+ # - 'activerecord.attributes.*'
75
+ # - '{devise,kaminari,will_paginate}.*'
76
+ # - 'simple_form.{yes,no}'
77
+ # - 'simple_form.{placeholders,hints,labels}.*'
78
+ # - 'simple_form.{error_notification,required}.:'
79
+
80
+ ## Exclude these keys from `i18n-tasks eq-base' report
81
+ # ignore_eq_base:
82
+ # all:
83
+ # - common.ok
84
+ # fr,es:
85
+ # - common.brand
86
+
87
+ ## Exclude these keys from all of the reports
88
+ #ignore:
89
+ # - kaminari.*
@@ -1,8 +1,7 @@
1
1
  en:
2
- some: ho
3
-
4
- fi:
5
- date_range: Päivämäärä
6
- group_by: Ryhmitellä
7
- all: Kaikki
8
- property: Omaisuus
2
+ profit: Profit
3
+ date_range: Date
4
+ group_by: Group by
5
+ all: All
6
+ property: Property
7
+
@@ -0,0 +1,6 @@
1
+ fi:
2
+ profit: Kate
3
+ date_range: Päivämäärä
4
+ group_by: Ryhmitellä
5
+ all: Kaikki
6
+ property: Omaisuus
@@ -24,7 +24,7 @@ module AccountantClerk
24
24
  end
25
25
  end
26
26
  initializer "accountant.precompile", :group => :all do |app|
27
- app.config.assets.precompile += ["accountant_office.css" , "accountant_office.js"]
27
+ app.config.assets.precompile += ["accountant_office.css" , "accountant_office.js" , "accountant_report.js" ]
28
28
  end
29
29
 
30
30
  config.to_prepare &method(:activate).to_proc
@@ -5,7 +5,7 @@ describe OrdersController do
5
5
 
6
6
  before :all do
7
7
  create :admin unless Clerk.where(:admin => true).first
8
- end
8
+ end
9
9
 
10
10
  # This should return the minimal set of values that should be in the session
11
11
  # in order to pass any filters (e.g. authentication) defined in
@@ -34,37 +34,9 @@ describe OrdersController do
34
34
  it "assigns a new order as @order" do
35
35
  get :new, {}, valid_session
36
36
  expect(assigns(:order)).to be_kind_of(Order)
37
- expect(assigns(:order)).to be_new_record
38
- end
39
- end
40
-
41
- describe "GET edit" do
42
- it "assigns the requested order as @order" do
43
- order = create :order
44
- get :edit, {:id => order.to_param}, valid_session
45
- expect(assigns(:order)).to eq(order)
46
37
  end
47
38
  end
48
39
 
49
- describe "POST create" do
50
-
51
- describe "with invalid params" do
52
- it "assigns a newly created but unsaved order as @order" do
53
- # Trigger the behavior that occurs when invalid params are submitted
54
- allow_any_instance_of(Order).to receive(:save).and_return(false)
55
- post :create, {:order => { :paid_on => ""}}, valid_session
56
- expect(assigns(:order)).to be_kind_of(Order)
57
- expect(assigns(:order)).to be_new_record
58
- end
59
-
60
- it "re-renders the 'new' template" do
61
- # Trigger the behavior that occurs when invalid params are submitted
62
- allow_any_instance_of(Order).to receive(:save).and_return(false)
63
- post :create, {:order => { :paid_on => ""}}, valid_session
64
- expect(response).to render_template(:edit)
65
- end
66
- end
67
- end
68
40
 
69
41
  describe "PUT update" do
70
42
  describe "with valid params" do
data/spec/i18n_spec.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'i18n/tasks'
3
+ require "i18n-spec"
4
+
5
+ describe 'locale:' do
6
+
7
+ Dir.glob('config/locales/*.yml') do |locale_file|
8
+ next if locale_file == "config/locales/config.yml"
9
+ next if locale_file.include? "extra"
10
+ context locale_file do
11
+ it { is_expected.to be_parseable }
12
+ it { is_expected.to have_valid_pluralization_keys }
13
+ it { is_expected.not_to have_missing_pluralization_keys }
14
+ it { is_expected.to have_one_top_level_namespace }
15
+ it { is_expected.not_to have_legacy_interpolations }
16
+ it { is_expected.to have_a_valid_locale }
17
+ it { is_expected.to be_a_complete_translation_of 'config/locales/en.yml' }
18
+ end
19
+ end
20
+ context 'config/locales/en.yml' do
21
+ it { is_expected.to be_a_complete_translation_of 'config/locales/fi.yml' }
22
+ end
23
+ end
24
+
25
+ describe 'I18n' do
26
+ let(:i18n) { I18n::Tasks::BaseTask.new }
27
+ let(:missing_keys) { i18n.missing_keys }
28
+ let(:unused_keys) { i18n.unused_keys }
29
+
30
+ it 'does not have missing keys' do
31
+ # needs work
32
+ # expect(missing_keys).to be_empty,
33
+ # "Missing #{missing_keys.leaves.count} i18n keys, run `i18n-tasks missing' to show them"
34
+ end
35
+
36
+ it 'does not have unused keys' do
37
+ expect(i18n.unused_keys).to be_empty,
38
+ "#{unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them"
39
+ end
40
+ end
@@ -16,10 +16,6 @@ describe OrdersController do
16
16
  expect(get("/orders/1")).to route_to("orders#show", :id => "1")
17
17
  end
18
18
 
19
- it "routes to #edit" do
20
- expect(get("/orders/1/edit")).to route_to("orders#edit", :id => "1")
21
- end
22
-
23
19
  it "routes to #create" do
24
20
  expect(post("/orders")).to route_to("orders#create")
25
21
  end
@@ -24,5 +24,6 @@ module TestApp
24
24
  # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
25
25
  # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
26
26
  # config.i18n.default_locale = :de
27
+ config.active_record.raise_in_transactional_callbacks = true
27
28
  end
28
29
  end
@@ -20,7 +20,7 @@ TestApp::Application.configure do
20
20
  # config.action_dispatch.rack_cache = true
21
21
 
22
22
  # Disable Rails's static asset server (Apache or nginx will already do this).
23
- config.serve_static_assets = false
23
+ config.serve_static_files = false
24
24
 
25
25
  # Compress JavaScripts and CSS.
26
26
  config.assets.js_compressor = :uglifier
@@ -13,7 +13,7 @@ TestApp::Application.configure do
13
13
  config.eager_load = false
14
14
 
15
15
  # Configure static asset server for tests with Cache-Control for performance.
16
- config.serve_static_assets = true
16
+ config.serve_static_files = true
17
17
  config.static_cache_control = "public, max-age=3600"
18
18
 
19
19
  # Show full error reports and disable caching.